wsi/metal: Fix size query and present result

Reviewed-By: Aleksi Sapon <aleksi.sapon@autodesk.com>
Acked-By: Yiwei Zhang <zzyiwei@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37493>
This commit is contained in:
Aitor Camacho 2025-10-01 15:22:10 +02:00 committed by Marge Bot
parent a1c8b21774
commit 33695f9c48
2 changed files with 23 additions and 2 deletions

View file

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

View file

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