自从将我的所有c#SlimDX DX11渲染代码从我的窗体(是的,我是一个懒惰的开发人员)移到定制类之后,最近我一直有点滞后。我将程序重入EQATEC Profiler,并认为这是造成我滞后的主要原因:
现在很明显,postRender()中的内容确实占用了宝贵的毫秒。实际上,无论我在其中遇到什么疯狂的,令人费解的代码,都可以有效地将其帧速率降低到15 FPS。
那么postRender()中有什么?只需一行代码:
swapChain.Present(0, PresentFlags.None);
我只是不知道是什么原因导致它减速这么快,我根本没有对swapchain代码进行任何更改。我所更改的只是屏幕分辨率(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锁定,直到完成。
最佳答案
有几个原因导致您可能会发现Present()在框架中占用大量时间。 Present调用是CPU和GPU之间同步的主要方法。如果CPU生成的帧比GPU处理帧的速度快得多,它们就会排队。一旦缓冲区已满,Present()就会变成一个美化的Sleep()调用,同时等待其清空。
当然,要在这里给出的少量信息很难说。仅仅因为一台机器运行《孤岛危机》并不意味着您可以随意扔任何东西。仔细检查您是否不希望渲染大量的几何图形,并且您的着色器没有异常长且复杂。
另外,使用可用的GPU探查器之一查看您的应用; PIX是很好的基础,而NVIDIA和AMD各自为自己的产品提供了自己的更具体的产品。最后,确保您的驱动程序已更新。如果驱动程序中存在错误,则您有任何可能推理出此问题的机会就将落空。
关于c# - Swapchain.Present()花费的时间太长,导致出现滞后,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10373169/