/*
- * 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" */