在OpenGL和CUDA之间共享纹理

3
我将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));

这段代码运行良好,device_ptr不是指向我的CUDA内存的指针。现在,在某个时间点上,我想使用双线性插值重新采样这个图像。在CUDA中,似乎最好的方法是将设备数据映射到CUDA纹理内存,然后使用tex2D调用执行插值。
现在,我的问题是,成像数据已经存在于OpenGL纹理内存中,我想知道是否有一种方法可以避免再次调用cudaBindTexture2D,并以某种方式在CUDA中使用OpenGL纹理进行此插值?

为什么 device_ptr 不是一个指向 CUDA 内存的指针?调用 cudaGraphicsResourceGetMappedPointer 后,您应该能够将其视为指向设备内存上数组的指针,并启动核函数来执行插值。插值完成后,您只需要调用 cudaGraphicsUnmapResources(1, &cgr, 0) 就可以通过 OpenGL 显示它了。 - mty
当然可以,但我能用它来执行使用tex2D调用的纹理插值吗?我需要像常规CUDA内存一样将其映射到纹理上才能进行插值吗? - Luca
1个回答

7

你可以直接使用tex2D读写OpenGL纹理。

  1. Initialize graphic ressource

    struct cudaGraphicsResource *vbo_res;
    cudaGraphicsGLRegisterImage(&vbo_res, gl_buffer,gl_target, cudaGraphicsRegisterFlagsSurfaceLoadStore);
    
  2. Map ressource to array (every frame)

    cudaArray *array;
    cudaGraphicsMapResources(1, &vbo_res, 0);
    cudaGraphicsSubResourceGetMappedArray(&array, vbo_res, 0,0);
    
  3. Bind texture to array

    texture<uchar4, cudaTextureType2D, cudaReadModeNormalizedFloat> texRef;
    cudaBindTextureToArray(texRef, (cudaArray *)array));
    texRef.filterMode = cudaFilterModeLinear;
    
注意:
如果 texRef 存储在全局内存中,则可以使用 float4 rgba = tex2D( texRef, u,v); 在 CUDA 内核中访问它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接