获取 "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
,那么该特定设备的实现不支持它。
我有一个问题,当我使用 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
,那么该特定设备的实现不支持它。