[Mesa-dev] [PATCH 1/2] nir: add new nir_remove_dead_barriers() pass

Timothy Arceri tarceri at itsqueeze.com
Wed Nov 14 05:30:38 UTC 2018


Link time opts can remove unused outputs leaving behind useless
barriers. This pass is intended to be called after linking so
I've added it to nir_linking_helpers.c

This pass removes some barriers from Witcher 3 (DXVK) Vulkan
shaders.
---
 src/compiler/nir/nir.h                 |  1 +
 src/compiler/nir/nir_linking_helpers.c | 38 ++++++++++++++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index c469e111b2..224d2f66e2 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -2817,6 +2817,7 @@ void nir_compact_varyings(nir_shader *producer, nir_shader *consumer,
                           bool default_to_smooth_interp);
 void nir_link_xfb_varyings(nir_shader *producer, nir_shader *consumer);
 bool nir_link_constant_varyings(nir_shader *producer, nir_shader *consumer);
+void nir_remove_dead_barriers(nir_shader *shader);
 
 typedef enum {
    /* If set, this forces all non-flat fragment shader inputs to be
diff --git a/src/compiler/nir/nir_linking_helpers.c b/src/compiler/nir/nir_linking_helpers.c
index a05890ada4..61982659a0 100644
--- a/src/compiler/nir/nir_linking_helpers.c
+++ b/src/compiler/nir/nir_linking_helpers.c
@@ -669,3 +669,41 @@ nir_link_constant_varyings(nir_shader *producer, nir_shader *consumer)
 
    return progress;
 }
+/* This is intended to be called this after linking opts as unused tcs outputs
+ * may have been removed leaving useless barriers in the shader.
+ *
+ * TODO: We could make this pass more complex and actually check if we are
+ * reading outputs set by other invocations.
+ */
+void
+nir_remove_dead_barriers(nir_shader *shader)
+{
+   if (shader->info.stage != MESA_SHADER_TESS_CTRL)
+      return;
+
+   bool progress = false;
+
+   nir_function_impl *impl = nir_shader_get_entrypoint(shader);
+
+   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 we see a store or load of an output then bail */
+         if (intr->intrinsic == nir_intrinsic_store_deref ||
+             intr->intrinsic == nir_intrinsic_load_deref) {
+            nir_variable *var =
+               nir_deref_instr_get_variable(nir_src_as_deref(intr->src[0]));
+            if (var->data.mode == nir_var_shader_out)
+               return;
+         }
+
+         /* Remove barriers if we have not yet touched any outputs */
+         if (intr->intrinsic == nir_intrinsic_barrier)
+            nir_instr_remove(instr);
+      }
+   }
+}
-- 
2.19.1



More information about the mesa-dev mailing list