diff --git a/docs/features.txt b/docs/features.txt index 5f08899840c..04084bc9ae9 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -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) diff --git a/src/kosmickrisp/vulkan/kk_physical_device.c b/src/kosmickrisp/vulkan/kk_physical_device.c index f1b6430caee..5b981faaa69 100644 --- a/src/kosmickrisp/vulkan/kk_physical_device.c +++ b/src/kosmickrisp/vulkan/kk_physical_device.c @@ -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, diff --git a/src/vulkan/wsi/wsi_common_metal.c b/src/vulkan/wsi/wsi_common_metal.c index b8883716855..1e2e6f264ac 100644 --- a/src/vulkan/wsi/wsi_common_metal.c +++ b/src/vulkan/wsi/wsi_common_metal.c @@ -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); diff --git a/src/vulkan/wsi/wsi_common_metal_layer.h b/src/vulkan/wsi/wsi_common_metal_layer.h index d8416646a7a..e9473b129c8 100644 --- a/src/vulkan/wsi/wsi_common_metal_layer.h +++ b/src/vulkan/wsi/wsi_common_metal_layer.h @@ -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, diff --git a/src/vulkan/wsi/wsi_common_metal_layer.m b/src/vulkan/wsi/wsi_common_metal_layer.m index 7f923edcf3c..67c3e7ff1cb 100644 --- a/src/vulkan/wsi/wsi_common_metal_layer.m +++ b/src/vulkan/wsi/wsi_common_metal_layer.m @@ -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,