title: OpenCL/OpenGL Interop on OSX -- has anyone ever shared a Renderbuffer or Texture?
body: <p>Problem: Attempting to share a Renderbuffer (or a Texture), bound to a Framebuffer, fails when clSetKernelArg() is called.  Thorough error checking reports no problems until that call.</p>
  
  <p>My program generates frames for a video projector that runs at 60fps (16.7ms frames).</p>
  
  <p>My kernel runs in (typically) 24ms, but it's taking 50ms between each frame. I assume that some of the extra cost is because I'm using the GPU to calculate the pixels, then enqueuing a readbuffer to pull the data <em>off</em> the GPU, then using glDrawPixels to put it <em>back onto</em> the GPU for display. Perfect situation to try OpenGL/OpenCL interoperation, right?, to avoid the two extra copy operations.</p>
  
  <p>There are many examples, and I <em>have</em> succeeded in sharing a VBO with OpenCL, and can write to it, but that doesn't help me. I don't want to write vertex data, just a 2-D image that's been calculated.</p>
  
  <p>There are examples of two different ways to do this, and they both involve Framebuffer objects.</p>
  
  <p>You can attach a Renderbuffer to a Framebuffer, or you can attach a Texture to a Framebuffer.</p>
  
  <p>Then you should be able to write to that buffer in opencl and display it with opengl, no extra copies.</p>
  
  <p>I have found a few examples of this in code, and I think I'm doing everything exactly the way the examples say to do it, but maybe it is broken in OSX? .. because it doesn't work. The FBO is "Complete", no errors along the way, until I try to do the clSetKernelArg. That call returns error -38, CL_INVALID_MEM_OBJECT.</p>
  
  <p>*note: I would rather use a Renderbuffer than a Texture, since all I'm doing is making a 2-D RGB image that I want to display. But I tried a Texture out of desperation. Still no help.</p>
  
  <p>I do these steps, in this order, with some other stuff in between:</p>
  
  <pre><code>kCGLContext = CGLGetCurrentContext(); 
  kCGLShareGroup = CGLGetShareGroup( kCGLContext );
  
  glGenFramebuffers( 1, &amp;fboid );
  glBindFramebuffer( GL_FRAMEBUFFER, fboid );
  
  glGenRenderbuffers( 1, &amp;rboid );
  glBindRenderbuffer( GL_RENDERBUFFER, rboid );
  glRenderbufferStorage( GL_RENDERBUFFER, GL_RGBA, rb_wid, rb_hgt );
  
  glboid = rboid;
  
  glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboid );
  </code></pre>
  
  <p>then:</p>
  
  <pre><code>cl_context_properties ourprops[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 };
  
  contextZ = clCreateContext( ourprops, 1, &amp;dev_idZ[0], clLogMessagesToStdoutAPPLE, NULL, &amp;err );
  
  clbo = clCreateFromGLRenderbuffer( contextZ, CL_MEM_WRITE_ONLY, glboid, &amp;err );
  </code></pre>
  
  <p>then clCreateCommandQueue, clCreateProgramWithBinary, clBuildProgram, clCreateKernel, all no errors</p>
  
  <p>then later:</p>
  
  <pre><code>glFinish();
  clEnqueueAcquireGLObjects( queueZ, 1, &amp;clbo, 0,0,0 );
  
  err = clSetKernelArg( kernelZ, 1, sizeof(cl_mem), &amp;clbo );
  </code></pre>
  
  <p>... which fails with error -38, CL_INVALID_MEM_OBJECT.</p>
  
  <p>clbo is a static cl_mem, just like the buffer object that's used when interop is not on. The difference being that it was created using clCreateFromGLRenderbuffer instead of clCreateBuffer, and it's in a context created in association with the gl sharegroup.</p>
  
  <hr>
  
  <p>(I've tried adding a second Renderbuffer and attaching it to a Depth Attachment Point, in case that was needed. No help.)</p>
  
  <p>(I've tried the same thing with a Texture bound to the FBO, and I get the same error in the same place.)</p>
  
  <p>... does anybody have any ideas at all?</p>