我正在开发一款大型游戏,当你在游戏世界中移动时,它会在关卡数据(包括着色器)中流动.因为着色器是编译/链接的,或者在第一次使用时,我不希望在帧速率上出现问题.
我有一个着色器编译和链接工作在一个单独的线程与自己的open-gl上下文.但是我无法使着色器的预热在单独的线程上工作(因此在首次使用着色器时没有性能损失).
在iOS或OpenGL文档中,任何地方都没有提到预热.然而,它在OpenGL ES分析器中提到(从xcode分析时可用的仪器之一).在这个工具中,每次使用之前没有用于渲染某些内容的着色器渲染某些内容时,我会收到"在预热阶段之外编译的着色器"警告."扩展细节"说:
"OpenGL ES Analyzer检测到一个着色器编译,它不是初始预热阶段的一部分.着色器编译可能是一个耗时的操作.要避免它们,请预热所有用于渲染的着色器.为此,在应用程序启动时进行预热通道使用每个着色器程序执行绘图调用,使用任何gl状态设置,着色器程序将与.一起使用.混合,颜色掩码,逻辑运算,多重采样,纹理格式和点原始状态等状态可以都会影响着色器编译."
"汇编"这个词在这里有点令人困惑.顶点和片段着色器已经编译,程序已经链接.但是第一次使用给定的OpenGL状态渲染某些东西时,它会在着色器上做更多工作,以便针对该状态对其进行优化.
我有代码通过在第一次使用之前渲染零大小的三角形来预热着色器.
如果我使用与正常渲染相同的Open GL上下文编译,链接和预热主线程上的着色器,那么它可以工作.但是,如果我在具有单独的Open GL上下文的后台线程上执行此操作,则它不起作用(它在第一次使用时仍会收到Analyzer警告).
所以...可能是在单独的上下文中预先设置着色器对其他上下文没有影响.或者可能是我没有所有相同的状态设置单独的上下文.可能需要设置很多潜在的Open GL状态.我在后台线程上使用了屏幕外渲染缓冲区,因此可以将其视为状态的一部分.
有没有人成功地在后台线程上进行预热?
说实话,直到昨天我才对这件事情一无所知,虽然我已经在我的发动机优化工作了一段时间.所以,首先,谢谢你的提示:).
从那时起我就开始研究着色器变暖的主题,而且我没有找到太多的东西.
我在标题为"ATI OpenGL编程和优化指南"的文档中找到了官方AMD文档:
这是一个摘录,指的是着色器的变暖:
引用:
虽然R500本身支持片段着色单元中的流控制,但R300和R400 asics却不支持.R300和R400的静态流量控制由驱动程序模拟,编译未使用的条件并根据设置的常量展开循环.即使R500 asics系列本身支持流控制,驱动程序仍将尝试编译静态流条件,使其能够重新组织着色器指令以实现更好的指令调度.驱动程序还将尝试将已编译的着色器缓存到特定的静态流条件集,以预期其重用.因此,在编写使用静态流控制的片段程序时,建议通过在第一帧上渲染虚拟三角形来"加热"着色器缓存,该三角形使用与着色器生命周期相关的常见静态条件排列.
我发现的最佳解释如下:
http://fgiesen.wordpress.com/2011/07/01/a-trip-through-the-graphics-pipeline-2011-part-1/
引用:
顺便说一句,这也是您第一次使用新着色器或资源时经常会看到延迟的原因; 很多创建/编译工作都是由驱动程序推迟的,只有在实际需要时才会执行(你不会相信某些应用程序创建了多少未使用的垃圾!).图形程序员知道故事的另一面 - 如果你想确保实际创建某些东西(而不是只保留内存),你需要发出一个虚拟绘图调用,用它来"加热".丑陋和烦人,但自从我1999年第一次开始使用3D硬件以来就是这种情况 - 这意味着,在这一点上它几乎是生活中的事实,所以要习惯它.:)
在本演示文稿中,提到了cryteck引擎如何在远程引擎上执行它,尽管它主要与DirectX相关.
http://www.powershow.com/view/11f2b1-MzUxN/Far_Cry_and_DirectX_flash_ppt_presentation
我希望这些链接在某种程度上有所帮助.
| 归档时间: |
|
| 查看次数: |
1835 次 |
| 最近记录: |