jay*_*lee 101 c c++ opengl graphics
我无法区分调用glFlush()和调用之间的实际区别glFinish().
文档说glFlush()并且glFinish()会将所有缓冲操作推送到OpenGL,以便可以确保它们都将被执行,区别在于glFlush()直接返回作为glFinish()块的所有操作都完成.
阅读完定义之后,我认为如果我使用glFlush()它,我可能会遇到向OpenGL提交更多操作而不是执行的问题.所以,只是为了尝试,我换掉了我glFinish()的东西glFlush(),看,我的程序运行(据我所知),完全相同; 帧率,资源使用,一切都是一样的.
所以我想知道这两个调用之间是否存在很大差异,或者如果我的代码使它们运行没有区别.或者应该使用哪一个而不是另一个.我还认为OpenGL会有一些调用,比如glIsDone()检查a的所有缓冲命令glFlush()是否完整(因此不会比OpenGL更快地发送操作到OpenGL),但我找不到这样的函数.
我的代码是典型的游戏循环:
while (running) {
process_stuff();
render_stuff();
}
Run Code Online (Sandbox Code Playgroud)
Mal*_*sen 91
请注意,这些命令自OpenGL早期就存在.glFlush确保以前的OpenGL命令必须在有限的时间内完成(OpenGL 2.1规范,第245页).如果直接绘制到前缓冲区,这将确保OpenGL驱动程序开始绘制而不会有太多延迟.当你在每个对象之后调用glFlush时,你可以想到一个复杂的场景,它出现在屏幕上的对象后面.但是,当使用双缓冲时,glFlush几乎没有任何影响,因为在交换缓冲区之前,更改将不可见.
glFinish 在完全实现之前发出的命令的所有效果之前不会返回.这意味着程序的执行会在此处等待,直到绘制完每个最后一个像素,OpenGL无需执行任何操作.如果直接渲染到前缓冲区,glFinish是在使用操作系统调用截取屏幕之前调用make.它对双缓冲的用处要小得多,因为你没有看到你被迫完成的更改.
因此,如果你使用双缓冲,你可能不需要glFlush和glFinish.SwapBuffers隐式地将OpenGL调用指向正确的缓冲区,不需要先调用glFlush.并且不介意强调OpenGL驱动程序:glFlush不会扼杀太多命令.不保证此调用立即返回(无论这意味着什么),因此它可能需要任何时间来处理您的命令.
And*_*oss 21
正如其他答案所暗示的那样,根据规范确实没有好的答案.一般的意图glFlush()是,在调用它之后,主机CPU将没有与OpenGL相关的工作要做 - 命令将被推送到图形硬件.一般的意图glFinish()是,在它返回之后,不会剩下剩余的工作,结果也应该是所有适当的非OpenGL API(例如从帧缓冲区读取,截图等......).这是否真的发生了依赖于驱动因素.该规范允许大量的合法范围.
Tar*_*ara 14
我总是对这两个命令感到困惑,但是这个图像让我很清楚:
显然,除非累积了一定数量的命令,否则某些GPU驱动程序不会将发出的命令发送到硬件.在此示例中,该数字为5.
该图显示了已发布的各种OpenGL命令(A,B,C,D,E ...).正如我们在顶部看到的那样,命令还没有发出,因为队列尚未完整.
在中间我们看到如何glFlush()影响排队的命令.它告诉驱动程序将所有排队的命令发送到硬件(即使队列尚未填满).这不会阻止调用线程.它只是告诉驱动程序我们可能不会发送任何其他命令.因此,等待队列填满将是浪费时间.
在底部我们看到一个使用的示例glFinish().它几乎做同样的事情glFlush(),除了它使调用线程等到所有命令都被硬件处理.
图像取自"使用OpenGL进行高级图形编程"一书.
如果你没有看到任何性能差异,那就意味着你做错了什么.正如其他人提到的那样,你也不需要调用,但是如果你调用glFinish,那么你将自动失去GPU和CPU可以实现的并行性.让我深入一点:
实际上,您提交给驱动程序的所有工作都是批处理的,并且可能稍后发送到硬件(例如,在SwapBuffer时间).
所以,如果你正在调用glFinish,那么你实际上是强迫驱动程序将命令推送到GPU(它直到那时才进行批处理,并且从未要求GPU继续工作),并且停止CPU直到命令被推送完全为止执行.因此,在GPU工作的整个时间内,CPU不会(至少在此线程上).在CPU完成其工作(主要是批处理命令)的所有时间里,GPU都没有做任何事情.所以是的,glFinish会伤害你的表现.(这是一个近似值,因为驱动程序可能会开始让GPU在某些命令上工作,如果它们中的很多已经批处理.虽然这不常见,因为命令缓冲区往往足够大以容纳相当多的命令).
现在,你为什么要打电话给glFinish呢?我使用它的唯一时间是我有驱动程序错误.实际上,如果您发送到硬件的命令之一崩溃了GPU,那么确定哪个命令是罪魁祸首的最简单选项是在每次Draw之后调用glFinish.这样,您可以缩小确切触发崩溃的范围
作为旁注,像Direct3D这样的API根本不支持Finish概念.
glFlush真的可以追溯到客户端服务器模型.您通过管道将所有gl命令发送到gl服务器.那管道可能会缓冲.就像任何文件或网络i/o可能缓冲一样.glFlush只说"现在发送缓冲区,即使它还没有填满!".在本地系统上,这几乎从不需要,因为本地OpenGL API不太可能缓冲自身并且只是直接发出命令.所有导致实际渲染的命令都会执行隐式刷新.
另一方面,glFinish用于性能测量.GL服务器的PING类型.它往返一个命令并等待服务器响应"我闲置".
如今,现代的本地司机都有很有创意的想法,这意味着闲置的意义.它是"所有像素被绘制"还是"我的命令队列有空间"?还因为许多旧程序在他们的代码中散布了glFlush和glFinish而没有理由像许多现代驱动程序一样编码,只是将它们视为"优化".真的,不能责怪他们.
总而言之:除非您编写古老的远程SGI OpenGL服务器,否则将glFinish和glFlush视为无操作.
| 归档时间: |
|
| 查看次数: |
63434 次 |
| 最近记录: |