【问题标题】:CUDA/OpenGL interop, draw to OpenGL texture with CUDACUDA/OpenGL 互操作,使用 CUDA 绘制到 OpenGL 纹理
【发布时间】:2013-10-15 04:03:02
【问题描述】:

我正在用 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 调用都会开始喷出“未知错误”,并且在视觉上看起来纹理实际上并未调整大小,只是在整个视图中拉伸。为什么会发生这种情况,我该如何解决?

【问题讨论】:

    标签: opengl cuda interop


    【解决方案1】:

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

    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);
    }
    

    【讨论】:

      猜你喜欢
      • 2011-09-22
      • 2011-12-03
      • 2013-04-30
      • 2013-04-04
      • 2011-10-13
      • 1970-01-01
      • 2016-01-25
      • 2011-07-23
      • 2020-12-22
      相关资源
      最近更新 更多