与表面对象(Cuda/OpenGL互操作)错位的错误
问题描述:
我目前正试图在我的项目上互操作Cuda和OpenGL,但它证明是一项具有挑战性的任务。我目前使用下面的代码:与表面对象(Cuda/OpenGL互操作)错位的错误
GLuint _frameTextureGL;
cudaGraphicsResource_t _frameTextureCUDA;
void GLInit(){
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &_frameTextureGL);
glBindTexture(GL_TEXTURE_2D, _frameTextureGL);
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, RES_X, RES_Y, 0, GL_RGBA, GL_FLOAT, NULL);
}
glBindTexture(GL_TEXTURE_2D, 0);
CudaErrorCheck(cudaGraphicsGLRegisterImage(&_frameTextureCUDA, _frameTextureGL, GL_TEXTURE_2D, cudaGraphicsRegisterFlagsWriteDiscard));
}
void DrawFrame(){
LaunchKernel();
glBindTexture(GL_TEXTURE_2D, _frameTextureGL);
{
glBegin(GL_QUADS);
{
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(0.0f, 1.0f);
}
glEnd();
}
glBindTexture(GL_TEXTURE_2D, 0);
glFinish();
glutPostRedisplay();
}
LaunchKernel(){
CudaErrorCheck (cudaGraphicsMapResources(1, &_frameTextureCUDA)); //error happens here
cudaArray_t frameCudaArray;
CudaErrorCheck(cudaGraphicsSubResourceGetMappedArray(&frameCudaArray, _frameTextureCUDA, 0, 0));
cudaResourceDesc frameCudaArrayResourceDesc;
frameCudaArrayResourceDesc.resType = cudaResourceTypeArray;
frameCudaArrayResourceDesc.res.array.array = frameCudaArray;
cudaSurfaceObject_t frameCudaSurfaceObject;
CudaErrorCheck(cudaCreateSurfaceObject(&frameCudaSurfaceObject, &frameCudaArrayResourceDesc));
KernelFunction<< <(RES_X * RES_Y/CUDA_THREADS_PER_BLOCK) + 1, CUDA_THREADS_PER_BLOCK >> >(frameCudaSurfaceObject);
CudaErrorCheck(cudaDestroySurfaceObject(frameCudaSurfaceObject));
CudaErrorCheck(cudaGraphicsUnmapResources(1, &_frameTextureCUDA));
cudaStreamSynchronize(0);
}
__global__ void KernelFunction(cudaSurfaceObject_t frameCudaSurfaceObject){
const int maxIndex = RES_X * RES_Y;
int idx = threadIdx.x + blockDim.x * blockIdx.x;
if (idx > maxIndex) return;
surf2Dwrite(make_float4(1.0f, 0.0f, 0.0f, 1.0f), frameCudaSurfaceObject, 0, 0);
//surf2Dwrite(make_float4(1.0f, 0.0f, 0.0f, 1.0f), frameCudaSurfaceObject, (idx % RES_X) * 4, idx/RES_X);
}
的问题是,在内核中的surf2Dwrite会导致我的代码的其他地方得到一个错误。
随着它的当前状态的代码我的项目运行,但它不显示任何东西(我认为是正常的,因为我没有正确填充表面对象)。但是,如果我将X坐标改变为除(0,0)以外的任何东西(例如通过取消注释最后一行),则会在LaunchKernel函数的第一行中得到一个“未对齐的错误”。 (这个错误只显示在第二帧,而不是第一帧)
我已经根据我的代码this other answer,所以我认为这部分是正确的。
答
表面使用以字节为单位的坐标,而不是在元素中。对于float4
x坐标应该是x * 16
(或x * sizeof(float4)
),不x * 4
:
surf2Dwrite(make_float4(1.0f, 0.0f, 0.0f, 1.0f), frameCudaSurfaceObject,
(idx % RES_X) * sizeof(float4), idx/RES_X);
谢谢,这似乎修复错误。我改变了我的纹理使用GL_UNSIGNED_BYTE,并改变surf2Dwrite只使用4个字节。除了黑色窗户,我还看不到其他任何东西,但这是另一个问题。 – Duolasa 2014-10-29 12:42:33
如果将来有人想要使用此代码,我通过调整glVertex2f的坐标到窗口resultion而不是使用1来解决黑窗问题。 – Duolasa 2014-10-29 13:18:04