Mesa (main): radeonsi: apply key.ge.opt.kill_{outputs,pointsize,clipdistance} in NIR

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Apr 22 22:47:27 UTC 2022


Module: Mesa
Branch: main
Commit: 981bd8cbe2ddc3b0a3cabee1b439d8fba139bdee
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=981bd8cbe2ddc3b0a3cabee1b439d8fba139bdee

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Sun Dec 12 23:38:21 2021 -0500

radeonsi: apply key.ge.opt.kill_{outputs,pointsize,clipdistance} in NIR

This may be needed by ACO, but it doesn't do anything for LLVM yet other
than making the initial LLVM IR smaller.

It will be needed by a future commit, which rewrites ac_optimize_vs_outputs
in NIR, which relies on NIR matching the shader key.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14414>

---

 src/gallium/drivers/radeonsi/si_pipe.h            |  2 +-
 src/gallium/drivers/radeonsi/si_shader.c          | 86 +++++++++++++++++++++++
 src/gallium/drivers/radeonsi/si_state.c           |  2 +-
 src/gallium/drivers/radeonsi/si_state_shaders.cpp |  2 +-
 4 files changed, 89 insertions(+), 3 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 61c48f7300d..38cdc43c75e 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -122,7 +122,7 @@ extern "C" {
 
 #define SI_MAX_BORDER_COLORS              4096
 #define SI_MAX_VIEWPORTS                  16
-#define SIX_BITS                          0x3F
+#define SI_USER_CLIP_PLANE_MASK           0x3F
 #define SI_MAP_BUFFER_ALIGNMENT           64
 /* We only support the minimum allowed value (512), so that we can pack a 3D block size
  * in 1 SGPR. */
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index c60909833fa..4a2960bf01b 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -25,6 +25,7 @@
 #include "ac_nir.h"
 #include "ac_rtld.h"
 #include "nir.h"
+#include "nir_builder.h"
 #include "nir_serialize.h"
 #include "si_pipe.h"
 #include "si_shader_internal.h"
@@ -1373,6 +1374,87 @@ void si_get_vs_prolog_key(const struct si_shader_info *info, unsigned num_input_
       shader_out->info.uses_instanceid = true;
 }
 
+/* TODO: convert to nir_shader_instructions_pass */
+static bool si_nir_kill_outputs(nir_shader *nir, const union si_shader_key *key)
+{
+   nir_function_impl *impl = nir_shader_get_entrypoint(nir);
+   assert(impl);
+
+   if (nir->info.stage > MESA_SHADER_GEOMETRY ||
+       (!key->ge.opt.kill_outputs &&
+        !key->ge.opt.kill_pointsize &&
+        !key->ge.opt.kill_clip_distances)) {
+      nir_metadata_preserve(impl, nir_metadata_all);
+      return false;
+   }
+
+   bool progress = false;
+
+   nir_builder b;
+   nir_builder_init(&b, impl);
+
+   nir_foreach_block(block, impl) {
+      nir_foreach_instr_safe(instr, block) {
+         if (instr->type != nir_instr_type_intrinsic)
+            continue;
+
+         nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
+         if (intr->intrinsic != nir_intrinsic_store_output)
+            continue;
+
+         /* No indirect indexing allowed. */
+         ASSERTED nir_src offset = *nir_get_io_offset_src(intr);
+         assert(nir_src_is_const(offset) && nir_src_as_uint(offset) == 0);
+
+         assert(intr->num_components == 1); /* only scalar stores expected */
+         nir_io_semantics sem = nir_intrinsic_io_semantics(intr);
+
+         if (nir_slot_is_varying(sem.location) &&
+             key->ge.opt.kill_outputs &
+             (1ull << si_shader_io_get_unique_index(sem.location, true))) {
+            nir_remove_varying(intr);
+            progress = true;
+         }
+
+         if (key->ge.opt.kill_pointsize && sem.location == VARYING_SLOT_PSIZ) {
+            nir_remove_sysval_output(intr);
+            progress = true;
+         }
+
+         /* TODO: We should only kill specific clip planes as required by kill_clip_distance,
+          * not whole gl_ClipVertex. Lower ClipVertex in NIR.
+          */
+         if ((key->ge.opt.kill_clip_distances & SI_USER_CLIP_PLANE_MASK) == SI_USER_CLIP_PLANE_MASK &&
+             sem.location == VARYING_SLOT_CLIP_VERTEX) {
+            nir_remove_sysval_output(intr);
+            progress = true;
+         }
+
+         if (key->ge.opt.kill_clip_distances &&
+             (sem.location == VARYING_SLOT_CLIP_DIST0 ||
+              sem.location == VARYING_SLOT_CLIP_DIST1)) {
+            assert(nir_intrinsic_src_type(intr) == nir_type_float32);
+            unsigned index = (sem.location - VARYING_SLOT_CLIP_DIST0) * 4 +
+                             nir_intrinsic_component(intr);
+
+            if ((key->ge.opt.kill_clip_distances >> index) & 0x1) {
+               nir_remove_sysval_output(intr);
+               progress = true;
+            }
+         }
+      }
+   }
+
+   if (progress) {
+      nir_metadata_preserve(impl, nir_metadata_dominance |
+                                  nir_metadata_block_index);
+   } else {
+      nir_metadata_preserve(impl, nir_metadata_all);
+   }
+
+   return progress;
+}
+
 struct nir_shader *si_get_nir_shader(struct si_shader_selector *sel,
                                      const union si_shader_key *key,
                                      bool *free_nir)
@@ -1397,6 +1479,10 @@ struct nir_shader *si_get_nir_shader(struct si_shader_selector *sel,
 
    bool progress = false;
 
+   /* Kill outputs according to the shader key. */
+   if (sel->info.stage <= MESA_SHADER_GEOMETRY)
+      NIR_PASS(progress, nir, si_nir_kill_outputs, key);
+
    bool inline_uniforms = false;
    uint32_t *inlined_uniform_values;
    si_get_inline_uniform_state((union si_shader_key*)key, sel->pipe_shader_type,
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index d7cd93d7cc7..fb52d33ad19 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -835,7 +835,7 @@ static void si_emit_clip_regs(struct si_context *sctx)
    bool window_space = info->stage == MESA_SHADER_VERTEX ?
                           info->base.vs.window_space_position : 0;
    unsigned clipdist_mask = vs_sel->clipdist_mask;
-   unsigned ucp_mask = clipdist_mask ? 0 : rs->clip_plane_enable & SIX_BITS;
+   unsigned ucp_mask = clipdist_mask ? 0 : rs->clip_plane_enable & SI_USER_CLIP_PLANE_MASK;
    unsigned culldist_mask = vs_sel->culldist_mask;
 
    /* Clip distances on points have no effect, so need to be implemented
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.cpp b/src/gallium/drivers/radeonsi/si_state_shaders.cpp
index c9d78016bf2..7575d1631eb 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.cpp
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.cpp
@@ -3218,7 +3218,7 @@ static void *si_create_shader_selector(struct pipe_context *ctx,
       }
    }
 
-   sel->clipdist_mask = sel->info.writes_clipvertex ? SIX_BITS :
+   sel->clipdist_mask = sel->info.writes_clipvertex ? SI_USER_CLIP_PLANE_MASK :
                            u_bit_consecutive(0, sel->info.base.clip_distance_array_size);
    sel->culldist_mask = u_bit_consecutive(0, sel->info.base.cull_distance_array_size) <<
                         sel->info.base.clip_distance_array_size;



More information about the mesa-commit mailing list