diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 6964a82737..ead5d56fd5 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -61,6 +61,7 @@ void LogSettings() { log_setting("Renderer_UseVsync", values.use_vsync.GetValue()); log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue()); log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue()); + log_setting("Renderer_UseGarbageCollectionAdvanced", values.use_caches_gc_adv.GetValue()); log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue()); log_setting("Audio_OutputEngine", values.sink_id.GetValue()); log_setting("Audio_OutputDevice", values.audio_device_id.GetValue()); @@ -193,6 +194,7 @@ void RestoreGlobalState(bool is_powered_on) { values.shader_backend.SetGlobal(true); values.use_asynchronous_shaders.SetGlobal(true); values.use_fast_gpu_time.SetGlobal(true); + values.use_caches_gc_adv.SetGlobal(true); values.bg_red.SetGlobal(true); values.bg_green.SetGlobal(true); values.bg_blue.SetGlobal(true); diff --git a/src/common/settings.h b/src/common/settings.h index d01c0448c7..ea58490143 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -530,6 +530,7 @@ struct Values { ShaderBackend::SPIRV, "shader_backend"}; Setting use_asynchronous_shaders{false, "use_asynchronous_shaders"}; Setting use_fast_gpu_time{true, "use_fast_gpu_time"}; + Setting use_caches_gc_adv{false, "use_caches_gc_adv"}; Setting bg_red{0, "bg_red"}; Setting bg_green{0, "bg_green"}; diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp index 654db0b524..88e291872f 100644 --- a/src/core/telemetry_session.cpp +++ b/src/core/telemetry_session.cpp @@ -245,6 +245,8 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader, static_cast(Settings::values.shader_backend.GetValue())); AddField(field_type, "Renderer_UseAsynchronousShaders", Settings::values.use_asynchronous_shaders.GetValue()); + AddField(field_type, "Renderer_UseGarbageCollectionAdvanced", + Settings::values.use_caches_gc_adv.GetValue()); AddField(field_type, "System_UseDockedMode", Settings::values.use_docked_mode.GetValue()); } diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 43bed63ac2..8b689e09cf 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -78,8 +78,8 @@ class BufferCache { static constexpr BufferId NULL_BUFFER_ID{0}; - static constexpr u64 EXPECTED_MEMORY = 512_MiB; - static constexpr u64 CRITICAL_MEMORY = 1_GiB; + static constexpr u64 EXPECTED_MEMORY = 1_GiB; + static constexpr u64 CRITICAL_MEMORY = 2_GiB; using Maxwell = Tegra::Engines::Maxwell3D::Regs; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index c1cfed05da..21cba01b94 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -53,12 +53,14 @@ TextureCache

::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& const auto device_memory = runtime.GetDeviceLocalMemory(); const u64 possible_expected_memory = (device_memory * 4) / 10; const u64 possible_critical_memory = (device_memory * 7) / 10; + over_4gb_memory = device_memory > 4_GiB; expected_memory = std::max(possible_expected_memory, DEFAULT_EXPECTED_MEMORY - 256_MiB); critical_memory = std::max(possible_critical_memory, DEFAULT_CRITICAL_MEMORY - 512_MiB); } else { // On OpenGL we can be more conservatives as the driver takes care. expected_memory = DEFAULT_EXPECTED_MEMORY + 512_MiB; critical_memory = DEFAULT_CRITICAL_MEMORY + 1_GiB; + over_4gb_memory = false; } } @@ -66,8 +68,8 @@ template void TextureCache

::RunGarbageCollector() { const bool high_priority_mode = total_used_memory >= expected_memory; const bool aggressive_mode = total_used_memory >= critical_memory; - const u64 ticks_to_destroy = aggressive_mode ? 10ULL : high_priority_mode ? 25ULL : 100ULL; - size_t num_iterations = aggressive_mode ? 300 : (high_priority_mode ? 50 : 10); + const u64 ticks_to_destroy = aggressive_mode ? 240ULL : high_priority_mode ? 240ULL : 240ULL; + size_t num_iterations = aggressive_mode ? 2048 : (high_priority_mode ? 128 : 32); const auto clean_up = [this, &num_iterations, high_priority_mode](ImageId image_id) { if (num_iterations == 0) { return true; @@ -97,7 +99,14 @@ void TextureCache

::RunGarbageCollector() { template void TextureCache

::TickFrame() { - if (total_used_memory > expected_memory) { + if (over_4gb_memory) { + if (Settings::values.use_caches_gc_adv.GetValue() && total_used_memory > critical_memory) { + RunGarbageCollector(); + } else if (!Settings::values.use_caches_gc_adv.GetValue() && + total_used_memory > expected_memory) { + RunGarbageCollector(); + } + } else { RunGarbageCollector(); } sentenced_images.Tick(); diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index ebda4fbcfa..c6971bee0f 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h @@ -369,6 +369,7 @@ private: bool has_deleted_images = false; bool is_rescaling = false; + bool over_4gb_memory = false; u64 total_used_memory = 0; u64 expected_memory; u64 critical_memory; diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 0f679c37e6..e050ffb297 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -645,6 +645,7 @@ void Config::ReadRendererValues() { ReadGlobalSetting(Settings::values.shader_backend); ReadGlobalSetting(Settings::values.use_asynchronous_shaders); ReadGlobalSetting(Settings::values.use_fast_gpu_time); + ReadGlobalSetting(Settings::values.use_caches_gc_adv); ReadGlobalSetting(Settings::values.bg_red); ReadGlobalSetting(Settings::values.bg_green); ReadGlobalSetting(Settings::values.bg_blue); @@ -1192,6 +1193,7 @@ void Config::SaveRendererValues() { Settings::values.shader_backend.UsingGlobal()); WriteGlobalSetting(Settings::values.use_asynchronous_shaders); WriteGlobalSetting(Settings::values.use_fast_gpu_time); + WriteGlobalSetting(Settings::values.use_caches_gc_adv); WriteGlobalSetting(Settings::values.bg_red); WriteGlobalSetting(Settings::values.bg_green); WriteGlobalSetting(Settings::values.bg_blue); diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp index 30c5a3595b..e115ca2a37 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.cpp +++ b/src/yuzu/configuration/configure_graphics_advanced.cpp @@ -28,6 +28,7 @@ void ConfigureGraphicsAdvanced::SetConfiguration() { ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue()); ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue()); + ui->use_caches_gc_adv->setChecked(Settings::values.use_caches_gc_adv.GetValue()); ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue()); if (Settings::IsConfiguringGlobal()) { @@ -54,6 +55,8 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() { ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders, ui->use_asynchronous_shaders, use_asynchronous_shaders); + ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_caches_gc_adv, + ui->use_caches_gc_adv, use_caches_gc_adv); ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_fast_gpu_time, ui->use_fast_gpu_time, use_fast_gpu_time); } @@ -78,6 +81,7 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() { ui->use_asynchronous_shaders->setEnabled( Settings::values.use_asynchronous_shaders.UsingGlobal()); ui->use_fast_gpu_time->setEnabled(Settings::values.use_fast_gpu_time.UsingGlobal()); + ui->use_caches_gc_adv->setEnabled(Settings::values.use_caches_gc_adv.UsingGlobal()); ui->anisotropic_filtering_combobox->setEnabled( Settings::values.max_anisotropy.UsingGlobal()); @@ -90,6 +94,8 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() { use_asynchronous_shaders); ConfigurationShared::SetColoredTristate(ui->use_fast_gpu_time, Settings::values.use_fast_gpu_time, use_fast_gpu_time); + ConfigurationShared::SetColoredTristate(ui->use_caches_gc_adv, + Settings::values.use_caches_gc_adv, use_caches_gc_adv); ConfigurationShared::SetColoredComboBox( ui->gpu_accuracy, ui->label_gpu_accuracy, static_cast(Settings::values.gpu_accuracy.GetValue(true))); diff --git a/src/yuzu/configuration/configure_graphics_advanced.h b/src/yuzu/configuration/configure_graphics_advanced.h index 0a1724ce4a..057c646d1d 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.h +++ b/src/yuzu/configuration/configure_graphics_advanced.h @@ -40,6 +40,7 @@ private: ConfigurationShared::CheckState use_vsync; ConfigurationShared::CheckState use_asynchronous_shaders; ConfigurationShared::CheckState use_fast_gpu_time; + ConfigurationShared::CheckState use_caches_gc_adv; const Core::System& system; }; diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui index 96de0b3d10..c8b4e5912e 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.ui +++ b/src/yuzu/configuration/configure_graphics_advanced.ui @@ -99,6 +99,16 @@ + + + + This will try to unlock more than 4GB of VRAM with a late reset of the least used textures. More stable operation with increased video memory consumption. + + + Advanced GPU Cache Garbage Collection Mode (Hack) + + + diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index 8e9c7d211c..f3422278b9 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -292,6 +292,7 @@ void Config::ReadValues() { ReadSetting("Renderer", Settings::values.nvdec_emulation); ReadSetting("Renderer", Settings::values.accelerate_astc); ReadSetting("Renderer", Settings::values.use_fast_gpu_time); + ReadSetting("Renderer", Settings::values.use_caches_gc_adv); ReadSetting("Renderer", Settings::values.bg_red); ReadSetting("Renderer", Settings::values.bg_green); diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h index 6d613bf7a1..5306d5b5ec 100644 --- a/src/yuzu_cmd/default_ini.h +++ b/src/yuzu_cmd/default_ini.h @@ -303,9 +303,9 @@ use_asynchronous_gpu_emulation = # 0: Off, 1 (default): On use_fast_gpu_time = -# Whether to use garbage collection or not for GPU caches. +# Whether to use garbage collection or not for GPU caches up max VRAM. # 0 (default): Off, 1: On -use_caches_gc = +use_caches_gc_adv = # The clear color for the renderer. What shows up on the sides of the bottom screen. # Must be in range of 0-255. Defaults to 0 for all.