v3dv: signal fence when all submitted jobs complete execution

We track last submitted jobs by queue type. After all cmd buffer
batches have been submitted, we emit a noop job that waits all jobs
submitted to each GPU queue complete and signals the fence.

Signed-off-by: Melissa Wen <mwen@igalia.com>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13178>
This commit is contained in:
Melissa Wen 2021-12-16 10:47:18 +00:00
parent bce77e758a
commit 9319ffb53d
2 changed files with 39 additions and 5 deletions

View file

@ -989,6 +989,9 @@ struct v3dv_submit_info_semaphores {
/* List of semaphores to signal when all jobs complete */
uint32_t signal_sem_count;
VkSemaphore *signal_sems;
/* A fence to signal when all jobs complete */
VkFence fence;
};
struct v3dv_event_set_cpu_job_info {

View file

@ -632,6 +632,11 @@ process_semaphores_to_signal(struct v3dv_device *device,
return result;
}
static VkResult
queue_submit_noop_job(struct v3dv_queue *queue,
struct v3dv_submit_info_semaphores *sems_info,
bool do_sem_signal, bool serialize);
static VkResult
process_fence_to_signal(struct v3dv_device *device, VkFence _fence)
{
@ -642,6 +647,26 @@ process_fence_to_signal(struct v3dv_device *device, VkFence _fence)
int render_fd = device->pdevice->render_fd;
if (device->pdevice->caps.multisync) {
struct v3dv_queue *queue = &device->queue;
/* We signal the fence once all submitted command buffers have completed
* execution. For this, we emit a noop job that waits on the completion
* of all submitted jobs and signal the fence for this submission.
* FIXME: In simpler cases (for instance, when all jobs were submitted to
* the same queue), we can just import the last out sync produced into
* the fence.
*/
struct v3dv_submit_info_semaphores sems_info = {
.wait_sem_count = 0,
.wait_sems = NULL,
.signal_sem_count = 0,
.signal_sems = NULL,
.fence = _fence,
};
return queue_submit_noop_job(queue, &sems_info, false, true);
}
int fd;
mtx_lock(&device->mutex);
drmSyncobjExportSyncFile(render_fd,
@ -727,11 +752,12 @@ set_out_syncs(struct v3dv_device *device,
uint32_t n_sems = job->do_sem_signal ? sems_info->signal_sem_count : 0;
/* We always signal the syncobj from `device->last_job_syncs` related to
* this v3dv_queue_type to track the last job submitted to this queue. We
* also signal the last overall job (V3DV_QUEUE_ANY) as we use it to
* process signal semaphores and fence.
* this v3dv_queue_type to track the last job submitted to this queue.
*/
(*count) = n_sems + 2;
(*count) = n_sems + 1;
if (sems_info->fence)
(*count)++;
struct drm_v3d_sem *syncs =
vk_zalloc(&device->vk.alloc, *count * sizeof(struct drm_v3d_sem),
@ -749,7 +775,11 @@ set_out_syncs(struct v3dv_device *device,
}
syncs[n_sems].handle = device->last_job_syncs.syncs[queue];
syncs[++n_sems].handle = device->last_job_syncs.syncs[V3DV_QUEUE_ANY];
if (sems_info->fence) {
struct v3dv_fence *fence = v3dv_fence_from_handle(sems_info->fence);
syncs[++n_sems].handle = fence->sync;
}
return syncs;
}
@ -1310,6 +1340,7 @@ queue_submit_cmd_buffer_batch(struct v3dv_queue *queue,
.wait_sems = (VkSemaphore *) pSubmit->pWaitSemaphores,
.signal_sem_count = pSubmit->signalSemaphoreCount,
.signal_sems = (VkSemaphore *) pSubmit->pSignalSemaphores,
.fence = 0,
};
/* In the beginning of a cmd buffer batch, we set all last_job_syncs as