From f21b298e5e545c0da43b0529489e9e7abab1440c Mon Sep 17 00:00:00 2001 From: nastys Date: Tue, 19 Apr 2022 04:13:02 +0200 Subject: [PATCH] Make MSL Fast Math and software vkSemaphore optional --- .ci/build-mac.sh | 1 + 3rdparty/MoltenVK/CMakeLists.txt | 7 ++++--- 3rdparty/MoltenVK/patches.patch | 7 +++++++ rpcs3/Emu/RSX/VK/vkutils/device.cpp | 7 ++++--- rpcs3/Emu/system_config.h | 3 ++- rpcs3/Emu/system_config_types.cpp | 17 ----------------- rpcs3/Emu/system_config_types.h | 8 -------- rpcs3/rpcs3qt/emu_settings.cpp | 9 --------- rpcs3/rpcs3qt/emu_settings_type.h | 6 ++++-- rpcs3/rpcs3qt/settings_dialog.cpp | 17 ++++++++++------- rpcs3/rpcs3qt/settings_dialog.ui | 26 ++++++++++++++------------ rpcs3/rpcs3qt/tooltips.h | 3 ++- 12 files changed, 48 insertions(+), 63 deletions(-) create mode 100644 3rdparty/MoltenVK/patches.patch diff --git a/.ci/build-mac.sh b/.ci/build-mac.sh index 6b1ad01217..0f63a08605 100755 --- a/.ci/build-mac.sh +++ b/.ci/build-mac.sh @@ -24,6 +24,7 @@ cmake .. \ -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF \ -DLLVM_INCLUDE_UTILS=OFF -DLLVM_USE_PERF=OFF -DLLVM_ENABLE_Z3_SOLVER=OFF \ -DUSE_NATIVE_INSTRUCTIONS=OFF \ + -DUSE_SYSTEM_MVK=OFF \ -G Ninja ninja; build_status=$?; diff --git a/3rdparty/MoltenVK/CMakeLists.txt b/3rdparty/MoltenVK/CMakeLists.txt index b97e1983db..5fb379c642 100644 --- a/3rdparty/MoltenVK/CMakeLists.txt +++ b/3rdparty/MoltenVK/CMakeLists.txt @@ -1,14 +1,15 @@ -cmake_minimum_required(VERSION 2.8.2) +cmake_minimum_required(VERSION 2.8.12) project(moltenvk NONE) include(ExternalProject) ExternalProject_Add(moltenvk GIT_REPOSITORY https://github.com/KhronosGroup/MoltenVK.git - GIT_TAG 9cfc946 + GIT_TAG 1236d2f BUILD_IN_SOURCE 1 SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK + PATCH_COMMAND git apply "${CMAKE_CURRENT_SOURCE_DIR}/patches.patch" CONFIGURE_COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/fetchDependencies" --macos - BUILD_COMMAND xcodebuild build -quiet -project "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVKPackaging.xcodeproj" -scheme "MoltenVK Package \(macOS only\)" -configuration "Release" -arch "x86_64" MVK_CONFIG_RESUME_LOST_DEVICE=1 + BUILD_COMMAND xcodebuild build -quiet -project "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVKPackaging.xcodeproj" -scheme "MoltenVK Package \(macOS only\)" -configuration "Release" -arch "x86_64" COMMAND ln -f "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVK/dylib/macOS/libMoltenVK.dylib" "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/Build/Products/Release/dynamic/libMoltenVK.dylib" INSTALL_COMMAND "" BUILD_BYPRODUCTS "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/Build/Products/Release/dynamic/libMoltenVK.dylib" diff --git a/3rdparty/MoltenVK/patches.patch b/3rdparty/MoltenVK/patches.patch new file mode 100644 index 0000000000..623d0acc34 --- /dev/null +++ b/3rdparty/MoltenVK/patches.patch @@ -0,0 +1,7 @@ +diff --git a/ExternalRevisions/SPIRV-Cross_repo_revision b/ExternalRevisions/SPIRV-Cross_repo_revision +index 777346a0..c1971b45 100644 +--- a/ExternalRevisions/SPIRV-Cross_repo_revision ++++ b/ExternalRevisions/SPIRV-Cross_repo_revision +@@ -1 +1 @@ +-0d4ce028bf8b8a94d325dc1e1c20446153ba19c4 ++44c3333a1c315ead00c24f7aef5fa8a7ccf49299 diff --git a/rpcs3/Emu/RSX/VK/vkutils/device.cpp b/rpcs3/Emu/RSX/VK/vkutils/device.cpp index 6794e713a2..4e5570f243 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/device.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/device.cpp @@ -141,14 +141,15 @@ namespace vk CHECK_RESULT_EX(_vkGetMoltenVKConfigurationMVK(VK_NULL_HANDLE, &mvk_config, &mvk_config_size), std::string("Could not get MoltenVK configuration.")); - mvk_config.semaphoreUseMTLEvent = (g_cfg.video.vk.metal_semaphore == vk_metal_semaphore_mode::mtlevent_preferred || g_cfg.video.vk.metal_semaphore == vk_metal_semaphore_mode::mtlevent); - mvk_config.semaphoreUseMTLFence = (g_cfg.video.vk.metal_semaphore == vk_metal_semaphore_mode::mtlevent_preferred || g_cfg.video.vk.metal_semaphore == vk_metal_semaphore_mode::mtlfence); + mvk_config.resumeLostDevice = true; + mvk_config.semaphoreUseMTLEvent = mvk_config.semaphoreUseMTLFence = !(g_cfg.video.mvk_software_vksemaphore.get()); + mvk_config.fastMathEnabled = !(g_cfg.video.disable_msl_fast_math.get()); CHECK_RESULT_EX(_vkSetMoltenVKConfigurationMVK(VK_NULL_HANDLE, &mvk_config, &mvk_config_size), std::string("Could not set MoltenVK configuration.")); } else { - rsx_log.error("Cannot set Metal Semaphore because VK_MVK_moltenvk is not supported.\nIf you're using MoltenVK through libvulkan, manually set the MVK_ALLOW_METAL_EVENTS and/or MVK_ALLOW_METAL_FENCES environment variables instead."); + rsx_log.error("Cannot set the MoltenVK configuration because VK_MVK_moltenvk is not supported.\nIf you're using MoltenVK through libvulkan, please manually set the appropriate environment variables instead."); } #endif diff --git a/rpcs3/Emu/system_config.h b/rpcs3/Emu/system_config.h index 17be037760..e6bd9c6883 100644 --- a/rpcs3/Emu/system_config.h +++ b/rpcs3/Emu/system_config.h @@ -158,6 +158,8 @@ struct cfg_root : cfg::node cfg::_bool vblank_ntsc{ this, "Vblank NTSC Fixup", false, true }; cfg::_bool decr_memory_layout{ this, "DECR memory layout", false}; // Force enable increased allowed main memory range as DECR console cfg::_bool host_label_synchronization{ this, "Allow Host GPU Labels", false }; + cfg::_bool disable_msl_fast_math{ this, "Disable MSL Fast Math", false }; + cfg::_bool mvk_software_vksemaphore{ this, "Software VkSemaphore", false }; struct node_vk : cfg::node { @@ -171,7 +173,6 @@ struct cfg_root : cfg::node cfg::_bool fsr_upscaling{ this, "Enable FidelityFX Super Resolution Upscaling", false, true }; cfg::uint<0, 100> rcas_sharpening_intensity{ this, "FidelityFX CAS Sharpening Intensity", 50, true }; cfg::_enum asynchronous_scheduler{ this, "Asynchronous Queue Scheduler", vk_gpu_scheduler_mode::safe }; - cfg::_enum metal_semaphore{ this, "Metal Semaphore", vk_metal_semaphore_mode::mtlevent_preferred }; } vk{ this }; diff --git a/rpcs3/Emu/system_config_types.cpp b/rpcs3/Emu/system_config_types.cpp index cdafc4efc7..7432b6506d 100644 --- a/rpcs3/Emu/system_config_types.cpp +++ b/rpcs3/Emu/system_config_types.cpp @@ -544,23 +544,6 @@ void fmt_class_string::format(std::string& out, u64 arg) }); } -template <> -void fmt_class_string::format(std::string& out, u64 arg) -{ - format_enum(out, arg, [](vk_metal_semaphore_mode value) - { - switch (value) - { - case vk_metal_semaphore_mode::software: return "Software emulation"; - case vk_metal_semaphore_mode::mtlevent_preferred: return "MTLEvent preferred"; - case vk_metal_semaphore_mode::mtlevent: return "MTLEvent"; - case vk_metal_semaphore_mode::mtlfence: return "MTLFence"; - } - - return unknown; - }); -} - template <> void fmt_class_string::format(std::string& out, u64 arg) { diff --git a/rpcs3/Emu/system_config_types.h b/rpcs3/Emu/system_config_types.h index ee78d0723f..1b8e26a139 100644 --- a/rpcs3/Emu/system_config_types.h +++ b/rpcs3/Emu/system_config_types.h @@ -238,14 +238,6 @@ enum class vk_gpu_scheduler_mode fast }; -enum class vk_metal_semaphore_mode -{ - software, - mtlevent_preferred, - mtlevent, - mtlfence -}; - enum class thread_scheduler_mode { os, diff --git a/rpcs3/rpcs3qt/emu_settings.cpp b/rpcs3/rpcs3qt/emu_settings.cpp index 06b6b7bd0b..a3a69b7d5d 100644 --- a/rpcs3/rpcs3qt/emu_settings.cpp +++ b/rpcs3/rpcs3qt/emu_settings.cpp @@ -1167,15 +1167,6 @@ QString emu_settings::GetLocalizedSetting(const QString& original, emu_settings_ case vk_gpu_scheduler_mode::fast: return tr("Fast"); } break; - case emu_settings_type::MetalSemaphore: - switch (static_cast(index)) - { - case vk_metal_semaphore_mode::software: return tr("Software emulation"); - case vk_metal_semaphore_mode::mtlevent_preferred: return tr("MTLEvent preferred"); - case vk_metal_semaphore_mode::mtlevent: return tr("MTLEvent"); - case vk_metal_semaphore_mode::mtlfence: return tr("MTLFence"); - } - break; default: break; } diff --git a/rpcs3/rpcs3qt/emu_settings_type.h b/rpcs3/rpcs3qt/emu_settings_type.h index 512d45dd98..627db386c3 100644 --- a/rpcs3/rpcs3qt/emu_settings_type.h +++ b/rpcs3/rpcs3qt/emu_settings_type.h @@ -91,7 +91,8 @@ enum class emu_settings_type VulkanAsyncTextureUploads, VulkanAsyncSchedulerDriver, AllowHostGPULabels, - MetalSemaphore, + DisableMSLFastMath, + SoftwareVkSemaphore, // Performance Overlay PerfOverlayEnabled, @@ -250,13 +251,14 @@ inline static const QMap settings_location = { emu_settings_type::VBlankRate, { "Video", "Vblank Rate"}}, { emu_settings_type::DriverWakeUpDelay, { "Video", "Driver Wake-Up Delay"}}, { emu_settings_type::AllowHostGPULabels, { "Video", "Allow Host GPU Labels"}}, + { emu_settings_type::DisableMSLFastMath, { "Video", "Disable MSL Fast Math"}}, + { emu_settings_type::SoftwareVkSemaphore, { "Video", "Software VkSemaphore"}}, // Vulkan { emu_settings_type::VulkanAsyncTextureUploads, { "Video", "Vulkan", "Asynchronous Texture Streaming 2"}}, { emu_settings_type::VulkanAsyncSchedulerDriver, { "Video", "Vulkan", "Asynchronous Queue Scheduler"}}, { emu_settings_type::FsrUpscalingEnable, { "Video", "Vulkan", "Enable FidelityFX Super Resolution Upscaling"}}, { emu_settings_type::FsrSharpeningStrength, { "Video", "Vulkan", "FidelityFX CAS Sharpening Intensity"}}, - { emu_settings_type::MetalSemaphore, { "Video", "Vulkan", "Metal Semaphore"}}, // Performance Overlay { emu_settings_type::PerfOverlayEnabled, { "Video", "Performance Overlay", "Enabled" } }, diff --git a/rpcs3/rpcs3qt/settings_dialog.cpp b/rpcs3/rpcs3qt/settings_dialog.cpp index 7cb40ddfb7..e1a713db69 100644 --- a/rpcs3/rpcs3qt/settings_dialog.cpp +++ b/rpcs3/rpcs3qt/settings_dialog.cpp @@ -1241,6 +1241,16 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std m_emu_settings->SetSetting(emu_settings_type::MFCCommandsShuffling, str); }); + m_emu_settings->EnhanceCheckBox(ui->disableMslFastMath, emu_settings_type::DisableMSLFastMath); + m_emu_settings->EnhanceCheckBox(ui->softwareVkSemaphore, emu_settings_type::SoftwareVkSemaphore); +#ifdef __APPLE__ + SubscribeTooltip(ui->disableMslFastMath, tooltips.settings.disable_msl_fast_math); + SubscribeTooltip(ui->softwareVkSemaphore, tooltips.settings.mvk_software_vksemaphore); +#else + ui->disableMslFastMath->setVisible(false); + ui->softwareVkSemaphore->setVisible(false); +#endif + // Comboboxes m_emu_settings->EnhanceComboBox(ui->maxSPURSThreads, emu_settings_type::MaxSPURSThreads, true); @@ -1253,13 +1263,6 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std m_emu_settings->EnhanceComboBox(ui->vulkansched, emu_settings_type::VulkanAsyncSchedulerDriver); SubscribeTooltip(ui->gb_vulkansched, tooltips.settings.vulkan_async_scheduler); - m_emu_settings->EnhanceComboBox(ui->metalsemaphore, emu_settings_type::MetalSemaphore); -#ifdef __APPLE__ - SubscribeTooltip(ui->gb_metalsemaphore, tooltips.settings.metal_semaphore); -#else - ui->gb_metalsemaphore->setVisible(false); -#endif - // Sliders EnhanceSlider(emu_settings_type::DriverWakeUpDelay, ui->wakeupDelay, ui->wakeupText, tr(reinterpret_cast(u8"%0 µs"), "Driver wake up delay")); diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index ce3534d9d6..3661377819 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -2386,6 +2386,20 @@ + + + + Disable MSL Fast Math + + + + + + + Software VkSemaphore + + + @@ -3959,18 +3973,6 @@ - - - - Metal Semaphore - - - - - - - - diff --git a/rpcs3/rpcs3qt/tooltips.h b/rpcs3/rpcs3qt/tooltips.h index 7a5349348a..4365e36cf9 100644 --- a/rpcs3/rpcs3qt/tooltips.h +++ b/rpcs3/rpcs3qt/tooltips.h @@ -39,6 +39,8 @@ public: const QString disabled_from_global = tr("Do not change this setting globally.\nRight-click a game in the game list and choose \"Configure\" instead."); const QString vulkan_async_scheduler = tr("Determines how to schedule GPU async compute jobs when using asynchronous streaming.\nUse 'Safe' mode for more spec compliant behavior at the cost of some CPU overhead. This setting works with all devices.\nUse 'Fast' to use a faster but hacky version. This option is internally disabled for NVIDIA GPUs due to causing GPU hangs."); const QString allow_host_labels = tr("Allows the host GPU to synchronize with CELL directly. This incurs a performance penalty, but exposes the true state of GPU objects to the guest CPU. Can help eliminate visual noise and glitching at the cost of performance. Use with caution."); + const QString disable_msl_fast_math = tr("Disables Fast Math for MSL shaders, which may violate the IEEE 754 standard.\nDisabling it may fix some artefacts especially on Apple GPUs, at the cost of performance."); + const QString mvk_software_vksemaphore = tr("Emulates VkSemaphore purely in software instead of using MTLEvent/MTLFence.\nEnabling this might fix artefacts caused by synchronization issues, but can cause tearing and usually has a very high performance cost.\nMainly affects Apple GPUs when running the emulator using Rosetta."); // audio @@ -107,7 +109,6 @@ public: const QString accurate_ppu_128_loop = tr("When enabled, PPU atomic operations will operate on entire cache line data, as opposed to a single 64bit block of memory when disabled.\nNumerical values control whether or not to enable the accurate version based on the atomic operation's length."); const QString enable_performance_report = tr("Measure certain events and print a chart after the emulator is stopped. Don't enable if not asked to."); const QString num_ppu_threads = tr("Affects maximum amount of PPU threads running concurrently, the value of 1 has very low compatibility with games.\n2 is the default, if unsure do not modify this setting."); - const QString metal_semaphore = tr("Determines how MoltenVK will simulate vkSemaphore on the Metal API.\nSoftware emulation is the slowest, but most accurate option. However, it can cause tearing.\nMTLEvent is faster, but not available under Rosetta (if MTLEvent preferred is selected, MTLFence is used; otherwise, emulation is used).\nMTLFence is faster than emulation, but can randomly cause synchronization issues."); // emulator