首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >映射PBO cudaGraphicsResource时出错

映射PBO cudaGraphicsResource时出错
EN

Stack Overflow用户
提问于 2013-06-27 23:25:45
回答 1查看 2.3K关注 0票数 1

我有一个关于CUDA缓冲区访问的问题:我注册了一个OpenGL缓冲区来使用CUDA,cudaGraphicsGLRegisterBuffer()没有返回错误(即成功),但是当我想用cudaGraphicsMapResources()映射我的PBO时,我得到"cudaErrorMapBufferObjectFailed“。

以下是我的代码(经过简化,但包含了相关部分):

在.h文件中

代码语言:javascript
复制
GLuint bufferID;
struct cudaGraphicsResource* PBO_CUDA_Widget;

在.cpp文件中

代码语言:javascript
复制
void HDR_GLWidget::initializeGL()
{
    cutilSafeCall(cudaGLSetGLDevice(cutGetMaxGflopsDeviceId()));

        // create pixel buffer object
    glGenBuffersARB(1, &bufferID);
    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, bufferID);
    glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, width * height * 4, NULL, GL_STREAM_DRAW_ARB);
    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);

    cudaError_t error_test = cudaGraphicsGLRegisterBuffer(&PBO_CUDA_Widget, bufferID, cudaGraphicsMapFlagsWriteDiscard); //no cuda error here
}

void HDR_GLWidget::uploadBuffer
{
    cudaError_t error_test = cudaGraphicsMapResources(1, &PBO_CUDA_Widget, 0); //crash here

        [...]
}

下面是我得到的错误:

代码语言:javascript
复制
First-chance exception at 0x000007fefd47bccd in IHM_Qt_TM_cuda.exe: Microsoft C++ exception: cudaError_enum at memory location 0x073ff200..

我在一台装有Windows7的x64电脑上,在一台GTX580上运行CUDA4.2。

编辑:以下是修改后的代码

在.h文件中

代码语言:javascript
复制
cudaGraphicsResource* PBO_CUDA_Widget;
GLuint bufferID;

在.cpp文件中

代码语言:javascript
复制
void HDR_GLWidget::initializeGL()
{
    cutilSafeCall(cudaGLSetGLDevice(cutGetMaxGflopsDeviceId()));
    GLenum err = glewInit();
    glGenBuffers(1, &bufferID);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, bufferID);
    glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, width * height * 4, NULL, GL_STREAM_DRAW);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);

    cutilSafeCall(cudaMalloc((void**) PBO_CUDA_Widget, width * height * sizeof(uchar4)));
    cudaError_t error_reg = cudaGraphicsGLRegisterBuffer((cudaGraphicsResource **)PBO_CUDA_Widget, bufferID, cudaGraphicsMapFlagsWriteDiscard);
}

void HDR_GLWidget::uploadBuffer()
{
    cudaError_t error_map = cudaGraphicsMapResources(1, (cudaGraphicsResource_t*)PBO_CUDA_Widget, 0); //error here
[...]
cudaError_t flag_unmap = cudaGraphicsUnmapResources(1, (cudaGraphicsResource_t*)PBO_CUDA_Widget, 0);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-06-28 00:25:14

cudaGraphisMapResources接受一个指针作为第二个参数。不是指向指针的指针。您的PBO_CUDA_Widget变量已经是一个指针。调用应该是(不带地址,即省略'&'):

代码语言:javascript
复制
cudaError_t error_test = cudaGraphicsMapResources(1, PBO_CUDA_Widget, 0);

请记住,在启动访问资源的OpenGL内核之前,要解除PBO与CUDA的绑定。

顺便说一句:从OpenGL1.5开始,OpenGL Buffer对象就一直是核心OpenGL的一部分。任何支持CUDA的图形处理器也支持比OpenGL-2更好的=>不要使用ARB后缀。

更新示例代码:

这是我的一个项目中实际的、经过测试的代码。从技术上讲,它分布在几个函数中,变量名称略有不同。但是将它合并到一个函数中,它就是这样工作的。

代码语言:javascript
复制
void example(void)
{
    GLuint pbo_ID;
    size_t pbo_size = ...;

    // note the type, there's no '*' and it's initialized to 0
    cudaGraphicsResource_t cgr = 0;

    glGenBuffers(1, &pbo_ID);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_ID);
    glBufferData(GL_PIXEL_UNPACK_BUFFER, pbo_size, NULL, GL_DYNAMIC_DRAW);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

    cudaGraphicsGLRegisterBuffer(&cgr, pbo_ID, cudaGraphicsRegisterFlagsWriteDiscard);

    cudaGraphicsMapResources(1, &cgr, 0);

    void *ptr;
    size_t mapped_size;
    cudaGraphicsResourceGetMappedPointer(
        &ptr, &mapped_size, cgr);

    cudaArray_t array;
    cudaGraphicsSubResourceGetMappedArray(
    &array,
    cgr,
    0, 0 );

    call_CUDA_kernel();
    
    cudaGraphicsUnmapResources(1, &cgr, 0);
}

现在,我说的让cudaGrapicsResource成为一个指针是什么意思呢?好吧,这样的话:

代码语言:javascript
复制
cudaGraphicsResource_t *p_cuda_gr_resources =
    malloc(count * sizeof cudaGraphicsResource_t);

/* do some stuff */

free(p_cuda_gr_resources);

如果你有一大堆资源,这是很有用的,这个数字不是预先确定的。不过,在通常情况下,您不需要动态分配。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17347193

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档