- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a question regarding OpenCL / OpenGL interoperation when run on an Intel CPU.
I just don't quite understand the purpose of the cl_khr_gl_sharing extension on a CPU.
When a shared GL-CL context is created, must the GL device context and CL context both be associated with the same device?
Or am I able to have the GL context associated with my GPU, and the CL context associated with my CPU?
I am currently trying to do the latter, but am having issues writing to the GL texture objects from within the kernel on the CPU, where the same code works without problems on my GPU.
Does anybody have any experience with GL CL interop on a CPU when a dedicated GPU is being used for OpenGL?
Thanks
Lewis
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Lewis,
I was able to modify the following sample (https://software.intel.com/en-us/articles/sharing-surfaces-between-opencl-and-opengl-43-on-intel-processor-graphics-using-implicit) and make it work on the CPU, with OpenGL running on the GPU.
CL context is associated w/ CPU, GL context is associated with the GPU. Judging from the speed of the sample, there is an implicit copy involved unlike zero copy when CL context is associated w/ GPU as well.
HGLRC hGLRC = 0; HDC hDC = 0; hGLRC = wglGetCurrentContext(); hDC = wglGetCurrentDC(); //need to pass it the current window handle cl_context_properties cps[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)g_platformToUse, CL_GL_CONTEXT_KHR, (cl_context_properties)hGLRC, CL_WGL_HDC_KHR, (cl_context_properties)hDC, 0 }; // Find CL capable devices in the current GL context cl_device_id devices[32]; size_t size; clGetGLContextInfoKHR_fn pclGetGLContextInfoKHR = (clGetGLContextInfoKHR_fn)clGetExtensionFunctionAddressForPlatform(g_platformToUse, "clGetGLContextInfoKHR"); status = pclGetGLContextInfoKHR(cps, CL_DEVICES_FOR_GL_CONTEXT_KHR, 32 * sizeof(cl_device_id), devices, &size); //create an OCL context - first device here is CPU g_clContext = clCreateContext(cps, 1, devices, NULL, NULL, &status); testStatus(status, "clCreateContext error"); //create an openCL commandqueue g_clCommandQueue = clCreateCommandQueue(g_clContext, devices[0], 0, &status); testStatus(status, "clCreateCommandQueue error");
Share your GL surface as usual:
g_SharedRGBAimageCLMemObject = clCreateFromGLTexture(g_clContext, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, g_RGBAbufferGLBindName, &status);
Then in your OpenCL update loop don't forget to call glFinish before acquiring GL objects and clFinish on your CPU command queue, since CPU does not support cl_khr_gl_event:
//platform does not support the sync extenion, requires glFinish() for compatibility if(g_clEventFromGLsyncObjectSupported == FALSE) { glFinish(); } status = clEnqueueAcquireGLObjects(g_clCommandQueue, 1, &g_SharedRGBAimageCLMemObject, 0, 0, 0); testStatus(status, "clSetKernelArg"); status = clSetKernelArg(cl_kernel_drawBox, 0, sizeof(cl_mem), &g_SharedRGBAimageCLMemObject); testStatus(status, "clSetKernelArg"); status = clSetKernelArg(cl_kernel_drawBox, 1, sizeof(cl_float), &fDimmerSwitch); testStatus(status, "clSetKernelArg"); size_t global_dim[2]; global_dim[0] = CL_GL_SHARED_TEXTURE_HEIGHT; global_dim[1] = CL_GL_SHARED_TEXTURE_WIDTH; status = clEnqueueNDRangeKernel(g_clCommandQueue, cl_kernel_drawBox, 2, NULL, global_dim, NULL, 0, NULL, NULL); testStatus(status, "clEnqueueNDRangeKernel fail"); status = clEnqueueReleaseGLObjects(g_clCommandQueue, 1, &g_SharedRGBAimageCLMemObject, 0, NULL, NULL); testStatus(status, "Fail on clEnqueueReleaseGLObjects"); if(g_clEventFromGLsyncObjectSupported == FALSE) { clFinish(g_clCommandQueue); }
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Robert, thanks for your reply.
I read over my code again, and couldn't see anything fundamentally different to yours.
I managed to get it working anyway... although I am not entirely sure how.
After rebooting my PC to boot with Intel HD Graphics 4600 (Integrated), and then reboot again with my dedicated GPU, the problem seemed to have resolved itself - My kernel can now execute on Intel CPU, and modify shared OpenGL memory on my AMD GPU.
I will try this code on my other PC (Intel + Nvidia) in a few days, but hopefully it should be OK :)
Cheers.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page