Mali GPU的独有特性
众所周知,Tile Based Rendering已经成为了事实上的移动平台GPU标配,不仅如此,intel的新一代集成显卡也悄悄地加上这一特性的支持。移动平台GPU御三家(Adreno,Mali,PowerVR)也在自己的解决方案里,纷纷加上了自己的私货,不仅能够优化性能,如果被标准化组织(Khronos)看上了列为下一代API的标配,又可以在市场竞争中多一份筹码。下面介绍Mali-GPU提供的一些独有特性。
FPK(Forward Pixel Killing)
在一个Render Pass中,每一个Tile中的每个像素可能会被绘制多次,由此带来的Overdraw问题不可忽视。通常的做法是采取对模型的渲染顺序进行排序,按照Opaque:从近到远,Transparent:从远到近来进行,这样可以充分利用Early-Z进行剔除。但是这样的做法要求很高,一般很难做到完美。Mali的做法是,如果每个Pixel会被渲染多次(假设都是Opaque),那么将其放入一个队列中,不会马上进行Fragment计算,如果后进入的Fragment深度比队列中前面的要小(假设ZTest为Less),那么前面的将会被抛弃掉。
和PowerVT的HSV(Hidden Surface Removal)相比,这个方案存在一定的剔除不干净的可能(队列中的Fragment已经被处理了),但是其实现起来简单,如果不生效,队列就退化成正常渲染所用的队列。不过Mali推荐还是使用排序的方式以充分进行Overdraw剔除。
TE(Transaction Elimination)
Transaction Elimination也是一种很有效的降低带宽的方法。在有些情况下,只有部分Tile中的内容会变化(例如摄像机不动,一个Tile中只有静态物体)。此时通过比较该Tile前一次和本次的渲染结果的CRC值,可得到Tile是否变化的结论,如果不变,那么就没有必要执行Tile到System Memory的写回操作了,有效地降低了带宽占用。
AFBC(Arm FrameBuffer Compression)
FrameBuffer中的内容,以无损的压缩格式存储,不仅降低了传输带宽,还降低了显存占用,是一种用时间换空间/带宽的技术(这个技术貌似AMD的显卡也用了)。
然而这种技术有一定的局限性,如果Texture仅作为FrameBuffer的Color Output和Shader中使用texture()进行读取,那是没问题的,可如果使用了imageLoad和imageStore方法,驱动就是隐式地插入一个解压缩的步骤。这样反而造成了更多地存储占用和更多地计算负担。
从上面的描述可以看出,这种算法可能是一种基于块的压缩算法,如果使用texture()去读,会去走texture缓存那条读取通道,这条通道上本来就有各种压缩格式的解压缩算法,再加一种也不是什么事。而imageLoad和imageStore走的是另一条通用的存储读写通道,这条通道如果想加上on the fly的压缩/解压缩,看上去不是很现实。
目前也没有扩展进行显式的控制(待查证),如果一个Texture被作为FrameBuffer的Color Output写入之后马上被Compute Shader用到了,那不是还得解压缩一份?这个问题有待实验考证。
参考资料:
- The Mali GPU: An Abstract Machine
- Arm Mali GPU Bast Practices Programmer Guide