【问题标题】:Why is using multiple Pixel buffer Objects advised. Surely it is redundant?为什么建议使用多个像素缓冲区对象。确定是多余的吗?
【发布时间】:2018-11-09 08:47:18
【问题描述】:

This 文章在任何人询问 OpenGL 中的视频流纹理时通常会被引用。

上面写着:

为了最大限度地提高流传输性能,您可以使用多个像素缓冲区对象。该图显示同时使用了 2 个 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.

所以,这是我的问题... 这不是让第二个 PBO 完全没用吗?只是浪费内存!?

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

只有一个 PBO。数据有两个副本。如果 glMapBuffer 创建一个新的缓冲区,因为现有的缓冲区目前正在被 DMA 处理到纹理,暂时只有第三个?

cmets 似乎建议 OpenGL 驱动程序在内部能够创建第二个缓冲区 IF 并且仅在需要避免停止管道时才创建。正在使用的缓冲区正在被 DMA 处理,我对 map 的调用会产生一个新的缓冲区供我写入。

那篇文章的作者在这方面的知识似乎比我自己还要多。我完全误解了重点吗?

【问题讨论】:

  • 我不知道我在说什么,但我的盲目猜测是:您使用两个缓冲区,以便随时可以写入另一个可以读取而不会读写干扰,内存与避免竞争条件的成本相比,它相当便宜
  • 恕我直言,我认为它是这样的:想象一下,其中一个 PBO 被发送到渲染缓冲区以绘制到屏幕上。虽然此操作在当前帧期间发生,但如果 PBO 中的信息要在下一帧或绘制调用之前更改怎么办......而不是等待帧完成绘制,取回信息,然后更新它并将其发送回渲染缓冲区,更新可以在当前绘制帧期间在后台进行,然后一旦该帧完成绘制,它几乎可以立即交换缓冲区以绘制更新的信息。
  • 不要完全引用我的话,因为我没有使用过 PBO,因为我主要使用的是 vbo、vba 和 rbo,但我认为这就是原因。
  • @FrancisCugler 谢谢。但是,PBO 中的信息不能更改。任何更改它的尝试都会使 GPU 停止工作,直到它不再被使用。或者,如果缓冲区已被 glBufferData(...NULL) 孤立,那么任何修改它的尝试都只会提供一个全新的缓冲区。
  • @cds84 你不是在那儿回答你自己的问题吗? “任何改变它的尝试都会停止 GPU 直到它不再被使用”即你需要 2 个这样你就不会停止 GPU

标签: c++ opengl pbo


【解决方案1】:

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

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

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

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

  • 无 PBO(产生 6fps)

  • 1 公益组织。孤立先前的缓冲区。 (产生 12.2 fps)。

  • 2 个 PBO。 Orpha 上一个缓冲区。 (产生 12.2 fps)。

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

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

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

我已经尝试过不同的纹理大小...和不同的 updatePixels 函数...我不能,尽管我尽了最大努力让双 PBO 实现比单 PBO 实现更好。

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    相关资源
    最近更新 更多