diff --git a/.ci/build-mac-arm64.sh b/.ci/build-mac-arm64.sh index 42e0f61fb3..29087d5ff8 100755 --- a/.ci/build-mac-arm64.sh +++ b/.ci/build-mac-arm64.sh @@ -6,7 +6,7 @@ export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 export HOMEBREW_NO_ENV_HINTS=1 export HOMEBREW_NO_INSTALL_CLEANUP=1 -brew install -f --overwrite --quiet pipenv googletest ffmpeg@5 "llvm@$LLVM_COMPILER_VER" glew sdl3 vulkan-headers +brew install -f --overwrite --quiet pipenv googletest ffmpeg@5 "llvm@$LLVM_COMPILER_VER" glew sdl3 vulkan-headers vulkan-loader brew link -f --quiet "llvm@$LLVM_COMPILER_VER" ffmpeg@5 # moltenvk based on commit for 1.4.0 release @@ -56,15 +56,14 @@ export SDL3_DIR="$BREW_PATH/opt/sdl3/lib/cmake/SDL3" export PATH="$BREW_PATH/opt/llvm@$LLVM_COMPILER_VER/bin:$WORKDIR/qt-downloader/$QT_VER/clang_64/bin:$BREW_BIN:$BREW_SBIN:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Library/Apple/usr/bin:$PATH" export LDFLAGS="-L$BREW_PATH/lib $BREW_PATH/opt/ffmpeg@5/lib/libavcodec.dylib $BREW_PATH/opt/ffmpeg@5/lib/libavformat.dylib $BREW_PATH/opt/ffmpeg@5/lib/libavutil.dylib $BREW_PATH/opt/ffmpeg@5/lib/libswscale.dylib $BREW_PATH/opt/ffmpeg@5/lib/libswresample.dylib $BREW_PATH/opt/llvm@$LLVM_COMPILER_VER/lib/c++/libc++.1.dylib $BREW_PATH/lib/libSDL3.dylib $BREW_PATH/lib/libGLEW.dylib $BREW_PATH/opt/llvm@$LLVM_COMPILER_VER/lib/unwind/libunwind.1.dylib -Wl,-rpath,$BREW_PATH/lib" -export CPPFLAGS="-I$BREW_PATH/include -I$BREW_PATH/include -no-pie -D__MAC_OS_X_VERSION_MIN_REQUIRED=140000" +export CPPFLAGS="-I$BREW_PATH/include -no-pie -D__MAC_OS_X_VERSION_MIN_REQUIRED=140000" export CFLAGS="-D__MAC_OS_X_VERSION_MIN_REQUIRED=140000" export LIBRARY_PATH="$BREW_PATH/lib" export LD_LIBRARY_PATH="$BREW_PATH/lib" export VULKAN_SDK VULKAN_SDK="$BREW_PATH/opt/molten-vk" -ln -s "$VULKAN_SDK/lib/libMoltenVK.dylib" "$VULKAN_SDK/lib/libvulkan.dylib" || true -export VK_ICD_FILENAMES="$VULKAN_SDK/share/vulkan/icd.d/MoltenVK_icd.json" +ln -s "$BREW_PATH/opt/vulkan-loader/lib/libvulkan.dylib" "$VULKAN_SDK/lib/libvulkan.dylib" || true export LLVM_DIR LLVM_DIR="$BREW_PATH/opt/llvm@$LLVM_COMPILER_VER" diff --git a/.ci/build-mac.sh b/.ci/build-mac.sh index afd687061c..bd1a17f39c 100755 --- a/.ci/build-mac.sh +++ b/.ci/build-mac.sh @@ -12,7 +12,7 @@ brew link -f --overwrite --quiet "llvm@$LLVM_COMPILER_VER" rm /usr/local/bin/{idle3.14,pip3.14,pydoc3.14,python3.14,python3.14-config} && \ rm /usr/local/bin/{idle3,pip3,pydoc3,python3,python3-config} arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" -arch -x86_64 /usr/local/bin/brew install -f --overwrite --quiet ffmpeg@5 "llvm@$LLVM_COMPILER_VER" glew sdl3 vulkan-headers +arch -x86_64 /usr/local/bin/brew install -f --overwrite --quiet ffmpeg@5 "llvm@$LLVM_COMPILER_VER" glew sdl3 vulkan-headers vulkan-loader arch -x86_64 /usr/local/bin/brew link -f --overwrite --quiet "llvm@$LLVM_COMPILER_VER" ffmpeg@5 # moltenvk based on commit for 1.4.0 release @@ -63,8 +63,7 @@ export LD_LIBRARY_PATH="$BREW_X64_PATH/opt/llvm@$LLVM_COMPILER_VER/lib:$BREW_X64 export VULKAN_SDK VULKAN_SDK="$BREW_X64_PATH/opt/molten-vk" -ln -s "$VULKAN_SDK/lib/libMoltenVK.dylib" "$VULKAN_SDK/lib/libvulkan.dylib" -export VK_ICD_FILENAMES="$VULKAN_SDK/share/vulkan/icd.d/MoltenVK_icd.json" +ln -s "$BREW_X64_PATH/opt/vulkan-loader/lib/libvulkan.dylib" "$VULKAN_SDK/lib/libvulkan.dylib" export LLVM_DIR LLVM_DIR="$BREW_X64_PATH/opt/llvm@$LLVM_COMPILER_VER" diff --git a/.ci/deploy-mac-arm64.sh b/.ci/deploy-mac-arm64.sh index 6e067bde9f..4ec79603e0 100755 --- a/.ci/deploy-mac-arm64.sh +++ b/.ci/deploy-mac-arm64.sh @@ -15,6 +15,10 @@ echo "AVVER=$AVVER" >> ../.ci/ci-vars.env cd bin mkdir "rpcs3.app/Contents/lib/" || true +mkdir -p "rpcs3.app/Contents/Resources/vulkan/icd.d" || true +cp "$(realpath /opt/homebrew/lib/libMoltenVK.dylib)" "rpcs3.app/Contents/Frameworks/libMoltenVK.dylib" +cp "$(realpath /opt/homebrew/etc/vulkan/icd.d/MoltenVK_icd.json)" "rpcs3.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json" +sed -i '' "s/lib\//Frameworks\//g" "rpcs3.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json" cp "$(realpath /opt/homebrew/opt/llvm@$LLVM_COMPILER_VER/lib/c++/libc++abi.1.0.dylib)" "rpcs3.app/Contents/Frameworks/libc++abi.1.dylib" cp "$(realpath /opt/homebrew/lib/libsharpyuv.0.dylib)" "rpcs3.app/Contents/lib/libsharpyuv.0.dylib" diff --git a/.ci/deploy-mac.sh b/.ci/deploy-mac.sh index 4b54267539..cbfb991456 100755 --- a/.ci/deploy-mac.sh +++ b/.ci/deploy-mac.sh @@ -14,7 +14,11 @@ AVVER="${COMM_TAG}-${COMM_COUNT}" echo "AVVER=$AVVER" >> ../.ci/ci-vars.env cd bin -mkdir "rpcs3.app/Contents/lib/" +mkdir "rpcs3.app/Contents/lib/" || true +mkdir -p "rpcs3.app/Contents/Resources/vulkan/icd.d" || true +cp "$(realpath /usr/local/lib/libMoltenVK.dylib)" "rpcs3.app/Contents/Frameworks/libMoltenVK.dylib" +cp "$(realpath /usr/local/etc/vulkan/icd.d/MoltenVK_icd.json)" "rpcs3.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json" +sed -i '' "s/lib\//Frameworks\//g" "rpcs3.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json" cp "/usr/local/opt/llvm@$LLVM_COMPILER_VER/lib/c++/libc++abi.1.0.dylib" "rpcs3.app/Contents/Frameworks/libc++abi.1.dylib" cp "/usr/local/opt/llvm@$LLVM_COMPILER_VER/lib/unwind/libunwind.1.dylib" "rpcs3.app/Contents/Frameworks/libunwind.1.dylib" diff --git a/rpcs3/Emu/CMakeLists.txt b/rpcs3/Emu/CMakeLists.txt index 1a902b46df..39e145900a 100644 --- a/rpcs3/Emu/CMakeLists.txt +++ b/rpcs3/Emu/CMakeLists.txt @@ -623,6 +623,11 @@ if(TARGET 3rdparty_vulkan) RSX/VK/VKTextureCache.cpp RSX/VK/VulkanAPI.cpp ) + if(APPLE) + target_sources(rpcs3_emu PRIVATE + RSX/VK/vkutils/metal_layer.mm + ) + endif() endif() find_package(Threads REQUIRED) diff --git a/rpcs3/Emu/RSX/VK/VulkanAPI.h b/rpcs3/Emu/RSX/VK/VulkanAPI.h index c91e9cb5a5..411d653807 100644 --- a/rpcs3/Emu/RSX/VK/VulkanAPI.h +++ b/rpcs3/Emu/RSX/VK/VulkanAPI.h @@ -4,7 +4,7 @@ #ifdef _WIN32 #define VK_USE_PLATFORM_WIN32_KHR #elif defined(__APPLE__) -#define VK_USE_PLATFORM_MACOS_MVK +#define VK_USE_PLATFORM_METAL_EXT #elif defined(ANDROID) #define VK_USE_PLATFORM_ANDROID_KHR #else @@ -29,7 +29,7 @@ // Undefine header configuration variables #undef VK_USE_PLATFORM_WIN32_KHR -#undef VK_USE_PLATFORM_MACOS_MVK +#undef VK_USE_PLATFORM_METAL_EXT #undef VK_USE_PLATFORM_ANDROID_KHR #undef VK_USE_PLATFORM_XLIB_KHR #undef VK_USE_PLATFORM_WAYLAND_KHR diff --git a/rpcs3/Emu/RSX/VK/vkutils/device.cpp b/rpcs3/Emu/RSX/VK/vkutils/device.cpp index e29a9b66c2..34b7758b50 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/device.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/device.cpp @@ -3,6 +3,9 @@ #include "util/logs.hpp" #include "Emu/system_config.h" #include +#ifdef __APPLE__ +#include +#endif namespace vk { @@ -555,6 +558,10 @@ namespace vk { requested_extensions.push_back(VK_EXT_DEVICE_FAULT_EXTENSION_NAME); } + +#ifdef __APPLE__ + requested_extensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME); +#endif enabled_features.robustBufferAccess = VK_TRUE; enabled_features.fullDrawIndexUint32 = VK_TRUE; diff --git a/rpcs3/Emu/RSX/VK/vkutils/instance.cpp b/rpcs3/Emu/RSX/VK/vkutils/instance.cpp index fff6691aea..49224fcc27 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/instance.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/instance.cpp @@ -124,10 +124,11 @@ namespace vk } #ifdef __APPLE__ + extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); + extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); if (support.is_supported(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME)) { extensions.push_back(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME); - layers.push_back(kMVKMoltenVKDriverLayerName); mvk_settings.push_back(VkLayerSettingEXT{ kMVKMoltenVKDriverLayerName, "MVK_CONFIG_RESUME_LOST_DEVICE", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &setting_true }); mvk_settings.push_back(VkLayerSettingEXT{ kMVKMoltenVKDriverLayerName, "MVK_CONFIG_FAST_MATH_ENABLED", VK_LAYER_SETTING_TYPE_INT32_EXT, 1, &setting_fast_math }); @@ -154,7 +155,7 @@ namespace vk #ifdef _WIN32 extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); #elif defined(__APPLE__) - extensions.push_back(VK_MVK_MACOS_SURFACE_EXTENSION_NAME); + extensions.push_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME); #else bool found_surface_ext = false; #ifdef HAVE_X11 @@ -187,15 +188,32 @@ namespace vk if (g_cfg.video.debug_output) layers.push_back("VK_LAYER_KHRONOS_validation"); } +#ifdef __APPLE__ + // MoltenVK's ICD will not be detected without these extensions enabled. + else + { + extensions_loaded = true; + extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); + extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + } +#endif VkInstanceCreateInfo instance_info = {}; instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instance_info.pApplicationInfo = &app; instance_info.enabledLayerCount = static_cast(layers.size()); instance_info.ppEnabledLayerNames = layers.data(); +#ifdef __APPLE__ + instance_info.enabledExtensionCount = static_cast(extensions.size()); + instance_info.ppEnabledExtensionNames = extensions.data(); +#else instance_info.enabledExtensionCount = fast ? 0 : static_cast(extensions.size()); instance_info.ppEnabledExtensionNames = fast ? nullptr : extensions.data(); +#endif instance_info.pNext = next_info; +#ifdef __APPLE__ + instance_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; +#endif if (VkResult result = vkCreateInstance(&instance_info, nullptr, &m_instance); result != VK_SUCCESS) { diff --git a/rpcs3/Emu/RSX/VK/vkutils/metal_layer.h b/rpcs3/Emu/RSX/VK/vkutils/metal_layer.h new file mode 100644 index 0000000000..d587b55bf7 --- /dev/null +++ b/rpcs3/Emu/RSX/VK/vkutils/metal_layer.h @@ -0,0 +1,2 @@ +#pragma once +void* GetCAMetalLayerFromMetalView(void* view); diff --git a/rpcs3/Emu/RSX/VK/vkutils/metal_layer.mm b/rpcs3/Emu/RSX/VK/vkutils/metal_layer.mm new file mode 100644 index 0000000000..5c593bc5b6 --- /dev/null +++ b/rpcs3/Emu/RSX/VK/vkutils/metal_layer.mm @@ -0,0 +1,10 @@ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wold-style-cast" +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#pragma GCC diagnostic ignored "-Wmissing-declarations" +#import +#import +#import + +void* GetCAMetalLayerFromMetalView(void* view) { return ((NSView*)view).layer; } +#pragma GCC diagnostic pop diff --git a/rpcs3/Emu/RSX/VK/vkutils/swapchain_macos.hpp b/rpcs3/Emu/RSX/VK/vkutils/swapchain_macos.hpp index 9e4217692d..e4485324d5 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/swapchain_macos.hpp +++ b/rpcs3/Emu/RSX/VK/vkutils/swapchain_macos.hpp @@ -1,6 +1,7 @@ #pragma once #include "swapchain_core.h" +#include "metal_layer.h" namespace vk { @@ -12,11 +13,11 @@ namespace vk VkSurfaceKHR make_WSI_surface(VkInstance vk_instance, display_handle_t window_handle, WSI_config* /*config*/) { VkSurfaceKHR result = VK_NULL_HANDLE; - VkMacOSSurfaceCreateInfoMVK createInfo = {}; - createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; - createInfo.pView = window_handle; + VkMetalSurfaceCreateInfoEXT createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; + createInfo.pLayer = GetCAMetalLayerFromMetalView(window_handle); - CHECK_RESULT(vkCreateMacOSSurfaceMVK(vk_instance, &createInfo, NULL, &result)); + CHECK_RESULT(vkCreateMetalSurfaceEXT(vk_instance, &createInfo, NULL, &result)); return result; } #endif