layer/swapchain_api.cpp
util/timed_semaphore.cpp
wsi/swapchain_base.cpp
+ wsi/wsi_factory.cpp
wsi/headless/surface_properties.cpp
wsi/headless/swapchain.cpp)
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 11)
#include <cstring>
#include <vulkan/vk_layer.h>
-#include <wsi/surface_properties.hpp>
-
#include "private_data.hpp"
#include "surface_api.hpp"
#include "swapchain_api.hpp"
#define DISPATCH_TABLE_ENTRY(x) PFN_vk##x x;
-#define INSTANCE_ENTRYPOINTS_LIST(V) \
- V(GetInstanceProcAddr) \
- V(GetPhysicalDeviceProperties) \
- V(GetPhysicalDeviceImageFormatProperties) \
- V(EnumerateDeviceExtensionProperties)
+#define INSTANCE_ENTRYPOINTS_LIST(V) \
+ V(GetInstanceProcAddr) \
+ V(GetPhysicalDeviceProperties) \
+ V(GetPhysicalDeviceImageFormatProperties) \
+ V(EnumerateDeviceExtensionProperties) \
+ V(GetPhysicalDeviceSurfaceCapabilitiesKHR) \
+ V(GetPhysicalDeviceSurfaceFormatsKHR) \
+ V(GetPhysicalDeviceSurfacePresentModesKHR) \
+ V(GetPhysicalDeviceSurfaceSupportKHR)
namespace layer
{
#include <cassert>
-#include <wsi/headless/surface_properties.hpp>
+#include <wsi/wsi_factory.hpp>
+
+#include "private_data.hpp"
#include "surface_api.hpp"
extern "C"
VKAPI_ATTR VkResult wsi_layer_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities)
{
- assert(physicalDevice);
- assert(surface);
- assert(pSurfaceCapabilities);
+ wsi::surface_properties *props = wsi::get_surface_properties(surface);
+ if (props)
+ {
+ return props->get_surface_capabilities(physicalDevice, surface, pSurfaceCapabilities);
+ }
- return wsi::headless::surface_properties::get_surface_capabilities(physicalDevice, surface, pSurfaceCapabilities);
+ return layer::instance_private_data::get(layer::get_key(physicalDevice))
+ .disp.GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, pSurfaceCapabilities);
}
/**
uint32_t *pSurfaceFormatCount,
VkSurfaceFormatKHR *pSurfaceFormats)
{
- assert(physicalDevice);
- assert(surface);
+ wsi::surface_properties *props = wsi::get_surface_properties(surface);
+ if (props)
+ {
+ return props->get_surface_formats(physicalDevice, surface, pSurfaceFormatCount, pSurfaceFormats);
+ }
- return wsi::headless::surface_properties::get_surface_formats(physicalDevice, surface, pSurfaceFormatCount, pSurfaceFormats);
+ return layer::instance_private_data::get(layer::get_key(physicalDevice))
+ .disp.GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pSurfaceFormatCount, pSurfaceFormats);
}
/**
uint32_t *pPresentModeCount,
VkPresentModeKHR *pPresentModes)
{
- assert(physicalDevice);
- assert(surface);
- assert(pPresentModeCount);
+ wsi::surface_properties *props = wsi::get_surface_properties(surface);
+ if (props)
+ {
+ return props->get_surface_present_modes(physicalDevice, surface, pPresentModeCount, pPresentModes);
+ }
- return wsi::headless::surface_properties::get_surface_present_modes(physicalDevice, surface, pPresentModeCount, pPresentModes);
+ return layer::instance_private_data::get(layer::get_key(physicalDevice))
+ .disp.GetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, pPresentModeCount, pPresentModes);
}
/**
uint32_t queueFamilyIndex, VkSurfaceKHR surface,
VkBool32 *pSupported)
{
- assert(physicalDevice);
- assert(surface);
- assert(pSupported);
-
+ wsi::surface_properties *props = wsi::get_surface_properties(surface);
/* We assume that presentation to surface is supported by default */
- *pSupported = VK_TRUE;
- return VK_SUCCESS;
+ if (props)
+ {
+ *pSupported = VK_TRUE;
+ return VK_SUCCESS;
+ }
+
+ return layer::instance_private_data::get(layer::get_key(physicalDevice))
+ .disp.GetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, pSupported);
}
} /* extern "C" */
#include <cassert>
#include <cstdlib>
#include <new>
-#include <vulkan/vk_icd.h>
-#include <wsi/headless/swapchain.hpp>
+#include <wsi/wsi_factory.hpp>
#include "private_data.hpp"
#include "swapchain_api.hpp"
{
assert(pSwapchain != nullptr);
- wsi::swapchain_base *sc = nullptr;
-
- VkIcdSurfaceBase *surface_base = reinterpret_cast<VkIcdSurfaceBase *>(pSwapchainCreateInfo->surface);
- assert(VK_ICD_WSI_PLATFORM_HEADLESS == (int)surface_base->platform);
-
- void *memory = nullptr;
- if (pAllocator)
- {
- memory = static_cast<wsi::headless::swapchain *>(
- pAllocator->pfnAllocation(pAllocator->pUserData, sizeof(wsi::headless::swapchain),
- alignof(wsi::headless::swapchain), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE));
- }
- else
- {
- memory = static_cast<wsi::headless::swapchain *>(malloc(sizeof(wsi::headless::swapchain)));
- }
-
- if (memory)
- {
- sc = new (memory) wsi::headless::swapchain(layer::device_private_data::get(layer::get_key(device)), pAllocator);
- }
+ wsi::swapchain_base *sc = wsi::allocate_surface_swapchain(
+ pSwapchainCreateInfo->surface, layer::device_private_data::get(layer::get_key(device)), pAllocator);
if (sc == nullptr)
{
if (result != VK_SUCCESS)
{
/* Error occured during initialization, need to free allocated memory. */
- sc->~swapchain_base();
-
- if (pAllocator != nullptr)
- {
- pAllocator->pfnFree(pAllocator->pUserData, reinterpret_cast<void *>(sc));
- }
- else
- {
- free(reinterpret_cast<void *>(sc));
- }
-
+ wsi::destroy_surface_swapchain(sc, pAllocator);
return result;
}
wsi::swapchain_base *sc = reinterpret_cast<wsi::swapchain_base *>(swapc);
- sc->~swapchain_base();
-
- if (pAllocator != nullptr)
- {
- pAllocator->pfnFree(pAllocator->pUserData, reinterpret_cast<void *>(swapc));
- }
- else
- {
- free(reinterpret_cast<void *>(swapc));
- }
+ wsi::destroy_surface_swapchain(sc, pAllocator);
}
VKAPI_ATTR VkResult wsi_layer_vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapc,
namespace headless
{
+surface_properties& surface_properties::get_instance()
+{
+ static surface_properties instance;
+ return instance;
+}
+
VkResult surface_properties::get_surface_capabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
VkSurfaceCapabilitiesKHR *surface_capabilities)
{
namespace headless
{
-struct surface_properties
+class surface_properties : public wsi::surface_properties
{
- static VkResult get_surface_capabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
- VkSurfaceCapabilitiesKHR *pSurfaceCapabilities);
+public:
+ VkResult get_surface_capabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
+ VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) override;
- static VkResult get_surface_formats(VkPhysicalDevice physical_device, VkSurfaceKHR surface, uint32_t *surfaceFormatCount,
- VkSurfaceFormatKHR *surfaceFormats);
+ VkResult get_surface_formats(VkPhysicalDevice physical_device, VkSurfaceKHR surface, uint32_t *surfaceFormatCount,
+ VkSurfaceFormatKHR *surfaceFormats) override;
- static VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
- uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes);
+ VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
+ uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) override;
+
+ static surface_properties &get_instance();
};
} /* namespace headless */
/**
* @brief The base surface property query interface.
*/
-template <typename T>
-struct surface_properties
+class surface_properties
{
- static VkResult get_surface_capabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
- VkSurfaceCapabilitiesKHR *surface_capabilities)
- {
- return T::get_surface_capabilities(physical_device, surface, surface_capabilities);
- }
-
- static VkResult get_surface_formats(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
- uint32_t *surface_format_count, VkSurfaceFormatKHR *surface_formats)
- {
- return T::get_surface_formats(physical_device, surface, surface_format_count, surface_formats);
- }
-
- static VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
- uint32_t *present_mode_count, VkPresentModeKHR *present_modes)
- {
- return T::get_surface_present_modes(physical_device, surface, present_mode_count, present_modes);
- }
+public:
+ /**
+ * Implementation of vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the specific VkSurface type.
+ */
+ virtual VkResult get_surface_capabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
+ VkSurfaceCapabilitiesKHR *surface_capabilities) = 0;
+
+ /**
+ * Implementation of vkGetPhysicalDeviceSurfaceFormatsKHR for the specific VkSurface type.
+ */
+ virtual VkResult get_surface_formats(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
+ uint32_t *surface_format_count, VkSurfaceFormatKHR *surface_formats) = 0;
+
+ /**
+ * Implementation of vkGetPhysicalDeviceSurfacePresentModesKHR for the specific VkSurface type.
+ */
+ virtual VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
+ uint32_t *present_mode_count, VkPresentModeKHR *present_modes) = 0;
};
} /* namespace wsi */
--- /dev/null
+
+/*
+ * Copyright (c) 2019 Arm Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @file
+ * @brief Implements factory methods for obtaining the specific surface and swapchain implementations.
+ */
+
+#include "wsi_factory.hpp"
+#include <cassert>
+#include <cstdlib>
+#include <cstdio>
+#include <new>
+#include <vulkan/vk_icd.h>
+
+#include "headless/surface_properties.hpp"
+#include "headless/swapchain.hpp"
+
+namespace wsi
+{
+
+surface_properties *get_surface_properties(VkSurfaceKHR surface)
+{
+ VkIcdSurfaceBase *surface_base = reinterpret_cast<VkIcdSurfaceBase *>(surface);
+
+ switch (surface_base->platform)
+ {
+ case VK_ICD_WSI_PLATFORM_HEADLESS:
+ return &headless::surface_properties::get_instance();
+ default:
+ return nullptr;
+ }
+}
+
+template <typename swapchain_type>
+static swapchain_base *allocate_swapchain(layer::device_private_data &dev_data, const VkAllocationCallbacks *pAllocator)
+{
+ if (!pAllocator)
+ {
+ return new swapchain_type(dev_data, pAllocator);
+ }
+ void *memory = pAllocator->pfnAllocation(pAllocator->pUserData, sizeof(swapchain_type), alignof(swapchain_type),
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ return new (memory) swapchain_type(dev_data, pAllocator);
+}
+
+swapchain_base *allocate_surface_swapchain(VkSurfaceKHR surface, layer::device_private_data &dev_data,
+ const VkAllocationCallbacks *pAllocator)
+{
+ VkIcdSurfaceBase *surface_base = reinterpret_cast<VkIcdSurfaceBase *>(surface);
+
+ switch (surface_base->platform)
+ {
+ case VK_ICD_WSI_PLATFORM_HEADLESS:
+ return allocate_swapchain<wsi::headless::swapchain>(dev_data, pAllocator);
+ default:
+ return nullptr;
+ }
+}
+
+void destroy_surface_swapchain(swapchain_base *swapchain, const VkAllocationCallbacks *pAllocator)
+{
+ assert(swapchain);
+
+ if (!pAllocator)
+ {
+ delete swapchain;
+ }
+ else
+ {
+ swapchain->~swapchain_base();
+ pAllocator->pfnFree(pAllocator->pUserData, reinterpret_cast<void *>(swapchain));
+ }
+}
+
+} // namespace wsi
\ No newline at end of file
--- /dev/null
+
+/*
+ * Copyright (c) 2019 Arm Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @file
+ * @brief Contains the factory methods for obtaining the specific surface and swapchain implementations.
+ */
+#pragma once
+
+#include "swapchain_base.hpp"
+#include "surface_properties.hpp"
+#include <layer/private_data.hpp>
+
+namespace wsi
+{
+
+/**
+ * Obtains the surface properties for the specific surface type.
+ *
+ * @param surface The surface for which to get the properties.
+ *
+ * @return nullptr if surface type is unsupported.
+ */
+surface_properties *get_surface_properties(VkSurfaceKHR surface);
+
+/**
+ * Allocates a surface specific swapchain.
+ *
+ * @param surface The surface for which a swapchain is allocated.
+ * @param dev_data The device specific data.
+ * @param pAllocator The allocator from which to allocate any memory.
+ *
+ * @return nullptr on failure.
+ */
+swapchain_base *allocate_surface_swapchain(VkSurfaceKHR surface, layer::device_private_data &dev_data,
+ const VkAllocationCallbacks *pAllocator);
+
+/**
+ * Destroys a swapchain and frees memory. Used with @ref allocate_surface_swapchain.
+ *
+ * @param swapchain Pointer to the swapchain to destroy.
+ * @param pAllocator The allocator to use for freeing memory.
+ */
+void destroy_surface_swapchain(swapchain_base *swapchain, const VkAllocationCallbacks *pAllocator);
+
+} // namespace wsi
\ No newline at end of file