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