From bf285c3be99e13f26b8d4c5c3b71a0e6aff7899b Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Wed, 19 Jun 2024 10:02:44 -0500 Subject: [PATCH] vulkan/wsi: Add basic support for PresentWait2 Add common code for PresentWait2. Unlike PresentWait, PresentWait2 is exposed by a surface capability. On Wayland, PresentWait (and PresentWait2) require the presentation-time extension to be available for a proper implementation, but not all compositors support this. PresentWait would either have to be exposed nowhere, or have weird/complicated fallback paths to try to enable it on systems where presentation-time is unavailable. Since PresentWait2 has a surface capability, we can simply not expose it on Wayland when present-time is unavailable instead of always having to have a less compliant fallback path. PresentWait2 also explicitly forbids waiting on an ID that hasn't been queued for presentation, so we don't need to handle that weird case. Signed-off-by: Derek Foreman Part-of: --- src/vulkan/wsi/wsi_common.c | 15 +++++++++++++++ src/vulkan/wsi/wsi_common_private.h | 3 +++ 2 files changed, 18 insertions(+) diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c index 8276717290b..a71011ed545 100644 --- a/src/vulkan/wsi/wsi_common.c +++ b/src/vulkan/wsi/wsi_common.c @@ -1383,6 +1383,8 @@ wsi_common_queue_present(const struct wsi_device *wsi, vk_find_struct_const(pPresentInfo->pNext, PRESENT_REGIONS_KHR); const VkPresentIdKHR *present_ids = vk_find_struct_const(pPresentInfo->pNext, PRESENT_ID_KHR); + const VkPresentId2KHR *present_ids2 = + vk_find_struct_const(pPresentInfo->pNext, PRESENT_ID_2_KHR); const VkSwapchainPresentFenceInfoEXT *present_fence_info = vk_find_struct_const(pPresentInfo->pNext, SWAPCHAIN_PRESENT_FENCE_INFO_EXT); const VkSwapchainPresentModeInfoEXT *present_mode_info = @@ -1574,6 +1576,10 @@ wsi_common_queue_present(const struct wsi_device *wsi, uint64_t present_id = 0; if (present_ids && present_ids->pPresentIds) present_id = present_ids->pPresentIds[i]; + if (present_ids2 && present_ids2->pPresentIds) { + assert(present_id == 0); + present_id = present_ids2->pPresentIds[i]; + } VkFence present_fence = VK_NULL_HANDLE; if (present_fence_info && present_fence_info->pFences) present_fence = present_fence_info->pFences[i]; @@ -2341,6 +2347,15 @@ wsi_WaitForPresentKHR(VkDevice device, VkSwapchainKHR _swapchain, return swapchain->wait_for_present(swapchain, presentId, timeout); } +VKAPI_ATTR VkResult VKAPI_CALL +wsi_WaitForPresent2KHR(VkDevice device, VkSwapchainKHR _swapchain, + const VkPresentWait2InfoKHR *info) +{ + VK_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain); + assert(swapchain->wait_for_present2); + return swapchain->wait_for_present2(swapchain, info->presentId, info->timeout); +} + VkImageUsageFlags wsi_caps_get_image_usage(void) { diff --git a/src/vulkan/wsi/wsi_common_private.h b/src/vulkan/wsi/wsi_common_private.h index 51bfa77d4b2..e11f0058a99 100644 --- a/src/vulkan/wsi/wsi_common_private.h +++ b/src/vulkan/wsi/wsi_common_private.h @@ -220,6 +220,9 @@ struct wsi_swapchain { VkResult (*wait_for_present)(struct wsi_swapchain *swap_chain, uint64_t present_id, uint64_t timeout); + VkResult (*wait_for_present2)(struct wsi_swapchain *swap_chain, + uint64_t present_id, + uint64_t timeout); VkResult (*release_images)(struct wsi_swapchain *swap_chain, uint32_t count, const uint32_t *indices);