【发布时间】:2014-05-20 16:34:17
【问题描述】:
如果我打算在 OpenGL 中使用多线程,我是否应该为每个上下文设置单独的缓冲区(来自 glGenBuffers)?
我还不太了解 OpenGL 多线程(目前我在“单”线程中工作)。我需要知道我是否可以共享已经推送到视频内存的缓冲区(使用 glBufferData/glBufferSubData),或者我必须为另一个线程保留缓冲区副本。
【问题讨论】:
-
首先,你想用多线程做什么?如果您在上下文之间共享资源,则缓冲区对象名称(
glGenBuffers (...)返回的内容)将具有共享池。 VAO、FBO 和状态机的其他部分是不共享的 - 基本上只有实际存储数据的对象(如缓冲区对象、纹理和 GLSL 程序)是共享的。此外,如果您在其他线程中修改这些缓冲区,而这些缓冲区正在被尚未完成的绘图命令使用,您将严重损害您的性能。 -
@AndonM.Coleman 那么,VBO 是共享的吗?关于为什么...我认为一个线程可以将数据推送到 VBO,而其他渲染先前已推送。但是知道我对此有疑问.. stackoverflow.com/questions/11097170/… 有人说它会自动并行化,即使你有某种 SLI。我说的对吗?
-
是的,VBO 是共享的如果您设置了具有共享的渲染上下文(默认情况下不在上下文之间共享)。这与您拥有的 GPU 数量无关。如果您有一个绘制命令在管道中排队,则在完成之前不允许修改它使用的数据,否则您会产生无效的结果。因此,驱动程序要么复制您的缓冲区,要么停止管道以防止这种情况发生。
-
Andon M. Coleman 我不会尝试绘制 VBO,我当时在并行线程中将其移动到内存中。它是这样的:1 线程绘制 VBO1,2 线程推送 VBO2;然后 1 线程绘制 VBO2,2 线程推送 VBO3
-
在适当的条件下,无论您使用多少 GPU,这都可以提高性能,特别是如果您可以处理线程 2 中上传的数据可能延迟 1 帧到达的情况。但是,当您开始为此使用多个上下文时,您需要注意一些额外的同步问题。在单个上下文中,驱动程序会自动对所有命令进行正确排序,但在多个上下文中则不会,您需要栅栏同步或
glFinish (...)和 CPU 信号才能发生这种情况。
标签: c++ multithreading opengl