From 33695f9c480636db8e095852111952a54cca4662 Mon Sep 17 00:00:00 2001 From: Aitor Camacho Date: Wed, 1 Oct 2025 15:22:10 +0200 Subject: [PATCH] wsi/metal: Fix size query and present result Reviewed-By: Aleksi Sapon Acked-By: Yiwei Zhang Part-of: --- src/vulkan/wsi/wsi_common_metal.c | 5 ++++- src/vulkan/wsi/wsi_common_metal_layer.m | 20 +++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/vulkan/wsi/wsi_common_metal.c b/src/vulkan/wsi/wsi_common_metal.c index 619061a8883..186231f76b1 100644 --- a/src/vulkan/wsi/wsi_common_metal.c +++ b/src/vulkan/wsi/wsi_common_metal.c @@ -352,7 +352,10 @@ wsi_metal_swapchain_queue_present(struct wsi_swapchain *wsi_chain, chain->extent.width, chain->extent.height, image->base.row_pitches[0]); - return VK_SUCCESS; + uint32_t width = 0u, height = 0u; + wsi_metal_layer_size(chain->surface->pLayer, &width, &height); + bool is_optimal = (width == chain->extent.width && height == chain->extent.height); + return is_optimal ? VK_SUCCESS : VK_SUBOPTIMAL_KHR; } static VkResult diff --git a/src/vulkan/wsi/wsi_common_metal_layer.m b/src/vulkan/wsi/wsi_common_metal_layer.m index ae269448998..69311dd656b 100644 --- a/src/vulkan/wsi/wsi_common_metal_layer.m +++ b/src/vulkan/wsi/wsi_common_metal_layer.m @@ -14,7 +14,25 @@ wsi_metal_layer_size(const CAMetalLayer *metal_layer, uint32_t *width, uint32_t *height) { @autoreleasepool { - CGSize size = [metal_layer drawableSize]; + /* The reason why "drawableSize" is not being used here because it will + * only return non-zero values if there has actually been any kind of + * drawable allocated (acquired). Without this we also run into crashes + * in KosmicKrisp. Initializing the CAMetalLayer with a NSView with + * a frame does not create the drawable. Due to this, we fail/crash + * tests in the following Vulkan CTS test family: + * dEQP-VK.wsi.metal.surface.* + * + * There are 2 possible ways to fix this: + * 1. The one implemented. + * 2. Return the special value allowed by the spec to state that we will + * actually give it a value once the swapchain is created + * https://registry.khronos.org/vulkan/specs/latest/man/html/VkSurfaceCapabilitiesKHR.html + */ + CGSize size = metal_layer.bounds.size; + CGFloat scaleFactor = metal_layer.contentsScale; + size.width *= scaleFactor; + size.height *= scaleFactor; + if (width) *width = size.width; if (height)