Two Tips on OpenCL-OpenGL Interoperability

>> Monday, May 28, 2012

I thought I'd share two points related to coding OpenCL-OpenGL applications:

  1. Combine shared data into as few buffers as possible and combine them into an array or vector.

    It takes time for the CPU to coordinate the GPU's OpenCL/OpenGL processing, so it's good to keep this to a minimum. More specifically, you want to call clEnqueueAcquireGLObjects as few times as possible. This function can synchronize multiple buffers with a single call, but only if they're placed in contiguous memory locations (such as inside an array or a vector).

    For example, the following code creates and synchronizes two distinct buffers:
    GLuint vbos[2];
    cl_mem buff_1, buff_2;
    ...
    glGenBuffers(2, vbos);
    ...
    buff_1 = clCreateFromGLBuffer(context, CL_MEM_WRITE_ONLY, vbos[0], &err);
    buff_2 = clCreateFromGLBuffer(context, CL_MEM_WRITE_ONLY, vbos[1], &err);
    ...
    clEnqueueAcquireGLObjects(queue, 1, &buff_1, 0, NULL, NULL);
    clEnqueueAcquireGLObjects(queue, 1, &buff_2, 0, NULL, NULL);
    ...
    clEnqueueReleaseGLObjects(queue, 1, &buff_1, 0, NULL, NULL);
    clEnqueueReleaseGLObjects(queue, 1, &buff_2, 0, NULL, NULL);
    ...
    In contrast, this code creates and synchronizes two buffers in an array:
    GLuint vbos[2];
    cl_mem buffs[2];
    ...
    glGenBuffers(2, vbos);
    ...
    buffs[0] = clCreateFromGLBuffer(context, CL_MEM_WRITE_ONLY, vbos[0], &err);
    buffs[1] = clCreateFromGLBuffer(context, CL_MEM_WRITE_ONLY, vbos[1], &err);
    ...
    clEnqueueAcquireGLObjects(queue, 2, buffs, 0, NULL, NULL);
    ...
    clEnqueueReleaseGLObjects(queue, 2, buffs, 0, NULL, NULL);
    ...
    The second example is simpler because it only calls clEnqueueAcquireGLObjects once. This reduces the synchronization time required for OpenCL-OpenGL interoperability.

  2. Place OpenCL and OpenGL function calls in separate classes.

    My C++/Qt project has become very complex, and if I placed all the OpenCL/OpenGL function calls in the same class, it would be impossible to read. So, in addition to my GLWidget class, I created two helper classes: GLUtils and CLUtils. The first contains static functions related to OpenGL and the second contains static functions related to OpenCL.

    These classes are friends of the GLWidget class, which means they can access its private resources. This separation has made my code easier to read and debug.
On an unrelated note, the AMD Fusion Developer Summit is two weeks away, but the agenda doesn't say anything about the session topics. Does AMD think people are going to attend without knowing what's going to be discussed? It's like advertising a rock concert without telling people who's playing.

0 comments:

Post a Comment

  © Blogger template Werd by Ourblogtemplates.com 2009

Back to TOP