nir: Add nir_lower_helper_writes pass
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Mon, 20 Feb 2023 19:16:05 +0000 (14:16 -0500)
committerAlyssa Rosenzweig <alyssa@rosenzweig.io>
Sat, 4 Mar 2023 18:31:05 +0000 (13:31 -0500)
commit586da7b32908eb6cb4282a58339689b6d23c224b
tree97c1e1976dd1fa89f016d839736b188073353504
parent1dd872ec17d0fc1285536899fd0370be3ab0dd13
nir: Add nir_lower_helper_writes pass

This NIR pass lowers stores in fragment shaders to:

   if (!gl_HelperInvocaton) {
      store();
   }

This implements the API requirement that helper invocations do not have visible
side effects, and the lowering is required on any hardware that cannot directly
mask helper invocation's side effects. The pass was originally written for
Midgard (which has this issue) but is also needed for Asahi. Let's share the
code, and fix it while we're at it.

Changes from the Midgard pass:

1. Add an option to only lower atomics.

   AGX hardware can mask helper invocations for "plain" stores but not for
   atomics.  Accordingly, the AGX compiler wants this lowering for atomics but
   not store_global. By contrast, Midgard cannot mask any stores and needs the
   lowering for all store intrinsics. Add an option to the common pass to
   accommodate both cases.

   This is an optimization for AGX. It is not required for correctness, this
   lowering is always legal.

2. Fix dominance issues.

   It's invalid to have NIR like

      if ... {
         ssa_1 = ...
      }

      foo ssa_1

   Instead we need to rewrite as

      if ... {
         ssa_1 = ...
      } else {
         ssa_2 = undef
      }
      ssa_3 = phi ssa_1, ssa_2

      foo ssa_3

   By default, neither nir_validate nor the backends check this, so this doesn't
   currently fix a (known) real bug. But it's still invalid and fails validation
   with NIR_DEBUG=validate_ssa_dominance.

   Fix this in lower_helper_writes for intrinsics that return data (atomics).

3. Assert that the pass is run only for fragment shaders. This encourages
   backends to be judicious about which passes they call instead of just
   throwing everything in a giant lower everything spaghetti.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Italo Nicola <italonicola@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21413>
src/compiler/nir/meson.build
src/compiler/nir/nir.h
src/compiler/nir/nir_lower_helper_writes.c [new file with mode: 0644]
src/panfrost/midgard/midgard_nir_lower_helper_writes.c