There are a few ways to disable EarlyZ list here:
Shader depth output disabled
Alpha test with depth or stencil writes on disabled
Alpha test with depth or stencil writes off enabled
Alpha to coverage with depth or stencil writes on disabled
Alpha to coverage with depth or stencil writes off enabled
sample mask contains 0 bit with depth or stencil writes on disabled
sample mask contains 0 bit with depth or stencil writes off enabled
shader writes SSBO disabled
shader calls imageStore() or imageAtomic*() disabled
shader discards a fragment disabled
earlyz on depth test before fragmentshader
earlyz off depth test after fragmentshader
Maxwell GPU还有个有意思的东西 打开earlyz 关闭color write 可以开4倍速zbuffer写
==================================================
讲一下pipeline在这部分的原理
通常 ps后面output merge阶段会有depth test 这样把 ps的结果B混到 color buffer上已有的结果A上面的时候 会按照深度 剔除
为了减小ps的计算量 会把depth test往前挪 就是earlyz
这个挪到前面的 深度测试 肯定需要用到 一个之前产生的 深度信息 所以 如果这个深度信息 在接下来的pipleine流程中 被改掉了 就不能在这次 的数据流中 提前使用 就是失效的
===
黄色部分理解有误 下面这部分我更新对此2.0版本的认识:
如果depthbuffer本次drawcall被更新 肯定也不是这次om阶段用来做 depth test的 而是下次用
失效的是另外一部分数据,之前的思考忽略了一点 有两部分数据在进行earlyz的时候会被使用 一个是depth buffer 另一个是以别的方式被记录的本次drawcall相关的深度信息 比如vertex position
经过前面的transform 得到的z 是这两部分数据拿来做earlyz的测试的 如果ps里对深度进行了改动失效的是后者
这里更正一下这个细节 所以受影响的是本次drawcall
这个事情 我目前认为 不会累积到后面的drawcall 比如在pc平台 和hsr失效的影响范围不一样 (待议)
====
这里上面的认识还是有问题
更新3.0版本的认识
参考powervr 两部分关于hsr 和earlyz的解释
我倾向 这个事情的判断肯定取决于earlyz的实现方式
我现在倾向他还是用一张depth buffer 做的 就像isp遇到 alphatest失效那件事一样
先 用本次 drawcall更新出来的 (因为在光栅化之后了)新的depthbuffer(就像isp那里)
用这个 做了测试 但是 shader里面如果discard了 usse才能得出这个结果 再回去更新 isp里面的depth 具体要看pc的硬件架构了
所以 行为和powervr很相似了 但是 我现在觉得这影响的是 这次drawcall之后的所有drawcall吗 这里是不是有问题
mobile 和pc不一样的地方在与isp还会有个影响这个tile 全部primitive的list 很可能排序了 从后到前
每次这个list里 如果 有alphtest isp原本的结果都会在usse之后更新 所以 所谓后面的 是指深度比alphatest那个primitive靠前的
如果有一个这样的结果 都要等这个结果返回 所以还是都挪到后面比较好 先画opque再画alphatest
而不是drawcall 时间靠后的
pc是没有这个primitivelist 的 晚提交的drawcall肯定依赖前面的结果
包含上述操作
SSBO shader storage buffer objects
Unlike UBOs, SSBOs: can be written to by the graphics core
can be used as compute kernel input/output
can be much larger than UBOs - megabytes instead of kilobytes.
have variable storage up to the range bound for the given buffer.
The actual size of the array, based on the range of the buffer bound, can be queried at runtime in the shader using the length function on the unbounded array variable.