| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- using Ryujinx.Graphics.GAL;
- using System;
- namespace Ryujinx.Graphics.Gpu.Memory
- {
- class Buffer : IRange<Buffer>, IDisposable
- {
- private GpuContext _context;
- private IBuffer _buffer;
- public IBuffer HostBuffer => _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, ResourceName.Buffer);
- 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 Flush(ulong address, ulong size)
- {
- int offset = (int)(address - Address);
- byte[] data = _buffer.GetData(offset, (int)size);
- _context.PhysicalMemory.Write(address, data);
- }
- public void Invalidate()
- {
- _buffer.SetData(0, _context.PhysicalMemory.Read(Address, Size));
- }
- public void Dispose()
- {
- _buffer.Dispose();
- }
- }
- }
|