From 32f7ff2c204b28e6d312ecac6463f588d4d68f3e Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Fri, 21 Apr 2023 17:22:47 +0200 Subject: [PATCH] wsi/x11: Fix present ID signal when IDLE comes before COMPLETE. It appears to be possible that IDLE is observed before COMPLETE. In this case, an application may access present_id in subsequent QueuePresentKHR and race against the fence worker reading present_id. Solve this by adding a separate signal_present_id that is used when completing to avoid the race. Signed-off-by: Hans-Kristian Arntzen Reviewed-by: Adam Jackson Part-of: --- src/vulkan/wsi/wsi_common_x11.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 2ca68e5baa0..3c0dad260b3 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -1008,6 +1008,7 @@ struct x11_image { int shmid; uint8_t * shmaddr; uint64_t present_id; + uint64_t signal_present_id; }; struct x11_swapchain { @@ -1079,8 +1080,8 @@ static void x11_present_complete(struct x11_swapchain *swapchain, { if (image->present_id) { pthread_mutex_lock(&swapchain->present_progress_mutex); - if (image->present_id > swapchain->present_id) { - swapchain->present_id = image->present_id; + if (image->signal_present_id > swapchain->present_id) { + swapchain->present_id = image->signal_present_id; pthread_cond_broadcast(&swapchain->present_progress_cond); } pthread_mutex_unlock(&swapchain->present_progress_mutex); @@ -1104,6 +1105,11 @@ static void x11_notify_pending_present(struct x11_swapchain *swapchain, pthread_cond_broadcast(&swapchain->present_progress_cond); pthread_mutex_unlock(&swapchain->present_progress_mutex); } + + /* It is possible that an IDLE is observed before PRESENT_COMPLETE when + * not flipping. In this case, reading image->present_id might be a race + * in the FIFO management thread. */ + image->signal_present_id = image->present_id; } static void x11_swapchain_notify_error(struct x11_swapchain *swapchain, VkResult result)