我正在编写一个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
调用cudaMemcpyHostToDevice
将cudaSurfaceObject_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
对象。我还没有找到关于如何做到这一点的任何其他事情。任何帮助表示赞赏。感谢。
答案 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