为什么建议使用多个Pixel缓冲区对象.当然这是多余的?

cds*_*s84 8 c++ opengl pbo

时候有人问关于OpenGL的视频流纹理文章经常引用.

它说:

要最大化流传输性能,可以使用多个像素缓冲区对象.该图显示同时使用2个PBO; 当纹理源被写入另一个PBO时,glTexSubImage2D()从PBO复制像素数据.

双PBO

对于第n帧,PBO 1用于glTexSubImage2D(),PBO 2用于获得新的纹理源.对于第n + 1帧,2个像素缓冲区正在切换角色并继续更新纹理.由于异步DMA传输,可以同时执行更新和复制过程.CPU将纹理源更新为PBO,而GPU从其他PBO复制纹理.

它们提供了一个简单的基准程序,允许您在没有PBO的情况下在单个PBO之间循环纹理更新,并且如上所述使用两个PBO.

启用一个PBO时,我看到性能略有改善.但第二个PBO没有真正的区别.

在代码glMapBuffer的PBO之前,它调用glBufferData并将指针设置为NULL.这样做是为了避免同步停顿.

// map the buffer object into client's memory
// Note that glMapBufferARB() causes sync issue.
// If GPU is working with this buffer, glMapBufferARB() will wait(stall)
// for GPU to finish its job. To avoid waiting (stall), you can call
// first glBufferDataARB() with NULL pointer before glMapBufferARB().
// If you do that, the previous data in PBO will be discarded and
// glMapBufferARB() returns a new allocated pointer immediately
// even if GPU is still working with the previous data.
Run Code Online (Sandbox Code Playgroud)

所以,这是我的问题......难道这不会使第二个PBO完全无用吗?只是浪费记忆!

使用两个PBO,纹理数据存储3次.纹理中的1,每个PBO中的一个.

只有一个PBO.有两份数据副本.在glMapBuffer创建新缓冲区的情况下暂时只有第3个,因为现有的缓冲区目前正在对纹理进行DMA处理?

评论似乎表明OpenGL驱动程序内部能够创建第二个缓冲区IF,并且只有在需要时才能避免使管道停滞.正在使用的缓冲区是DMA,我对map的调用产生了一个新的缓冲区供我写入.

该文章的作者似乎比我自己更了解这方面的知识.我完全误解了这一点吗?

cds*_*s84 3

回答我自己的问题...但我不会接受它作为答案...(还)。

问题中链接的基准程序存在很多问题。它使用立即模式。它使用过剩!

该程序大部分时间都花在做我们对分析不感兴趣的事情上。主要通过GLUT渲染文本,并在纹理上写入漂亮的条纹。所以我删除了这些功能。

我将纹理结果提高到 8K,并添加了更多PBO 模式

  • 无 PBO(产生 6fps)

  • 1 个 PBO。孤立的前一个缓冲区。(产生 12.2 fps)。

  • 2 个 PBO。Orpha 之前的缓冲区。(产生 12.2 fps)。

  • 1 个 PBO。不要孤立以前的 PBO(可能的停顿 - 由我自己添加。产生 12.4 fps)。

  • 2 个 PBO。不要孤立以前的 PBO(可能的停顿 - 由我自己添加。产生 12.4 fps)。

如果其他人想检查我的代码,可以在这里找到

我尝试过不同的纹理大小...以及不同的 updatePixels 函数...尽管我尽了最大努力,但我还是无法让双 PBO 实现比单 PBO 实现更好。

此外...不孤立以前的缓冲区,实际上会产生更好的性能。与文章声称的完全相反。

也许现代驱动程序/硬件不会遇到此设计试图解决的问题......

也许我的图形硬件/驱动程序有问题,并且没有利用双 PBO...

也许经常引用的文章是完全错误的?

谁知道。。。。我的测试硬件是 Intel(R) HD Graphics 5500 (Broadwell GT2)。

编辑:许多年后,在 @Heiner 评论说集成不是一个好的测试,因为它与 CPU 共享 RAM 后,我在新硬件(独立 GPU)上重复了这个测试。

新硬件是 AMD Radeon RX 6800M (Navi22)。

  • 无 PBO = 39 FPS
  • 1 PBO,孤立的前一个缓冲区 = 48.1 FPS。
  • 2 PBO,孤立的前一个缓冲区 = 48.3 FPS。
  • 1 PBO,没有孤立的先前缓冲区 = 47.0 FPS。
  • 2 PBO,无孤立的先前缓冲区 = 47.2 FPS。

所以...是的,在独立 GPU 上,我能够使用第二个 PBO 观察到 0.4% 的帧速率提升...然而,PBO 性能的最大提升是孤立以前的缓冲区 (2%)。