From 4a9da29016cdebd472fea67db78c5afaabbe1d4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= Date: Tue, 25 Jul 2023 17:44:52 -0300 Subject: [PATCH] v3dv: use the copy timestamp query results user extension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The copy timestamp query user extension allows the creation of a CPU job that copies the results of a timestamp query to a BO with the possibility to indicate the timestamp availability with a availability bit. By using the copy timestamp query user extension, it will be possible to use the multisync user extension to synchronize this type of job, which currently possible with the user space implementation without stalling. Signed-off-by: MaĆ­ra Canal Reviewed-by: Iago Toral Quiroga Part-of: --- src/broadcom/vulkan/v3dv_queue.c | 73 +++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_queue.c b/src/broadcom/vulkan/v3dv_queue.c index 465988a1322..3c7367846fc 100644 --- a/src/broadcom/vulkan/v3dv_queue.c +++ b/src/broadcom/vulkan/v3dv_queue.c @@ -522,8 +522,12 @@ fail: } static VkResult -handle_copy_query_results_cpu_job(struct v3dv_job *job) +handle_copy_query_results_cpu_job(struct v3dv_queue *queue, + struct v3dv_job *job, + struct v3dv_submit_sync_info *sync_info, + bool signal_syncs) { + struct v3dv_device *device = queue->device; struct v3dv_copy_query_results_cpu_job_info *info = &job->cpu.query_copy_results; @@ -533,6 +537,71 @@ handle_copy_query_results_cpu_job(struct v3dv_job *job) assert(info->dst && info->dst->mem && info->dst->mem->bo); struct v3dv_bo *bo = info->dst->mem->bo; + if (device->pdevice->caps.cpu_queue && + info->pool->query_type == VK_QUERY_TYPE_TIMESTAMP) { + struct drm_v3d_submit_cpu submit = {0}; + struct drm_v3d_multi_sync ms = {0}; + + uint32_t *offsets = (uint32_t *) malloc(sizeof(uint32_t) * info->count); + uint32_t *syncs = (uint32_t *) malloc(sizeof(uint32_t) * info->count); + uint32_t *bo_handles = NULL; + + submit.bo_handle_count = 2; + + bo_handles = (uint32_t *) + malloc(sizeof(uint32_t) * submit.bo_handle_count); + + bo_handles[0] = bo->handle; + bo_handles[1] = info->pool->timestamp.bo->handle; + submit.bo_handles = (uintptr_t)(void *)bo_handles; + + struct drm_v3d_copy_timestamp_query copy = {0}; + + set_ext(©.base, NULL, DRM_V3D_EXT_ID_CPU_COPY_TIMESTAMP_QUERY, 0); + + copy.do_64bit = info->flags & VK_QUERY_RESULT_64_BIT; + copy.do_partial = info->flags & VK_QUERY_RESULT_PARTIAL_BIT; + copy.availability_bit = info->flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT; + copy.offset = info->offset + info->dst->mem_offset; + copy.stride = info->stride; + copy.count = info->count; + + for (uint32_t i = 0; i < info->count; i++) { + assert(info->first < info->pool->query_count); + assert(info->first + info->count <= info->pool->query_count); + struct v3dv_query *query = &info->pool->queries[info->first + i]; + + offsets[i] = query->timestamp.offset; + syncs[i] = vk_sync_as_drm_syncobj(query->timestamp.sync)->syncobj; + } + + copy.offsets = (uintptr_t)(void *)offsets; + copy.syncs = (uintptr_t)(void *)syncs; + + set_multisync(&ms, sync_info, NULL, 0, (void *)©, device, job, + V3DV_QUEUE_CPU, V3DV_QUEUE_CPU, V3D_CPU, signal_syncs); + if (!ms.base.id) + return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + + submit.flags |= DRM_V3D_SUBMIT_EXTENSION; + submit.extensions = (uintptr_t)(void *)&ms; + + int ret = v3dv_ioctl(device->pdevice->render_fd, + DRM_IOCTL_V3D_SUBMIT_CPU, &submit); + + free(bo_handles); + free(offsets); + free(syncs); + multisync_free(device, &ms); + + queue->last_job_syncs.first[V3DV_QUEUE_CPU] = false; + + if (ret) + return vk_queue_set_lost(&queue->vk, "V3D_SUBMIT_CPU failed: %m"); + + return VK_SUCCESS; + } + /* Map the entire dst buffer for the CPU copy if needed */ assert(!bo->map || bo->map_size == bo->size); if (!bo->map && !v3dv_bo_map(job->device, bo, bo->size)) @@ -1186,7 +1255,7 @@ queue_handle_job(struct v3dv_queue *queue, case V3DV_JOB_TYPE_CPU_END_QUERY: return handle_end_query_cpu_job(job, counter_pass_idx); case V3DV_JOB_TYPE_CPU_COPY_QUERY_RESULTS: - return handle_copy_query_results_cpu_job(job); + return handle_copy_query_results_cpu_job(queue, job, sync_info, signal_syncs); case V3DV_JOB_TYPE_CPU_CSD_INDIRECT: return handle_csd_indirect_cpu_job(queue, job, sync_info, signal_syncs); case V3DV_JOB_TYPE_CPU_TIMESTAMP_QUERY: