在 OpenGL 上下文之间同步资源时是否需要调用 glFinish?

Is calling glFinish necessary when synchronizing resources between OpenGL contexts?

我在我的应用程序中使用了两个 OpenGL 上下文。

第一个用于渲染数据,第二个用于后台加载并生成 VBO 和纹理。

当我的加载上下文生成一个 VBO 并将其发送到我的渲染线程时,我在我的 VBO 中得到无效数据(全为零),除非我在创建 VBO 后调用 glFlushglFinish加载上下文。

我认为这是由于我的加载上下文没有任何缓冲区交换或任何告诉 GPU 开始处理其命令队列而不执行任何操作的内容(这导致渲染上下文端的 VBO 为空)。

据我所见,在 Windows 上不需要此刷新(使用 Nvidia GPU 测试,即使没有刷新也能正常工作)但在 linux/macOS.[=19 上是必需的=]

Apple 文档上的这个页面说调用 glFlush 是必要的 (https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/OpenGLESApplicationDesign/OpenGLESApplicationDesign.html)

If your app shares OpenGL ES objects (such as vertex buffers or textures) between multiple contexts, you should call the glFlush function to synchronize access to these resources. For example, you should call the glFlush function after loading vertex data in one context to ensure that its contents are ready to be retrieved by another context.

但是调用 glFinishglFlush 是否有必要,或者是否有 simpler/lighter 命令可用于实现相同的结果? (哪个是必要的,glFlushglFinish?)

此外,是否有任何文档或参考资料谈到了这一点?我找不到任何提及,它似乎在实现之间有所不同。

如果您在线程 A 中操作任何对象的内容,这些内容对其他线程 B 是不可见的 until two things have happened:

  1. 修改对象的命令有completed. glFlush does not complete commands; you must use glFinish or a sync object确保命令完成。

    请注意,完成需要传达给线程 B,但同步命令必须在线程 A 上发出。因此,如果线程 A 使用 glFinish,它现在必须使用一些 CPU同步以向线程 B 传达线程已完成。如果您改用栅栏同步对象,则需要在线程 A 上创建栅栏,然后将其交给线程 B,线程 B 可以 test/wait 在该栅栏上。

  2. 该对象必须 re-bound 到线程 B 的上下文。也就是说,您必须在命令完成后将其绑定到该上下文(直接使用 glBind* 命令或通过绑定附加有此对象的容器对象来间接绑定)。

这在 OpenGL 规范的第 5 章中有详细说明。