kk,wsi/metal: Support VK_(KHR/EXT)_swapchain_maintenance1
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

Primary additions are support for releasing images and changing
present mode in the Metal WSI backend.

Reviewed-by: Aitor Camacho <aitor@lunarg.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42062>
This commit is contained in:
squidbus 2026-06-05 17:43:33 -07:00 committed by Marge Bot
parent 5882459c45
commit 6e5773687f
5 changed files with 67 additions and 2 deletions

View file

@ -594,7 +594,7 @@ Khronos extensions that are not part of any Vulkan version:
VK_KHR_surface_maintenance1 DONE (anv, hk, kk, lvp, nvk, panvk, radv, tu, v3dv, vn)
VK_KHR_surface_protected_capabilities DONE (anv, hasvk, hk, kk, lvp, nvk, radv, tu, v3dv, vn)
VK_KHR_swapchain DONE (anv, dzn, hasvk, hk, kk, lvp, nvk, panvk, pvr, radv, tu, v3dv, vn)
VK_KHR_swapchain_maintenance1 DONE (anv, hk, lvp, nvk, panvk, radv, tu, v3dv, vn)
VK_KHR_swapchain_maintenance1 DONE (anv, hk, kk, lvp, nvk, panvk, radv, tu, v3dv, vn)
VK_KHR_swapchain_mutable_format DONE (anv, hasvk, hk, kk, lvp, nvk, panvk, pvr, radv, tu, v3dv, vn)
VK_KHR_unified_image_layouts DONE (kk, lvp, nvk, panvk, radv/gfx11+, tu)
VK_KHR_wayland_surface DONE (anv, dzn, hasvk, hk, kk, lvp, nvk, panvk, pvr, radv, tu, v3dv, vn)
@ -698,7 +698,7 @@ Khronos extensions that are not part of any Vulkan version:
VK_EXT_shader_uniform_buffer_unsized_array DONE (anv, hk, nvk, panvk, radv, tu, vn)
VK_EXT_surface_maintenance1 DONE (anv, hk, kk, lvp, nvk, panvk, radv, tu, v3dv, vn)
VK_EXT_swapchain_colorspace DONE (anv, hk, kk, lvp, nvk, radv, tu, v3dv, vn)
VK_EXT_swapchain_maintenance1 DONE (anv, hk, lvp, nvk, panvk, radv, tu, v3dv, vn)
VK_EXT_swapchain_maintenance1 DONE (anv, hk, kk, lvp, nvk, panvk, radv, tu, v3dv, vn)
VK_EXT_transform_feedback DONE (anv, hasvk, hk, lvp, nvk, radv, tu, vn)
VK_EXT_vertex_attribute_divisor DONE (anv, dzn, hasvk, hk, kk, lvp, nvk, panvk, pvr, radv, tu, v3dv, vn)
VK_EXT_vertex_attribute_robustness DONE (kk)

View file

@ -149,6 +149,7 @@ kk_get_device_extensions(const struct kk_instance *instance,
.KHR_shader_untyped_pointers = true,
#ifdef KK_USE_WSI_PLATFORM
.KHR_swapchain = true,
.KHR_swapchain_maintenance1 = true,
.KHR_swapchain_mutable_format = true,
#endif
.KHR_unified_image_layouts = true,
@ -181,6 +182,9 @@ kk_get_device_extensions(const struct kk_instance *instance,
.EXT_shader_replicated_composites = true,
.EXT_shader_subgroup_ballot = true,
.EXT_shader_subgroup_vote = true,
#ifdef KK_USE_WSI_PLATFORM
.EXT_swapchain_maintenance1 = true,
#endif
.EXT_vertex_attribute_robustness = true,
.GOOGLE_decorate_string = true,
@ -369,6 +373,11 @@ kk_get_device_features(
/* VK_KHR_shader_untyped_pointers */
.shaderUntypedPointers = true,
#ifdef KK_USE_WSI_PLATFORM
/* VK_KHR_swapchain_maintenance1 */
.swapchainMaintenance1 = true,
#endif
/* VK_KHR_unified_image_layouts */
.unifiedImageLayouts = true,
.unifiedImageLayoutsVideo = false,

View file

@ -506,6 +506,49 @@ wsi_metal_swapchain_acquire_next_image(struct wsi_swapchain *wsi_chain,
}
}
static VkResult
wsi_metal_swapchain_release_images(struct wsi_swapchain *wsi_chain,
uint32_t count, const uint32_t *indices)
{
const struct wsi_device *wsi = wsi_chain->wsi;
struct wsi_metal_swapchain *chain =
(struct wsi_metal_swapchain *)wsi_chain;
const uint32_t queue_count = chain->base.blit.queue != NULL ? 1 :
wsi->queue_family_count;
for (uint32_t idx = 0; idx < count; idx++) {
struct wsi_metal_image *image = &chain->images[indices[idx]];
if (wsi->sw) {
/* Directly release drawable */
if (image->drawable) {
wsi_metal_release_drawable(image->drawable);
image->drawable = NULL;
}
} else {
/* Drawable has been released and is retained by blit command buffers.
* Free them to release the reference. */
for (uint32_t queue_idx = 0; queue_idx < queue_count; queue_idx++) {
wsi->FreeCommandBuffers(
chain->base.device, chain->base.cmd_pools[queue_idx], 1u,
&image->base.blit.cmd_buffers[queue_idx]);
image->base.blit.cmd_buffers[queue_idx] = NULL;
}
}
}
return VK_SUCCESS;
}
static void
wsi_metal_swapchain_set_present_mode(struct wsi_swapchain *wsi_chain,
VkPresentModeKHR mode)
{
struct wsi_metal_swapchain *chain = (struct wsi_metal_swapchain *)wsi_chain;
const bool immediate_mode = mode == VK_PRESENT_MODE_IMMEDIATE_KHR;
wsi_metal_layer_set_immediate(chain->surface->pLayer, immediate_mode);
}
static VkResult
wsi_metal_swapchain_queue_present(struct wsi_swapchain *wsi_chain,
uint32_t image_index,
@ -686,6 +729,8 @@ wsi_metal_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
chain->base.destroy = wsi_metal_swapchain_destroy;
chain->base.get_wsi_image = wsi_metal_swapchain_get_wsi_image;
chain->base.acquire_next_image = wsi_metal_swapchain_acquire_next_image;
chain->base.release_images = wsi_metal_swapchain_release_images;
chain->base.set_present_mode = wsi_metal_swapchain_set_present_mode;
chain->base.queue_present = wsi_metal_swapchain_queue_present;
chain->base.set_hdr_metadata = wsi_metal_swapchain_set_hdr_metadata;
chain->base.present_mode = wsi_swapchain_get_present_mode(wsi_device, pCreateInfo);

View file

@ -19,6 +19,10 @@ void
wsi_metal_layer_size(const CAMetalLayer *metal_layer,
uint32_t *width, uint32_t *height);
void
wsi_metal_layer_set_immediate(const CAMetalLayer *metal_layer,
bool enable_immediate);
VkResult
wsi_metal_layer_configure(const CAMetalLayer *metal_layer,
uint32_t width, uint32_t height, uint32_t image_count,

View file

@ -133,6 +133,13 @@ get_color_space_info(VkColorSpaceKHR color_space, CGColorSpaceRef *cg_color_spac
return VK_SUCCESS;
}
void
wsi_metal_layer_set_immediate(const CAMetalLayer *metal_layer,
bool enable_immediate)
{
metal_layer.displaySyncEnabled = !enable_immediate;
}
VkResult
wsi_metal_layer_configure(const CAMetalLayer *metal_layer,
uint32_t width, uint32_t height, uint32_t image_count,