Merge 'Implement vkWaitForPresent2KHR' into 'main'

See merge request mesa/vulkan-wsi-layer!194
This commit is contained in:
Rosen Zhelev 2025-08-28 15:46:50 +01:00
commit 6baf6ff52a
15 changed files with 112 additions and 36 deletions

View file

@ -673,10 +673,19 @@ wsi_layer_vkGetDeviceProcAddr(VkDevice device, const char *funcName) VWL_API_POS
{
GET_PROC_ADDR(vkReleaseSwapchainImagesEXT);
}
/* VK_KHR_present_wait */
if (device_data.is_device_extension_enabled(VK_KHR_PRESENT_WAIT_EXTENSION_NAME))
{
GET_PROC_ADDR(vkWaitForPresentKHR);
}
#if VULKAN_WSI_LAYER_EXPERIMENTAL
/* VK_KHR_present_wait2 */
if (device_data.is_device_extension_enabled(VK_KHR_PRESENT_WAIT_2_EXTENSION_NAME))
{
GET_PROC_ADDR(vkWaitForPresent2KHR);
}
#endif
return device_data.disp.get_user_enabled_entrypoint(device, funcName);
}

View file

@ -34,7 +34,7 @@
#include "present_wait_api.hpp"
/**
* @brief Implements vkSetSwapchainPresentTimingQueueSizeEXT Vulkan entrypoint.
* @brief Implements vkWaitForPresentKHR Vulkan entrypoint.
*/
VWL_VKAPI_CALL(VkResult)
wsi_layer_vkWaitForPresentKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t present_id,
@ -51,5 +51,32 @@ wsi_layer_vkWaitForPresentKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_
auto *sc = reinterpret_cast<wsi::swapchain_base *>(swapchain);
auto *ext = sc->get_swapchain_extension<wsi::wsi_ext_present_wait>(true);
assert(!ext->is_present_wait2());
return ext->wait_for_present_id(present_id, timeout);
}
#if VULKAN_WSI_LAYER_EXPERIMENTAL
/**
* @brief Implements vkWaitForPresent2KHR Vulkan entrypoint.
*/
VWL_VKAPI_CALL(VkResult)
wsi_layer_vkWaitForPresent2KHR(VkDevice device, VkSwapchainKHR swapchain,
const VkPresentWait2InfoKHR *pPresentWait2Info) VWL_API_POST
{
assert(swapchain != VK_NULL_HANDLE);
auto &device_data = layer::device_private_data::get(device);
if (!device_data.layer_owns_swapchain(swapchain))
{
return device_data.disp.WaitForPresent2KHR(device, swapchain, pPresentWait2Info);
}
auto *sc = reinterpret_cast<wsi::swapchain_base *>(swapchain);
auto *ext = sc->get_swapchain_extension<wsi::wsi_ext_present_wait>(true);
assert(ext->is_present_wait2());
return ext->wait_for_present_id(pPresentWait2Info->presentId, pPresentWait2Info->timeout);
}
#endif

View file

@ -33,3 +33,9 @@
VWL_VKAPI_CALL(VkResult)
wsi_layer_vkWaitForPresentKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t present_id,
uint64_t timeout) VWL_API_POST;
#if VULKAN_WSI_LAYER_EXPERIMENTAL
VWL_VKAPI_CALL(VkResult)
wsi_layer_vkWaitForPresent2KHR(VkDevice device, VkSwapchainKHR swapchain,
const VkPresentWait2InfoKHR *pPresentWait2Info) VWL_API_POST;
#endif

View file

@ -384,7 +384,9 @@ private:
EP(GetSwapchainTimeDomainPropertiesEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \
EP(GetSwapchainTimingPropertiesEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \
EP(SetSwapchainPresentTimingQueueSizeEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \
EP(GetPastPresentationTimingEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, )
EP(GetPastPresentationTimingEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \
/* VK_KHR_present_wait2 */ \
EP(WaitForPresent2KHR, VK_KHR_PRESENT_WAIT_2_EXTENSION_NAME, API_VERSION_MAX, false, )
#else
#define DEVICE_ENTRYPOINTS_LIST_EXPERIMENTAL(EP)
#endif

View file

@ -35,8 +35,8 @@ namespace wsi
namespace display
{
wsi_ext_present_wait_display::wsi_ext_present_wait_display(wsi_ext_present_id &present_id_extension)
: wsi_ext_present_wait(present_id_extension)
wsi_ext_present_wait_display::wsi_ext_present_wait_display(wsi_ext_present_id &present_id_extension, bool present_wait2)
: wsi_ext_present_wait(present_id_extension, present_wait2)
{
}

View file

@ -51,10 +51,11 @@ public:
* @brief Constructs present ID class.
*
* @param present_id_extension Present ID extension that this class will use to query
* the last delivered present ID for the swapchain. This extension pointer must outlive
* this class.
* the last delivered present ID for the swapchain. This extension pointer must outlive
* this class.
* @param present_wait2 Indication for using/not using the Present Wait2 extension.
*/
wsi_ext_present_wait_display(wsi_ext_present_id &present_id_extension);
wsi_ext_present_wait_display(wsi_ext_present_id &present_id_extension, bool present_wait2);
private:
/**

View file

@ -102,15 +102,19 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr
}
}
if (m_device_data.is_present_wait_enabled()
bool present_wait2;
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|| (swapchain_create_info->flags &
(VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR | VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR))
constexpr VkSwapchainCreateFlagsKHR present_wait2_mask =
(VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR | VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR);
present_wait2 = (swapchain_create_info->flags & present_wait2_mask) == present_wait2_mask;
#else
present_wait2 = false;
#endif
)
if (m_device_data.is_present_wait_enabled() || present_wait2)
{
if (!add_swapchain_extension(
m_allocator.make_unique<wsi_ext_present_wait_display>(*get_swapchain_extension<wsi_ext_present_id>(true))))
if (!add_swapchain_extension(m_allocator.make_unique<wsi_ext_present_wait_display>(
*get_swapchain_extension<wsi_ext_present_id>(true), present_wait2)))
{
return VK_ERROR_OUT_OF_HOST_MEMORY;
}

View file

@ -34,8 +34,9 @@
namespace wsi
{
wsi_ext_present_wait::wsi_ext_present_wait(wsi_ext_present_id &present_id_extension)
wsi_ext_present_wait::wsi_ext_present_wait(wsi_ext_present_id &present_id_extension, bool present_wait2)
: m_present_id_ext(present_id_extension)
, m_present_wait2(present_wait2)
{
}

View file

@ -58,8 +58,9 @@ public:
* @param present_id_extension Present ID extension that this class will use to query
* the last delivered present ID for the swapchain. This extension pointer must outlive
* this class.
* @param present_wait2 Indication for using/not using the Present Wait2 extension.
*/
wsi_ext_present_wait(wsi_ext_present_id &present_id_extension);
wsi_ext_present_wait(wsi_ext_present_id &present_id_extension, bool present_wait2);
/**
* @brief Waits for present ID to be updated.
@ -71,6 +72,14 @@ public:
*/
VkResult wait_for_present_id(uint64_t present_id, uint64_t timeout_in_ns);
/**
* @brief Getter for the present_wait2.
*/
bool is_present_wait2() const
{
return m_present_wait2;
};
protected:
/**
* @brief Backend specific implementation that will wait for the present ID to
@ -86,6 +95,12 @@ protected:
* @brief Present ID extension pointer.
*/
wsi_ext_present_id &m_present_id_ext;
private:
/**
* @brief Present Wait2 indication.
*/
bool m_present_wait2{ false };
};
} /* namespace wsi */

View file

@ -35,8 +35,9 @@ namespace wsi
namespace headless
{
wsi_ext_present_wait_headless::wsi_ext_present_wait_headless(wsi_ext_present_id &present_id_extension)
: wsi_ext_present_wait(present_id_extension)
wsi_ext_present_wait_headless::wsi_ext_present_wait_headless(wsi_ext_present_id &present_id_extension,
bool present_wait2)
: wsi_ext_present_wait(present_id_extension, present_wait2)
{
}

View file

@ -51,10 +51,11 @@ public:
* @brief Constructs present ID class.
*
* @param present_id_extension Present ID extension that this class will use to query
* the last delivered present ID for the swapchain. This extension pointer must outlive
* this class.
* the last delivered present ID for the swapchain. This extension pointer must outlive
* this class.
* @param present_wait2 Indication for using/not using the Present Wait2 extension.
*/
wsi_ext_present_wait_headless(wsi_ext_present_id &present_id_extension);
wsi_ext_present_wait_headless(wsi_ext_present_id &present_id_extension, bool present_wait2);
private:
/**

View file

@ -109,15 +109,19 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr
}
#endif
if (m_device_data.is_present_wait_enabled()
bool present_wait2;
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|| (swapchain_create_info->flags &
(VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR | VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR))
constexpr VkSwapchainCreateFlagsKHR present_wait2_mask =
(VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR | VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR);
present_wait2 = (swapchain_create_info->flags & present_wait2_mask) == present_wait2_mask;
#else
present_wait2 = false;
#endif
)
if (m_device_data.is_present_wait_enabled() || present_wait2)
{
if (!add_swapchain_extension(m_allocator.make_unique<wsi_ext_present_wait_headless>(
*get_swapchain_extension<wsi_ext_present_id>(true))))
*get_swapchain_extension<wsi_ext_present_id>(true), present_wait2)))
{
return VK_ERROR_OUT_OF_HOST_MEMORY;
}

View file

@ -38,8 +38,8 @@ namespace wsi
namespace wayland
{
wsi_ext_present_wait_wayland::wsi_ext_present_wait_wayland(wsi_ext_present_id &present_id_extension)
: wsi_ext_present_wait(present_id_extension)
wsi_ext_present_wait_wayland::wsi_ext_present_wait_wayland(wsi_ext_present_id &present_id_extension, bool present_wait2)
: wsi_ext_present_wait(present_id_extension, present_wait2)
{
}

View file

@ -52,10 +52,11 @@ public:
* @brief Constructs present ID class.
*
* @param present_id_extension Present ID extension that this class will use to query
* the last delivered present ID for the swapchain. This extension pointer must outlive
* this class.
* the last delivered present ID for the swapchain. This extension pointer must outlive
* this class.
* @param present_wait2 Indication for using/not using the Present Wait2 extension.
*/
wsi_ext_present_wait_wayland(wsi_ext_present_id &present_id_extension);
wsi_ext_present_wait_wayland(wsi_ext_present_id &present_id_extension, bool present_wait2);
/**
* @brief Set the wayland dispatch object.

View file

@ -113,15 +113,19 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr
}
}
if (m_device_data.is_present_wait_enabled()
bool present_wait2;
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|| (swapchain_create_info->flags &
(VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR | VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR))
constexpr VkSwapchainCreateFlagsKHR present_wait2_mask =
(VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR | VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR);
present_wait2 = (swapchain_create_info->flags & present_wait2_mask) == present_wait2_mask;
#else
present_wait2 = false;
#endif
)
if (m_device_data.is_present_wait_enabled() || present_wait2)
{
if (!add_swapchain_extension(
m_allocator.make_unique<wsi_ext_present_wait_wayland>(*get_swapchain_extension<wsi_ext_present_id>(true))))
if (!add_swapchain_extension(m_allocator.make_unique<wsi_ext_present_wait_wayland>(
*get_swapchain_extension<wsi_ext_present_id>(true), present_wait2)))
{
return VK_ERROR_OUT_OF_HOST_MEMORY;
}