diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index feea0b6b82b..e34a3003403 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -595,9 +595,9 @@ v3dv_cmd_buffer_finish_job(struct v3dv_cmd_buffer *cmd_buffer) * a barrier involving geometry stages but none of the draw calls in the * job actually required a binning sync. */ - if (!(cmd_buffer->state.barrier.active_mask & V3DV_BARRIER_GRAPHICS_BIT)) { - cmd_buffer->state.barrier.bcl_barrier_buffer_access = 0; - cmd_buffer->state.barrier.bcl_barrier_image_access = 0; + if (!(cmd_buffer->state.barrier.dst_mask & V3DV_BARRIER_GRAPHICS_BIT)) { + cmd_buffer->state.barrier.bcl_buffer_access = 0; + cmd_buffer->state.barrier.bcl_image_access = 0; } if (cmd_buffer->state.oom) { @@ -683,7 +683,7 @@ cmd_buffer_serialize_job_if_needed(struct v3dv_cmd_buffer *cmd_buffer, if (!v3dv_job_type_is_gpu(job)) return; - uint8_t barrier_mask = cmd_buffer->state.barrier.active_mask; + uint8_t barrier_mask = cmd_buffer->state.barrier.dst_mask; if (barrier_mask == 0) return; @@ -704,7 +704,7 @@ cmd_buffer_serialize_job_if_needed(struct v3dv_cmd_buffer *cmd_buffer, if (barrier_mask & bit) { job->serialize = true; - cmd_buffer->state.barrier.active_mask &= ~bit; + cmd_buffer->state.barrier.dst_mask &= ~bit; } } @@ -1680,9 +1680,7 @@ cmd_buffer_execute_outside_pass(struct v3dv_cmd_buffer *primary, uint32_t cmd_buffer_count, const VkCommandBuffer *cmd_buffers) { - uint8_t pending_barrier = 0; - VkAccessFlags pending_bcl_barrier_buffer_access = 0; - VkAccessFlags pending_bcl_barrier_image_access = 0; + struct v3dv_barrier_state pending_barrier = { 0 }; for (uint32_t i = 0; i < cmd_buffer_count; i++) { V3DV_FROM_HANDLE(v3dv_cmd_buffer, secondary, cmd_buffers[i]); @@ -1710,15 +1708,13 @@ cmd_buffer_execute_outside_pass(struct v3dv_cmd_buffer *primary, if (!job) return; - if (pending_barrier) { + if (pending_barrier.dst_mask) { job->serialize = true; - if (pending_bcl_barrier_buffer_access || - pending_bcl_barrier_image_access) { + if (pending_barrier.bcl_buffer_access || + pending_barrier.bcl_image_access) { job->needs_bcl_sync = true; } - pending_barrier = 0; - pending_bcl_barrier_buffer_access = 0; - pending_bcl_barrier_image_access = 0; + memset(&pending_barrier, 0, sizeof(pending_barrier)); } } @@ -1726,23 +1722,14 @@ cmd_buffer_execute_outside_pass(struct v3dv_cmd_buffer *primary, * barrier state consumed with whatever comes after it (first job in * the next secondary or the primary, if this was the last secondary). */ - assert(secondary->state.barrier.active_mask || - (!secondary->state.barrier.bcl_barrier_buffer_access && - !secondary->state.barrier.bcl_barrier_image_access)); - pending_barrier = secondary->state.barrier.active_mask; - pending_bcl_barrier_buffer_access = - secondary->state.barrier.bcl_barrier_buffer_access; - pending_bcl_barrier_image_access = - secondary->state.barrier.bcl_barrier_image_access; + assert(secondary->state.barrier.dst_mask || + (!secondary->state.barrier.bcl_buffer_access && + !secondary->state.barrier.bcl_image_access)); + pending_barrier = secondary->state.barrier; } - if (pending_barrier) { - primary->state.barrier.active_mask = pending_barrier; - primary->state.barrier.bcl_barrier_buffer_access |= - pending_bcl_barrier_buffer_access; - primary->state.barrier.bcl_barrier_image_access |= - pending_bcl_barrier_image_access; - } + if (pending_barrier.dst_mask) + primary->state.barrier = pending_barrier; } VKAPI_ATTR void VKAPI_CALL @@ -2450,7 +2437,7 @@ cmd_buffer_binning_sync_required(struct v3dv_cmd_buffer *cmd_buffer, pipeline->shared_data->maps[BROADCOM_SHADER_GEOMETRY_BIN]; VkAccessFlags buffer_access = - cmd_buffer->state.barrier.bcl_barrier_buffer_access; + cmd_buffer->state.barrier.bcl_buffer_access; if (buffer_access) { /* Index buffer read */ if (indexed && (buffer_access & VK_ACCESS_INDEX_READ_BIT)) @@ -2499,7 +2486,7 @@ cmd_buffer_binning_sync_required(struct v3dv_cmd_buffer *cmd_buffer, } VkAccessFlags image_access = - cmd_buffer->state.barrier.bcl_barrier_image_access; + cmd_buffer->state.barrier.bcl_image_access; if (image_access) { /* Image load / store */ if (image_access & (VK_ACCESS_SHADER_READ_BIT | @@ -2520,8 +2507,8 @@ static void consume_bcl_sync(struct v3dv_cmd_buffer *cmd_buffer, struct v3dv_job *job) { job->needs_bcl_sync = true; - cmd_buffer->state.barrier.bcl_barrier_buffer_access = 0; - cmd_buffer->state.barrier.bcl_barrier_image_access = 0; + cmd_buffer->state.barrier.bcl_buffer_access = 0; + cmd_buffer->state.barrier.bcl_image_access = 0; } void @@ -2553,8 +2540,8 @@ v3dv_cmd_buffer_emit_pre_draw(struct v3dv_cmd_buffer *cmd_buffer, * to sync at the binning stage by testing if the binning shaders involved * with the draw call require access to external resources. */ - if (job->serialize && (cmd_buffer->state.barrier.bcl_barrier_buffer_access || - cmd_buffer->state.barrier.bcl_barrier_image_access)) { + if (job->serialize && (cmd_buffer->state.barrier.bcl_buffer_access || + cmd_buffer->state.barrier.bcl_image_access)) { assert(!job->needs_bcl_sync); struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline; if (cmd_buffer_binning_sync_required(cmd_buffer, pipeline, @@ -2817,17 +2804,17 @@ v3dv_CmdPipelineBarrier(VkCommandBuffer commandBuffer, if (dstStageMask & (VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)) { - cmd_buffer->state.barrier.active_mask |= V3DV_BARRIER_COMPUTE_BIT; + cmd_buffer->state.barrier.dst_mask |= V3DV_BARRIER_COMPUTE_BIT; } if (dstStageMask & (VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)) { - cmd_buffer->state.barrier.active_mask |= V3DV_BARRIER_TRANSFER_BIT; + cmd_buffer->state.barrier.dst_mask |= V3DV_BARRIER_TRANSFER_BIT; } if (dstStageMask & (~(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT))) { - cmd_buffer->state.barrier.active_mask |= V3DV_BARRIER_GRAPHICS_BIT; + cmd_buffer->state.barrier.dst_mask |= V3DV_BARRIER_GRAPHICS_BIT; if (dstStageMask & (VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | @@ -2838,18 +2825,18 @@ v3dv_CmdPipelineBarrier(VkCommandBuffer commandBuffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)) { for (int i = 0; i < memoryBarrierCount; i++) { - cmd_buffer->state.barrier.bcl_barrier_buffer_access |= + cmd_buffer->state.barrier.bcl_buffer_access |= pMemoryBarriers[i].dstAccessMask; - cmd_buffer->state.barrier.bcl_barrier_image_access |= + cmd_buffer->state.barrier.bcl_image_access |= pMemoryBarriers[i].dstAccessMask; } for (int i = 0; i < bufferBarrierCount; i++) { - cmd_buffer->state.barrier.bcl_barrier_buffer_access |= + cmd_buffer->state.barrier.bcl_buffer_access |= pBufferBarriers[i].dstAccessMask; } for (int i = 0; i < imageBarrierCount; i++) { if (pImageBarriers[i].oldLayout != VK_IMAGE_LAYOUT_UNDEFINED) { - cmd_buffer->state.barrier.bcl_barrier_image_access |= + cmd_buffer->state.barrier.bcl_image_access |= pImageBarriers[i].dstAccessMask; } } diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 10e964dace1..5c662d6095f 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -1197,6 +1197,17 @@ enum { V3DV_BARRIER_TRANSFER_BIT = (1 << 2), }; +struct v3dv_barrier_state { + /* Mask of V3DV_BARRIER_* indicating where we consume a barrier. */ + uint8_t dst_mask; + + /* For graphics barriers, access masks involved. Used to decide if we need + * to execute a binning or render barrier. + */ + VkAccessFlags bcl_buffer_access; + VkAccessFlags bcl_image_access; +}; + struct v3dv_cmd_buffer_state { struct v3dv_render_pass *pass; struct v3dv_framebuffer *framebuffer; @@ -1261,12 +1272,7 @@ struct v3dv_cmd_buffer_state { bool is_transfer; /* Barrier state tracking */ - struct { - uint8_t active_mask; /* Bitmask of V3DV_BARRIER_* */ - /* Access flags relevant to decide about BCL barriers for CLs */ - VkAccessFlags bcl_barrier_buffer_access; - VkAccessFlags bcl_barrier_image_access; - } barrier; + struct v3dv_barrier_state barrier; /* Secondary command buffer state */ struct { diff --git a/src/broadcom/vulkan/v3dvx_cmd_buffer.c b/src/broadcom/vulkan/v3dvx_cmd_buffer.c index 89f6f2fc418..933210c84a4 100644 --- a/src/broadcom/vulkan/v3dvx_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dvx_cmd_buffer.c @@ -1630,9 +1630,7 @@ v3dX(cmd_buffer_execute_inside_pass)(struct v3dv_cmd_buffer *primary, * pipelines used by the secondaries do, we need to re-start the primary * job to enable MSAA. See cmd_buffer_restart_job_for_msaa_if_needed. */ - uint8_t pending_barrier = false; - VkAccessFlags pending_bcl_barrier_buffer_access = 0; - VkAccessFlags pending_bcl_barrier_image_access = 0; + struct v3dv_barrier_state pending_barrier = { 0 }; for (uint32_t i = 0; i < cmd_buffer_count; i++) { V3DV_FROM_HANDLE(v3dv_cmd_buffer, secondary, cmd_buffers[i]); @@ -1666,11 +1664,12 @@ v3dX(cmd_buffer_execute_inside_pass)(struct v3dv_cmd_buffer *primary, * branch? */ struct v3dv_job *primary_job = primary->state.job; - if (!primary_job || secondary_job->serialize || pending_barrier) { + if (!primary_job || secondary_job->serialize || + pending_barrier.dst_mask) { const bool needs_bcl_barrier = secondary_job->needs_bcl_sync || - pending_bcl_barrier_buffer_access || - pending_bcl_barrier_image_access; + pending_barrier.bcl_buffer_access || + pending_barrier.bcl_image_access; primary_job = cmd_buffer_subpass_split_for_barrier(primary, @@ -1711,18 +1710,16 @@ v3dX(cmd_buffer_execute_inside_pass)(struct v3dv_cmd_buffer *primary, */ v3dv_cmd_buffer_finish_job(primary); v3dv_job_clone_in_cmd_buffer(secondary_job, primary); - if (pending_barrier) { + if (pending_barrier.dst_mask) { secondary_job->serialize = true; - if (pending_bcl_barrier_buffer_access || - pending_bcl_barrier_image_access) { + if (pending_barrier.bcl_buffer_access || + pending_barrier.bcl_image_access) { secondary_job->needs_bcl_sync = true; } } } - pending_barrier = 0; - pending_bcl_barrier_buffer_access = 0; - pending_bcl_barrier_image_access = 0; + memset(&pending_barrier, 0, sizeof(pending_barrier)); } /* If the secondary has recorded any vkCmdEndQuery commands, we need to @@ -1734,24 +1731,15 @@ v3dX(cmd_buffer_execute_inside_pass)(struct v3dv_cmd_buffer *primary, /* If this secondary had any pending barrier state we will need that * barrier state consumed with whatever comes next in the primary. */ - assert(secondary->state.barrier.active_mask || - (!secondary->state.barrier.bcl_barrier_buffer_access && - !secondary->state.barrier.bcl_barrier_image_access)); + assert(secondary->state.barrier.dst_mask || + (!secondary->state.barrier.bcl_buffer_access && + !secondary->state.barrier.bcl_image_access)); - pending_barrier = secondary->state.barrier.active_mask; - pending_bcl_barrier_buffer_access = - secondary->state.barrier.bcl_barrier_buffer_access; - pending_bcl_barrier_image_access = - secondary->state.barrier.bcl_barrier_image_access; + pending_barrier = secondary->state.barrier; } - if (pending_barrier) { - primary->state.barrier.active_mask = pending_barrier; - primary->state.barrier.bcl_barrier_buffer_access |= - pending_bcl_barrier_buffer_access; - primary->state.barrier.bcl_barrier_image_access |= - pending_bcl_barrier_image_access; - } + if (pending_barrier.dst_mask) + primary->state.barrier = pending_barrier; } static void