From: Bas Nieuwenhuizen Date: Thu, 16 Jul 2020 00:43:32 +0000 (+0200) Subject: radv: Add winsys functions for timeline syncobj. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=55d8022878fd11093c861a6386734f88454f21b1;p=mesa.git radv: Add winsys functions for timeline syncobj. Reviewed-by: Samuel Pitoiset Part-of: --- diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index a5a0c73560f..4145e25f5da 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -7325,7 +7325,7 @@ static VkResult radv_import_sync_fd(struct radv_device *device, } } else { if (fd == -1) - device->ws->signal_syncobj(device->ws, syncobj_handle); + device->ws->signal_syncobj(device->ws, syncobj_handle, 0); } if (fd != -1) { diff --git a/src/amd/vulkan/radv_radeon_winsys.h b/src/amd/vulkan/radv_radeon_winsys.h index 2741870abca..da410e5ef63 100644 --- a/src/amd/vulkan/radv_radeon_winsys.h +++ b/src/amd/vulkan/radv_radeon_winsys.h @@ -328,9 +328,12 @@ struct radeon_winsys { void (*destroy_syncobj)(struct radeon_winsys *ws, uint32_t handle); void (*reset_syncobj)(struct radeon_winsys *ws, uint32_t handle); - void (*signal_syncobj)(struct radeon_winsys *ws, uint32_t handle); + void (*signal_syncobj)(struct radeon_winsys *ws, uint32_t handle, uint64_t point); + VkResult (*query_syncobj)(struct radeon_winsys *ws, uint32_t handle, uint64_t *point); bool (*wait_syncobj)(struct radeon_winsys *ws, const uint32_t *handles, uint32_t handle_count, bool wait_all, uint64_t timeout); + bool (*wait_timeline_syncobj)(struct radeon_winsys *ws, const uint32_t *handles, const uint64_t *points, + uint32_t handle_count, bool wait_all, bool available, 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/radv_wsi.c b/src/amd/vulkan/radv_wsi.c index ff05324caf3..0c9c8593783 100644 --- a/src/amd/vulkan/radv_wsi.c +++ b/src/amd/vulkan/radv_wsi.c @@ -270,7 +270,7 @@ VkResult radv_AcquireNextImage2KHR( device->ws->signal_fence(part->fence); break; case RADV_FENCE_SYNCOBJ: - device->ws->signal_syncobj(device->ws, part->syncobj); + device->ws->signal_syncobj(device->ws, part->syncobj, 0); break; default: unreachable("Invalid WSI fence type"); @@ -289,7 +289,7 @@ VkResult radv_AcquireNextImage2KHR( case RADV_SEMAPHORE_TIMELINE: unreachable("WSI only allows binary semaphores."); case RADV_SEMAPHORE_SYNCOBJ: - device->ws->signal_syncobj(device->ws, part->syncobj); + device->ws->signal_syncobj(device->ws, part->syncobj, 0); break; } } diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c index 4265ca5ad9b..79e5d8daa6d 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c @@ -1832,10 +1832,30 @@ static void radv_amdgpu_reset_syncobj(struct radeon_winsys *_ws, } static void radv_amdgpu_signal_syncobj(struct radeon_winsys *_ws, - uint32_t handle) + uint32_t handle, uint64_t point) +{ + struct radv_amdgpu_winsys *ws = radv_amdgpu_winsys(_ws); + if (point) + amdgpu_cs_syncobj_timeline_signal(ws->dev, &handle, &point, 1); + else + amdgpu_cs_syncobj_signal(ws->dev, &handle, 1); +} + +static VkResult radv_amdgpu_query_syncobj(struct radeon_winsys *_ws, + uint32_t handle, uint64_t *point) { struct radv_amdgpu_winsys *ws = radv_amdgpu_winsys(_ws); - amdgpu_cs_syncobj_signal(ws->dev, &handle, 1); + int ret = amdgpu_cs_syncobj_query(ws->dev, &handle, point, 1); + if (ret == 0) + return VK_SUCCESS; + else if (ret == -ENOMEM) + return VK_ERROR_OUT_OF_HOST_MEMORY; + else { + /* Remaining error are driver internal issues: EFAULT for + * dangling pointers and ENOENT for non-existing syncobj. */ + fprintf(stderr, "amdgpu: internal error in radv_amdgpu_query_syncobj. (%d)\n", ret); + return VK_ERROR_UNKNOWN; + } } static bool radv_amdgpu_wait_syncobj(struct radeon_winsys *_ws, const uint32_t *handles, @@ -1861,6 +1881,32 @@ static bool radv_amdgpu_wait_syncobj(struct radeon_winsys *_ws, const uint32_t * } } +static bool radv_amdgpu_wait_timeline_syncobj(struct radeon_winsys *_ws, const uint32_t *handles, + const uint64_t *points, uint32_t handle_count, + bool wait_all, bool available, uint64_t timeout) +{ + struct radv_amdgpu_winsys *ws = radv_amdgpu_winsys(_ws); + + /* The timeouts are signed, while vulkan timeouts are unsigned. */ + timeout = MIN2(timeout, INT64_MAX); + + int ret = amdgpu_cs_syncobj_timeline_wait(ws->dev, (uint32_t*)handles, (uint64_t*)points, + handle_count, timeout, + DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT | + (wait_all ? DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL : 0) | + (available ? DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE : 0), + NULL); + if (ret == 0) { + return true; + } else if (ret == -ETIME) { + return false; + } else { + fprintf(stderr, "amdgpu: radv_amdgpu_wait_syncobj failed! (%d)\n", errno); + return false; + } +} + + static int radv_amdgpu_export_syncobj(struct radeon_winsys *_ws, uint32_t syncobj, int *fd) @@ -1923,7 +1969,9 @@ void radv_amdgpu_cs_init_functions(struct radv_amdgpu_winsys *ws) ws->base.destroy_syncobj = radv_amdgpu_destroy_syncobj; ws->base.reset_syncobj = radv_amdgpu_reset_syncobj; ws->base.signal_syncobj = radv_amdgpu_signal_syncobj; + ws->base.query_syncobj = radv_amdgpu_query_syncobj; ws->base.wait_syncobj = radv_amdgpu_wait_syncobj; + ws->base.wait_timeline_syncobj = radv_amdgpu_wait_timeline_syncobj; ws->base.export_syncobj = radv_amdgpu_export_syncobj; ws->base.import_syncobj = radv_amdgpu_import_syncobj; ws->base.export_syncobj_to_sync_file = radv_amdgpu_export_syncobj_to_sync_file;