radv: Use the syncobj wait ioctl to wait on fences if possible.
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Mon, 26 Feb 2018 20:52:49 +0000 (21:52 +0100)
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Thu, 1 Mar 2018 00:07:18 +0000 (01:07 +0100)
Handles the !waitAll and signal after the start of the wait cases correctly.

Reviewed-by: Dave Airlie <airlied@redhat.com>
src/amd/vulkan/radv_device.c
src/amd/vulkan/radv_radeon_winsys.h
src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c

index 21ccfa679f84681fc8725ded104f17ba58a0575c..36d7a406bf88250c0255c2f5fa614a482bf1f52c 100644 (file)
@@ -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;
        }
 
index 643d76a826f535350fdde0a3a1817099677b71e7..270b3bceaba90868b6892519bc62673109b2cdf6 100644 (file)
@@ -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);
index d2b33546cc4a6b588be3bab9c883eedc2677a8d5..cd7ab384e7361c5536b522a822270c13d7d26a46 100644 (file)
@@ -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;