OpenCL and OpenGL interop

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

OpenCL and OpenGL interop

askoh
Administrator
Feel free to ask these questions on-list; others might be interested.

On Jun 6, 2010, at 7:20 PM, askoh@askoh.com wrote:

> Josh:
>
> I would like to use OpenCL and OpenGL interop where they share buffers
> for graphics.

That would be great!


> Anything to prevent that now?

Yes, some work still needs to be done, but nothing too difficult.


> What needs to be done?

In order to share buffers with OpenGL, the OpenCL context-creation function needs to be passed a handle to the OpenGL context. Unfortunately, if you're using the Croquet-OpenGL bindings, the context is not readily accessible... a primitive in the B3DAcceleratorPlugin (#primCreateRenderer:x:y:w:h:) abstracts away context-creation (hiding whether the renderer uses Direct3D or OpenGL, and other messy stuff, eg: on some platforms creating a child window for the OpenGL context to draw into). After all of this, it returns an integer that acts as a Squeak-specific handle to the renderer.

In short, what needs to be done is to obtain the pointer. This will require modifications to the B3DAcceleratorPlugin. The easiest thing to do would be to add another primitive that takes the integer renderer-handle and returns a pointer (possibly as an ExternalAddress?) to the OpenGL context. This can then be passed to clCreateContext(). I haven't added convenience methods to use clCreateContext() in such a fashion, but this should be a straightforward extension of my existing code (feel free to ask more questions if this isn't clear).

Of course, if you get this working, I'll be glad to integrate any patches you provide, and to help you bug the VM people to integrate it as well.

Cheers,
Josh



>
> Thanks,
> Aik-Siong
>
Reply | Threaded
Open this post in threaded view
|

Re: OpenCL and OpenGL interop

askoh
Administrator
Since Squeak/OpenCL uses FFI, can we use FFI for OpenGL also and code everything like the C examples that Nvidia provides?

Thanks,
Aik-Siong Koh
Reply | Threaded
Open this post in threaded view
|

Re: OpenCL and OpenGL interop

Josh Gargus
In reply to this post by askoh
In case it wasn't clear, Aik-Siong forwarded this private correspondence after I suggested that others might be interested.

Cheers,
Josh



On Jun 7, 2010, at 7:31 AM, askoh wrote:

>
> Feel free to ask these questions on-list; others might be interested.
>
> On Jun 6, 2010, at 7:20 PM, [hidden email] wrote:
>
>> Josh:
>>
>> I would like to use OpenCL and OpenGL interop where they share buffers
>> for graphics.
>
> That would be great!
>
>
>> Anything to prevent that now?
>
> Yes, some work still needs to be done, but nothing too difficult.
>
>
>> What needs to be done?
>
> In order to share buffers with OpenGL, the OpenCL context-creation function
> needs to be passed a handle to the OpenGL context. Unfortunately, if you're
> using the Croquet-OpenGL bindings, the context is not readily accessible...
> a primitive in the B3DAcceleratorPlugin (#primCreateRenderer:x:y:w:h:)
> abstracts away context-creation (hiding whether the renderer uses Direct3D
> or OpenGL, and other messy stuff, eg: on some platforms creating a child
> window for the OpenGL context to draw into). After all of this, it returns
> an integer that acts as a Squeak-specific handle to the renderer.
>
> In short, what needs to be done is to obtain the pointer. This will require
> modifications to the B3DAcceleratorPlugin. The easiest thing to do would be
> to add another primitive that takes the integer renderer-handle and returns
> a pointer (possibly as an ExternalAddress?) to the OpenGL context. This can
> then be passed to clCreateContext(). I haven't added convenience methods to
> use clCreateContext() in such a fashion, but this should be a
> straightforward extension of my existing code (feel free to ask more
> questions if this isn't clear).
>
> Of course, if you get this working, I'll be glad to integrate any patches
> you provide, and to help you bug the VM people to integrate it as well.
>
> Cheers,
> Josh
>
>
>
>>
>> Thanks,
>> Aik-Siong
>>
>
> --
> View this message in context: http://forum.world.st/OpenCL-and-OpenGL-interop-tp2246017p2246017.html
> Sent from the Squeak - Dev mailing list archive at Nabble.com.
>


Reply | Threaded
Open this post in threaded view
|

Re: OpenCL and OpenGL interop

Josh Gargus
In reply to this post by askoh
On Jun 7, 2010, at 7:42 AM, askoh wrote:

>
> Since Squeak/OpenCL uses FFI, can we use FFI for OpenGL also and code
> everything like the C examples that Nvidia provides?

I'm not quite sure what you're getting at... Croquet-OpenGL does use the FFI for everything except for a few things such as initial context-creation, making a context current, and buffer swapping.  Everything else is accessible via FFI.

Are you talking about coding "closer to the metal" than using Croquet's higher level classes such as TFrame and TTexture?  There's no reason why this couldn't be done... these higher level classes are implemented using OpenGL FFI calls, and anyone can write an application that completely ignores these and calls the OpenGL FFI calls directly.

Or perhaps I'm missing the point of your question?

Cheers,
Josh



>
> Thanks,
> Aik-Siong Koh
> --
> View this message in context: http://forum.world.st/OpenCL-and-OpenGL-interop-tp2246017p2246036.html
> Sent from the Squeak - Dev mailing list archive at Nabble.com.
>


Reply | Threaded
Open this post in threaded view
|

Re: OpenCL and OpenGL interop

askoh
Administrator
The following code is from Nvidia example oclSimpleGL_vc9.sln
Can we create the following code in Squeak without creating primitives?

Thanks,
Aik-Siong Koh

void createVBO(GLuint* vbo)
{
    // create VBO
    unsigned int size = mesh_width * mesh_height * 4 * sizeof(float);
    if(!bQATest)
    {
        // create buffer object
        glGenBuffers(1, vbo);
        glBindBuffer(GL_ARRAY_BUFFER, *vbo);

        // initialize buffer object
        glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW);

        #ifdef GL_INTEROP
            // create OpenCL buffer from GL VBO
            vbo_cl = clCreateFromGLBuffer(cxGPUContext, CL_MEM_WRITE_ONLY, *vbo, NULL);
        #else
            // create standard OpenCL mem buffer
            vbo_cl = clCreateBuffer(cxGPUContext, CL_MEM_WRITE_ONLY, size, NULL, &ciErrNum);
        #endif
        shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup);
    }
    else
    {
        // create standard OpenCL mem buffer
        vbo_cl = clCreateBuffer(cxGPUContext, CL_MEM_WRITE_ONLY, size, NULL, &ciErrNum);
        shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup);
    }
}
Reply | Threaded
Open this post in threaded view
|

Re: OpenCL and OpenGL interop

Josh Gargus
On Jun 7, 2010, at 11:39 AM, askoh wrote:

>
> The following code is from Nvidia example oclSimpleGL_vc9.sln
> Can we create the following code in Squeak without creating primitives?
>

Ah, I see what you're getting at.  The answer is "yes and no".  As I said before, in order to have OpenCL/OpenGL compatibility, you need to create an OpenCL context that refers to the OpenGL context that it wishes to share with (see Section 9.11 of the OpenCL specification: "Creating CL context from a GL context or share group").  The hitch is that we don't have easy access to the OpenGL context created by Croquet-OpenGL (a new B3DAcceleratorPlugin primitive is required).

Once you have obtained the OpenGL context handle and used it to create a new OpenCL context, you can directly transcribe the code below into Squeak using only FFI calls.

Cheers,
Josh




> Thanks,
> Aik-Siong Koh
>
> void createVBO(GLuint* vbo)
> {
>    // create VBO
>    unsigned int size = mesh_width * mesh_height * 4 * sizeof(float);
>    if(!bQATest)
>    {
>        // create buffer object
>        glGenBuffers(1, vbo);
>        glBindBuffer(GL_ARRAY_BUFFER, *vbo);
>
>        // initialize buffer object
>        glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW);
>
>        #ifdef GL_INTEROP
>            // create OpenCL buffer from GL VBO
>            vbo_cl = clCreateFromGLBuffer(cxGPUContext, CL_MEM_WRITE_ONLY,
> *vbo, NULL);
>        #else
>            // create standard OpenCL mem buffer
>            vbo_cl = clCreateBuffer(cxGPUContext, CL_MEM_WRITE_ONLY, size,
> NULL, &ciErrNum);
>        #endif
>        shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup);
>    }
>    else
>    {
>        // create standard OpenCL mem buffer
>        vbo_cl = clCreateBuffer(cxGPUContext, CL_MEM_WRITE_ONLY, size, NULL,
> &ciErrNum);
>        shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup);
>    }
> }
>
> --
> View this message in context: http://forum.world.st/OpenCL-and-OpenGL-interop-tp2246017p2246383.html
> Sent from the Squeak - Dev mailing list archive at Nabble.com.
>


Reply | Threaded
Open this post in threaded view
|

Re: OpenCL and OpenGL interop

askoh
Administrator
Do we really need a primitive to do the following? AS

                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)cpPlatform,
                    0
                };
                cxGPUContext = clCreateContext(props, 1, &cdDevices[uiDeviceUsed], NULL, NULL, &ciErrNum);
Reply | Threaded
Open this post in threaded view
|

Re: OpenCL and OpenGL interop

Josh Gargus
Ah, you've got me there (I don't really use WGL directly).  You should be able to do that without any new primitives.

Cheers,
Josh


On Jun 7, 2010, at 1:15 PM, askoh wrote:

>
> Do we really need a primitive to do the following? AS
>
>                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)cpPlatform,
>                    0
>                };
>                cxGPUContext = clCreateContext(props, 1,
> &cdDevices[uiDeviceUsed], NULL, NULL, &ciErrNum);
>
> --
> View this message in context: http://forum.world.st/OpenCL-and-OpenGL-interop-tp2246017p2246493.html
> Sent from the Squeak - Dev mailing list archive at Nabble.com.
>


Reply | Threaded
Open this post in threaded view
|

Re: OpenCL and OpenGL interop

askoh
Administrator
I am curious why Croquet uses a primitive to create an opengl context
instead of a straight call to wglGetCurrentContext()?
Aik-Siong
 
On Mon, 7 Jun 2010 13:28:11 -0700 (PDT), "Josh Gargus [via Smalltalk]"  wrote:
Ah, you've got me there (I don't really use WGL directly).  You should
be able to do that without any new primitives.
  >
  > Cheers,
  > Josh
  >

Reply | Threaded
Open this post in threaded view
|

Re: OpenCL and OpenGL interop

Josh Gargus
wglGetCurrentContext() does not create a context, it merely answers the context that was most recently made current.  

Take a peek in sqWin32OpenGL.c in the B3DAcceleratorPlugin source code.  It's hiding a lot of tedious stuff; "creating a context" is about a lot more than wrapping a single API call.  The B3D plugin nicely abstracts this away so you can use the same setup code across platforms (and can also use Direct 3D as a backend, although Croquet-OpenGL doesn't use this).

Cheers,
Josh


On Jun 7, 2010, at 8:50 PM, askoh wrote:

I am curious why Croquet uses a primitive to create an opengl context
instead of a straight call to wglGetCurrentContext()?
Aik-Siong
 
On Mon, 7 Jun 2010 13:28:11 -0700 (PDT), "Josh Gargus [via Smalltalk]"  wrote:
Ah, you've got me there (I don't really use WGL directly).  You should
be able to do that without any new primitives.
  >
  > Cheers,
  > Josh
  >



View this message in context: Re: OpenCL and OpenGL interop
Sent from the Squeak - Dev mailing list archive at Nabble.com.