From db3eb168cd6a55c6387e3bfb23fb2eca061a691b Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Thu, 25 Aug 2022 12:32:14 -0400
Subject: [PATCH] video_core: add option for pessimistic flushing

---
 src/common/settings.cpp                                |  1 +
 src/common/settings.h                                  |  1 +
 src/video_core/buffer_cache/buffer_base.h              |  5 ++++-
 src/yuzu/configuration/config.cpp                      |  2 ++
 src/yuzu/configuration/configure_graphics_advanced.cpp |  8 ++++++++
 src/yuzu/configuration/configure_graphics_advanced.h   |  1 +
 src/yuzu/configuration/configure_graphics_advanced.ui  | 10 ++++++++++
 src/yuzu_cmd/config.cpp                                |  1 +
 src/yuzu_cmd/default_ini.h                             |  4 ++++
 9 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 7282a45d3..0a560ebb7 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -195,6 +195,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_pessimistic_flushes.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 14ed9b237..13651de57 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -446,6 +446,7 @@ struct Values {
                                                           ShaderBackend::SPIRV, "shader_backend"};
     SwitchableSetting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"};
     SwitchableSetting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"};
+    SwitchableSetting<bool> use_pessimistic_flushes{false, "use_pessimistic_flushes"};
 
     SwitchableSetting<u8> bg_red{0, "bg_red"};
     SwitchableSetting<u8> bg_green{0, "bg_green"};
diff --git a/src/video_core/buffer_cache/buffer_base.h b/src/video_core/buffer_cache/buffer_base.h
index 0b2bc67b1..f9a6472cf 100644
--- a/src/video_core/buffer_cache/buffer_base.h
+++ b/src/video_core/buffer_cache/buffer_base.h
@@ -12,6 +12,7 @@
 #include "common/common_funcs.h"
 #include "common/common_types.h"
 #include "common/div_ceil.h"
+#include "common/settings.h"
 #include "core/memory.h"
 
 namespace VideoCommon {
@@ -219,7 +220,9 @@ public:
             NotifyRasterizer<false>(word_index, untracked_words[word_index], cached_bits);
             untracked_words[word_index] |= cached_bits;
             cpu_words[word_index] |= cached_bits;
-            cached_words[word_index] = 0;
+            if (!Settings::values.use_pessimistic_flushes) {
+                cached_words[word_index] = 0;
+            }
         }
     }
 
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index da6e5aa88..8ecd87150 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -684,6 +684,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_pessimistic_flushes);
     ReadGlobalSetting(Settings::values.bg_red);
     ReadGlobalSetting(Settings::values.bg_green);
     ReadGlobalSetting(Settings::values.bg_blue);
@@ -1300,6 +1301,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_pessimistic_flushes);
     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 7c3196c83..01f074699 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_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue());
+    ui->use_pessimistic_flushes->setChecked(Settings::values.use_pessimistic_flushes.GetValue());
 
     if (Settings::IsConfiguringGlobal()) {
         ui->gpu_accuracy->setCurrentIndex(
@@ -55,6 +56,8 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() {
                                              use_asynchronous_shaders);
     ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_fast_gpu_time,
                                              ui->use_fast_gpu_time, use_fast_gpu_time);
+    ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_pessimistic_flushes,
+                                             ui->use_pessimistic_flushes, use_pessimistic_flushes);
 }
 
 void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) {
@@ -77,6 +80,8 @@ 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_pessimistic_flushes->setEnabled(
+            Settings::values.use_pessimistic_flushes.UsingGlobal());
         ui->anisotropic_filtering_combobox->setEnabled(
             Settings::values.max_anisotropy.UsingGlobal());
 
@@ -89,6 +94,9 @@ 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_pessimistic_flushes,
+                                            Settings::values.use_pessimistic_flushes,
+                                            use_pessimistic_flushes);
     ConfigurationShared::SetColoredComboBox(
         ui->gpu_accuracy, ui->label_gpu_accuracy,
         static_cast<int>(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 1ef7bd916..12e816905 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.h
+++ b/src/yuzu/configuration/configure_graphics_advanced.h
@@ -39,6 +39,7 @@ private:
     ConfigurationShared::CheckState use_vsync;
     ConfigurationShared::CheckState use_asynchronous_shaders;
     ConfigurationShared::CheckState use_fast_gpu_time;
+    ConfigurationShared::CheckState use_pessimistic_flushes;
 
     const Core::System& system;
 };
diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui
index d6d819364..87a121471 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.ui
+++ b/src/yuzu/configuration/configure_graphics_advanced.ui
@@ -99,6 +99,16 @@
           </property>
          </widget>
         </item>
+        <item>
+         <widget class="QCheckBox" name="use_pessimistic_flushes">
+          <property name="toolTip">
+            <string>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</string>
+          </property>
+          <property name="text">
+           <string>Use pessimistic buffer flushes (Hack)</string>
+          </property>
+         </widget>
+        </item>
         <item>
          <widget class="QWidget" name="af_layout" native="true">
           <layout class="QHBoxLayout" name="horizontalLayout_1">
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index bd0fb75f8..66dd0dc15 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -314,6 +314,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_pessimistic_flushes);
 
     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 1168cf136..d214771b0 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -319,6 +319,10 @@ use_asynchronous_gpu_emulation =
 # 0: Off, 1 (default): On
 use_fast_gpu_time =
 
+# Force unmodified buffers to be flushed, which can cost performance.
+# 0: Off (default), 1: On
+use_pessimistic_flushes =
+
 # Whether to use garbage collection or not for GPU caches.
 # 0 (default): Off, 1: On
 use_caches_gc =