diff options
author | Enrico Galli <enrico.galli@intel.com> | 2021-04-23 18:27:44 -0700 |
---|---|---|
committer | Marge Bot <eric+marge@anholt.net> | 2021-04-27 01:53:16 +0000 |
commit | 3a3ab2f8ee3e67559b8e19ccb51c7314b99076f7 (patch) | |
tree | b9b44afa54f005f9eb927a7cb3cb415091967441 | |
parent | 95844b0978eb378290e04a4c2dbef8227299ee89 (diff) |
microsoft/compiler: zero out unused WebGPU system values
Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10439>
-rw-r--r-- | src/microsoft/compiler/dxil_nir.c | 60 | ||||
-rw-r--r-- | src/microsoft/compiler/dxil_nir.h | 3 | ||||
-rw-r--r-- | src/microsoft/spirv_to_dxil/spirv_to_dxil.c | 20 |
3 files changed, 82 insertions, 1 deletions
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; |