是否可以在写入纹理时渲染纹理?

时间:2017-09-26 18:58:57

标签: opengl

我有一个应用程序,它在一个线程中呈现一个纹理,另一个线程从该纹理中读取数据。两个线程之间的上下文是共享的。是否有可能在读取线程读取部分数据的情况下发生竞争条件?

2 个答案:

答案 0 :(得分:1)

可能,绝对是。

但这绝不是必要的。 GLsync和glFinish中有精细的同步原语,你没有理由不使用它们。

确切地说,来自数据竞赛的影响是未指定的。您最终可能会读取一半纹理,您可能会在驱动程序中调用致命错误,或者它可能会停止。

答案 1 :(得分:1)

来自the OpenGL 4.6 core spec,第5.3.1节:

  

一旦完成了5.3节中描述的命令,就认为对象T的内容已经改变。可以通过调用Finish,或通过调用FenceSync并在关联的同步对象上执行WaitSync命令来确定命令1的完成。

通常,数据竞赛在以下情况发生:

  1. 两个或多个线程正在写入内存中的相同位置,

  2. 至少有一个主题是写作,

  3. 线程之间没有同步。

  4. 您可以看到,在OpenGL中,您需要等待Finish()WaitSync()返回才能知道您的操作已同步。还有其他规则,请注意第5.3.3节:

      

    规则4 如果在当前上下文以外的上下文中更改了对象T的内容,则必须将T附加或重新附加到当前上下文中的至少一个绑定点,或者当前绑定的容器对象C的至少一个附着点,以保证T的新内容在当前上下文中可见。

    因此,如果您在线程A中写入纹理,并在线程B中读取它,则必须执行以下操作:

    1. 创建同步对象。

    2. 写完后,从线程A发出同步对象的信号。

    3. 等待主题B中的同步对象。

    4. 在线程B中重新绑定纹理。

    5. 完成这些步骤后,您可以从线程B中的纹理中读取。

      注意:如果您在自己的计算机上进行测试,您可能会发现带有数据竞争的代码将“正常运行”。这并不奇怪......有时它会起作用,有时却不会。也许它会一直在您的计算机上运行并炸毁其他人的计算机。最好通过线程同步来解决问题,只是测试不够好。