vulkan/wsi: Use one fence per image.
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Mon, 20 May 2019 00:51:51 +0000 (02:51 +0200)
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Fri, 26 Jul 2019 14:37:28 +0000 (16:37 +0200)
Much easier to work with if we want to use them in the WS-specific
WSI implementation.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
src/vulkan/wsi/wsi_common.c
src/vulkan/wsi/wsi_common_private.h

index d44b9fad542458873a546ff7c15b4cff25d517c7..50304e773c92bba7e5591f94277e8cadd0bbe5c4 100644 (file)
@@ -283,8 +283,12 @@ wsi_swapchain_get_present_mode(struct wsi_device *wsi,
 void
 wsi_swapchain_finish(struct wsi_swapchain *chain)
 {
-   for (unsigned i = 0; i < ARRAY_SIZE(chain->fences); i++)
-      chain->wsi->DestroyFence(chain->device, chain->fences[i], &chain->alloc);
+   if (chain->fences) {
+      for (unsigned i = 0; i < chain->image_count; i++)
+         chain->wsi->DestroyFence(chain->device, chain->fences[i], &chain->alloc);
+
+      vk_free(&chain->alloc, chain->fences);
+   }
 
    for (uint32_t i = 0; i < chain->wsi->queue_family_count; i++) {
       chain->wsi->DestroyCommandPool(chain->device, chain->cmd_pools[i],
@@ -949,6 +953,15 @@ wsi_common_create_swapchain(struct wsi_device *wsi,
    if (result != VK_SUCCESS)
       return result;
 
+   swapchain->fences = vk_zalloc(pAllocator,
+                                 sizeof (*swapchain->fences) * swapchain->image_count,
+                                 sizeof (*swapchain->fences),
+                                 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (!swapchain->fences) {
+      swapchain->destroy(swapchain, pAllocator);
+      return VK_ERROR_OUT_OF_HOST_MEMORY;
+   }
+
    *pSwapchain = wsi_swapchain_to_handle(swapchain);
 
    return VK_SUCCESS;
@@ -1008,9 +1021,10 @@ wsi_common_queue_present(const struct wsi_device *wsi,
 
    for (uint32_t i = 0; i < pPresentInfo->swapchainCount; i++) {
       WSI_FROM_HANDLE(wsi_swapchain, swapchain, pPresentInfo->pSwapchains[i]);
+      uint32_t image_index = pPresentInfo->pImageIndices[i];
       VkResult result;
 
-      if (swapchain->fences[0] == VK_NULL_HANDLE) {
+      if (swapchain->fences[image_index] == VK_NULL_HANDLE) {
          const VkFenceCreateInfo fence_info = {
             .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
             .pNext = NULL,
@@ -1018,11 +1032,14 @@ wsi_common_queue_present(const struct wsi_device *wsi,
          };
          result = wsi->CreateFence(device, &fence_info,
                                    &swapchain->alloc,
-                                   &swapchain->fences[0]);
+                                   &swapchain->fences[image_index]);
          if (result != VK_SUCCESS)
             goto fail_present;
       } else {
-         wsi->ResetFences(device, 1, &swapchain->fences[0]);
+         wsi->WaitForFences(device, 1, &swapchain->fences[image_index],
+                            true, 1);
+
+         wsi->ResetFences(device, 1, &swapchain->fences[image_index]);
       }
 
       VkSubmitInfo submit_info = {
@@ -1059,13 +1076,13 @@ wsi_common_queue_present(const struct wsi_device *wsi,
           * command buffer is attached to the image.
           */
          struct wsi_image *image =
-            swapchain->get_wsi_image(swapchain, pPresentInfo->pImageIndices[i]);
+            swapchain->get_wsi_image(swapchain, image_index);
          submit_info.commandBufferCount = 1;
          submit_info.pCommandBuffers =
             &image->prime.blit_cmd_buffers[queue_family_index];
       }
 
-      result = wsi->QueueSubmit(queue, 1, &submit_info, swapchain->fences[0]);
+      result = wsi->QueueSubmit(queue, 1, &submit_info, swapchain->fences[image_index]);
       vk_free(&swapchain->alloc, stage_flags);
       if (result != VK_SUCCESS)
          goto fail_present;
@@ -1074,21 +1091,10 @@ wsi_common_queue_present(const struct wsi_device *wsi,
       if (regions && regions->pRegions)
          region = &regions->pRegions[i];
 
-      result = swapchain->queue_present(swapchain,
-                                        pPresentInfo->pImageIndices[i],
-                                        region);
+      result = swapchain->queue_present(swapchain, image_index, region);
       if (result != VK_SUCCESS)
          goto fail_present;
 
-      VkFence last = swapchain->fences[2];
-      swapchain->fences[2] = swapchain->fences[1];
-      swapchain->fences[1] = swapchain->fences[0];
-      swapchain->fences[0] = last;
-
-      if (last != VK_NULL_HANDLE) {
-         wsi->WaitForFences(device, 1, &last, true, 1);
-      }
-
    fail_present:
       if (pPresentInfo->pResults != NULL)
          pPresentInfo->pResults[i] = result;
index 6d8f4b7a0e4d90728d1da011cfccfe2125143364..60d45bc540000b331aae78296ab37c643b488acb 100644 (file)
@@ -48,7 +48,7 @@ struct wsi_swapchain {
 
    VkDevice device;
    VkAllocationCallbacks alloc;
-   VkFence fences[3];
+   VkFence* fences;
    VkPresentModeKHR present_mode;
    uint32_t image_count;