Mesa (main): v3dv: consume barriers at the right stages

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue May 31 06:30:22 UTC 2022


Module: Mesa
Branch: main
Commit: 24ebcbbaa77761cf058b2a7252251d3284383431
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=24ebcbbaa77761cf058b2a7252251d3284383431

Author: Iago Toral Quiroga <itoral at igalia.com>
Date:   Wed May 25 13:56:33 2022 +0200

v3dv: consume barriers at the right stages

Until now, we have always consumed barriers with the next GPU job
recorded into the command buffer after the barrier even if the job
was not the target of the barrier itself. This works based on the
idea that when we consume a barrier in a job we serialize it against
all queues, so effectively we are ensuring that whatever came
before it has completed, so if the barrier was intended for an
even later job, it would have served its purpose anyway.

It should be noted that CL jobs are special because they are actually
split in two different queues: the binning queue and the render
queue, with a dependency between them to ensure render runs after
binning. With our current implementation, if we have 3 jobs (A, B,
C) and we have a barrier after job A which is intended to block job C
on A's completion, with our implementation we would instead block
B on A's completion. If C is a CL job, and the barrier was targetting
the binning stage then we can have the following scenarios:

1. If B) is a CL job, it will consume the barrier at its binning
   stage, so we know that B's binning will not start until A has
   completed. Then C's binning will not start until B's binning
   has completed, and thus, will not start until A has completed,
   as intended.

2. If B) is not a CL job, it will consume the barrier and will not
   start until A has completed, however, C's binning job will be
   submitted to the binning queue without any sync requirements
   and since B did not put any jobs in the binning queue it will
   start as soon as A's binning has completed, but not A's render,
   which would be incorrect.

Further, since a981ac0539 we now skip consumming BCL barriers if
a job does not have draw calls that can be affected by them. In the
same scenarios as before, now case 1) would also be problematic,
since B may skip the binning sync in that case and start immediately,
and since C's binning would be allowe to start immediately after B's
binning, there is no guarantee that this doesn't happen in parallel
with A's render.

With this patch we fix this situation by tracking the intended
consumer of each barrier: graphics, compute or transfer, and we make
sure to consume them only with jobs that match those semantics.

This fixes flakyness in dEQP-VK.device_group.*

Fixes: a981ac0539 ('v3dv: skip binning sync if binning shaders don't access external resources')
Reviewed-by: Alejandro Piñeiro <apinheiro at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16743>

---

 src/broadcom/vulkan/v3dv_cmd_buffer.c  | 135 +++++++++++++++++++++------------
 src/broadcom/vulkan/v3dv_meta_clear.c  |   8 ++
 src/broadcom/vulkan/v3dv_meta_copy.c   |  39 +++++++++-
 src/broadcom/vulkan/v3dv_private.h     |  25 ++++--
 src/broadcom/vulkan/v3dvx_cmd_buffer.c |  24 +++---
 5 files changed, 160 insertions(+), 71 deletions(-)

diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c
index a70c46eee32..e761289eaaa 100644
--- a/src/broadcom/vulkan/v3dv_cmd_buffer.c
+++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c
@@ -597,8 +597,8 @@ v3dv_cmd_buffer_finish_job(struct v3dv_cmd_buffer *cmd_buffer)
     * (we always finish the current job before processing a pipeline barrier).
     */
    if (job->serialize) {
-      cmd_buffer->state.bcl_barrier_buffer_access = 0;
-      cmd_buffer->state.bcl_barrier_image_access = 0;
+      cmd_buffer->state.barrier.bcl_barrier_buffer_access = 0;
+      cmd_buffer->state.barrier.bcl_barrier_image_access = 0;
    }
 
    if (cmd_buffer->state.oom) {
@@ -678,17 +678,35 @@ cmd_buffer_serialize_job_if_needed(struct v3dv_cmd_buffer *cmd_buffer,
 {
    assert(cmd_buffer && job);
 
-   if (!cmd_buffer->state.has_barrier)
-      return;
-
    /* Serialization only affects GPU jobs, CPU jobs are always automatically
     * serialized.
     */
    if (!v3dv_job_type_is_gpu(job))
       return;
 
-   job->serialize = true;
-   cmd_buffer->state.has_barrier = false;
+   uint8_t barrier_mask = cmd_buffer->state.barrier.active_mask;
+   if (barrier_mask == 0)
+      return;
+
+   uint8_t bit = 0;
+   if (job->type == V3DV_JOB_TYPE_GPU_CSD) {
+      assert(!job->is_transfer);
+      bit = V3DV_BARRIER_COMPUTE_BIT;
+   } 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;
+   } else {
+      assert(job->type == V3DV_JOB_TYPE_GPU_CL ||
+             job->type == V3DV_JOB_TYPE_GPU_CL_SECONDARY);
+      bit = V3DV_BARRIER_GRAPHICS_BIT;
+   }
+
+   if (barrier_mask & bit) {
+      job->serialize = true;
+      cmd_buffer->state.barrier.active_mask &= ~bit;
+   }
 }
 
 void
@@ -752,6 +770,8 @@ v3dv_job_init(struct v3dv_job *job,
       if (cmd_buffer->state.pass)
          job->first_subpass = subpass_idx;
 
+      job->is_transfer = cmd_buffer->state.is_transfer;
+
       cmd_buffer_serialize_job_if_needed(cmd_buffer, job);
    }
 }
@@ -1661,7 +1681,7 @@ cmd_buffer_execute_outside_pass(struct v3dv_cmd_buffer *primary,
                                 uint32_t cmd_buffer_count,
                                 const VkCommandBuffer *cmd_buffers)
 {
-   bool pending_barrier = false;
+   uint8_t pending_barrier = 0;
    VkAccessFlags pending_bcl_barrier_buffer_access = 0;
    VkAccessFlags pending_bcl_barrier_image_access = 0;
    for (uint32_t i = 0; i < cmd_buffer_count; i++) {
@@ -1697,7 +1717,7 @@ cmd_buffer_execute_outside_pass(struct v3dv_cmd_buffer *primary,
                 pending_bcl_barrier_image_access) {
                job->needs_bcl_sync = true;
             }
-            pending_barrier = false;
+            pending_barrier = 0;
             pending_bcl_barrier_buffer_access = 0;
             pending_bcl_barrier_image_access = 0;
          }
@@ -1707,21 +1727,21 @@ 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.has_barrier ||
-             (!secondary->state.bcl_barrier_buffer_access &&
-              !secondary->state.bcl_barrier_image_access));
-      pending_barrier = secondary->state.has_barrier;
+      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.bcl_barrier_buffer_access;
+         secondary->state.barrier.bcl_barrier_buffer_access;
       pending_bcl_barrier_image_access =
-         secondary->state.bcl_barrier_image_access;
+         secondary->state.barrier.bcl_barrier_image_access;
    }
 
    if (pending_barrier) {
-      primary->state.has_barrier = true;
-      primary->state.bcl_barrier_buffer_access |=
+      primary->state.barrier.active_mask = pending_barrier;
+      primary->state.barrier.bcl_barrier_buffer_access |=
          pending_bcl_barrier_buffer_access;
-      primary->state.bcl_barrier_image_access |=
+      primary->state.barrier.bcl_barrier_image_access |=
          pending_bcl_barrier_image_access;
    }
 }
@@ -2430,9 +2450,9 @@ cmd_buffer_binning_sync_required(struct v3dv_cmd_buffer *cmd_buffer,
    const struct v3dv_descriptor_maps *gs_bin_maps =
       pipeline->shared_data->maps[BROADCOM_SHADER_GEOMETRY_BIN];
 
-   if (cmd_buffer->state.bcl_barrier_buffer_access) {
-      VkAccessFlags buffer_access = cmd_buffer->state.bcl_barrier_buffer_access;
-
+  VkAccessFlags buffer_access =
+      cmd_buffer->state.barrier.bcl_barrier_buffer_access;
+   if (buffer_access) {
       /* Index buffer read */
       if (indexed && (buffer_access & VK_ACCESS_INDEX_READ_BIT))
          return true;
@@ -2479,9 +2499,9 @@ cmd_buffer_binning_sync_required(struct v3dv_cmd_buffer *cmd_buffer,
       }
    }
 
-   if (cmd_buffer->state.bcl_barrier_image_access) {
-      VkAccessFlags image_access = cmd_buffer->state.bcl_barrier_image_access;
-
+   VkAccessFlags image_access =
+      cmd_buffer->state.barrier.bcl_barrier_image_access;
+   if (image_access) {
       /* Image load / store */
       if (image_access & (VK_ACCESS_SHADER_READ_BIT |
                           VK_ACCESS_SHADER_WRITE_BIT |
@@ -2501,8 +2521,8 @@ static void
 consume_bcl_sync(struct v3dv_cmd_buffer *cmd_buffer, struct v3dv_job *job)
 {
    job->needs_bcl_sync = true;
-   cmd_buffer->state.bcl_barrier_buffer_access = 0;
-   cmd_buffer->state.bcl_barrier_image_access = 0;
+   cmd_buffer->state.barrier.bcl_barrier_buffer_access = 0;
+   cmd_buffer->state.barrier.bcl_barrier_image_access = 0;
 }
 
 void
@@ -2534,14 +2554,15 @@ 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.bcl_barrier_buffer_access ||
-                          cmd_buffer->state.bcl_barrier_image_access)) {
+   if (job->serialize && (cmd_buffer->state.barrier.bcl_barrier_buffer_access ||
+                          cmd_buffer->state.barrier.bcl_barrier_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,
                                            indexed, indirect)) {
          consume_bcl_sync(cmd_buffer, job);
       }
+      /* FIXME: clear bc flags whether consumed bcl barrier or not? */
    }
 
    /* GL shader state binds shaders, uniform and vertex attribute state. The
@@ -2795,29 +2816,43 @@ v3dv_CmdPipelineBarrier(VkCommandBuffer commandBuffer,
    if (job)
       v3dv_cmd_buffer_finish_job(cmd_buffer);
 
-   cmd_buffer->state.has_barrier = true;
-   if (dstStageMask & (VK_PIPELINE_STAGE_VERTEX_INPUT_BIT |
-                       VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
-                       VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT |
-                       VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
-                       VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT |
-                       VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT |
-                       VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT |
+   if (dstStageMask & (VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
                        VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)) {
-      for (int i = 0; i < memoryBarrierCount; i++) {
-         cmd_buffer->state.bcl_barrier_buffer_access |=
-            pMemoryBarriers[i].dstAccessMask;
-         cmd_buffer->state.bcl_barrier_image_access |=
-            pMemoryBarriers[i].dstAccessMask;
-      }
-      for (int i = 0; i < bufferBarrierCount; i++) {
-         cmd_buffer->state.bcl_barrier_buffer_access |=
-            pBufferBarriers[i].dstAccessMask;
-      }
-      for (int i = 0; i < imageBarrierCount; i++) {
-         if (pImageBarriers[i].oldLayout != VK_IMAGE_LAYOUT_UNDEFINED) {
-            cmd_buffer->state.bcl_barrier_image_access |=
-               pImageBarriers[i].dstAccessMask;
+      cmd_buffer->state.barrier.active_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;
+   }
+
+   if (dstStageMask & (~(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
+                         VK_PIPELINE_STAGE_TRANSFER_BIT))) {
+      cmd_buffer->state.barrier.active_mask |= V3DV_BARRIER_GRAPHICS_BIT;
+
+      if (dstStageMask & (VK_PIPELINE_STAGE_VERTEX_INPUT_BIT |
+                          VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
+                          VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT |
+                          VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
+                          VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT |
+                          VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT |
+                          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 |=
+               pMemoryBarriers[i].dstAccessMask;
+            cmd_buffer->state.barrier.bcl_barrier_image_access |=
+               pMemoryBarriers[i].dstAccessMask;
+         }
+         for (int i = 0; i < bufferBarrierCount; i++) {
+            cmd_buffer->state.barrier.bcl_barrier_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 |=
+                  pImageBarriers[i].dstAccessMask;
+            }
          }
       }
    }
diff --git a/src/broadcom/vulkan/v3dv_meta_clear.c b/src/broadcom/vulkan/v3dv_meta_clear.c
index 3bbede23b9c..00c5d11c183 100644
--- a/src/broadcom/vulkan/v3dv_meta_clear.c
+++ b/src/broadcom/vulkan/v3dv_meta_clear.c
@@ -160,11 +160,15 @@ v3dv_CmdClearColorImage(VkCommandBuffer commandBuffer,
       .color = *pColor,
    };
 
+   cmd_buffer->state.is_transfer = true;
+
    for (uint32_t i = 0; i < rangeCount; i++) {
       if (clear_image_tlb(cmd_buffer, image, &clear_value, &pRanges[i]))
          continue;
       unreachable("Unsupported color clear.");
    }
+
+   cmd_buffer->state.is_transfer = false;
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -182,11 +186,15 @@ v3dv_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer,
       .depthStencil = *pDepthStencil,
    };
 
+   cmd_buffer->state.is_transfer = true;
+
    for (uint32_t i = 0; i < rangeCount; i++) {
       if (clear_image_tlb(cmd_buffer, image, &clear_value, &pRanges[i]))
          continue;
       unreachable("Unsupported depth/stencil clear.");
    }
+
+   cmd_buffer->state.is_transfer = false;
 }
 
 static void
diff --git a/src/broadcom/vulkan/v3dv_meta_copy.c b/src/broadcom/vulkan/v3dv_meta_copy.c
index a1dbbd9fd65..3e746a75d08 100644
--- a/src/broadcom/vulkan/v3dv_meta_copy.c
+++ b/src/broadcom/vulkan/v3dv_meta_copy.c
@@ -749,6 +749,8 @@ v3dv_CmdCopyImageToBuffer2KHR(VkCommandBuffer commandBuffer,
 
    assert(image->vk.samples == VK_SAMPLE_COUNT_1_BIT);
 
+   cmd_buffer->state.is_transfer = true;
+
    for (uint32_t i = 0; i < info->regionCount; i++) {
       if (copy_image_to_buffer_tlb(cmd_buffer, buffer, image, &info->pRegions[i]))
          continue;
@@ -756,6 +758,8 @@ v3dv_CmdCopyImageToBuffer2KHR(VkCommandBuffer commandBuffer,
          continue;
       unreachable("Unsupported image to buffer copy.");
    }
+
+   cmd_buffer->state.is_transfer = false;
 }
 
 /**
@@ -1169,6 +1173,8 @@ v3dv_CmdCopyImage2KHR(VkCommandBuffer commandBuffer,
 
    assert(src->vk.samples == dst->vk.samples);
 
+   cmd_buffer->state.is_transfer = true;
+
    for (uint32_t i = 0; i < info->regionCount; i++) {
       if (copy_image_tfu(cmd_buffer, dst, src, &info->pRegions[i]))
          continue;
@@ -1178,6 +1184,8 @@ v3dv_CmdCopyImage2KHR(VkCommandBuffer commandBuffer,
          continue;
       unreachable("Image copy not supported");
    }
+
+   cmd_buffer->state.is_transfer = false;
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -1188,6 +1196,8 @@ v3dv_CmdCopyBuffer2KHR(VkCommandBuffer commandBuffer,
    V3DV_FROM_HANDLE(v3dv_buffer, src_buffer, pCopyBufferInfo->srcBuffer);
    V3DV_FROM_HANDLE(v3dv_buffer, dst_buffer, pCopyBufferInfo->dstBuffer);
 
+   cmd_buffer->state.is_transfer = true;
+
    for (uint32_t i = 0; i < pCopyBufferInfo->regionCount; i++) {
       v3dv_X(cmd_buffer->device, meta_copy_buffer)
          (cmd_buffer,
@@ -1195,6 +1205,8 @@ v3dv_CmdCopyBuffer2KHR(VkCommandBuffer commandBuffer,
           src_buffer->mem->bo, src_buffer->mem_offset,
           &pCopyBufferInfo->pRegions[i]);
    }
+
+   cmd_buffer->state.is_transfer = false;
 }
 
 static void
@@ -1230,6 +1242,8 @@ v3dv_CmdUpdateBuffer(VkCommandBuffer commandBuffer,
       return;
    }
 
+   cmd_buffer->state.is_transfer = true;
+
    memcpy(src_bo->map, pData, dataSize);
 
    v3dv_bo_unmap(cmd_buffer->device, src_bo);
@@ -1245,11 +1259,12 @@ v3dv_CmdUpdateBuffer(VkCommandBuffer commandBuffer,
       (cmd_buffer, dst_buffer->mem->bo, dst_buffer->mem_offset,
        src_bo, 0, &region);
 
-   if (!copy_job)
-      return;
+   if (copy_job) {
+      v3dv_cmd_buffer_add_private_obj(
+         cmd_buffer, (uint64_t)(uintptr_t)src_bo, destroy_update_buffer_cb);
+   }
 
-   v3dv_cmd_buffer_add_private_obj(
-      cmd_buffer, (uint64_t)(uintptr_t)src_bo, destroy_update_buffer_cb);
+   cmd_buffer->state.is_transfer = false;
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -1262,6 +1277,8 @@ v3dv_CmdFillBuffer(VkCommandBuffer commandBuffer,
    V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
    V3DV_FROM_HANDLE(v3dv_buffer, dst_buffer, dstBuffer);
 
+   cmd_buffer->state.is_transfer = true;
+
    struct v3dv_bo *bo = dst_buffer->mem->bo;
 
    /* From the Vulkan spec:
@@ -1276,6 +1293,8 @@ v3dv_CmdFillBuffer(VkCommandBuffer commandBuffer,
 
    v3dv_X(cmd_buffer->device, meta_fill_buffer)
       (cmd_buffer, bo, dstOffset, size, data);
+
+   cmd_buffer->state.is_transfer = false;
 }
 
 /**
@@ -2710,6 +2729,8 @@ v3dv_CmdCopyBufferToImage2KHR(VkCommandBuffer commandBuffer,
 
    assert(image->vk.samples == VK_SAMPLE_COUNT_1_BIT);
 
+   cmd_buffer->state.is_transfer = true;
+
    uint32_t r = 0;
    while (r < info->regionCount) {
       /* The TFU and TLB paths can only copy one region at a time and the region
@@ -2774,6 +2795,8 @@ v3dv_CmdCopyBufferToImage2KHR(VkCommandBuffer commandBuffer,
 handled:
       r += batch_size;
    }
+
+   cmd_buffer->state.is_transfer = false;
 }
 
 static void
@@ -4247,6 +4270,8 @@ v3dv_CmdBlitImage2KHR(VkCommandBuffer commandBuffer,
    /* We don't export VK_FORMAT_FEATURE_BLIT_DST_BIT on compressed formats */
    assert(!vk_format_is_compressed(dst->vk.format));
 
+   cmd_buffer->state.is_transfer = true;
+
    for (uint32_t i = 0; i < pBlitImageInfo->regionCount; i++) {
       if (blit_tfu(cmd_buffer, dst, src, &pBlitImageInfo->pRegions[i]))
          continue;
@@ -4260,6 +4285,8 @@ v3dv_CmdBlitImage2KHR(VkCommandBuffer commandBuffer,
       }
       unreachable("Unsupported blit operation");
    }
+
+   cmd_buffer->state.is_transfer = false;
 }
 
 static bool
@@ -4363,6 +4390,8 @@ v3dv_CmdResolveImage2KHR(VkCommandBuffer commandBuffer,
    assert(src->vk.samples == VK_SAMPLE_COUNT_4_BIT);
    assert(dst->vk.samples == VK_SAMPLE_COUNT_1_BIT);
 
+   cmd_buffer->state.is_transfer = true;
+
    for (uint32_t i = 0; i < info->regionCount; i++) {
       if (resolve_image_tlb(cmd_buffer, dst, src, &info->pRegions[i]))
          continue;
@@ -4370,4 +4399,6 @@ v3dv_CmdResolveImage2KHR(VkCommandBuffer commandBuffer,
          continue;
       unreachable("Unsupported multismaple resolve operation");
    }
+
+   cmd_buffer->state.is_transfer = false;
 }
diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h
index 48001c6aa77..10e964dace1 100644
--- a/src/broadcom/vulkan/v3dv_private.h
+++ b/src/broadcom/vulkan/v3dv_private.h
@@ -1036,6 +1036,9 @@ struct v3dv_job {
     */
    bool is_clone;
 
+   /* If the job executes on the transfer stage of the pipeline */
+   bool is_transfer;
+
    enum v3dv_job_type type;
 
    struct v3dv_device *device;
@@ -1188,6 +1191,12 @@ struct v3dv_cmd_pipeline_state {
    struct v3dv_descriptor_state descriptor_state;
 };
 
+enum {
+   V3DV_BARRIER_GRAPHICS_BIT = (1 << 0),
+   V3DV_BARRIER_COMPUTE_BIT  = (1 << 1),
+   V3DV_BARRIER_TRANSFER_BIT = (1 << 2),
+};
+
 struct v3dv_cmd_buffer_state {
    struct v3dv_render_pass *pass;
    struct v3dv_framebuffer *framebuffer;
@@ -1248,12 +1257,16 @@ struct v3dv_cmd_buffer_state {
    /* Used to flag OOM conditions during command buffer recording */
    bool oom;
 
-   /* Whether we have recorded a pipeline barrier that we still need to
-    * process.
-    */
-   bool has_barrier;
-   VkAccessFlags bcl_barrier_buffer_access;
-   VkAccessFlags bcl_barrier_image_access;
+   /* If we are currently recording job(s) for a transfer operation */
+   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;
 
    /* Secondary command buffer state */
    struct {
diff --git a/src/broadcom/vulkan/v3dvx_cmd_buffer.c b/src/broadcom/vulkan/v3dvx_cmd_buffer.c
index b2dd2dc76f6..89f6f2fc418 100644
--- a/src/broadcom/vulkan/v3dvx_cmd_buffer.c
+++ b/src/broadcom/vulkan/v3dvx_cmd_buffer.c
@@ -1630,7 +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.
     */
-   bool pending_barrier = false;
+   uint8_t pending_barrier = false;
    VkAccessFlags pending_bcl_barrier_buffer_access = 0;
    VkAccessFlags pending_bcl_barrier_image_access = 0;
    for (uint32_t i = 0; i < cmd_buffer_count; i++) {
@@ -1720,7 +1720,7 @@ v3dX(cmd_buffer_execute_inside_pass)(struct v3dv_cmd_buffer *primary,
             }
          }
 
-         pending_barrier = false;
+         pending_barrier = 0;
          pending_bcl_barrier_buffer_access = 0;
          pending_bcl_barrier_image_access = 0;
       }
@@ -1734,21 +1734,23 @@ 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.has_barrier ||
-             (!secondary->state.bcl_barrier_buffer_access &&
-              !secondary->state.bcl_barrier_image_access));
+      assert(secondary->state.barrier.active_mask ||
+             (!secondary->state.barrier.bcl_barrier_buffer_access &&
+              !secondary->state.barrier.bcl_barrier_image_access));
 
-      pending_barrier = secondary->state.has_barrier;
+      pending_barrier = secondary->state.barrier.active_mask;
       pending_bcl_barrier_buffer_access =
-         secondary->state.bcl_barrier_buffer_access;
+         secondary->state.barrier.bcl_barrier_buffer_access;
       pending_bcl_barrier_image_access =
-         secondary->state.bcl_barrier_image_access;
+         secondary->state.barrier.bcl_barrier_image_access;
    }
 
    if (pending_barrier) {
-      primary->state.has_barrier = true;
-      primary->state.bcl_barrier_buffer_access |= pending_bcl_barrier_buffer_access;
-      primary->state.bcl_barrier_image_access |= pending_bcl_barrier_image_access;
+      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;
    }
 }
 



More information about the mesa-commit mailing list