TexturePoolCache.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. using System.Collections.Generic;
  2. namespace Ryujinx.Graphics.Gpu.Image
  3. {
  4. /// <summary>
  5. /// Texture pool cache.
  6. /// This can keep multiple texture pools, and return the current one as needed.
  7. /// It is useful for applications that uses multiple texture pools.
  8. /// </summary>
  9. class TexturePoolCache
  10. {
  11. private const int MaxCapacity = 4;
  12. private GpuContext _context;
  13. private LinkedList<TexturePool> _pools;
  14. /// <summary>
  15. /// Constructs a new instance of the texture pool.
  16. /// </summary>
  17. /// <param name="context">GPU context that the texture pool belongs to</param>
  18. public TexturePoolCache(GpuContext context)
  19. {
  20. _context = context;
  21. _pools = new LinkedList<TexturePool>();
  22. }
  23. /// <summary>
  24. /// Finds a cache texture pool, or creates a new one if not found.
  25. /// </summary>
  26. /// <param name="address">Start address of the texture pool</param>
  27. /// <param name="maximumId">Maximum ID of the texture pool</param>
  28. /// <returns>The found or newly created texture pool</returns>
  29. public TexturePool FindOrCreate(ulong address, int maximumId)
  30. {
  31. TexturePool pool;
  32. // First we try to find the pool.
  33. for (LinkedListNode<TexturePool> node = _pools.First; node != null; node = node.Next)
  34. {
  35. pool = node.Value;
  36. if (pool.Address == address)
  37. {
  38. if (pool.CacheNode != _pools.Last)
  39. {
  40. _pools.Remove(pool.CacheNode);
  41. pool.CacheNode = _pools.AddLast(pool);
  42. }
  43. return pool;
  44. }
  45. }
  46. // If not found, create a new one.
  47. pool = new TexturePool(_context, address, maximumId);
  48. pool.CacheNode = _pools.AddLast(pool);
  49. if (_pools.Count > MaxCapacity)
  50. {
  51. TexturePool oldestPool = _pools.First.Value;
  52. _pools.RemoveFirst();
  53. oldestPool.Dispose();
  54. oldestPool.CacheNode = null;
  55. }
  56. return pool;
  57. }
  58. /// <summary>
  59. /// Invalidates a memory range of all intersecting texture pools on the cache.
  60. /// </summary>
  61. /// <param name="address">Start address of the range to invalidate</param>
  62. /// <param name="size">Size of the range to invalidate</param>
  63. public void InvalidateRange(ulong address, ulong size)
  64. {
  65. for (LinkedListNode<TexturePool> node = _pools.First; node != null; node = node.Next)
  66. {
  67. TexturePool pool = node.Value;
  68. pool.InvalidateRange(address, size);
  69. }
  70. }
  71. }
  72. }