diff options
author | Iago Toral Quiroga <itoral@igalia.com> | 2020-01-13 17:45:04 +0100 |
---|---|---|
committer | Marge Bot <eric+marge@anholt.net> | 2020-10-13 21:21:26 +0000 |
commit | 56b4eac8d66089e3926606c46b2548107f5d84d2 (patch) | |
tree | fe6ec14409f9bd7087299a9a1926fd70e117ed77 | |
parent | d24dbd87ad1d9b1dc7b64cc60e3f5f4286686389 (diff) |
v3dv: implement semaphore waits and signals on queue submissions
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
-rw-r--r-- | src/broadcom/vulkan/v3dv_private.h | 3 | ||||
-rw-r--r-- | src/broadcom/vulkan/v3dv_queue.c | 61 |
2 files changed, 57 insertions, 7 deletions
diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 8e10a766f79..1c3e64d2e3f 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -522,6 +522,9 @@ void v3dv_cmd_buffer_start_frame(struct v3dv_cmd_buffer *cmd_buffer, struct v3dv_semaphore { /* A syncobject handle associated with this semaphore */ uint32_t sync; + + /* The file handle of a fence that we imported into our syncobject */ + int32_t fd; }; struct v3dv_shader_module { diff --git a/src/broadcom/vulkan/v3dv_queue.c b/src/broadcom/vulkan/v3dv_queue.c index e9a6c2f33cb..8357b176630 100644 --- a/src/broadcom/vulkan/v3dv_queue.c +++ b/src/broadcom/vulkan/v3dv_queue.c @@ -57,16 +57,53 @@ v3dv_clif_dump(struct v3dv_device *device, } static VkResult -job_submit(struct v3dv_job *job) +process_semaphores_to_signal(struct v3dv_device *device, + uint32_t count, const VkSemaphore *sems) +{ + if (count == 0) + return VK_SUCCESS; + + for (uint32_t i = 0; i < count; i++) { + struct v3dv_semaphore *sem = v3dv_semaphore_from_handle(sems[i]); + + if (sem->fd >= 0) + close(sem->fd); + sem->fd = -1; + + int fd; + drmSyncobjExportSyncFile(device->fd, device->last_job_sync, &fd); + if (fd == -1) + return VK_ERROR_DEVICE_LOST; + + int ret = drmSyncobjImportSyncFile(device->fd, sem->sync, fd); + if (ret) + return VK_ERROR_DEVICE_LOST; + + sem->fd = fd; + } + + return VK_SUCCESS; +} + +static VkResult +job_submit(struct v3dv_job *job, bool do_wait) { assert(job); struct drm_v3d_submit_cl submit; - /* While the RCL will implicitly depend on the last RCL to have finished, we - * also need to block on any previous TFU job we may have dispatched. + /* RCL jobs don't start until the previous RCL job has finished so we don't + * really need to add a fence for those, however, we might need to wait on a + * CSD or TFU job, which are not serialized. + * + * FIXME: for now, if we are asked to wait on any semaphores, we just wait + * on the last job we submitted. In the future we might want to pass the + * actual syncobj of the wait semaphores so we don't block on the last RCL + * if we only need to wait for a previous CSD or TFU, for example, but + * we would have to extend our kernel interface to support the case where + * we have more than one semaphore to wait on. */ - submit.in_sync_rcl = 0; /* FIXME */ + submit.in_sync_rcl = do_wait ? job->cmd_buffer->device->last_job_sync : 0; /* Update the sync object for the last rendering by this device. */ submit.out_sync = job->cmd_buffer->device->last_job_sync; @@ -124,15 +161,19 @@ queue_submit(struct v3dv_queue *queue, { /* FIXME */ assert(fence == 0); - assert(pSubmit->waitSemaphoreCount == 0); - assert(pSubmit->signalSemaphoreCount == 0); assert(pSubmit->commandBufferCount == 1); V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, pSubmit->pCommandBuffers[0]); list_for_each_entry_safe(struct v3dv_job, job, &cmd_buffer->submit_jobs, list_link) { - VkResult result = job_submit(job); + VkResult result = job_submit(job, pSubmit->waitSemaphoreCount > 0); + if (result != VK_SUCCESS) + return result; + + result = process_semaphores_to_signal(cmd_buffer->device, + pSubmit->signalSemaphoreCount, + pSubmit->pSignalSemaphores); if (result != VK_SUCCESS) return result; } @@ -174,6 +215,8 @@ v3dv_CreateSemaphore(VkDevice _device, if (sem == NULL) return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + sem->fd = -1; + int ret = drmSyncobjCreate(device->fd, 0, &sem->sync); if (ret) { vk_free2(&device->alloc, pAllocator, sem); @@ -197,5 +240,9 @@ v3dv_DestroySemaphore(VkDevice _device, return; drmSyncobjDestroy(device->fd, sem->sync); + + if (sem->fd != -1) + close(sem->fd); + vk_free2(&device->alloc, pAllocator, sem); } |