NvGpuVmmCache.cs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. using ChocolArm64.Events;
  2. using ChocolArm64.Memory;
  3. using System.Collections.Concurrent;
  4. namespace Ryujinx.Graphics.Memory
  5. {
  6. class NvGpuVmmCache
  7. {
  8. private const int PageBits = MemoryManager.PageBits;
  9. private const long PageSize = MemoryManager.PageSize;
  10. private const long PageMask = MemoryManager.PageMask;
  11. private ConcurrentDictionary<long, int>[] CachedPages;
  12. private MemoryManager _memory;
  13. public NvGpuVmmCache(MemoryManager memory)
  14. {
  15. _memory = memory;
  16. _memory.ObservedAccess += MemoryAccessHandler;
  17. CachedPages = new ConcurrentDictionary<long, int>[1 << 20];
  18. }
  19. private void MemoryAccessHandler(object sender, MemoryAccessEventArgs e)
  20. {
  21. long pa = _memory.GetPhysicalAddress(e.Position);
  22. CachedPages[pa >> PageBits]?.Clear();
  23. }
  24. public bool IsRegionModified(long position, long size, NvGpuBufferType bufferType)
  25. {
  26. long pa = _memory.GetPhysicalAddress(position);
  27. long addr = pa;
  28. long endAddr = (addr + size + PageMask) & ~PageMask;
  29. int newBuffMask = 1 << (int)bufferType;
  30. _memory.StartObservingRegion(position, size);
  31. long cachedPagesCount = 0;
  32. while (addr < endAddr)
  33. {
  34. long page = addr >> PageBits;
  35. ConcurrentDictionary<long, int> dictionary = CachedPages[page];
  36. if (dictionary == null)
  37. {
  38. dictionary = new ConcurrentDictionary<long, int>();
  39. CachedPages[page] = dictionary;
  40. }
  41. if (dictionary.TryGetValue(pa, out int currBuffMask))
  42. {
  43. if ((currBuffMask & newBuffMask) != 0)
  44. {
  45. cachedPagesCount++;
  46. }
  47. else
  48. {
  49. dictionary[pa] |= newBuffMask;
  50. }
  51. }
  52. else
  53. {
  54. dictionary[pa] = newBuffMask;
  55. }
  56. addr += PageSize;
  57. }
  58. return cachedPagesCount != (endAddr - pa + PageMask) >> PageBits;
  59. }
  60. }
  61. }