是否可以使用OpenCL获取OpenGL缓冲区的值?例如,编写一个用缓冲区创建OpenGL上下文的程序,另一个用于执行OpenCL代码?我不希望第一个程序代码改变.
有一个可选的OpenCL扩展,cl_khr_gl_sharing允许实现与OpenCL对象(缓冲区和图像)共享某些OpenGL对象(缓冲区和纹理).OpenCL的大多数可用GPU实现都支持此扩展.扩展定义的其他API函数在头文件中可用CL/cl_gl.h.
你可以通过调用检查是否您的设备和平台支持该扩展clGetDeviceInfo与CL_DEVICE_EXTENSIONS论证,并检查所产生的字符串是否cl_khr_gl_sharing存在.
在OpenCL初始化期间,您需要以特定方式创建OpenCL上下文,以便与OpenGL共享对象.这是特定于操作系统的,但在所有情况下都涉及创建一组传递给的上下文属性clCreateContext.以下是一些例子:
OS X.
CGLContextObj CGLGetCurrentContext(void);
CGLShareGroupObj CGLGetShareGroup(CGLContextObj);
CGLContextObj kCGLContext = CGLGetCurrentContext();
CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext);
cl_context_properties properties[] =
{
CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE,
(cl_context_properties) kCGLShareGroup,
0
};
Run Code Online (Sandbox Code Playgroud)
Linux(使用GLX)
cl_context_properties properties[] =
{
CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(),
CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(),
CL_CONTEXT_PLATFORM, (cl_context_properties)platform, // OpenCL platform object
0
};
Run Code Online (Sandbox Code Playgroud)
Windows(WGL)
cl_context_properties properties[] =
{
CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(),
CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(),
CL_CONTEXT_PLATFORM, (cl_context_properties)platform, // OpenCL platform object
0
};
Run Code Online (Sandbox Code Playgroud)
Android(使用EGL)
cl_context_properties properties[] =
{
CL_GL_CONTEXT_KHR, (cl_context_properties)eglGetCurrentContext(),
CL_EGL_DISPLAY_KHR, (cl_context_properties)eglGetCurrentDisplay(),
CL_CONTEXT_PLATFORM, (cl_context_properties)platform, // OpenCL platform object
0
};
Run Code Online (Sandbox Code Playgroud)
设置属性后,创建如下的上下文:
context = clCreateContext(properties, 1, &device, NULL, NULL, &err);
Run Code Online (Sandbox Code Playgroud)
接下来要做的是从现有的OpenGL对象创建OpenCL对象.OpenGL方面的任何内容都不需要改变.给定一个调用的现有OpenGL缓冲区bufferGL,您可以从中创建一个OpenCL缓冲区对象,如下所示:
bufferCL = clCreateFromGLBuffer(context, CL_MEM_READ_WRITE, bufferGL, &err);
Run Code Online (Sandbox Code Playgroud)
或者,您可以从OpenGL纹理创建OpenCL图像:
imageCL = clCreateFromGLTexture2D(context, CL_MEM_WRITE_ONLY,
GL_TEXTURE_2D, 0, textureGL, &err);
Run Code Online (Sandbox Code Playgroud)
剩下的就是将在这些共享CL/GL对象上运行的OpenCL内核排入队列.您需要在内核的任何一侧排队一些额外的命令,以告诉实现您要将对象的所有权转移到OpenCL或从OpenCL转移对象的所有权.您需要执行的一般操作顺序如下:
// Flush GL queue
glFlush();
// Acquire shared objects
err = clEnqueueAcquireGLObjects(queue, 1, &bufferCL, 0, NULL, NULL);
// Enqueue OpenCL commands to operate on objects (kernels, read/write commands, etc)
// Release shared objects
err = clEnqueueReleaseGLObjects(queue, 1, &bufferCL, 0, NULL, NULL);
checkError(err, "releasing GL objects");
// Flush CL queue
err = clFinish(queue);
Run Code Online (Sandbox Code Playgroud)
有一些示例代码可以演示OpenCL/OpenGL的互操作性,值得一看,在完整的应用程序中展示了所有这些: