opengl - CUDA/OpenGL 互操作,使用 CUDA 绘制到 OpenGL 纹理

标签 opengl cuda interop

我正在 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)
}

每当调整 View 大小时,我都会适本地调整视口(viewport)和纹理图像的大小:
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();
}

问题是:每当调整 View 大小时,所有 CUDA 调用都会开始喷出“未知错误”,并且在视觉上看起来纹理实际上并未调整大小,只是在整个 View 中拉伸(stretch)。为什么会发生这种情况,我该如何解决?

最佳答案

似乎互操作需要在调整大小时重新注册纹理。以下作品:

void resize() {
    glViewport(0, 0, view.getWidth(), view.getHeight());

        // unregister
    cudaGraphicsUnregisterResource(viewCudaResource);
        // resize
    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);
        // register back
    cudaGraphicsGLRegisterImage(&viewCudaResource, viewGLTexture, GL_TEXTURE_2D, cudaGraphicsRegisterFlagsWriteDiscard);
}

关于opengl - CUDA/OpenGL 互操作,使用 CUDA 绘制到 OpenGL 纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19244191/

相关文章:

c++ - 为什么我的 glBindBufferRange 偏移对齐不正确?

python - 如何在 PyOpenGL 中旋转某个对象(Quad)?

cuda - 使用多个 CUDA GPU

OpenGL - FPS 风格相机移动,物体固定在相机上

opengl - 在openGL中重新编译着色器

c++ - 转换为 void 的双指针地址**

pytorch - 为什么即使我将可见 CUDA 设置为 2,DDP 中的 `local_rank` 仍为零?

c# - 创建并保存 Excel 文件

c# - 来自 System.Windows.Forms 的 AccessViolationException,在 WPF 中使用 WinFormsHost

PHP:从非 native 数组返回值?