From 0c2dbb646847391548ec2b562092fe6e5dcea5e2 Mon Sep 17 00:00:00 2001 From: Emma Anholt Date: Thu, 22 Jan 2026 12:13:11 -0800 Subject: [PATCH 1/2] vulkan/wsi/display: Don't re-probe connectors in between hotplugs. The state we return is a single plane per connector, and (effectively) whether we're currently presenting on it. We already know what connectors we're presenting on, and there's no reason to re-probe for hotplugged connectors here to learn that they're not active -- vkGetPhysicalDeviceDisplayProperties2KHR() is what you'd need to do to get far more important information about the connector in the first place. Running dEQP-VK.wsi.direct_drm.maintenance1.present\* on my CFL goes from 5.5s to 4.4s due to not re-probing EDID over and over. --- src/vulkan/wsi/wsi_common_display.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c index f72e85c5e66..e411b400df0 100644 --- a/src/vulkan/wsi/wsi_common_display.c +++ b/src/vulkan/wsi/wsi_common_display.c @@ -224,6 +224,9 @@ struct wsi_display { pthread_t hotplug_thread; struct list_head connectors; /* list of all discovered connectors */ + /* Flag that we've called wsi_get_connectors() with the current fd. + */ + bool get_connectors_current; /* A unique monotonically increasing value to associate with an individual * colorimetry outcome on the output. This is used to avoid propagating @@ -864,7 +867,7 @@ wsi_get_connectors(VkPhysicalDevice physicalDevice) struct wsi_display *wsi = (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY]; - if (wsi->fd < 0) + if (wsi->fd < 0 || wsi->get_connectors_current) return VK_SUCCESS; drmModeResPtr mode_res = drmModeGetResources(wsi->fd); @@ -883,6 +886,8 @@ wsi_get_connectors(VkPhysicalDevice physicalDevice) } } + wsi->get_connectors_current = true; + drmModeFreeResources(mode_res); return VK_SUCCESS; } @@ -3480,6 +3485,7 @@ udev_event_listener_thread(void *data) * and wsi_display_wait_for_event. */ mtx_lock(&wsi->wait_mutex); + wsi->get_connectors_current = false; u_cnd_monotonic_broadcast(&wsi->hotplug_cond); list_for_each_entry(struct wsi_display_fence, fence, &wsi_device->hotplug_fences, link) { @@ -3641,6 +3647,7 @@ wsi_ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, if (wsi->fd != wsi->device_fd) close(wsi->fd); wsi->fd = wsi->device_fd; + wsi->get_connectors_current = false; } struct wsi_display_connector *connector = From a20c01ea2011db450062d7e14893e43001c4a9e9 Mon Sep 17 00:00:00 2001 From: Emma Anholt Date: Thu, 22 Jan 2026 12:37:20 -0800 Subject: [PATCH 2/2] vulkan/wsi/display: Check with an atomic commit if the swapchain fails. The TEST_ONLY flag lets you run your display configuration past the driver to see if it exceeds any of the many arbitrary hardware limits that can't be expressed through the limited properties that DRM exposes. This maps quite well to VK_ERROR_INITIALIZATION_FAILED. Fixes dEQP-VK.wsi.direct_drm.colorspace.basic failure on my anv CFL system, where we exceeded the primary plane's width restriction for the specific tiling format chosen. Closes: #14314 --- src/amd/ci/radv-gfx1201-fails.txt | 12 ---------- src/amd/ci/radv-raven-fails.txt | 3 --- src/amd/ci/radv-renoir-fails.txt | 30 ++++--------------------- src/amd/ci/radv-stoney-fails.txt | 3 --- src/amd/ci/radv-vangogh-fails.txt | 24 -------------------- src/vulkan/wsi/wsi_common_display.c | 35 ++++++++++++++++++++++++++--- 6 files changed, 36 insertions(+), 71 deletions(-) diff --git a/src/amd/ci/radv-gfx1201-fails.txt b/src/amd/ci/radv-gfx1201-fails.txt index a684826774e..f036ab8276c 100644 --- a/src/amd/ci/radv-gfx1201-fails.txt +++ b/src/amd/ci/radv-gfx1201-fails.txt @@ -106,18 +106,6 @@ dEQP-VK.sparse_resources.shader_intrinsics.2d_sparse_read.r12x4g12x4_unorm_2pack dEQP-VK.wsi.direct_drm.colorspace.basic,Fail dEQP-VK.wsi.direct_drm.colorspace.hdr,Fail -dEQP-VK.wsi.direct_drm.incremental_present.scale_none.fifo.identity.opaque.incremental_present,Fail -dEQP-VK.wsi.direct_drm.incremental_present.scale_none.fifo.identity.opaque.reference,Fail -dEQP-VK.wsi.direct_drm.maintenance1.deferred_alloc.fifo.basic,Fail -dEQP-VK.wsi.direct_drm.maintenance1.deferred_alloc.fifo.bind_image,Fail -dEQP-VK.wsi.direct_drm.maintenance1.present_fence.fifo.basic,Fail -dEQP-VK.wsi.direct_drm.maintenance1.present_fence.fifo.ordering,Fail -dEQP-VK.wsi.direct_drm.maintenance1.present_modes.fifo.change_modes,Fail -dEQP-VK.wsi.direct_drm.maintenance1.release_images.fifo.no_scaling.basic,Fail -dEQP-VK.wsi.direct_drm.maintenance1.release_images.fifo.no_scaling.release_before_present,Fail -dEQP-VK.wsi.direct_drm.maintenance1.release_images.fifo.no_scaling.resize_window_after_acquire_release_before_retire,Fail -dEQP-VK.wsi.direct_drm.maintenance1.release_images.fifo.no_scaling.resize_window_after_acquire,Fail -dEQP-VK.wsi.direct_drm.maintenance1.release_images.fifo.no_scaling.resize_window,Fail # deqp-vk: ../src/vulkan/wsi/wsi_common.c:2579: wsi_common_create_swapchain_image: Assertion `pCreateInfo->extent.width == swcInfo->extent.width' failed. dEQP-VK.wsi.direct_drm.swapchain.create.image_swapchain_create_info_concurrent,Crash diff --git a/src/amd/ci/radv-raven-fails.txt b/src/amd/ci/radv-raven-fails.txt index db4f046f561..08d56e828c8 100644 --- a/src/amd/ci/radv-raven-fails.txt +++ b/src/amd/ci/radv-raven-fails.txt @@ -105,9 +105,6 @@ dEQP-VK.sparse_resources.shader_intrinsics.2d_sparse_read.r12x4g12x4_unorm_2pack dEQP-VK.sparse_resources.shader_intrinsics.2d_sparse_read.r12x4g12x4_unorm_2pack16.512_256_1,Crash dEQP-VK.wsi.direct.colorspace.hdr,Fail -dEQP-VK.wsi.direct.maintenance1.release_images.fifo.no_scaling.resize_window,Fail -dEQP-VK.wsi.direct_drm.maintenance1.release_images.fifo.no_scaling.resize_window,Fail -dEQP-VK.wsi.direct_drm.maintenance1.release_images.fifo.no_scaling.resize_window_after_acquire_release_before_retire,Fail # deqp-vk: ../src/vulkan/wsi/wsi_common.c:2579: wsi_common_create_swapchain_image: Assertion `pCreateInfo->extent.width == swcInfo->extent.width' failed. dEQP-VK.wsi.direct.swapchain.simulate_oom.image_swapchain_create_info_concurrent,Crash diff --git a/src/amd/ci/radv-renoir-fails.txt b/src/amd/ci/radv-renoir-fails.txt index 267689b9f95..103194eed73 100644 --- a/src/amd/ci/radv-renoir-fails.txt +++ b/src/amd/ci/radv-renoir-fails.txt @@ -169,21 +169,12 @@ dEQP-VK.sparse_resources.shader_intrinsics.2d_sparse_read.r12x4g12x4_unorm_2pack dEQP-VK.sparse_resources.shader_intrinsics.2d_sparse_read.r12x4g12x4_unorm_2pack16.503_137_1,Crash dEQP-VK.sparse_resources.shader_intrinsics.2d_sparse_read.r12x4g12x4_unorm_2pack16.512_256_1,Crash +# Probably https://gitlab.khronos.org/Tracker/vk-gl-cts/-/issues/6287 +dEQP-VK.wsi.direct_drm.present_timing.time_domain.present_stage_calibration,Fail +dEQP-VK.wsi.direct.present_timing.time_domain.present_stage_calibration,Fail + dEQP-VK.wsi.direct_drm.colorspace.basic,Fail dEQP-VK.wsi.direct_drm.colorspace.hdr,Fail -dEQP-VK.wsi.direct_drm.incremental_present.scale_none.fifo.identity.opaque.incremental_present,Fail -dEQP-VK.wsi.direct_drm.incremental_present.scale_none.fifo.identity.opaque.reference,Fail -dEQP-VK.wsi.direct_drm.maintenance1.deferred_alloc.fifo.basic,Fail -dEQP-VK.wsi.direct_drm.maintenance1.deferred_alloc.fifo.bind_image,Fail -dEQP-VK.wsi.direct_drm.maintenance1.present_fence.fifo.basic,Fail -dEQP-VK.wsi.direct_drm.maintenance1.present_fence.fifo.ordering,Fail -dEQP-VK.wsi.direct_drm.maintenance1.present_modes.fifo.change_modes,Fail -dEQP-VK.wsi.direct_drm.maintenance1.release_images.fifo.no_scaling.basic,Fail -dEQP-VK.wsi.direct_drm.maintenance1.release_images.fifo.no_scaling.release_before_present,Fail -dEQP-VK.wsi.direct_drm.maintenance1.release_images.fifo.no_scaling.resize_window_after_acquire_release_before_retire,Fail -dEQP-VK.wsi.direct_drm.maintenance1.release_images.fifo.no_scaling.resize_window_after_acquire,Fail -dEQP-VK.wsi.direct_drm.maintenance1.release_images.fifo.no_scaling.resize_window,Fail -dEQP-VK.wsi.direct_drm.present_timing.time_domain.present_stage_calibration,Fail dEQP-VK.wsi.direct_drm.swapchain.create.image_sharing_mode,Crash dEQP-VK.wsi.direct_drm.swapchain.create.image_swapchain_create_info_concurrent,Crash dEQP-VK.wsi.direct_drm.swapchain.create.image_swapchain_create_info,Crash @@ -192,19 +183,6 @@ dEQP-VK.wsi.direct_drm.swapchain.simulate_oom.image_swapchain_create_info_concur dEQP-VK.wsi.direct_drm.swapchain.simulate_oom.image_swapchain_create_info,Crash dEQP-VK.wsi.direct.colorspace.basic,Fail dEQP-VK.wsi.direct.colorspace.hdr,Fail -dEQP-VK.wsi.direct.incremental_present.scale_none.fifo.identity.opaque.incremental_present,Fail -dEQP-VK.wsi.direct.incremental_present.scale_none.fifo.identity.opaque.reference,Fail -dEQP-VK.wsi.direct.maintenance1.deferred_alloc.fifo.basic,Fail -dEQP-VK.wsi.direct.maintenance1.deferred_alloc.fifo.bind_image,Fail -dEQP-VK.wsi.direct.maintenance1.present_fence.fifo.basic,Fail -dEQP-VK.wsi.direct.maintenance1.present_fence.fifo.ordering,Fail -dEQP-VK.wsi.direct.maintenance1.present_modes.fifo.change_modes,Fail -dEQP-VK.wsi.direct.maintenance1.release_images.fifo.no_scaling.basic,Fail -dEQP-VK.wsi.direct.maintenance1.release_images.fifo.no_scaling.release_before_present,Fail -dEQP-VK.wsi.direct.maintenance1.release_images.fifo.no_scaling.resize_window_after_acquire_release_before_retire,Fail -dEQP-VK.wsi.direct.maintenance1.release_images.fifo.no_scaling.resize_window_after_acquire,Fail -dEQP-VK.wsi.direct.maintenance1.release_images.fifo.no_scaling.resize_window,Fail -dEQP-VK.wsi.direct.present_timing.time_domain.present_stage_calibration,Fail dEQP-VK.wsi.direct.swapchain.create.image_sharing_mode,Crash dEQP-VK.wsi.direct.swapchain.create.image_swapchain_create_info_concurrent,Crash dEQP-VK.wsi.direct.swapchain.create.image_swapchain_create_info,Crash diff --git a/src/amd/ci/radv-stoney-fails.txt b/src/amd/ci/radv-stoney-fails.txt index 8c5ac91efc0..0ecc844274d 100644 --- a/src/amd/ci/radv-stoney-fails.txt +++ b/src/amd/ci/radv-stoney-fails.txt @@ -1,5 +1,2 @@ # See https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9049 dEQP-VK.pipeline.timestamp.calibrated.calibration_test,Fail - -dEQP-VK.wsi.direct_drm.incremental_present.scale_none.fifo.identity.opaque.reference,Fail -dEQP-VK.wsi.direct_drm.incremental_present.scale_none.fifo.identity.opaque.incremental_present,Fail diff --git a/src/amd/ci/radv-vangogh-fails.txt b/src/amd/ci/radv-vangogh-fails.txt index 2799b6b4f41..8af1130c40b 100644 --- a/src/amd/ci/radv-vangogh-fails.txt +++ b/src/amd/ci/radv-vangogh-fails.txt @@ -107,36 +107,12 @@ dEQP-VK.sparse_resources.shader_intrinsics.2d_sparse_read.r12x4g12x4_unorm_2pack dEQP-VK.wsi.direct_drm.colorspace.basic,Fail dEQP-VK.wsi.direct_drm.colorspace.hdr,Fail -dEQP-VK.wsi.direct_drm.incremental_present.scale_none.fifo.identity.opaque.incremental_present,Fail -dEQP-VK.wsi.direct_drm.incremental_present.scale_none.fifo.identity.opaque.reference,Fail -dEQP-VK.wsi.direct_drm.maintenance1.deferred_alloc.fifo.basic,Fail -dEQP-VK.wsi.direct_drm.maintenance1.deferred_alloc.fifo.bind_image,Fail -dEQP-VK.wsi.direct_drm.maintenance1.present_fence.fifo.basic,Fail -dEQP-VK.wsi.direct_drm.maintenance1.present_fence.fifo.ordering,Fail -dEQP-VK.wsi.direct_drm.maintenance1.present_modes.fifo.change_modes,Fail -dEQP-VK.wsi.direct_drm.maintenance1.release_images.fifo.no_scaling.basic,Fail -dEQP-VK.wsi.direct_drm.maintenance1.release_images.fifo.no_scaling.release_before_present,Fail -dEQP-VK.wsi.direct_drm.maintenance1.release_images.fifo.no_scaling.resize_window_after_acquire_release_before_retire,Fail -dEQP-VK.wsi.direct_drm.maintenance1.release_images.fifo.no_scaling.resize_window_after_acquire,Fail -dEQP-VK.wsi.direct_drm.maintenance1.release_images.fifo.no_scaling.resize_window,Fail dEQP-VK.wsi.direct_drm.swapchain.create.image_swapchain_create_info_concurrent,Crash dEQP-VK.wsi.direct_drm.swapchain.create.image_swapchain_create_info,Crash dEQP-VK.wsi.direct_drm.swapchain.simulate_oom.image_swapchain_create_info_concurrent,Crash dEQP-VK.wsi.direct_drm.swapchain.simulate_oom.image_swapchain_create_info,Crash dEQP-VK.wsi.direct.colorspace.basic,Fail dEQP-VK.wsi.direct.colorspace.hdr,Fail -dEQP-VK.wsi.direct.incremental_present.scale_none.fifo.identity.opaque.incremental_present,Fail -dEQP-VK.wsi.direct.incremental_present.scale_none.fifo.identity.opaque.reference,Fail -dEQP-VK.wsi.direct.maintenance1.deferred_alloc.fifo.basic,Fail -dEQP-VK.wsi.direct.maintenance1.deferred_alloc.fifo.bind_image,Fail -dEQP-VK.wsi.direct.maintenance1.present_fence.fifo.basic,Fail -dEQP-VK.wsi.direct.maintenance1.present_fence.fifo.ordering,Fail -dEQP-VK.wsi.direct.maintenance1.present_modes.fifo.change_modes,Fail -dEQP-VK.wsi.direct.maintenance1.release_images.fifo.no_scaling.basic,Fail -dEQP-VK.wsi.direct.maintenance1.release_images.fifo.no_scaling.release_before_present,Fail -dEQP-VK.wsi.direct.maintenance1.release_images.fifo.no_scaling.resize_window_after_acquire_release_before_retire,Fail -dEQP-VK.wsi.direct.maintenance1.release_images.fifo.no_scaling.resize_window_after_acquire,Fail -dEQP-VK.wsi.direct.maintenance1.release_images.fifo.no_scaling.resize_window,Fail dEQP-VK.wsi.direct.swapchain.create.image_swapchain_create_info_concurrent,Crash dEQP-VK.wsi.direct.swapchain.create.image_swapchain_create_info,Crash dEQP-VK.wsi.direct.swapchain.simulate_oom.image_swapchain_create_info_concurrent,Crash diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c index e411b400df0..3251117601f 100644 --- a/src/vulkan/wsi/wsi_common_display.c +++ b/src/vulkan/wsi/wsi_common_display.c @@ -2823,7 +2823,7 @@ _wsi_display_convert_hdr_metadata(VkHdrMetadataEXT *pMetadata, uint8_t hdmi_eotf } static int -drm_atomic_commit(wsi_display_connector *connector, struct wsi_display_image *image) +drm_atomic_commit(wsi_display_connector *connector, struct wsi_display_image *image, bool test_only) { const drmModeModeInfo *mode = &connector->current_drm_mode; int fd = connector->wsi->fd; @@ -2910,6 +2910,11 @@ drm_atomic_commit(wsi_display_connector *connector, struct wsi_display_image *im drmModeAtomicAddProperty(req, plane_id, prop[CRTC_W], mode->hdisplay); drmModeAtomicAddProperty(req, plane_id, prop[CRTC_H], mode->vdisplay); + if (test_only) { + flags |= DRM_MODE_ATOMIC_TEST_ONLY; + flags &= ~DRM_MODE_PAGE_FLIP_EVENT; + } + ret = drmModeAtomicCommit(fd, req, flags, image); if (ret) goto out; @@ -2940,7 +2945,7 @@ _wsi_display_cleanup_state(struct wsi_display_swapchain *chain) if (chain->color_outcome_serial) { chain->color_outcome_serial = 0; chain->base.image_info.color_space = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; - drm_atomic_commit(connector, &chain->images[0]); + drm_atomic_commit(connector, &chain->images[0], false); } } @@ -3085,7 +3090,7 @@ _wsi_display_queue_next(struct wsi_swapchain *drv_chain) image->state = WSI_IMAGE_QUEUED; - int ret = drm_atomic_commit(connector, image); + int ret = drm_atomic_commit(connector, image, false); if (ret == 0) { image->state = WSI_IMAGE_FLIPPING; connector->active = true; @@ -3373,6 +3378,30 @@ wsi_display_surface_create_swapchain( create_info, drm_format, &chain->images[image]); + + /* Check that we could actually possibly atomic commit to this plane. This + * catches cases where the swapchain exceeds some limits of the hardware * + * that we couldn't tell from the probed properties. This is allowed by + * the spec: + * + * "In some cases, swapchain creation may fail if exclusive full-screen + * mode is requested for application control, but for some + * implementation-specific reason exclusive full-screen access is + * unavailable for the particular combination of parameters provided. If + * this occurs, VK_ERROR_INITIALIZATION_FAILED will be returned." + */ + if (result == VK_SUCCESS) { + ret = drm_atomic_commit(display_mode->connector, &chain->images[image], true); + if (ret != 0) { + wsi_display_debug("Atomic commit check for %dx%d %s, failed: %s\n", + create_info->imageExtent.width, + create_info->imageExtent.height, + util_format_short_name(vk_format_to_pipe_format(create_info->imageFormat)), + strerror(-errno)); + result = VK_ERROR_INITIALIZATION_FAILED; + } + } + if (result != VK_SUCCESS) { while (image > 0) { --image;