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

时间:2018-05-30 13:13:22

标签: c++ opengl pbo

当有人在OpenGL中询问视频流纹理时,通常会引用

This文章。

它说:

  

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

Double 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.

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

使用两个PBO,纹理数据存储3次。纹理中为1,每个PBO中有一个。

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

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

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

1 个答案:

答案 0 :(得分:1)

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

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

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

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

  • 没有PBO(yeilds 6fps)

  • 1 PBO。孤儿先前的缓冲区。 (收益12.2 fps)。

  • 2 PBO。 Orpha以前的缓冲区。 (收益12.2 fps)。

  • 1 PBO。不要孤儿以前的公益组织(可能失速 - 由我自己添加。收益率为12.4 fps)。

  • 2 PBO。不要孤儿以前的公益组织(可能失速 - 由我自己添加。收益率为12.4 fps)。

如果其他人想检查我的代码,则可以使用here

我已经尝试了不同的纹理大小......以及不同的updatePixels函数......我不能,尽管我付出了最大的努力,但是双PBO实现比单PBO实现更好。

此外......不对前一个缓冲区进行孤立操作,实际上可以获得更好的性能。与文章所声称的完全相反。

也许现代的驱动程序/硬件不会遇到这种设计需要解决的问题......

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

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

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