From e8a59e42ec6fca1d92956ec7c6e1bb493ad975dc Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Thu, 1 Dec 2022 10:59:17 +0100 Subject: [PATCH] v3dv: make single-sync paths more explicit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of having functions that return early in multi-sync mode let's only call them when we are in single-sync mode. I think this makes the code more explicit. Reviewed-by: Alejandro PiƱeiro cc: mesa-stable Part-of: (cherry picked from commit 95b9293eeb02f3b43fb7de5afc6f7c89ffffe92f) --- .pick_status.json | 2 +- src/broadcom/vulkan/v3dv_queue.c | 68 ++++++++++++++++---------------- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 636bcc11f0b..42b086e37c0 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -5242,7 +5242,7 @@ "description": "v3dv: make single-sync paths more explicit", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null }, diff --git a/src/broadcom/vulkan/v3dv_queue.c b/src/broadcom/vulkan/v3dv_queue.c index 1b2bee4b5d4..d7ae326fc42 100644 --- a/src/broadcom/vulkan/v3dv_queue.c +++ b/src/broadcom/vulkan/v3dv_queue.c @@ -408,23 +408,18 @@ handle_csd_indirect_cpu_job(struct v3dv_queue *queue, } static VkResult -process_waits(struct v3dv_queue *queue, - uint32_t count, struct vk_sync_wait *waits) +process_singlesync_waits(struct v3dv_queue *queue, + uint32_t count, struct vk_sync_wait *waits) { struct v3dv_device *device = queue->device; - VkResult result = VK_SUCCESS; - int err = 0; + assert(!device->pdevice->caps.multisync); if (count == 0) return VK_SUCCESS; - /* If multisync is supported, we wait on semaphores in the first job - * submitted to each of the individual queues. We don't need to - * pre-populate the syncobjs. - */ - if (queue->device->pdevice->caps.multisync) - return VK_SUCCESS; + VkResult result = VK_SUCCESS; + int err = 0; int fd = -1; err = drmSyncobjExportSyncFile(device->pdevice->render_fd, queue->last_job_syncs.syncs[V3DV_QUEUE_ANY], @@ -469,19 +464,17 @@ fail: return result; } +/** + * This handles signaling for the single-sync path by importing the QUEUE_ANY + * syncobj into all syncs to be signaled. + */ static VkResult -process_signals(struct v3dv_queue *queue, - uint32_t count, struct vk_sync_signal *signals) +process_singlesync_signals(struct v3dv_queue *queue, + uint32_t count, struct vk_sync_signal *signals) { struct v3dv_device *device = queue->device; + assert(!device->pdevice->caps.multisync && count > 0); - if (count == 0) - return VK_SUCCESS; - - /* If multisync is supported, we are signalling semaphores in the last job - * of the last command buffer and, therefore, we do not need to process any - * semaphores here. - */ if (device->pdevice->caps.multisync) return VK_SUCCESS; @@ -1027,9 +1020,16 @@ v3dv_queue_driver_submit(struct vk_queue *vk_queue, for (int i = 0; i < V3DV_QUEUE_COUNT; i++) queue->last_job_syncs.first[i] = true; - result = process_waits(queue, sync_info.wait_count, sync_info.waits); - if (result != VK_SUCCESS) - return result; + /* If we do not have multisync we need to ensure we accumulate any wait + * semaphores into our QUEUE_ANY syncobj so we can handle waiting on + * external semaphores. + */ + if (!queue->device->pdevice->caps.multisync) { + result = + process_singlesync_waits(queue, sync_info.wait_count, sync_info.waits); + if (result != VK_SUCCESS) + return result; + } for (uint32_t i = 0; i < submit->command_buffer_count; i++) { struct v3dv_cmd_buffer *cmd_buffer = @@ -1056,20 +1056,22 @@ v3dv_queue_driver_submit(struct vk_queue *vk_queue, } } - /* Finish by submitting a no-op job that synchronizes across all queues. - * This will ensure that the signal semaphores don't get triggered until - * all work on any queue completes. See Vulkan's signal operation order - * requirements. - */ + /* Handle signaling now */ if (submit->signal_count > 0) { - result = queue_submit_noop_job(queue, submit->perf_pass_index, - &sync_info, true); - if (result != VK_SUCCESS) - return result; + if (queue->device->pdevice->caps.multisync) { + /* Finish by submitting a no-op job that synchronizes across all queues. + * This will ensure that the signal semaphores don't get triggered until + * all work on any queue completes. See Vulkan's signal operation order + * requirements. + */ + return queue_submit_noop_job(queue, submit->perf_pass_index, + &sync_info, true); + } else { + return process_singlesync_signals(queue, sync_info.signal_count, + sync_info.signals); + } } - process_signals(queue, sync_info.signal_count, sync_info.signals); - return VK_SUCCESS; }