mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-06-28 00:16:23 +02:00
refactor: use Spans for aligned buffer creation
This commit is contained in:
parent
ce438f7276
commit
fe5b6ad7c7
3 changed files with 32 additions and 28 deletions
|
@ -110,7 +110,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
ulong size,
|
||||
BufferStage stage,
|
||||
bool sparseCompatible,
|
||||
IEnumerable<RangeItem<Buffer>> baseBuffers = null)
|
||||
ReadOnlySpan<RangeItem<Buffer>> baseBuffers)
|
||||
{
|
||||
_context = context;
|
||||
_physicalMemory = physicalMemory;
|
||||
|
@ -126,21 +126,22 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
|
||||
_useGranular = size > GranularBufferThreshold;
|
||||
|
||||
IEnumerable<IRegionHandle> baseHandles = null;
|
||||
List<IRegionHandle> baseHandles = null;
|
||||
|
||||
if (baseBuffers != null)
|
||||
if (!baseBuffers.IsEmpty)
|
||||
{
|
||||
baseHandles = baseBuffers.SelectMany(buffer =>
|
||||
baseHandles = new List<IRegionHandle>();
|
||||
foreach (RangeItem<Buffer> buffer in baseBuffers)
|
||||
{
|
||||
if (buffer.Value._useGranular)
|
||||
{
|
||||
return buffer.Value._memoryTrackingGranular.GetHandles();
|
||||
baseHandles.AddRange((buffer.Value._memoryTrackingGranular.GetHandles()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return Enumerable.Repeat(buffer.Value._memoryTracking, 1);
|
||||
baseHandles.Add(buffer.Value._memoryTracking);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (_useGranular)
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
/// <param name="parent">Parent buffer</param>
|
||||
/// <param name="stage">Initial buffer stage</param>
|
||||
/// <param name="baseBuffers">Buffers to inherit state from</param>
|
||||
public BufferBackingState(GpuContext context, Buffer parent, BufferStage stage, IEnumerable<RangeItem<Buffer>> baseBuffers = null)
|
||||
public BufferBackingState(GpuContext context, Buffer parent, BufferStage stage, ReadOnlySpan<RangeItem<Buffer>> baseBuffers)
|
||||
{
|
||||
_size = (int)parent.Size;
|
||||
_systemMemoryType = context.Capabilities.MemoryType;
|
||||
|
@ -73,7 +73,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
|
||||
BufferStage storageFlags = stage & BufferStage.StorageMask;
|
||||
|
||||
if (parent.Size > DeviceLocalSizeThreshold && baseBuffers == null)
|
||||
if (parent.Size > DeviceLocalSizeThreshold && baseBuffers.IsEmpty)
|
||||
{
|
||||
_desiredType = BufferBackingType.DeviceMemory;
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
// TODO: Might be nice to force atomic access to be device local for any stage.
|
||||
}
|
||||
|
||||
if (baseBuffers != null)
|
||||
if (!baseBuffers.IsEmpty)
|
||||
{
|
||||
foreach (RangeItem<Buffer> buffer in baseBuffers)
|
||||
{
|
||||
|
|
|
@ -495,8 +495,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
private void CreateBufferAligned(ulong address, ulong size, BufferStage stage)
|
||||
{
|
||||
_buffers.Lock.EnterWriteLock();
|
||||
RangeItem<Buffer>[] overlaps = _bufferOverlaps;
|
||||
OverlapResult result = _buffers.FindOverlapsNonOverlapping(address, size, ref overlaps);
|
||||
OverlapResult result = _buffers.FindOverlapsNonOverlappingAsSpan(address, size, out ReadOnlySpan<RangeItem<Buffer>> overlaps);
|
||||
|
||||
if (result.Count != 0)
|
||||
{
|
||||
|
@ -534,10 +533,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
size = Math.Max(size, growthSize);
|
||||
endAddress = address + size;
|
||||
|
||||
result = _buffers.FindOverlapsNonOverlapping(address, size, ref overlaps);
|
||||
result = _buffers.FindOverlapsNonOverlappingAsSpan(address, size, out overlaps);
|
||||
}
|
||||
|
||||
_buffers.RemoveRange(result);
|
||||
|
||||
address = Math.Min(address, overlaps[0].Address);
|
||||
endAddress = Math.Max(endAddress, overlaps[^1].EndAddress);
|
||||
|
@ -549,15 +547,20 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
anySparseCompatible |= buffer.Value.SparseCompatible;
|
||||
}
|
||||
|
||||
|
||||
ulong newSize = endAddress - address;
|
||||
|
||||
CreateBufferAligned(address, newSize, stage, anySparseCompatible, overlaps, result.Count);
|
||||
Buffer newBuffer = CreateBufferAligned(address, newSize, stage, anySparseCompatible, overlaps);
|
||||
|
||||
_buffers.RemoveRange(result);
|
||||
|
||||
_buffers.Add(newBuffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No overlap, just create a new buffer.
|
||||
Buffer buffer = new(_context, _physicalMemory, address, size, stage, sparseCompatible: false);
|
||||
Buffer buffer = new(_context, _physicalMemory, address, size, stage, sparseCompatible: false, ReadOnlySpan<RangeItem<Buffer>>.Empty);
|
||||
|
||||
_buffers.Add(buffer);
|
||||
}
|
||||
|
@ -579,8 +582,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
private void CreateBufferAligned(ulong address, ulong size, BufferStage stage, ulong alignment)
|
||||
{
|
||||
_buffers.Lock.EnterWriteLock();
|
||||
RangeItem<Buffer>[] overlaps = _bufferOverlaps;
|
||||
OverlapResult result = _buffers.FindOverlapsNonOverlapping(address, size, ref overlaps);
|
||||
OverlapResult result = _buffers.FindOverlapsNonOverlappingAsSpan(address, size, out ReadOnlySpan<RangeItem<Buffer>> overlaps);
|
||||
bool sparseAligned = alignment >= SparseBufferAlignmentSize;
|
||||
|
||||
if (result.Count != 0)
|
||||
|
@ -611,21 +613,23 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
address &= ~(alignment - 1);
|
||||
|
||||
oldOverlapsCount = result.Count;
|
||||
result = _buffers.FindOverlapsNonOverlapping(address, endAddress - address, ref overlaps);
|
||||
result = _buffers.FindOverlapsNonOverlappingAsSpan(address, endAddress - address, out overlaps);
|
||||
}
|
||||
while (oldOverlapsCount != result.Count);
|
||||
|
||||
_buffers.RemoveRange(result);
|
||||
|
||||
ulong newSize = endAddress - address;
|
||||
|
||||
CreateBufferAligned(address, newSize, stage, sparseAligned, overlaps, result.Count);
|
||||
Buffer newBuffer = CreateBufferAligned(address, newSize, stage, sparseAligned, overlaps);
|
||||
|
||||
_buffers.RemoveRange(result);
|
||||
|
||||
_buffers.Add(newBuffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No overlap, just create a new buffer.
|
||||
Buffer buffer = new(_context, _physicalMemory, address, size, stage, sparseAligned);
|
||||
Buffer buffer = new(_context, _physicalMemory, address, size, stage, sparseAligned, ReadOnlySpan<RangeItem<Buffer>>.Empty);
|
||||
|
||||
_buffers.Add(buffer);
|
||||
}
|
||||
|
@ -644,14 +648,11 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
/// <param name="stage">The type of usage that created the buffer</param>
|
||||
/// <param name="sparseCompatible">Indicates if the buffer can be used in a sparse buffer mapping</param>
|
||||
/// <param name="overlaps">Buffers overlapping the range</param>
|
||||
/// <param name="overlapsCount">Total of overlaps</param>
|
||||
private void CreateBufferAligned(ulong address, ulong size, BufferStage stage, bool sparseCompatible, RangeItem<Buffer>[] overlaps, int overlapsCount)
|
||||
private Buffer CreateBufferAligned(ulong address, ulong size, BufferStage stage, bool sparseCompatible, ReadOnlySpan<RangeItem<Buffer>> overlaps)
|
||||
{
|
||||
Buffer newBuffer = new(_context, _physicalMemory, address, size, stage, sparseCompatible, overlaps);
|
||||
|
||||
_buffers.Add(newBuffer);
|
||||
|
||||
for (int index = 0; index < overlapsCount; index++)
|
||||
for (int index = 0; index < overlaps.Length; index++)
|
||||
{
|
||||
Buffer buffer = overlaps[index].Value;
|
||||
|
||||
|
@ -669,6 +670,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
NotifyBuffersModified?.Invoke();
|
||||
|
||||
RecreateMultiRangeBuffers(address, size);
|
||||
|
||||
return newBuffer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue