From 29ad1980033061704d1fe1e86ff13e1ff6e3d988 Mon Sep 17 00:00:00 2001 From: Jim Horvath <38920027+jhorv@users.noreply.github.com> Date: Sun, 4 Feb 2024 01:09:19 -0500 Subject: [PATCH] - WritableRegion: enable wrapping IMemoryOwner - IVirtualMemoryManager impls of GetWritableRegion() use pooled memory when region is non-contiguous. - IVirtualMemoryManager: add GetReadOnlySequence() and impls - ByteMemoryPool: add new method RentCopy() - ByteMemoryPool: make class static, remove ctor and singleton field from earlier impl --- src/Ryujinx.Common/Memory/ByteMemoryPool.cs | 14 ++++++++++ .../Memory/BytesReadOnlySequenceSegment.cs | 26 +++++++++++++++++++ src/Ryujinx.Memory/IVirtualMemoryManager.cs | 10 +++++++ 3 files changed, 50 insertions(+) create mode 100644 src/Ryujinx.Common/Memory/BytesReadOnlySequenceSegment.cs diff --git a/src/Ryujinx.Common/Memory/ByteMemoryPool.cs b/src/Ryujinx.Common/Memory/ByteMemoryPool.cs index 6fd6a98aa7..53bbee4fa6 100644 --- a/src/Ryujinx.Common/Memory/ByteMemoryPool.cs +++ b/src/Ryujinx.Common/Memory/ByteMemoryPool.cs @@ -78,6 +78,20 @@ namespace Ryujinx.Common.Memory return buffer; } + + /// + /// Copies into a newly rented byte memory buffer. + /// + /// The byte buffer to copy + /// A wrapping the rented memory with copied to it + public static IMemoryOwner RentCopy(ReadOnlySpan buffer) + { + var copy = RentImpl(buffer.Length); + + buffer.CopyTo(copy.Memory.Span); + + return copy; + } /// /// Copies into a newly rented byte memory buffer. diff --git a/src/Ryujinx.Common/Memory/BytesReadOnlySequenceSegment.cs b/src/Ryujinx.Common/Memory/BytesReadOnlySequenceSegment.cs new file mode 100644 index 0000000000..9c4cd1ff36 --- /dev/null +++ b/src/Ryujinx.Common/Memory/BytesReadOnlySequenceSegment.cs @@ -0,0 +1,26 @@ +using System; +using System.Buffers; + +namespace Ryujinx.Common.Memory +{ + /// + /// A concrete implementation of , + /// with methods to help build a full sequence. + /// + public sealed class BytesReadOnlySequenceSegment : ReadOnlySequenceSegment + { + public BytesReadOnlySequenceSegment(Memory memory) => Memory = memory; + + public BytesReadOnlySequenceSegment Append(Memory memory) + { + var nextSegment = new BytesReadOnlySequenceSegment(memory) + { + RunningIndex = RunningIndex + Memory.Length + }; + + Next = nextSegment; + + return nextSegment; + } + } +} diff --git a/src/Ryujinx.Memory/IVirtualMemoryManager.cs b/src/Ryujinx.Memory/IVirtualMemoryManager.cs index 96d3e85797..a94be42f73 100644 --- a/src/Ryujinx.Memory/IVirtualMemoryManager.cs +++ b/src/Ryujinx.Memory/IVirtualMemoryManager.cs @@ -123,6 +123,16 @@ namespace Ryujinx.Memory writableRegion.Memory.Span.Fill(value); } } + + /// + /// Gets a read-only sequence of read-only memory blocks from CPU mapped memory. + /// + /// Virtual address of the data + /// Size of the data + /// True if read tracking is triggered on the memory + /// A read-only sequence of read-only memory of the data + /// Throw for unhandled invalid or unmapped memory accesses + ReadOnlySequence GetReadOnlySequence(ulong va, int size, bool tracked = false); /// /// Gets a read-only sequence of read-only memory blocks from CPU mapped memory.