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. */