Mesa (main): microsoft/compiler: use nir_shader_instructions_pass in dxil_nir_split_clip_cull_distance

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Aug 11 11:56:55 UTC 2021


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

Author: Marcin Ślusarz <marcin.slusarz at intel.com>
Date:   Tue Aug 10 13:30:56 2021 +0200

microsoft/compiler: use nir_shader_instructions_pass in dxil_nir_split_clip_cull_distance

No functional changes.

v2: fix build

Signed-off-by: Marcin Ślusarz <marcin.slusarz at intel.com>
Reviewed-by: Jesse Natalie <jenatali at microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12324>

---

 src/microsoft/compiler/dxil_nir.c | 165 ++++++++++++++++++++------------------
 1 file changed, 86 insertions(+), 79 deletions(-)

diff --git a/src/microsoft/compiler/dxil_nir.c b/src/microsoft/compiler/dxil_nir.c
index e7ecaeabf48..0aae871ee39 100644
--- a/src/microsoft/compiler/dxil_nir.c
+++ b/src/microsoft/compiler/dxil_nir.c
@@ -1136,6 +1136,11 @@ dxil_nir_lower_upcast_phis(nir_shader *shader, unsigned min_bit_size)
    return progress;
 }
 
+struct dxil_nir_split_clip_cull_distance_params {
+   nir_variable *new_var;
+   nir_shader *shader;
+};
+
 /* In GLSL and SPIR-V, clip and cull distance are arrays of floats (with a limit of 8).
  * In DXIL, clip and cull distances are up to 2 float4s combined.
  * Coming from GLSL, we can request this 2 float4 format, but coming from SPIR-V,
@@ -1144,96 +1149,98 @@ dxil_nir_lower_upcast_phis(nir_shader *shader, unsigned min_bit_size)
  * To help emitting a valid input signature for this case, split the variables so that they
  * match what we need to put in the signature (e.g. { float clip[4]; float clip1; float cull[3]; })
  */
-bool
-dxil_nir_split_clip_cull_distance(nir_shader *shader)
+static bool
+dxil_nir_split_clip_cull_distance_instr(nir_builder *b,
+                                        nir_instr *instr,
+                                        void *cb_data)
 {
-   nir_variable *new_var = NULL;
-   nir_foreach_function(function, shader) {
-      if (!function->impl)
-         continue;
+   struct dxil_nir_split_clip_cull_distance_params *params = cb_data;
+   nir_variable *new_var = params->new_var;
 
-      bool progress = false;
-      nir_builder b;
-      nir_builder_init(&b, function->impl);
-      nir_foreach_block(block, function->impl) {
-         nir_foreach_instr_safe(instr, block) {
-            if (instr->type != nir_instr_type_deref)
-               continue;
-            nir_deref_instr *deref = nir_instr_as_deref(instr);
-            nir_variable *var = nir_deref_instr_get_variable(deref);
-            if (!var ||
-                var->data.location < VARYING_SLOT_CLIP_DIST0 ||
-                var->data.location > VARYING_SLOT_CULL_DIST1 ||
-                !var->data.compact)
-               continue;
+   if (instr->type != nir_instr_type_deref)
+      return false;
 
-            /* The location should only be inside clip distance, because clip
-             * and cull should've been merged by nir_lower_clip_cull_distance_arrays()
-             */
-            assert(var->data.location == VARYING_SLOT_CLIP_DIST0 ||
-                   var->data.location == VARYING_SLOT_CLIP_DIST1);
+   nir_deref_instr *deref = nir_instr_as_deref(instr);
+   nir_variable *var = nir_deref_instr_get_variable(deref);
+   if (!var ||
+       var->data.location < VARYING_SLOT_CLIP_DIST0 ||
+       var->data.location > VARYING_SLOT_CULL_DIST1 ||
+       !var->data.compact)
+      return false;
 
-            /* The deref chain to the clip/cull variables should be simple, just the 
-             * var and an array with a constant index, otherwise more lowering/optimization
-             * might be needed before this pass, e.g. copy prop, lower_io_to_temporaries,
-             * split_var_copies, and/or lower_var_copies
-             */
-            assert(deref->deref_type == nir_deref_type_var ||
-                   deref->deref_type == nir_deref_type_array);
-
-            b.cursor = nir_before_instr(instr);
-            if (!new_var) {
-               /* Update lengths for new and old vars */
-               int old_length = glsl_array_size(var->type);
-               int new_length = (old_length + var->data.location_frac) - 4;
-               old_length -= new_length;
-
-               /* The existing variable fits in the float4 */
-               if (new_length <= 0)
-                  continue;
+   /* The location should only be inside clip distance, because clip
+    * and cull should've been merged by nir_lower_clip_cull_distance_arrays()
+    */
+   assert(var->data.location == VARYING_SLOT_CLIP_DIST0 ||
+          var->data.location == VARYING_SLOT_CLIP_DIST1);
 
-               new_var = nir_variable_clone(var, shader);
-               nir_shader_add_variable(shader, new_var);
-               assert(glsl_get_base_type(glsl_get_array_element(var->type)) == GLSL_TYPE_FLOAT);
-               var->type = glsl_array_type(glsl_float_type(), old_length, 0);
-               new_var->type = glsl_array_type(glsl_float_type(), new_length, 0);
-               new_var->data.location++;
-               new_var->data.location_frac = 0;
-            }
+   /* The deref chain to the clip/cull variables should be simple, just the
+    * var and an array with a constant index, otherwise more lowering/optimization
+    * might be needed before this pass, e.g. copy prop, lower_io_to_temporaries,
+    * split_var_copies, and/or lower_var_copies
+    */
+   assert(deref->deref_type == nir_deref_type_var ||
+          deref->deref_type == nir_deref_type_array);
 
-            /* Update the type for derefs of the old var */
-            if (deref->deref_type == nir_deref_type_var) {
-               deref->type = var->type;
-               continue;
-            }
+   b->cursor = nir_before_instr(instr);
+   if (!new_var) {
+      /* Update lengths for new and old vars */
+      int old_length = glsl_array_size(var->type);
+      int new_length = (old_length + var->data.location_frac) - 4;
+      old_length -= new_length;
 
-            nir_const_value *index = nir_src_as_const_value(deref->arr.index);
-            assert(index);
+      /* The existing variable fits in the float4 */
+      if (new_length <= 0)
+         return false;
 
-            /* Treat this array as a vector starting at the component index in location_frac,
-             * so if location_frac is 1 and index is 0, then it's accessing the 'y' component
-             * of the vector. If index + location_frac is >= 4, there's no component there,
-             * so we need to add a new variable and adjust the index.
-             */
-            unsigned total_index = index->u32 + var->data.location_frac;
-            if (total_index < 4)
-               continue;
+      new_var = nir_variable_clone(var, params->shader);
+      nir_shader_add_variable(params->shader, new_var);
+      assert(glsl_get_base_type(glsl_get_array_element(var->type)) == GLSL_TYPE_FLOAT);
+      var->type = glsl_array_type(glsl_float_type(), old_length, 0);
+      new_var->type = glsl_array_type(glsl_float_type(), new_length, 0);
+      new_var->data.location++;
+      new_var->data.location_frac = 0;
+      params->new_var = new_var;
+   }
 
-            nir_deref_instr *new_var_deref = nir_build_deref_var(&b, new_var);
-            nir_deref_instr *new_array_deref = nir_build_deref_array(&b, new_var_deref, nir_imm_int(&b, total_index % 4));
-            nir_ssa_def_rewrite_uses(&deref->dest.ssa, &new_array_deref->dest.ssa);
-            progress = true;
-         }
-      }
-      if (progress)
-         nir_metadata_preserve(function->impl, nir_metadata_block_index |
-                                               nir_metadata_dominance |
-                                               nir_metadata_loop_analysis);
-      else
-         nir_metadata_preserve(function->impl, nir_metadata_all);
+   /* Update the type for derefs of the old var */
+   if (deref->deref_type == nir_deref_type_var) {
+      deref->type = var->type;
+      return false;
    }
 
-   return new_var != NULL;
+   nir_const_value *index = nir_src_as_const_value(deref->arr.index);
+   assert(index);
+
+   /* Treat this array as a vector starting at the component index in location_frac,
+    * so if location_frac is 1 and index is 0, then it's accessing the 'y' component
+    * of the vector. If index + location_frac is >= 4, there's no component there,
+    * so we need to add a new variable and adjust the index.
+    */
+   unsigned total_index = index->u32 + var->data.location_frac;
+   if (total_index < 4)
+      return false;
+
+   nir_deref_instr *new_var_deref = nir_build_deref_var(b, new_var);
+   nir_deref_instr *new_array_deref = nir_build_deref_array(b, new_var_deref, nir_imm_int(b, total_index % 4));
+   nir_ssa_def_rewrite_uses(&deref->dest.ssa, &new_array_deref->dest.ssa);
+   return true;
+}
+
+bool
+dxil_nir_split_clip_cull_distance(nir_shader *shader)
+{
+   struct dxil_nir_split_clip_cull_distance_params params = {
+      .new_var = NULL,
+      .shader = shader,
+   };
+   nir_shader_instructions_pass(shader,
+                                dxil_nir_split_clip_cull_distance_instr,
+                                nir_metadata_block_index |
+                                nir_metadata_dominance |
+                                nir_metadata_loop_analysis,
+                                &params);
+   return params.new_var != NULL;
 }
 
 bool



More information about the mesa-commit mailing list