Opengl中的重复状态更改

Ayy*_*ppa 4 iphone gpu opengl-es cocos2d-iphone

   Its a fact that state changes in Opengl leads to performance degradation. 
Run Code Online (Sandbox Code Playgroud)

//说如果我在每一帧中重复调用glEnable(GL_DEPTH_TEST)/ glBlendFunc.

编辑:>这里我只想说'这样的状态变化状态变化导致性能问题'

任何人都可以详细解释一下这个原因吗?

据我所知,可以在寄存器中维护状态,并且可以在传统渲染GPU(立即模式类型)中使用状态,或者可以在基于Tile的延迟渲染中为每个绘制调用维护状态向量.维护成本真的很高吗?(想知道为什么GPU还有这个问题:()

dat*_*olf 17

实际上,状态变化可能是性能杀手.然而,要问的重要问题是:"哪个州".一些状态变化是如此便宜,因此跟踪它们以最小化它们的使用是没有意义的.

在今天的OpenGL实现中glEnable/ glDisable几乎没有性能压力(当然,一些状态被禁用对渲染性能有很大影响).

那么什么是昂贵的状态变化?关于杀死缓存内容的所有内容,缓存中的数据将以高带宽访问或需要高吞吐量.

纹理是关于要切换的最昂贵的数据源.因此,作为一项基本规则,您可以使用纹理对场景进行排序,以尽可能少地切换纹理.

另一个昂贵的状态变化是切换着色器.切换着色器会以两种方式对GPU产生负面影响:首先,它会强制处理单元完全停止,刷新其执行管道.重新填充管道,直到事情工作"像发条"需要几百个周期.另一个问题是,不同的着色器具有不同的执行和数据访问模式.执行模式由代码路径预测单元确定,以估计哪些操作最有可能被执行.这也意味着知道要预取哪些数据.切换着色器会破坏这些重要信息.

非常便宜但不是免费的国家是可用一小组数字描述的任何东西:制服.切换制服非常便宜,因为它与GPU的通信只需要非常少的开销,并且由于Uniforms存在于寄存器中,因此更改它们既不会影响高速缓存行也不会影响执行预测.如果你想知道传统的固定功能OpenGL:转换矩阵,照明参数,剪裁平面是制服(只需看看OpenGL-2.1 GLSL规范,其中有内置制服).

  • 由于您将对许多几何体和纹理使用相同的着色器,并且由于您将为不同的着色器使用一组完全不同的纹理,因此实用的方法是先按纹理排序,然后按着色器排序。由于纹理和着色器之间的关联,这也最大限度地减少了着色器切换。–– 顺便说一句,长期以来,建议首先对近远的几何进行排序,以有效利用早期的深度测试。这仍然在多通道渲染器中完成,它使用遮挡查询来调整它们的渲染队列和延迟渲染器。 (2认同)