<div dir="ltr"><div>Hi,</div><div><br></div><div>"is_used_once" within an inexact transformation in nir_opt_algebraic can lead to geometry differences with multi-pass rendering, causing incorrect output. Here's an example to proof this:<br></div><br><div>Let's assume there is a pass that writes out some intermediate value from the position calculation as a varying. Let's assume there is another pass that does the same thing, but only draws to the depth buffer, so varyings are eliminated. The second pass would get "is_used_once" because there is just the position, and let's assume there is an inexact transformation with "is_used_once" that matches that. On the other hand, the first pass wouldn't get "is_used_once" because there is the varying. Now the same position calculation is different for each pass, causing depth test functions commonly used in multi-pass rendering such as EQUAL to fail.<br></div><div><br></div><div>The application might even use the exact same shader for both passes, and the driver might just look for depth-only rendering and remove the varyings based on that. Or it can introduce more "is_used_once" cases via uniform inlining. From the app's point of view, the positions should be identical between both passes if it's the exact same shader.<br></div><div></div><div><br></div><div>The workaround we have for this issue is called "vs_position_always_invariant", which was added for inexact FMA fusing, but it works with all inexact transformations containing "is_used_once".</div><div><br></div><div>This issue could be exacerbated by future optimizations.</div><div><br></div><div>Some of the solutions are:</div><div>- Remove "is_used_once" (safe)<br></div><div>- Enable vs_position_always_invariant by default (not helpful if the data flow is shader->texture->shader->position)<br></div><div>- Always suppress inexact transformations containing "is_used_once" for all instructions contributing to the final position value (less aggressive than vs_position_always_invariant; it needs a proof that it's equivalent to vs_position_always_invariant in terms of invariance, not behavior)</div><div>- Continue using app workarounds.<br></div><div></div><div></div><div><br></div><div>Just some food for thought.</div><div><br></div><div>Marek</div></div>