Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting OpenGL buffers using OpenCL

Tags:

c++

opengl

opencl

Is it possible to get the values of OpenGL buffers using OpenCL? For example, writing a program that creates OpenGL context with buffers, and another one to execute OpenCL code? I don't want the first programs code to change.

like image 618
user3075425 Avatar asked Oct 25 '25 02:10

user3075425


1 Answers

There is an optional OpenCL extension, cl_khr_gl_sharing, that allows an implementation to share certain OpenGL objects (buffers and textures) with OpenCL objects (buffers and images). This extension is supported on most of the available GPU implementations of OpenCL. The additional API functions defined by the extension are available in the header file CL/cl_gl.h.

You can check whether your device and platform support this extension by calling clGetDeviceInfo with the CL_DEVICE_EXTENSIONS argument, and checking the resulting string to see if cl_khr_gl_sharing is present.

During OpenCL initialisation, you need to create the OpenCL context in a particular way in order to enable sharing objects with OpenGL. This is OS specific, but in all cases involves creating a set of context properties which you pass to clCreateContext. Here's a few examples:


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
};

Linux (with 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
};

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
};

Android (with 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
};

Once the properties have been set up, create the context like this:

context = clCreateContext(properties, 1, &device, NULL, NULL, &err);

The next thing to do is to create your OpenCL objects from the existing OpenGL objects. Nothing on the OpenGL side needs to change. Given an existing OpenGL buffer called bufferGL, you can create an OpenCL buffer object from it like this:

bufferCL = clCreateFromGLBuffer(context, CL_MEM_READ_WRITE, bufferGL, &err);

Or you can create an OpenCL image from an OpenGL texture:

imageCL = clCreateFromGLTexture2D(context, CL_MEM_WRITE_ONLY,
                                  GL_TEXTURE_2D, 0, textureGL, &err);

All that remains is to enqueue your OpenCL kernels that operate on these shared CL/GL objects. You need to enqueue some extra commands either side of your kernel in order to tell the implementation that you want to transfer ownership of the objects to/from OpenCL. The general sequence of operations that you need to perform is as follows:

// 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);

There's a few example codes out there that demonstrate OpenCL/OpenGL interoperability, which would be worth a look to see all of this demonstrated inside a full application:

  • Intel's OpenCL/OpenGL tutorial
  • Apple's OpenCL Procedural Geometric Displacement Example
  • NVIDIA's simple OpenCL/OpenGL example
like image 68
jprice Avatar answered Oct 27 '25 18:10

jprice