【问题标题】:Is calling glFinish necessary when synchronizing resources between OpenGL contexts?在 OpenGL 上下文之间同步资源时是否需要调用 glFinish?
【发布时间】:2021-01-04 03:36:48
【问题描述】:

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

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

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

我认为这是由于我的加载上下文没有任何缓冲区交换或任何告诉 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 函数,以确保其内容已准备好被另一个上下文检索。

但是调用glFinishglFlush 是必要的,还是有更简单/更轻松的命令可以实现相同的结果? (哪个是必要的,glFlushglFinish?)

另外,是否有文档或参考资料在某处谈论这个?我找不到任何提及,而且它似乎在实现之间的工作方式不同。

【问题讨论】:

    标签: opengl vbo openglcontext


    【解决方案1】:

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

    1. 修改对象的命令有completedglFlush 没有完成命令;您必须使用glFinishsync object 来确保命令完成。

      注意,完成需要传达给线程 B,但同步命令必须在线程 A 上发出。所以如果线程 A 使用glFinish,它现在必须使用一些 CPU 同步来传达线程已完成到线程 B。如果您使用栅栏同步对象,则需要在线程 A 上创建栅栏,然后将其交给可以在该栅栏上测试/等待的线程 B。

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

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

    【讨论】:

    • 感谢您的回答。从规格来看,我几乎可以肯定我必须使用glFinish,但我对 Apple 的文档感到困惑。如果我做对了,这个文件是错的吗?还是操作系统之间存在行为差异?
    猜你喜欢
    • 1970-01-01
    • 2020-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多