From fe601b9293df1556abaab805b23ae587eb85a052 Mon Sep 17 00:00:00 2001 From: Konstantin Seurer Date: Wed, 20 Nov 2024 16:20:46 +0100 Subject: [PATCH] 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 Part-of: --- src/gallium/auxiliary/gallivm/lp_bld_nir.c | 10 +++++++++ .../auxiliary/gallivm/lp_bld_nir_soa.c | 8 +++---- src/gallium/frontends/lavapipe/lvp_pipeline.c | 22 ------------------- 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir.c b/src/gallium/auxiliary/gallivm/lp_bld_nir.c index d7af02f5baf..38b8b2884dc 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir.c @@ -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); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c index 9f82a00eb46..a2d1a7139f3 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c @@ -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: diff --git a/src/gallium/frontends/lavapipe/lvp_pipeline.c b/src/gallium/frontends/lavapipe/lvp_pipeline.c index 99f222552d3..a7b83ed5afa 100644 --- a/src/gallium/frontends/lavapipe/lvp_pipeline.c +++ b/src/gallium/frontends/lavapipe/lvp_pipeline.c @@ -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);