From 085cfc98cc07a756bf93d25440b265dd650a0505 Mon Sep 17 00:00:00 2001 From: Patrick Lerda Date: Fri, 7 Mar 2025 12:47:30 +0100 Subject: [PATCH] r600: fix cayman main non-deterministic behavior problem Cayman has a non-deterministic behavior issue which is visible with the test below (arb_shader_image_size). The tests fail randomly at the "fragment" test category. Anyway, if the "compute" category is removed, the same tests are working flawlessly. The "compute" part of the driver was interfering with the graphic pipeline. The culprit is the packet PKT3_DEALLOC_STATE which puts the gpu in an incorrect state to perform some graphic operations. This change fixes this problem by issuing a PKT3_CLEAR_STATE packet just after the PKT3_SURFACE_SYNC packet. As explained by d51dbe048af PKT3_DEALLOC_STATE is mandatory on cayman to avoid a gpu hang at the PKT3_SURFACE_SYNC stage. This correction makes tests like "spec@glsl-4.30@execution@built-in-functions@cs-.*" to pass in an utterly deterministic way without random failures. This change removes around 500 random failures for a "piglit run all". For instance, this issue is triggered on cayman with "piglit/bin/arb_shader_image_size-builtin -auto -fbo". Fixes: d51dbe048af ("r600g/compute: Emit DEALLOC_STATE on cayman after dispatching a compute shader.") Signed-off-by: Patrick Lerda Part-of: --- src/gallium/drivers/r600/evergreen_compute.c | 1 + src/gallium/drivers/r600/r600_hw_context.c | 10 ++++++++++ src/gallium/drivers/r600/r600_pipe.h | 1 + src/gallium/drivers/r600/r600d.h | 1 + 4 files changed, 13 insertions(+) diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c index 444ce5905a1..f9d09e03cbc 100644 --- a/src/gallium/drivers/r600/evergreen_compute.c +++ b/src/gallium/drivers/r600/evergreen_compute.c @@ -844,6 +844,7 @@ static void compute_emit_cs(struct r600_context *rctx, */ radeon_emit(cs, PKT3C(PKT3_DEALLOC_STATE, 0, 0)); radeon_emit(cs, 0); + rctx->cayman_dealloc_state = true; } if (rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_TGSI || rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_NIR) diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index 57021b69f57..9b3e997fb76 100644 --- a/src/gallium/drivers/r600/r600_hw_context.c +++ b/src/gallium/drivers/r600/r600_hw_context.c @@ -222,6 +222,16 @@ void r600_flush_emit(struct r600_context *rctx) radeon_emit(cs, 0xffffffff); /* CP_COHER_SIZE */ radeon_emit(cs, 0); /* CP_COHER_BASE */ radeon_emit(cs, 0x0000000A); /* POLL_INTERVAL */ + + /* PKT3_CLEAR_STATE below is required on cayman to set the gpu + * in a deterministic state after a compute shader. Otherwise, + * the graphic pipeline could fail in a non-deterministic way. + * See https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33973 */ + if (unlikely(rctx->cayman_dealloc_state)) { + radeon_emit(cs, PKT3C(PKT3_CLEAR_STATE, 0, 0)); + radeon_emit(cs, 0); + rctx->cayman_dealloc_state = false; + } } if (rctx->b.flags & R600_CONTEXT_START_PIPELINE_STATS) { diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 67716ede6af..8c0315a8dbe 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -609,6 +609,7 @@ struct r600_context { bool cmd_buf_is_compute; struct pipe_resource *append_fence; uint32_t append_fence_id; + bool cayman_dealloc_state; }; static inline void r600_emit_command_buffer(struct radeon_cmdbuf *cs, diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h index 9265e957a70..1eb0a7422c5 100644 --- a/src/gallium/drivers/r600/r600d.h +++ b/src/gallium/drivers/r600/r600d.h @@ -36,6 +36,7 @@ #define PKT3_NOP 0x10 #define EG_PKT3_SET_BASE 0x11 /* >= evergreen */ #define EG_DRAW_INDEX_INDIRECT_PATCH_TABLE_BASE 1 /* DX11 Draw_Index_Indirect Patch Table Base */ +#define PKT3_CLEAR_STATE 0x12 #define EG_PKT3_INDEX_BUFFER_SIZE 0x13 #define PKT3_INDIRECT_BUFFER_END 0x17 #define PKT3_SET_PREDICATION 0x20