我为主要场景,阴影,反射和后处理地图整体渲染了一个带有50个drawcall的简单场景。对于以下测试,我将阴影贴图大小设置为4k(4096x4096),并将改变反射贴图大小。
测试将在具有1Gb视频内存的NVidia GTX 650上运行。当测试应用程序运行时,所有正在运行的应用程序只使用600多MB的视频内存,因此我有200-300 MB的可用视频内存。 Vsync已禁用,应用程序中没有FPS边界,因此GPU利用率为99%-100%。所有指标均使用Nvidia驱动程序工具进行衡量:
好的,让我们启动应用程序并根据反射贴图大小测量它的FPS:
从2k切换到4k反射纹理会显着降低FPS速率,而测量实用程序显示PCI带宽利用率异常,从1%增加到65%。同时,使用的视频内存量不超过700Mb(可用1Gb)。
好的,让我们运行Nvidia graphics debugger,看看最重的OpenGL调用是什么。它表明反射贴图的glClear
需要超过10毫秒!将反射贴图切换为2k会将此值降低到数千纳秒,这对于当前的硬件来说是可以的。您可以说glClear
实际上刷新了所有以前的渲染命令,但是如果我在调试器中禁用了清除调用,则帧速率会增加到90-100 FPS。
此行为也可以使用Emscripten + Chrome重现,但在Chrome中,慢功能是glDrawElements
,它将地形绘制到shadowmap。甚至更奇怪的是,绘制主要场景地形(具有更重的片段着色器)的调用花费更少的时间。
那么问题是什么?为什么驱动程序在拥有300Mb的免费视频内存时通过PCIe传输内容?可能是纹理不当或帧缓冲使用的原因?