Module: Mesa Branch: main Commit: eff4db3718b85c9dab5f34ec868a8297c0bf250c URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=eff4db3718b85c9dab5f34ec868a8297c0bf250c
Author: Timur Kristóf <[email protected]> Date: Fri Oct 20 19:55:38 2023 +0200 radv: Add gang follower semaphore functions. These functions implement the possibility to have the gang leader wait for its follower. Signed-off-by: Timur Kristóf <[email protected]> Reviewed-by: Samuel Pitoiset <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25796> --- src/amd/vulkan/radv_cmd_buffer.c | 33 +++++++++++++++++++++++++++++++-- src/amd/vulkan/radv_private.h | 8 +++++--- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 7d8fc9760d1..4fcdf44d7c2 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -618,6 +618,12 @@ radv_gang_leader_sem_dirty(const struct radv_cmd_buffer *cmd_buffer) return cmd_buffer->gang.sem.leader_value != cmd_buffer->gang.sem.emitted_leader_value; } +static bool +radv_gang_follower_sem_dirty(const struct radv_cmd_buffer *cmd_buffer) +{ + return cmd_buffer->gang.sem.follower_value != cmd_buffer->gang.sem.emitted_follower_value; +} + ALWAYS_INLINE static bool radv_flush_gang_semaphore(struct radv_cmd_buffer *cmd_buffer, struct radeon_cmdbuf *cs, const enum radv_queue_family qf, const uint32_t va_off, const uint32_t value) @@ -646,6 +652,18 @@ radv_flush_gang_leader_semaphore(struct radv_cmd_buffer *cmd_buffer) return radv_flush_gang_semaphore(cmd_buffer, cmd_buffer->cs, cmd_buffer->qf, 0, cmd_buffer->gang.sem.leader_value); } +ALWAYS_INLINE static bool +radv_flush_gang_follower_semaphore(struct radv_cmd_buffer *cmd_buffer) +{ + if (!radv_gang_follower_sem_dirty(cmd_buffer)) + return false; + + /* Follower writes a value to the semaphore which the gang leader can wait for. */ + cmd_buffer->gang.sem.emitted_follower_value = cmd_buffer->gang.sem.follower_value; + return radv_flush_gang_semaphore(cmd_buffer, cmd_buffer->gang.cs, RADV_QUEUE_COMPUTE, 4, + cmd_buffer->gang.sem.follower_value); +} + ALWAYS_INLINE static void radv_wait_gang_semaphore(struct radv_cmd_buffer *cmd_buffer, struct radeon_cmdbuf *cs, const enum radv_queue_family qf, const uint32_t va_off, const uint32_t value) @@ -662,6 +680,13 @@ radv_wait_gang_leader(struct radv_cmd_buffer *cmd_buffer) radv_wait_gang_semaphore(cmd_buffer, cmd_buffer->gang.cs, RADV_QUEUE_COMPUTE, 0, cmd_buffer->gang.sem.leader_value); } +ALWAYS_INLINE static void +radv_wait_gang_follower(struct radv_cmd_buffer *cmd_buffer) +{ + /* Gang leader waits for the semaphore which the follower wrote. */ + radv_wait_gang_semaphore(cmd_buffer, cmd_buffer->cs, cmd_buffer->qf, 4, cmd_buffer->gang.sem.follower_value); +} + static bool radv_gang_init(struct radv_cmd_buffer *cmd_buffer) { @@ -7507,9 +7532,11 @@ radv_CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCou /* Emit pending flushes on primary prior to executing secondary. */ radv_gang_cache_flush(primary); - /* Wait for primary GFX->ACE semaphore, if necessary. */ + /* Wait for gang semaphores, if necessary. */ if (radv_flush_gang_leader_semaphore(primary)) radv_wait_gang_leader(primary); + if (radv_flush_gang_follower_semaphore(primary)) + radv_wait_gang_follower(primary); /* Execute the secondary compute cmdbuf. * Don't use IB2 packets because they are not supported on compute queues. @@ -7520,12 +7547,14 @@ radv_CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCou /* Update pending ACE internal flush bits from the secondary cmdbuf */ primary->gang.flush_bits |= secondary->gang.flush_bits; - /* Increment primary semaphore if secondary was dirty. + /* Increment gang semaphores if secondary was dirty. * This happens when the secondary cmdbuf has a barrier which * isn't consumed by a draw call. */ if (radv_gang_leader_sem_dirty(secondary)) primary->gang.sem.leader_value++; + if (radv_gang_follower_sem_dirty(secondary)) + primary->gang.sem.follower_value++; primary->device->ws->cs_execute_secondary(primary->cs, secondary->cs, allow_ib2); diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index a0db145fdfe..b241c17f0c9 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -1844,9 +1844,11 @@ struct radv_cmd_buffer { * The follower writes the value, and the leader waits. */ struct { - uint64_t va; /* Virtual address of the semaphore. */ - uint32_t leader_value; /* Current value of the leader. */ - uint32_t emitted_leader_value; /* Emitted value emitted by the leader. */ + uint64_t va; /* Virtual address of the semaphore. */ + uint32_t leader_value; /* Current value of the leader. */ + uint32_t emitted_leader_value; /* Last value emitted by the leader. */ + uint32_t follower_value; /* Current value of the follower. */ + uint32_t emitted_follower_value; /* Last value emitted by the follower. */ } sem; } gang;
