microsoft/compiler: Back-propagate interpolator modes from FS
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41067>
This commit is contained in:
Jesse Natalie 2026-04-20 13:54:18 -07:00 committed by Marge Bot
parent c4287eaa04
commit 6f8656ec64
4 changed files with 37 additions and 0 deletions

View file

@ -1177,6 +1177,9 @@ select_shader_variant(struct d3d12_selection_context *sel_ctx, d3d12_shader_sele
/* Remove not-read outputs and re-sort */
if (next) {
if (next->stage == MESA_SHADER_FRAGMENT)
dxil_nir_propagate_interp_to_outputs(new_nir_variant, next->initial);
NIR_PASS(_, new_nir_variant, dxil_nir_kill_unused_outputs, key.next_varying_inputs,
next->initial->info.patch_inputs_read, key.next_varying_frac_inputs);
dxil_reassign_driver_locations(new_nir_variant, nir_var_shader_out, key.next_varying_inputs,

View file

@ -2876,3 +2876,33 @@ dxil_nir_kill_unused_outputs(nir_shader *shader, uint64_t next_stage_read_mask,
progress |= nir_remove_dead_variables(shader, nir_var_shader_out, &options);
return progress;
}
void
dxil_nir_propagate_interp_to_outputs(nir_shader *prev_stage_nir,
const nir_shader *fs_nir)
{
/* Work around a bug in some D3D12 drivers where the interpolation mode on
* outputs of the previous shader stage must match the interpolation mode on
* the corresponding fragment shader inputs. Back-propagate interpolation
* qualifiers (interpolation, centroid, sample) from FS inputs to the
* previous stage's outputs.
*/
assert(fs_nir->info.stage == MESA_SHADER_FRAGMENT);
nir_foreach_variable_with_modes(fs_input, fs_nir, nir_var_shader_in) {
unsigned loc = fs_input->data.location;
/* Skip system values - only propagate for user varyings */
if (loc < VARYING_SLOT_VAR0)
continue;
nir_foreach_variable_with_modes(prev_output, prev_stage_nir,
nir_var_shader_out) {
if (prev_output->data.location == loc) {
prev_output->data.interpolation = fs_input->data.interpolation;
prev_output->data.centroid = fs_input->data.centroid;
prev_output->data.sample = fs_input->data.sample;
}
}
}
}

View file

@ -89,6 +89,8 @@ bool dxil_nir_kill_undefined_varyings(nir_shader *shader, uint64_t prev_stage_wr
uint32_t prev_stage_patch_written_mask, const BITSET_WORD *prev_stage_frac_output_mask);
bool dxil_nir_kill_unused_outputs(nir_shader *shader, uint64_t next_stage_read_mask,
uint32_t next_stage_patch_read_mask, const BITSET_WORD *next_stage_frac_input_mask);
void dxil_nir_propagate_interp_to_outputs(nir_shader *prev_stage_nir,
const nir_shader *fs_nir);
#ifdef __cplusplus
}

View file

@ -804,6 +804,8 @@ dxil_spirv_nir_link(nir_shader *nir, nir_shader *prev_stage_nir,
NIR_PASS(_, nir, dxil_spirv_compute_pntc);
metadata->requires_runtime_data = true;
}
dxil_nir_propagate_interp_to_outputs(prev_stage_nir, nir);
}
NIR_PASS(_, nir, dxil_nir_kill_undefined_varyings, prev_stage_nir->info.outputs_written, prev_stage_nir->info.patch_outputs_written, NULL);