diff --git a/README.md b/README.md index 7df6bc8..4836b5b 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,12 @@ The ICDs installed in the system are required to support the following extension * VK_KHR_external_fence_fd * Any dependencies of the above extensions +### Vulkan Header Version + +The Vulkan WSI Layer has been validated against Vulkan header version 1.4.299. + +If you are using a Vulkan header version newer than this, a warning will appear during compilation. + ### Building the VulkanĀ® loader This step is not necessary if your system already has a loader and associated diff --git a/layer/VkLayer_window_system_integration.json b/layer/VkLayer_window_system_integration.json index 276b937..71945e6 100644 --- a/layer/VkLayer_window_system_integration.json +++ b/layer/VkLayer_window_system_integration.json @@ -4,7 +4,7 @@ "name": "VK_LAYER_window_system_integration", "type": "GLOBAL", "library_path": "./libVkLayer_window_system_integration.so", - "api_version": "1.3.216", + "api_version": "1.4.299", "implementation_version": "1", "description": "Window system integration layer", "functions": { diff --git a/layer/layer.cpp b/layer/layer.cpp index 1d52a7b..5f809fe 100644 --- a/layer/layer.cpp +++ b/layer/layer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2024 Arm Limited. + * Copyright (c) 2016-2025 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -40,6 +40,7 @@ #include "util/log.hpp" #include "util/macros.hpp" #include "util/helpers.hpp" +#include "wsi/unsupported_surfaces.hpp" #if VULKAN_WSI_LAYER_EXPERIMENTAL #include "wsi_layer_experimental.hpp" @@ -157,6 +158,18 @@ VKAPI_ATTR VkResult create_instance(const VkInstanceCreateInfo *pCreateInfo, con modified_info.enabledExtensionCount = modified_enabled_extensions.size(); } + bool maintainance1_support = true; + /* Loop through unsupported extensions and check if they exist in enabled extensions */ + for (const auto &unsupported_surface_ext : wsi::unsupported_surfaces_ext_array) + { + if (extensions.contains(unsupported_surface_ext)) + { + maintainance1_support = false; + WSI_LOG_ERROR( + "Warning: Swapchain maintenance feature is unsupported for the current surface and ICD configuration.\n"); + } + } + /* Advance the link info for the next element on the chain. */ layer_link_info->u.pLayerInfo = layer_link_info->u.pLayerInfo->pNext; @@ -191,6 +204,8 @@ VKAPI_ATTR VkResult create_instance(const VkInstanceCreateInfo *pCreateInfo, con TRY_LOG_CALL(instance_private_data::associate(*pInstance, std::move(*table), loader_callback, layer_platforms_to_enable, api_version, instance_allocator)); + /* Set the swapchain maintenance flag to true or false based on the enabled extensions checked above*/ + instance_private_data::get(*pInstance).set_maintainance1_support(maintainance1_support); /* * Store the enabled instance extensions in order to return nullptr in * vkGetInstanceProcAddr for functions of disabled extensions. @@ -469,7 +484,15 @@ wsi_layer_vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2 *pFeatures) VWL_API_POST { auto &instance = layer::instance_private_data::get(physicalDevice); - +#if VULKAN_WSI_LAYER_EXPERIMENTAL + auto *physical_device_swapchain_maintenance1_features = + util::find_extension( + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT, pFeatures->pNext); + if (physical_device_swapchain_maintenance1_features != nullptr) + { + physical_device_swapchain_maintenance1_features->swapchainMaintenance1 = false; + } +#endif instance.disp.GetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures); #if WSI_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN @@ -491,13 +514,7 @@ wsi_layer_vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice, } #if VULKAN_WSI_LAYER_EXPERIMENTAL - auto *physical_device_swapchain_maintenance1_features = - util::find_extension( - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT, pFeatures->pNext); - if (physical_device_swapchain_maintenance1_features != nullptr) - { - physical_device_swapchain_maintenance1_features->swapchainMaintenance1 = true; - } + wsi::set_swapchain_maintenance1_state(physicalDevice, physical_device_swapchain_maintenance1_features); auto *present_timing_features = util::find_extension( VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_TIMING_FEATURES_EXT, pFeatures->pNext); diff --git a/layer/private_data.cpp b/layer/private_data.cpp index 080c831..1be75ba 100644 --- a/layer/private_data.cpp +++ b/layer/private_data.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2024 Arm Limited. + * Copyright (c) 2018-2025 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -398,6 +398,16 @@ bool instance_private_data::is_instance_extension_enabled(const char *extension_ return enabled_extensions.contains(extension_name); } +void instance_private_data::set_maintainance1_support(bool enabled_unsupport_ext) +{ + enabled_unsupported_swapchain_maintenance1_extensions = enabled_unsupport_ext; +} + +bool instance_private_data::get_maintainance1_support() +{ + return enabled_unsupported_swapchain_maintenance1_extensions; +} + device_private_data::device_private_data(instance_private_data &inst_data, VkPhysicalDevice phys_dev, VkDevice dev, device_dispatch_table table, PFN_vkSetDeviceLoaderData set_loader_data, const util::allocator &alloc) diff --git a/layer/private_data.hpp b/layer/private_data.hpp index 2b293e0..1b36b23 100644 --- a/layer/private_data.hpp +++ b/layer/private_data.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2024 Arm Limited. + * Copyright (c) 2018-2025 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -637,6 +637,22 @@ public: const instance_dispatch_table disp; const uint32_t api_version; + /** + * @brief Set if swapchain maintainance1 support is enabled. + * + * @param enabled_unsupport_ext True if it is enabled, false otherwise. + * + */ + void set_maintainance1_support(bool enabled_unsupport_ext); + + /** + * @brief Check if swapchain maintainance1 support is enabled. + * + * @return true if it is enabled, false otherwise. + * + */ + bool get_maintainance1_support(); + private: /* Allow util::allocator to access the private constructor */ friend util::allocator; @@ -687,6 +703,11 @@ private: * @brief List with the names of the enabled instance extensions. */ util::extension_list enabled_extensions; + + /** + * @brief True if unsupported extensions are enabled. + */ + bool enabled_unsupported_swapchain_maintenance1_extensions; }; /** diff --git a/wsi/unsupported_surfaces.hpp b/wsi/unsupported_surfaces.hpp new file mode 100644 index 0000000..20d7d1a --- /dev/null +++ b/wsi/unsupported_surfaces.hpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2024-2025 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +/* Define the patch version directly as macros */ +#define WSI_LAYER_VK_PATCH 299 + +/* Convert macros to string */ +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) + +#if VK_HEADER_VERSION > WSI_LAYER_VK_PATCH +#pragma message("The Vulkan header version is newer than the currently supported version.") +#pragma message("Current Vulkan header version: " TOSTRING(VK_HEADER_VERSION)) +#pragma message("Supported Vulkan API version: " TOSTRING(WSI_LAYER_VK_PATCH)) +#endif + +namespace wsi +{ +/* A list of platform-specific unsupported surface extensions + Not using the extension macros and symbols due to missing definitions for native platform symbols. */ +static constexpr std::array unsupported_surfaces_ext_array = { "VK_KHR_win32_surface", "VK_KHR_xlib_surface", + "VK_KHR_xcb_surface", "VK_EXT_metal_surface", + "VK_KHR_android_surface" }; + +} // namespace wsi diff --git a/wsi/wsi_factory.cpp b/wsi/wsi_factory.cpp index 321d779..fb7ec43 100644 --- a/wsi/wsi_factory.cpp +++ b/wsi/wsi_factory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2024 Arm Limited. + * Copyright (c) 2019-2025 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -281,4 +281,25 @@ PFN_vkVoidFunction get_proc_addr(const char *name, const layer::instance_private return nullptr; } +void set_swapchain_maintenance1_state(VkPhysicalDevice physicalDevice, + VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT *swapchain_maintenance1_features) +{ + if (swapchain_maintenance1_features != nullptr) + { + if (swapchain_maintenance1_features->swapchainMaintenance1) + { + auto &instance = layer::instance_private_data::get(physicalDevice); + if (instance.is_instance_extension_enabled(VK_KHR_DISPLAY_EXTENSION_NAME)) + { + swapchain_maintenance1_features->swapchainMaintenance1 = false; + } + } + else + { + swapchain_maintenance1_features->swapchainMaintenance1 = + layer::instance_private_data::get(physicalDevice).get_maintainance1_support(); + } + } +} + } // namespace wsi diff --git a/wsi/wsi_factory.hpp b/wsi/wsi_factory.hpp index 6211d77..c76e076 100644 --- a/wsi/wsi_factory.hpp +++ b/wsi/wsi_factory.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, 2023 Arm Limited. + * Copyright (c) 2019, 2021, 2023-2025 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -124,4 +124,17 @@ VkResult add_instance_extensions_required_by_layer(const util::wsi_platform_set */ PFN_vkVoidFunction get_proc_addr(const char *name, const layer::instance_private_data &instance_data); +/** + * @brief Set swapchain maintenance1 features state, true or false. + * + * Sets the state of the swapchain maintenance1 extensions + * according to the supported enabled extensions. + * + * @param physical_device Vulkan physical_device. + * @param swapchain_maintenance_features address of Vulkan swapchain maintenance capabilities struct. + * + */ +void set_swapchain_maintenance1_state( + VkPhysicalDevice physicalDevice, VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT *swapchain_maintenance1_features); + } // namespace wsi