OpenGL多线程/共享上下文与glGenBuffers

6
如果我计划在OpenGL中使用多线程,是否应该为每个上下文(从glGenBuffers)拥有单独的缓冲区?
我目前对OpenGL多线程还不太了解(现在我是在“单”线程中工作)。我需要知道是否可以共享已推送到视频内存中的缓冲区(使用glBufferData / glBufferSubData),还是必须为另一个线程保留缓冲区的副本。

1
首先,您想使用多线程做什么?如果在上下文之间共享资源,则缓冲对象名称(即glGenBuffers(...)返回的内容)将具有共享池。但是VAO、FBO和状态机的其他部分不会被共享——基本上只有实际存储数据的对象,如缓冲区对象、纹理和GLSL程序才会被共享。此外,如果您在其他线程中修改这些缓冲区,而它们正在被尚未完成的绘制命令使用,那么您的性能将受到明显的影响。 - Andon M. Coleman
@AndonM.Coleman,VBO是共享的吗?我曾认为一个线程可以向VBO推送数据,而其他线程则渲染之前已经推送的数据。但现在我对此有所怀疑...https://dev59.com/7Wgu5IYBdhLWcg3wxZlL?rq=1 上面说即使你有某种类型的SLI,它也会自动并行化。我是对的吗? - tower120
1
是的,如果您使用共享设置(默认情况下不在上下文之间共享),则VBO是共享的。这与您拥有的GPU数量无关。如果您在管道中排队了绘制命令,则不允许修改它使用的数据,直到完成,否则会产生无效结果。因此,驱动程序要么复制缓冲区,要么暂停管道以防止出现此情况。 - Andon M. Coleman
@AndonM.Coleman 谢谢,我会记住这个(关于glFenceSync)。如果我只有一个GPU - 这种技术(一个线程推送,另一个绘制)不会提高性能吗?还是说它仍然有意义:ALU写入内存,而着色器处理器绘制场景? :) - tower120
1
在正确的情况下,这可以提高性能,无论您使用多少个GPU,特别是如果您可以处理线程2中上传的数据可能会在1帧后到达的情况。但是,当您开始使用多个上下文时,您必须自己处理一些额外的同步问题。在单个上下文中,驱动程序会自动正确地排序所有命令,但在多个上下文中,它不会这样做,因此您需要使用fence syncs或glFinish(...)和CPU信号来实现。 - Andon M. Coleman
显示剩余4条评论
2个回答

7

您不希望在多个线程中使用多个上下文。您真的不希望。

虽然这听起来像是一个好主意,但实际上多上下文和多线程是复杂、麻烦的,在驱动程序方面支持也很差,而且它只能稍微提高(甚至降低!)性能。

真正想要的是仅有一个线程与OpenGL通信(显然只有一个上下文),映射一个缓冲区,并将内存指针传递给另一个线程,最好使用3个缓冲区(一个3倍大小的缓冲区的3个子缓冲区)和不可变存储和持久映射,如果这是可用的。
此外,还可以采用间接渲染调用,其中第二个线程向缓冲区提供间接调用所读取的内容。

关于持久映射主题的更多信息:请参见GDC2014演示文稿的22-25幻灯片,这基本上是Cass Everitt 2013年SIGGRAPH演讲的翻版。
还可以参见Everitt的原始演讲:超越移植


为什么需要三个缓冲区? - tower120
2
实际上你不需要。你使用一个“三倍大小”的缓冲区(实际上是3个缓冲区,但在一个缓冲区对象中)。由于你在GPU读取时进行写入,所以必须至少有两个缓冲区(或缓冲区“子区域”),因此你必须小心,不要在数据被使用时踩到它。使用3个缓冲区而不是2个意味着你很可能永远不会(或极少)在你的围栏上阻塞,而如果你只使用了2个缓冲区,那么你几乎每次都会阻塞,浪费时间。 - Damon
1
用一個緩衝區,必須等待GPU完成後才能進行任何操作。使用兩個緩衝區時,您可以在GPU讀取第一個緩衝區時編寫第二個緩衝區,並在GPU讀取第二個緩衝區時編寫第一個緩衝區。在此期間,您必須等待(停滯),以確保不會損壞東西。使用三個緩衝區,您可以在GPU讀取第一個緩衝區時編寫第二個緩衝區,並在GPU可能仍在完成第一個緩衝區或讀取第二個緩衝區時繼續編寫第三個緩衝區。之後只需要同步,但很可能此時#1已再次可用。 - Damon

6

Vaos是不共享的,因此每个对象的上下文都需要生成一个新的vaos,否则在删除/创建新vaos时其行为将变得不可预测且不正确。 这可能是一个重大错误源。 Vbos可以共享,因此您只需要一个vbo即可。


1
这个问题是关于缓冲对象(glGenBuffers)而不是顶点数组对象的。 - Andon M. Coleman
VBO可以共享,因此每个对象只需要一个VBO。- 好的,我认为这就回答了问题。 - tower120

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接