mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-09-09 19:28:52 +00:00
Memory changes 2.2.1 (ryubing/ryujinx!144)
See merge request ryubing/ryujinx!144
This commit is contained in:
@@ -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)
|
||||||
{
|
{
|
||||||
|
@@ -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);
|
||||||
|
@@ -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];
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user