From 03d4e86b617835e12664a6db24a561d52d8238fc Mon Sep 17 00:00:00 2001 From: Samuliak Date: Sun, 3 Nov 2024 12:09:47 +0100 Subject: [PATCH] add an option to use the host memory instead of buffer cache --- src/Cafe/CafeSystem.cpp | 1 + src/Cafe/GameProfile/GameProfile.cpp | 14 +++++++++----- src/Cafe/GameProfile/GameProfile.h | 2 ++ .../HW/Latte/Renderer/Metal/MetalMemoryManager.cpp | 6 +++--- src/gui/GameProfileWindow.cpp | 9 +++++++++ src/gui/GameProfileWindow.h | 3 ++- 6 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/Cafe/CafeSystem.cpp b/src/Cafe/CafeSystem.cpp index 40d26a671..08228b621 100644 --- a/src/Cafe/CafeSystem.cpp +++ b/src/Cafe/CafeSystem.cpp @@ -258,6 +258,7 @@ void InfoLog_PrintActiveSettings() { 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, "Use host memory for cache: {}", g_current_game_profile->UseHostMemForCache() ? "true" : "false"); 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 ee92107a7..337786edd 100644 --- a/src/Cafe/GameProfile/GameProfile.cpp +++ b/src/Cafe/GameProfile/GameProfile.cpp @@ -127,7 +127,7 @@ bool gameProfile_loadIntegerOption(IniParser& iniParser, const char* optionName, { cemuLog_log(LogType::Force, "Value '{}' is out of range for option '{}' in game profile", *option_value, optionName); return false; - } + } } template @@ -224,8 +224,9 @@ bool GameProfile::Load(uint64_t title_id) gameProfile_loadIntegerOption(&iniParser, "graphics_api", &graphicsApi, -1, 0, 1); if (graphicsApi.value != -1) m_graphics_api = (GraphicAPI)graphicsApi.value; - + gameProfile_loadEnumOption(iniParser, "accurateShaderMul", m_accurateShaderMul); + gameProfile_loadBooleanOption2(iniParser, "useHostMemForCache", m_useHostMemForCache); // legacy support auto option_precompiledShaders = iniParser.FindOption("precompiledShaders"); @@ -277,7 +278,7 @@ bool GameProfile::Load(uint64_t title_id) void GameProfile::Save(uint64_t title_id) { auto gameProfileDir = ActiveSettings::GetConfigPath("gameProfiles"); - if (std::error_code ex_ec; !fs::exists(gameProfileDir, ex_ec)) + if (std::error_code ex_ec; !fs::exists(gameProfileDir, ex_ec)) fs::create_directories(gameProfileDir, ex_ec); auto gameProfilePath = gameProfileDir / fmt::format("{:016x}.ini", title_id); FileStream* fs = FileStream::createFile2(gameProfilePath); @@ -308,6 +309,7 @@ void GameProfile::Save(uint64_t title_id) fs->writeLine("[Graphics]"); WRITE_ENTRY(accurateShaderMul); + WRITE_ENTRY(useHostMemForCache); WRITE_OPTIONAL_ENTRY(precompiledShaders); WRITE_OPTIONAL_ENTRY(graphics_api); fs->writeLine(""); @@ -337,6 +339,7 @@ void GameProfile::ResetOptional() // graphic settings m_accurateShaderMul = AccurateShaderMulOption::True; + m_useHostMemForCache = false; // cpu settings m_threadQuantum = kThreadQuantumDefault; m_cpuMode.reset(); // CPUModeOption::kSingleCoreRecompiler; @@ -354,9 +357,10 @@ void GameProfile::Reset() // general settings m_loadSharedLibraries = true; m_startWithPadView = false; - + // graphic settings m_accurateShaderMul = AccurateShaderMulOption::True; + m_useHostMemForCache = false; m_precompiledShaders = PrecompiledShaderOption::Auto; // cpu settings m_threadQuantum = kThreadQuantumDefault; @@ -366,4 +370,4 @@ void GameProfile::Reset() // controller settings for (auto& profile : m_controllerProfile) profile.reset(); -} \ No newline at end of file +} diff --git a/src/Cafe/GameProfile/GameProfile.h b/src/Cafe/GameProfile/GameProfile.h index 6a1f2ebd6..e2ab29f7a 100644 --- a/src/Cafe/GameProfile/GameProfile.h +++ b/src/Cafe/GameProfile/GameProfile.h @@ -31,6 +31,7 @@ class GameProfile [[nodiscard]] const std::optional& GetGraphicsAPI() const { return m_graphics_api; } [[nodiscard]] const AccurateShaderMulOption& GetAccurateShaderMul() const { return m_accurateShaderMul; } + [[nodiscard]] bool UseHostMemForCache() const { return m_useHostMemForCache; } [[nodiscard]] const std::optional& GetPrecompiledShadersState() const { return m_precompiledShaders; } [[nodiscard]] uint32 GetThreadQuantum() const { return m_threadQuantum; } @@ -54,6 +55,7 @@ class GameProfile // graphic settings std::optional m_graphics_api{}; AccurateShaderMulOption m_accurateShaderMul = AccurateShaderMulOption::True; + bool m_useHostMemForCache = false; std::optional m_precompiledShaders{}; // cpu settings uint32 m_threadQuantum = kThreadQuantumDefault; // values: 20000 45000 60000 80000 100000 diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.cpp index 4eb4d1056..5f02847a8 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.cpp @@ -1,8 +1,10 @@ #include "Cafe/HW/Latte/Renderer/Metal/MetalCommon.h" #include "Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.h" #include "Cafe/HW/Latte/Renderer/Metal/MetalVoidVertexPipeline.h" + #include "Cemu/Logging/CemuLogging.h" #include "Common/precompiled.h" +#include "GameProfile/GameProfile.h" /* MetalVertexBufferCache::~MetalVertexBufferCache() @@ -117,8 +119,7 @@ void MetalMemoryManager::InitBufferCache(size_t size) cemu_assert_debug(!m_bufferCache); // First, try to import the host memory as a buffer - // TODO: only import if the option is ticked in game profile - if (m_mtlr->IsAppleGPU()) + if (g_current_game_profile->UseHostMemForCache() && m_mtlr->IsAppleGPU()) { m_importedMemBaseAddress = 0x10000000; size_t hostAllocationSize = 0x40000000ull; @@ -165,7 +166,6 @@ void MetalMemoryManager::UploadToBufferCache(const void* data, size_t offset, si void MetalMemoryManager::CopyBufferCache(size_t srcOffset, size_t dstOffset, size_t size) { - cemu_assert_debug(!m_useHostMemoryForCache); cemu_assert_debug(m_bufferCache); m_mtlr->CopyBufferToBuffer(m_bufferCache, srcOffset, m_bufferCache, dstOffset, size, ALL_MTL_RENDER_STAGES, ALL_MTL_RENDER_STAGES); diff --git a/src/gui/GameProfileWindow.cpp b/src/gui/GameProfileWindow.cpp index 76b8801c4..c1aa63e42 100644 --- a/src/gui/GameProfileWindow.cpp +++ b/src/gui/GameProfileWindow.cpp @@ -127,6 +127,13 @@ 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, _("Use host memory for cache")), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); + + wxString mem_values[] = { _("false"), _("true")}; + m_use_host_mem_for_cache = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, (int)std::size(mem_values), mem_values); + m_use_host_mem_for_cache->SetToolTip(_("EXPERT OPTION\nAllows the GPU to access data directly without the need for an intermediate cache. May increase performance and reduce memory usage, but can also cause flickering.\n\nMetal only\n\nRecommended: false")); + first_row->Add(m_use_host_mem_for_cache, 0, wxALL, 5); + /*first_row->Add(new wxStaticText(panel, wxID_ANY, _("GPU buffer cache accuracy")), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); wxString accuarcy_values[] = { _("high"), _("medium"), _("low") }; m_cache_accuracy = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, (int)std::size(accuarcy_values), accuarcy_values); @@ -273,6 +280,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_use_host_mem_for_cache->SetSelection((int)m_game_profile.m_useHostMemForCache); //// audio //m_disable_audio->Set3StateValue(GetCheckboxState(m_game_profile.disableAudio)); @@ -332,6 +340,7 @@ void GameProfileWindow::SaveProfile() // gpu m_game_profile.m_accurateShaderMul = (AccurateShaderMulOption)m_shader_mul_accuracy->GetSelection(); + m_game_profile.m_useHostMemForCache = (bool)m_use_host_mem_for_cache->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 6ca36de68..a1fe8132c 100644 --- a/src/gui/GameProfileWindow.h +++ b/src/gui/GameProfileWindow.h @@ -40,6 +40,7 @@ class GameProfileWindow : public wxFrame wxChoice* m_graphic_api; wxChoice* m_shader_mul_accuracy; + wxChoice* m_use_host_mem_for_cache; //wxChoice* m_cache_accuracy; // audio @@ -47,4 +48,4 @@ class GameProfileWindow : public wxFrame // controller wxComboBox* m_controller_profile[8]; -}; \ No newline at end of file +};