当前位置: 华文问答 > 数码

Tile

2016-08-07数码

早期的渲染方式都是IMR(Immediate Mode Rendering,也就是Full Screen,因为它不去分Tile), IMR的优势 是每个primitive直接提交渲染,pipeline没有中断,渲染速度快,pipeline并行起来时,每个Raster core只要负责render分给它的primitive即可,无需其他控制逻辑,只需在pixel shader后对Raster出的pixel做个排序:

IMR的劣势 在于带宽压力和功耗较大:

  1. z test跟blending都要频繁从framebuffer里读数据,毕竟framebuffer是位于Memory上,带宽压力和功耗自然高;
  2. Overdraw的问题,比如Application在一帧里先画了棵树,然后画了面墙刚好遮住了树,在IMR下树仍然要在Pixel Shader里Sample texture,而Texture也是放在Memory,访存功耗大。

正因为这种劣势,许多Mobile GPU转向TBR(Tile Based Rendering),比如Imagination家的PowerVR,Arm家的Mali,Qualcomm家的Adreno(从AMD的Imageon收过来的),其实PC也有过尝试TBR,但最终或失败或取消,如微软的Talisman, PowerVR的Kyro,Intel的Larrabee都失败了,Nvidia的PC GPU Maxwell据说用了TBR做优化(但NV的mobile GPU tegra是IMR的,好吧):

为什么mobile GPU要转向TBR呢,因为 TBR 解决带宽功耗大 的两个源头提供了机会:

  1. 对于IMR所有 read z/framebuffer,到了TBR通通不需要 。TBR只需render完tile后把on-chip的pixel写到frame buffer(不需要写z,因为下一帧不需要用到前一帧的z和color)。
    这个好处在于TBR将Screen Tiling。这样,每次render的区域变小,小到可以把z/framebuffer搬到on-chip,快,省电。
    Tiled也意味着Deferred:要延迟到整个场景的primitive都收到后才能开始Raster 。为什么?试想,刚拿到整个场景一半的primitive就开始Raster了,那么render结束后z buffer就必须写回framebuffer,然后另一半的primitive开始raster时还必须把z/framebuffer从memory读回来,这样一来就大打折扣了。
  2. TBR给消除Overdraw提供了机会 ,PowerVR用了HSR技术,Mali用了Forward Pixel Killing技术,目标一样,就是要最大限度减少被遮挡pixel的texturing和shading,具体见后文。

Tiled要求Defer,把pipeline提前打断,从parallel rendering的角度看,IMR跟TBR是Sort Last和Sort Middle的区别:

Sort Middle:

Sort Last:

但凡并行渲染,都希望vertex直接找IDLE的shader,raster等资源执行,吐出数据,每个硬件资源之间不用互相通信,结果不需要统筹,但Graphics API的渲染是有顺序的,例如blending时Triangle的顺序决定blending pixel的先后,而并行的rendering快慢不易,最终必须有个阶段做个排序(Sort),用IMR的话,是到了pixel shading后才sort,简单;用TBR的话,是在Geometry变化后,在Raster前做Sort,复杂,但有优化空间。

再说说TBR的劣势,比较下IMR和TBR两者的pipeline和memory access:

TBR的pipeline被分成两部分:
1)第一部分处理Geometry的transform和场景的tiling,然后往memory里写入Geometry的数据和每个tile所要rendering的Geometry,好吧,跟IMR比起来多了memory的开销,读写,这个是Trade off,没有绝对好坏,总之说是机会,优化做得好就赚。例如Tile Size就是个Trade off点,大Tile意味着更少的Tile,重复setup的primitive(一个primitive覆盖多个tile)更少,但也意味着每个tile有更多的triangle,on-chip buffer更大。

不过Tile list需要把每个draw的state info和所有primitive数据都保存起来,场景大的时候memory会overflow,overflow的问题可以优化,比如选择一部分tile(PowerVR的macro tile)做rendering(这时需要读写memory上的z/framebuffer,牺牲下bandwidth和power,没办法)然后释放这部分tile的memory。

PC屏幕大,PC game场景复杂,对Tile list压力大,另外PC追求frame rate,所以很少用TBR,即使用了,遇到复杂游戏场景估计会切换到IMR。

2)第二部分是tile raster, HSR Forward Pixel Kill 就是在这个阶段做优化。

PowerVR的整体架构是这样子的(Imagination官网图片):

HSR 对完成覆盖每个Tile的每个primitive的每个pixel做z test,最终保留最近的pixel(如果有blending,还需要保留透明半透明的pixel),最终每个pixel location只有一个pixel进shading(如果无blending的话)。

Forward Pixel Kill 会让primtive cover到的每个pixel都进 shading thread(准确是quad,因为Pixel Shading是以quad为单位的),Mali用FPK logic和FPK buffer完成Forward Pixel Kill,其输入为每个pass z test的quad(意味着每个input的quad是已收到的,对应同一位置的所有quad中距离眼睛最近)

  • 如果Raster新产生的quad pass test,并且quad的4个pixel被fully covered,那就把与该quad具有相同位置的,更早的(意味着更远)那些thread全终止(它们可能还在FPK Buffer或已经在近Fragment Shader了)。
  • 另外,当quad被两个较近triangle组合起来cover到时,较远的triangle对应该位置的quad也不需要做shading。因此为进一步优化,Mali保存了整个tile所有Quad最近一次的coverage,如果FPK新近的quad不是full covered,但与该quad最近的一次coverage相或后是full coverage,则类似1),要把更早的thread全终止,即发出kill信号。
  • 另外, TBR和TBDR是两个很容易被混淆的概念,因为各家厂商用的术语不一样
    其实在ARM看来,TBR延迟了Rendering(第一个阶段的整个场景被tiling后),所以他家认为TBR跟TBDR(Tile-Based Deferred Rendering)是同一个概念;
    而在Imagination看来,PowerVR的HSR把texturing和shading也延迟了(剔除不可见pixle之后),它家认为TBR+HSR才是真正意义的TBDR。

    所以可以看出,IMR的pipeline畅通无干扰,sorting简单,TBR的sorting较复杂,但也给低功耗优化提供了灵活的选择。另外TBR pipeline的分割让pipeline中断了,各种defer,跟IMR比起来,速度也可能会进一步被影响而变慢。

    总结一下,TBR用增大memory resource,以及(有可能)降低render rate的代价,获得降低bandwidth,power的效益。