From de162a648b3bb1c8080460bfb8392951340ef40b Mon Sep 17 00:00:00 2001 From: riperiperi 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 b9b533fb7..07dbd2094 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 rangeAction) { ref var ranges = ref ThreadStaticArray.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)