在OpenGL和CUDA之间共享纹理

Luc*_*uca 1 opengl cuda

我在OpenGL和CUDA之间共享数据,如下所示:

GLuint buffer;
glGenBuffers(1, &buffer);
// Some image is bound to this texture buffer at some point.
...
cudaGraphicsResource_t cgr;
checkCudaErrors(cudaGraphicsGLRegisterBuffer(&cgr, 
                buffer, cudaGraphicsRegisterFlagsNone));
checkCudaErrors(cudaGraphicsMapResources(1, &cgr, 0));
uchar4 * device_ptr = 0;
size_t num_bytes;
checkCudaErrors(cudaGraphicsResourceGetMappedPointer(
               (void **)&device_ptr, &num_bytes, cgr));
Run Code Online (Sandbox Code Playgroud)

这可以正常工作,并且device_ptr不是指向我的CUDA内存的指针。现在,在某些时候,我想使用双线性插值对该图像进行重新采样。似乎在CUDA中执行此操作的首选方法是将设备数据映射到CUDA纹理内存,然后使用tex2D调用执行插值。

现在,我的问题是成像数据已经存在于OpenGL纹理内存中,我想知道是否有一种方法可以避免再次调用cudaBindTexture2D并以某种方式在CUDA中使用OpenGL纹理进行插值?

dar*_*ari 5

是的,您可以使用tex2D直接读取/写入opengl纹理。

  1. 初始化图形资源

    struct cudaGraphicsResource *vbo_res;
    cudaGraphicsGLRegisterImage(&vbo_res, gl_buffer,gl_target, cudaGraphicsRegisterFlagsSurfaceLoadStore);
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将资源映射到数组(每帧)

    cudaArray *array;
    cudaGraphicsMapResources(1, &vbo_res, 0);
    cudaGraphicsSubResourceGetMappedArray(&array, vbo_res, 0,0);
    
    Run Code Online (Sandbox Code Playgroud)
  3. 将纹理绑定到数组

    texture<uchar4, cudaTextureType2D, cudaReadModeNormalizedFloat> texRef;
    cudaBindTextureToArray(texRef, (cudaArray *)array));
    texRef.filterMode = cudaFilterModeLinear;
    
    Run Code Online (Sandbox Code Playgroud)

注意:

如果texRef驻留在全局内存中,则可以使用以下命令在cuda内核中进行访问:float4 rgba = tex2D( texRef, u,v);