Mesa (main): d3d12: When adding new output varyings, write 0s
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Feb 4 21:01:15 UTC 2022
Module: Mesa
Branch: main
Commit: a3a3599a08960c306e29118dafd609b978584623
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=a3a3599a08960c306e29118dafd609b978584623
Author: Jesse Natalie <jenatali at microsoft.com>
Date: Fri Feb 4 08:24:02 2022 -0800
d3d12: When adding new output varyings, write 0s
This avoids undefined behavior in some cases, and in the case
where the new output varying is actually a sysval like viewport
index, the DXIL validator will require it to be written.
Reviewed-by: Sil Vilerino <sivileri at microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14881>
---
src/gallium/drivers/d3d12/d3d12_compiler.cpp | 3 ++
src/gallium/drivers/d3d12/d3d12_nir_passes.c | 58 ++++++++++++++++++++++++++++
src/gallium/drivers/d3d12/d3d12_nir_passes.h | 3 ++
3 files changed, 64 insertions(+)
diff --git a/src/gallium/drivers/d3d12/d3d12_compiler.cpp b/src/gallium/drivers/d3d12/d3d12_compiler.cpp
index 20e18b1c50d..2975adc485f 100644
--- a/src/gallium/drivers/d3d12/d3d12_compiler.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_compiler.cpp
@@ -535,6 +535,9 @@ create_varying_from_info(nir_shader *nir, struct d3d12_varying_info *info,
if (patch)
var->data.location += VARYING_SLOT_PATCH0;
+ if (mode == nir_var_shader_out)
+ NIR_PASS_V(nir, d3d12_write_0_to_new_varying, var);
+
return var;
}
diff --git a/src/gallium/drivers/d3d12/d3d12_nir_passes.c b/src/gallium/drivers/d3d12/d3d12_nir_passes.c
index 4a8ca704eea..b2a28834a4f 100644
--- a/src/gallium/drivers/d3d12/d3d12_nir_passes.c
+++ b/src/gallium/drivers/d3d12/d3d12_nir_passes.c
@@ -1142,3 +1142,61 @@ d3d12_split_multistream_varyings(nir_shader *s)
return progress;
}
+
+static void
+write_0(nir_builder *b, nir_deref_instr *deref)
+{
+ if (glsl_type_is_array_or_matrix(deref->type)) {
+ for (unsigned i = 0; i < glsl_get_length(deref->type); ++i)
+ write_0(b, nir_build_deref_array_imm(b, deref, i));
+ } else if (glsl_type_is_struct(deref->type)) {
+ for (unsigned i = 0; i < glsl_get_length(deref->type); ++i)
+ write_0(b, nir_build_deref_struct(b, deref, i));
+ } else {
+ nir_ssa_def *scalar = nir_imm_intN_t(b, 0, glsl_get_bit_size(deref->type));
+ nir_ssa_def *scalar_arr[NIR_MAX_VEC_COMPONENTS];
+ unsigned num_comps = glsl_get_components(deref->type);
+ unsigned writemask = (1 << num_comps) - 1;
+ for (unsigned i = 0; i < num_comps; ++i)
+ scalar_arr[i] = scalar;
+ nir_ssa_def *zero_val = nir_vec(b, scalar_arr, num_comps);
+ nir_store_deref(b, deref, zero_val, writemask);
+ }
+}
+
+void
+d3d12_write_0_to_new_varying(nir_shader *s, nir_variable *var)
+{
+ /* Skip per-vertex HS outputs */
+ if (s->info.stage == MESA_SHADER_TESS_CTRL && !var->data.patch)
+ return;
+
+ nir_foreach_function(func, s) {
+ if (!func->impl)
+ continue;
+
+ nir_builder b;
+ nir_builder_init(&b, func->impl);
+
+ nir_foreach_block(block, func->impl) {
+ b.cursor = nir_before_block(block);
+ if (s->info.stage != MESA_SHADER_GEOMETRY) {
+ write_0(&b, nir_build_deref_var(&b, var));
+ break;
+ }
+
+ nir_foreach_instr_safe(instr, block) {
+ if (instr->type != nir_instr_type_intrinsic)
+ continue;
+ nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
+ if (intr->intrinsic != nir_intrinsic_emit_vertex)
+ continue;
+
+ b.cursor = nir_before_instr(instr);
+ write_0(&b, nir_build_deref_var(&b, var));
+ }
+ }
+
+ nir_metadata_preserve(func->impl, nir_metadata_block_index | nir_metadata_dominance);
+ }
+}
diff --git a/src/gallium/drivers/d3d12/d3d12_nir_passes.h b/src/gallium/drivers/d3d12/d3d12_nir_passes.h
index 4550dc253a0..dca85e4ff95 100644
--- a/src/gallium/drivers/d3d12/d3d12_nir_passes.h
+++ b/src/gallium/drivers/d3d12/d3d12_nir_passes.h
@@ -117,6 +117,9 @@ d3d12_disable_multisampling(nir_shader *s);
bool
d3d12_split_multistream_varyings(nir_shader *s);
+void
+d3d12_write_0_to_new_varying(nir_shader *s, nir_variable *var);
+
#ifdef __cplusplus
}
#endif
More information about the mesa-commit
mailing list