mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-26 10:40:11 +01:00
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@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14881>
This commit is contained in:
parent
ccaa79a1ba
commit
a3a3599a08
3 changed files with 64 additions and 0 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue