由于我将所有c#SlimDX DX11渲染代码从我的表格(是的,我是一个懒惰的开发人员)移动到定制课程,我最近得到了一些滞后。我把我的程序打到了EQATEC Profiler中,并把它作为我滞后的主要原因:
现在很明显,postRender()中的任何内容都真正占用了宝贵的毫秒数。事实上,无论我遇到什么疯狂,错综复杂的代码,都可以有效地将帧速率降低到约15 FPS。
那么postRender()中有什么?只需一行代码:
swapChain.Present(0, PresentFlags.None);
我只是不知道是什么导致它减速太多,我根本没有对交换链代码做任何改动。所有我改变的是屏幕分辨率(1680x1050),但这应该是绝对正常的(作为参考,这台机器可以在该分辨率下以最大设置运行crysis2而不会出汗)。
有没有人知道什么可能导致交换链花费这么长时间呈现或者我应该在下一步看问题?
编辑:
查看我的代码的结构,我的RenderFrame()函数如下:
preRender();
DeferredRender(preShader);
//Composite scene to output image
CompositeScene(compositeShader);
//Post Process
PostProcess(postProcShader);
//Depth of Field
DoF(dofShader);
//Present the swapchain
postRender();
其中一些函数的结果基于之前的函数(例如,DeferredRender使用四个渲染目标以逐像素方式捕获漫反射光照,法线,位置和颜色.CompositeScene然后将它们全部放在一起。需要GPU才能继续计算上一步。整个过程继续进行,DoF需要PostProcess的结果等。因此唯一可能持有Swapchain.Present()的着色器必须是着色器它在函数DoF中运行,因为所有其他着色器都会导致CPU锁定直到它们完成。正确吗?
答案 0 :(得分:1)
有几个原因导致你可能会发现Present()在你的框架中占用了那么多时间。 Present调用是CPU和GPU之间同步的主要方法;如果CPU生成帧的速度比GPU处理它们的速度快得多,它们就会排队等候。一旦缓冲区变满,Present()会在等待它清空时变成一个美化的Sleep()调用。
当然,用你在这里提供的小信息几乎不可能说出来。仅仅因为一台机器运行“孤岛危机”并不意味着你可以放弃在卡上扔任何你想要的东西。仔细检查一下,你不希望渲染疯狂的几何体,并且你的着色器不会异常漫长而复杂。
还可以使用其中一个可用的GPU分析器查看您的应用; PIX是一个很好的基点,而NVIDIA和AMD每个都有自己的产品更具体的产品。最后,确保您的驱动程序已更新。如果驱动程序中存在错误,那么您有任何理由可以解决问题。