gallivm: Implement demote and lower terminate in nir

The current implementation does not work for terminate since loads need
to ignore the mask because of helper invocations. This can lead to
crashes.

Reviewed-by: Mary Guillemard <mary@mary.zone>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33003>
This commit is contained in:
Konstantin Seurer 2024-11-20 16:20:46 +01:00 committed by Marge Bot
parent aacfc663cb
commit fe601b9293
3 changed files with 14 additions and 26 deletions

View file

@ -59,6 +59,16 @@ lp_build_opt_nir(struct nir_shader *nir)
NIR_PASS_V(nir, nir_lower_task_shader, ts_opts);
}
if (nir->info.stage == MESA_SHADER_FRAGMENT) {
bool demote_progress = false;
NIR_PASS(demote_progress, nir, nir_lower_terminate_to_demote);
if (demote_progress) {
NIR_PASS(_, nir, nir_lower_halt_to_return);
NIR_PASS(_, nir, nir_lower_returns);
NIR_PASS(_, nir, nir_opt_dead_cf);
}
}
NIR_PASS_V(nir, nir_lower_flrp, 16|32|64, true);
NIR_PASS_V(nir, nir_lower_fp16_casts, nir_lower_fp16_all | nir_lower_fp16_split_fp64);

View file

@ -78,7 +78,7 @@ lp_nir_instr_src_divergent(nir_instr *instr, uint32_t src_index)
case nir_intrinsic_store_deref:
case nir_intrinsic_store_shared:
case nir_intrinsic_store_task_payload:
case nir_intrinsic_terminate_if:
case nir_intrinsic_demote_if:
case nir_intrinsic_ballot:
case nir_intrinsic_vote_all:
case nir_intrinsic_vote_any:
@ -4569,7 +4569,7 @@ visit_discard(struct lp_build_nir_soa_context *bld,
LLVMBuilderRef builder = bld->base.gallivm->builder;
LLVMValueRef cond = NULL;
if (instr->intrinsic == nir_intrinsic_terminate_if) {
if (instr->intrinsic == nir_intrinsic_demote_if) {
cond = get_src(bld, &instr->src[0], 0);
cond = LLVMBuildSExt(builder, cond, bld->uint_bld.vec_type, "");
}
@ -5016,8 +5016,8 @@ visit_intrinsic(struct lp_build_nir_soa_context *bld,
case nir_intrinsic_load_helper_invocation:
emit_helper_invocation(bld, &result[0]);
break;
case nir_intrinsic_terminate_if:
case nir_intrinsic_terminate:
case nir_intrinsic_demote_if:
case nir_intrinsic_demote:
visit_discard(bld, instr);
break;
case nir_intrinsic_emit_vertex:

View file

@ -161,27 +161,6 @@ remove_barriers(nir_shader *nir, bool is_compute)
(void*)is_compute);
}
static bool
lower_demote_impl(nir_builder *b, nir_intrinsic_instr *intr, void *data)
{
if (intr->intrinsic == nir_intrinsic_demote) {
intr->intrinsic = nir_intrinsic_terminate;
return true;
}
if (intr->intrinsic == nir_intrinsic_demote_if) {
intr->intrinsic = nir_intrinsic_terminate_if;
return true;
}
return false;
}
static bool
lower_demote(nir_shader *nir)
{
return nir_shader_intrinsics_pass(nir, lower_demote_impl,
nir_metadata_dominance, NULL);
}
static bool
find_tex(const nir_instr *instr, const void *data_cb)
{
@ -370,7 +349,6 @@ lvp_shader_lower(struct lvp_device *pdevice, nir_shader *nir, struct lvp_pipelin
lvp_lower_input_attachments(nir, false);
NIR_PASS_V(nir, nir_lower_system_values);
NIR_PASS_V(nir, nir_lower_is_helper_invocation);
NIR_PASS_V(nir, lower_demote);
const struct nir_lower_compute_system_values_options compute_system_values = {0};
NIR_PASS_V(nir, nir_lower_compute_system_values, &compute_system_values);