Move WSI type specific calls

Move all WSI type specific calls to WSI factory methods. This
removes headless references in layer/ and allows for simpler
support of multiple windowing systems.

Change-Id: I757a7a3bb4267783420b52cceb3bde8ce233297e
Signed-off-by: Rosen Zhelev <rosen.zhelev@arm.com>
This commit is contained in:
Rosen 2019-11-21 15:23:59 +00:00 committed by Matteo Franchin
parent 05a76ba34a
commit 3262341839
10 changed files with 247 additions and 93 deletions

View file

@ -47,6 +47,7 @@ add_library(${PROJECT_NAME} SHARED
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)

View file

@ -27,8 +27,6 @@
#include <cstring>
#include <vulkan/vk_layer.h>
#include <wsi/surface_properties.hpp>
#include "private_data.hpp"
#include "surface_api.hpp"
#include "swapchain_api.hpp"

View file

@ -29,11 +29,15 @@
#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
{

View file

@ -24,7 +24,9 @@
#include <cassert>
#include <wsi/headless/surface_properties.hpp>
#include <wsi/wsi_factory.hpp>
#include "private_data.hpp"
#include "surface_api.hpp"
extern "C"
@ -36,11 +38,14 @@ 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);
}
/**
@ -51,10 +56,14 @@ extern "C"
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);
}
/**
@ -65,11 +74,14 @@ extern "C"
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);
}
/**
@ -79,13 +91,16 @@ extern "C"
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" */

View file

@ -31,9 +31,8 @@
#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"
@ -48,27 +47,8 @@ extern "C"
{
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)
{
@ -79,17 +59,7 @@ extern "C"
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;
}
@ -105,16 +75,7 @@ extern "C"
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,

View file

@ -43,6 +43,12 @@ namespace wsi
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)
{

View file

@ -33,16 +33,19 @@ namespace wsi
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 */

View file

@ -38,26 +38,26 @@ namespace wsi
/**
* @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);
}
public:
/**
* Implementation of vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the specific VkSurface type.
*/
virtual VkResult get_surface_capabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
VkSurfaceCapabilitiesKHR *surface_capabilities) = 0;
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);
}
/**
* 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;
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);
}
/**
* 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 */

98
wsi/wsi_factory.cpp Normal file
View file

@ -0,0 +1,98 @@
/*
* 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

68
wsi/wsi_factory.hpp Normal file
View file

@ -0,0 +1,68 @@
/*
* 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