From 670f1e9476e7be951a831da143e61319ddaa7119 Mon Sep 17 00:00:00 2001 From: Avi Shif Date: Wed, 4 Jun 2025 08:39:03 +0000 Subject: [PATCH] Support VK_PRESENT_MODE_FIFO_LATEST_READY_EXT for headless & wayland Enabling VK_PRESENT_MODE_FIFO_LATEST_READY_EXT for headless & wayland This extension is handled the same as the MAILBOX ext. Signed-off-by: Nir Ekhauz Change-Id: I010c3c9474a6d9c28964806ba5aa63549b622454 --- CMakeLists.txt | 2 +- layer/VkLayer_window_system_integration.json | 4 ++++ layer/layer.cpp | 19 +++++++++++++++++++ layer/private_data.cpp | 6 ++++++ layer/private_data.hpp | 15 +++++++++++++++ wsi/headless/surface_properties.cpp | 16 +++++++++++++--- wsi/headless/surface_properties.hpp | 15 ++++++++++++--- wsi/wayland/surface_properties.cpp | 18 ++++++++++++++---- wsi/wayland/surface_properties.hpp | 15 +++++++++++---- wsi/wayland/swapchain.cpp | 13 ++++++++----- wsi/wsi_factory.cpp | 1 - wsi/wsi_factory.hpp | 1 - 12 files changed, 103 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 045f56a..4ef48f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -319,7 +319,7 @@ if (VULKAN_WSI_LAYER_EXPERIMENTAL) target_sources(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/wsi/extensions/present_wait.cpp) add_definitions("-DVULKAN_WSI_LAYER_EXPERIMENTAL=1") else() - list(APPEND JSON_COMMANDS COMMAND sed -Ei '/VK_EXT_present_timing|VK_KHR_present_wait/d' ${CMAKE_CURRENT_BINARY_DIR}/VkLayer_window_system_integration.json) + list(APPEND JSON_COMMANDS COMMAND sed -Ei '/VK_EXT_present_timing|VK_KHR_present_wait|VK_EXT_present_mode_fifo_latest_ready/d' ${CMAKE_CURRENT_BINARY_DIR}/VkLayer_window_system_integration.json) add_definitions("-DVULKAN_WSI_LAYER_EXPERIMENTAL=0") endif() diff --git a/layer/VkLayer_window_system_integration.json b/layer/VkLayer_window_system_integration.json index ec03a00..48eade2 100644 --- a/layer/VkLayer_window_system_integration.json +++ b/layer/VkLayer_window_system_integration.json @@ -60,6 +60,10 @@ "entrypoints": [ "vkWaitForPresentKHR" ] + }, + { + "name": "VK_EXT_present_mode_fifo_latest_ready", + "spec_version": "1" } ], "disable_environment": { diff --git a/layer/layer.cpp b/layer/layer.cpp index 6db80fd..94221a0 100644 --- a/layer/layer.cpp +++ b/layer/layer.cpp @@ -364,6 +364,17 @@ VKAPI_ATTR VkResult create_device(VkPhysicalDevice physicalDevice, const VkDevic device_data.set_present_id_feature_enabled(present_id_features->presentId); } +#if VULKAN_WSI_LAYER_EXPERIMENTAL + const auto present_mode_fifo_latest_ready_features = + util::find_extension( + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_MODE_FIFO_LATEST_READY_FEATURES_EXT, pCreateInfo->pNext); + if (present_mode_fifo_latest_ready_features != nullptr) + { + device_data.set_present_mode_fifo_latest_ready_enabled( + present_mode_fifo_latest_ready_features->presentModeFifoLatestReady); + } +#endif + auto *physical_device_swapchain_maintenance1_features = util::find_extension( VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT, pCreateInfo->pNext); @@ -535,6 +546,14 @@ wsi_layer_vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physical_device, present_timing_features->presentAtAbsoluteTime = VK_TRUE; present_timing_features->presentAtRelativeTime = VK_TRUE; } + + auto *present_mode_fifo_latest_ready_features = + util::find_extension( + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_MODE_FIFO_LATEST_READY_FEATURES_EXT, pFeatures->pNext); + if (present_mode_fifo_latest_ready_features != nullptr) + { + present_mode_fifo_latest_ready_features->presentModeFifoLatestReady = VK_TRUE; + } #endif } diff --git a/layer/private_data.cpp b/layer/private_data.cpp index 461daa6..9b874b0 100644 --- a/layer/private_data.cpp +++ b/layer/private_data.cpp @@ -451,6 +451,7 @@ device_private_data::device_private_data(instance_private_data &inst_data, VkPhy , swapchain_maintenance1_enabled{ false } #if VULKAN_WSI_LAYER_EXPERIMENTAL , present_timing_enabled { true } + , present_mode_fifo_latest_ready_enabled { false } #endif /* clang-format on */ { @@ -643,6 +644,11 @@ bool device_private_data::is_present_wait_enabled() { return present_wait_enabled; } + +void device_private_data::set_present_mode_fifo_latest_ready_enabled(bool enable) +{ + present_mode_fifo_latest_ready_enabled = enable; +} #endif } /* namespace layer */ diff --git a/layer/private_data.hpp b/layer/private_data.hpp index d342fb6..cf10bca 100644 --- a/layer/private_data.hpp +++ b/layer/private_data.hpp @@ -897,6 +897,15 @@ public: */ bool is_present_id_enabled(); +#if VULKAN_WSI_LAYER_EXPERIMENTAL + /** + * @brief Selectively enable/disable the fifo_latest_ready for this device + * + * @param enable Value to set fifo_latest_ready_enabled member variable. + */ + void set_present_mode_fifo_latest_ready_enabled(bool enable); +#endif + /** * @brief Selectively enable/disable the swapchain maintenance1 features for this device. * @@ -995,6 +1004,12 @@ private: * @brief Stores whether the device has enabled support for the present timing features. */ bool present_timing_enabled{ false }; + + /** + * @brief Stores whether the device supports the fifo latest ready present mode. + * + */ + bool present_mode_fifo_latest_ready_enabled{ false }; #endif }; diff --git a/wsi/headless/surface_properties.cpp b/wsi/headless/surface_properties.cpp index d63582d..f18c5fc 100644 --- a/wsi/headless/surface_properties.cpp +++ b/wsi/headless/surface_properties.cpp @@ -56,15 +56,25 @@ void surface_properties::populate_present_mode_compatibilities() present_mode_compatibility{ VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, 1, { VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR } }, present_mode_compatibility{ - VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR, 1, { VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR } }, + VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR, 1, { VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR } } +#if VULKAN_WSI_LAYER_EXPERIMENTAL + , + present_mode_compatibility{ VK_PRESENT_MODE_FIFO_LATEST_READY_EXT, 1, { VK_PRESENT_MODE_FIFO_LATEST_READY_EXT } } +#endif }; m_compatible_present_modes = compatible_present_modes(compatible_present_modes_list); } surface_properties::surface_properties() - : m_supported_modes({ VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_FIFO_RELAXED_KHR, - VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR }) + : m_supported_modes({ + VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_FIFO_RELAXED_KHR, VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, + VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR +#if VULKAN_WSI_LAYER_EXPERIMENTAL + , + VK_PRESENT_MODE_FIFO_LATEST_READY_EXT +#endif + }) { populate_present_mode_compatibilities(); } diff --git a/wsi/headless/surface_properties.hpp b/wsi/headless/surface_properties.hpp index 955166e..f15902e 100644 --- a/wsi/headless/surface_properties.hpp +++ b/wsi/headless/surface_properties.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, 2022-2024 Arm Limited. + * Copyright (c) 2017-2019, 2022-2025 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -28,10 +28,19 @@ #include #include #include + namespace wsi { namespace headless { +#if VULKAN_WSI_LAYER_EXPERIMENTAL +/* + * Due to VK_PRESENT_MODE_FIFO_LATEST_READY_EXT + */ +constexpr int PRESENT_MODES_NUM = 5; +#else +constexpr int PRESENT_MODES_NUM = 4; +#endif class surface_properties : public wsi::surface_properties { @@ -68,10 +77,10 @@ public: private: /* List of supported presentation modes */ - std::array m_supported_modes; + std::array m_supported_modes; /* Stores compatible presentation modes */ - compatible_present_modes<4> m_compatible_present_modes; + compatible_present_modes m_compatible_present_modes; void populate_present_mode_compatibilities() override; diff --git a/wsi/wayland/surface_properties.cpp b/wsi/wayland/surface_properties.cpp index c25858d..f1fabcb 100644 --- a/wsi/wayland/surface_properties.cpp +++ b/wsi/wayland/surface_properties.cpp @@ -53,17 +53,28 @@ namespace wayland void surface_properties::populate_present_mode_compatibilities() { - std::array compatible_present_modes_list = { + std::array compatible_present_modes_list = { present_mode_compatibility{ VK_PRESENT_MODE_FIFO_KHR, 1, { VK_PRESENT_MODE_FIFO_KHR } }, present_mode_compatibility{ VK_PRESENT_MODE_MAILBOX_KHR, 1, { VK_PRESENT_MODE_MAILBOX_KHR } } +#if VULKAN_WSI_LAYER_EXPERIMENTAL + , + present_mode_compatibility{ VK_PRESENT_MODE_FIFO_LATEST_READY_EXT, 1, { VK_PRESENT_MODE_FIFO_LATEST_READY_EXT } } +#endif }; - m_compatible_present_modes = compatible_present_modes<2>(compatible_present_modes_list); + m_compatible_present_modes = + compatible_present_modes(compatible_present_modes_list); } surface_properties::surface_properties(surface *wsi_surface, const util::allocator &allocator) : specific_surface(wsi_surface) , supported_formats(allocator) - , m_supported_modes({ VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_MAILBOX_KHR }) + , m_supported_modes({ + VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_MAILBOX_KHR +#if VULKAN_WSI_LAYER_EXPERIMENTAL + , + VK_PRESENT_MODE_FIFO_LATEST_READY_EXT +#endif + }) { populate_present_mode_compatibilities(); } @@ -242,7 +253,6 @@ VkResult surface_properties::get_surface_present_modes(VkPhysicalDevice physical { UNUSED(physical_device); UNUSED(surface); - return get_surface_present_modes_common(pPresentModeCount, pPresentModes, m_supported_modes); } diff --git a/wsi/wayland/surface_properties.hpp b/wsi/wayland/surface_properties.hpp index cb14c93..47d60a3 100644 --- a/wsi/wayland/surface_properties.hpp +++ b/wsi/wayland/surface_properties.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, 2021-2024 Arm Limited. + * Copyright (c) 2017-2019, 2021-2025 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -32,7 +32,14 @@ namespace wsi { namespace wayland { - +#if VULKAN_WSI_LAYER_EXPERIMENTAL +/* + * Due to VK_PRESENT_MODE_FIFO_LATEST_READY_EXT + */ +constexpr int PRESENT_MODES_NUM = 3; +#else +constexpr int PRESENT_MODES_NUM = 2; +#endif struct surface_format_properties_hasher { size_t operator()(const VkFormat &format) const @@ -88,10 +95,10 @@ private: surface_format_properties_map supported_formats; /* List of supported presentation modes */ - std::array m_supported_modes; + std::array m_supported_modes; /* Stores compatible presentation modes */ - compatible_present_modes<2> m_compatible_present_modes; + compatible_present_modes m_compatible_present_modes; void populate_present_mode_compatibilities() override; diff --git a/wsi/wayland/swapchain.cpp b/wsi/wayland/swapchain.cpp index b7299c3..2ebf729 100644 --- a/wsi/wayland/swapchain.cpp +++ b/wsi/wayland/swapchain.cpp @@ -188,12 +188,15 @@ VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKH } /* - * When VK_PRESENT_MODE_MAILBOX_KHR has been chosen by the application we don't - * initialize the page flip thread so the present_image function can be called - * during vkQueuePresent. + * When VK_PRESENT_MODE_MAILBOX_KHR or VK_PRESENT_MODE_FIFO_LATEST_READY_EXT has + * been chosen by the application we don't initialize the page flip thread + * so the present_image function can be called during vkQueuePresent. */ - use_presentation_thread = - WAYLAND_FIFO_PRESENTATION_THREAD_ENABLED && (m_present_mode != VK_PRESENT_MODE_MAILBOX_KHR); + use_presentation_thread = WAYLAND_FIFO_PRESENTATION_THREAD_ENABLED +#if VULKAN_WSI_LAYER_EXPERIMENTAL + && (m_present_mode != VK_PRESENT_MODE_FIFO_LATEST_READY_EXT) +#endif + && (m_present_mode != VK_PRESENT_MODE_MAILBOX_KHR); #if VULKAN_WSI_LAYER_EXPERIMENTAL auto present_wait = get_swapchain_extension(); diff --git a/wsi/wsi_factory.cpp b/wsi/wsi_factory.cpp index 8fdc93b..2f4fbff 100644 --- a/wsi/wsi_factory.cpp +++ b/wsi/wsi_factory.cpp @@ -302,5 +302,4 @@ void set_swapchain_maintenance1_state(VkPhysicalDevice physicalDevice, } } } - } // namespace wsi diff --git a/wsi/wsi_factory.hpp b/wsi/wsi_factory.hpp index c76e076..bedbe09 100644 --- a/wsi/wsi_factory.hpp +++ b/wsi/wsi_factory.hpp @@ -136,5 +136,4 @@ PFN_vkVoidFunction get_proc_addr(const char *name, const layer::instance_private */ void set_swapchain_maintenance1_state( VkPhysicalDevice physicalDevice, VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT *swapchain_maintenance1_features); - } // namespace wsi