diff options
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Memory/Buffer.cs')
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Memory/Buffer.cs | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.Gpu/Memory/Buffer.cs b/Ryujinx.Graphics.Gpu/Memory/Buffer.cs new file mode 100644 index 00000000..30bd1ac0 --- /dev/null +++ b/Ryujinx.Graphics.Gpu/Memory/Buffer.cs @@ -0,0 +1,99 @@ +using Ryujinx.Graphics.GAL; +using System; + +namespace Ryujinx.Graphics.Gpu.Memory +{ + class Buffer : IRange<Buffer>, IDisposable + { + private GpuContext _context; + + private IBuffer _buffer; + + public ulong Address { get; } + public ulong Size { get; } + + public ulong EndAddress => Address + Size; + + private int[] _sequenceNumbers; + + public Buffer(GpuContext context, ulong address, ulong size) + { + _context = context; + Address = address; + Size = size; + + _buffer = context.Renderer.CreateBuffer((int)size); + + _sequenceNumbers = new int[size / MemoryManager.PageSize]; + + Invalidate(); + } + + public BufferRange GetRange(ulong address, ulong size) + { + int offset = (int)(address - Address); + + return new BufferRange(_buffer, offset, (int)size); + } + + public bool OverlapsWith(ulong address, ulong size) + { + return Address < address + size && address < EndAddress; + } + + public void SynchronizeMemory(ulong address, ulong size) + { + int currentSequenceNumber = _context.SequenceNumber; + + bool needsSync = false; + + ulong buffOffset = address - Address; + + ulong buffEndOffset = (buffOffset + size + MemoryManager.PageMask) & ~MemoryManager.PageMask; + + int startIndex = (int)(buffOffset / MemoryManager.PageSize); + int endIndex = (int)(buffEndOffset / MemoryManager.PageSize); + + for (int index = startIndex; index < endIndex; index++) + { + if (_sequenceNumbers[index] != currentSequenceNumber) + { + _sequenceNumbers[index] = currentSequenceNumber; + + needsSync = true; + } + } + + if (!needsSync) + { + return; + } + + (ulong, ulong)[] modifiedRanges = _context.PhysicalMemory.GetModifiedRanges(address, size); + + for (int index = 0; index < modifiedRanges.Length; index++) + { + (ulong mAddress, ulong mSize) = modifiedRanges[index]; + + int offset = (int)(mAddress - Address); + + _buffer.SetData(offset, _context.PhysicalMemory.Read(mAddress, mSize)); + } + } + + public void CopyTo(Buffer destination, int dstOffset) + { + _buffer.CopyTo(destination._buffer, 0, dstOffset, (int)Size); + } + + public void Invalidate() + { + _buffer.SetData(0, _context.PhysicalMemory.Read(Address, Size)); + } + + public void Dispose() + { + _buffer.Dispose(); + } + } +}
\ No newline at end of file |
