multithreading - OpenGL:单独线程上的 glClientWaitSync

标签 multithreading opengl synchronization

我使用带有 GL_MAP_UNSYNCHRONIZED_BIT 的 glMapBufferRange 来映射缓冲区对象。然后我将返回的指针传递给工作线程以异步计算新顶点。对象是双重缓冲的,因此我可以在写入另一个对象时渲染一个对象。使用 GL_MAP_UNSYNCHRONIZED_BIT 给了我明显更好的性能(主要是因为 glUnmapBuffer 返回得更快),但我得到了一些视觉伪影(尽管有双缓冲) - 所以我假设 GPU 在 DMA 上传仍在进行时开始渲染,或者工作线程过早地开始写入顶点。
如果我正确理解 glFenceSync、glWaitSync 和 glClientWaitSync,那么我应该通过以下方式解决这些问题:

A:避免在 DMA 过程完成之前让 GPU 渲染缓冲区对象:
直接在 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。除了 gl 调用之外,还有其他方法可以检查 GLsync 是否已发出信号?

最佳答案

您可以做的是在工作线程中创建一个 OpenGL 上下文,然后与主线程共享它。下一个:

Run on the main thread:

GLsync renderSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();

然后

Run on the worker thread:

glClientWaitSync(renderSync,0,100000000);
glFlush在主线程上很重要,否则您可能会无限等待。另见 OpenGL docs :

4.1.2 Signaling

Footnote 3: The simple flushing behavior defined by SYNC_FLUSH_COMMANDS_BIT will not help when waiting for a fence command issued in another context’s command stream to complete. Applications which block on a fence sync object must take additional steps to assure that the context from which the corresponding fence command was issued has flushed that command to the graphics pipeline.

关于multithreading - OpenGL:单独线程上的 glClientWaitSync,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33640702/

相关文章:

java - 多线程访问LinkedList时的线程安全

c++ - glutSolidSphere 没有被点亮

c++ - 如何有效地绘制数千个顶点?

mysql - 如何同步 2 个 MySQL 数据库?

JavaScript 最佳实践 : Syncing Browser Windows

c - ResumeThread 在这种特殊情况下不起作用

multithreading - 比较和交换 - 如果 2 个处理器同时执行锁定会怎样?

mysql - 数据库同步服务器到本地

C#只有一个线程执行

opengl - OpenGL 的坐标系是如何工作的?