diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c index db6b6ab614a..6125074a386 100644 --- a/src/broadcom/vulkan/v3dv_device.c +++ b/src/broadcom/vulkan/v3dv_device.c @@ -1026,17 +1026,12 @@ queue_init(struct v3dv_device *device, struct v3dv_queue *queue) queue->_loader_data.loaderMagic = ICD_LOADER_MAGIC; queue->device = device; queue->flags = 0; - list_inithead(&queue->noop_jobs); return VK_SUCCESS; } static void queue_finish(struct v3dv_queue *queue) { - /* We wait for the device to be idle before finishing the queue, so - * this should any pending jobs. - */ - v3dv_queue_destroy_completed_noop_jobs(queue); } static void diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 99a9ee2a403..e27f3af6726 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -206,18 +206,8 @@ struct v3dv_queue { struct v3dv_device *device; VkDeviceQueueCreateFlags flags; - - /* When the client submits to the queue without a command buffer the queue - * needs to create and submit a no-op job and it is then responsible from - * destroying it once it has completed execution. This list keeps references - * to all no-op jobs in flight so we can do that. - */ - struct list_head noop_jobs; }; -void v3dv_queue_destroy_completed_noop_jobs(struct v3dv_queue *queue); - - struct v3dv_meta_color_clear_pipeline { VkPipeline pipeline; VkRenderPass pass; @@ -672,14 +662,6 @@ struct v3dv_job { enum v3dv_ez_state ez_state; enum v3dv_ez_state first_ez_state; - /* Typically, the client is responsible for handling the life-time of - * command buffers by using fences to tell when they are no longer in - * use by the GPU, however, when the jobs that are submitted to the GPU - * are created internally by the driver (for example when we need to - * submit no-op jobs), then it is our responsibility to do that. - */ - struct v3dv_fence *fence; - /* Number of draw calls recorded into the job */ uint32_t draw_count; diff --git a/src/broadcom/vulkan/v3dv_queue.c b/src/broadcom/vulkan/v3dv_queue.c index 80beacab2b4..8d2dc80dbde 100644 --- a/src/broadcom/vulkan/v3dv_queue.c +++ b/src/broadcom/vulkan/v3dv_queue.c @@ -403,93 +403,21 @@ queue_create_noop_job(struct v3dv_queue *queue, struct v3dv_job **job) return VK_SUCCESS; } -void -v3dv_queue_destroy_completed_noop_jobs(struct v3dv_queue *queue) -{ - struct v3dv_device *device = queue->device; - VkDevice _device = v3dv_device_to_handle(device); - - list_for_each_entry_safe(struct v3dv_job, job, - &queue->noop_jobs, list_link) { - assert(job->fence); - if (!drmSyncobjWait(device->render_fd, &job->fence->sync, 1, 0, 0, NULL)) { - v3dv_job_destroy(job); - v3dv_DestroyFence(_device, v3dv_fence_to_handle(job->fence), NULL); - } - } -} - static VkResult queue_submit_noop_job(struct v3dv_queue *queue, const VkSubmitInfo *pSubmit) { - VkResult result; - bool can_destroy_job = true; - - struct v3dv_device *device = queue->device; - VkDevice _device = v3dv_device_to_handle(device); - - /* Create noop job */ - struct v3dv_job *job; - result = queue_create_noop_job(queue, &job); - if (result != VK_SUCCESS) - goto fail_job; - - /* Create a fence for the job */ - VkFence _fence; - VkFenceCreateInfo fence_info = { - .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, - .pNext = NULL, - .flags = 0 - }; - - result = v3dv_CreateFence(_device, &fence_info, NULL, &_fence); - if (result != VK_SUCCESS) - goto fail_fence; - - /* Submit the job */ - result = queue_submit_job(queue, job, pSubmit->waitSemaphoreCount > 0); - if (result != VK_SUCCESS) - goto fail_submit; - - list_addtail(&job->list_link, &queue->noop_jobs); - - /* At this point we have submitted the job for execution and we can no - * longer destroy it until we know it has completed execution on the GPU. + /* VkQueue host access is externally synchronized so we don't need to lock + * here for the static variable. */ - can_destroy_job = false; + static struct v3dv_job *noop_job = NULL; - /* Bind a fence to the job we have just submitted so we can poll if the job - * has completed. - */ - if (process_fence_to_signal(device, _fence) != VK_SUCCESS) { - /* If we could not bind the fence, then we need to do a sync wait so - * we don't leak the job. If the sync wait also fails, then we are - * out of options. - */ - int ret = drmSyncobjWait(device->render_fd, - &device->last_job_sync, 1, INT64_MAX, 0, NULL); - if (!ret) - can_destroy_job = true; - else - result = vk_error(device->instance, VK_ERROR_DEVICE_LOST); - - goto fail_signal_fence; + if (!noop_job) { + VkResult result = queue_create_noop_job(queue, &noop_job); + if (result != VK_SUCCESS) + return result; } - job->fence = v3dv_fence_from_handle(_fence); - - return result; - -fail_signal_fence: -fail_submit: - v3dv_DestroyFence(_device, _fence, NULL); - -fail_fence: - if (can_destroy_job) - v3dv_job_destroy(job); - -fail_job: - return result; + return queue_submit_job(queue, noop_job, pSubmit->waitSemaphoreCount > 0); } static VkResult @@ -557,8 +485,6 @@ v3dv_QueueSubmit(VkQueue _queue, { V3DV_FROM_HANDLE(v3dv_queue, queue, _queue); - v3dv_queue_destroy_completed_noop_jobs(queue); - VkResult result = VK_SUCCESS; for (uint32_t i = 0; i < submitCount; i++) { result = queue_submit_cmd_buffer_batch(queue, &pSubmits[i], fence);