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 <nir.ekhauz@arm.com>
Change-Id: I010c3c9474a6d9c28964806ba5aa63549b622454
This commit is contained in:
Avi Shif 2025-06-04 08:39:03 +00:00 committed by Rosen Zhelev
parent 16293a438b
commit 670f1e9476
12 changed files with 103 additions and 22 deletions

View file

@ -319,7 +319,7 @@ if (VULKAN_WSI_LAYER_EXPERIMENTAL)
target_sources(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/wsi/extensions/present_wait.cpp) target_sources(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/wsi/extensions/present_wait.cpp)
add_definitions("-DVULKAN_WSI_LAYER_EXPERIMENTAL=1") add_definitions("-DVULKAN_WSI_LAYER_EXPERIMENTAL=1")
else() 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") add_definitions("-DVULKAN_WSI_LAYER_EXPERIMENTAL=0")
endif() endif()

View file

@ -60,6 +60,10 @@
"entrypoints": [ "entrypoints": [
"vkWaitForPresentKHR" "vkWaitForPresentKHR"
] ]
},
{
"name": "VK_EXT_present_mode_fifo_latest_ready",
"spec_version": "1"
} }
], ],
"disable_environment": { "disable_environment": {

View file

@ -364,6 +364,17 @@ VKAPI_ATTR VkResult create_device(VkPhysicalDevice physicalDevice, const VkDevic
device_data.set_present_id_feature_enabled(present_id_features->presentId); 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<VkPhysicalDevicePresentModeFifoLatestReadyFeaturesEXT>(
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 = auto *physical_device_swapchain_maintenance1_features =
util::find_extension<VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT>( util::find_extension<VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT>(
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT, pCreateInfo->pNext); 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->presentAtAbsoluteTime = VK_TRUE;
present_timing_features->presentAtRelativeTime = VK_TRUE; present_timing_features->presentAtRelativeTime = VK_TRUE;
} }
auto *present_mode_fifo_latest_ready_features =
util::find_extension<VkPhysicalDevicePresentModeFifoLatestReadyFeaturesEXT>(
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 #endif
} }

View file

@ -451,6 +451,7 @@ device_private_data::device_private_data(instance_private_data &inst_data, VkPhy
, swapchain_maintenance1_enabled{ false } , swapchain_maintenance1_enabled{ false }
#if VULKAN_WSI_LAYER_EXPERIMENTAL #if VULKAN_WSI_LAYER_EXPERIMENTAL
, present_timing_enabled { true } , present_timing_enabled { true }
, present_mode_fifo_latest_ready_enabled { false }
#endif #endif
/* clang-format on */ /* clang-format on */
{ {
@ -643,6 +644,11 @@ bool device_private_data::is_present_wait_enabled()
{ {
return 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 #endif
} /* namespace layer */ } /* namespace layer */

View file

@ -897,6 +897,15 @@ public:
*/ */
bool is_present_id_enabled(); 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. * @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. * @brief Stores whether the device has enabled support for the present timing features.
*/ */
bool present_timing_enabled{ false }; 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 #endif
}; };

View file

@ -56,15 +56,25 @@ void surface_properties::populate_present_mode_compatibilities()
present_mode_compatibility{ present_mode_compatibility{
VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, 1, { VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR } }, VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, 1, { VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR } },
present_mode_compatibility{ 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 = m_compatible_present_modes =
compatible_present_modes<compatible_present_modes_list.size()>(compatible_present_modes_list); compatible_present_modes<compatible_present_modes_list.size()>(compatible_present_modes_list);
} }
surface_properties::surface_properties() surface_properties::surface_properties()
: m_supported_modes({ VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_FIFO_RELAXED_KHR, : m_supported_modes({
VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR }) 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(); populate_present_mode_compatibilities();
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-2019, 2022-2024 Arm Limited. * Copyright (c) 2017-2019, 2022-2025 Arm Limited.
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@ -28,10 +28,19 @@
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include <wsi/surface_properties.hpp> #include <wsi/surface_properties.hpp>
#include <wsi/compatible_present_modes.hpp> #include <wsi/compatible_present_modes.hpp>
namespace wsi namespace wsi
{ {
namespace headless 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 class surface_properties : public wsi::surface_properties
{ {
@ -68,10 +77,10 @@ public:
private: private:
/* List of supported presentation modes */ /* List of supported presentation modes */
std::array<VkPresentModeKHR, 4> m_supported_modes; std::array<VkPresentModeKHR, PRESENT_MODES_NUM> m_supported_modes;
/* Stores compatible presentation modes */ /* Stores compatible presentation modes */
compatible_present_modes<4> m_compatible_present_modes; compatible_present_modes<PRESENT_MODES_NUM> m_compatible_present_modes;
void populate_present_mode_compatibilities() override; void populate_present_mode_compatibilities() override;

View file

@ -53,17 +53,28 @@ namespace wayland
void surface_properties::populate_present_mode_compatibilities() void surface_properties::populate_present_mode_compatibilities()
{ {
std::array<present_mode_compatibility, 2> 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_FIFO_KHR, 1, { VK_PRESENT_MODE_FIFO_KHR } },
present_mode_compatibility{ VK_PRESENT_MODE_MAILBOX_KHR, 1, { VK_PRESENT_MODE_MAILBOX_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.size()>(compatible_present_modes_list);
} }
surface_properties::surface_properties(surface *wsi_surface, const util::allocator &allocator) surface_properties::surface_properties(surface *wsi_surface, const util::allocator &allocator)
: specific_surface(wsi_surface) : specific_surface(wsi_surface)
, supported_formats(allocator) , 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(); populate_present_mode_compatibilities();
} }
@ -242,7 +253,6 @@ VkResult surface_properties::get_surface_present_modes(VkPhysicalDevice physical
{ {
UNUSED(physical_device); UNUSED(physical_device);
UNUSED(surface); UNUSED(surface);
return get_surface_present_modes_common(pPresentModeCount, pPresentModes, m_supported_modes); return get_surface_present_modes_common(pPresentModeCount, pPresentModes, m_supported_modes);
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-2019, 2021-2024 Arm Limited. * Copyright (c) 2017-2019, 2021-2025 Arm Limited.
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@ -32,7 +32,14 @@ namespace wsi
{ {
namespace wayland 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 struct surface_format_properties_hasher
{ {
size_t operator()(const VkFormat &format) const size_t operator()(const VkFormat &format) const
@ -88,10 +95,10 @@ private:
surface_format_properties_map supported_formats; surface_format_properties_map supported_formats;
/* List of supported presentation modes */ /* List of supported presentation modes */
std::array<VkPresentModeKHR, 2> m_supported_modes; std::array<VkPresentModeKHR, PRESENT_MODES_NUM> m_supported_modes;
/* Stores compatible presentation modes */ /* Stores compatible presentation modes */
compatible_present_modes<2> m_compatible_present_modes; compatible_present_modes<PRESENT_MODES_NUM> m_compatible_present_modes;
void populate_present_mode_compatibilities() override; void populate_present_mode_compatibilities() override;

View file

@ -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 * When VK_PRESENT_MODE_MAILBOX_KHR or VK_PRESENT_MODE_FIFO_LATEST_READY_EXT has
* initialize the page flip thread so the present_image function can be called * been chosen by the application we don't initialize the page flip thread
* during vkQueuePresent. * so the present_image function can be called during vkQueuePresent.
*/ */
use_presentation_thread = use_presentation_thread = WAYLAND_FIFO_PRESENTATION_THREAD_ENABLED
WAYLAND_FIFO_PRESENTATION_THREAD_ENABLED && (m_present_mode != VK_PRESENT_MODE_MAILBOX_KHR); #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 #if VULKAN_WSI_LAYER_EXPERIMENTAL
auto present_wait = get_swapchain_extension<wsi_ext_present_wait_wayland>(); auto present_wait = get_swapchain_extension<wsi_ext_present_wait_wayland>();

View file

@ -302,5 +302,4 @@ void set_swapchain_maintenance1_state(VkPhysicalDevice physicalDevice,
} }
} }
} }
} // namespace wsi } // namespace wsi

View file

@ -136,5 +136,4 @@ PFN_vkVoidFunction get_proc_addr(const char *name, const layer::instance_private
*/ */
void set_swapchain_maintenance1_state( void set_swapchain_maintenance1_state(
VkPhysicalDevice physicalDevice, VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT *swapchain_maintenance1_features); VkPhysicalDevice physicalDevice, VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT *swapchain_maintenance1_features);
} // namespace wsi } // namespace wsi