Results 1 to 7 of 7

Thread: Grabbing image from OpenGL via OpenCL

  1. #1
    Junior Member
    Join Date
    Jul 2010
    Posts
    6

    Grabbing image from OpenGL via OpenCL

    Hi!

    I'm beginner to OpenCL world and I need some help to copy data from GPU to CPU. The problem is that this data is a 2D texture made by OpenGL (off-screen rendering with FBO + GLSL). The context init seems good and returns no error; recording the texture to CL via clCreateFromGLTexture2D and acquiring data (clEnqueueAcquireGLObjects) return nothing but CL_SUCCESS too.

    Then, there's the moment when I want to copy the texture back from GPU memory to RAM. I tried clEnqueueReadBuffer and clEnqueueReadImage, and I even tried to write something on it with clEnqueueWriteBuffer and clEnqueueWriteImage but each time it fails with the code CL_INVALID_VALUE which doesn't mean the same thing for all this functions. I verified some points but the application shows that th texture is known (clGetGLTextureInfo and clGetGLObjectInfo return the right texture ID and the right type : GL_TEXTURE_2D).

    I think I am wrong with the kind of memory the OpenCL handle to the texture is...

    Does someone have a sample code or any idea about this?

    Thank you!

  2. #2
    Senior Member
    Join Date
    May 2010
    Location
    Toronto, Canada
    Posts
    845

    Re: Grabbing image from OpenGL via OpenCL

    Could you show us the code that is returning CL_INVALID_VALUE? Say for instance when you use clEnqueueReadImage.
    Disclaimer: Employee of Qualcomm Canada. Any opinions expressed here are personal and do not necessarily reflect the views of my employer. LinkedIn profile.

  3. #3
    Junior Member
    Join Date
    Jul 2010
    Posts
    6

    Re: Grabbing image from OpenGL via OpenCL

    Ok, so let's go for some code :

    My initialisation first (in case of...)
    Code :
            // Get the number of plateforms
            cl_uint numPlatforms;
            errcode = clGetPlatformIDs(0, NULL, &numPlatforms);
            clErrorCodes(errcode);
     
            // The code will run on the same machine that does the compilation, I'm sure there will always be a single GPU
     
            // Get plateforms info
            platforms = new cl_platform_id[numPlatforms];
            errcode = clGetPlatformIDs(numPlatforms, platforms, NULL);
            clErrorCodes(errcode);
     
            if( NULL == (*platforms))
            {
                std::cout << "Failure!" << std::endl;
            }
     
            // Create a context to run OpenCL on our CUDA-enabled NVIDIA GPU
            cl_context_properties props[] =
            {
                CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(),
                CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(),
                CL_CONTEXT_PLATFORM, (cl_context_properties)(*platforms),
                0
            };
     
            theContext = clCreateContextFromType(props,targetDevice,NULL, NULL, &errcode);
     
            clErrorCodes(errcode);
     
            // Get the list of GPU devices associated with this context
            size_t ParmDataBytes;
            clGetContextInfo(theContext, CL_CONTEXT_DEVICES, 0, NULL, &ParmDataBytes);
            theDevice = new cl_device_id[ParmDataBytes];
            clGetContextInfo(theContext, CL_CONTEXT_DEVICES, ParmDataBytes, theDevice, NULL);
     
            // Create a command-queue on the first GPU device
            theCmdQueue = clCreateCommandQueue(theContext, theDevice[0], 0, &errcode);
            clErrorCodes(errcode);

    Then the code I'm using to read a valid OpenGL texture :
    Code :
    // prepare it first : (where glObject->getID() return the correct GLuint ID)
             clCreateFromGLTexture2D(HdlOCL::context(), CL_MEM_READ_WRITE, GL_TEXTURE_2D, 0, glObject->getID(), HdlOCL::errorFB());
             // returns CL_SUCCESS
     
    //grab the texture
             glFlush();
             HdlOCL::errorFB( clEnqueueAcquireGLObjects( HdlOCL::queue(), 1, &buffer, 0, 0, 0) );
             // returns CL_SUCCESS
     
    //Try to read it or write it
             HdlOCL::errorFB( clEnqueueReadBuffer( HdlOCL::queue(), buffer, CL_FALSE, 0, 1920*1080*3, ptr, 0, NULL, NULL) );
             //or HdlOCL::errorFB(clEnqueueWriteBuffer( HdlOCL::queue(), buffer, CL_FALSE, 0, 1920*1080*3, ptr, 0, NULL, NULL) );
             /* or 
             size_t origin[] = {0, 0, 0};
             size_t region[] = {1920, 1080, 1};
             HdlOCL::errorFB( clEnqueueReadImage(HdlOCL::queue(), buffer, CL_TRUE, origin, region, 0, 0, ptr, 0, 0, 0) );
             */
             /* or
             size_t origin[] = {0, 0, 0};
             size_t region[] = {1920, 1080, 1};
             HdlOCL::errorFB( clEnqueueWriteImage(HdlOCL::queue(), buffer, CL_TRUE, origin, region, 0, 0, ptr, 0, 0, 0) );
              */
              // each returns CL_INVALID_VALUE
     
    // Release it
             HdlOCL::errorFB( clEnqueueReleaseGLObjects( HdlOCL::queue(), 1, &buffer, 0, 0, 0) );
             clFinish(HdlOCL::queue());
             //returns CL_SUCCESS

    I also verified the information with the CL queries : clGetGLTextureInfo, clGetGLObjectInfo and I get the right values...

    Thanks for the help!

  4. #4
    Junior Member
    Join Date
    Jul 2010
    Posts
    6

    Re: Grabbing image from OpenGL via OpenCL

    I tried with a FBO (Texture -> FBO -> Texture) and it's a bit different.

    When trying to read in the FBO, clEnqueueReadBuffer returns CL_SUCCESS but writes only zeros in the host buffer (which was previously filled with a non-zero value!). And clEnqueueReadImage still fails with the same error code : CL_INVALID_VALUE.


  5. #5
    Senior Member
    Join Date
    May 2010
    Location
    Toronto, Canada
    Posts
    845

    Re: Grabbing image from OpenGL via OpenCL

    How did you create the GL texture? Is it possible that the dimensions of the texture are less than 1920x1080 or that the texel format is not RGB888? Try calling clEnqueueReadImage() passing a region of {1,1,1}.

    By the way, clEnqueue{Read,Write}Buffer() require a buffer object and you are passing an image. Stick to clEnqueue{Read,Write}Image() instead.
    Disclaimer: Employee of Qualcomm Canada. Any opinions expressed here are personal and do not necessarily reflect the views of my employer. LinkedIn profile.

  6. #6
    Junior Member
    Join Date
    Jul 2010
    Posts
    6

    Re: Grabbing image from OpenGL via OpenCL

    Thanks for the answer. I tried with clEnqueueReadImage() and {1, 1, 1} and I also verified the texture informations... But everything seems correct and I have still the same error CL_INVALID_VALUE.

    I found someone having the same problem on the Nvidia forums... it could be a drivers problem... but still not sure

  7. #7
    Senior Member
    Join Date
    Nov 2009
    Posts
    118

    Re: Grabbing image from OpenGL via OpenCL

    I guess it's a driver bug. You should post a bug report.

Similar Threads

  1. OpenCL 1.2 2D image array
    By Bacterius in forum OpenCL
    Replies: 2
    Last Post: 01-04-2013, 05:36 PM
  2. Grabbing image from canvas
    By onorinbejasus in forum Developers Coding:Advanced
    Replies: 1
    Last Post: 01-20-2012, 02:49 AM
  3. How to draw an image from openCL?
    By Noidea in forum OpenCL
    Replies: 4
    Last Post: 07-12-2011, 01:05 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •