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.
This commit is contained in:
riperiperi 2022-11-18 20:47:29 +00:00 committed by GitHub
parent 131baebe2a
commit de162a648b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -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)