Search code examples
openglcudatextures

Direct write to OpenGL default BackBuffer's ColorAttachment(GL_BACK) by CUDA from kernel


Is it possible to directly write to OpenGL default BackBuffer's ColorAttachment(GL_BACK) from a CUDA kernel?

So instead of copying the data back to the CPU and then sending back to the device to render as a texture, I could just access the buffer directly in my kernel?

Thanks!


Solution

  • Your best bet is to write to a buffer/texture from a CUDA kernel (like @BDL suggested in his comment) and then render that texture as a quad on the framebuffer.
    Directly writing to the color framebuffer in a portable way might not be possible because each GPU can use different settings to represent the image stored in the framebuffer (color encoding format, data layout) for performance reasons.
    You might be able to write or blit the texture directly to the framebuffer on certain GPUs but this might force OpenGL to use an image layout that is not optimal.

    I think that writing from CUDA to a OpenGL buffer/texture and then rendering that texture to a fullscreen quad might be the fastest way as you would avoid copying the image to the CPU and back to the GPU (that is the bottleneck in this case).

    thanks! and Texture is the fastest way? how about PBO or RenderBuffer?

    Texture would be the fastest way as you can sample quads of pixels very fast due to how the GPU stores textures in memory. I think CUDA has some functions to read and write to/from textures.

    for "..." aren't all the setting including(color encoding format, data layout) set by developer in code? What if it was able to set both them and the format for CUDA and Make them the same, would it then faster by direct to GL_BACK if possible?

    In OpenGL you can't (as far as i know) pick the specific memory layout of a texture (not sure about the color format). When you create a texture the data is uploaded to the GPU and then OpenGL (or the driver) uses the fastest format for the texture (this is why you can't read textures as a buffer and you have to use imageLoad/imageStore).

    If you managed to pick the color format and memory layout of the backbuffer by hand then you might be able to blit the image (that you would need to store in a buffer to have a predictable memory layout) directly to the backbuffer.
    The operations would be something like:

    • set the backbuffer with RGB format and layout LINEAR (one pixel after another line after line)
    • write to the buffer (with the same format) from CUDA
    • copy the buffer to the backbuffer.

    This also means that you would not have a portable program as some GPUs may not support that specific format or it might be not optimal.

    I did something similar to this with the Vulkan API and i had to enable extensions and select color format and memory layout by hand between those formats that supported writing directly to the backbuffer.