Mesa (staging/21.2): ac/nir/nggc: Refactor save_reusable_variables.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Sep 27 17:05:45 UTC 2021


Module: Mesa
Branch: staging/21.2
Commit: 134d11e4c2ef8f955a768981e45882d1a67223e1
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=134d11e4c2ef8f955a768981e45882d1a67223e1

Author: Timur Kristóf <timur.kristof at gmail.com>
Date:   Fri Sep 24 17:23:17 2021 +0200

ac/nir/nggc: Refactor save_reusable_variables.

This makes the code more elegant and also fixes the mistake of
skipping the blocks that come before loops.

Fossil DB changes on Sienna Cichlid with NGGC on:

Totals from 1026 (0.80% of 128647) affected shaders:
SpillSGPRs: 3817 -> 4035 (+5.71%)
CodeSize: 5582856 -> 5538732 (-0.79%); split: -0.89%, +0.10%
Instrs: 1106907 -> 1100180 (-0.61%); split: -0.68%, +0.07%
Latency: 10084948 -> 10052197 (-0.32%); split: -0.37%, +0.05%
InvThroughput: 1567012 -> 1564949 (-0.13%); split: -0.16%, +0.03%
SClause: 39789 -> 39075 (-1.79%); split: -2.33%, +0.54%
Copies: 95184 -> 96456 (+1.34%); split: -0.19%, +1.53%
Branches: 44087 -> 44093 (+0.01%); split: -0.01%, +0.02%
PreSGPRs: 47584 -> 51009 (+7.20%); split: -0.61%, +7.80%

Fixes: 0bb543bb60f93bea5b1c0ed6382ced49e659273e
Signed-off-by: Timur Kristóf <timur.kristof at gmail.com>
Reviewed-by: Daniel Schürmann <daniel at schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13001>
(cherry picked from commit cb19ebe7baca5f2c4c547094ae3088ad3035be84)

---

 .pick_status.json                 |  2 +-
 src/amd/common/ac_nir_lower_ngg.c | 47 ++++++++++++++++++++++++---------------
 2 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index e585819ff3f..c05804a3b84 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -544,7 +544,7 @@
         "description": "ac/nir/nggc: Refactor save_reusable_variables.",
         "nominated": true,
         "nomination_type": 1,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": "0bb543bb60f93bea5b1c0ed6382ced49e659273e"
     },
diff --git a/src/amd/common/ac_nir_lower_ngg.c b/src/amd/common/ac_nir_lower_ngg.c
index 2d35d65bbec..e33a431affa 100644
--- a/src/amd/common/ac_nir_lower_ngg.c
+++ b/src/amd/common/ac_nir_lower_ngg.c
@@ -744,31 +744,24 @@ save_reusable_variables(nir_builder *b, lower_ngg_nogs_state *nogs_state)
    ASSERTED int vec_ok = u_vector_init(&nogs_state->saved_uniforms, sizeof(saved_uniform), 4 * sizeof(saved_uniform));
    assert(vec_ok);
 
-   unsigned loop_depth = 0;
-
-   nir_foreach_block_safe(block, b->impl) {
-      /* Check whether we're in a loop. */
-      nir_cf_node *next_cf_node = nir_cf_node_next(&block->cf_node);
-      nir_cf_node *prev_cf_node = nir_cf_node_prev(&block->cf_node);
-      if (next_cf_node && next_cf_node->type == nir_cf_node_loop)
-         loop_depth++;
-      if (prev_cf_node && prev_cf_node->type == nir_cf_node_loop)
-         loop_depth--;
-
-      /* The following code doesn't make sense in loops, so just skip it then. */
-      if (loop_depth)
-         continue;
-
+   nir_block *block = nir_start_block(b->impl);
+   while (block) {
+      /* Process the instructions in the current block. */
       nir_foreach_instr_safe(instr, block) {
          /* Find instructions whose SSA definitions are used by both
-          * the top and bottom parts of the shader. In this case, it
-          * makes sense to try to reuse these from the top part.
+          * the top and bottom parts of the shader (before and after culling).
+          * Only in this case, it makes sense for the bottom part
+          * to try to reuse these from the top part.
           */
          if ((instr->pass_flags & nggc_passflag_used_by_both) != nggc_passflag_used_by_both)
             continue;
 
+         /* Determine if we can reuse the current SSA value.
+          * When vertex compaction is used, it is possible that the same shader invocation
+          * processes a different vertex in the top and bottom part of the shader.
+          * Therefore, we only reuse uniform values.
+          */
          nir_ssa_def *ssa = NULL;
-
          switch (instr->type) {
          case nir_instr_type_alu: {
             nir_alu_instr *alu = nir_instr_as_alu(instr);
@@ -802,6 +795,7 @@ save_reusable_variables(nir_builder *b, lower_ngg_nogs_state *nogs_state)
 
          assert(ssa);
 
+         /* Determine a suitable type for the SSA value. */
          enum glsl_base_type base_type = GLSL_TYPE_UINT;
          switch (ssa->bit_size) {
          case 8: base_type = GLSL_TYPE_UINT8; break;
@@ -818,6 +812,10 @@ save_reusable_variables(nir_builder *b, lower_ngg_nogs_state *nogs_state)
          saved_uniform *saved = (saved_uniform *) u_vector_add(&nogs_state->saved_uniforms);
          assert(saved);
 
+         /* Create a new NIR variable where we store the reusable value.
+          * Then, we reload the variable and replace the uses of the value
+          * with the reloaded variable.
+          */
          saved->var = nir_local_variable_create(b->impl, t, NULL);
          saved->ssa = ssa;
 
@@ -828,6 +826,19 @@ save_reusable_variables(nir_builder *b, lower_ngg_nogs_state *nogs_state)
          nir_ssa_def *reloaded = nir_load_var(b, saved->var);
          nir_ssa_def_rewrite_uses_after(ssa, reloaded, reloaded->parent_instr);
       }
+
+      /* Look at the next CF node. */
+      nir_cf_node *next_cf_node = nir_cf_node_next(&block->cf_node);
+      if (next_cf_node) {
+         /* It makes no sense to try to reuse things from within loops. */
+         if (next_cf_node->type == nir_cf_node_loop) {
+            block = nir_cf_node_cf_tree_next(next_cf_node);
+            continue;
+         }
+      }
+
+      /* Go to the next block. */
+      block = nir_block_cf_tree_next(block);
    }
 }
 



More information about the mesa-commit mailing list