From feee8f5d36151dfd7eba5dbbef608e66e10f459c Mon Sep 17 00:00:00 2001 From: Iason Paraskevopoulos Date: Mon, 28 Feb 2022 16:21:06 +0000 Subject: [PATCH] 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 --- layer/private_data.cpp | 6 ++- layer/surface_api.cpp | 6 +-- layer/swapchain_api.cpp | 4 +- wsi/headless/surface_properties.cpp | 58 +++++++++++------------------ wsi/headless/surface_properties.hpp | 6 +-- wsi/surface_properties.hpp | 55 +++++++++++++++++++++++++-- wsi/wayland/surface_properties.cpp | 37 +++--------------- wsi/wayland/surface_properties.hpp | 6 +-- 8 files changed, 92 insertions(+), 86 deletions(-) diff --git a/layer/private_data.cpp b/layer/private_data.cpp index 4e377a2..102034d 100644 --- a/layer/private_data.cpp +++ b/layer/private_data.cpp @@ -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 g_instance_data{ uti static util::unordered_map g_device_data{ util::allocator::get_generic() }; static const std::array 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 supported_device_extensions = { diff --git a/layer/surface_api.cpp b/layer/surface_api.cpp index bf9aca6..0f542af 100644 --- a/layer/surface_api.cpp +++ b/layer/surface_api.cpp @@ -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, diff --git a/layer/swapchain_api.cpp b/layer/swapchain_api.cpp index b7c495f..80fd051 100644 --- a/layer/swapchain_api.cpp +++ b/layer/swapchain_api.cpp @@ -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) { diff --git a/wsi/headless/surface_properties.cpp b/wsi/headless/surface_properties.cpp index a24e0d6..df36a46 100644 --- a/wsi/headless/surface_properties.cpp +++ b/wsi/headless/surface_properties.cpp @@ -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 &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 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(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(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 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, diff --git a/wsi/headless/surface_properties.hpp b/wsi/headless/surface_properties.hpp index b2d1ff9..373f648 100644 --- a/wsi/headless/surface_properties.hpp +++ b/wsi/headless/surface_properties.hpp @@ -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, diff --git a/wsi/surface_properties.hpp b/wsi/surface_properties.hpp index 23d49f9..4e1246d 100644 --- a/wsi/surface_properties.hpp +++ b/wsi/surface_properties.hpp @@ -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 + 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 */ diff --git a/wsi/wayland/surface_properties.cpp b/wsi/wayland/surface_properties.cpp index 83683db..195294d 100644 --- a/wsi/wayland/surface_properties.cpp +++ b/wsi/wayland/surface_properties.cpp @@ -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 &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, diff --git a/wsi/wayland/surface_properties.hpp b/wsi/wayland/surface_properties.hpp index 1ea5730..d7dfe9b 100644 --- a/wsi/wayland/surface_properties.hpp +++ b/wsi/wayland/surface_properties.hpp @@ -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;