intel/compiler: Ensure load_barycentric_at_sample and load_interpolated_input remain together

This previously worked by luck because we were incorrectly calling
nir_opt_remove_phis before calling nir_convert_from_ssa. See also #10727.

No shader-db or fossil-db changes on any Intel platform.

v2: Handle the load_interpolated_input and load_barycentric_at_sample as
separate passes. Based on discussion with Ken starting at
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28136#note_2330424.

Fixes: 74a40cc4b6 ("intel/fs: move lower of non-uniform at_sample barycentric to NIR")
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28136>
This commit is contained in:
Ian Romanick 2024-03-01 17:11:57 -08:00 committed by Marge Bot
parent 49217c2547
commit 87101e7d83

View file

@ -48,6 +48,9 @@ intel_nir_lower_non_uniform_barycentric_at_sample_instr(nir_builder *b,
!nir_src_is_divergent(intrin->src[0]))
return false;
if (intrin->def.parent_instr->pass_flags != 0)
return false;
nir_def *sample_id = intrin->src[0].ssa;
b->cursor = nir_instr_remove(&intrin->instr);
@ -59,6 +62,7 @@ intel_nir_lower_non_uniform_barycentric_at_sample_instr(nir_builder *b,
nir_push_if(b, nir_ieq(b, sample_id, first_sample_id));
{
nir_builder_instr_insert(b, &intrin->instr);
intrin->def.parent_instr->pass_flags = 1;
nir_src_rewrite(&intrin->src[0], first_sample_id);
@ -69,12 +73,77 @@ intel_nir_lower_non_uniform_barycentric_at_sample_instr(nir_builder *b,
return true;
}
static bool
intel_nir_lower_non_uniform_interpolated_input_instr(nir_builder *b,
nir_instr *instr,
void *cb_data)
{
if (instr->type != nir_instr_type_intrinsic)
return false;
nir_intrinsic_instr *load_ii = nir_instr_as_intrinsic(instr);
if (load_ii->intrinsic != nir_intrinsic_load_interpolated_input)
return false;
assert(load_ii->src[0].ssa->parent_instr->type == nir_instr_type_intrinsic);
nir_intrinsic_instr *bary =
nir_instr_as_intrinsic(load_ii->src[0].ssa->parent_instr);
if (bary->intrinsic != nir_intrinsic_load_barycentric_at_sample)
return false;
if (nir_src_is_always_uniform(bary->src[0]) ||
!nir_src_is_divergent(bary->src[0]))
return false;
nir_def *sample_id = bary->src[0].ssa;
b->cursor = nir_instr_remove(&load_ii->instr);
nir_push_loop(b);
{
nir_def *first_sample_id = nir_read_first_invocation(b, sample_id);
nir_push_if(b, nir_ieq(b, sample_id, first_sample_id));
{
nir_def *new_bary = nir_load_barycentric_at_sample(
b, bary->def.bit_size, first_sample_id,
.interp_mode = nir_intrinsic_interp_mode(bary));
/* Set pass_flags so that the other lowering pass won't try to also
* lower this new load_barycentric_at_sample.
*/
new_bary->parent_instr->pass_flags = 1;
nir_builder_instr_insert(b, &load_ii->instr);
nir_src_rewrite(&load_ii->src[0], new_bary);
nir_jump(b, nir_jump_break);
}
}
return true;
}
bool
intel_nir_lower_non_uniform_barycentric_at_sample(nir_shader *nir)
{
return nir_shader_instructions_pass(
bool progress;
nir_shader_clear_pass_flags(nir);
progress = nir_shader_instructions_pass(
nir,
intel_nir_lower_non_uniform_interpolated_input_instr,
nir_metadata_none,
NULL);
progress = nir_shader_instructions_pass(
nir,
intel_nir_lower_non_uniform_barycentric_at_sample_instr,
nir_metadata_none,
NULL);
NULL) || progress;
return progress;
}