From bdf45e015c1a3454649cd3cefa0992723e633a9f Mon Sep 17 00:00:00 2001 From: lizzie Date: Mon, 9 Feb 2026 11:07:26 +0000 Subject: [PATCH] [vk, macos] register and use legacy MVK surface if metal is unavailable Signed-off-by: lizzie --- .../vulkan_common/vk_enum_string_helper.h | 6 ++++ src/video_core/vulkan_common/vulkan.h | 9 +++++- .../vulkan_common/vulkan_surface.cpp | 31 ++++++++++++++----- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/video_core/vulkan_common/vk_enum_string_helper.h b/src/video_core/vulkan_common/vk_enum_string_helper.h index a1515814c6..e508fd57ba 100644 --- a/src/video_core/vulkan_common/vk_enum_string_helper.h +++ b/src/video_core/vulkan_common/vk_enum_string_helper.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -5,4 +8,7 @@ #include "video_core/vulkan_common/vulkan.h" +#if defined(__APPLE__) && !defined(VK_STRUCTURE_TYPE_OH_SURFACE_CREATE_INFO_OHOS) +# define VK_STRUCTURE_TYPE_OH_SURFACE_CREATE_INFO_OHOS VK_STRUCTURE_TYPE_SURFACE_CREATE_INFO_OHOS +#endif #include diff --git a/src/video_core/vulkan_common/vulkan.h b/src/video_core/vulkan_common/vulkan.h index 8d2e8e2a37..ecbd748cf6 100644 --- a/src/video_core/vulkan_common/vulkan.h +++ b/src/video_core/vulkan_common/vulkan.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project @@ -11,6 +11,7 @@ #define VK_USE_PLATFORM_WIN32_KHR #elif defined(__APPLE__) #define VK_USE_PLATFORM_METAL_EXT +#define VK_USE_PLATFORM_MACOS_MVK #elif defined(__ANDROID__) #define VK_USE_PLATFORM_ANDROID_KHR #elif defined(__HAIKU__) @@ -32,6 +33,12 @@ #ifndef VK_KHR_MAINTENANCE_9_EXTENSION_NAME #define VK_KHR_MAINTENANCE_9_EXTENSION_NAME "VK_KHR_maintenance9" #endif +#ifndef VK_EXT_METAL_SURFACE_EXTENSION_NAME +#define VK_EXT_METAL_SURFACE_EXTENSION_NAME "VK_EXT_metal_surface" +#endif +#ifndef VK_MVK_MACOS_SURFACE_EXTENSION_NAME +#define VK_MVK_MACOS_SURFACE_EXTENSION_NAME "VK_MVK_macos_surface" +#endif // Sanitize macros #undef CreateEvent diff --git a/src/video_core/vulkan_common/vulkan_surface.cpp b/src/video_core/vulkan_common/vulkan_surface.cpp index f1b56cc0a8..3420bd54b9 100644 --- a/src/video_core/vulkan_common/vulkan_surface.cpp +++ b/src/video_core/vulkan_common/vulkan_surface.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project @@ -32,15 +32,30 @@ vk::SurfaceKHR CreateSurface( } #elif defined(__APPLE__) if (window_info.type == Core::Frontend::WindowSystemType::Cocoa) { - const VkMetalSurfaceCreateInfoEXT macos_ci = { + const VkMetalSurfaceCreateInfoEXT metal_ci = { + .sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT, + .pNext = nullptr, + .flags = 0, .pLayer = static_cast(window_info.render_surface), }; - const auto vkCreateMetalSurfaceEXT = reinterpret_cast( - dld.vkGetInstanceProcAddr(*instance, "vkCreateMetalSurfaceEXT")); - if (!vkCreateMetalSurfaceEXT || - vkCreateMetalSurfaceEXT(*instance, &macos_ci, nullptr, &unsafe_surface) != VK_SUCCESS) { - LOG_ERROR(Render_Vulkan, "Failed to initialize Metal surface"); - throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); + const auto vkCreateMetalSurfaceEXT = PFN_vkCreateMetalSurfaceEXT(dld.vkGetInstanceProcAddr(*instance, "vkCreateMetalSurfaceEXT")); + if (!vkCreateMetalSurfaceEXT || vkCreateMetalSurfaceEXT(*instance, &metal_ci, nullptr, &unsafe_surface) != VK_SUCCESS) { + // TODO: Way to fallback? - where's my vulkan headers + // Attempt to make a macOS surface instead then... + // This is the deprecated VkMacOSSurfaceCreateInfoMVK(3) version; but should work if the above failed + // https://registry.khronos.org/vulkan/specs/latest/man/html/VkMacOSSurfaceCreateInfoMVK.html + const VkMacOSSurfaceCreateInfoMVK macos_legacy_ci = { + .sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK, + .pNext = nullptr, + .flags = 0, + .pView = static_cast(window_info.render_surface), + }; + const auto vkCreateMacOSSurfaceMVK = PFN_vkCreateMacOSSurfaceMVK(dld.vkGetInstanceProcAddr(*instance, "vkCreateMacOSSurfaceMVK")); + if (!vkCreateMacOSSurfaceMVK || vkCreateMacOSSurfaceMVK(*instance, &macos_legacy_ci, nullptr, &unsafe_surface) != VK_SUCCESS) { + LOG_ERROR(Render_Vulkan, "Failed to initialize Metal/macOS surface"); + throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); + } + LOG_ERROR(Render_Vulkan, "Failed to initialize Metal/macOS surface"); } } #elif defined(__ANDROID__)