From 36d5b58317179e5db32800743ef0faed4655b9fb Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Tue, 13 Jun 2023 16:55:45 -0400 Subject: [PATCH] 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 Reviewed-by: Adam Jackson Part-of: --- 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