opengl - CUDA OpenGL 互操作,资源映射弄乱了缓冲区

标签 opengl cuda

我最近开始编写 CUDA OpenGL 互操作性代码。大部分时间我都在 Linux 环境中进行开发。尝试将我的代码传输到运行 OS X 的 MacBook Pro 时,我遇到了以下问题:

每当我将 OpenGL 的顶点缓冲区对象作为资源映射到 CUDA 时,它会弄乱存储在相应缓冲区中的数据。

这是我的代码:

// OpenGL and window handler includes
#include <GL/glew.h>
#include <SDL/SDL.h>
#include <OpenGL/GL.h>

// OpenGL/CUDA interop
#include <cuda_runtime.h>
#include <cuda_gl_interop.h>

// C libraries
#include <iostream>

int main(int argc, char* argv[])
{
    GLuint vbo;
    struct cudaGraphicsResource *cuda_vbo_resource;

    // create OpenGL context with SDL
    SDL_Init(SDL_INIT_VIDEO);
    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
    SDL_SetVideoMode( 400, 200, 16, SDL_OPENGL);

    // initialize extension wrangler
    glewInit();

    // set cuda/GL device
    cudaGLSetGLDevice(0);

    // generate buffer
    glGenBuffers(1, &vbo);

    // fill buffer with data (1, 2, 3)
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    int inData[] = {1,2,3};
    glBufferData(GL_ARRAY_BUFFER, 3*sizeof(int), inData, GL_DYNAMIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // Register buffer with cuda
    cudaGraphicsGLRegisterBuffer(&cuda_vbo_resource, vbo,             
                                        cudaGraphicsMapFlagsWriteDiscard);

    // let's have a look at the buffer
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    int* mappedBuffer = (int *) glMapBuffer(GL_ARRAY_BUFFER,GL_READ_ONLY);
    printf("\tbefore mapping: %d, %d, %d\n",mappedBuffer[0], mappedBuffer[1], 
            mappedBuffer[2]);
    glUnmapBuffer(GL_ARRAY_BUFFER);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // map and unmap the cuda resource
    if (cudaGraphicsMapResources(1, &cuda_vbo_resource, 0) != cudaSuccess)
        printf("Resource mapping failed...\n");
    if (cudaGraphicsUnmapResources(1, &cuda_vbo_resource, 0) != cudaSuccess)
        printf("Resource unmapping failed...\n");

    // let's have a look at the buffer again
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    mappedBuffer = (int *) glMapBuffer(GL_ARRAY_BUFFER,GL_READ_ONLY);
    printf("\tafter mapping: %d, %d, %d\n",mappedBuffer[0], mappedBuffer[1], 
            mappedBuffer[2]);
    glUnmapBuffer(GL_ARRAY_BUFFER);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // unregister the cuda resource
    cudaGraphicsUnregisterResource(cuda_vbo_resource);

    // delete the buffer
    glBindBuffer(1, vbo);
    glDeleteBuffers(1, &vbo);

    return 0;
}

编译后:

g++ -o resourceMapping resourceMapping.cpp `sdl-config --cflags --libs` -lglew 
         -framework OpenGL -I /usr/local/cuda/include  -L /usr/local/cuda/lib -lcudart

我明白了

before mapping: 1, 2, 3
after mapping:  0, 33554432, 32

有谁知道为什么映射会改变缓冲区数据?这让我特别困惑,因为这不会发生在 Linux 机器上。

感谢任何评论或提示!

最佳答案

我注意到您使用 cudaGraphicsMapFlagsWriteDiscard 注册了 vbo。

来自 here “指定 CUDA 将不会从此资源读取并将覆盖资源的全部内容,因此不会保留先前存储在资源中的任何数据。”

也许试试 cudaGraphicsMapFlagsNone 或 cudaGraphicsMapFlagsReadOnly?

关于opengl - CUDA OpenGL 互操作,资源映射弄乱了缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16125819/

相关文章:

c++ - 为什么通过GLFW进行的这个简单的OpenGL程序在Intel HD P4600上不起作用?

cuda-memcheck 无法启动应用程序 (7)

cuda - 无法运行查询 NVML 的 CUDA 代码 - 关于 libnvidia-ml.so 的错误

c++ - 构建一个使用 boost 的 .cu 文件

c++ - OpenCV - Brox 光流 - opencv_core244d!cv::GlBuffer::unbind 异常

c++ - 每当我按下一个键时,如何在 1 个对象上应用照明颜色 C++

c - GLUT 无法正确检测到超过 2 个按键?

performance - 两个连续的内核还是全网格协作组同步?

C++/OpenGL随机分割错误

c++ - Electron中神秘无效的OpenGL上下文