PipelineLayoutCache.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. using Ryujinx.Graphics.GAL;
  2. using Silk.NET.Vulkan;
  3. using System;
  4. using System.Collections.Concurrent;
  5. using System.Collections.ObjectModel;
  6. namespace Ryujinx.Graphics.Vulkan
  7. {
  8. class PipelineLayoutCache
  9. {
  10. private readonly struct PlceKey : IEquatable<PlceKey>
  11. {
  12. public readonly ReadOnlyCollection<ResourceDescriptorCollection> SetDescriptors;
  13. public readonly bool UsePushDescriptors;
  14. public PlceKey(ReadOnlyCollection<ResourceDescriptorCollection> setDescriptors, bool usePushDescriptors)
  15. {
  16. SetDescriptors = setDescriptors;
  17. UsePushDescriptors = usePushDescriptors;
  18. }
  19. public override int GetHashCode()
  20. {
  21. HashCode hasher = new();
  22. if (SetDescriptors != null)
  23. {
  24. foreach (var setDescriptor in SetDescriptors)
  25. {
  26. hasher.Add(setDescriptor);
  27. }
  28. }
  29. hasher.Add(UsePushDescriptors);
  30. return hasher.ToHashCode();
  31. }
  32. public override bool Equals(object obj)
  33. {
  34. return obj is PlceKey other && Equals(other);
  35. }
  36. public bool Equals(PlceKey other)
  37. {
  38. if ((SetDescriptors == null) != (other.SetDescriptors == null))
  39. {
  40. return false;
  41. }
  42. if (SetDescriptors != null)
  43. {
  44. if (SetDescriptors.Count != other.SetDescriptors.Count)
  45. {
  46. return false;
  47. }
  48. for (int index = 0; index < SetDescriptors.Count; index++)
  49. {
  50. if (!SetDescriptors[index].Equals(other.SetDescriptors[index]))
  51. {
  52. return false;
  53. }
  54. }
  55. }
  56. return UsePushDescriptors == other.UsePushDescriptors;
  57. }
  58. }
  59. private readonly ConcurrentDictionary<PlceKey, PipelineLayoutCacheEntry> _plces;
  60. public PipelineLayoutCache()
  61. {
  62. _plces = new ConcurrentDictionary<PlceKey, PipelineLayoutCacheEntry>();
  63. }
  64. public PipelineLayoutCacheEntry GetOrCreate(
  65. VulkanRenderer gd,
  66. Device device,
  67. ReadOnlyCollection<ResourceDescriptorCollection> setDescriptors,
  68. bool usePushDescriptors)
  69. {
  70. var key = new PlceKey(setDescriptors, usePushDescriptors);
  71. return _plces.GetOrAdd(key, newKey => new PipelineLayoutCacheEntry(gd, device, setDescriptors, usePushDescriptors));
  72. }
  73. protected virtual void Dispose(bool disposing)
  74. {
  75. if (disposing)
  76. {
  77. foreach (var plce in _plces.Values)
  78. {
  79. plce.Dispose();
  80. }
  81. _plces.Clear();
  82. }
  83. }
  84. public void Dispose()
  85. {
  86. Dispose(true);
  87. }
  88. }
  89. }