diff --git a/src/Cafe/CafeSystem.cpp b/src/Cafe/CafeSystem.cpp index 7ba93fc8..a0c072b5 100644 --- a/src/Cafe/CafeSystem.cpp +++ b/src/Cafe/CafeSystem.cpp @@ -257,7 +257,7 @@ void InfoLog_PrintActiveSettings() else if (ActiveSettings::GetGraphicsAPI() == GraphicAPI::kMetal) { cemuLog_log(LogType::Force, "Async compile: {}", GetConfig().async_compile.GetValue() ? "true" : "false"); - cemuLog_log(LogType::Force, "Fast math: {}", GetConfig().fast_math.GetValue() ? "true" : "false"); + cemuLog_log(LogType::Force, "Fast math: {}", g_current_game_profile->GetFastMath() ? "true" : "false"); cemuLog_log(LogType::Force, "Buffer cache type: {}", g_current_game_profile->GetBufferCacheType()); if (!GetConfig().vk_accurate_barriers.GetValue()) cemuLog_log(LogType::Force, "Accurate barriers are disabled!"); diff --git a/src/Cafe/GameProfile/GameProfile.cpp b/src/Cafe/GameProfile/GameProfile.cpp index a4ce8fe8..9389b279 100644 --- a/src/Cafe/GameProfile/GameProfile.cpp +++ b/src/Cafe/GameProfile/GameProfile.cpp @@ -226,6 +226,7 @@ bool GameProfile::Load(uint64_t title_id) m_graphics_api = (GraphicAPI)graphicsApi.value; gameProfile_loadEnumOption(iniParser, "accurateShaderMul", m_accurateShaderMul); + gameProfile_loadBooleanOption2(iniParser, "fastMath", m_fastMath); gameProfile_loadEnumOption(iniParser, "bufferCacheType", m_bufferCacheType); // legacy support @@ -309,6 +310,7 @@ void GameProfile::Save(uint64_t title_id) fs->writeLine("[Graphics]"); WRITE_ENTRY(accurateShaderMul); + WRITE_ENTRY(fastMath); WRITE_ENTRY(bufferCacheType); WRITE_OPTIONAL_ENTRY(precompiledShaders); WRITE_OPTIONAL_ENTRY(graphics_api); @@ -339,6 +341,7 @@ void GameProfile::ResetOptional() // graphic settings m_accurateShaderMul = AccurateShaderMulOption::True; + m_fastMath = true; m_bufferCacheType = BufferCacheType::DevicePrivate; // cpu settings m_threadQuantum = kThreadQuantumDefault; @@ -360,6 +363,7 @@ void GameProfile::Reset() // graphic settings m_accurateShaderMul = AccurateShaderMulOption::True; + m_fastMath = true; m_bufferCacheType = BufferCacheType::DevicePrivate; m_precompiledShaders = PrecompiledShaderOption::Auto; // cpu settings diff --git a/src/Cafe/GameProfile/GameProfile.h b/src/Cafe/GameProfile/GameProfile.h index 5c2d28d7..0f68bc3a 100644 --- a/src/Cafe/GameProfile/GameProfile.h +++ b/src/Cafe/GameProfile/GameProfile.h @@ -31,6 +31,7 @@ public: [[nodiscard]] const std::optional& GetGraphicsAPI() const { return m_graphics_api; } [[nodiscard]] const AccurateShaderMulOption& GetAccurateShaderMul() const { return m_accurateShaderMul; } + [[nodiscard]] bool GetFastMath() const { return m_fastMath; } [[nodiscard]] BufferCacheType GetBufferCacheType() const { return m_bufferCacheType; } [[nodiscard]] const std::optional& GetPrecompiledShadersState() const { return m_precompiledShaders; } @@ -55,6 +56,7 @@ private: // graphic settings std::optional m_graphics_api{}; AccurateShaderMulOption m_accurateShaderMul = AccurateShaderMulOption::True; + bool m_fastMath = false; BufferCacheType m_bufferCacheType = BufferCacheType::DevicePrivate; std::optional m_precompiledShaders{}; // cpu settings diff --git a/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp b/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp index c8babb14..f8b5efe9 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp @@ -1,12 +1,12 @@ #include "Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.h" #include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h" #include "Cafe/HW/Latte/Renderer/Metal/MetalCommon.h" + //#include "Cemu/FileCache/FileCache.h" //#include "config/ActiveSettings.h" - #include "Cemu/Logging/CemuLogging.h" #include "Common/precompiled.h" -#include "config/CemuConfig.h" +#include "GameProfile/GameProfile.h" #include "util/helpers/helpers.h" static bool s_isLoadingShadersMtl{false}; @@ -174,7 +174,7 @@ void RendererShaderMtl::CompileInternal() { MTL::CompileOptions* options = MTL::CompileOptions::alloc()->init(); // TODO: always disable fast math for problematic shaders - if (GetConfig().fast_math) + if (g_current_game_profile->GetFastMath()) options->setFastMathEnabled(true); NS::Error* error = nullptr; diff --git a/src/config/CemuConfig.cpp b/src/config/CemuConfig.cpp index 06ad94d5..64c2f355 100644 --- a/src/config/CemuConfig.cpp +++ b/src/config/CemuConfig.cpp @@ -219,7 +219,6 @@ void CemuConfig::Load(XMLConfigParser& parser) downscale_filter = graphic.get("DownscaleFilter", kLinearFilter); fullscreen_scaling = graphic.get("FullscreenScaling", kKeepAspectRatio); async_compile = graphic.get("AsyncCompile", async_compile); - fast_math = graphic.get("FastMath", fast_math); vk_accurate_barriers = graphic.get("vkAccurateBarriers", true); // this used to be "VulkanAccurateBarriers" but because we changed the default to true in 1.27.1 the option name had to be changed auto overlay_node = graphic.get("Overlay"); @@ -476,7 +475,6 @@ void CemuConfig::Save(XMLConfigParser& parser) graphic.set("DownscaleFilter", downscale_filter); graphic.set("FullscreenScaling", fullscreen_scaling); graphic.set("AsyncCompile", async_compile.GetValue()); - graphic.set("FastMath", fast_math.GetValue()); graphic.set("vkAccurateBarriers", vk_accurate_barriers); auto overlay_node = graphic.set("Overlay"); diff --git a/src/config/CemuConfig.h b/src/config/CemuConfig.h index 02dc873a..32c87aa6 100644 --- a/src/config/CemuConfig.h +++ b/src/config/CemuConfig.h @@ -467,7 +467,6 @@ struct CemuConfig ConfigValue gx2drawdone_sync {true}; ConfigValue render_upside_down{ false }; ConfigValue async_compile{ true }; - ConfigValue fast_math{ true }; ConfigValue vk_accurate_barriers{ true }; diff --git a/src/gui/GameProfileWindow.cpp b/src/gui/GameProfileWindow.cpp index f54a8fb4..b26a866d 100644 --- a/src/gui/GameProfileWindow.cpp +++ b/src/gui/GameProfileWindow.cpp @@ -128,9 +128,16 @@ GameProfileWindow::GameProfileWindow(wxWindow* parent, uint64_t title_id) m_shader_mul_accuracy->SetToolTip(_("EXPERT OPTION\nControls the accuracy of floating point multiplication in shaders.\n\nRecommended: true")); first_row->Add(m_shader_mul_accuracy, 0, wxALL, 5); + first_row->Add(new wxStaticText(panel, wxID_ANY, _("Fast math")), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); + + wxString math_values[] = { _("false"), _("true") }; + m_fast_math = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, (int)std::size(math_values), math_values); + m_fast_math->SetToolTip(_("Enables fast math for all shaders. May (rarely) cause graphical bugs.\n\nMetal only\n\nRecommended: true")); + first_row->Add(m_fast_math, 0, wxALL, 5); + first_row->Add(new wxStaticText(panel, wxID_ANY, _("Buffer cache type")), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); - wxString cache_values[] = { _("device private"), _("device shared"), _("host")}; + wxString cache_values[] = { _("device private"), _("device shared"), _("host") }; m_buffer_cache_type = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, (int)std::size(cache_values), cache_values); m_buffer_cache_type->SetToolTip(_("EXPERT OPTION\nDecides how the buffer cache memory will be managed.\n\nMetal only\n\nRecommended: device private")); first_row->Add(m_buffer_cache_type, 0, wxALL, 5); @@ -281,6 +288,7 @@ void GameProfileWindow::ApplyProfile() else m_graphic_api->SetSelection(1 + m_game_profile.m_graphics_api.value()); // "", OpenGL, Vulkan, Metal m_shader_mul_accuracy->SetSelection((int)m_game_profile.m_accurateShaderMul); + m_fast_math->SetSelection((int)m_game_profile.m_fastMath); m_buffer_cache_type->SetSelection((int)m_game_profile.m_bufferCacheType); //// audio @@ -341,6 +349,7 @@ void GameProfileWindow::SaveProfile() // gpu m_game_profile.m_accurateShaderMul = (AccurateShaderMulOption)m_shader_mul_accuracy->GetSelection(); + m_game_profile.m_fastMath = (bool)m_fast_math->GetSelection(); m_game_profile.m_bufferCacheType = (BufferCacheType)m_buffer_cache_type->GetSelection(); if (m_game_profile.m_accurateShaderMul != AccurateShaderMulOption::False && m_game_profile.m_accurateShaderMul != AccurateShaderMulOption::True) m_game_profile.m_accurateShaderMul = AccurateShaderMulOption::True; // force a legal value diff --git a/src/gui/GameProfileWindow.h b/src/gui/GameProfileWindow.h index 22eda48d..88d5b438 100644 --- a/src/gui/GameProfileWindow.h +++ b/src/gui/GameProfileWindow.h @@ -40,6 +40,7 @@ private: wxChoice* m_graphic_api; wxChoice* m_shader_mul_accuracy; + wxChoice* m_fast_math; wxChoice* m_buffer_cache_type; //wxChoice* m_cache_accuracy; diff --git a/src/gui/GeneralSettings2.cpp b/src/gui/GeneralSettings2.cpp index 4812a884..8b6e0ee1 100644 --- a/src/gui/GeneralSettings2.cpp +++ b/src/gui/GeneralSettings2.cpp @@ -344,10 +344,6 @@ wxPanel* GeneralSettings2::AddGraphicsPage(wxNotebook* notebook) m_async_compile->SetToolTip(_("Enables async shader and pipeline compilation. Reduces stutter at the cost of objects not rendering for a short time.\nVulkan only")); graphic_misc_row->Add(m_async_compile, 0, wxALL, 5); - m_fast_math = new wxCheckBox(box, wxID_ANY, _("Fast math")); - m_fast_math->SetToolTip(_("Enables fast math for all shaders. May cause minor inaccuracies in some games.\nMetal only")); - graphic_misc_row->Add(m_fast_math, 0, wxALL, 5); - m_gx2drawdone_sync = new wxCheckBox(box, wxID_ANY, _("Full sync at GX2DrawDone()")); m_gx2drawdone_sync->SetToolTip(_("If synchronization is requested by the game, the emulated CPU will wait for the GPU to finish all operations.\nThis is more accurate behavior, but may cause lower performance")); graphic_misc_row->Add(m_gx2drawdone_sync, 0, wxALL, 5); @@ -1042,7 +1038,6 @@ void GeneralSettings2::StoreConfig() config.vsync = m_vsync->GetSelection(); config.gx2drawdone_sync = m_gx2drawdone_sync->IsChecked(); config.async_compile = m_async_compile->IsChecked(); - config.fast_math = m_fast_math->IsChecked(); config.upscale_filter = m_upscale_filter->GetSelection(); config.downscale_filter = m_downscale_filter->GetSelection(); @@ -1520,14 +1515,12 @@ void GeneralSettings2::HandleGraphicsApiSelection() m_gx2drawdone_sync->Enable(); m_async_compile->Disable(); - m_fast_math->Disable(); } else if (m_graphic_api->GetSelection() == 1) { // Vulkan m_gx2drawdone_sync->Disable(); m_async_compile->Enable(); - m_fast_math->Disable(); m_vsync->AppendString(_("Off")); m_vsync->AppendString(_("Double buffering")); @@ -1565,7 +1558,6 @@ void GeneralSettings2::HandleGraphicsApiSelection() // Metal m_gx2drawdone_sync->Disable(); m_async_compile->Enable(); - m_fast_math->Enable(); // TODO: vsync options m_vsync->AppendString(_("Off")); @@ -1629,7 +1621,6 @@ void GeneralSettings2::ApplyConfig() m_graphic_api->SetSelection(config.graphic_api); m_vsync->SetSelection(config.vsync); m_async_compile->SetValue(config.async_compile); - m_fast_math->SetValue(config.fast_math); m_gx2drawdone_sync->SetValue(config.gx2drawdone_sync); m_upscale_filter->SetSelection(config.upscale_filter); m_downscale_filter->SetSelection(config.downscale_filter); diff --git a/src/gui/GeneralSettings2.h b/src/gui/GeneralSettings2.h index 01c4845f..83ede03b 100644 --- a/src/gui/GeneralSettings2.h +++ b/src/gui/GeneralSettings2.h @@ -52,7 +52,7 @@ private: // Graphics wxChoice* m_graphic_api, * m_graphic_device; wxChoice* m_vsync; - wxCheckBox *m_async_compile, *m_fast_math, *m_gx2drawdone_sync; + wxCheckBox *m_async_compile, *m_gx2drawdone_sync; wxRadioBox* m_upscale_filter, *m_downscale_filter, *m_fullscreen_scaling; wxChoice* m_overlay_position, *m_notification_position, *m_overlay_scale, *m_notification_scale; wxCheckBox* m_controller_profile_name, *m_controller_low_battery, *m_shader_compiling, *m_friends_data;