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.

OpenGL interop on the CPU

Polar01
Beginner
1,679 Views

Hi,

I try to use the clCreateFromGLTexture to do openGL interop with the CPU, but it seems that it failed.

Here is my code:

glGenTextures(1, _glTex);

//-- Texture
glBindTexture(GL_TEXTURE_2D, _glTex[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, _width, _height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);

_clTex0 = clCreateFromGLTexture(_oclContext, CL_MEM_READ_WRITE, GL_TEXTURE_2D, 0, _glTex[0], &error);

Does someone has an idea (For info it works fine with AMD SDK) !

0 Kudos
18 Replies
Raghupathi_M_Intel
1,679 Views

Hi,

What is the error you are getting? Can you attach a full reproducible?

Thanks,
Raghu

0 Kudos
Polar01
Beginner
1,679 Views

Hi,

I got an INVALID_GL_OBJECT !!

0 Kudos
Maxim_S_Intel
Employee
1,679 Views

Hi,

can you shre your initialization code, i.e. how OCL-OGL shared context is created?

0 Kudos
Polar01
Beginner
1,679 Views

Sure,

cl_context_properties cps[] = {
CL_GL_CONTEXT_KHR, (intptr_t)_win32HGLRC,
CL_WGL_HDC_KHR, (intptr_t)_win32HDC,
CL_CONTEXT_PLATFORM, (cl_context_properties)platform(),
0};

return new cl::Context(devices, cps);

0 Kudos
Maxim_S_Intel
Employee
1,679 Views

And what is happening inside cl::Context(devices, cps)? For the CPU case it should be smth like "return  clCreateContextFromType(cps,CL_DEVICE_TYPE_CPU,NULL,NULL,NULL);"  if ommiting the error checking.  This way you simply ask to create an interop-context with the CPU device .

Notice that this is contrast to GPU-iterop case where you need to call clGetGLContextInfoKHR() with CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR which would return a specific device id to create context with (this handles the potential multi-GPU case, since sharing works with the particluar device which serves the specific GL context ).

0 Kudos
Polar01
Beginner
1,679 Views

Hi Maxim,

Here is the code :

Context(
const VECTOR_CLASS<Device>& devices,
cl_context_properties* properties = NULL,
void (CL_CALLBACK * notifyFptr)(
const char *,
const void *,
::size_t,
void *) = NULL,
void* data = NULL,
cl_int* err = NULL)
{
cl_int error;
object_ = ::clCreateContext(
properties, (cl_uint) devices.size(),
(cl_device_id*) &devices.front(),
notifyFptr, data, &error);

detail::errHandler(error, __CREATE_CONTEXT_ERR);
if (err != NULL) {
*err = error;
}
}

0 Kudos
Polar01
Beginner
1,679 Views

This code is extracted from cl.hpp, provided by the Khronos group.

Thanks

0 Kudos
Maxim_S_Intel
Employee
1,679 Views

Hi again,

Actualy you need to create PBO (which is kind of "view" associated with the texture), and this will be the PBO object to share with. Since PBO is extension, you would need to use glew that smoothly works with available extensions, or otherwise manually get the func adresses for the PBO API.

//create pixel-buffer object  

glGenBuffers(1, &pbo); 

glBindBuffer(GL_ARRAY_BUFFER, pbo);

glBufferData(GL_ARRAY_BUFFER, _width * _height * sizeof(cl_uchar4), NULL, GL_DYNAMIC_DRAW);

After that you call the clCreateFromGLTexture for the PBO object to get the OpenCL buffer object to work with. So you do a call to the clEnqueueAcquireGLObjects for the resulting buffer, some processing with OpenCL and clEnqueueReleaseGLObjects after that. Notice that these OpenCL APIs are conceptually similar to glBindBuffer/glUnmapBuffer that are used to work with PBOs usinf regular native code like C/C++.

Finally to use (e.g. display) the texture  with OpenGL again, you bind both PBO and the texture and sync them like this:

//tells the driver you wish to transfer pixel data from PBO (unpack)

glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);

//to the specific texture

glBindTexture(GL_TEXTURE_2D, texture);

//data upload

glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _width, _height, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

Now you can for example render a textured quad.

0 Kudos
Polar01
Beginner
1,679 Views

Thanks a lot Maxim,

I have also try with the PBO, but failed to create this one, here is my code :

glGenBuffers(1, &_glPBO);
glBindBuffer(GL_ARRAY_BUFFER, _glPBO);
glBufferData(GL_ARRAY_BUFFER, _width * _height * 4, NULL, GL_DYNAMIC_DRAW);

_clPBO = _oclContext.CreateFromGLTexture(CL_MEM_READ_WRITE, GL_TEXTURE_2D, 0, _glPBO, &error);

Then I got an opengl error : 

GL_INVALID_ENUM error generated. <pname> requires feature(s) disabled in the current profile.

0 Kudos
Maxim_S_Intel
Employee
1,679 Views

Hi,

when working with PBO, you should use clCreateFromGLBuffer, since PBO is kind of "mapped" view of the texture which is translated to OpenCL buffers.  While CreateFromGLTexture generates OpenCL image object. Which way is more optimal depends on the rest of app (and kernels) code.

We will try to reproduce an issue with CreateFromGLTexture and will come back to you soon. You can use PBO/clCreateFromGLBuffer as a workaround in a meantime.

0 Kudos
Polar01
Beginner
1,679 Views

Hi Maxim,

I'm still trying to figure out why I have such error.... now I can create the PBO without problem, but when I try to create the texture I got an OpenGL error : "GL_INVALID_ENUM error generated. <pname> requires feature(s) disabled in the current profile."

I receive this error from the "OpenGL ARB Callback" !!

And the CreateFromGLTexture return "INVALID GL OBJECT" !

So, to summarize I create a PBO and 2 textures... but the texture creation fail !

Here is the code (I got a crash at the last 2 lines)

//---- Initialize the PBO
_glContext->glGenBuffers(1, &_glPBO);
_glContext->glBindBuffer(GL_ARRAY_BUFFER, _glPBO);
_glContext->glBufferData(GL_ARRAY_BUFFER, _width * _height * _components * _bytesPerComponent, NULL, GL_DYNAMIC_DRAW);

_clPBO = _oclContext.CreateFromGLBuffer(OPENCL_MEMORY_OBJECT_FLAGS::READ_WRITE, _glPBO, &error);

//---- Texture
_glContext->glGenTextures(2, _glTex);

//-- Texture 0
_glContext->glBindTexture(GL_TEXTURE_2D, _glTex[0]); // Bind
_glContext->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
_glContext->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
_glContext->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
_glContext->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
_glContext->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, _width, _height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
_glContext->glBindTexture(GL_TEXTURE_2D, 0); // Unbind

//-- Texture 1
_glContext->glBindTexture(GL_TEXTURE_2D, _glTex[1]); // Bind
_glContext->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
_glContext->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
_glContext->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
_glContext->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
_glContext->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, _width, _height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
_glContext->glBindTexture(GL_TEXTURE_2D, 0); // Unbind

_glContext->glFinish();

_clTex0 = _oclContext.CreateFromGLTexture(OPENCL_MEMORY_OBJECT_FLAGS::READ_WRITE, GL_TEXTURE_2D, 0, _glTex[0], &error);
_clTex1 = _oclContext.CreateFromGLTexture(OPENCL_MEMORY_OBJECT_FLAGS::READ_WRITE, GL_TEXTURE_2D, 0, _glTex[1], &error);


 

0 Kudos
Raghupathi_M_Intel
1,679 Views

Sorry for the late reply. I am doing the exact same thing and the call to clCreateFromGLTexture() succeeds. Is it possible to share a minimal reproducer demonstrating the problem? Also what's you system config and driver version?

Thanks,
Raghu

0 Kudos
Maxim_S_Intel
Employee
1,679 Views

Polar01 wrote:

And the CreateFromGLTexture return "INVALID GL OBJECT" ! 

Hi again, as a potential workaround, can you please try calling  glGenerateMipmap( GL_TEXTURE_2D ); right after glTexImage2D?

0 Kudos
Polar01
Beginner
1,679 Views

Thanks Maxim,

I have just try, but it still crash !

I have the following OpenGL message : GL_INVALID_ENUM error generated. <pname> requires feature(s) disabled in the current profile.​

How can I check the problem with my profile ?

0 Kudos
Polar01
Beginner
1,679 Views

Hi,

I think that I have found the problem and it is on our side, in fact we use OpenGL 3+ and we create the openGL context in the following way :

attribs[current++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
attribs[current++] = 3;
attribs[current++] = WGL_CONTEXT_MINOR_VERSION_ARB;
attribs[current++] = 2;
attribs[current++] = WGL_CONTEXT_FLAGS_ARB;
attribs[current++] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | WGL_CONTEXT_DEBUG_BIT_ARB;
glRC3 = wglCreateContextAttribsARB(hDC, 0, attribs);

But it seems that you use some depreceated OpenGL functions in the OpenCL SDK !

Please, can you advice ?

0 Kudos
Polar01
Beginner
1,679 Views

Hi Maxim,

Have you find some time to look at this problem ?

Krys

0 Kudos
Polar01
Beginner
1,679 Views

Hiiiiiii,

Is there someone here ? :'(

How can I help you to fix the problem  ?

Thanks

0 Kudos
Maxim_S_Intel
Employee
1,679 Views

Hi,

Sorry for the late answer on this.

I tried  creating the context with wglCreateContextAttribsARB, and the subsequent calls to clCreateFromGLTexture work fine for me.

We would need a small repro from you, as Raghu already asked.

 

0 Kudos
Reply