wsi/x11: Fix present ID signal when IDLE comes before COMPLETE.
authorHans-Kristian Arntzen <post@arntzen-software.no>
Fri, 21 Apr 2023 15:22:47 +0000 (17:22 +0200)
committerMarge Bot <emma+marge@anholt.net>
Fri, 21 Apr 2023 19:15:06 +0000 (19:15 +0000)
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 <post@arntzen-software.no>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22633>

src/vulkan/wsi/wsi_common_x11.c

index 2ca68e5..3c0dad2 100644 (file)
@@ -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)