From f9898b211eb23c18d27508a2cbbdd629fc3dc734 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Mon, 26 Feb 2018 21:52:49 +0100 Subject: [PATCH] radv: Use the syncobj wait ioctl to wait on fences if possible. Handles the !waitAll and signal after the start of the wait cases correctly. Reviewed-by: Dave Airlie --- src/amd/vulkan/radv_device.c | 24 +++++++++++++++---- src/amd/vulkan/radv_radeon_winsys.h | 3 ++- src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c | 8 +++---- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index 21ccfa679f8..36d7a406bf8 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -2928,6 +2928,22 @@ VkResult radv_WaitForFences( RADV_FROM_HANDLE(radv_device, device, _device); timeout = radv_get_absolute_timeout(timeout); + if (device->always_use_syncobj) { + uint32_t *handles = malloc(sizeof(uint32_t) * fenceCount); + if (!handles) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + + for (uint32_t i = 0; i < fenceCount; ++i) { + RADV_FROM_HANDLE(radv_fence, fence, pFences[i]); + handles[i] = fence->temp_syncobj ? fence->temp_syncobj : fence->syncobj; + } + + bool success = device->ws->wait_syncobj(device->ws, handles, fenceCount, waitAll, timeout); + + free(handles); + return success ? VK_SUCCESS : VK_TIMEOUT; + } + if (!waitAll && fenceCount > 1) { /* Not doing this by default for waitAll, due to needing to allocate twice. */ if (device->physical_device->rad_info.drm_minor >= 10 && radv_all_fences_plain_and_submitted(fenceCount, pFences)) { @@ -2968,13 +2984,13 @@ VkResult radv_WaitForFences( bool expired = false; if (fence->temp_syncobj) { - if (!device->ws->wait_syncobj(device->ws, fence->temp_syncobj, timeout)) + if (!device->ws->wait_syncobj(device->ws, &fence->temp_syncobj, 1, true, timeout)) return VK_TIMEOUT; continue; } if (fence->syncobj) { - if (!device->ws->wait_syncobj(device->ws, fence->syncobj, timeout)) + if (!device->ws->wait_syncobj(device->ws, &fence->syncobj, 1, true, timeout)) return VK_TIMEOUT; continue; } @@ -3035,12 +3051,12 @@ VkResult radv_GetFenceStatus(VkDevice _device, VkFence _fence) RADV_FROM_HANDLE(radv_fence, fence, _fence); if (fence->temp_syncobj) { - bool success = device->ws->wait_syncobj(device->ws, fence->temp_syncobj, 0); + bool success = device->ws->wait_syncobj(device->ws, &fence->temp_syncobj, 1, true, 0); return success ? VK_SUCCESS : VK_NOT_READY; } if (fence->syncobj) { - bool success = device->ws->wait_syncobj(device->ws, fence->syncobj, 0); + bool success = device->ws->wait_syncobj(device->ws, &fence->syncobj, 1, true, 0); return success ? VK_SUCCESS : VK_NOT_READY; } diff --git a/src/amd/vulkan/radv_radeon_winsys.h b/src/amd/vulkan/radv_radeon_winsys.h index 643d76a826f..270b3bceaba 100644 --- a/src/amd/vulkan/radv_radeon_winsys.h +++ b/src/amd/vulkan/radv_radeon_winsys.h @@ -286,7 +286,8 @@ struct radeon_winsys { void (*reset_syncobj)(struct radeon_winsys *ws, uint32_t handle); void (*signal_syncobj)(struct radeon_winsys *ws, uint32_t handle); - bool (*wait_syncobj)(struct radeon_winsys *ws, uint32_t handle, uint64_t timeout); + bool (*wait_syncobj)(struct radeon_winsys *ws, const uint32_t *handles, uint32_t handle_count, + bool wait_all, uint64_t timeout); int (*export_syncobj)(struct radeon_winsys *ws, uint32_t syncobj, int *fd); int (*import_syncobj)(struct radeon_winsys *ws, int fd, uint32_t *syncobj); diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c index d2b33546cc4..cd7ab384e73 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c @@ -1332,8 +1332,8 @@ static void radv_amdgpu_signal_syncobj(struct radeon_winsys *_ws, amdgpu_cs_syncobj_signal(ws->dev, &handle, 1); } -static bool radv_amdgpu_wait_syncobj(struct radeon_winsys *_ws, - uint32_t handle, uint64_t timeout) +static bool radv_amdgpu_wait_syncobj(struct radeon_winsys *_ws, const uint32_t *handles, + uint32_t handle_count, bool wait_all, uint64_t timeout) { struct radv_amdgpu_winsys *ws = radv_amdgpu_winsys(_ws); uint32_t tmp; @@ -1341,9 +1341,9 @@ static bool radv_amdgpu_wait_syncobj(struct radeon_winsys *_ws, /* The timeouts are signed, while vulkan timeouts are unsigned. */ timeout = MIN2(timeout, INT64_MAX); - int ret = amdgpu_cs_syncobj_wait(ws->dev, &handle, 1, timeout, + int ret = amdgpu_cs_syncobj_wait(ws->dev, (uint32_t*)handles, handle_count, timeout, DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT | - DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL, + (wait_all ? DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL : 0), &tmp); if (ret == 0) { return true; -- 2.30.2