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 * 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 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 *, 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 = { 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 * SPDX-License-Identifier: MIT
* *
@ -39,7 +39,7 @@ wsi_layer_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDev
{ {
wsi::surface_properties *props = wsi::get_surface_properties(instance, surface); wsi::surface_properties *props = wsi::get_surface_properties(instance, surface);
assert(props != nullptr); 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 /* 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); wsi::surface_properties *props = wsi::get_surface_properties(instance, surface);
assert(props != nullptr); 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, 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 * SPDX-License-Identifier: MIT
* *
@ -295,7 +295,7 @@ wsi_layer_vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevic
*pRectCount = 1; *pRectCount = 1;
VkSurfaceCapabilitiesKHR surface_caps; VkSurfaceCapabilitiesKHR surface_caps;
result = props->get_surface_capabilities(physicalDevice, surface, &surface_caps); result = props->get_surface_capabilities(physicalDevice, &surface_caps);
if (result != VK_SUCCESS) 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 * SPDX-License-Identifier: MIT
* *
@ -46,16 +46,17 @@ namespace wsi
namespace headless namespace headless
{ {
constexpr int max_core_1_0_formats = VK_FORMAT_ASTC_12x12_SRGB_BLOCK + 1;
surface_properties& surface_properties::get_instance() surface_properties& surface_properties::get_instance()
{ {
static surface_properties instance; static surface_properties instance;
return 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) VkSurfaceCapabilitiesKHR *surface_capabilities)
{ {
UNUSED(surface);
/* Image count limits */ /* Image count limits */
surface_capabilities->minImageCount = 1; surface_capabilities->minImageCount = 1;
surface_capabilities->maxImageCount = MAX_SWAPCHAIN_IMAGE_COUNT; surface_capabilities->maxImageCount = MAX_SWAPCHAIN_IMAGE_COUNT;
@ -88,25 +89,19 @@ VkResult surface_properties::get_surface_capabilities(VkPhysicalDevice physical_
return VK_SUCCESS; return VK_SUCCESS;
} }
VkResult surface_properties::get_surface_formats(VkPhysicalDevice physical_device, VkSurfaceKHR surface, static uint32_t fill_supported_formats(VkPhysicalDevice physical_device,
uint32_t *surface_format_count, VkSurfaceFormatKHR *surface_formats) 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; uint32_t format_count = 0;
for (int id = 0; id < max_core_1_0_formats; id++) for (int id = 0; id < max_core_1_0_formats; id++)
{ {
VkImageFormatProperties image_format_props; VkImageFormatProperties image_format_props;
res = layer::instance_private_data::get(physical_device) VkResult res =
.disp.GetPhysicalDeviceImageFormatProperties( layer::instance_private_data::get(physical_device)
physical_device, static_cast<VkFormat>(id), VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, .disp.GetPhysicalDeviceImageFormatProperties(physical_device, static_cast<VkFormat>(id), VK_IMAGE_TYPE_2D,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, &image_format_props); 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) if (res != VK_ERROR_FORMAT_NOT_SUPPORTED)
{ {
@ -114,29 +109,18 @@ VkResult surface_properties::get_surface_formats(VkPhysicalDevice physical_devic
format_count++; 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); return 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 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, 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 * SPDX-License-Identifier: MIT
* *
@ -36,10 +36,10 @@ namespace headless
class surface_properties : public wsi::surface_properties class surface_properties : public wsi::surface_properties
{ {
public: public:
VkResult get_surface_capabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface, VkResult get_surface_capabilities(VkPhysicalDevice physical_device,
VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) override; 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; VkSurfaceFormatKHR *surfaceFormats) override;
VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface, 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 * SPDX-License-Identifier: MIT
* *
@ -46,14 +46,14 @@ public:
/** /**
* @brief Implementation of vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the specific VkSurface type. * @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; VkSurfaceCapabilitiesKHR *surface_capabilities) = 0;
/** /**
* @brief Implementation of vkGetPhysicalDeviceSurfaceFormatsKHR for the specific VkSurface type. * @brief Implementation of vkGetPhysicalDeviceSurfaceFormatsKHR for the specific VkSurface type.
*/ */
virtual VkResult get_surface_formats(VkPhysicalDevice physical_device, VkSurfaceKHR surface, virtual VkResult get_surface_formats(VkPhysicalDevice physical_device, uint32_t *surface_format_count,
uint32_t *surface_format_count, VkSurfaceFormatKHR *surface_formats) = 0; VkSurfaceFormatKHR *surface_formats) = 0;
/** /**
* @brief Implementation of vkGetPhysicalDeviceSurfacePresentModesKHR for the specific VkSurface type. * @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 */ /* There is no maximum theoretically speaking however we choose 3 for practicality */
static constexpr uint32_t MAX_SWAPCHAIN_IMAGE_COUNT = 3; 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 */ } /* 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 * SPDX-License-Identifier: MIT
* *
@ -66,10 +66,9 @@ surface_properties &surface_properties::get_instance()
return 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) VkSurfaceCapabilitiesKHR *pSurfaceCapabilities)
{ {
/* Image count limits */
pSurfaceCapabilities->minImageCount = 2; pSurfaceCapabilities->minImageCount = 2;
pSurfaceCapabilities->maxImageCount = MAX_SWAPCHAIN_IMAGE_COUNT; 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; return VK_SUCCESS;
} }
VkResult surface_properties::get_surface_formats(VkPhysicalDevice physical_device, VkSurfaceKHR surface, VkResult surface_properties::get_surface_formats(VkPhysicalDevice physical_device, uint32_t *surfaceFormatCount,
uint32_t *surfaceFormatCount, VkSurfaceFormatKHR *surfaceFormats) VkSurfaceFormatKHR *surfaceFormats)
{ {
assert(specific_surface); assert(specific_surface);
if (!supported_formats.size()) if (!supported_formats.size())
@ -140,33 +139,7 @@ VkResult surface_properties::get_surface_formats(VkPhysicalDevice physical_devic
} }
} }
assert(surfaceFormatCount != nullptr); return set_surface_formats(supported_formats.begin(), supported_formats.end(), surfaceFormatCount, surfaceFormats);
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;
} }
VkResult surface_properties::get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface, 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 * SPDX-License-Identifier: MIT
* *
@ -51,9 +51,9 @@ public:
static surface_properties &get_instance(); static surface_properties &get_instance();
VkResult get_surface_capabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface, VkResult get_surface_capabilities(VkPhysicalDevice physical_device,
VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) override; 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; VkSurfaceFormatKHR *surfaceFormats) override;
VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface, VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) override; uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) override;