Reputation: 575
I was rendering in OpenGL and acquiring a texture, that I had bound to the FrameBuffer, to an OpenCL cl_mem, doing some modifications in OpenCL, and then returning the modified image to the FrameBuffer for display. I am trying to do the same thing with OpenCV cv::UMat instead, with the only changes shown below. The last line, call to acquire the GLObjects, is where the fault occurs...
UMat cvImage(480,640,CV_8UC4, ACCESS_RW);
cl_mem clImage = (cl_mem)cvImage.handle(ACCESS_RW);
--- generate/bind/etc glFrameBuffer
--- render stuff
clEnqueueAcquireGLObjects(ocl_queue, 1, &clImage , 0, NULL, NULL); //
I was previously instantiating clImage with:
clImage = clCreateFromGLTexture2D(context, CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, g_fb_tex, &err);
and it was working fine. In debug I can see the memory addresses are the same for cvImage and clImage so maybe I haven't created a large enough image size for cvImage? I do not know how the clCreateFromGLTexture2D call does it. Alternatively, I could maintain the way I had it and transfer the cl_mem to UMat after the AcquireGLObjects call.
--------Update 1-------
Based on boiler96's response, I tried the following process which doesn't fault but only gives me a nice blue screen (not a BSOD, but a similar shade in the CV window) and an INVALID_CONTEXT error:
UMat cvImage(480,640,CV_8UC4, cv::ACCESS_RW);
cl_mem clImage = clCreateFromGLTexture2D(context, CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, g_fb_tex, &err);
clEnqueueAcquireGLObjects(ocl_queue, 1, &clImage, 0, NULL, NULL); //
clEnqueueCopyImageToBuffer(ocl_queue, clImage, (cl_mem)cvImage.handle(ACCESS_RW), origin, region,0,0,NULL,NULL);
imshow("window", me);
waitKey(0);
More work to do... next attempt will try clCreateFromGLBuffer instead. Thanks!
Upvotes: 1
Views: 1617
Reputation: 1177
I think there's a couple things wrong here.
First, when sharing OpenCL objects with OpenGL, OpenGL is the API in which the objects have to be created. In the code block above, it appears that OpenCV is creating the object as part of the cvImage constructor (perhaps if we saw the binding to glFrameBuffer, this issue would be more apparent.)
Second, OpenCV 3.0 UMat objects have OpenCL buffer handles, whereas sharing OpenGL frame buffers produces OpenCL image handles. This is a bit deceptive because both types of objects are represented by cl_mem handles. But they are, in fact, different. So, I don't see a way for OpenCV to operate directly on an OpenGL frame buffer.
Instead, I think you might be forced to create your OpenCL image handle and OpenCV UMat as completely separate entities. And when OpenCV is done with filling the UMat, acquire the OpenCL image that represents the render buffer, enqueue a copy command to copy data from the UMat's OpenCL buffer to the OpenCL image, and release the OpenCL image so OpenGL can use it.
Upvotes: 1