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 <daniels@collabora.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23835>
This commit is contained in:
Mike Blumenkrantz
2023-06-13 16:55:45 -04:00
committed by Marge Bot
parent fb9f697fbb
commit 36d5b58317

View File

@@ -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