我正在使用glMapBufferRange和GL_MAP_UNSYNCHRONIZED_BIT来映射缓冲区对象。然后,我将返回的指针传递给工作线程以异步计算新顶点。对象是双重缓冲的,所以我可以渲染一个对象而另一个被写入。使用GL_MAP_UNSYNCHRONIZED_BIT给了我明显更好的性能(主要是因为glUnmapBuffer更快地返回),但是我得到了一些视觉工件(尽管有双重缓冲) - 所以我假设GPU在DMA上传仍在进行时开始渲染,或者工作线程开始写入顶点太早。 如果我理解glFenceSync,glWaitSync和glClientWaitSync正确的,那么我应该解决以下方式将这些问题:OpenGL:单独线程上的glClientWaitSync
答:避免在GPU渲染缓存对象的DMA过程完成之前:glUnmapBufferRange后直接 ,通话在主线程
GLsync uploadSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
glWaitSync(uploadSync, 0, GL_TIMEOUT_IGNORED);
B:避免在工作者线程写入缓冲区中的GPU呈现完毕之前:glDrawElements后 照片直接,调用主线程
GLsync renderSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
,并在工作线程,右侧开始将数据写入指针与先前已从glMapBufferRange
glClientWaitSync(renderSync,0,100000000);
...start writing to the mapped pointer
1返回前:我的办法来明确同步正确吗?
2:如何处理第二种情况?我想在工作线程中等待(我不想让主线程停止工作),但是我无法从工作线程发出glCommands。是否有另一种方法来检查GLsync是否已被发送,而非gl呼叫?
您可以为上传线程使用单独的GL上下文,该上下文线程将所有对象与主要上下文共享以进行绘制。在这种情况下,您也可以共享同步对象,并且可以通过这种方式同步这些线程。 – derhass
我理解GLsync对象的方式是它们没有绑定到上下文,所以我猜这些上下文甚至不需要共享。如果可能的话,我想避免为工作线程分开上下文。在Android上,似乎可以通过eglDupNativeFenceFDANDROID从GLsync生成本地栅栏 - 如果Windows也有类似的东西,或者与平台无关,那就太棒了。 – user1282931
同步对象与GL上下文(或多个共享的上下文)相关联的对象与任何其他GL对象一样,所以如果没有共享上下文,您就无法离开。 – derhass