From ad249e902016a287c4aadafeba063c5688608efc Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Mon, 30 May 2022 08:52:31 +0200 Subject: [PATCH] v3dv: track sources of barriers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Until now we have been tracking the dstStageMask of barriers (where they are consumed) but not where they are produced (the srcStageMask). With this change we extend our barrier state to keep track of this as well. This allows the driver to have better knowledge of the intended barrier semantics so it can limit the amount of synchronization it does only to the source stages involved with a barrier. We will do this in a later patch. Reviewed-by: Alejandro PiƱeiro Part-of: --- src/broadcom/vulkan/v3dv_cmd_buffer.c | 26 ++++++++++++++++++++++++++ src/broadcom/vulkan/v3dv_private.h | 7 +++++++ 2 files changed, 33 insertions(+) diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index e34a3003403..6b245d303d4 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -688,22 +688,27 @@ cmd_buffer_serialize_job_if_needed(struct v3dv_cmd_buffer *cmd_buffer, return; uint8_t bit = 0; + uint8_t *src_mask; if (job->type == V3DV_JOB_TYPE_GPU_CSD) { assert(!job->is_transfer); bit = V3DV_BARRIER_COMPUTE_BIT; + src_mask = &cmd_buffer->state.barrier.src_mask_compute; } else if (job->is_transfer) { assert(job->type == V3DV_JOB_TYPE_GPU_CL || job->type == V3DV_JOB_TYPE_GPU_CL_SECONDARY || job->type == V3DV_JOB_TYPE_GPU_TFU); bit = V3DV_BARRIER_TRANSFER_BIT; + src_mask = &cmd_buffer->state.barrier.src_mask_transfer; } else { assert(job->type == V3DV_JOB_TYPE_GPU_CL || job->type == V3DV_JOB_TYPE_GPU_CL_SECONDARY); bit = V3DV_BARRIER_GRAPHICS_BIT; + src_mask = &cmd_buffer->state.barrier.src_mask_graphics; } if (barrier_mask & bit) { job->serialize = true; + *src_mask = 0; cmd_buffer->state.barrier.dst_mask &= ~bit; } } @@ -2802,19 +2807,40 @@ v3dv_CmdPipelineBarrier(VkCommandBuffer commandBuffer, if (job) v3dv_cmd_buffer_finish_job(cmd_buffer); + /* Track the source of the barrier */ + uint8_t src_mask = 0; + if (srcStageMask & (VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)) { + src_mask |= V3DV_BARRIER_COMPUTE_BIT; + } + + if (srcStageMask & (VK_PIPELINE_STAGE_TRANSFER_BIT | + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)) { + src_mask |= V3DV_BARRIER_TRANSFER_BIT; + } + + if (srcStageMask & (~(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | + VK_PIPELINE_STAGE_TRANSFER_BIT))) { + src_mask |= V3DV_BARRIER_GRAPHICS_BIT; + } + + /* Track consumer of the barrier */ if (dstStageMask & (VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)) { cmd_buffer->state.barrier.dst_mask |= V3DV_BARRIER_COMPUTE_BIT; + cmd_buffer->state.barrier.src_mask_compute |= src_mask; } if (dstStageMask & (VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)) { cmd_buffer->state.barrier.dst_mask |= V3DV_BARRIER_TRANSFER_BIT; + cmd_buffer->state.barrier.src_mask_transfer |= src_mask; } if (dstStageMask & (~(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT))) { cmd_buffer->state.barrier.dst_mask |= V3DV_BARRIER_GRAPHICS_BIT; + cmd_buffer->state.barrier.src_mask_graphics |= src_mask; if (dstStageMask & (VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 5c662d6095f..bfde1119e9e 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -1201,6 +1201,13 @@ struct v3dv_barrier_state { /* Mask of V3DV_BARRIER_* indicating where we consume a barrier. */ uint8_t dst_mask; + /* For each possible consumer of a barrier, a mask of V3DV_BARRIER_* + * indicating the sources of the dependency. + */ + uint8_t src_mask_graphics; + uint8_t src_mask_transfer; + uint8_t src_mask_compute; + /* For graphics barriers, access masks involved. Used to decide if we need * to execute a binning or render barrier. */