From 16526e451e3c2693a51956b054afd4c95b5ae7ab Mon Sep 17 00:00:00 2001 From: Roman Stratiienko Date: Wed, 29 Apr 2026 19:03:27 +0300 Subject: [PATCH] v3dv: move noop_job creation to device scope Preparation step for multiple queue emulation support Signed-off-by: Roman Stratiienko Reviewed-by: Iago Toral Quiroga Part-of: --- src/broadcom/vulkan/v3dv_device.c | 33 ++++++++++++++++++++++++++++--- src/broadcom/vulkan/v3dv_device.h | 6 ++++-- src/broadcom/vulkan/v3dv_queue.c | 32 ++---------------------------- 3 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c index b540f1b3ed1..ccce410fa4f 100644 --- a/src/broadcom/vulkan/v3dv_device.c +++ b/src/broadcom/vulkan/v3dv_device.c @@ -1841,7 +1841,6 @@ queue_init(struct v3dv_device *device, struct v3dv_queue *queue, } } - queue->noop_job = NULL; return VK_SUCCESS; fail_last_job_syncs: @@ -1854,12 +1853,31 @@ fail_submit_thread: static void queue_finish(struct v3dv_queue *queue) { - if (queue->noop_job) - v3dv_job_destroy(queue->noop_job); destroy_queue_syncs(queue); vk_queue_finish(&queue->vk); } +VkResult +v3dv_device_create_noop_job(struct v3dv_device *device) +{ + device->noop_job = vk_zalloc(&device->vk.alloc, sizeof(struct v3dv_job), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!device->noop_job) + return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); + v3dv_job_init(device->noop_job, V3DV_JOB_TYPE_GPU_CL, device, NULL, -1); + + v3d_X((&device->devinfo), job_emit_noop)(device->noop_job); + + /* We use no-op jobs to signal semaphores/fences. These jobs needs to be + * serialized across all hw queues to comply with Vulkan's signal operation + * order requirements, which basically require that signal operations occur + * in submission order. + */ + device->noop_job->serialize = V3DV_BARRIER_ALL; + + return VK_SUCCESS; +} + static void init_device_meta(struct v3dv_device *device) { @@ -1955,6 +1973,10 @@ v3dv_CreateDevice(VkPhysicalDevice physicalDevice, device->default_attribute_float = v3d_X((&device->devinfo), create_default_attribute_values)(device, NULL); + result = v3dv_device_create_noop_job(device); + if (result != VK_SUCCESS) + goto fail; + device->device_address_mem_ctx = ralloc_context(NULL); util_dynarray_init(&device->device_address_bo_list, device->device_address_mem_ctx); @@ -1981,6 +2003,8 @@ fail: cnd_destroy(&device->query_ended); mtx_destroy(&device->query_mutex); queue_finish(&device->queue); + if (device->noop_job) + v3dv_job_destroy(device->noop_job); destroy_device_meta(device); v3dv_pipeline_cache_finish(&device->default_pipeline_cache); v3dv_event_free_resources(device); @@ -2000,6 +2024,9 @@ v3dv_DestroyDevice(VkDevice _device, device->vk.dispatch_table.DeviceWaitIdle(_device); queue_finish(&device->queue); + if (device->noop_job) + v3dv_job_destroy(device->noop_job); + v3dv_event_free_resources(device); mtx_destroy(&device->events.lock); diff --git a/src/broadcom/vulkan/v3dv_device.h b/src/broadcom/vulkan/v3dv_device.h index 7e28204e100..835030bfacd 100644 --- a/src/broadcom/vulkan/v3dv_device.h +++ b/src/broadcom/vulkan/v3dv_device.h @@ -205,8 +205,6 @@ struct v3dv_queue { struct v3dv_last_job_sync last_job_syncs; - struct v3dv_job *noop_job; - /* The last active perfmon ID to prevent mixing of counter results when a * job is submitted with a different perfmon id. */ @@ -216,6 +214,8 @@ struct v3dv_queue { VkResult v3dv_queue_driver_submit(struct vk_queue *vk_queue, struct vk_queue_submit *submit); +VkResult v3dv_device_create_noop_job(struct v3dv_device *device); + #define V3DV_META_BLIT_CACHE_KEY_SIZE (4 * sizeof(uint32_t)) #define V3DV_META_TEXEL_BUFFER_COPY_CACHE_KEY_SIZE (3 * sizeof(uint32_t) + \ sizeof(VkComponentMapping)) @@ -255,6 +255,8 @@ struct v3dv_device { struct v3d_device_info devinfo; struct v3dv_queue queue; + struct v3dv_job *noop_job; + /* Guards query->maybe_available and value for timestamps */ mtx_t query_mutex; diff --git a/src/broadcom/vulkan/v3dv_queue.c b/src/broadcom/vulkan/v3dv_queue.c index 10cf99a757c..3ef2a853f05 100644 --- a/src/broadcom/vulkan/v3dv_queue.c +++ b/src/broadcom/vulkan/v3dv_queue.c @@ -1232,42 +1232,14 @@ queue_handle_job(struct v3dv_queue *queue, } } -static VkResult -queue_create_noop_job(struct v3dv_queue *queue) -{ - struct v3dv_device *device = queue->device; - queue->noop_job = vk_zalloc(&device->vk.alloc, sizeof(struct v3dv_job), 8, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (!queue->noop_job) - return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); - v3dv_job_init(queue->noop_job, V3DV_JOB_TYPE_GPU_CL, device, NULL, -1); - - v3d_X((&device->devinfo), job_emit_noop)(queue->noop_job); - - /* We use no-op jobs to signal semaphores/fences. These jobs needs to be - * serialized across all hw queues to comply with Vulkan's signal operation - * order requirements, which basically require that signal operations occur - * in submission order. - */ - queue->noop_job->serialize = V3DV_BARRIER_ALL; - - return VK_SUCCESS; -} - static VkResult queue_submit_noop_job(struct v3dv_queue *queue, uint32_t counter_pass_idx, 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, counter_pass_idx, NULL, + assert(queue->device->noop_job); + return queue_handle_job(queue, queue->device->noop_job, counter_pass_idx, NULL, sync_info, signal_syncs); }