获取 "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR" 当 GLtexture GL_RED 用于 clCreateFromGLTexture

Get "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR" when GLtexture GL_RED are used for clCreateFromGLTexture

我有一个问题,当我使用 GL_RED、GL_RED_INTEGER 作为 OpenGL 纹理格式和 GL_R32F/GL_R16UI 作为内部格式时,命令“clCreateFromGLTexture " 创建纹理到 OpenCL returns CL_INVALID_IMAGE_FORMAT_DESCRIPTOR。 OpenCL 真的支持这种格式吗?或者在使用之前缺少了什么?

初始化OpenCL的代码简要如下:

void initMemoryOpenCL(bool CL_info, const size_t select_device_number,  const int device_type)
{
    cl_uint num;
    err = clGetPlatformIDs(0, 0, &num);
    std::vector<cl_platform_id> platforms(num);
    err = clGetPlatformIDs(num, &platforms[0], &num);

    cl_device_id *device_id = NULL;

    cl_uint num_devices = -1;
    clGetDeviceIDs(platforms[select_device_number], CL_DEVICE_TYPE_GPU, 0, device_id, &num);
    device_id = (cl_device_id *)malloc(sizeof(cl_device_id)*num_devices);
    clGetDeviceIDs(platforms[select_device_number], CL_DEVICE_TYPE_GPU, num_devices, device_id, 0);

    cl_context_properties prop_cl[] = {
        CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(platforms[select_device_number]),
        CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(),
        CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(),
        0 };
    context_CL = clCreateContextFromType(prop_cl, CL_DEVICE_TYPE_GPU, NULL, NULL, &err);

    clGetGLContextInfoKHR_fn pclGetGLContextInfoKHR = (clGetGLContextInfoKHR_fn)
        clGetExtensionFunctionAddressForPlatform(platforms[select_device_number], "clGetGLContextInfoKHR");

    size_t bytes = 0;
    pclGetGLContextInfoKHR(prop_cl, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, 0, NULL, &bytes);
    unsigned int numDevs = bytes / sizeof(cl_device_id);
    cl_device_id *devID = NULL;
    device_id = (cl_device_id*)malloc(sizeof(cl_device_id)* numDevs);
    pclGetGLContextInfoKHR(prop_cl, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, bytes, device_id, NULL);

    cl_bool sup;
    size_t rsize;
    clGetDeviceInfo(device_id[0], CL_DEVICE_IMAGE_SUPPORT, sizeof(sup), &sup, &rsize);
    if (sup != CL_TRUE){ std::cout << "Image not Supported" << std::endl; }
    cl_uint work_item_dimens;
    size_t cb, work_group_size;

    if (checkForExtension(device_id[0],"cl_khr_gl_sharing"))
    {
        printf("Found GL Sharing Support!\n");
    }
    else
    {
        printf("Can NOT Found GL Sharing Support!\n");
    }

    this->queue_CL = clCreateCommandQueue(this->context_CL, device_id[0], 0, &err);
    this->program = load_program(context_CL, "openclfuncs.cl", device_id[0]);
}

OpenCL 1.2 扩展规范9.7.3.1、table 9.4 部分列出OpenGL内部格式对应的OpenCL图像格式。请注意,实现可能不支持相应的扩展 cl_khr_gl_sharing

cl_khr_gl_sharing 中,对于 OpenCL 1.2,单通道或双通道内部格式之间没有对应关系。该规范还指出

Texture objects created with other OpenGL internal formats may (but are not guaranteed to) have a mapping to a CL image format;

我无法解释为什么会出现这种情况(具有讽刺意味的是,D3D 扩展提供了更多的格式)- 我有点无法理解为什么它需要下一个 CL 版本来完成它。

如果您需要对您请求的功能的支持,您将不得不升级到 OpenCL 2.0 或更高版本 - 它的扩展规范定义了您所请求的映射。

或者您可以尝试将您的值打包在 GL_RGBA[32|16][F|UI] 纹理中。


要检查您的设备是否支持必要的扩展,您可以使用这样的函数查询您操作的设备(需要 C++14):

auto checkForExtension(cl_device_id device, std::string const& extensionName)
{
  std::size_t extensionSize = 0;
  clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, 0, nullptr, &extensionSize);

  std::vector<char> extensions(extensionSize);
  clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, extensionSize, extensions.data(), nullptr);

  auto iter = std::search(
    extensions.cbegin(), 
    extensions.cend(), 
    extensionName.cbegin(), 
    extensionName.cend()
  );

  return iter != extensions.end();
}

如果像 checkForExtension(device, "cl_khr_gl_sharing"); 这样调用时 return true,那么该特定设备的实现不支持它。