From 14391cc5c5f9960d9dfd682dd9a2b18889484201 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Fri, 5 Dec 2025 16:55:41 +0100 Subject: [PATCH] panvk/csf: Make sure we don't get the same iter SB assigned twice in a row We are about to add sequences where we will do wait(cur_iter_sb),signal(next_iter_sb) in some deferred operations. When that happens, the wait mask can't have the signal sb set, otherwise the behavior is undefined. On v11+, we have enough scoreboards to disallow the currently bound endpoint SB from being returned on a NEXT_SB_ENTRY, so let's do that all the time. Signed-off-by: Boris Brezillon Reviewed-by: Christoph Pillmayer Reviewed-by: Lars-Ivar Hesselberg Simonsen Part-of: --- src/panfrost/vulkan/csf/panvk_vX_cmd_buffer.c | 16 ++++++++++++---- src/panfrost/vulkan/csf/panvk_vX_gpu_queue.c | 6 ++++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/panfrost/vulkan/csf/panvk_vX_cmd_buffer.c b/src/panfrost/vulkan/csf/panvk_vX_cmd_buffer.c index 1d7d3ac461f..6fee1ddbf9b 100644 --- a/src/panfrost/vulkan/csf/panvk_vX_cmd_buffer.c +++ b/src/panfrost/vulkan/csf/panvk_vX_cmd_buffer.c @@ -774,18 +774,26 @@ panvk_per_arch(cs_next_iter_sb)(struct panvk_cmd_buffer *cmdbuf, enum panvk_subqueue_id subqueue, struct cs_index scratch_regs) { + struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device); struct cs_builder *b = panvk_get_cs_builder(cmdbuf, subqueue); struct cs_index iter_sb = cs_extract32(b, scratch_regs, 0); - struct cs_index sb_wait_mask = cs_extract32(b, scratch_regs, 1); + struct cs_index sb_mask = cs_extract32(b, scratch_regs, 1); /* Wait for scoreboard to be available and select the next scoreboard entry */ cs_next_sb_entry(b, iter_sb, MALI_CS_SCOREBOARD_TYPE_ENDPOINT, MALI_CS_NEXT_SB_ENTRY_FORMAT_INDEX); /* Setup indirect scoreboard wait mask now for indirect defer */ - cs_move32_to(b, sb_wait_mask, 0); - cs_bit_set32(b, sb_wait_mask, sb_wait_mask, iter_sb); - cs_set_state(b, MALI_CS_SET_STATE_TYPE_SB_MASK_WAIT, sb_wait_mask); + cs_move32_to(b, sb_mask, 0); + cs_bit_set32(b, sb_mask, sb_mask, iter_sb); + cs_set_state(b, MALI_CS_SET_STATE_TYPE_SB_MASK_WAIT, sb_mask); + + /* Prevent direct re-use of the current SB to avoid conflict between + * wait(current),signal(next) (can't wait on an SB we signal). + */ + cs_move32_to(b, sb_mask, dev->csf.sb.all_iters_mask); + cs_bit_clear32(b, sb_mask, sb_mask, iter_sb); + cs_set_state(b, MALI_CS_SET_STATE_TYPE_SB_MASK_STREAM, sb_mask); } #else void diff --git a/src/panfrost/vulkan/csf/panvk_vX_gpu_queue.c b/src/panfrost/vulkan/csf/panvk_vX_gpu_queue.c index f7748f24008..f1bf49d98b8 100644 --- a/src/panfrost/vulkan/csf/panvk_vX_gpu_queue.c +++ b/src/panfrost/vulkan/csf/panvk_vX_gpu_queue.c @@ -449,8 +449,10 @@ init_subqueue(struct panvk_gpu_queue *queue, enum panvk_subqueue_id subqueue) #if PAN_ARCH >= 11 cs_set_state_imm32(&b, MALI_CS_SET_STATE_TYPE_SB_SEL_ENDPOINT, SB_ITER(0)); cs_set_state_imm32(&b, MALI_CS_SET_STATE_TYPE_SB_SEL_OTHER, SB_ID(LS)); - cs_set_state_imm32(&b, MALI_CS_SET_STATE_TYPE_SB_SEL_DEFERRED, SB_ID(DEFERRED_SYNC)); - cs_set_state_imm32(&b, MALI_CS_SET_STATE_TYPE_SB_MASK_STREAM, dev->csf.sb.all_iters_mask); + cs_set_state_imm32(&b, MALI_CS_SET_STATE_TYPE_SB_SEL_DEFERRED, + SB_ID(DEFERRED_SYNC)); + cs_set_state_imm32(&b, MALI_CS_SET_STATE_TYPE_SB_MASK_STREAM, + dev->csf.sb.all_iters_mask & ~SB_WAIT_ITER(0)); #else cs_set_scoreboard_entry(&b, SB_ITER(0), SB_ID(LS)); #endif