OpenGL:哪些OpenGL实现不是流水线的?

OpenGL:哪些OpenGL实现不是流水线的?,opengl,pipeline,Opengl,Pipeline,在这方面,它说: “OpenGL实现几乎总是流水线式的——也就是说, 当您告诉OpenGL绘制时,不一定要绘制对象- OpenGL调用返回的事实并不意味着它完成了 渲染。” 因为它说“几乎”,这意味着有些实现没有流水线 我在这里找到一个: “常规glReadPixels()阻塞管道并等待所有 像素数据被传输。然后,它将控制权返回给 相反,带有PBO的glReadPixels()可以调度 异步DMA传输并立即返回,不会出现暂停。 因此,应用程序(CPU)可以立即执行其他进程, 通过OpenGL(

在这方面,它说:

“OpenGL实现几乎总是流水线式的——也就是说, 当您告诉OpenGL绘制时,不一定要绘制对象- OpenGL调用返回的事实并不意味着它完成了 渲染。”

因为它说“几乎”,这意味着有些实现没有流水线

我在这里找到一个:

“常规glReadPixels()阻塞管道并等待所有 像素数据被传输。然后,它将控制权返回给 相反,带有PBO的glReadPixels()可以调度 异步DMA传输并立即返回,不会出现暂停。 因此,应用程序(CPU)可以立即执行其他进程, 通过OpenGL(GPU)使用DMA传输数据时。”

因此,这意味着传统的glReadPixels()(不带PBO)会阻塞管道。 但实际上,在OpenGL对glReadPixels的引用中,我无法说出事实

那么我想知道: 哪些OpenGL实现不是流水线的


glDrawArrays怎么样?

OpenGL规范本身并没有指定术语“管道”,而是“命令流”。命令流执行的运行时行为故意保持打开状态,以给实现者最大的灵活性

重要的术语是“OpenGL同步点”:

在这里我找到一个:(链接到songho文章)

请注意,这不是一个正式的OpenGL规范资源。“阻塞OpenGL管道”这句话有点令人遗憾,因为它将实际的阻塞和瓶颈“颠倒过来”。从本质上讲,这意味着glReadPixels只能在它将获取的图像之前的所有命令执行完毕后返回

因此,这意味着传统的glReadPixels()(不带PBO)会阻塞管道。但实际上,在OpenGL对glReadPixels的引用中,我无法说出事实

实际上,阻塞的不是OpenGL管道,而是CPU上程序的执行。这意味着,GPU看不到来自CPU的更多命令。因此,管道不会被“堵塞”,但事实上会被排干。当管道排水或需要重新启动时,表示管道已停止(即管道中的流量停止)

从GPU的角度来看,一切都是以最大吞吐量进行的:在调用glReadPixels点之前渲染内容,执行DMA传输,不幸的是,在启动传输后没有其他命令可用

那么GLD阵列呢


glDrawArrays在数据排队并完成必要的操作后立即返回。

实际上,这意味着此特定操作不能通过管道进行,因为所有数据都需要在函数返回之前进行传输,但这并不意味着其他事情不能进行

这样的操作据说会使管道停止运行。始终暂停管道的一个函数是
glFinish

通常,当函数返回一个值(如获取缓冲区的内容)时,它会导致暂停

根据驱动程序实现,创建程序和缓冲区等操作可以在不暂停的情况下完成

然后我想知道:哪些OpenGL实现不是流水线的

我可以想象,一个纯粹的软件实现可能不会被管道化。如果您最终在同一个CPU上执行工作,则没有太多理由排队。除非你想利用多线程

但可以肯定地说,任何使用专用硬件(通常称为GPU)的OpenGL实现都将是流水线的。这允许CPU和GPU并行工作,这对于获得良好的系统性能至关重要。此外,向GPU提交工作会产生一定的开销,因此将工作排队,然后以更大的批量提交是有益的

但实际上,在OpenGL对glReadPixels的引用中,我无法说出事实

对。手册页不会直接指定哪些调用导致同步。通常,任何返回GPU生成的值/数据的操作都会导致同步。我想到的例子有:

  • glFinish()
    。显式地需要完全同步,这实际上是它的唯一目的
  • glReadPixels()
    ,在非PBO情况下。GPU必须先完成渲染,然后才能读回结果
  • glGetQueryObjectiv(id,GL\u查询结果,…)
    。阻塞,直到GPU到达提交查询的点
  • glClientWaitSync()
    。等待GPU到达相应的
    glFenceSync()
    提交点

请注意,可以有不同类型的同步,它们不直接绑定到特定的OpenGL调用。例如,在整个工作负载受GPU限制的情况下,CPU将排队等待无限多个工作,除非有一些限制。因此,驱动程序将在或多或少的任意点阻塞CPU,以使GPU赶上某一点。这可能发生在帧边界处,但不必如此。如果内存不足或内部驱动程序资源耗尽,则可能需要类似的同步。

不是100%确定,但我认为所有不返回任何内容的操作都是流水线操作。例如,glDrawArrays是流水线的,而glGenBuffers不是。
glFlush()
只提交挂起的工作,而不等待它完成。您可能会想到
glFinish()
,这样管道就不会被“阻塞”,而是实际上被耗尽了。“当我在glReadPixels()之后在CPU中设置时钟时,时钟记录的时间是什么时候?”@user1914692:这实际上取决于OpenGL实现。假设你做了一些事情,比如
draw_something();glFinish();时钟获取时间(时钟单调和开始);glReadPixels(&cpumem);时钟获取时间(时钟单调,&end)您将设置裸传输和格式转换时间。如果你