mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-09-10 11:55:16 +00:00
Memory changes 2.1 (ryubing/ryujinx!132)
See merge request ryubing/ryujinx!132
This commit is contained in:
@@ -82,15 +82,7 @@ namespace Ryujinx.Graphics.Device
|
|||||||
{
|
{
|
||||||
uint alignedOffset = index * RegisterSize;
|
uint alignedOffset = index * RegisterSize;
|
||||||
|
|
||||||
Func<int> readCallback = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(_readCallbacks), (nint)index);
|
return _readCallbacks[index]?.Invoke() ?? GetRefUnchecked<int>(alignedOffset);
|
||||||
if (readCallback != null)
|
|
||||||
{
|
|
||||||
return readCallback();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return GetRefUnchecked<int>(alignedOffset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -107,7 +99,7 @@ namespace Ryujinx.Graphics.Device
|
|||||||
|
|
||||||
GetRefIntAlignedUncheck(index) = data;
|
GetRefIntAlignedUncheck(index) = data;
|
||||||
|
|
||||||
Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(_writeCallbacks), (nint)index)?.Invoke(data);
|
_writeCallbacks[index]?.Invoke(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +116,7 @@ namespace Ryujinx.Graphics.Device
|
|||||||
changed = storage != data;
|
changed = storage != data;
|
||||||
storage = data;
|
storage = data;
|
||||||
|
|
||||||
Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(_writeCallbacks), (nint)index)?.Invoke(data);
|
_writeCallbacks[index]?.Invoke(data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -109,7 +109,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
|
|
||||||
if (index < BlockSize)
|
if (index < BlockSize)
|
||||||
{
|
{
|
||||||
int groupIndex = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(_registerToGroupMapping), (nint)index);
|
int groupIndex = _registerToGroupMapping[index];
|
||||||
if (groupIndex != 0)
|
if (groupIndex != 0)
|
||||||
{
|
{
|
||||||
groupIndex--;
|
groupIndex--;
|
||||||
|
@@ -120,11 +120,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
public void ExcludeModifiedRegions(ulong address, ulong size, Action<ulong, ulong> action)
|
public void ExcludeModifiedRegions(ulong address, ulong size, Action<ulong, ulong> action)
|
||||||
{
|
{
|
||||||
// Slices a given region using the modified regions in the list. Calls the action for the new slices.
|
// Slices a given region using the modified regions in the list. Calls the action for the new slices.
|
||||||
bool lockOwner = Lock.IsReadLockHeld;
|
Lock.EnterReadLock();
|
||||||
if (!lockOwner)
|
|
||||||
{
|
|
||||||
Lock.EnterReadLock();
|
|
||||||
}
|
|
||||||
|
|
||||||
(RangeItem<BufferModifiedRange> first, RangeItem<BufferModifiedRange> last) = FindOverlaps(address, size);
|
(RangeItem<BufferModifiedRange> first, RangeItem<BufferModifiedRange> last) = FindOverlaps(address, size);
|
||||||
|
|
||||||
@@ -145,10 +141,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
current = current.Next;
|
current = current.Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lockOwner)
|
Lock.ExitReadLock();
|
||||||
{
|
|
||||||
Lock.ExitReadLock();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((long)size > 0)
|
if ((long)size > 0)
|
||||||
{
|
{
|
||||||
@@ -179,9 +172,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferModifiedRange buffPost = null;
|
|
||||||
bool extendsPost = false;
|
|
||||||
bool extendsPre = false;
|
|
||||||
|
|
||||||
if (first == last)
|
if (first == last)
|
||||||
{
|
{
|
||||||
@@ -196,14 +187,12 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
if (first.Address < address)
|
if (first.Address < address)
|
||||||
{
|
{
|
||||||
first.Value.Size = address - first.Address;
|
first.Value.Size = address - first.Address;
|
||||||
|
Update(first);
|
||||||
extendsPre = true;
|
|
||||||
|
|
||||||
if (first.EndAddress > endAddress)
|
if (first.EndAddress > endAddress)
|
||||||
{
|
{
|
||||||
buffPost = new BufferModifiedRange(endAddress, first.EndAddress - endAddress,
|
Add(new BufferModifiedRange(endAddress, first.EndAddress - endAddress,
|
||||||
first.Value.SyncNumber, first.Value.Parent);
|
first.Value.SyncNumber, first.Value.Parent));
|
||||||
extendsPost = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -212,6 +201,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
{
|
{
|
||||||
first.Value.Size = first.EndAddress - endAddress;
|
first.Value.Size = first.EndAddress - endAddress;
|
||||||
first.Value.Address = endAddress;
|
first.Value.Address = endAddress;
|
||||||
|
Update(first);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -219,11 +209,6 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extendsPre && extendsPost)
|
|
||||||
{
|
|
||||||
Add(buffPost);
|
|
||||||
}
|
|
||||||
|
|
||||||
Add(new BufferModifiedRange(address, size, syncNumber, this));
|
Add(new BufferModifiedRange(address, size, syncNumber, this));
|
||||||
Lock.ExitWriteLock();
|
Lock.ExitWriteLock();
|
||||||
|
|
||||||
@@ -231,6 +216,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
}
|
}
|
||||||
|
|
||||||
BufferModifiedRange buffPre = null;
|
BufferModifiedRange buffPre = null;
|
||||||
|
BufferModifiedRange buffPost = null;
|
||||||
|
bool extendsPost = false;
|
||||||
|
bool extendsPre = false;
|
||||||
|
|
||||||
if (first.Address < address)
|
if (first.Address < address)
|
||||||
{
|
{
|
||||||
@@ -329,7 +317,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
public bool HasRange(ulong address, ulong size)
|
public bool HasRange(ulong address, ulong size)
|
||||||
{
|
{
|
||||||
Lock.EnterReadLock();
|
Lock.EnterReadLock();
|
||||||
(RangeItem<BufferModifiedRange> first, RangeItem<BufferModifiedRange> _) = FindOverlaps(address, size);
|
RangeItem<BufferModifiedRange> first = FindOverlapFast(address, size);
|
||||||
bool result = first is not null;
|
bool result = first is not null;
|
||||||
Lock.ExitReadLock();
|
Lock.ExitReadLock();
|
||||||
return result;
|
return result;
|
||||||
@@ -386,9 +374,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
ulong clampAddress = Math.Max(address, overlap.Address);
|
ulong clampAddress = Math.Max(address, overlap.Address);
|
||||||
ulong clampEnd = Math.Min(endAddress, overlap.EndAddress);
|
ulong clampEnd = Math.Min(endAddress, overlap.EndAddress);
|
||||||
|
|
||||||
Lock.EnterWriteLock();
|
|
||||||
ClearPart(overlap, clampAddress, clampEnd);
|
ClearPart(overlap, clampAddress, clampEnd);
|
||||||
Lock.ExitWriteLock();
|
|
||||||
|
|
||||||
RangeActionWithMigration(clampAddress, clampEnd - clampAddress, waitSync, _flushAction);
|
RangeActionWithMigration(clampAddress, clampEnd - clampAddress, waitSync, _flushAction);
|
||||||
}
|
}
|
||||||
@@ -418,40 +404,33 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
ulong endAddress = address + size;
|
ulong endAddress = address + size;
|
||||||
ulong currentSync = _context.SyncNumber;
|
ulong currentSync = _context.SyncNumber;
|
||||||
|
|
||||||
int rangeCount = 0;
|
|
||||||
|
|
||||||
List<RangeItem<BufferModifiedRange>> overlaps = [];
|
List<RangeItem<BufferModifiedRange>> overlaps = [];
|
||||||
|
|
||||||
// Range list must be consistent for this operation
|
// Range list must be consistent for this operation
|
||||||
Lock.EnterReadLock();
|
|
||||||
if (_migrationTarget != null)
|
if (_migrationTarget != null)
|
||||||
{
|
|
||||||
rangeCount = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// We use the non-span method here because the array is partially modified by the code, which would invalidate a span.
|
|
||||||
(RangeItem<BufferModifiedRange> first, RangeItem<BufferModifiedRange> last) = FindOverlaps(address, size);
|
|
||||||
|
|
||||||
RangeItem<BufferModifiedRange> current = first;
|
|
||||||
while (last != null && current != last.Next)
|
|
||||||
{
|
|
||||||
rangeCount++;
|
|
||||||
overlaps.Add(current);
|
|
||||||
current = current.Next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Lock.ExitReadLock();
|
|
||||||
|
|
||||||
if (rangeCount == -1)
|
|
||||||
{
|
{
|
||||||
_migrationTarget!.WaitForAndFlushRanges(address, size);
|
_migrationTarget!.WaitForAndFlushRanges(address, size);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Lock.EnterWriteLock();
|
||||||
|
// We use the non-span method here because the array is partially modified by the code, which would invalidate a span.
|
||||||
|
(RangeItem<BufferModifiedRange> first, RangeItem<BufferModifiedRange> last) = FindOverlaps(address, size);
|
||||||
|
|
||||||
|
RangeItem<BufferModifiedRange> current = first;
|
||||||
|
while (last != null && current != last.Next)
|
||||||
|
{
|
||||||
|
overlaps.Add(current);
|
||||||
|
current = current.Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rangeCount = overlaps.Count;
|
||||||
|
|
||||||
if (rangeCount == 0)
|
if (rangeCount == 0)
|
||||||
{
|
{
|
||||||
|
Lock.ExitWriteLock();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,6 +453,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
|
|
||||||
if (highestDiff == long.MinValue)
|
if (highestDiff == long.MinValue)
|
||||||
{
|
{
|
||||||
|
Lock.ExitWriteLock();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,6 +462,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
_context.Renderer.WaitSync(currentSync + (ulong)highestDiff);
|
_context.Renderer.WaitSync(currentSync + (ulong)highestDiff);
|
||||||
|
|
||||||
RemoveRangesAndFlush(overlaps.ToArray(), rangeCount, highestDiff, currentSync, address, endAddress);
|
RemoveRangesAndFlush(overlaps.ToArray(), rangeCount, highestDiff, currentSync, address, endAddress);
|
||||||
|
|
||||||
|
Lock.ExitWriteLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -607,22 +590,17 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferModifiedRange buffPost = null;
|
|
||||||
bool extendsPost = false;
|
|
||||||
bool extendsPre = false;
|
|
||||||
|
|
||||||
if (first == last)
|
if (first == last)
|
||||||
{
|
{
|
||||||
if (first.Address < address)
|
if (first.Address < address)
|
||||||
{
|
{
|
||||||
first.Value.Size = address - first.Address;
|
first.Value.Size = address - first.Address;
|
||||||
extendsPre = true;
|
Update(first);
|
||||||
|
|
||||||
if (first.EndAddress > endAddress)
|
if (first.EndAddress > endAddress)
|
||||||
{
|
{
|
||||||
buffPost = new BufferModifiedRange(endAddress, first.EndAddress - endAddress,
|
Add(new BufferModifiedRange(endAddress, first.EndAddress - endAddress,
|
||||||
first.Value.SyncNumber, first.Value.Parent);
|
first.Value.SyncNumber, first.Value.Parent));
|
||||||
extendsPost = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -631,6 +609,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
{
|
{
|
||||||
first.Value.Size = first.EndAddress - endAddress;
|
first.Value.Size = first.EndAddress - endAddress;
|
||||||
first.Value.Address = endAddress;
|
first.Value.Address = endAddress;
|
||||||
|
Update(first);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -638,16 +617,14 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extendsPre && extendsPost)
|
|
||||||
{
|
|
||||||
Add(buffPost);
|
|
||||||
}
|
|
||||||
|
|
||||||
Lock.ExitWriteLock();
|
Lock.ExitWriteLock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferModifiedRange buffPre = null;
|
BufferModifiedRange buffPre = null;
|
||||||
|
BufferModifiedRange buffPost = null;
|
||||||
|
bool extendsPost = false;
|
||||||
|
bool extendsPre = false;
|
||||||
|
|
||||||
if (first.Address < address)
|
if (first.Address < address)
|
||||||
{
|
{
|
||||||
|
@@ -87,6 +87,43 @@ namespace Ryujinx.Memory.Range
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates an item's end address on the list. Address must be the same.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The RangeItem to be updated</param>
|
||||||
|
/// <returns>True if the item was located and updated, false otherwise</returns>
|
||||||
|
protected override bool Update(RangeItem<T> item)
|
||||||
|
{
|
||||||
|
int index = BinarySearch(item.Address);
|
||||||
|
|
||||||
|
RangeItem<T> rangeItem = new(item.Value) { Previous = item.Previous, Next = item.Next };
|
||||||
|
|
||||||
|
if (index > 0)
|
||||||
|
{
|
||||||
|
Items[index - 1].Next = rangeItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < Count - 1)
|
||||||
|
{
|
||||||
|
Items[index + 1].Previous = rangeItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (ulong addr in item.QuickAccessAddresses)
|
||||||
|
{
|
||||||
|
_quickAccess.Remove(addr);
|
||||||
|
_fastQuickAccess.Remove(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Items[index] = rangeItem;
|
||||||
|
|
||||||
|
if (item.Address != rangeItem.Address)
|
||||||
|
_quickAccess.Remove(item.Address);
|
||||||
|
|
||||||
|
_quickAccess[rangeItem.Address] = rangeItem;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void Insert(int index, RangeItem<T> item)
|
private void Insert(int index, RangeItem<T> item)
|
||||||
{
|
{
|
||||||
@@ -193,10 +230,9 @@ namespace Ryujinx.Memory.Range
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int startIndex = BinarySearch(startItem.Address);
|
(int startIndex, int endIndex) = BinarySearchEdges(startItem.Address, endItem.EndAddress);
|
||||||
int endIndex = BinarySearch(endItem.Address);
|
|
||||||
|
|
||||||
for (int i = startIndex; i <= endIndex; i++)
|
for (int i = startIndex; i < endIndex; i++)
|
||||||
{
|
{
|
||||||
_quickAccess.Remove(Items[i].Address);
|
_quickAccess.Remove(Items[i].Address);
|
||||||
foreach (ulong addr in Items[i].QuickAccessAddresses)
|
foreach (ulong addr in Items[i].QuickAccessAddresses)
|
||||||
@@ -206,23 +242,23 @@ namespace Ryujinx.Memory.Range
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endIndex < Count - 1)
|
if (endIndex < Count)
|
||||||
{
|
{
|
||||||
Items[endIndex + 1].Previous = startIndex > 0 ? Items[startIndex - 1] : null;
|
Items[endIndex].Previous = startIndex > 0 ? Items[startIndex - 1] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startIndex > 0)
|
if (startIndex > 0)
|
||||||
{
|
{
|
||||||
Items[startIndex - 1].Next = endIndex < Count - 1 ? Items[endIndex + 1] : null;
|
Items[startIndex - 1].Next = endIndex < Count ? Items[endIndex] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (endIndex < Count - 1)
|
if (endIndex < Count)
|
||||||
{
|
{
|
||||||
Array.Copy(Items, endIndex + 1, Items, startIndex, Count - endIndex - 1);
|
Array.Copy(Items, endIndex, Items, startIndex, Count - endIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
Count -= endIndex - startIndex + 1;
|
Count -= endIndex - startIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@@ -81,12 +81,73 @@ namespace Ryujinx.Memory.Range
|
|||||||
{
|
{
|
||||||
if (Items[index].Value.Equals(item))
|
if (Items[index].Value.Equals(item))
|
||||||
{
|
{
|
||||||
|
RangeItem<T> rangeItem = new(item) { Previous = Items[index].Previous, Next = Items[index].Next };
|
||||||
|
|
||||||
|
if (index > 0)
|
||||||
|
{
|
||||||
|
Items[index - 1].Next = rangeItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < Count - 1)
|
||||||
|
{
|
||||||
|
Items[index + 1].Previous = rangeItem;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (ulong address in Items[index].QuickAccessAddresses)
|
foreach (ulong address in Items[index].QuickAccessAddresses)
|
||||||
{
|
{
|
||||||
_quickAccess.Remove(address);
|
_quickAccess.Remove(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
Items[index] = new RangeItem<T>(item);
|
Items[index] = rangeItem;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Items[index].Address > item.Address)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates an item's end address on the list. Address must be the same.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The RangeItem to be updated</param>
|
||||||
|
/// <returns>True if the item was located and updated, false otherwise</returns>
|
||||||
|
protected override bool Update(RangeItem<T> item)
|
||||||
|
{
|
||||||
|
int index = BinarySearch(item.Address);
|
||||||
|
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
while (index < Count)
|
||||||
|
{
|
||||||
|
if (Items[index].Equals(item))
|
||||||
|
{
|
||||||
|
RangeItem<T> rangeItem = new(item.Value) { Previous = item.Previous, Next = item.Next };
|
||||||
|
|
||||||
|
if (index > 0)
|
||||||
|
{
|
||||||
|
Items[index - 1].Next = rangeItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < Count - 1)
|
||||||
|
{
|
||||||
|
Items[index + 1].Previous = rangeItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (ulong address in item.QuickAccessAddresses)
|
||||||
|
{
|
||||||
|
_quickAccess.Remove(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
Items[index] = rangeItem;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -30,7 +30,7 @@ namespace Ryujinx.Memory.Range
|
|||||||
return u1 == u2;
|
return u1 == u2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetHashCode(ulong value) => (int)(value >> 5);
|
public int GetHashCode(ulong value) => (int)(value << 5);
|
||||||
|
|
||||||
public static readonly AddressEqualityComparer Comparer = new();
|
public static readonly AddressEqualityComparer Comparer = new();
|
||||||
}
|
}
|
||||||
@@ -63,6 +63,13 @@ namespace Ryujinx.Memory.Range
|
|||||||
/// <returns>True if the item was located and updated, false otherwise</returns>
|
/// <returns>True if the item was located and updated, false otherwise</returns>
|
||||||
protected abstract bool Update(T item);
|
protected abstract bool Update(T item);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates an item's end address on the list. Address must be the same.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The RangeItem to be updated</param>
|
||||||
|
/// <returns>True if the item was located and updated, false otherwise</returns>
|
||||||
|
protected abstract bool Update(RangeItem<T> item);
|
||||||
|
|
||||||
public abstract bool Remove(T item);
|
public abstract bool Remove(T item);
|
||||||
|
|
||||||
public abstract void RemoveRange(RangeItem<T> startItem, RangeItem<T> endItem);
|
public abstract void RemoveRange(RangeItem<T> startItem, RangeItem<T> endItem);
|
||||||
|
@@ -182,11 +182,15 @@ namespace Ryujinx.Memory.Tracking
|
|||||||
{
|
{
|
||||||
if (region.Guest)
|
if (region.Guest)
|
||||||
{
|
{
|
||||||
|
_guestVirtualRegions.Lock.EnterWriteLock();
|
||||||
_guestVirtualRegions.Remove(region);
|
_guestVirtualRegions.Remove(region);
|
||||||
|
_guestVirtualRegions.Lock.ExitWriteLock();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
_virtualRegions.Lock.EnterWriteLock();
|
||||||
_virtualRegions.Remove(region);
|
_virtualRegions.Remove(region);
|
||||||
|
_virtualRegions.Lock.ExitWriteLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user