[Mesa-dev] [PATCH 04/15] nir: rename and generalize nir_lower_read_invocation_to_scalar

Connor Abbott connora at valvesoftware.com
Tue Aug 8 01:32:30 UTC 2017


From: Connor Abbott <cwabbott0 at gmail.com>

We'll want to scalarize other intrinsics in a similar manner for
AMD_shader_ballot, and possibly other extensions in the future. This
patch reworks the pass to use the intrinsic's info to detect whether we
need to copy the source or scalarize it, similarly to how ALU operations
are handled, and makes sure we copy indices if there are any. We don't
yet handle any other intrinsics, though, so this should shouldn't have
any functional effect yet.
---
 src/compiler/Makefile.sources                      |  2 +-
 src/compiler/nir/nir.h                             |  2 +-
 ...scalar.c => nir_lower_cross_thread_to_scalar.c} | 39 ++++++++++++++--------
 src/intel/compiler/brw_nir.c                       |  2 +-
 4 files changed, 28 insertions(+), 17 deletions(-)
 rename src/compiler/nir/{nir_lower_read_invocation_to_scalar.c => nir_lower_cross_thread_to_scalar.c} (70%)

diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources
index 091b228..734424a 100644
--- a/src/compiler/Makefile.sources
+++ b/src/compiler/Makefile.sources
@@ -213,6 +213,7 @@ NIR_FILES = \
 	nir/nir_lower_clip.c \
 	nir/nir_lower_clip_cull_distance_arrays.c \
 	nir/nir_lower_constant_initializers.c \
+	nir/nir_lower_cross_thread_to_scalar.c \
 	nir/nir_lower_double_ops.c \
 	nir/nir_lower_drawpixels.c \
 	nir/nir_lower_global_vars_to_local.c \
@@ -229,7 +230,6 @@ NIR_FILES = \
 	nir/nir_lower_passthrough_edgeflags.c \
 	nir/nir_lower_patch_vertices.c \
 	nir/nir_lower_phis_to_scalar.c \
-	nir/nir_lower_read_invocation_to_scalar.c \
 	nir/nir_lower_regs_to_ssa.c \
 	nir/nir_lower_returns.c \
 	nir/nir_lower_samplers.c \
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 4b5d78e..2836cd1 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -2569,7 +2569,7 @@ bool nir_move_vec_src_uses_to_dest(nir_shader *shader);
 bool nir_lower_vec_to_movs(nir_shader *shader);
 bool nir_lower_alu_to_scalar(nir_shader *shader);
 bool nir_lower_load_const_to_scalar(nir_shader *shader);
-bool nir_lower_read_invocation_to_scalar(nir_shader *shader);
+bool nir_lower_cross_thread_to_scalar(nir_shader *shader);
 bool nir_lower_phis_to_scalar(nir_shader *shader);
 void nir_lower_io_to_scalar(nir_shader *shader, nir_variable_mode mask);
 
diff --git a/src/compiler/nir/nir_lower_read_invocation_to_scalar.c b/src/compiler/nir/nir_lower_cross_thread_to_scalar.c
similarity index 70%
rename from src/compiler/nir/nir_lower_read_invocation_to_scalar.c
rename to src/compiler/nir/nir_lower_cross_thread_to_scalar.c
index 69e7c0a..56feba6 100644
--- a/src/compiler/nir/nir_lower_read_invocation_to_scalar.c
+++ b/src/compiler/nir/nir_lower_cross_thread_to_scalar.c
@@ -24,18 +24,20 @@
 #include "nir.h"
 #include "nir_builder.h"
 
-/** @file nir_lower_read_invocation_to_scalar.c
+/** @file nir_lower_cross_thread_to_scalar.c
  *
- * Replaces nir_intrinsic_read_invocation/nir_intrinsic_read_first_invocation
- * operations with num_components != 1 with individual per-channel operations.
+ * Replaces certain cross-thread intrinsics with num_components != 1 with
+ * individual per-channel operations. So far, the operations supported are:
+ *
+ * - read_invocation
+ * - read_first_invocation
  */
 
 static void
-lower_read_invocation_to_scalar(nir_builder *b, nir_intrinsic_instr *intrin)
+lower_to_scalar(nir_builder *b, nir_intrinsic_instr *intrin)
 {
    b->cursor = nir_before_instr(&intrin->instr);
 
-   nir_ssa_def *value = nir_ssa_for_src(b, intrin->src[0], intrin->num_components);
    nir_ssa_def *reads[4];
 
    for (unsigned i = 0; i < intrin->num_components; i++) {
@@ -44,12 +46,21 @@ lower_read_invocation_to_scalar(nir_builder *b, nir_intrinsic_instr *intrin)
       nir_ssa_dest_init(&chan_intrin->instr, &chan_intrin->dest,
                         1, intrin->dest.ssa.bit_size, NULL);
       chan_intrin->num_components = 1;
+      const nir_intrinsic_info *info = &nir_intrinsic_infos[intrin->intrinsic];
+
+      for (unsigned src = 0; src < info->num_srcs; src++) {
+         if (info->src_components[src] != 0) {
+            nir_src_copy(&chan_intrin->src[src], &intrin->src[src],
+                         chan_intrin);
+         } else {
+            nir_ssa_def *value = nir_ssa_for_src(b, intrin->src[src],
+                                                 intrin->num_components);
+            chan_intrin->src[src] = nir_src_for_ssa(nir_channel(b, value, i));
+         }
+      }
 
-      /* value */
-      chan_intrin->src[0] = nir_src_for_ssa(nir_channel(b, value, i));
-      /* invocation */
-      if (intrin->intrinsic == nir_intrinsic_read_invocation)
-         nir_src_copy(&chan_intrin->src[1], &intrin->src[1], chan_intrin);
+      for (unsigned idx = 0; idx < info->num_indices; idx++)
+         chan_intrin->const_index[idx] = intrin->const_index[idx];
 
       nir_builder_instr_insert(b, &chan_intrin->instr);
 
@@ -63,7 +74,7 @@ lower_read_invocation_to_scalar(nir_builder *b, nir_intrinsic_instr *intrin)
 }
 
 static bool
-nir_lower_read_invocation_to_scalar_impl(nir_function_impl *impl)
+nir_lower_cross_thread_to_scalar_impl(nir_function_impl *impl)
 {
    bool progress = false;
    nir_builder b;
@@ -82,7 +93,7 @@ nir_lower_read_invocation_to_scalar_impl(nir_function_impl *impl)
          switch (intrin->intrinsic) {
          case nir_intrinsic_read_invocation:
          case nir_intrinsic_read_first_invocation:
-            lower_read_invocation_to_scalar(&b, intrin);
+            lower_to_scalar(&b, intrin);
             progress = true;
             break;
          default:
@@ -99,13 +110,13 @@ nir_lower_read_invocation_to_scalar_impl(nir_function_impl *impl)
 }
 
 bool
-nir_lower_read_invocation_to_scalar(nir_shader *shader)
+nir_lower_cross_thread_to_scalar(nir_shader *shader)
 {
    bool progress = false;
 
    nir_foreach_function(function, shader) {
       if (function->impl)
-         progress |= nir_lower_read_invocation_to_scalar_impl(function->impl);
+         progress |= nir_lower_cross_thread_to_scalar_impl(function->impl);
    }
 
    return progress;
diff --git a/src/intel/compiler/brw_nir.c b/src/intel/compiler/brw_nir.c
index ce21c01..80b8822 100644
--- a/src/intel/compiler/brw_nir.c
+++ b/src/intel/compiler/brw_nir.c
@@ -620,7 +620,7 @@ brw_preprocess_nir(const struct brw_compiler *compiler, nir_shader *nir)
 
    OPT(nir_lower_tex, &tex_options);
    OPT(nir_normalize_cubemap_coords);
-   OPT(nir_lower_read_invocation_to_scalar);
+   OPT(nir_lower_cross_thread_to_scalar);
 
    OPT(nir_lower_global_vars_to_local);
 
-- 
2.9.4



More information about the mesa-dev mailing list