OpenCL与OpenGL协作方法

OpenCL和OpenGL都能用于操作GPU,但是前者主要用于通用计算,而后者主要用于图像渲染。在某些情况下,我们希望能用OpenCL计得到算图像,然后展示在显示器上。如果直接调用OpenGL的现有API,则需要把计算得到的结果通过pci-e总线传回host端内存,再由OpenGL再次通过pci-e总线传回gpu端显存。这样就造成了额外的拷贝,传输开销。事实上,可以使用OpenCL的OpenGL扩展功能,使得OpenCL和OpenGL能共享buffer,从而避免额外的传输。这种共享可以通俗的理解为是让OpenCL和OpenGL共享同一块内存的指针。

  要实现这种共享需要三步:

  1.OpenCL在OpenGL的上下文基础上创建上下文

  //创建上下文的属性
  cl_context_properties properties[] = {
  CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(), //获得OpenGL上下文
  CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(), //获得OpenGl设备信息
  CL_CONTEXT_PLATFORM, (cl_context_properties) platform, //获得平台信息
  0};
  //利用刚刚创建的属性创建上下文
  ctx = clCreateContext(properties, 1, &device, NULL, NULL, &err);


  2.OpenCL在OpenGL内存对象的基础上创建内存对象
  //以buffer为例,需要一个OpenGL的vbo才能创建共用的内存对象
  cl_mem clCreateFromGLBuffer(cl_context context, cl_mem_flags flags, 
  GLuint vbo_desc, cl_int *err)

  注意:OpenGL的内存对象必须先行创建,使用OpenCL中的image则需要OpenGL中的texture

  3.共享内存对象的同步及访问
  很显然OpenCL和OpenGL不能同时去访问同一个数据对象,需要加锁,解锁进行同步
   
  //加锁
  int clEnqueueAcquireGLObjects(cl_command_queue queue, cl_uint num_objects,
  const cl_mem *mem_objects, cl_uint num_events_in_wait_list,
  const cl_event *event_wait_list, cl_event *event)
  //加锁后在该处运行openCL代码
  //解锁
  int clEnqueueReleaseGLObjects(cl_command_queue queue, cl_uint num_objects,
  const cl_mem *mem_objects, cl_uint num_events_in_wait_list,
  const cl_event *event_wait_list, cl_event *event)

  做完这三步后,OpenGL即可直接使用共享的内存对象进行渲染及其他操作。

  更加详细的信息请参考: Understanding OpenCL-OpenGL Interoperability
  OpenCL / OpenGL Interoperation 教程及实例

你可能感兴趣的:(OpenCL与OpenGL协作方法)