Use common code for get_surface_formats implementations

Adds a template function for setting the supported surface formats for
a surface. This function is used in the get_surface_formats
implementation of both the WSI backends, which previously were
implementing the same logic independently.

Removes the unused surface argument from get_surface_formats and
get_surface_capabilities.

Change-Id: Ib220166675d1c24aeef230cf9f510abba9e42a61
Signed-off-by: Iason Paraskevopoulos <iason.paraskevopoulos@arm.com>
This commit is contained in:
Iason Paraskevopoulos 2022-02-28 16:21:06 +00:00
parent ba0684b5e0
commit feee8f5d36
8 changed files with 92 additions and 86 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2021 Arm Limited.
* Copyright (c) 2018-2022 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
@ -41,7 +41,9 @@ static util::unordered_map<void *, instance_private_data *> g_instance_data{ uti
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 = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME,
VK_KHR_SURFACE_EXTENSION_NAME,
VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME,
VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME,
};
static const std::array<const char *, 1> supported_device_extensions = {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2017, 2019, 2021 Arm Limited.
* Copyright (c) 2016-2017, 2019, 2021-2022 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
@ -39,7 +39,7 @@ wsi_layer_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDev
{
wsi::surface_properties *props = wsi::get_surface_properties(instance, surface);
assert(props != nullptr);
return props->get_surface_capabilities(physicalDevice, surface, pSurfaceCapabilities);
return props->get_surface_capabilities(physicalDevice, pSurfaceCapabilities);
}
/* If the layer cannot handle this surface, then necessarily the surface must have been created by the ICDs (or a
@ -62,7 +62,7 @@ wsi_layer_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,
{
wsi::surface_properties *props = wsi::get_surface_properties(instance, surface);
assert(props != nullptr);
return props->get_surface_formats(physicalDevice, surface, pSurfaceFormatCount, pSurfaceFormats);
return props->get_surface_formats(physicalDevice, pSurfaceFormatCount, pSurfaceFormats);
}
return instance.disp.GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pSurfaceFormatCount,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2019, 2021 Arm Limited.
* Copyright (c) 2017, 2019, 2021-2022 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
@ -295,7 +295,7 @@ wsi_layer_vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevic
*pRectCount = 1;
VkSurfaceCapabilitiesKHR surface_caps;
result = props->get_surface_capabilities(physicalDevice, surface, &surface_caps);
result = props->get_surface_capabilities(physicalDevice, &surface_caps);
if (result != VK_SUCCESS)
{

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019, 2021 Arm Limited.
* Copyright (c) 2017-2019, 2021-2022 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
@ -46,16 +46,17 @@ namespace wsi
namespace headless
{
constexpr int max_core_1_0_formats = VK_FORMAT_ASTC_12x12_SRGB_BLOCK + 1;
surface_properties& surface_properties::get_instance()
{
static surface_properties instance;
return instance;
}
VkResult surface_properties::get_surface_capabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
VkResult surface_properties::get_surface_capabilities(VkPhysicalDevice physical_device,
VkSurfaceCapabilitiesKHR *surface_capabilities)
{
UNUSED(surface);
/* Image count limits */
surface_capabilities->minImageCount = 1;
surface_capabilities->maxImageCount = MAX_SWAPCHAIN_IMAGE_COUNT;
@ -88,25 +89,19 @@ VkResult surface_properties::get_surface_capabilities(VkPhysicalDevice physical_
return VK_SUCCESS;
}
VkResult surface_properties::get_surface_formats(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
uint32_t *surface_format_count, VkSurfaceFormatKHR *surface_formats)
static uint32_t fill_supported_formats(VkPhysicalDevice physical_device,
std::array<VkFormat, max_core_1_0_formats> &formats)
{
UNUSED(surface);
VkResult res = VK_SUCCESS;
/* Construct a list of all formats supported by the driver - for color attachment */
constexpr int max_core_1_0_formats = VK_FORMAT_ASTC_12x12_SRGB_BLOCK + 1;
std::array<VkFormat, max_core_1_0_formats> formats{};
uint32_t format_count = 0;
for (int id = 0; id < max_core_1_0_formats; id++)
{
VkImageFormatProperties image_format_props;
res = layer::instance_private_data::get(physical_device)
.disp.GetPhysicalDeviceImageFormatProperties(
physical_device, static_cast<VkFormat>(id), VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, &image_format_props);
VkResult res =
layer::instance_private_data::get(physical_device)
.disp.GetPhysicalDeviceImageFormatProperties(physical_device, static_cast<VkFormat>(id), VK_IMAGE_TYPE_2D,
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, &image_format_props);
if (res != VK_ERROR_FORMAT_NOT_SUPPORTED)
{
@ -114,29 +109,18 @@ VkResult surface_properties::get_surface_formats(VkPhysicalDevice physical_devic
format_count++;
}
}
assert(format_count > 0);
assert(surface_format_count != nullptr);
res = VK_SUCCESS;
if (nullptr == surface_formats)
{
*surface_format_count = format_count;
}
else
{
if (format_count > *surface_format_count)
{
res = VK_INCOMPLETE;
}
*surface_format_count = std::min(*surface_format_count, format_count);
for (uint32_t i = 0; i < *surface_format_count; ++i)
{
surface_formats[i].format = formats[i];
surface_formats[i].colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
}
}
return format_count;
}
return res;
VkResult surface_properties::get_surface_formats(VkPhysicalDevice physical_device, uint32_t *surface_format_count,
VkSurfaceFormatKHR *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);
}
VkResult surface_properties::get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019 Arm Limited.
* Copyright (c) 2017-2019, 2022 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
@ -36,10 +36,10 @@ namespace headless
class surface_properties : public wsi::surface_properties
{
public:
VkResult get_surface_capabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
VkResult get_surface_capabilities(VkPhysicalDevice physical_device,
VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) override;
VkResult get_surface_formats(VkPhysicalDevice physical_device, VkSurfaceKHR surface, uint32_t *surfaceFormatCount,
VkResult get_surface_formats(VkPhysicalDevice physical_device, uint32_t *surfaceFormatCount,
VkSurfaceFormatKHR *surfaceFormats) override;
VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019, 2021 Arm Limited.
* Copyright (c) 2017-2019, 2021-2022 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
@ -46,14 +46,14 @@ public:
/**
* @brief Implementation of vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the specific VkSurface type.
*/
virtual VkResult get_surface_capabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
virtual VkResult get_surface_capabilities(VkPhysicalDevice physical_device,
VkSurfaceCapabilitiesKHR *surface_capabilities) = 0;
/**
* @brief 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;
virtual VkResult get_surface_formats(VkPhysicalDevice physical_device, uint32_t *surface_format_count,
VkSurfaceFormatKHR *surface_formats) = 0;
/**
* @brief Implementation of vkGetPhysicalDeviceSurfacePresentModesKHR for the specific VkSurface type.
@ -84,6 +84,53 @@ public:
/* There is no maximum theoretically speaking however we choose 3 for practicality */
static constexpr uint32_t MAX_SWAPCHAIN_IMAGE_COUNT = 3;
protected:
/**
* @brief Helper function for the vkGetPhysicalDeviceSurfaceFormatsKHR entrypoint.
*
* 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.
*
* 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)
{
assert(surface_formats_count != nullptr);
const uint32_t supported_formats_count = std::distance(begin, end);
if (surface_formats == nullptr)
{
*surface_formats_count = supported_formats_count;
return VK_SUCCESS;
}
VkResult res = VK_SUCCESS;
if (supported_formats_count > *surface_formats_count)
{
res = VK_INCOMPLETE;
}
*surface_formats_count = std::min(*surface_formats_count, supported_formats_count);
uint32_t format_count = 0;
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;
}
});
return res;
}
};
} /* namespace wsi */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019, 2021 Arm Limited.
* Copyright (c) 2017-2019, 2021-2022 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
@ -66,10 +66,9 @@ surface_properties &surface_properties::get_instance()
return instance;
}
VkResult surface_properties::get_surface_capabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
VkResult surface_properties::get_surface_capabilities(VkPhysicalDevice physical_device,
VkSurfaceCapabilitiesKHR *pSurfaceCapabilities)
{
/* Image count limits */
pSurfaceCapabilities->minImageCount = 2;
pSurfaceCapabilities->maxImageCount = MAX_SWAPCHAIN_IMAGE_COUNT;
@ -127,8 +126,8 @@ static VkResult get_vk_supported_formats(const util::vector<drm_format_pair> &dr
return VK_SUCCESS;
}
VkResult surface_properties::get_surface_formats(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
uint32_t *surfaceFormatCount, VkSurfaceFormatKHR *surfaceFormats)
VkResult surface_properties::get_surface_formats(VkPhysicalDevice physical_device, uint32_t *surfaceFormatCount,
VkSurfaceFormatKHR *surfaceFormats)
{
assert(specific_surface);
if (!supported_formats.size())
@ -140,33 +139,7 @@ VkResult surface_properties::get_surface_formats(VkPhysicalDevice physical_devic
}
}
assert(surfaceFormatCount != nullptr);
if (nullptr == surfaceFormats)
{
*surfaceFormatCount = supported_formats.size();
return VK_SUCCESS;
}
VkResult res = VK_SUCCESS;
if (supported_formats.size() > *surfaceFormatCount)
{
res = VK_INCOMPLETE;
}
uint32_t format_count = 0;
for (const auto &format : supported_formats)
{
if (format_count >= *surfaceFormatCount)
{
break;
}
surfaceFormats[format_count].format = format;
surfaceFormats[format_count++].colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
}
*surfaceFormatCount = format_count;
return res;
return set_surface_formats(supported_formats.begin(), supported_formats.end(), surfaceFormatCount, surfaceFormats);
}
VkResult surface_properties::get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019, 2021 Arm Limited.
* Copyright (c) 2017-2019, 2021-2022 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
@ -51,9 +51,9 @@ public:
static surface_properties &get_instance();
VkResult get_surface_capabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
VkResult get_surface_capabilities(VkPhysicalDevice physical_device,
VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) override;
VkResult get_surface_formats(VkPhysicalDevice physical_device, VkSurfaceKHR surface, uint32_t *surfaceFormatCount,
VkResult get_surface_formats(VkPhysicalDevice physical_device, uint32_t *surfaceFormatCount,
VkSurfaceFormatKHR *surfaceFormats) override;
VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) override;