From 4a7446e4e458a5ad7bded5378670d60721ff58fc Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Mon, 13 Jun 2022 13:53:45 +0200 Subject: [PATCH] v3dv: handle barriers at the end of a command buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we only consume barriers at the beginning of a new job, if a command buffer ends with a barrier we will not handle it. Fix this by emitting a noop job in that case to consume it. Ideally, we could do better and check the pending barrier state to fine tune the noop job so we don't wait on all queues, but for now this fixes flakyness with some CTS pipeline barrier tests that started to show up after we optimized binning sync barriers. It is likely that the additional sync we had before that change was enough to prevent the problem from showing up. Reviewed-by: Alejandro PiƱeiro Part-of: --- src/broadcom/vulkan/v3dv_queue.c | 33 ++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_queue.c b/src/broadcom/vulkan/v3dv_queue.c index 83ea99200c3..799139b9174 100644 --- a/src/broadcom/vulkan/v3dv_queue.c +++ b/src/broadcom/vulkan/v3dv_queue.c @@ -911,6 +911,21 @@ queue_create_noop_job(struct v3dv_queue *queue) return VK_SUCCESS; } +static VkResult +queue_submit_noop_job(struct v3dv_queue *queue, + struct v3dv_submit_sync_info *sync_info, + bool signal_syncs) +{ + if (!queue->noop_job) { + VkResult result = queue_create_noop_job(queue); + if (result != VK_SUCCESS) + return result; + } + + assert(queue->noop_job); + return queue_handle_job(queue, queue->noop_job, sync_info, signal_syncs); +} + VkResult v3dv_queue_driver_submit(struct vk_queue *vk_queue, struct vk_queue_submit *submit) @@ -942,6 +957,17 @@ v3dv_queue_driver_submit(struct vk_queue *vk_queue, if (result != VK_SUCCESS) return result; } + + /* If the command buffer ends with a barrier we need to consume it now. + * + * FIXME: this will drain all hw queues. Instead, we could use the pending + * barrier state to limit the queues we serialize against. + */ + if (cmd_buffer->state.barrier.dst_mask) { + result = queue_submit_noop_job(queue, &sync_info, false); + if (result != VK_SUCCESS) + return result; + } } /* Finish by submitting a no-op job that synchronizes across all queues. @@ -950,12 +976,7 @@ v3dv_queue_driver_submit(struct vk_queue *vk_queue, * requirements. */ if (submit->signal_count > 0) { - if (!queue->noop_job) { - result = queue_create_noop_job(queue); - if (result != VK_SUCCESS) - return result; - } - result = queue_handle_job(queue, queue->noop_job, &sync_info, true); + result = queue_submit_noop_job(queue, &sync_info, true); if (result != VK_SUCCESS) return result; }