From 279d21607c09d030a80ef099563bc4403f403102 Mon Sep 17 00:00:00 2001 From: Ryan Zhang Date: Mon, 15 Sep 2025 19:31:02 +0800 Subject: [PATCH] Guarantee surface caps is consisitent between EXT and KHR Due to Vulkan WSI only support query surface caps by KHR, so query result will mismatch when driver support EXT and have different strategy with Vulkan WSI. Mesa init min/maxImageCount = {4,0} both in EXT and KHR Vulkan WSI init min/maxImageCount = {2,6} only in KHR So cts obtain {4,0} by vkGetPhysicalDeviceSurface Capabilities2EXT and obtain {2,6} by vkGetPhysicalDevi ceSurfaceCapabilitiesKHR. fix case: dEQP-VK.wsi.wayland.surface.query_surface_counters Signed-off-by: Ryan Zhang --- layer/layer.cpp | 5 ++++ layer/private_data.hpp | 1 + layer/surface_api.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++ layer/surface_api.hpp | 9 ++++++- 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/layer/layer.cpp b/layer/layer.cpp index 64d14fa..baa6a75 100644 --- a/layer/layer.cpp +++ b/layer/layer.cpp @@ -796,6 +796,11 @@ wsi_layer_vkGetInstanceProcAddr(VkInstance instance, const char *funcName) VWL_A GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceCapabilities2KHR); GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceFormats2KHR); } + + if (instance_data.is_instance_extension_enabled(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)) + { + GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceCapabilities2EXT); + } } return instance_data.disp.get_user_enabled_entrypoint(instance, funcName); diff --git a/layer/private_data.hpp b/layer/private_data.hpp index d57759d..edb1526 100644 --- a/layer/private_data.hpp +++ b/layer/private_data.hpp @@ -222,6 +222,7 @@ static constexpr uint32_t API_VERSION_MAX = UINT32_MAX; /* VK_KHR_surface */ \ EP(DestroySurfaceKHR, VK_KHR_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false, ) \ EP(GetPhysicalDeviceSurfaceCapabilitiesKHR, VK_KHR_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + EP(GetPhysicalDeviceSurfaceCapabilities2EXT, VK_KHR_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false, ) \ EP(GetPhysicalDeviceSurfaceFormatsKHR, VK_KHR_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false, ) \ EP(GetPhysicalDeviceSurfacePresentModesKHR, VK_KHR_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false, ) \ EP(GetPhysicalDeviceSurfaceSupportKHR, VK_KHR_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false, ) \ diff --git a/layer/surface_api.cpp b/layer/surface_api.cpp index dc4cf65..dde362d 100644 --- a/layer/surface_api.cpp +++ b/layer/surface_api.cpp @@ -52,6 +52,59 @@ wsi_layer_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDev return instance.disp.GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, pSurfaceCapabilities); } +/** + * @brief Implements vkGetPhysicalDeviceSurfaceCapabilities2EXT Vulkan entrypoint. + */ +VWL_VKAPI_CALL(VkResult) +wsi_layer_vkGetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, + VkSurfaceCapabilities2EXT *pSurfaceCapabilities) VWL_API_POST +{ + /* + * To adapt vulkan driver like mesa:panvk which still expose vkGetPhysicalDeviceSurfaceCapabilities2EXT + * and VK_EXT_display_surface_counter. Vulkan WSI need to implement vkGetPhysicalDeviceSurfaceCapabilities2EXT + * to handle the compatibility between Vulkan WSI and ICD. + * Because mesa has different initialization strategy on min/maxImageCount with Vulkan WSI, + * so if we haven't do like this, app will obtain different value between + * vkGetPhysicalDeviceSurfaceCapabilities2EXT and vkGetPhysicalDeviceSurfaceCapabilities2KHR. + */ + auto &instance = layer::instance_private_data::get(physicalDevice); + if (instance.should_layer_handle_surface(physicalDevice, surface)) + { + wsi::surface_properties *props = wsi::get_surface_properties(instance, surface); + assert(props != nullptr); + + /* + * Firstly, VkSurfaceCapabilities2EXT equal to { VkSurfaceCapabilitiesKHR, VkSurfaceCounterFlagsEXT } + * So we set the common variable by common function as same as VkSurfaceCapabilitiesKHR, + * then set supportedSurfaceCounters manually. + * + * Secondly, from the vulkan spec, VkSurfaceCapabilities2EXT->pNext must be NULL, + * so we needn't to deal with the pNext Structure like vkGetPhysicalDeviceSurfaceCapabilities2KHR. + */ + VkSurfaceCapabilitiesKHR khr_caps = {}; + VkResult res = props->get_surface_capabilities(physicalDevice, &khr_caps); + if (res != VK_SUCCESS) + { + return res; + } + pSurfaceCapabilities->minImageCount = khr_caps.minImageCount; + pSurfaceCapabilities->maxImageCount = khr_caps.maxImageCount; + pSurfaceCapabilities->currentExtent = khr_caps.currentExtent; + pSurfaceCapabilities->minImageExtent = khr_caps.minImageExtent; + pSurfaceCapabilities->maxImageExtent = khr_caps.maxImageExtent; + pSurfaceCapabilities->maxImageArrayLayers = khr_caps.maxImageArrayLayers; + pSurfaceCapabilities->supportedTransforms = khr_caps.supportedTransforms; + pSurfaceCapabilities->currentTransform = khr_caps.currentTransform; + pSurfaceCapabilities->supportedCompositeAlpha = khr_caps.supportedCompositeAlpha; + pSurfaceCapabilities->supportedUsageFlags = khr_caps.supportedUsageFlags; + pSurfaceCapabilities->supportedSurfaceCounters = 0; + + return res; + } + + return instance.disp.GetPhysicalDeviceSurfaceCapabilities2EXT(physicalDevice, surface, pSurfaceCapabilities); +} + /** * @brief Implements vkGetPhysicalDeviceSurfaceCapabilities2KHR Vulkan entrypoint. */ diff --git a/layer/surface_api.hpp b/layer/surface_api.hpp index 74c4120..c61d548 100644 --- a/layer/surface_api.hpp +++ b/layer/surface_api.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, 2021-2022 Arm Limited. + * Copyright (c) 2018-2019, 2021-2022, 2025 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -39,6 +39,13 @@ VWL_VKAPI_CALL(VkResult) wsi_layer_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) VWL_API_POST; +/** + * @brief Implements vkGetPhysicalDeviceSurfaceCapabilities2EXT Vulkan entrypoint. + */ +VWL_VKAPI_CALL(VkResult) +wsi_layer_vkGetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, + VkSurfaceCapabilities2EXT *pSurfaceCapabilities) VWL_API_POST; + /** * @brief Implements vkGetPhysicalDeviceSurfaceCapabilities2KHR Vulkan entrypoint. */