From 1ee1a5d3d64379bf2463c072a32af8e64a8c14cf Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Fri, 29 May 2020 23:52:47 -0300
Subject: [PATCH] texture_cache: More relaxed reconstruction

Only reupload textures when they've not been modified from the GPU.
---
 src/video_core/texture_cache/texture_cache.h | 22 ++++++++------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 3e024a098..4ba0d2c3a 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -656,19 +656,19 @@ private:
         if (params.target == SurfaceTarget::Texture3D) {
             return std::nullopt;
         }
+        const auto test_modified = [](TSurface& surface) { return surface->IsModified(); };
         TSurface new_surface = GetUncachedSurface(gpu_addr, params);
-        std::size_t passed_tests = 0;
-        bool modified = false;
 
-        u32 num_resources = 0;
-        for (auto& surface : overlaps) {
-            const SurfaceParams& src_params = surface->GetSurfaceParams();
-            num_resources += src_params.depth * src_params.num_levels;
-        }
-        if (num_resources != params.depth * params.num_levels) {
+        if (std::none_of(overlaps.begin(), overlaps.end(), test_modified)) {
             LoadSurface(new_surface);
+            for (const auto& surface : overlaps) {
+                Unregister(surface);
+            }
+            Register(new_surface);
+            return {{new_surface, new_surface->GetMainView()}};
         }
 
+        std::size_t passed_tests = 0;
         for (auto& surface : overlaps) {
             const SurfaceParams& src_params = surface->GetSurfaceParams();
             const auto mipmap_layer{new_surface->GetLayerMipmap(surface->GetGpuAddr())};
@@ -681,11 +681,6 @@ private:
             }
             ++passed_tests;
 
-            if (!surface->IsModified()) {
-                continue;
-            }
-            modified = true;
-
             // Copy all mipmaps and layers
             const u32 block_width = params.GetDefaultBlockWidth();
             const u32 block_height = params.GetDefaultBlockHeight();
@@ -709,6 +704,7 @@ private:
             return std::nullopt;
         }
 
+        const bool modified = std::any_of(overlaps.begin(), overlaps.end(), test_modified);
         for (const auto& surface : overlaps) {
             Unregister(surface);
         }