Implement VK_KHR_get_surface_capabilities2 entrypoints

Adds support for the VK_KHR_get_surface_capabilities2 extension.

Change-Id: Iae882a41819baf413a0ba949ec44d6e722ebca5a
Signed-off-by: Iason Paraskevopoulos <iason.paraskevopoulos@arm.com>
This commit is contained in:
Iason Paraskevopoulos 2022-03-03 11:21:07 +00:00
parent feee8f5d36
commit 2aa963ba92
11 changed files with 114 additions and 21 deletions

View file

@ -13,7 +13,8 @@
"instance_extensions": [
{"name" : "VK_EXT_headless_surface", "spec_version" : "1"},
{"name" : "VK_KHR_wayland_surface", "spec_version" : "6"},
{"name" : "VK_KHR_surface", "spec_version" : "25"}
{"name" : "VK_KHR_surface", "spec_version" : "25"},
{"name" : "VK_KHR_get_surface_capabilities2", "spec_version" : "1"}
],
"device_extensions": [
{

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2021 Arm Limited.
* Copyright (c) 2016-2022 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
@ -423,6 +423,12 @@ wsi_layer_vkGetInstanceProcAddr(VkInstance instance, const char *funcName) VWL_A
GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceFormatsKHR);
GET_PROC_ADDR(vkGetPhysicalDeviceSurfacePresentModesKHR);
GET_PROC_ADDR(vkDestroySurfaceKHR);
if (instance_data.is_instance_extension_enabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME))
{
GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceCapabilities2KHR);
GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceFormats2KHR);
}
}
return instance_data.disp.GetInstanceProcAddr(instance, funcName);

View file

@ -40,10 +40,11 @@ static std::mutex g_data_lock;
static util::unordered_map<void *, instance_private_data *> g_instance_data{ util::allocator::get_generic() };
static util::unordered_map<void *, device_private_data *> g_device_data{ util::allocator::get_generic() };
static const std::array<const char *, 3> supported_instance_extensions = {
static const std::array<const char *, 4> supported_instance_extensions = {
VK_KHR_SURFACE_EXTENSION_NAME,
VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME,
VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME,
VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
};
static const std::array<const char *, 1> supported_device_extensions = {

View file

@ -63,7 +63,9 @@ namespace layer
REQUIRED(GetPhysicalDeviceImageFormatProperties) \
REQUIRED(EnumerateDeviceExtensionProperties) \
OPTIONAL(GetPhysicalDeviceSurfaceCapabilitiesKHR) \
OPTIONAL(GetPhysicalDeviceSurfaceCapabilities2KHR) \
OPTIONAL(GetPhysicalDeviceSurfaceFormatsKHR) \
OPTIONAL(GetPhysicalDeviceSurfaceFormats2KHR) \
OPTIONAL(GetPhysicalDeviceSurfacePresentModesKHR) \
OPTIONAL(GetPhysicalDeviceSurfaceSupportKHR) \
OPTIONAL(CreateHeadlessSurfaceEXT) \

View file

@ -49,6 +49,31 @@ wsi_layer_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDev
return instance.disp.GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, pSurfaceCapabilities);
}
/**
* @brief Implements vkGetPhysicalDeviceSurfaceCapabilities2KHR Vulkan entrypoint.
*/
VWL_VKAPI_CALL(VkResult)
wsi_layer_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
VkSurfaceCapabilities2KHR *pSurfaceCapabilities) VWL_API_POST
{
auto &instance = layer::instance_private_data::get(physicalDevice);
if (instance.should_layer_handle_surface(physicalDevice, pSurfaceInfo->surface))
{
wsi::surface_properties *props = wsi::get_surface_properties(instance, pSurfaceInfo->surface);
assert(props != nullptr);
/*
* Any of the extensions that extend pSurfaceInfo are not supported by the
* swapchain implementation so it is safe to ignore pNext here, even if
* the extensions are supported by the ICD.
*/
return props->get_surface_capabilities(physicalDevice, &pSurfaceCapabilities->surfaceCapabilities);
}
return instance.disp.GetPhysicalDeviceSurfaceCapabilities2KHR(physicalDevice, pSurfaceInfo, pSurfaceCapabilities);
}
/**
* @brief Implements vkGetPhysicalDeviceSurfaceFormatsKHR Vulkan entrypoint.
*/
@ -69,6 +94,27 @@ wsi_layer_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,
pSurfaceFormats);
}
/**
* @brief Implements vkGetPhysicalDeviceSurfaceFormats2KHR Vulkan entrypoint.
*/
VWL_VKAPI_CALL(VkResult)
wsi_layer_vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
uint32_t *pSurfaceFormatCount,
VkSurfaceFormat2KHR *pSurfaceFormats) VWL_API_POST
{
auto &instance = layer::instance_private_data::get(physicalDevice);
if (instance.should_layer_handle_surface(physicalDevice, pSurfaceInfo->surface))
{
wsi::surface_properties *props = wsi::get_surface_properties(instance, pSurfaceInfo->surface);
assert(props != nullptr);
return props->get_surface_formats(physicalDevice, pSurfaceFormatCount, nullptr, pSurfaceFormats);
}
return instance.disp.GetPhysicalDeviceSurfaceFormats2KHR(physicalDevice, pSurfaceInfo, pSurfaceFormatCount,
pSurfaceFormats);
}
/**
* @brief Implements vkGetPhysicalDeviceSurfacePresentModesKHR Vulkan entrypoint.
*/

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2019, 2021 Arm Limited.
* Copyright (c) 2018-2019, 2021-2022 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
@ -39,6 +39,14 @@ VWL_VKAPI_CALL(VkResult)
wsi_layer_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) VWL_API_POST;
/**
* @brief Implements vkGetPhysicalDeviceSurfaceCapabilities2KHR Vulkan entrypoint.
*/
VWL_VKAPI_CALL(VkResult)
wsi_layer_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
VkSurfaceCapabilities2KHR *pSurfaceCapabilities) VWL_API_POST;
/**
* @brief Implements vkGetPhysicalDeviceSurfaceFormatsKHR Vulkan entrypoint.
*/
@ -47,6 +55,15 @@ wsi_layer_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,
uint32_t *pSurfaceFormatCount,
VkSurfaceFormatKHR *pSurfaceFormats) VWL_API_POST;
/**
* @brief Implements vkGetPhysicalDeviceSurfaceFormats2KHR Vulkan entrypoint.
*/
VWL_VKAPI_CALL(VkResult)
wsi_layer_vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
uint32_t *pSurfaceFormatCount,
VkSurfaceFormat2KHR *pSurfaceFormats) VWL_API_POST;
/**
* @brief Implements vkGetPhysicalDeviceSurfacePresentModesKHR Vulkan entrypoint.
*/

View file

@ -114,13 +114,15 @@ static uint32_t fill_supported_formats(VkPhysicalDevice physical_device,
}
VkResult surface_properties::get_surface_formats(VkPhysicalDevice physical_device, uint32_t *surface_format_count,
VkSurfaceFormatKHR *surface_formats)
VkSurfaceFormatKHR *surface_formats,
VkSurfaceFormat2KHR *extended_surface_formats)
{
/* Construct a list of all formats supported by the driver - for color attachment */
std::array<VkFormat, max_core_1_0_formats> formats{};
auto format_count = fill_supported_formats(physical_device, formats);
return set_surface_formats(formats.begin(), formats.begin() + format_count, surface_format_count, surface_formats);
return set_surface_formats(formats.begin(), formats.begin() + format_count, surface_format_count, surface_formats,
extended_surface_formats);
}
VkResult surface_properties::get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,

View file

@ -40,7 +40,8 @@ public:
VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) override;
VkResult get_surface_formats(VkPhysicalDevice physical_device, uint32_t *surfaceFormatCount,
VkSurfaceFormatKHR *surfaceFormats) override;
VkSurfaceFormatKHR *surfaceFormats,
VkSurfaceFormat2KHR *extended_surface_formats) override;
VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) override;

View file

@ -52,8 +52,9 @@ public:
/**
* @brief Implementation of vkGetPhysicalDeviceSurfaceFormatsKHR for the specific VkSurface type.
*/
virtual VkResult get_surface_formats(VkPhysicalDevice physical_device, uint32_t *surface_format_count,
VkSurfaceFormatKHR *surface_formats) = 0;
virtual VkResult get_surface_formats(VkPhysicalDevice physical_device, uint32_t *surface_formats_count,
VkSurfaceFormatKHR *surface_formats,
VkSurfaceFormat2KHR *extended_surface_formats = nullptr) = 0;
/**
* @brief Implementation of vkGetPhysicalDeviceSurfacePresentModesKHR for the specific VkSurface type.
@ -92,22 +93,26 @@ protected:
* Implements the common logic, which is used by all the WSI backends for
* setting the supported formats by the surface.
*
* @param begin Beginning of an iterator with the supported VkFormats.
* @param end End of the iterator.
* @param surface_formats_count Pointer for setting the length of the supported
* formats.
* @param surface_formats The supported formats by the surface.
* @param begin Beginning of an iterator with the supported VkFormats.
* @param end End of the iterator.
* @param surface_formats_count Pointer for setting the length of the supported
* formats.
* @param surface_formats The supported formats by the surface.
* @param extended_surface_formats Extended surface formats supported by the surface, it
* is being used when the vkGetPhysicalDeviceSurfaceFormats2KHR
* entrypoint is used.
*
* return VK_SUCCESS on success, an appropriate error code otherwise.
*
*/
template <typename It>
VkResult set_surface_formats(It begin, It end, uint32_t *surface_formats_count, VkSurfaceFormatKHR *surface_formats)
VkResult set_surface_formats(It begin, It end, uint32_t *surface_formats_count, VkSurfaceFormatKHR *surface_formats,
VkSurfaceFormat2KHR *extended_surface_formats)
{
assert(surface_formats_count != nullptr);
const uint32_t supported_formats_count = std::distance(begin, end);
if (surface_formats == nullptr)
if (surface_formats == nullptr && extended_surface_formats == nullptr)
{
*surface_formats_count = supported_formats_count;
return VK_SUCCESS;
@ -124,8 +129,16 @@ protected:
std::for_each(begin, end, [&](const VkFormat &format) {
if (format_count < *surface_formats_count)
{
surface_formats[format_count].format = format;
surface_formats[format_count++].colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
if (extended_surface_formats == nullptr)
{
surface_formats[format_count].format = format;
surface_formats[format_count++].colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
}
else
{
extended_surface_formats[format_count].surfaceFormat.format = format;
extended_surface_formats[format_count++].surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
}
}
});

View file

@ -69,6 +69,7 @@ surface_properties &surface_properties::get_instance()
VkResult surface_properties::get_surface_capabilities(VkPhysicalDevice physical_device,
VkSurfaceCapabilitiesKHR *pSurfaceCapabilities)
{
/* Image count limits */
pSurfaceCapabilities->minImageCount = 2;
pSurfaceCapabilities->maxImageCount = MAX_SWAPCHAIN_IMAGE_COUNT;
@ -127,7 +128,8 @@ static VkResult get_vk_supported_formats(const util::vector<drm_format_pair> &dr
}
VkResult surface_properties::get_surface_formats(VkPhysicalDevice physical_device, uint32_t *surfaceFormatCount,
VkSurfaceFormatKHR *surfaceFormats)
VkSurfaceFormatKHR *surfaceFormats,
VkSurfaceFormat2KHR *extended_surface_formats)
{
assert(specific_surface);
if (!supported_formats.size())
@ -139,7 +141,8 @@ VkResult surface_properties::get_surface_formats(VkPhysicalDevice physical_devic
}
}
return set_surface_formats(supported_formats.begin(), supported_formats.end(), surfaceFormatCount, surfaceFormats);
return set_surface_formats(supported_formats.begin(), supported_formats.end(), surfaceFormatCount, surfaceFormats,
extended_surface_formats);
}
VkResult surface_properties::get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,

View file

@ -54,7 +54,8 @@ public:
VkResult get_surface_capabilities(VkPhysicalDevice physical_device,
VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) override;
VkResult get_surface_formats(VkPhysicalDevice physical_device, uint32_t *surfaceFormatCount,
VkSurfaceFormatKHR *surfaceFormats) override;
VkSurfaceFormatKHR *surfaceFormats,
VkSurfaceFormat2KHR *extended_surface_formats) override;
VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) override;