Module: Mesa
Branch: staging/23.0
Commit: b0489e6221d2daa2a9ff431d777706549dff6a71
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=b0489e6221d2daa2a9ff431d777706549dff6a71

Author: Hans-Kristian Arntzen <[email protected]>
Date:   Fri Apr 21 17:22:47 2023 +0200

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 <[email protected]>
Reviewed-by: Adam Jackson <[email protected]>
(cherry picked from commit 32f7ff2c204b28e6d312ecac6463f588d4d68f3e)

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22638>

---

 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 16b0c34b7e7..9d466e73f39 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
@@ -939,6 +939,7 @@ struct x11_image {
    int                                       shmid;
    uint8_t *                                 shmaddr;
    uint64_t                                  present_id;
+   uint64_t                                  signal_present_id;
 };
 
 struct x11_swapchain {
@@ -1010,8 +1011,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);
@@ -1035,6 +1036,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)

Reply via email to