From de162a648b3bb1c8080460bfb8392951340ef40b Mon Sep 17 00:00:00 2001
From: riperiperi <rhy3756547@hotmail.com>
Date: Fri, 18 Nov 2022 20:47:29 +0000
Subject: [PATCH] Gpu: Fix thread safety of ReregisterRanges (#3865)

A quick fix to prevent reading the wrong value of Count when reregistering ranges for a new target buffer. Buffer flushes from another thread can modify the range list when the lock isn't active, which can change the count.

This prevents some crashes in Pokemon Scarlet/Violet. It's probably likely that buffer migration during flush is causing some other issues in this game, but this at least prevents the crashing.
---
 Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs b/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs
index b9b533fb73..07dbd2094a 100644
--- a/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs
@@ -325,13 +325,15 @@ namespace Ryujinx.Graphics.Gpu.Memory
         public void ReregisterRanges(Action<ulong, ulong> rangeAction)
         {
             ref var ranges = ref ThreadStaticArray<BufferModifiedRange>.Get();
+            int count;
 
             // Range list must be consistent for this operation.
             lock (_lock)
             {
-                if (ranges.Length < Count)
+                count = Count;
+                if (ranges.Length < count)
                 {
-                    Array.Resize(ref ranges, Count);
+                    Array.Resize(ref ranges, count);
                 }
 
                 int i = 0;
@@ -342,7 +344,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
             }
 
             ulong currentSync = _context.SyncNumber;
-            for (int i = 0; i < Count; i++)
+            for (int i = 0; i < count; i++)
             {
                 BufferModifiedRange range = ranges[i];
                 if (range.SyncNumber != currentSync)