Buffer.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using Ryujinx.Graphics.GAL;
  2. using System;
  3. namespace Ryujinx.Graphics.Gpu.Memory
  4. {
  5. class Buffer : IRange<Buffer>, IDisposable
  6. {
  7. private GpuContext _context;
  8. private IBuffer _buffer;
  9. public ulong Address { get; }
  10. public ulong Size { get; }
  11. public ulong EndAddress => Address + Size;
  12. private int[] _sequenceNumbers;
  13. public Buffer(GpuContext context, ulong address, ulong size)
  14. {
  15. _context = context;
  16. Address = address;
  17. Size = size;
  18. _buffer = context.Renderer.CreateBuffer((int)size);
  19. _sequenceNumbers = new int[size / MemoryManager.PageSize];
  20. Invalidate();
  21. }
  22. public BufferRange GetRange(ulong address, ulong size)
  23. {
  24. int offset = (int)(address - Address);
  25. return new BufferRange(_buffer, offset, (int)size);
  26. }
  27. public bool OverlapsWith(ulong address, ulong size)
  28. {
  29. return Address < address + size && address < EndAddress;
  30. }
  31. public void SynchronizeMemory(ulong address, ulong size)
  32. {
  33. int currentSequenceNumber = _context.SequenceNumber;
  34. bool needsSync = false;
  35. ulong buffOffset = address - Address;
  36. ulong buffEndOffset = (buffOffset + size + MemoryManager.PageMask) & ~MemoryManager.PageMask;
  37. int startIndex = (int)(buffOffset / MemoryManager.PageSize);
  38. int endIndex = (int)(buffEndOffset / MemoryManager.PageSize);
  39. for (int index = startIndex; index < endIndex; index++)
  40. {
  41. if (_sequenceNumbers[index] != currentSequenceNumber)
  42. {
  43. _sequenceNumbers[index] = currentSequenceNumber;
  44. needsSync = true;
  45. }
  46. }
  47. if (!needsSync)
  48. {
  49. return;
  50. }
  51. (ulong, ulong)[] modifiedRanges = _context.PhysicalMemory.GetModifiedRanges(address, size);
  52. for (int index = 0; index < modifiedRanges.Length; index++)
  53. {
  54. (ulong mAddress, ulong mSize) = modifiedRanges[index];
  55. int offset = (int)(mAddress - Address);
  56. _buffer.SetData(offset, _context.PhysicalMemory.Read(mAddress, mSize));
  57. }
  58. }
  59. public void CopyTo(Buffer destination, int dstOffset)
  60. {
  61. _buffer.CopyTo(destination._buffer, 0, dstOffset, (int)Size);
  62. }
  63. public void Invalidate()
  64. {
  65. _buffer.SetData(0, _context.PhysicalMemory.Read(Address, Size));
  66. }
  67. public void Dispose()
  68. {
  69. _buffer.Dispose();
  70. }
  71. }
  72. }