Pool.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. using Ryujinx.Graphics.Gpu.Memory;
  2. using System;
  3. namespace Ryujinx.Graphics.Gpu.Image
  4. {
  5. /// <summary>
  6. /// Represents a pool of GPU resources, such as samplers or textures.
  7. /// </summary>
  8. /// <typeparam name="T">GPU resource type</typeparam>
  9. abstract class Pool<T> : IDisposable
  10. {
  11. protected const int DescriptorSize = 0x20;
  12. protected GpuContext Context;
  13. protected T[] Items;
  14. /// <summary>
  15. /// The maximum ID value of resources on the pool (inclusive).
  16. /// The maximum amount of resources on the pool is equal to this value plus one.
  17. /// </summary>
  18. public int MaximumId { get; }
  19. /// <summary>
  20. /// The address of the pool in guest memory.
  21. /// </summary>
  22. public ulong Address { get; }
  23. /// <summary>
  24. /// The size of the pool in bytes.
  25. /// </summary>
  26. public ulong Size { get; }
  27. public Pool(GpuContext context, ulong address, int maximumId)
  28. {
  29. Context = context;
  30. MaximumId = maximumId;
  31. int count = maximumId + 1;
  32. ulong size = (ulong)(uint)count * DescriptorSize;;
  33. Items = new T[count];
  34. Address = address;
  35. Size = size;
  36. }
  37. /// <summary>
  38. /// Gets the GPU resource with the given ID.
  39. /// </summary>
  40. /// <param name="id">ID of the resource. This is effectively a zero-based index</param>
  41. /// <returns>The GPU resource with the given ID</returns>
  42. public abstract T Get(int id);
  43. /// <summary>
  44. /// Synchronizes host memory with guest memory.
  45. /// This causes a invalidation of pool entries,
  46. /// if a modification of entries by the CPU is detected.
  47. /// </summary>
  48. public void SynchronizeMemory()
  49. {
  50. (ulong, ulong)[] modifiedRanges = Context.PhysicalMemory.GetModifiedRanges(Address, Size, ResourceName.TexturePool);
  51. for (int index = 0; index < modifiedRanges.Length; index++)
  52. {
  53. (ulong mAddress, ulong mSize) = modifiedRanges[index];
  54. if (mAddress < Address)
  55. {
  56. mAddress = Address;
  57. }
  58. ulong maxSize = Address + Size - mAddress;
  59. if (mSize > maxSize)
  60. {
  61. mSize = maxSize;
  62. }
  63. InvalidateRangeImpl(mAddress, mSize);
  64. }
  65. }
  66. /// <summary>
  67. /// Invalidates a range of memory of the GPU resource pool.
  68. /// Entries that falls inside the speicified range will be invalidated,
  69. /// causing all the data to be reloaded from guest memory.
  70. /// </summary>
  71. /// <param name="address">The start address of the range to invalidate</param>
  72. /// <param name="size">The size of the range to invalidate</param>
  73. public void InvalidateRange(ulong address, ulong size)
  74. {
  75. ulong endAddress = address + size;
  76. ulong texturePoolEndAddress = Address + Size;
  77. // If the range being invalidated is not overlapping the texture pool range,
  78. // then we don't have anything to do, exit early.
  79. if (address >= texturePoolEndAddress || endAddress <= Address)
  80. {
  81. return;
  82. }
  83. if (address < Address)
  84. {
  85. address = Address;
  86. }
  87. if (endAddress > texturePoolEndAddress)
  88. {
  89. endAddress = texturePoolEndAddress;
  90. }
  91. size = endAddress - address;
  92. InvalidateRangeImpl(address, size);
  93. }
  94. protected abstract void InvalidateRangeImpl(ulong address, ulong size);
  95. protected abstract void Delete(T item);
  96. /// <summary>
  97. /// Performs the disposal of all resources stored on the pool.
  98. /// It's an error to try using the pool after disposal.
  99. /// </summary>
  100. public void Dispose()
  101. {
  102. if (Items != null)
  103. {
  104. for (int index = 0; index < Items.Length; index++)
  105. {
  106. Delete(Items[index]);
  107. }
  108. Items = null;
  109. }
  110. }
  111. }
  112. }