【问题标题】:PBO not working Properly in Integrated GPUPBO 在集成 GPU 中无法正常工作
【发布时间】:2015-04-04 23:29:57
【问题描述】:

为了进行基准测试,让我们来看看这个著名的PBO Read-back code

问题:

  1. 在我的 PC 中使用 PBO 无效。即使使用最新的驱动程序更新和正确的像素格式 BGRA。

更新 1:我也尝试了 3 个 PBO 的相同示例。但即使那样也没有区别。

注意:Intel(R) Core(TM) i5-3470S CPU @ 2.90GHz,2901 Mhz,4 核, 显卡:Intel(R) HD Graphics 2500

PBO: off  
Read Time: 9 ms
Process Time: 2 ms
Transfer Rate: 39.5 Mpixels/s. (45.0 FPS)

PBO: on 
Read Time: 7 ms
Process Time: 2 ms
PBO: on Transfer Rate: 38.8 Mpixels/s. (44.2 FPS)

更新 2:PBO 在外部 GPU 和 Intel i-7 系列中正常工作。

电脑配置: Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz, 3400 Mhz, 4 Core(s), 8 Logical Processor(s), Video Card: Geforce 210. 所以它原来是 问题集成 GPU 和外部 GPU。我相信这对于许多想知道为什么他们的代码不起作用的人来说是一个有用的提示!

PBO: on 
PBO: on Read Time: 0.06 ms
Process Time: 2 ms
Transfer Rate: 112.4 Mpixels/s. (127.9 FPS)

PBO: off 
Read Time: 4 ms
Process Time: 2 ms
Transfer Rate: 93.3 Mpixels/s. (106.1 FPS)

【问题讨论】:

  • 你自己试过了吗?我不想听起来冒犯,但这听起来像你在质疑其他人的能力,但你不愿意做自己的研究;如果您有任何自己的基准,请添加它们。实际上,这对于 stackoverflow 来说是相当不合适的,所以也许写一篇关于你的基准测试的文章并将其放到网上某个地方,然后在这里引用它。
  • @Marcus 也欢迎你改进这个问题,让它变得更好!
  • 这可能与拥有单独的 GPU/VRAM 和集成的有关。我在英特尔 GPU 上看到了非常接近的结果。将在几个小时内检查单独的 nvidia 卡。
  • @BalajiR 是的,我在独立显卡上看到了非常显着的差异(64 与 41 Mpix/s)。在集成 GPU 上,系统 RAM 和 VRAM 是相同的,因此 CPU 可以直接访问数据,而无需使用相对窄/慢的 PCIe。
  • @keltar 听起来不错!如果您可以在代码中证明这一点作为答案,那就太好了。

标签: c++ opengl graphics pbo


【解决方案1】:

link

映射 PBO ...

请注意,如果 GPU 仍在使用缓冲区对象, glMapBufferARB() 在 GPU 完成其工作之前不会返回 对应的缓冲区对象。为避免此停顿(等待),请致电 在 glMapBufferARB() 之前带有 NULL 指针的 glBufferDataARB()。 然后,OpenGL 会丢弃旧的缓冲区,并分配新的内存 缓冲区对象的空间。

您可能需要将上面建议的更改应用于以下代码:

// "index" is used to read pixels from framebuffer to a PBO
// "nextIndex" is used to update pixels in the other PBO
index = (index + 1) % 2;
nextIndex = (index + 1) % 2;

// set the target framebuffer to read
glReadBuffer(GL_FRONT);

// read pixels from framebuffer to PBO
// glReadPixels() should return immediately.
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[index]);
glReadPixels(0, 0, WIDTH, HEIGHT, GL_BGRA, GL_UNSIGNED_BYTE, 0);

// map the PBO to process its data by CPU
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[nextIndex]);
glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, 0, NULL, GL_STATIC_DRAW_ARB);
GLubyte* ptr = (GLubyte*)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,
                                        GL_READ_ONLY_ARB);
if(ptr)
{
    processPixels(ptr, ...);
    glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
}

// back to conventional pixel operation
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);

【讨论】: