From 2beb0c8820587b272b72ecac0ba3733bc5b392df Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Fri, 29 May 2026 04:55:54 +0200 Subject: [PATCH] wsi/common: Allow VK_EXT_present_timing present without presentStageQueries. Spec allows to request a present at a specific target time or duration without actually storing + querying any present records about completion time. Iow. it allows VkPresentTimingInfoEXT.presentStageQueries == 0. In this case, skip allocation and processing of a timing history record, but still assign a VkPresentTimingInfoEXT.targetTime for timed present. Signed-off-by: Mario Kleiner Fixes: 47d69664d8f ("vulkan/wsi: Add common infrastructure for EXT_present_timing.") Reviewed-by: Hans-Kristian Arntzen Part-of: --- src/vulkan/wsi/wsi_common.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c index 59c44b89ae0..0616cea7f88 100644 --- a/src/vulkan/wsi/wsi_common.c +++ b/src/vulkan/wsi/wsi_common.c @@ -1549,6 +1549,13 @@ wsi_swapchain_present_timing_notify_completion(struct wsi_swapchain *chain, for (size_t i = 0; i < chain->present_timing.timings_count; i++) { if (chain->present_timing.timings[i].serial == timing_serial) { + /* Prevent re-processing old records if same timing_serial is passed in multiple times. This + * is prep for future work and a safe-guard that should not get hit in the current state of + * things. + */ + if (chain->present_timing.timings[i].complete) + break; + chain->present_timing.timings[i].complete_time = timestamp; chain->present_timing.timings[i].complete = VK_TRUE; @@ -2180,18 +2187,24 @@ wsi_common_queue_present(const struct wsi_device *wsi, for (uint32_t i = 0; i < present_timings_info->swapchainCount; i++) { const VkPresentTimingInfoEXT *info = &present_timings_info->pTimingInfos[i]; VK_FROM_HANDLE(wsi_swapchain, swapchain, pPresentInfo->pSwapchains[i]); - if (results[i] != VK_SUCCESS || !swapchain->set_timing_request || info->presentStageQueries == 0) + if (results[i] != VK_SUCCESS || !swapchain->set_timing_request) continue; assert(swapchain->present_timing.active); - uint32_t image_index = pPresentInfo->pImageIndices[i]; + /* Only alloc timing record if present timing feedback is requested. */ + if (info->presentStageQueries) { + uint32_t image_index = pPresentInfo->pImageIndices[i]; - /* EXT_present_timing is defined to only work with present_id2. - * It's only used when reporting back timings. */ - results[i] = wsi_common_allocate_timing_request( - swapchain, info, present_ids2 ? present_ids2->pPresentIds[i] : 0, - swapchain->get_wsi_image(swapchain, image_index)); + /* EXT_present_timing is defined to only work with present_id2. + * It's only used when reporting back timings. */ + results[i] = wsi_common_allocate_timing_request( + swapchain, info, present_ids2 ? present_ids2->pPresentIds[i] : 0, + swapchain->get_wsi_image(swapchain, image_index)); + } else { + /* Make sure it is non-zero / incrementing, to keep wsi backends happy. */ + ++swapchain->present_timing.serial; + } /* Application is responsible for allocating sufficient size here. * We fail with VK_ERROR_PRESENT_TIMING_QUEUE_FULL_EXT if application is bugged. */