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

5
我在应用程序中使用了两个OpenGL上下文。
第一个用于渲染数据,第二个用于后台加载和生成VBO和纹理。
当我的加载上下文生成VBO并将其发送到渲染线程时,除非我在加载上下文中创建VBO后调用`glFlush`或`glFinish`,否则我会得到无效数据(全零)。
我认为这是因为我的加载上下文没有任何缓冲区交换或其他任何东西来告诉GPU开始处理其命令队列并执行操作(这导致渲染上下文侧的空VBO)。
从我看到的情况来看,在Windows上不需要这种刷新(使用Nvidia GPU进行测试,即使没有刷新也可以正常工作),但在Linux / macOS上需要。
Apple文档页面上指出必须调用`glFlush` (https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/OpenGLESApplicationDesign/OpenGLESApplicationDesign.html) >如果您的应用程序在多个上下文之间共享OpenGL ES对象(例如顶点缓冲区或纹理),则应调用`glFlush`函数以同步对这些资源的访问。例如,在一个上下文中加载顶点数据后,应调用`glFlush`函数以确保其内容已准备好由另一个上下文检索。
但是,调用 `glFinish`或`glFlush`是否必要?是否有更简单/轻量级的命令可以实现相同的结果? (哪个是必要的,`glFlush`还是`glFinish`?)
此外,是否有一个讨论这个问题的文档或参考资料?我找不到任何提到它的地方,而且似乎在不同的实现之间工作方式不同。
1个回答

5
如果您在线程A中操纵任何对象的内容,则这些内容对于其他线程B 直到发生两件事情才能看到:
  1. 修改对象的命令已经完成glFlush 命令不会完成命令;你必须使用 glFinish 命令或者同步对象来确保命令已经完成。

    需要注意的是,线程B需要知道命令已经完成,但是同步命令必须在线程A中发出。因此,如果线程A使用 glFinish 命令,现在必须使用一些CPU同步来将线程已经完成的信息传达给线程B。如果你使用屏障同步对象,你需要在线程A上创建屏障,然后将其交给线程B进行测试/等待。

  2. 该对象必须重新绑定到线程B的上下文中。也就是说,你必须在命令已经完成之后将其绑定到该上下文中(可以直接使用 glBind* 命令,也可以通过绑定一个包含该对象的容器对象间接绑定)。

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


谢谢您的回答。从规格上来看,我几乎肯定需要使用glFinish,但是苹果的文档让我感到困惑。如果我理解正确,这份文档是错误的?或者不同的操作系统之间是否存在行为差异? - Ebatsin

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