layer: improve how layer handles Vulkan extensions
[platform/core/uifw/vulkan-wsi-tizen.git] / layer / swapchain_api.cpp
index 092c22c..4469f94 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2019 Arm Limited.
+ * Copyright (c) 2017, 2019, 2021 Arm Limited.
  *
  * SPDX-License-Identifier: MIT
  *
 #include "private_data.hpp"
 #include "swapchain_api.hpp"
 
-extern "C"
+extern "C" {
+
+VKAPI_ATTR VkResult wsi_layer_vkCreateSwapchainKHR(VkDevice device,
+                                                   const VkSwapchainCreateInfoKHR *pSwapchainCreateInfo,
+                                                   const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain)
 {
+   assert(pSwapchain != nullptr);
+   layer::device_private_data &device_data = layer::device_private_data::get(device);
+   VkSurfaceKHR surface = pSwapchainCreateInfo->surface;
 
-   VKAPI_ATTR VkResult wsi_layer_vkCreateSwapchainKHR(VkDevice device,
-                                                      const VkSwapchainCreateInfoKHR *pSwapchainCreateInfo,
-                                                      const VkAllocationCallbacks *pAllocator,
-                                                      VkSwapchainKHR *pSwapchain)
+   if (!device_data.should_layer_create_swapchain(surface))
    {
-      assert(pSwapchain != nullptr);
-
-      wsi::swapchain_base *sc = wsi::allocate_surface_swapchain(
-         pSwapchainCreateInfo->surface, layer::device_private_data::get(layer::get_key(device)), pAllocator);
-
-      if (sc == nullptr)
+      if (!device_data.can_icds_create_swapchain(surface))
       {
-         return VK_ERROR_OUT_OF_HOST_MEMORY;
-      }
-
-      VkResult result = sc->init(device, pSwapchainCreateInfo);
-      if (result != VK_SUCCESS)
-      {
-         /* Error occured during initialization, need to free allocated memory. */
-         wsi::destroy_surface_swapchain(sc, pAllocator);
-         return result;
+         return VK_ERROR_INITIALIZATION_FAILED;
       }
+      return device_data.disp.CreateSwapchainKHR(device_data.device, pSwapchainCreateInfo, pAllocator, pSwapchain);
+   }
 
-      *pSwapchain = reinterpret_cast<VkSwapchainKHR>(sc);
+   wsi::swapchain_base *sc = wsi::allocate_surface_swapchain(surface, device_data, pAllocator);
+   if (sc == nullptr)
+   {
+      return VK_ERROR_OUT_OF_HOST_MEMORY;
+   }
 
+   VkResult result = sc->init(device, pSwapchainCreateInfo);
+   if (result != VK_SUCCESS)
+   {
+      /* Error occured during initialization, need to free allocated memory. */
+      wsi::destroy_surface_swapchain(sc, pAllocator);
       return result;
    }
 
-   VKAPI_ATTR void wsi_layer_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapc,
-                                                   const VkAllocationCallbacks *pAllocator)
-   {
-      assert(swapc != VK_NULL_HANDLE);
+   *pSwapchain = reinterpret_cast<VkSwapchainKHR>(sc);
+   device_data.add_layer_swapchain(*pSwapchain);
+   return result;
+}
 
-      wsi::swapchain_base *sc = reinterpret_cast<wsi::swapchain_base *>(swapc);
+VKAPI_ATTR void wsi_layer_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapc,
+                                                const VkAllocationCallbacks *pAllocator)
+{
+   layer::device_private_data &device_data = layer::device_private_data::get(device);
 
-      wsi::destroy_surface_swapchain(sc, pAllocator);
+   if (!device_data.layer_owns_swapchain(swapc))
+   {
+      return device_data.disp.DestroySwapchainKHR(device_data.device, swapc, pAllocator);
    }
 
-   VKAPI_ATTR VkResult wsi_layer_vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapc,
-                                                         uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages)
-   {
-      assert(pSwapchainImageCount != nullptr);
-      assert(swapc != VK_NULL_HANDLE);
+   assert(swapc != VK_NULL_HANDLE);
+   wsi::swapchain_base *sc = reinterpret_cast<wsi::swapchain_base *>(swapc);
+   wsi::destroy_surface_swapchain(sc, pAllocator);
+}
 
-      wsi::swapchain_base *sc = reinterpret_cast<wsi::swapchain_base *>(swapc);
+VKAPI_ATTR VkResult wsi_layer_vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapc,
+                                                      uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages)
+{
+   layer::device_private_data &device_data = layer::device_private_data::get(device);
 
-      return sc->get_swapchain_images(pSwapchainImageCount, pSwapchainImages);
+   if (!device_data.layer_owns_swapchain(swapc))
+   {
+      return device_data.disp.GetSwapchainImagesKHR(device_data.device, swapc, pSwapchainImageCount, pSwapchainImages);
    }
 
-   VKAPI_ATTR VkResult wsi_layer_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapc, uint64_t timeout,
-                                                       VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex)
+   assert(pSwapchainImageCount != nullptr);
+   assert(swapc != VK_NULL_HANDLE);
+   wsi::swapchain_base *sc = reinterpret_cast<wsi::swapchain_base *>(swapc);
+   return sc->get_swapchain_images(pSwapchainImageCount, pSwapchainImages);
+}
+
+VKAPI_ATTR VkResult wsi_layer_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapc, uint64_t timeout,
+                                                    VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex)
+{
+   layer::device_private_data &device_data = layer::device_private_data::get(device);
+
+   if (!device_data.layer_owns_swapchain(swapc))
    {
-      assert(swapc != VK_NULL_HANDLE);
-      assert(semaphore != VK_NULL_HANDLE || fence != VK_NULL_HANDLE);
-      assert(pImageIndex != nullptr);
+      return device_data.disp.AcquireNextImageKHR(device_data.device, swapc, timeout, semaphore, fence, pImageIndex);
+   }
 
-      wsi::swapchain_base *sc = reinterpret_cast<wsi::swapchain_base *>(swapc);
+   assert(swapc != VK_NULL_HANDLE);
+   assert(semaphore != VK_NULL_HANDLE || fence != VK_NULL_HANDLE);
+   assert(pImageIndex != nullptr);
+   wsi::swapchain_base *sc = reinterpret_cast<wsi::swapchain_base *>(swapc);
+   return sc->acquire_next_image(timeout, semaphore, fence, pImageIndex);
+}
+
+VKAPI_ATTR VkResult wsi_layer_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo)
+{
+   assert(queue != VK_NULL_HANDLE);
+   assert(pPresentInfo != nullptr);
 
-      return sc->acquire_next_image(timeout, semaphore, fence, pImageIndex);
+   layer::device_private_data &device_data = layer::device_private_data::get(queue);
+
+   if (!device_data.layer_owns_all_swapchains(pPresentInfo->pSwapchains, pPresentInfo->swapchainCount))
+   {
+      return device_data.disp.QueuePresentKHR(queue, pPresentInfo);
    }
 
-   VKAPI_ATTR VkResult wsi_layer_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo)
+   VkResult ret = VK_SUCCESS;
+   for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i)
    {
-      assert(queue != VK_NULL_HANDLE);
-      assert(pPresentInfo != nullptr);
+      VkSwapchainKHR swapc = pPresentInfo->pSwapchains[i];
+
+      wsi::swapchain_base *sc = reinterpret_cast<wsi::swapchain_base *>(swapc);
+      assert(sc != nullptr);
 
-      uint32_t resultMask = 0;
+      VkResult res = sc->queue_present(queue, pPresentInfo, pPresentInfo->pImageIndices[i]);
 
-      for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i)
+      if (pPresentInfo->pResults != nullptr)
       {
-         wsi::swapchain_base *sc = reinterpret_cast<wsi::swapchain_base *>(pPresentInfo->pSwapchains[i]);
-         assert(sc != nullptr);
-
-         VkResult res = sc->queue_present(queue, pPresentInfo, pPresentInfo->pImageIndices[i]);
-
-         if (pPresentInfo->pResults != nullptr)
-         {
-            pPresentInfo->pResults[i] = res;
-         }
-
-         if (res == VK_ERROR_DEVICE_LOST)
-            resultMask |= (1u << 1);
-         else if (res == VK_ERROR_SURFACE_LOST_KHR)
-            resultMask |= (1u << 2);
-         else if (res == VK_ERROR_OUT_OF_DATE_KHR)
-            resultMask |= (1u << 3);
+         pPresentInfo->pResults[i] = res;
       }
 
-      if (resultMask & (1u << 1))
-         return VK_ERROR_DEVICE_LOST;
-      else if (resultMask & (1u << 2))
-         return VK_ERROR_SURFACE_LOST_KHR;
-      else if (resultMask & (1u << 3))
-         return VK_ERROR_OUT_OF_DATE_KHR;
-
-      return VK_SUCCESS;
+      if (res != VK_SUCCESS && ret == VK_SUCCESS)
+      {
+         ret = res;
+      }
    }
 
+   return ret;
+}
+
 } /* extern "C" */