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
