我正在 CUDA 中编写一个渲染系统,并希望通过 OpenGL 快速显示结果,而无需触及主内存。我基本上做以下事情:
创建并初始化 OpenGL 纹理,并在 CUDA 中注册为 cudaGraphicsResource
GLuint viewGLTexture;
cudaGraphicsResource_t viewCudaResource;
void initialize() {
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &viewGLTexture);
glBindTexture(GL_TEXTURE_2D, viewGLTexture);
{
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, view.getWidth(), view.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
glBindTexture(GL_TEXTURE_2D, 0);
cudaGraphicsGLRegisterImage(&viewCudaResource, viewGLTexture, GL_TEXTURE_2D, cudaGraphicsRegisterFlagsWriteDiscard)
}
每当调整视图大小时,我都会适当地调整视口和纹理图像的大小:
void resize() {
glViewport(0, 0, view.getWidth(), view.getHeight());
glBindTexture(GL_TEXTURE_2D, viewGLTexture);
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view.getWidth(), view.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
glBindTexture(GL_TEXTURE_2D, 0);
}
然后每一帧我通过 cudaArray 将 graphicsResource 映射为 cudaSurfaceObject,在其上调用渲染内核,取消映射并同步以让 OpenGL 使用此纹理绘制一个全屏四边形:
void renderFrame() {
cudaGraphicsMapResources(1, &viewCudaResource);
{
cudaArray_t viewCudaArray;
cudaGraphicsSubResourceGetMappedArray(&viewCudaArray, viewCudaResource, 0, 0);
cudaResourceDesc viewCudaArrayResourceDesc;
{
viewCudaArrayResourceDesc.resType = cudaResourceTypeArray;
viewCudaArrayResourceDesc.res.array.array = viewCudaArray;
}
cudaSurfaceObject_t viewCudaSurfaceObject;
cudaCreateSurfaceObject(&viewCudaSurfaceObject, &viewCudaArrayResourceDesc);
{
invokeRenderingKernel(viewCudaSurfaceObject);
}
cudaDestroySurfaceObject(viewCudaSurfaceObject));
}
cudaGraphicsUnmapResources(1, &viewCudaResource);
cudaStreamSynchronize(0);
glBindTexture(GL_TEXTURE_2D, viewGLTexture);
{
glBegin(GL_QUADS);
{
glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f(+1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f(+1.0f, +1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, +1.0f);
}
glEnd();
}
glBindTexture(GL_TEXTURE_2D, 0);
glFinish();
}
问题是:每当调整视图大小时,所有 CUDA 调用都会开始喷出“未知错误”,并且在视觉上看起来纹理实际上并未调整大小,只是在整个视图中拉伸。为什么会发生这种情况,我该如何解决?