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