From c61c1ea8980f0a97ea4d77a5465745d7103e2452 Mon Sep 17 00:00:00 2001
From: riperiperi <rhy3756547@hotmail.com>
Date: Thu, 7 Oct 2021 00:00:56 +0100
Subject: [PATCH 1/2] Reregister flush actions when taking a buffer's modified
 range list.

Fixes a regression from #2663 where buffer flush would not happen after a resize. Specifically caused the world map in Yoshi's Crafted World to flash.

I have other planned changes to this class so this might change soon, but this regression could affect a lot so it couldn't wait.
---
 Ryujinx.Graphics.Gpu/Memory/Buffer.cs         | 26 +++++++++++--------
 .../Memory/BufferModifiedRangeList.cs         | 16 ++++++++++++
 2 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/Ryujinx.Graphics.Gpu/Memory/Buffer.cs b/Ryujinx.Graphics.Gpu/Memory/Buffer.cs
index 0eaf012357..81f7068417 100644
--- a/Ryujinx.Graphics.Gpu/Memory/Buffer.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/Buffer.cs
@@ -299,24 +299,28 @@ namespace Ryujinx.Graphics.Gpu.Memory
                     _syncActionRegistered = true;
                 }
 
+                Action<ulong, ulong> registerRangeAction = (ulong address, ulong size) =>
+                {
+                    if (_useGranular)
+                    {
+                        _memoryTrackingGranular.RegisterAction(address, size, _externalFlushDelegate);
+                    }
+                    else
+                    {
+                        _memoryTracking.RegisterAction(_externalFlushDelegate);
+                    }
+                };
+
                 if (_modifiedRanges == null)
                 {
                     _modifiedRanges = from._modifiedRanges;
+                    _modifiedRanges.ReregisterRanges(registerRangeAction);
+
                     from._modifiedRanges = null;
                 }
                 else
                 {
-                    _modifiedRanges.InheritRanges(from._modifiedRanges, (ulong address, ulong size) =>
-                    {
-                        if (_useGranular)
-                        {
-                            _memoryTrackingGranular.RegisterAction(address, size, _externalFlushDelegate);
-                        }
-                        else
-                        {
-                            _memoryTracking.RegisterAction(_externalFlushDelegate);
-                        }
-                    });
+                    _modifiedRanges.InheritRanges(from._modifiedRanges, registerRangeAction);
                 }
             }
         }
diff --git a/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs b/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs
index 84cf0dd8bb..faaccf13cf 100644
--- a/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs
@@ -318,6 +318,22 @@ namespace Ryujinx.Graphics.Gpu.Memory
             }
         }
 
+        /// <summary>
+        /// Calls the given action for modified ranges that aren't from the current sync number.
+        /// </summary>
+        /// <param name="rangeAction">The action to call for each modified range</param>
+        public void ReregisterRanges(Action<ulong, ulong> rangeAction)
+        {
+            ulong currentSync = _context.SyncNumber;
+            foreach (BufferModifiedRange range in this)
+            {
+                if (range.SyncNumber != currentSync)
+                {
+                    rangeAction(range.Address, range.Size);
+                }
+            }
+        }
+
         private void ClearPart(BufferModifiedRange overlap, ulong address, ulong endAddress)
         {
             Remove(overlap);

From a4956591ec485e9b23ded32a853f2a63af92b769 Mon Sep 17 00:00:00 2001
From: riperiperi <rhy3756547@hotmail.com>
Date: Thu, 7 Oct 2021 01:13:51 +0100
Subject: [PATCH 2/2] Avoid potential race

---
 .../Memory/BufferModifiedRangeList.cs         | 22 +++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs b/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs
index faaccf13cf..b9b533fb73 100644
--- a/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs
@@ -324,9 +324,27 @@ namespace Ryujinx.Graphics.Gpu.Memory
         /// <param name="rangeAction">The action to call for each modified range</param>
         public void ReregisterRanges(Action<ulong, ulong> rangeAction)
         {
-            ulong currentSync = _context.SyncNumber;
-            foreach (BufferModifiedRange range in this)
+            ref var ranges = ref ThreadStaticArray<BufferModifiedRange>.Get();
+
+            // Range list must be consistent for this operation.
+            lock (_lock)
             {
+                if (ranges.Length < Count)
+                {
+                    Array.Resize(ref ranges, Count);
+                }
+
+                int i = 0;
+                foreach (BufferModifiedRange range in this)
+                {
+                    ranges[i++] = range;
+                }
+            }
+
+            ulong currentSync = _context.SyncNumber;
+            for (int i = 0; i < Count; i++)
+            {
+                BufferModifiedRange range = ranges[i];
                 if (range.SyncNumber != currentSync)
                 {
                     rangeAction(range.Address, range.Size);