4

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.

1
  • 1
    It may be possible, depending on the vendor. Look for cl_khr_gl_sharing extension. Commented Nov 7, 2014 at 14:00

1 Answer 1

12

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:

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.