Memory changes 2.2.1 (ryubing/ryujinx!144)

See merge request ryubing/ryujinx!144
This commit is contained in:
LotP
2025-09-06 13:51:08 -05:00
parent a60b2a0ba3
commit b000f91dad
3 changed files with 49 additions and 108 deletions

View File

@@ -487,10 +487,12 @@ namespace Ryujinx.Graphics.Gpu.Memory
/// <param name="stage">The type of usage that created the buffer</param> /// <param name="stage">The type of usage that created the buffer</param>
private void CreateBufferAligned(ulong address, ulong size, BufferStage stage) private void CreateBufferAligned(ulong address, ulong size, BufferStage stage)
{ {
Buffer newBuffer = null;
_buffers.Lock.EnterWriteLock(); _buffers.Lock.EnterWriteLock();
Span<RangeItem<Buffer>> overlaps = _buffers.FindOverlapsAsSpan(address, size); Span<RangeItem<Buffer>> overlaps = _buffers.FindOverlapsAsSpan(address, size);
if (overlaps.Length > 0) if (overlaps.Length != 0)
{ {
// The buffer already exists. We can just return the existing buffer // The buffer already exists. We can just return the existing buffer
// if the buffer we need is fully contained inside the overlapping buffer. // if the buffer we need is fully contained inside the overlapping buffer.
@@ -530,13 +532,13 @@ namespace Ryujinx.Graphics.Gpu.Memory
address = Math.Min(address, overlaps[0].Address); address = Math.Min(address, overlaps[0].Address);
endAddress = Math.Max(endAddress, overlaps[^1].EndAddress); endAddress = Math.Max(endAddress, overlaps[^1].EndAddress);
RangeItem<Buffer>[] overlapsArray = overlaps.ToArray();
for (int i = 0; i < overlaps.Length; i++) for (int i = 0; i < overlaps.Length; i++)
{ {
anySparseCompatible |= overlaps[i].Value.SparseCompatible; anySparseCompatible |= overlaps[i].Value.SparseCompatible;
} }
RangeItem<Buffer>[] overlapsArray = overlaps.ToArray();
_buffers.RemoveRange(overlaps[0], overlaps[^1]); _buffers.RemoveRange(overlaps[0], overlaps[^1]);
@@ -544,22 +546,29 @@ namespace Ryujinx.Graphics.Gpu.Memory
ulong newSize = endAddress - address; ulong newSize = endAddress - address;
Buffer newBuffer = CreateBufferAligned(address, newSize, stage, anySparseCompatible, overlapsArray); newBuffer = CreateBufferAligned(address, newSize, stage, anySparseCompatible, overlapsArray);
}
_buffers.Lock.EnterWriteLock(); else
{
_buffers.Add(newBuffer); _buffers.Lock.ExitWriteLock();
} }
} }
else else
{ {
_buffers.Lock.ExitWriteLock();
// No overlap, just create a new buffer. // No overlap, just create a new buffer.
Buffer buffer = new(_context, _physicalMemory, address, size, stage, sparseCompatible: false, []); newBuffer = new(_context, _physicalMemory, address, size, stage, sparseCompatible: false, []);
}
_buffers.Add(buffer);
if (newBuffer is not null)
{
_buffers.Lock.EnterWriteLock();
_buffers.Add(newBuffer);
_buffers.Lock.ExitWriteLock();
} }
_buffers.Lock.ExitWriteLock();
} }
/// <summary> /// <summary>
@@ -574,11 +583,12 @@ namespace Ryujinx.Graphics.Gpu.Memory
private void CreateBufferAligned(ulong address, ulong size, BufferStage stage, ulong alignment) private void CreateBufferAligned(ulong address, ulong size, BufferStage stage, ulong alignment)
{ {
bool sparseAligned = alignment >= SparseBufferAlignmentSize; bool sparseAligned = alignment >= SparseBufferAlignmentSize;
Buffer newBuffer = null;
_buffers.Lock.EnterWriteLock(); _buffers.Lock.EnterWriteLock();
Span<RangeItem<Buffer>> overlaps = _buffers.FindOverlapsAsSpan(address, size); Span<RangeItem<Buffer>> overlaps = _buffers.FindOverlapsAsSpan(address, size);
if (overlaps.Length > 0) if (overlaps.Length != 0)
{ {
// If the buffer already exists, make sure if covers the entire range, // If the buffer already exists, make sure if covers the entire range,
// and make sure it is properly aligned, otherwise sparse mapping may fail. // and make sure it is properly aligned, otherwise sparse mapping may fail.
@@ -595,19 +605,20 @@ namespace Ryujinx.Graphics.Gpu.Memory
// overlaps more buffers, so try again after each extension // overlaps more buffers, so try again after each extension
// and ensure we cover all overlaps. // and ensure we cover all overlaps.
RangeItem<Buffer> oldFirst;
endAddress = Math.Max(endAddress, overlaps[^1].EndAddress); endAddress = Math.Max(endAddress, overlaps[^1].EndAddress);
int oldOverlapCount;
do do
{ {
address = Math.Min(address, overlaps[0].Address); address = Math.Min(address, overlaps[0].Address);
endAddress = Math.Max(endAddress, overlaps[^1].EndAddress);
address &= ~(alignment - 1); address &= ~(alignment - 1);
oldFirst = overlaps[0]; oldOverlapCount = overlaps.Length;
overlaps = _buffers.FindOverlapsAsSpan(address, endAddress - address); overlaps = _buffers.FindOverlapsAsSpan(address, endAddress - address);
} }
while (oldFirst != overlaps[0]); while (oldOverlapCount != overlaps.Length);
ulong newSize = endAddress - address; ulong newSize = endAddress - address;
@@ -617,22 +628,29 @@ namespace Ryujinx.Graphics.Gpu.Memory
_buffers.Lock.ExitWriteLock(); _buffers.Lock.ExitWriteLock();
Buffer newBuffer = CreateBufferAligned(address, newSize, stage, sparseAligned, overlapsArray); newBuffer = CreateBufferAligned(address, newSize, stage, sparseAligned, overlapsArray);
}
_buffers.Lock.EnterWriteLock(); else
{
_buffers.Add(newBuffer); _buffers.Lock.ExitWriteLock();
} }
} }
else else
{ {
_buffers.Lock.ExitWriteLock();
// No overlap, just create a new buffer. // No overlap, just create a new buffer.
Buffer buffer = new(_context, _physicalMemory, address, size, stage, sparseAligned, []); newBuffer = new(_context, _physicalMemory, address, size, stage, sparseAligned, []);
}
_buffers.Add(buffer);
if (newBuffer is not null)
{
_buffers.Lock.EnterWriteLock();
_buffers.Add(newBuffer);
_buffers.Lock.ExitWriteLock();
} }
_buffers.Lock.ExitWriteLock();
} }
/// <summary> /// <summary>
@@ -879,7 +897,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
{ {
MemoryRange subRange = range.GetSubRange(i); MemoryRange subRange = range.GetSubRange(i);
Buffer subBuffer = _buffers.FindOverlapFast(subRange.Address, subRange.Size).Value; Buffer subBuffer = _buffers.FindOverlap(subRange.Address, subRange.Size).Value;
subBuffer.SynchronizeMemory(subRange.Address, subRange.Size); subBuffer.SynchronizeMemory(subRange.Address, subRange.Size);
@@ -977,7 +995,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
{ {
if (size != 0) if (size != 0)
{ {
Buffer buffer = _buffers.FindOverlapFast(address, size).Value; Buffer buffer = _buffers.FindOverlap(address, size).Value;
if (copyBackVirtual) if (copyBackVirtual)
{ {

View File

@@ -473,6 +473,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
ranges._migrationTarget = this; ranges._migrationTarget = this;
Lock.EnterWriteLock(); Lock.EnterWriteLock();
foreach (BufferModifiedRange range in inheritRanges) foreach (BufferModifiedRange range in inheritRanges)
{ {
Add(range); Add(range);

View File

@@ -12,9 +12,6 @@ namespace Ryujinx.Memory.Range
/// <typeparam name="T">Type of the range.</typeparam> /// <typeparam name="T">Type of the range.</typeparam>
public unsafe class NonOverlappingRangeList<T> : RangeListBase<T> where T : class, INonOverlappingRange public unsafe class NonOverlappingRangeList<T> : RangeListBase<T> where T : class, INonOverlappingRange
{ {
// private readonly Dictionary<ulong, RangeItem<T>> _quickAccess = new(AddressEqualityComparer.Comparer);
// private readonly Dictionary<ulong, RangeItem<T>> _fastQuickAccess = new(AddressEqualityComparer.Comparer);
public readonly ReaderWriterLockSlim Lock = new(); public readonly ReaderWriterLockSlim Lock = new();
/// <summary> /// <summary>
@@ -44,8 +41,6 @@ namespace Ryujinx.Memory.Range
RangeItem<T> rangeItem = new(item); RangeItem<T> rangeItem = new(item);
Insert(index, rangeItem); Insert(index, rangeItem);
// _quickAccess.Add(item.Address, rangeItem);
} }
/// <summary> /// <summary>
@@ -71,15 +66,7 @@ namespace Ryujinx.Memory.Range
Items[index + 1].Previous = rangeItem; Items[index + 1].Previous = rangeItem;
} }
// foreach (ulong addr in Items[index].QuickAccessAddresses)
// {
// _quickAccess.Remove(addr);
// _fastQuickAccess.Remove(addr);
// }
Items[index] = rangeItem; Items[index] = rangeItem;
// _quickAccess[item.Address] = rangeItem;
return true; return true;
} }
@@ -108,19 +95,8 @@ namespace Ryujinx.Memory.Range
Items[index + 1].Previous = rangeItem; Items[index + 1].Previous = rangeItem;
} }
// foreach (ulong addr in item.QuickAccessAddresses)
// {
// _quickAccess.Remove(addr);
// _fastQuickAccess.Remove(addr);
// }
Items[index] = rangeItem; Items[index] = rangeItem;
// if (item.Address != rangeItem.Address)
// _quickAccess.Remove(item.Address);
//
// _quickAccess[rangeItem.Address] = rangeItem;
return true; return true;
} }
@@ -196,14 +172,6 @@ namespace Ryujinx.Memory.Range
if (index >= 0 && Items[index].Value.Equals(item)) if (index >= 0 && Items[index].Value.Equals(item))
{ {
// _quickAccess.Remove(item.Address);
//
// foreach (ulong addr in Items[index].QuickAccessAddresses)
// {
// _quickAccess.Remove(addr);
// _fastQuickAccess.Remove(addr);
// }
RemoveAt(index); RemoveAt(index);
return true; return true;
@@ -232,16 +200,6 @@ namespace Ryujinx.Memory.Range
(int startIndex, int endIndex) = BinarySearchEdges(startItem.Address, endItem.EndAddress); (int startIndex, int endIndex) = BinarySearchEdges(startItem.Address, endItem.EndAddress);
// for (int i = startIndex; i < endIndex; i++)
// {
// _quickAccess.Remove(Items[i].Address);
// foreach (ulong addr in Items[i].QuickAccessAddresses)
// {
// _quickAccess.Remove(addr);
// _fastQuickAccess.Remove(addr);
// }
// }
if (endIndex < Count) if (endIndex < Count)
{ {
Items[endIndex].Previous = startIndex > 0 ? Items[startIndex - 1] : null; Items[endIndex].Previous = startIndex > 0 ? Items[startIndex - 1] : null;
@@ -279,13 +237,6 @@ namespace Ryujinx.Memory.Range
while (Items[endIndex] is not null && Items[endIndex].Address < address + size) while (Items[endIndex] is not null && Items[endIndex].Address < address + size)
{ {
// _quickAccess.Remove(Items[endIndex].Address);
// foreach (ulong addr in Items[endIndex].QuickAccessAddresses)
// {
// _quickAccess.Remove(addr);
// _fastQuickAccess.Remove(addr);
// }
if (endIndex == Count - 1) if (endIndex == Count - 1)
{ {
break; break;
@@ -322,8 +273,6 @@ namespace Ryujinx.Memory.Range
Lock.EnterWriteLock(); Lock.EnterWriteLock();
Count = 0; Count = 0;
Lock.ExitWriteLock(); Lock.ExitWriteLock();
// _quickAccess.Clear();
// _fastQuickAccess.Clear();
} }
/// <summary> /// <summary>
@@ -436,11 +385,6 @@ namespace Ryujinx.Memory.Range
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public override RangeItem<T> FindOverlap(ulong address, ulong size) public override RangeItem<T> FindOverlap(ulong address, ulong size)
{ {
// if (_quickAccess.TryGetValue(address, out RangeItem<T> overlap))
// {
// return overlap;
// }
int index = BinarySearchLeftEdge(address, address + size); int index = BinarySearchLeftEdge(address, address + size);
if (index < 0) if (index < 0)
@@ -448,12 +392,6 @@ namespace Ryujinx.Memory.Range
return null; return null;
} }
// if (Items[index].Address < address)
// {
// _quickAccess.TryAdd(address, Items[index]);
// Items[index].QuickAccessAddresses.Add(address);
// }
return Items[index]; return Items[index];
} }
@@ -466,28 +404,12 @@ namespace Ryujinx.Memory.Range
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public override RangeItem<T> FindOverlapFast(ulong address, ulong size) public override RangeItem<T> FindOverlapFast(ulong address, ulong size)
{ {
// if (_quickAccess.TryGetValue(address, out RangeItem<T> overlap) || _fastQuickAccess.TryGetValue(address, out overlap))
// {
// return overlap;
// }
int index = BinarySearch(address, address + size); int index = BinarySearch(address, address + size);
if (index < 0) if (index < 0)
{ {
return null; return null;
} }
// if (Items[index].Address < address)
// {
// _quickAccess.TryAdd(address, Items[index]);
// }
// else
// {
// _fastQuickAccess.TryAdd(address, Items[index]);
// }
//
// Items[index].QuickAccessAddresses.Add(address);
return Items[index]; return Items[index];
} }