d3d12: ensure all compoents of clip-distances are written

This fixes a regression that happened after rebasing on master, where we
end up not writing all components of the clip-distance array, which the
DXIL validation code in the D3D12 runtime treats as an error.

To ensure we don't end up overwriting a previous wrire, enable
nir_shader_compiler_options::lower_all_io_to_temps as well.

Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7477>
This commit is contained in:
Erik Faye-Lund 2020-11-05 18:46:15 +01:00 committed by Marge Bot
parent 2ea15cd661
commit bd5f928506
4 changed files with 53 additions and 0 deletions

View File

@ -153,6 +153,7 @@ compile_nir(struct d3d12_context *ctx, struct d3d12_shader_selector *sel,
NIR_PASS_V(nir, d3d12_lower_load_first_vertex);
NIR_PASS_V(nir, d3d12_lower_state_vars, shader);
NIR_PASS_V(nir, d3d12_lower_bool_input);
NIR_PASS_V(nir, d3d12_fixup_clipdist_writes);
struct nir_to_dxil_options opts = {};
opts.interpolate_at_vertex = screen->have_load_at_vertex;

View File

@ -996,3 +996,51 @@ d3d12_lower_triangle_strip(nir_shader *shader)
nir_metadata_preserve(impl, 0);
NIR_PASS_V(shader, nir_lower_var_copies);
}
void
d3d12_fixup_clipdist_writes(nir_shader *shader)
{
nir_builder b;
nir_function_impl *impl = nir_shader_get_entrypoint(shader);
nir_ssa_def *primitive_id;
nir_builder_init(&b, impl);
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 (intr->intrinsic != nir_intrinsic_store_deref)
continue;
nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
nir_variable *var = nir_deref_instr_get_variable(deref);
if (var->data.mode != nir_var_shader_out ||
(var->data.location != VARYING_SLOT_CLIP_DIST0 &&
var->data.location != VARYING_SLOT_CLIP_DIST1))
continue;
uint32_t writemask = nir_intrinsic_write_mask(intr);
if (writemask == 0xf)
continue;
b.cursor = nir_before_instr(instr);
nir_ssa_def *defs[4];
nir_ssa_def *prev = nir_ssa_for_src(&b, intr->src[1],
nir_src_num_components(intr->src[1]));
for (int i = 0; i < 4; ++i) {
if (writemask & (1 << i))
defs[i] = nir_channel(&b, prev, i);
else
defs[i] = nir_imm_zero(&b, 1, nir_src_bit_size(intr->src[1]));
}
nir_ssa_def *def = nir_vec4(&b, defs[0], defs[1], defs[2], defs[3]);
nir_instr_rewrite_src(&intr->instr, intr->src + 1, nir_src_for_ssa(def));
nir_intrinsic_set_write_mask(intr, 0xf);
}
}
nir_metadata_preserve(impl, nir_metadata_all);
}

View File

@ -91,6 +91,9 @@ d3d12_lower_primitive_id(nir_shader *shader);
void
d3d12_lower_triangle_strip(nir_shader *shader);
void
d3d12_fixup_clipdist_writes(nir_shader *shader);
#ifdef __cplusplus
}
#endif

View File

@ -87,6 +87,7 @@ nir_options = {
.lower_extract_word = true,
.lower_extract_byte = true,
.lower_all_io_to_elements = true,
.lower_all_io_to_temps = true,
.lower_hadd = true,
.lower_add_sat = true,
.lower_uadd_carry = true,