From d6121a43ea614045d83d054fbdcf99764b8d096c Mon Sep 17 00:00:00 2001 From: Stan Date: Thu, 26 Jan 2023 15:24:12 +0000 Subject: [PATCH] Add MoltenVK support to fix Vulkan on macOS. Tested by: @Langbart, @real_tabasco_sauce, @wraitii Refs #6636 Differential Revision: https://code.wildfiregames.com/D4905 This was SVN commit r27488. --- libraries/osx/build-osx-libs.sh | 28 +++++++++++++++++++++++++++ source/ps/DllLoader.cpp | 7 +++---- source/ps/DllLoader.h | 5 ++++- source/ps/VideoMode.cpp | 25 ++++++++++++++++++++++++ source/tools/dist/build-osx-bundle.py | 1 + 5 files changed, 61 insertions(+), 5 deletions(-) diff --git a/libraries/osx/build-osx-libs.sh b/libraries/osx/build-osx-libs.sh index abb9374d6f..139d2a582b 100755 --- a/libraries/osx/build-osx-libs.sh +++ b/libraries/osx/build-osx-libs.sh @@ -48,6 +48,7 @@ ENET_VERSION="enet-1.3.17" MINIUPNPC_VERSION="miniupnpc-2.2.2" SODIUM_VERSION="libsodium-1.0.18" FMT_VERSION="7.1.3" +MOLTENVK_VERSION="1.2.2" # -------------------------------------------------------------- # Bundled with the game: # * SpiderMonkey @@ -1039,6 +1040,33 @@ else fi popd > /dev/null +# -------------------------------------------------------------- +echo -e "Building Molten VK..." +LIB_DIRECTORY="MoltenVK-$MOLTENVK_VERSION" +LIB_ARCHIVE="MoltenVK-$MOLTENVK_VERSION.tar.gz" +LIB_URL="https://releases.wildfiregames.com/libs/" + +mkdir -p "molten-vk" +pushd "molten-vk" > /dev/null +if [[ "$force_rebuild" = "true" ]] || [[ ! -e .already-built ]] || [[ "$(<.already-built)" != "$MOLTENVK_VERSION" ]] +then + INSTALL_DIR="../../../../binaries/system/" + rm -f .already-built + download_lib $LIB_URL $LIB_ARCHIVE + rm -rf "$LIB_DIRECTORY" + tar -xf $LIB_ARCHIVE + pushd $LIB_DIRECTORY + # The CI cannot build MoltenVK so we provide prebuild binaries instead. + # Use mv instead of copy to preserve binary signature integrity. See: + # https://developer.apple.com/forums/thread/130313?answerId=410541022#410541022 + mv dylib/libMoltenVK.dylib $INSTALL_DIR + popd > /dev/null + echo "$MOLTENVK_VERSION" > .already-built +else + already_built +fi +popd > /dev/null + # -------------------------------------------------------------------- # The following libraries are shared on different OSes and may # be customized, so we build and install them from bundled sources diff --git a/source/ps/DllLoader.cpp b/source/ps/DllLoader.cpp index c026157377..928ffb4cbd 100644 --- a/source/ps/DllLoader.cpp +++ b/source/ps/DllLoader.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -21,7 +21,6 @@ #include "lib/timer.h" #include "lib/posix/posix_dlfcn.h" -#include "ps/CStr.h" #if OS_MACOSX # include "lib/sysdep/os/osx/osx_bundle.h" @@ -69,7 +68,7 @@ static CStr extensions[] = { // the naming/location convention above - it'll need to be changed if we want // to support other DLLs.) -static CStr GenerateFilename(const CStr& name, const CStr& suffix, const CStr& extension) +CStr DllLoader::GenerateFilename(const CStr& name, const CStr& suffix, const CStr& extension) { CStr n; @@ -114,7 +113,7 @@ static void* LoadAnyVariant(const CStr& name, std::stringstream& errors) { for (size_t idxExtension = 0; idxExtension < ARRAY_SIZE(extensions); idxExtension++) { - CStr filename = GenerateFilename(name, suffixes[idxSuffix], extensions[idxExtension]); + CStr filename = DllLoader::GenerateFilename(name, suffixes[idxSuffix], extensions[idxExtension]); // we don't really care when relocations take place, but one of // {RTLD_NOW, RTLD_LAZY} must be specified. go with the former because diff --git a/source/ps/DllLoader.h b/source/ps/DllLoader.h index 2f360f102a..e3f67b2d7d 100644 --- a/source/ps/DllLoader.h +++ b/source/ps/DllLoader.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -20,6 +20,7 @@ #include "ps/Errors.h" #include "ps/CLogger.h" +#include "ps/CStr.h" ERROR_GROUP(DllLoader); ERROR_TYPE(DllLoader, DllNotLoaded); @@ -76,6 +77,8 @@ public: */ static void OverrideLibdir(const char* libdir); + static CStr GenerateFilename(const CStr& name, const CStr& suffix, const CStr& extension); + private: // Typeless version - the public LoadSymbol hides the slightly ugly // casting from users. diff --git a/source/ps/VideoMode.cpp b/source/ps/VideoMode.cpp index 7ef4e9d7f7..eac241482a 100644 --- a/source/ps/VideoMode.cpp +++ b/source/ps/VideoMode.cpp @@ -29,6 +29,9 @@ #include "ps/CLogger.h" #include "ps/ConfigDB.h" #include "ps/CStr.h" +#if OS_MACOSX && SDL_VERSION_ATLEAST(2, 0, 6) +#include "ps/DllLoader.h" +#endif #include "ps/Filesystem.h" #include "ps/Game.h" #include "ps/GameSetup/Config.h" @@ -41,6 +44,11 @@ #include +#if OS_MACOSX && SDL_VERSION_ATLEAST(2, 0, 6) +#include +#include +#endif + namespace { @@ -391,6 +399,23 @@ bool CVideoMode::SetVideoMode(int w, int h, int bpp, bool fullscreen) flags |= SDL_WINDOW_VULKAN; m_WindowedX = m_WindowedY = SDL_WINDOWPOS_CENTERED_DISPLAY(m_ConfigDisplay); +#if OS_MACOSX && SDL_VERSION_ATLEAST(2, 0, 6) + if (m_Backend == Renderer::Backend::Backend::VULKAN) + { + // MoltenVK - enable full component swizzling support. + setenv("MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE", "1", 1); + CStr fullPathToVulkanLibrary = DllLoader::GenerateFilename("MoltenVK", "", ".dylib"); + if (SDL_Vulkan_LoadLibrary(fullPathToVulkanLibrary.c_str()) != 0) + { + LOGWARNING("Failed to load %s.", fullPathToVulkanLibrary.c_str()); + DowngradeBackendSettingAfterCreationFailure(); + return SetVideoMode(w, h, bpp, fullscreen); + } + else + LOGMESSAGE("Loaded %s.", fullPathToVulkanLibrary.c_str()); + } +#endif + m_Window = SDL_CreateWindow(main_window_name, m_WindowedX, m_WindowedY, w, h, flags); if (!m_Window) { diff --git a/source/tools/dist/build-osx-bundle.py b/source/tools/dist/build-osx-bundle.py index 994159b607..6fda6f9553 100755 --- a/source/tools/dist/build-osx-bundle.py +++ b/source/tools/dist/build-osx-bundle.py @@ -60,6 +60,7 @@ shutil.copy("binaries/system/pyrogenesis", BUNDLE_BIN) print("Copying libs") shutil.copy("binaries/system/libAtlasUI.dylib", BUNDLE_FRAMEWORKS) shutil.copy("binaries/system/libCollada.dylib", BUNDLE_FRAMEWORKS) +shutil.copy("binaries/system/libMoltenVK.dylib", BUNDLE_FRAMEWORKS) if not args.dev: print("Copying archived game data from archives/")