From 5626f2ca1c49342b20772224f956147df6957b5a Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 21 May 2023 14:04:21 -0300 Subject: Replace ShaderBindings with new ResourceLayout structure for Vulkan (#5025) * Introduce ResourceLayout * Part 1: Use new ResourceSegments array on UpdateAndBind * Part 2: Use ResourceLayout to build PipelineLayout * Delete old code * XML docs * Fix shader cache load NRE * Fix typo --- src/Ryujinx.Graphics.Vulkan/PipelineLayoutCache.cs | 97 ++++++++++++++++------ 1 file changed, 73 insertions(+), 24 deletions(-) (limited to 'src/Ryujinx.Graphics.Vulkan/PipelineLayoutCache.cs') diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineLayoutCache.cs b/src/Ryujinx.Graphics.Vulkan/PipelineLayoutCache.cs index c834fa62..e7c43567 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineLayoutCache.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineLayoutCache.cs @@ -1,52 +1,101 @@ using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; -using System.Collections.Generic; +using System; +using System.Collections.Concurrent; +using System.Collections.ObjectModel; namespace Ryujinx.Graphics.Vulkan { class PipelineLayoutCache { - private readonly PipelineLayoutCacheEntry[] _plce; - private readonly List _plceMinimal; - - public PipelineLayoutCache() + private readonly struct PlceKey : IEquatable { - _plce = new PipelineLayoutCacheEntry[1 << Constants.MaxShaderStages]; - _plceMinimal = new List(); + public readonly ReadOnlyCollection SetDescriptors; + public readonly bool UsePushDescriptors; + + public PlceKey(ReadOnlyCollection setDescriptors, bool usePushDescriptors) + { + SetDescriptors = setDescriptors; + UsePushDescriptors = usePushDescriptors; + } + + public override int GetHashCode() + { + HashCode hasher = new HashCode(); + + if (SetDescriptors != null) + { + foreach (var setDescriptor in SetDescriptors) + { + hasher.Add(setDescriptor); + } + } + + hasher.Add(UsePushDescriptors); + + return hasher.ToHashCode(); + } + + public override bool Equals(object obj) + { + return obj is PlceKey other && Equals(other); + } + + public bool Equals(PlceKey other) + { + if ((SetDescriptors == null) != (other.SetDescriptors == null)) + { + return false; + } + + if (SetDescriptors != null) + { + if (SetDescriptors.Count != other.SetDescriptors.Count) + { + return false; + } + + for (int index = 0; index < SetDescriptors.Count; index++) + { + if (!SetDescriptors[index].Equals(other.SetDescriptors[index])) + { + return false; + } + } + } + + return UsePushDescriptors == other.UsePushDescriptors; + } } - public PipelineLayoutCacheEntry Create(VulkanRenderer gd, Device device, ShaderSource[] shaders) + private readonly ConcurrentDictionary _plces; + + public PipelineLayoutCache() { - var plce = new PipelineLayoutCacheEntry(gd, device, shaders); - _plceMinimal.Add(plce); - return plce; + _plces = new ConcurrentDictionary(); } - public PipelineLayoutCacheEntry GetOrCreate(VulkanRenderer gd, Device device, uint stages, bool usePd) + public PipelineLayoutCacheEntry GetOrCreate( + VulkanRenderer gd, + Device device, + ReadOnlyCollection setDescriptors, + bool usePushDescriptors) { - if (_plce[stages] == null) - { - _plce[stages] = new PipelineLayoutCacheEntry(gd, device, stages, usePd); - } + var key = new PlceKey(setDescriptors, usePushDescriptors); - return _plce[stages]; + return _plces.GetOrAdd(key, (newKey) => new PipelineLayoutCacheEntry(gd, device, setDescriptors, usePushDescriptors)); } protected virtual unsafe void Dispose(bool disposing) { if (disposing) { - for (int i = 0; i < _plce.Length; i++) - { - _plce[i]?.Dispose(); - } - - foreach (var plce in _plceMinimal) + foreach (var plce in _plces.Values) { plce.Dispose(); } - _plceMinimal.Clear(); + _plces.Clear(); } } -- cgit v1.2.3