From d15ff626f38fc0ea184b3da99c271ca033c9ba59 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Tue, 27 Jan 2026 18:37:02 +0200 Subject: [PATCH] vulkan/wsi/direct: remove VkDisplay created from GetDrmDisplayEXT on ReleaseDisplayEXT Signed-off-by: Lionel Landwerlin Cc: mesa-stable Reviewed-by: Emma Anholt (cherry picked from commit 1112c1461dcc4dc479c7e343c07ec4588898c097) Part-of: --- .pick_status.json | 2 +- src/vulkan/wsi/wsi_common_display.c | 41 ++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 6057b3c0ee9..156b8de8196 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -274,7 +274,7 @@ "description": "vulkan/wsi/direct: remove VkDisplay created from GetDrmDisplayEXT on ReleaseDisplayEXT", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c index d993d789ef3..d36733b43f7 100644 --- a/src/vulkan/wsi/wsi_common_display.c +++ b/src/vulkan/wsi/wsi_common_display.c @@ -170,6 +170,7 @@ typedef struct wsi_display_connector { char *name; bool connected; bool active; + bool imported; int refcount; /* swapchains using this connector */ struct list_head display_modes; wsi_display_mode *current_mode; @@ -617,7 +618,8 @@ wsi_display_is_crtc_available(const struct wsi_display * const wsi, static struct wsi_display_connector * wsi_display_alloc_connector(struct wsi_display *wsi, - uint32_t connector_id) + uint32_t connector_id, + bool imported) { struct wsi_display_connector *connector = vk_zalloc(wsi->alloc, sizeof (struct wsi_display_connector), @@ -628,6 +630,7 @@ wsi_display_alloc_connector(struct wsi_display *wsi, connector->id = connector_id; connector->wsi = wsi; connector->active = false; + connector->imported = imported; /* XXX use EDID name */ connector->name = "monitor"; list_inithead(&connector->display_modes); @@ -635,6 +638,17 @@ wsi_display_alloc_connector(struct wsi_display *wsi, return connector; } +static void +wsi_display_free_connector(struct wsi_display *wsi, + struct wsi_display_connector *connector) +{ + wsi_for_each_display_mode(mode, connector) { + vk_free(wsi->alloc, mode); + } + vk_free(wsi->alloc, connector->formats); + vk_free(wsi->alloc, connector); +} + static struct wsi_display_connector * wsi_display_get_connector(struct wsi_device *wsi_device, int drm_fd, @@ -664,7 +678,7 @@ wsi_display_get_connector(struct wsi_device *wsi_device, wsi_display_find_connector(wsi_device, connector_id); if (!connector) { - connector = wsi_display_alloc_connector(wsi, connector_id); + connector = wsi_display_alloc_connector(wsi, connector_id, drm_fd != wsi->fd); if (!connector) { drmModeFreeConnector(drm_connector); return NULL; @@ -3279,13 +3293,8 @@ wsi_display_finish_wsi(struct wsi_device *wsi_device, (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY]; if (wsi) { - wsi_for_each_connector(connector, wsi) { - wsi_for_each_display_mode(mode, connector) { - vk_free(wsi->alloc, mode); - } - vk_free(wsi->alloc, connector->formats); - vk_free(wsi->alloc, connector); - } + wsi_for_each_connector(connector, wsi) + wsi_display_free_connector(wsi, connector); wsi_display_stop_wait_thread(wsi); @@ -3321,12 +3330,20 @@ wsi_ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, wsi->fd = -1; } - wsi_display_connector_from_handle(display)->active = false; + struct wsi_display_connector *connector = + wsi_display_connector_from_handle(display); + + connector->active = false; #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT - wsi_display_connector_from_handle(display)->output = None; + connector->output = None; #endif + if (connector->imported) { + list_del(&connector->list); + wsi_display_free_connector(wsi, connector); + } + return VK_SUCCESS; } @@ -3620,7 +3637,7 @@ wsi_display_get_output(struct wsi_device *wsi_device, connector = wsi_display_find_connector(wsi_device, connector_id); if (connector == NULL) { - connector = wsi_display_alloc_connector(wsi, connector_id); + connector = wsi_display_alloc_connector(wsi, connector_id, false); if (!connector) { return NULL; }