Mesa (main): vulkan/wsi/x11: Ensure we have the required number of images for acquire.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun May 8 16:04:46 UTC 2022


Module: Mesa
Branch: main
Commit: a7f44b626943642e0cc0d132dd80aa820a45749f
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a7f44b626943642e0cc0d132dd80aa820a45749f

Author: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Date:   Wed Feb 23 02:27:46 2022 +0100

vulkan/wsi/x11: Ensure we have the required number of images for acquire.

For games that needs >1 at the same time the existing check wasn't enough.

Cc: mesa-stable
Reviewed-by: Hans-Kristian Arntzen <post at arntzen-software.no>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15132>

---

 src/vulkan/wsi/wsi_common_x11.c | 39 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 37 insertions(+), 2 deletions(-)

diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
index 099735dd9f3..1fc44ea79e7 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
@@ -612,7 +612,7 @@ x11_surface_get_support(VkIcdSurfaceBase *icd_surface,
 }
 
 static uint32_t
-x11_get_min_image_count(struct wsi_device *wsi_device)
+x11_get_min_image_count(const struct wsi_device *wsi_device)
 {
    if (wsi_device->x11.override_minImageCount)
       return wsi_device->x11.override_minImageCount;
@@ -1431,6 +1431,17 @@ x11_needs_wait_for_fences(const struct wsi_device *wsi_device,
    }
 }
 
+/**
+ * The number of images that are not owned by X11:
+ *  (1) in the ownership of the app, or
+ *  (2) app to take ownership through an acquire, or
+ *  (3) in the present queue waiting for the FIFO thread to present to X11.
+ */
+static unsigned x11_driver_owned_images(const struct x11_swapchain *chain)
+{
+   return chain->base.image_count - chain->sent_image_count;
+}
+
 /**
  * Our queue manager. Albeit called x11_manage_fifo_queues only directly
  * manages the present-queue and does this in general in fifo and mailbox presentation
@@ -1502,12 +1513,36 @@ x11_manage_fifo_queues(void *state)
         xcb_generic_event_t *event = NULL;
         xcb_connection_t *conn = chain->conn;
 
+         /* Assume this isn't a swapchain where we force 5 images, because those
+          * don't end up with an acquire queue at the moment.
+          */
+         unsigned min_image_count = x11_get_min_image_count(chain->base.wsi);
+
+         /* With drirc overrides some games have swapchain with less than
+          * minimum number of images. */
+         min_image_count = MIN2(min_image_count, chain->base.image_count);
+
+         /* We always need to ensure that the app can have this number of images
+          * acquired concurrently in between presents:
+          * "VUID-vkAcquireNextImageKHR-swapchain-01802
+          *  If the number of currently acquired images is greater than the difference
+          *  between the number of images in swapchain and the value of
+          *  VkSurfaceCapabilitiesKHR::minImageCount as returned by a call to
+          *  vkGetPhysicalDeviceSurfaceCapabilities2KHR with the surface used to
+          *  create swapchain, timeout must not be UINT64_MAX"
+          */
+         unsigned forward_progress_guaranteed_acquired_images =
+            chain->base.image_count - min_image_count + 1;
+
          /* Wait for our presentation to occur and ensure we have at least one
           * image that can be acquired by the client afterwards. This ensures we
           * can pull on the present-queue on the next loop.
           */
          while (chain->images[image_index].present_queued ||
-                chain->sent_image_count == chain->base.image_count) {
+                /* If we have images in the present queue the outer loop won't block and a break
+                 * here would end up at this loop again, otherwise a break here satisfies
+                 * VUID-vkAcquireNextImageKHR-swapchain-01802 */
+                x11_driver_owned_images(chain) < forward_progress_guaranteed_acquired_images) {
 
             event = xcb_poll_for_special_event(conn, chain->special_event);
             if (event) {



More information about the mesa-commit mailing list