From 3fc3b5fdad74c4a980c9942041103d69c36799f0 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Sun, 23 Nov 2025 20:47:26 -0400 Subject: [PATCH] [vk] Changing conditions for Swapchain maintenance1 --- src/video_core/renderer_vulkan/vk_swapchain.cpp | 12 +++++++++++- src/video_core/vulkan_common/vulkan_device.cpp | 15 +++++++++++++++ src/video_core/vulkan_common/vulkan_instance.cpp | 5 +++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index fdd2de2379..7418ad934e 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp @@ -306,7 +306,17 @@ void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities) { swapchain_ci.queueFamilyIndexCount = static_cast(queue_indices.size()); swapchain_ci.pQueueFamilyIndices = queue_indices.data(); } - static constexpr std::array view_formats{VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_SRGB}; + // According to Vulkan spec, when using VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR, + // the base format (imageFormat) MUST be included in pViewFormats + const std::array view_formats{ + swapchain_ci.imageFormat, // Base format MUST be first + VK_FORMAT_B8G8R8A8_UNORM, + VK_FORMAT_B8G8R8A8_SRGB, +#ifdef ANDROID + VK_FORMAT_R8G8B8A8_UNORM, // Android may use RGBA + VK_FORMAT_R8G8B8A8_SRGB, +#endif + }; VkImageFormatListCreateInfo format_list{ .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR, .pNext = nullptr, diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index eade00c099..e322ac97cb 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -1335,7 +1335,22 @@ void Device::RemoveUnsuitableExtensions() { VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME); // VK_EXT_swapchain_maintenance1 (extension only, has features) + // Requires VK_EXT_surface_maintenance1 instance extension extensions.swapchain_maintenance1 = features.swapchain_maintenance1.swapchainMaintenance1; + if (extensions.swapchain_maintenance1) { + // Check if VK_EXT_surface_maintenance1 instance extension is available + const auto instance_extensions = vk::EnumerateInstanceExtensionProperties(dld); + const bool has_surface_maintenance1 = instance_extensions && std::ranges::any_of(*instance_extensions, + [](const VkExtensionProperties& prop) { + return std::strcmp(prop.extensionName, VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME) == 0; + }); + if (!has_surface_maintenance1) { + LOG_WARNING(Render_Vulkan, + "VK_EXT_swapchain_maintenance1 requires VK_EXT_surface_maintenance1, disabling"); + extensions.swapchain_maintenance1 = false; + features.swapchain_maintenance1.swapchainMaintenance1 = false; + } + } RemoveExtensionFeatureIfUnsuitable(extensions.swapchain_maintenance1, features.swapchain_maintenance1, VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME); diff --git a/src/video_core/vulkan_common/vulkan_instance.cpp b/src/video_core/vulkan_common/vulkan_instance.cpp index ebb3fcd020..74035f294b 100644 --- a/src/video_core/vulkan_common/vulkan_instance.cpp +++ b/src/video_core/vulkan_common/vulkan_instance.cpp @@ -83,6 +83,11 @@ namespace { if (window_type != Core::Frontend::WindowSystemType::Headless && AreExtensionsSupported(dld, *properties, std::array{VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME})) extensions.push_back(VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME); } + // VK_EXT_surface_maintenance1 is required for VK_EXT_swapchain_maintenance1 + if (window_type != Core::Frontend::WindowSystemType::Headless && + AreExtensionsSupported(dld, std::array{VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME})) { + extensions.push_back(VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME); + } return extensions; }