From c707bb5e8ff601d3823a763700d6d78d610246c9 Mon Sep 17 00:00:00 2001 From: Patrick Lerda Date: Sun, 5 Jan 2025 14:27:21 +0100 Subject: [PATCH] r600: fix cayman sfn_nir_legalize_image_load_store ssa dominance After dae57e184aaf ("glsl,st/mesa: always lower IO for GLSL, unlower IO for drivers"), the shaders updated by sfn_nir_legalize_image_load_store on cayman could trigger a segmentation fault. The main issue is that sfn_nir_legalize_image_load_store does not handle properly the ssa dominance functionality and this issue is exacerbated by this last mesa update. This change makes the ssa dominance functionality operational. This commit implements pass_flags to avoid an infinite loop. For instance, this issue is triggered on cayman using this environment variable NIR_DEBUG=validate_ssa_dominance with: "piglit/bin/oes_egl_image_external_essl3 -auto -fbo": NIR validation failed after r600_legalize_image_load_store in ../src/gallium/drivers/r600/sfn/sfn_nir.cpp Signed-off-by: Patrick Lerda Part-of: --- .../sfn/sfn_nir_legalize_image_load_store.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/r600/sfn/sfn_nir_legalize_image_load_store.cpp b/src/gallium/drivers/r600/sfn/sfn_nir_legalize_image_load_store.cpp index de24174d0ed..2f23cee5d7a 100644 --- a/src/gallium/drivers/r600/sfn/sfn_nir_legalize_image_load_store.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_nir_legalize_image_load_store.cpp @@ -10,6 +10,10 @@ #include "nir_intrinsics_indices.h" #include "sfn_nir.h" +enum legalize_image_load_store_pass_flags { + FLAG_LEGALIZE_DONE = BITFIELD_BIT(7), +}; + static nir_def * r600_legalize_image_load_store_impl(nir_builder *b, nir_instr *instr, @@ -113,6 +117,7 @@ r600_legalize_image_load_store_impl(nir_builder *b, auto new_load_ir = nir_instr_as_intrinsic(new_load); nir_builder_instr_insert(b, new_load); + new_load_ir->instr.pass_flags |= FLAG_LEGALIZE_DONE; if (load_value) result = &new_load_ir->def; @@ -137,10 +142,12 @@ r600_legalize_image_load_store_impl(nir_builder *b, if (load_value) result = nir_if_phi(b, result, default_value); - if (load_value) - b->cursor = nir_after_instr(result->parent_instr); - else + { + nir_cf_list cf_list; + nir_cf_extract(&cf_list, nir_before_instr(instr), nir_after_instr(instr)); + nir_cf_reinsert(&cf_list, nir_before_block(nir_if_first_then_block(if_exists))); b->cursor = nir_after_cf_node(&else_exists->cf_node); + } return result; } @@ -158,7 +165,7 @@ r600_legalize_image_load_store_filter(const nir_instr *instr, UNUSED const void case nir_intrinsic_image_atomic: case nir_intrinsic_image_atomic_swap: case nir_intrinsic_image_size: - return true; + return (instr->pass_flags & FLAG_LEGALIZE_DONE) ? false : true; default: return false; }