We are using first pass depth. I know it's not recommended, but we have one and need it. Deferred renders uses this, and we do too.
We've tried setting [invariant] on the position, and now are resorting to slope and depth biasing the second pass. We even set -fpreserve-invariance on the compiler. This whole construct is confusing. "invariant" was added in MSL 2.1, but requires iOS 13 to set that compiler flag, and then other code states that flag must be set for iOS 14 and macOS11 SDK use (minSDK? buildSDK?). We also tried disabling -fno-fast-math to no avail.
But why is a simple v = v * m calculation different once polys hit the near plane or the viewport edges. The polys then seem to per-tile z-fight. Some tiles have stripes of z, and some are just completely missing. These are the same tris going through two shaders that do the same vertex calc.
That shouldn't be happening, unless the tiles are computing gradients per tile incorrectly from the one pass to the next. On long clipped tris, it looks like a hardware/driver bug computing consistent depths across the same triangles. This was tested on older (iPhone 6) and newer iOS devices and M1 MBP.