是OpenGL';s的执行模型是否在单个上下文中同步?

是OpenGL';s的执行模型是否在单个上下文中同步?,opengl,Opengl,给定一个OpenGL上下文(因此一次只能由一个CPU线程访问),如果我执行两个OpenGL命令,是否可以保证第二个命令将看到第一个命令的结果?在绝大多数情况下,这是正确的。OpenGL命令在很大程度上表现为之前的所有命令都已完全完成。值得注意的地方包括: 混合。混合通常是一种对顺序非常敏感的操作。混合不仅可以在渲染命令之间正确工作,还可以在渲染命令中正确工作。绘制调用中的三角形是显式排序的,混合将按照基本体在绘制调用中出现的顺序进行混合 从以前渲染的帧缓冲区图像读取。如果渲染到图像,则可以取消

给定一个OpenGL上下文(因此一次只能由一个CPU线程访问),如果我执行两个OpenGL命令,是否可以保证第二个命令将看到第一个命令的结果?

在绝大多数情况下,这是正确的。OpenGL命令在很大程度上表现为之前的所有命令都已完全完成。值得注意的地方包括:

  • 混合。混合通常是一种对顺序非常敏感的操作。混合不仅可以在渲染命令之间正确工作,还可以在渲染命令中正确工作。绘制调用中的三角形是显式排序的,混合将按照基本体在绘制调用中出现的顺序进行混合

  • 从以前渲染的帧缓冲区图像读取。如果渲染到图像,则可以取消绑定该帧缓冲区,并将图像绑定为纹理并从中读取,而无需执行任何特殊操作

  • 从变换反馈操作中使用的缓冲区读取数据。在生成反馈数据的命令和读取反馈数据的命令之间不需要任何特殊的操作(除了从TF操作中解除缓冲区的绑定并将其绑定到适当的读取目标之外)

显然,在让CPU发送更多声音之前,等待GPU完成其命令的速度非常慢。这就是OpenGL在“仿佛”规则下工作的原因:实现必须“仿佛”它们是同步的。因此,实现会花费大量时间跟踪哪些操作将生成哪些数据,因此,如果您做了一些需要等待GPU生成数据的事情,GPU就可以这样做

因此,您应该尽量避免立即尝试读取某个命令生成的数据。在发电机和耗电元件之间留出一定距离

现在,我在上面说过,“绝大多数情况下”都是这样。所以有一些后门

  • 通常禁止尝试读取当前用作渲染目标的图像。但是,通常可以通过使用
    glTextureBarrier
    命令来实现。此命令确保先前提交的渲染命令对后续命令的执行和可见性。未能正确执行此操作将导致未定义的行为

  • 缓冲区或图像的内容,这些内容可能会被写入(原子或其他)我们可以调用的内容。这些操作包括映像存储/原子操作、SSBO存储/原子操作和原子计数器操作。除非您使用各种工具,具体到谁在读取数据及其与作者的关系的细节,否则您将得到未定义的行为

  • 。从本质上讲,同步对象绕过顺序执行模型,因为。。。这就是他们的观点:允许用户直接了解GPU执行内容的方式

  • 这种情况很奇怪。它们实际上并没有破坏OpenGL内存模型的有序性。但是,由于您正在对无法直接访问的存储器进行读/写操作,因此实现可能会隐藏这样一个事实,即读取数据需要一些时间。因此,如果调用像素传输到缓冲区,然后立即尝试从缓冲区读取,系统必须在这两个命令之间设置等待。但是,如果在像素传输和它的使用者之间发出一系列命令,并且这些命令不使用正在使用的范围,那么像素传输的成本似乎可以忽略不计。可以使用同步对象来了解传输何时实际结束