cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

dikobraz
Journeyman III

Write to OpenGL texture problem

I am writing sample with OpenGL/OpenCL. The sample workflow is the following:

  • Create 2 textures via OpenGL. Create 2 OpenCL images for their first mip levels.
  • Render to first texture via OpenGL.
  • Acquire images for OpenCL via glFlush, clEnqueueAcquireGLObjects
  • Run OpenCL kernel to process first image and write result to second
  • Release images via clEnqueueReleaseGLObjects, clFlush.
  • Render screen quad to display second texture.

After this step I get correctly processed OpenCL image, but corresponding OpenGL texture is blank. Here is what I get in gDebugger:

gDebugger screen 1

gDebugger screen 2

Am I missing something?

UPD: I have Radeon 5750HD onboard, but using CPU device doesn't help. Both OpenGL and OpenCL code produce no errors. Demo is single-threaded.

UPD: Works on NVIDIA GeForce GTX 460SE with 285.62 driver. But only first frame is processed correctly.

 

0 Likes
20 Replies
nou
Exemplar

replace both GL and CL Flush to Finish

0 Likes

Originally posted by: nou replace both GL and CL Flush to Finish

 

Thank you for reply. Tried your suggestion, problem remains.

0 Likes

then one more thing. create OpenGL texture after creation of OpenCL context.

0 Likes

Originally posted by: nou then one more thing. create OpenGL texture after creation of OpenCL context.

 

All the resources are created after both contexts have been initialized.

0 Likes

I guess you need to acquire the texture2 also in OpenCL in case you want to write to it and then release it to display via OpenGL.

Is inplace processing an option for you.

0 Likes

Originally posted by: himanshu.gautam I guess you need to acquire the texture2 also in OpenCL in case you want to write to it and then release it to display via OpenGL.

 

Is inplace processing an option for you.

 

I acquire both textures and release both of them after processing. Inplace processing is not an option. Nevertheless, I want to find out the problem.

0 Likes

Did you compared your method with what the APP SDK Samples follow. There are many GL-interop samples.

BTW, the images you posted are not readable. And it is better to share some code to get better feedback.

0 Likes

Originally posted by: himanshu.gautam Did you compared your method with what the APP SDK Samples follow. There are many GL-interop samples.

 

BTW, the images you posted are not readable. And it is better to share some code to get better feedback.

 

Code is available at: https://bitbucket.org/DikobrAz/simplegl (sobel example, open_cl branch). But it is hidden under API.

0 Likes

I have code which demonstrates interop with basic image processing with input and output textures. I was going to clean it up and release it open source but I haven't got a chance. I will see if I can get that done sooner as many people have a lot of problems getting this to work. It is certainly understandable since some of the formats which are supposed to work do not and it varies between Nvidia and ATI.

Anyway back to your code dikobraz, I will try to compile it later tonight but at first glace I am a bit confused as you have android specific code in there. As I don't know of any android device which has an AMD chip nor one supported by their driver I am assuming you are using a x86 android port correct?

0 Likes

Okay so I took a look at your code and I don't have something definative but here are my thoughts:

in your render function you call your own SetKernelArgs function function then calls your own AcquireForOpenCL() function in your CLImage2D class. This creates a wait event that is later checked by AquireForOpenGL. You have one of these per image and my concern is that you have a call to clEnqueuReleaseGLObjects() for each of these. I am wondering if you are getting an undefined behavior behavior because you are making a number of calls to clEnqueueReleaseGLObjects() rather than just one. Also you might make this call while one of the mipmaplevels was still working (or so it would seem). I think you would be better to wait for the cl::events to complete then make one call to clEnqueueReleaseGLObjects() for all your objects. As I said I didn't fully look at all your code but as it is I would think you are  have a race condition here.

0 Likes

Originally posted by: thesmileman Okay so I took a look at your code and I don't have something definative but here are my thoughts:

 

in your render function you call your own SetKernelArgs function function then calls your own AcquireForOpenCL() function in your CLImage2D class. This creates a wait event that is later checked by AquireForOpenGL. You have one of these per image and my concern is that you have a call to clEnqueuReleaseGLObjects() for each of these. I am wondering if you are getting an undefined behavior behavior because you are making a number of calls to clEnqueueReleaseGLObjects() rather than just one. Also you might make this call while one of the mipmaplevels was still working (or so it would seem). I think you would be better to wait for the cl::events to complete then make one call to clEnqueueReleaseGLObjects() for all your objects. As I said I didn't fully look at all your code but as it is I would think you are  have a race condition here.

 

Thank you for your deep analysis thesmileman! Actually for all the platforms where I tested my code, cl_khr_gl_event is not supported, so the AcquireForOpenCL uses the following code to acquire images (without events):

void CLImage2D::AcquireForOpenCL()
{
    ...
    glFinish();
    errCode = clEnqueueAcquireGLObjects(context->clCommandQueue,  1,   &clImage, 0, 0, 0);
    assert(errCode == CL_SUCCESS);

    acquiredByOpenCL = true;
    texture->acquiredByOpenCL = true; // if even one mip level is bound, texture is acquired for OpenCL
    ...
}

The CLKernel::SetKernelArg function checks image->acquiredByOpenCL flag. If it is set to false, then CLImage2D::AcquireForOpenCL() is called. In the same fashion function CLContext::Draw functions check all bound textures and render targets acquiredByOpenCL flag. If necessary CLTexture2D::AcquireForOpenGL function is called.

void CLTexture2D::AcquireForOpenGL() const
{
    ...
    for (size_t i = 0; i<mipImages.size(); ++i)
    {
        if (mipImages && mipImages->acquiredByOpenCL)
    {
        errCode = clEnqueueReleaseGLObjects(context->clCommandQueue, 1, &mipImages->clImage, 0, 0, 0);
        assert(errCode == CL_SUCCESS);
        mipImages
->acquiredByOpenCL = false;
        }
    }
   
    errCode = clFinish(context->clCommandQueue);
    assert(errCode == CL_SUCCESS);

    acquiredByOpenCL = false;
    ...
}

May be there are still bugs somewhere, but I've checked the command flow in gDebugger and everything seems fine. For now, I assume it is driver problem. If you get your sample working, it will be very great.

 

0 Likes

Originally posted by: thesmileman I have code which demonstrates interop with basic image processing with input and output textures. I was going to clean it up and release it open source but I haven't got a chance. I will see if I can get that done sooner as many people have a lot of problems getting this to work. It is certainly understandable since some of the formats which are supposed to work do not and it varies between Nvidia and ATI.

 

Anyway back to your code dikobraz, I will try to compile it later tonight but at first glace I am a bit confused as you have android specific code in there. As I don't know of any android device which has an AMD chip nor one supported by their driver I am assuming you are using a x86 android port correct?

 

It would be really nice if you realease your code. There are very few examples of OpenCL/OpenGL interop with textures across internet.

The library I'm working was a cross-platform OpenGL wrapper originally, so there is some android related code. I've started to work with OpenGL/OpenCL interop recently. The library is not fully functional now, because I modified heavily the interface and OpenCL code is incomplete. And android related code there is irrelevant for now.

0 Likes

then all i can say is try SimpleGL example from SDK. and modify it to your need.

0 Likes

As I understood texture sharing is rather new feature. BoxFilterGL and SimpleGL demos use only buffer sharing. Texture are modified using PBO to copy content from buffer. As I assume this is slower and harder to implement, but seems there aren't many choices.

0 Likes

Did you have any luck with the shared GL/CL texture?

I have not been able to write (write_image) to a shared texture in OpenCL, though I can read from it.

I am using clCreateFromGLTexture2D to wrap a texture created with g(TexImage2D, with appropriate Bind and clEnqueueAcquireGLObjects calls.

cheers

0 Likes

do you use proper write_image function? i mean you need use an write_imagef() when you want write into regular GL_RGBA8 texture. with values in 0.0-1.0 range

0 Likes

Thanks nou, I am checking all the settings again, again.

0 Likes

With the latest NVidia drivers sample begun to work correctly. For AMD I still use workaround: share buffer and copy content through PBO (haven't check the latest drivers).

0 Likes

dikobraz: Which sample was working for you?  Does it use clCreateFromGLTexture2D?

None of the NVIDIA nor AMD samples use clCreateFromGLTexture2D.

thanks

0 Likes

Here are demos binaries: http://dl.dropbox.com/u/31853478/Sobel.zip

It uses texture sharing if can (simple check is performed), otherwise texture exchange is implemented through buffer. Source code you can find here: https://bitbucket.org/DikobrAz/simplegl/src/ddc55dc41873 - check out "opencl" branch.

There are lots of crazy buggy stuff, which I still haven't refactored. But you might be particularly interested in code fragment from this file (lines 197-306), where the check for texture sharing functionality is performed:

https://bitbucket.org/DikobrAz/simplegl-core/src/fca59f24b388/src/GL/CLContext.cpp

Works as follows: OpenGL texture is created and exposed to OpenCL via clCreateFromGLTexture2D. Then it is filled through FBO with some color, acquired for OpenCL, and check is performed that OpenCL image have the same content.

P.S: We have tested sample on AMD and it crashed (fine on NVidia). Not so far ago it worked on both cards. Tomorrow I try to locate bug, but it might be a driver problem.

0 Likes