我无法区分调用之间的实际差别glFlush()
和glFinish()
该文档说glFlush()
和glFinish()
将推动所有缓存操作的OpenGL,这样一个可以放心,他们都将被执行,不同之处在于glFlush()
立即返回,其中作为glFinish()
块,直到所有的操作都完成。
读过的定义,我想,如果我是用glFlush()
我可能会遇到更多的提交操作的OpenGL比它可能执行的问题。 所以,只是尝试一下,我换了我glFinish()
的glFlush()
你瞧,我的程序运行(据我所知),完全一样的; 帧速率,资源占用一切都是一样的。
所以我想知道如果有两个电话之间相差太大,或者如果我的代码使它们运行没有什么不同。 或者其中一个应使用与其他。 我也想通使OpenGL会有像一些呼叫glIsDone()
以检查是否所有的缓冲命令的glFlush()
完成或没有(这样一个不发送操作OpenGL的速度比它们可以执行),但我能找到没有这样的功能。
我的代码是典型的游戏循环:
while (running) {
process_stuff();
render_stuff();
}
Answer 1:
注意,由于OpenGL的初期存在这些命令。 glFlush确保以前的OpenGL命令必须完成在有限的时间 ( 的OpenGL 2.1规格 ,245页)。 如果你直接绘制到前台缓冲区,这应确保OpenGL驱动程序启动时没有太多的延迟绘制。 你能想到的,当你每个对象后调用glFlush屏幕上的对象后出现的对象,一个复杂的场景。 但是,使用双缓冲时,glFlush有几乎没有任何影响,因为直到你交换缓冲区的更改将不可见。
glfinish在不返回,直到自上次发行的命令所有的效果[...]得到充分实现 。 这意味着你的程序的执行,直到每一个最后的像素被渲染和OpenGL拥有无事可做这里等待。 如果直接渲染到前台缓冲区,glfinish在是呼叫使用操作系统调用采取截屏前进行。 这是一个双缓冲几乎没什么用处,因为你没有看到你不得不完成更改。
所以,如果你使用双缓冲,你可能不会需要既不glFlush也不glfinish在。 SwapBuffers隐含指示OpenGL调用到正确的缓冲区, 没有必要首先调用glFlush 。 并且不介意强调OpenGL驱动程序:glFlush不会呛太多的命令。 它不保证该调用立即返回(知道是什么意思),所以可以把它需要处理你的命令的任何时间。
Answer 2:
至于其他的答案已经暗示,实在是没有很好的答案按规范。 的总的意图glFlush()
是调用它之后,主机CPU将没有OpenGL相关的工作要做-命令将已经被推到了图形硬件。 的总的意图glFinish()
是返回后, 没有剩下的工作就是离开了,结果应该是可以过所有适当的非的OpenGL的API(例如,从帧缓冲,截图等..读取)。 这是否真的会发生什么是驱动程序相关。 该规范允许一吨纬度,什么是合法的。
Answer 3:
我总是搞不清这两个命令太多,但这一形象使这一切明确对我说: 显然,除非命令一定数量已经积累了一定的GPU驱动程序不发送该发出的命令到硬件。 在这个例子中该数为5。
图像显示已经发出的各种命令的OpenGL(A,B,C,d,E ...)。 正如我们可以在上面看到,该命令没有得到发行,但因为队列还没有满。
在中间,我们看到glFlush()
影响将排队的命令。 它告诉司机所有排队命令发送到硬件(即使队列还没有满)。 这不会阻止调用线程。 它只是标志着我们可能不会发送任何附加命令司机。 因此,等待队列被填满将是浪费时间。
在底部,我们看到使用的例子glFinish()
它几乎同样的事情glFlush()
但是它可以调用线程等待,直到所有的命令已经由硬件处理。
从书的“高级图形编程利用OpenGL”拍摄的图像。
Answer 4:
如果你没有看到任何性能上的差异,这意味着你正在做的事情是错误的。 正如一些人所说,你不需要任何电话,但如果你调用glFinish,那么你就自动消失了并行的GPU和CPU可以实现。 让我深入了解:
在实践中,所有提交给司机的工作是分批,并有可能的方式后发送给硬件(例如,在SwapBuffer时间)。
所以,如果你调用glfinish在,你基本上强迫司机的命令推到GPU(它成批直到那时,从不问到GPU上工作),并暂停CPU,直到推的命令是完全执行。 所以,在整个期间的GPU工作时,CPU没有(至少在这个线程)。 和所有的时间,CPU不工作(主要是批处理命令),该GPU没有做任何事情。 所以呀,glfinish在应该伤害你的表现。 (这是一个近似值,因为如果他们中的很多已经分批司机可能开始有一些命令GPU的工作。这不是典型的现象,因为命令缓冲区往往是大到足以容纳相当多的命令)。
现在,为什么你会调用glFinish可言呢? 我使用的唯一的时候,我有司机的错误它是。 事实上,如果您发送到硬件的命令之一崩溃的GPU,那么你的最简单的选项,找出哪些命令是罪魁祸首就是每次抽奖后调用glFinish。 这样,您可以缩小究竟是什么触发了崩溃
作为一个侧面说明,喜欢的Direct3D API不支持一个完成的概念都没有。
Answer 5:
glFlush真的可以追溯到客户端服务器模式。 您可以通过管道将所有GL命令到GL服务器。 该管道可能缓存。 就像任何文件或网络I / O缓冲区可能。 glFlush只是说“现在发送缓冲区,即使并未装满!”。 在本地系统中,这是几乎从来没有必要的,因为本地的OpenGL API是不太可能缓冲区本身和公正问题直接命令。 也是导致实际渲染的所有命令将进行隐齐平。
在另一方面glfinish在是为性能测量取得。 一个PING到GL服务器的种类。 它的往返命令并等待服务器响应“我是闲”。
如今现代的,当地的司机颇有创意的想法这意味着什么空闲虽然。 就是这样“的所有像素画”或“我的命令队列有空间”? 也正因为许多旧的程序洒glFlush和glfinish在整个代码没有道理的巫术编码许多现代司机不理会他们作为“优化”。 不能怪他们,真的。
因此,在总结:在实际治疗都glfinish在和glFlush因为没有OPS除非你是编码一个古老的远程SGI的OpenGL服务器。
Answer 6:
看看这里 。 总之,它说:
glfinish在()具有如glFlush()相同的效果,通过添加该glfinish在()将阻塞,直到提交的所有命令都被执行。
另外文章介绍了其他方面的差异:
- 交换功能(在双缓冲应用中使用的),自动刷新命令,所以不需要调用
glFlush
-
glFinish
部队的OpenGL到(与垂直同步EG)建奇功的命令,这是一个坏主意
综上所述,这意味着使用双缓冲时,除非你的交换缓冲器实现不自动刷新命令,你甚至都不需要这些功能。
Answer 7:
似乎没有要查询缓冲区的状态的一种方式。 有了这个苹果扩展其可以起到同样的目的,但它似乎没有跨平台的(没试过)在它看一眼,似乎之前flush
你推入围篱命令; 那么你就可以查询该围栏的地位,因为它移动通过缓冲。
我不知道你是否可以使用flush
之前缓冲的命令,但在此之前开始渲染调用下一帧finish
。 这将允许你开始处理下一帧作为GPU的工作,但如果它不是由你回来的时间内完成, finish
将阻止,以确保一切都在新鲜状态。
我没有试过,但我会很快。
我已经尝试过了一个旧的应用程序,具有相当甚至CPU和GPU的使用。 (它最初使用的finish
。)
当我改成了flush
的结束和finish
的开始,没有直接的问题。 (一切似乎都很正常!)的方案增加的反应,可能是因为CPU未停止等待的GPU。 这绝对是一个更好的方法。
为了进行比较,我删除finished
从帧的开始,留下flush
,并且执行相同的。
所以,我要说的使用flush
和finish
,因为当缓冲区为空在调用finish
,没有性能损失。 而且我猜如果缓冲区满了,你应该要finish
反正。
Answer 8:
现在的问题是:你想而OpenGL命令被执行,或者只是已经被执行的OpenGL命令后运行你的代码继续运行。
这可关系的情况下,像在网络延迟,有图像已被绘制或这种只有在某些控制台输出。
文章来源: opengl: glFlush() vs. glFinish()