8

当有人询问 OpenGL 中的视频流纹理时,通常会参考这篇文章。

它说:

为了最大限度地提高流传输性能,您可以使用多个像素缓冲区对象。该图显示同时使用了 2 个 PBO;glTexSubImage2D() 从一个 PBO 复制像素数据,同时将纹理源写入另一个 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到纹理中,暂时只有第三个?

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

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

4

1 回答 1

1

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

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

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

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

  • 没有 PBO(产生 6fps)

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

  • 2个公益组织。Orpha 上一个缓冲区。(产生 12.2 fps)。

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

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

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

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

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

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

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

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

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

于 2018-05-30T21:22:54.850 回答