agx: Lower system values in NIR in the driver
authorAlyssa Rosenzweig <alyssa@collabora.com>
Thu, 29 Dec 2022 02:16:35 +0000 (21:16 -0500)
committerMarge Bot <emma+marge@anholt.net>
Tue, 31 Jan 2023 17:02:34 +0000 (17:02 +0000)
commit02fe57b7e9cec6d1e0f6f7a9b7a15965db7b3d90
tree762f0ee9f268152f05d42054046a90a71bca5f98
parentb0b5a71c74f5d87846de69e2616c807b6d38eddc
agx: Lower system values in NIR in the driver

To comply with The Ekstrand Rule.

AGX has a large number of "uniform registers" available. These may be loaded
with arbitrary ranges of GPU memory by the driver, or they can be written by the
preamble shader. Currently, the compiler runs nir_opt_preamble on the first half
of the uniform file, and then translates NIR sysvals to moves from the second
half of the uniform file, passing back a uniform->sysval map for the GL driver
to respect. This has (at least) two issues:

* Since nir_opt_preamble runs before gathering sysvals, it has to assume the
  maximum number of sysvals are pushed, which can prevent it from moving some
  computation to the preamble due to running out of partitioned uniform registers.
  This is a problem for Dolphin's ubershaders, though it's unclear how much it
  matters for Dolphin perf.

* This violates The Ekstrand Rule and apparently will be a problem for our
  Vulkan driver. I'm just a compiler+GL girl, so I wouldn't know.

To fix this, we invert the order of operations. At the end of this series, we
instead lower NIR system values to NIR load_preamble instructions in the GL
driver. The compiler just translates directly to uniform registers reads. The
Vulkan driver will need its own version of this code, but maybe it can do
something clever and descriptor set aware.

This means that there will already be some load_preamble instructions when
nir_opt_preamble runs, so I've made minor changes to nir_opt_preamble to handle
that gracefully. This is a bit lazy... The alternative is to introduce a
`load_uniform_agx` intrinsic which `load_preamble` gets lowered to trivially.
But that's another pass over the IR (and due to AGX's shader variant hell I'm
sensitive to backend compile time) and it would be more complicated than what's
implemented here.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Acked-by: Ella Stanforth <ella@iglunix.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20562>
src/asahi/compiler/agx_compile.c
src/asahi/compiler/agx_compile.h
src/asahi/compiler/agx_compiler.h
src/asahi/compiler/agx_uniforms.c [deleted file]
src/asahi/compiler/meson.build
src/gallium/drivers/asahi/agx_nir_lower_sysvals.c [new file with mode: 0644]
src/gallium/drivers/asahi/agx_state.c
src/gallium/drivers/asahi/agx_state.h
src/gallium/drivers/asahi/agx_uniforms.c
src/gallium/drivers/asahi/meson.build