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

Author: Mike Blumenkrantz <[email protected]>
Date:   Tue Jun 13 16:55:45 2023 -0400

vk/wsi/x11: handle geometry updating more asynchronously

this uses geometry updates from events when possible in order to avoid
roundtripping during vkGetPhysicalDeviceSurfaceCapabilitiesKHR, which
significantly improves wsi performance in severely bottlenecked scenarios

now that roundtripping is completely eliminated from acquires in most scenarios,
this improves acquire perf by 10%+

Acked-by: Daniel Stone <[email protected]>
Reviewed-by: Adam Jackson <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23835>

---

 src/vulkan/wsi/wsi_common_x11.c | 44 ++++++++++++++++++++++++++++-------------
 1 file changed, 30 insertions(+), 14 deletions(-)

diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
index d74362d0548..697868d4d98 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
@@ -91,6 +91,8 @@ struct wsi_x11_vk_surface {
       VkIcdSurfaceXlib xlib;
       VkIcdSurfaceXcb xcb;
    };
+   VkExtent2D extent;
+   bool changed;
    bool has_alpha;
 };
 
@@ -688,25 +690,28 @@ x11_surface_get_capabilities(VkIcdSurfaceBase 
*icd_surface,
    struct wsi_x11_vk_surface *surface = (struct 
wsi_x11_vk_surface*)icd_surface;
    struct wsi_x11_connection *wsi_conn =
       wsi_x11_get_connection(wsi_device, conn);
-   xcb_get_geometry_cookie_t geom_cookie;
-   xcb_generic_error_t *err;
-   xcb_get_geometry_reply_t *geom;
 
-   geom_cookie = xcb_get_geometry(conn, window);
+   if (surface->changed) {
+      surface->changed = false;
+      xcb_get_geometry_cookie_t geom_cookie = xcb_get_geometry(conn, window);
+      xcb_get_geometry_reply_t *geom;
+
+      geom = xcb_get_geometry_reply(conn, geom_cookie, NULL);
+      if (!geom)
+         return VK_ERROR_SURFACE_LOST_KHR;
 
-   geom = xcb_get_geometry_reply(conn, geom_cookie, &err);
-   if (!geom)
-      return VK_ERROR_SURFACE_LOST_KHR;
-   {
       VkExtent2D extent = { geom->width, geom->height };
       caps->currentExtent = extent;
       caps->minImageExtent = extent;
       caps->maxImageExtent = extent;
+      surface->extent = extent;
+
+      free(geom);
+   } else {
+      caps->currentExtent = surface->extent;
+      caps->minImageExtent = surface->extent;
+      caps->maxImageExtent = surface->extent;
    }
-   free(err);
-   free(geom);
-   if (!geom)
-       return VK_ERROR_SURFACE_LOST_KHR;
 
    if (surface->has_alpha) {
       caps->supportedCompositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR |
@@ -984,6 +989,7 @@ wsi_CreateXcbSurfaceKHR(VkInstance _instance,
    surface->xcb.window = pCreateInfo->window;
 
    surface->has_alpha = visual_has_alpha(visual, visual_depth);
+   surface->changed = true;
 
    *pSurface = VkIcdSurfaceBase_to_handle(&surface->xcb.base);
    return VK_SUCCESS;
@@ -1016,6 +1022,7 @@ wsi_CreateXlibSurfaceKHR(VkInstance _instance,
    surface->xlib.window = pCreateInfo->window;
 
    surface->has_alpha = visual_has_alpha(visual, visual_depth);
+   surface->changed = true;
 
    *pSurface = VkIcdSurfaceBase_to_handle(&surface->xlib.base);
    return VK_SUCCESS;
@@ -1098,6 +1105,8 @@ struct x11_swapchain {
    /* Total number of images returned to application in AcquireNextImage. */
    uint64_t                                     present_poll_acquire_count;
 
+   struct wsi_x11_vk_surface                   *surface;
+
    struct x11_image                             images[0];
 };
 VK_DEFINE_NONDISP_HANDLE_CASTS(x11_swapchain, base.base, VkSwapchainKHR,
@@ -1229,8 +1238,11 @@ x11_handle_dri3_present_event(struct x11_swapchain 
*chain,
          return VK_ERROR_SURFACE_LOST_KHR;
 
       if (config->width != chain->extent.width ||
-          config->height != chain->extent.height)
+          config->height != chain->extent.height) {
+         chain->surface->extent.width = config->width;
+         chain->surface->extent.height = config->height;
          return VK_SUBOPTIMAL_KHR;
+      }
 
       break;
    }
@@ -2754,13 +2766,17 @@ x11_surface_create_swapchain(VkIcdSurfaceBase 
*icd_surface,
    chain->status = VK_SUCCESS;
    chain->has_dri3_modifiers = wsi_conn->has_dri3_modifiers;
    chain->has_mit_shm = wsi_conn->has_mit_shm;
+   chain->surface = (struct wsi_x11_vk_surface*)icd_surface;
+   chain->surface->extent = pCreateInfo->imageExtent;
 
    /* When images in the swapchain don't fit the window, X can still present 
them, but it won't
     * happen by flip, only by copy. So this is a suboptimal copy, because if 
the client would change
     * the chain extents X may be able to flip
     */
-   if (chain->extent.width != cur_width || chain->extent.height != cur_height)
+   if (chain->extent.width != cur_width || chain->extent.height != cur_height) 
{
        chain->status = VK_SUBOPTIMAL_KHR;
+       chain->surface->changed = true;
+   }
 
    /* On a new swapchain this helper variable is set to false. Once we present 
it will have an
     * impact once we ever do at least one flip and go back to copying 
afterwards. It is presumed

Reply via email to