深度解析AMD GPU Hierarchical Z & Early-z被诸多限制的原因
上图是这片文档的总结。文档上写的很详细 Alpha test, alpha to coverage or texkill with depth or stencil writes on都会令Early Z实效。这点不难理解。之所以这样是因为AMD R600 Arch同时满足了以下两个条件:
第二个,D3D Graphics Pipeline把Alpha Test放在了Depth Test前面。
那么假如你一个Fragment在Alpha Test不通过,则Z-buffer就看不见这个Fragment,更新Z-buffer就无从谈起了,但是你一旦把Depth Test给Early了之后,那就等于还没有进行Alpha Test的时候这个Fragment就要访问Z-buffer。如果不写Z-buffer的话,倒也无所谓,读了就读了,Read-only是不会破坏现场的。但是AMD的策略是Early-Z的时候就要Update Z-buffer,那就没招了……所以Alpha Test和Early-Z一定是Mutex的!
Alpha to Coverage是DX10的新特性,是一种Dithering-like Transparent Alogrithm,用来实现一定程度上的OIT(Order-independent Transparent)。但是DX10 Functional Spec 并没有规定这个Feature的算法,甚至连一个性能或是行为指标都没有给。所以各家厂商实现就不一样了。至于AMD这个为什么会和Early-z冲突,没有具体Algorithm Spec我也不好下结论!我只能说AMD的这个算法肯定是对应于Alpha小于等于某个值的时候,则Cull掉这个Fragment而不生成任何得 Subsample Mask,这相当于一种变相的Alpha Test。所以在Early-z方面,行为和Alpha Test一样,与之发生冲突。
至此位置,我们可以看出,凡是在Depth Test之前能Fragment Culling的特性都会和Early-z有冲突,这也就不难解释texkill Instruction on PS 怎么会和Early-Z互斥了。
但是为什么不会和HZB冲突呢?答案很简单,HZB是On-chip的,所以当PS之后更新也不会影响性能。所以HZB在PS之后更新。而在PS之前只是Read-only的。但是为什么Early-Z也不这样做呢?答案很简单,Early-z是Off-chip的,难道要一个Fragment在Graphics Pipeline上访问两次Depth Buffer?这不是和Reduce Z Traffic的初衷相反了么?!在GPU上,Memory Bandwidth是永远不够用的。所以,没人愿意同一件事干两次。(当然,兄弟们就不要拿Z-first Rendering和我抬杠了…,我知道我说的不严谨)
引用:
[1]F. Permadi,"Ray-Casting Tutorial",http://www.opengpu.org/bbs/viewthread.php?tid=369&extra=page%3D1
[2]Paul Hsieh,"Graphics Accelerators -- what are they?",http://www.opengpu.org/bbs/viewthread.php?tid=268&extra=page%3D2
[3]Noel D.Scott,"An Overview of the VISUALIZE fx Graphics Accelerator Hardware"
[4]Kristof Beets,"PowerVR Tile Based Rendering",http://www.opengpu.org/bbs/viewthread.php?tid=243&extra=page%3D1
[5]nVIDIA,"Deferred Shading" , http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf
后记:其实本文还可以写的更长,在Visibility Test方面的确有很多东西可以写,不过以后我会更多的写一些关于图形硬件方面的东西,希望朋友们批评 :〉