Two Pass Rendering Flickers on iOS12

Hi,


We use two pass rendering in our game. In the first pass we just write depth to depth buffer, and in the second pass, we use a "equal" depth-test to get correct z-order. Before iOS12, it works perfectly. But on iOS12, it starts to flickers.


Seems like that the output vertex positions in the first pass is not completely equal to those in the second pass, so that the "equal" depth-test fails randomly. We tried to set fastMathEnabled=false in the MTLCompileOption, then the rendering is correct.


But disable fast-math will impact the performance a lot. We are wondering if there is a better solution.


Thanks.

Replies

From the Metal Shading Language specification pdf:


[[invariant]] indicates that the floating-point math used in multiple function passes must generate a vertex position that matches exactly for every pass. [[invariant]] may only be used for a position in a vertex function (i.e., fields with the [[position]] attribute) to indicate the result of the calculation for the output is highly likely (although not guaranteed) to be invariant. This position invariance is essential for techniques such as shadow volumes or a z- prepass.


EDIT: That said, invariant is apparently only supported in MetalSL 2.1. If you're seeing the change you described when targeting an earlier Metal version, that sounds like a bug/regression.