Mesa (master): microsoft/compiler: zero out unused WebGPU system values

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Apr 27 02:02:58 UTC 2021


Module: Mesa
Branch: master
Commit: 3a3ab2f8ee3e67559b8e19ccb51c7314b99076f7
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3a3ab2f8ee3e67559b8e19ccb51c7314b99076f7

Author: Enrico Galli <enrico.galli at intel.com>
Date:   Fri Apr 23 18:27:44 2021 -0700

microsoft/compiler: zero out unused WebGPU system values

Reviewed-by: Jesse Natalie <jenatali at microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10439>

---

 src/microsoft/compiler/dxil_nir.c           | 60 +++++++++++++++++++++++++++++
 src/microsoft/compiler/dxil_nir.h           |  3 ++
 src/microsoft/spirv_to_dxil/spirv_to_dxil.c | 20 +++++++++-
 3 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/src/microsoft/compiler/dxil_nir.c b/src/microsoft/compiler/dxil_nir.c
index 2e86eb05879..aac3c3116de 100644
--- a/src/microsoft/compiler/dxil_nir.c
+++ b/src/microsoft/compiler/dxil_nir.c
@@ -1295,3 +1295,63 @@ dxil_nir_lower_double_math(nir_shader *shader)
 
    return progress;
 }
+
+typedef struct {
+   gl_system_value *values;
+   uint32_t count;
+} zero_system_values_state;
+
+static bool
+lower_system_value_to_zero_filter(const nir_instr* instr, const void* cb_state)
+{
+   if (instr->type != nir_instr_type_intrinsic) {
+      return false;
+   }
+
+   nir_intrinsic_instr* intrin = nir_instr_as_intrinsic(instr);
+
+   /* All the intrinsics we care about are loads */
+   if (!nir_intrinsic_infos[intrin->intrinsic].has_dest)
+      return false;
+
+   assert(intrin->dest.is_ssa);
+
+   zero_system_values_state* state = (zero_system_values_state*)cb_state;
+   for (uint32_t i = 0; i < state->count; ++i) {
+      gl_system_value value = state->values[i];
+      nir_intrinsic_op value_op = nir_intrinsic_from_system_value(value);
+
+      if (intrin->intrinsic == value_op) {
+         return true;
+      } else if (intrin->intrinsic == nir_intrinsic_load_deref) {
+         nir_deref_instr* deref = nir_src_as_deref(intrin->src[0]);
+         if (!nir_deref_mode_is(deref, nir_var_system_value))
+            return false;
+
+         nir_variable* var = deref->var;
+         if (var->data.location == value) {
+            return true;
+         }
+      }
+   }
+
+   return false;
+}
+
+static nir_ssa_def*
+lower_system_value_to_zero_instr(nir_builder* b, nir_instr* instr, void* _state)
+{
+   return nir_imm_int(b, 0);
+}
+
+bool
+dxil_nir_lower_system_values_to_zero(nir_shader* shader,
+                                     gl_system_value* system_values,
+                                     uint32_t count)
+{
+   zero_system_values_state state = { system_values, count };
+   return nir_shader_lower_instructions(shader,
+      lower_system_value_to_zero_filter,
+      lower_system_value_to_zero_instr,
+      &state);
+}
diff --git a/src/microsoft/compiler/dxil_nir.h b/src/microsoft/compiler/dxil_nir.h
index fe657efdd0c..84d4ca32e34 100644
--- a/src/microsoft/compiler/dxil_nir.h
+++ b/src/microsoft/compiler/dxil_nir.h
@@ -46,6 +46,9 @@ bool dxil_nir_lower_upcast_phis(nir_shader *shader, unsigned min_bit_size);
 bool dxil_nir_lower_fp16_casts(nir_shader *shader);
 bool dxil_nir_split_clip_cull_distance(nir_shader *shader);
 bool dxil_nir_lower_double_math(nir_shader *shader);
+bool dxil_nir_lower_system_values_to_zero(nir_shader *shader,
+                                          gl_system_value* system_value,
+                                          uint32_t count);
 
 nir_ssa_def *
 build_load_ubo_dxil(nir_builder *b, nir_ssa_def *buffer,
diff --git a/src/microsoft/spirv_to_dxil/spirv_to_dxil.c b/src/microsoft/spirv_to_dxil/spirv_to_dxil.c
index af7ca096d61..2eb25da67af 100644
--- a/src/microsoft/spirv_to_dxil/spirv_to_dxil.c
+++ b/src/microsoft/spirv_to_dxil/spirv_to_dxil.c
@@ -43,10 +43,14 @@ spirv_to_dxil(const uint32_t *words, size_t word_count,
 
    glsl_type_singleton_init_or_ref();
 
+   struct nir_shader_compiler_options nir_options = *dxil_get_nir_compiler_options();
+   // We will manually handle base_vertex
+   nir_options.lower_base_vertex = false;
+
    nir_shader *nir = spirv_to_nir(
       words, word_count, (struct nir_spirv_specialization *)specializations,
       num_specializations, (gl_shader_stage)stage, entry_point_name,
-      &spirv_opts, dxil_get_nir_compiler_options());
+      &spirv_opts, &nir_options);
    if (!nir) {
       glsl_type_singleton_decref();
       return false;
@@ -55,6 +59,18 @@ spirv_to_dxil(const uint32_t *words, size_t word_count,
    nir_validate_shader(nir,
                        "Validate before feeding NIR to the DXIL compiler");
 
+   NIR_PASS_V(nir, nir_lower_system_values);
+
+   // vertex_id and instance_id should have already been transformed to base
+   //  zero before spirv_to_dxil was called. Also, WebGPU does not support
+   //  base/firstVertex/Instance.
+   gl_system_value system_values[] = {
+      SYSTEM_VALUE_FIRST_VERTEX,
+      SYSTEM_VALUE_BASE_VERTEX,
+      SYSTEM_VALUE_BASE_INSTANCE
+   };
+   NIR_PASS_V(nir, dxil_nir_lower_system_values_to_zero, system_values, ARRAY_SIZE(system_values));
+
    NIR_PASS_V(nir, nir_split_per_member_structs);
 
    NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_ubo | nir_var_mem_ssbo,
@@ -112,6 +128,8 @@ spirv_to_dxil(const uint32_t *words, size_t word_count,
    NIR_PASS_V(nir, dxil_nir_split_clip_cull_distance);
    NIR_PASS_V(nir, dxil_nir_lower_loads_stores_to_dxil);
 
+   nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
+
    struct nir_to_dxil_options opts = {.vulkan_environment = true};
 
    struct blob dxil_blob;



More information about the mesa-commit mailing list