OpenCL* for CPU
Ask questions and share information on Intel® SDK for OpenCL™ Applications and OpenCL™ implementations for Intel® CPU.
Announcements
This forum covers OpenCL* for CPU only. OpenCL* for GPU questions can be asked in the GPU Compute Software forum. Intel® FPGA SDK for OpenCL™ questions can be ask in the FPGA Intel® High Level Design forum.
1719 Discussions

GL CL interop on CPU

Lewis_B_
Beginner
632 Views

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

0 Kudos
2 Replies
Robert_I_Intel
Employee
632 Views

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); 
	}

 

0 Kudos
Lewis_B_
Beginner
632 Views

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.

0 Kudos
Reply