radv: Clean up signalled and submitted fields from winsys fences.
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Sat, 11 May 2019 22:30:06 +0000 (00:30 +0200)
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Mon, 13 May 2019 20:36:29 +0000 (20:36 +0000)
Other types like syncobj do not need it, so lets make things a bit more uniform.

Also reduce confusion what the signalled/submitted referred to (especially with
imported fences)

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

index ebca4f5c454813ba7ea34cc2c9266ccec548954d..b32b1d539b74109f985dfe83865d61c6a1b3125d 100644 (file)
@@ -3031,7 +3031,6 @@ VkResult radv_QueueSubmit(
                        if (result != VK_SUCCESS)
                                return result;
                }
-               fence->submitted = true;
        }
 
        return VK_SUCCESS;
@@ -3656,8 +3655,6 @@ radv_sparse_image_opaque_bind_memory(struct radv_device *device,
                        }
 
                        fence_emitted = true;
-                       if (fence)
-                               fence->submitted = true;
                }
 
                radv_free_sem_info(&sem_info);
@@ -3670,7 +3667,6 @@ radv_sparse_image_opaque_bind_memory(struct radv_device *device,
                        if (result != VK_SUCCESS)
                                return result;
                }
-               fence->submitted = true;
        }
 
        return VK_SUCCESS;
@@ -3696,8 +3692,6 @@ VkResult radv_CreateFence(
                return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
 
        fence->fence_wsi = NULL;
-       fence->submitted = false;
-       fence->signalled = !!(pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT);
        fence->temp_syncobj = 0;
        if (device->always_use_syncobj || handleTypes) {
                int ret = device->ws->create_syncobj(device->ws, &fence->syncobj);
@@ -3716,6 +3710,8 @@ VkResult radv_CreateFence(
                        return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
                }
                fence->syncobj = 0;
+               if (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT)
+                       device->ws->signal_fence(fence->fence);
        }
 
        *pFence = radv_fence_to_handle(fence);
@@ -3763,13 +3759,14 @@ static uint64_t radv_get_absolute_timeout(uint64_t timeout)
 }
 
 
-static bool radv_all_fences_plain_and_submitted(uint32_t fenceCount, const VkFence *pFences)
+static bool radv_all_fences_plain_and_submitted(struct radv_device *device,
+                                                uint32_t fenceCount, const VkFence *pFences)
 {
        for (uint32_t i = 0; i < fenceCount; ++i) {
                RADV_FROM_HANDLE(radv_fence, fence, pFences[i]);
                if (fence->fence == NULL || fence->syncobj ||
-                   fence->temp_syncobj ||
-                   (!fence->signalled && !fence->submitted))
+                   fence->temp_syncobj || fence->fence_wsi ||
+                   (!device->ws->is_fence_waitable(fence->fence)))
                        return false;
        }
        return true;
@@ -3815,7 +3812,7 @@ VkResult radv_WaitForFences(
 
        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)) {
+               if (device->physical_device->rad_info.drm_minor >= 10 && radv_all_fences_plain_and_submitted(device, fenceCount, pFences)) {
                        uint32_t wait_count = 0;
                        struct radeon_winsys_fence **fences = malloc(sizeof(struct radeon_winsys_fence *) * fenceCount);
                        if (!fences)
@@ -3824,7 +3821,7 @@ VkResult radv_WaitForFences(
                        for (uint32_t i = 0; i < fenceCount; ++i) {
                                RADV_FROM_HANDLE(radv_fence, fence, pFences[i]);
 
-                               if (fence->signalled) {
+                               if (device->ws->fence_wait(device->ws, fence->fence, false, 0)) {
                                        free(fences);
                                        return VK_SUCCESS;
                                }
@@ -3864,23 +3861,11 @@ VkResult radv_WaitForFences(
                        continue;
                }
 
-               if (fence->signalled)
-                       continue;
-
                if (fence->fence) {
-                       if (!fence->submitted) {
-                               while(radv_get_current_time() <= timeout &&
-                                     !fence->submitted)
+                       if (!device->ws->is_fence_waitable(fence->fence)) {
+                               while(!device->ws->is_fence_waitable(fence->fence) &&
+                                     radv_get_current_time() <= timeout)
                                        /* Do nothing */;
-
-                               if (!fence->submitted)
-                                       return VK_TIMEOUT;
-
-                               /* Recheck as it may have been set by
-                                * submitting operations. */
-
-                               if (fence->signalled)
-                                       continue;
                        }
 
                        expired = device->ws->fence_wait(device->ws,
@@ -3895,8 +3880,6 @@ VkResult radv_WaitForFences(
                        if (result != VK_SUCCESS)
                                return result;
                }
-
-               fence->signalled = true;
        }
 
        return VK_SUCCESS;
@@ -3910,7 +3893,8 @@ VkResult radv_ResetFences(VkDevice _device,
 
        for (unsigned i = 0; i < fenceCount; ++i) {
                RADV_FROM_HANDLE(radv_fence, fence, pFences[i]);
-               fence->submitted = fence->signalled = false;
+               if (fence->fence)
+                       device->ws->reset_fence(fence->fence);
 
                /* Per spec, we first restore the permanent payload, and then reset, so
                 * having a temp syncobj should not skip resetting the permanent syncobj. */
@@ -3942,10 +3926,6 @@ VkResult radv_GetFenceStatus(VkDevice _device, VkFence _fence)
                        return success ? VK_SUCCESS : VK_NOT_READY;
        }
 
-       if (fence->signalled)
-               return VK_SUCCESS;
-       if (!fence->submitted)
-               return VK_NOT_READY;
        if (fence->fence) {
                if (!device->ws->fence_wait(device->ws, fence->fence, false, 0))
                        return VK_NOT_READY;
index 55c34d204b3cee7b9214a2f141b61727289d6d90..aa25e8f9805b8e5c2b3788f994d4f37a89d0e4ef 100644 (file)
@@ -1974,8 +1974,6 @@ void radv_initialize_fmask(struct radv_cmd_buffer *cmd_buffer,
 struct radv_fence {
        struct radeon_winsys_fence *fence;
        struct wsi_fence *fence_wsi;
-       bool submitted;
-       bool signalled;
 
        uint32_t syncobj;
        uint32_t temp_syncobj;
index ac3a8af600092210b4e65ef5621668f69fa28693..38d95624c30380a8a1708517f0a8049b7eb9daa5 100644 (file)
@@ -301,6 +301,9 @@ struct radeon_winsys {
 
        struct radeon_winsys_fence *(*create_fence)();
        void (*destroy_fence)(struct radeon_winsys_fence *fence);
+       void (*reset_fence)(struct radeon_winsys_fence *fence);
+       void (*signal_fence)(struct radeon_winsys_fence *fence);
+       bool (*is_fence_waitable)(struct radeon_winsys_fence *fence);
        bool (*fence_wait)(struct radeon_winsys *ws,
                           struct radeon_winsys_fence *fence,
                           bool absolute,
index 1b391f74f98a769123e84ada840ed1ea3690d815..fadb68a9504e02ca5b1e6c0adca92131c9e5947d 100644 (file)
@@ -238,8 +238,8 @@ VkResult radv_AcquireNextImage2KHR(
                                                         pImageIndex);
 
        if (fence && (result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR)) {
-               fence->submitted = true;
-               fence->signalled = true;
+               if (fence->fence)
+                       device->ws->signal_fence(fence->fence);
                if (fence->temp_syncobj) {
                        device->ws->signal_syncobj(device->ws, fence->temp_syncobj);
                } else if (fence->syncobj) {
index d8743a06e3ba5b218c3afd7f0228364c7bd12229..2d5167d5f5f7dd430a79fb1633b0f2455cc0928d 100644 (file)
@@ -283,8 +283,6 @@ radv_RegisterDeviceEventEXT(VkDevice                    _device,
                return VK_ERROR_OUT_OF_HOST_MEMORY;
 
        fence->fence = NULL;
-       fence->submitted = true;
-       fence->signalled = false;
        fence->syncobj = 0;
        fence->temp_syncobj = 0;
 
@@ -318,8 +316,6 @@ radv_RegisterDisplayEventEXT(VkDevice                           _device,
                return VK_ERROR_OUT_OF_HOST_MEMORY;
 
        fence->fence = NULL;
-       fence->submitted = true;
-       fence->signalled = false;
        fence->syncobj = 0;
        fence->temp_syncobj = 0;
 
index 49a86a72c31cb42ff34db39b60820ad5b96100cb..70f81119c02137d04a1f81097fa5ec174080374f 100644 (file)
@@ -169,6 +169,7 @@ static void radv_amdgpu_request_to_fence(struct radv_amdgpu_ctx *ctx,
 static struct radeon_winsys_fence *radv_amdgpu_create_fence()
 {
        struct radv_amdgpu_fence *fence = calloc(1, sizeof(struct radv_amdgpu_fence));
+       fence->fence.fence = UINT64_MAX;
        return (struct radeon_winsys_fence*)fence;
 }
 
@@ -178,6 +179,24 @@ static void radv_amdgpu_destroy_fence(struct radeon_winsys_fence *_fence)
        free(fence);
 }
 
+static void radv_amdgpu_reset_fence(struct radeon_winsys_fence *_fence)
+{
+       struct radv_amdgpu_fence *fence = (struct radv_amdgpu_fence *)_fence;
+       fence->fence.fence = UINT64_MAX;
+}
+
+static void radv_amdgpu_signal_fence(struct radeon_winsys_fence *_fence)
+{
+       struct radv_amdgpu_fence *fence = (struct radv_amdgpu_fence *)_fence;
+       fence->fence.fence = 0;
+}
+
+static bool radv_amdgpu_is_fence_waitable(struct radeon_winsys_fence *_fence)
+{
+       struct radv_amdgpu_fence *fence = (struct radv_amdgpu_fence *)_fence;
+       return fence->fence.fence < UINT64_MAX;
+}
+
 static bool radv_amdgpu_fence_wait(struct radeon_winsys *_ws,
                              struct radeon_winsys_fence *_fence,
                              bool absolute,
@@ -188,6 +207,13 @@ static bool radv_amdgpu_fence_wait(struct radeon_winsys *_ws,
        int r;
        uint32_t expired = 0;
 
+       /* Special casing 0 and UINT64_MAX so that they work without user_ptr/fence.ctx */
+       if (fence->fence.fence == UINT64_MAX)
+               return false;
+
+       if (fence->fence.fence == 0)
+               return true;
+
        if (fence->user_ptr) {
                if (*fence->user_ptr >= fence->fence.fence)
                        return true;
@@ -1617,6 +1643,9 @@ void radv_amdgpu_cs_init_functions(struct radv_amdgpu_winsys *ws)
        ws->base.cs_dump = radv_amdgpu_winsys_cs_dump;
        ws->base.create_fence = radv_amdgpu_create_fence;
        ws->base.destroy_fence = radv_amdgpu_destroy_fence;
+       ws->base.reset_fence = radv_amdgpu_reset_fence;
+       ws->base.signal_fence = radv_amdgpu_signal_fence;
+       ws->base.is_fence_waitable = radv_amdgpu_is_fence_waitable;
        ws->base.create_sem = radv_amdgpu_create_sem;
        ws->base.destroy_sem = radv_amdgpu_destroy_sem;
        ws->base.create_syncobj = radv_amdgpu_create_syncobj;