通过曲面写入CUDA中的浮点OpenGL纹理

时间:2015-01-02 12:01:52

标签: c++ opengl cuda interop textures

我正在编写一个OpenGL / CUDA(6.5)互操作应用程序。我尝试通过CUDA内核中的表面引用将浮点值写入OpenGL纹理时出现编译时错误。

这里我给出了如何设置互操作的高级描述,但是我在CUDA内核中成功地读取了我的纹理,所以我相信这是正确完成的。我有一个用

声明的OpenGL纹理
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB32F_ARB, 512, 512, 0, GL_RGB, GL_FLOAT, NULL);

创建纹理后,我设置了cudaGraphicsGLRegisterImage来调用cudaGraphicsRegisterFlagsSurfaceLoadStore。在运行我的CUDA内核之前,我取消绑定纹理并对从cudaGraphicsMapResources获得的cudaGraphicsResource指针调用cudaGraphicsGLRegisterImage。然后我从cudaArray获得cudaGraphicsSubResourceGetMappedArray,为数组创建适当的资源描述符,并调用cudaCreateSurfaceObject以获取指向cudaSurfaceObject_t的指针。然后我使用cudaMemcpy调用cudaMemcpyHostToDevicecudaSurfaceObject_t复制到cudaMalloc分配的设备上的缓冲区。

在我的CUDA内核中,我可以使用类似的东西从表面引用中读取,并且我已经验证了这是按预期工作的。

__global__ void cudaKernel(cudaSurfaceObject_t tex) {
    int x = blockIdx.x*blockDim.x + threadIdx.x;
    int y = blockIdx.y*blockDim.y + threadIdx.y;
    float4 sample = surf2Dread<float4>(tex, (int)sizeof(float4)*x, y, cudaBoundaryModeClamp);

在内核中我想修改样本并将其写回纹理。 GPU具有5.0的计算能力,因此这应该是可能的。我正在尝试这个

surf2Dwrite<float4>(sample, tex, (int)sizeof(float4)*x, y, cudaBoundaryModeClamp);

但我收到错误:

error: no instance of overloaded function "surf2Dwrite" matches the argument list
argument types are: (float4, cudaSurfaceObject_t, int, int, cudaSurfaceBoundaryMode)

我可以在

中看到
cuda-6.5/include/surface_functions.h

只有surf2Dwrite的整数版本的原型才接受第二个参数的void *。我确实看到surf2Dwrite的原型接受带有模板化float4对象的surface,但是,我不确定如何使用OpenGL互操作声明模板surface对象。我还没有找到关于如何做到这一点的任何其他事情。任何帮助表示赞赏。感谢。

3 个答案:

答案 0 :(得分:1)

事实证明答案很简单,但我不知道它为什么会起作用。而不是打电话

surf2Dwrite<float4>(sample, tex, (int)sizeof(float4)*x, y, cudaBoundaryModeClamp);

我需要致电

surf2Dwrite(sample, tex, (int)sizeof(float4)*x, y, cudaBoundaryModeClamp);

说实话,我不确定我是否完全理解CUDA在c ++中使用模板。有人有解释吗?

答案 1 :(得分:0)

CUDA Documentation中,这是表面模板函数的定义:

template<class T>
T surf2Dread(cudaSurfaceObject_t surfObj,
              int x, int y,
              boundaryMode = cudaBoundaryModeTrap);

template<class T>
void surf2Dread(T* data,
                 cudaSurfaceObject_t surfObj,
                 int x, int y,
                 boundaryMode = cudaBoundaryModeTrap);

答案 2 :(得分:-1)

有关CUDA写入链接到OpenGL纹理的曲面的完整示例,请参阅此项目:

https://github.com/nvpro-samples/gl_cuda_interop_pingpong_st