From 43d9765e35d936a54fb5a1846ce21b06edb1c3da Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Fri, 24 Oct 2025 16:59:22 +0200 Subject: [PATCH] r600/sfn: AR loads are not dependend on the future and other code blocks If the AR is loaded from a register changing that register in a loop was resulting in a scheduling failure because the AR load was made dependend on a later instruction. Fix the dependencies by only using dependencies on older instruuctions in the same block. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/14114 Fixes: d21054b4bc9 ("r600/sfn: Add pass to split addess and index register loads") Signed-off-by: Gert Wollny Part-of: --- .../r600/sfn/sfn_split_address_loads.cpp | 6 +- .../drivers/r600/sfn/tests/meson.build | 2 +- .../r600/sfn/tests/sfn_regression_test.cpp | 65 +++++++++++++++++++ 3 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 src/gallium/drivers/r600/sfn/tests/sfn_regression_test.cpp diff --git a/src/gallium/drivers/r600/sfn/sfn_split_address_loads.cpp b/src/gallium/drivers/r600/sfn/sfn_split_address_loads.cpp index ad6860fd6f8..f1ba86c6cf5 100644 --- a/src/gallium/drivers/r600/sfn/sfn_split_address_loads.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_split_address_loads.cpp @@ -88,8 +88,10 @@ class CollectDeps : public ConstRegisterVisitor { public: void visit(const Register& r) override { - for (auto p : r.parents()) - add_dep(p); + for (auto p : r.parents()) { + if (instr->block_id() == p->block_id() && instr->index() < p->index()) + add_dep(p); + } } void visit(const LocalArray& value) override {(void)value; UNREACHABLE("Array is not a value");} void visit(const LocalArrayValue& r) override diff --git a/src/gallium/drivers/r600/sfn/tests/meson.build b/src/gallium/drivers/r600/sfn/tests/meson.build index 83505e25625..9dac01d961c 100644 --- a/src/gallium/drivers/r600/sfn/tests/meson.build +++ b/src/gallium/drivers/r600/sfn/tests/meson.build @@ -22,7 +22,7 @@ r600_test_dep = declare_dependency( if with_tests foreach t : ['valuefactory', 'value', 'instr', 'instrfromstring', 'liverange', - 'optimizer', 'shaderfromstring', 'split_address_loads' ] + 'optimizer', 'regression', 'shaderfromstring', 'split_address_loads' ] test( t, executable('test-@0@-r600-sfn'.format(t), diff --git a/src/gallium/drivers/r600/sfn/tests/sfn_regression_test.cpp b/src/gallium/drivers/r600/sfn/tests/sfn_regression_test.cpp new file mode 100644 index 00000000000..6347db8bca8 --- /dev/null +++ b/src/gallium/drivers/r600/sfn/tests/sfn_regression_test.cpp @@ -0,0 +1,65 @@ +#include "sfn_test_shaders.h" + +#include "../sfn_optimizer.h" +#include "../sfn_ra.h" +#include "../sfn_scheduler.h" +#include "../sfn_shader.h" +#include "../sfn_split_address_loads.h" + +using namespace r600; +using std::ostringstream; + +TEST_F(TestShaderFromNir, CombineRegisterToTexSrc) +{ + const char *shader_input = + R"(VS +CHIPCLASS EVERGREEN +INPUT LOC:0 +INPUT LOC:1 +OUTPUT LOC:0 VARYING_SLOT:0 MASK:15 +OUTPUT LOC:1 VARYING_SLOT:32 MASK:3 +REGISTERS R1.xyzw R2.xyzw R6.y R7.x R8.y R9.x R10.y +ARRAYS A3[2].zw +SHADER +BLOCK_START +ALU MOV R10.y@free : R2.x@fully{sb} {W} +ALU MOV R9.x@free : R2.y@fully{sb} {W} +ALU MOV R8.y@free : R2.z@fully{sb} {W} +ALU MOV R7.x@free : R2.w@fully{sb} {W} +ALU MOV R6.y@free : I[0] {W} +LOOP_BEGIN +BLOCK_END +BLOCK_START +IF (( ALU PRED_SETGE_INT __.x : R6.y@free KC0[0].x {LEP} PUSH_BEFORE )) +BLOCK_END +BLOCK_START +BREAK +BLOCK_END +BLOCK_START +ENDIF +BLOCK_END +BLOCK_START +ALU INT_TO_FLT CLAMP S22.y@free{s} : R6.y@free {W} +ALU TRUNC S24.w@free{s} : S22.y@free{s} {W} +ALU FLT_TO_INT S25.x@free{s} : S24.w@free{s} {W} +ALU MOV A3[S25.x@free].z : R10.y@free {W} +ALU MOV A3[S25.x@free].w : R9.x@free {W} +ALU MUL_IEEE R5.x@free : R9.x@free I[0.5] {W} +ALU MUL_IEEE R9.x@free : R8.y@free I[0.5] {W} +ALU MUL_IEEE R8.y@free : R7.x@free I[0.5] {W} +ALU MUL_IEEE R7.x@free : R10.y@free I[0.5] {W} +ALU ADD_INT R6.y@free : R6.y@free I[1] {W} +ALU MOV R10.y@free : R5.x@free {W} +LOOP_END +BLOCK_END +BLOCK_START +ALU ADD S47.z@group{s} : A3[0].z A3[1].z {W} +ALU ADD S47.x@group{s} : A3[0].w A3[1].w {W} +EXPORT_DONE PARAM 0 S47.zx__ +EXPORT_DONE POS 0 R1.xyzw +BLOCK_END)"; + + auto sh = from_string(shader_input); + split_address_loads(*sh); + schedule(sh); +}