diff options
Diffstat (limited to 'Ryujinx.Graphics.Vulkan/ShaderCollection.cs')
-rw-r--r-- | Ryujinx.Graphics.Vulkan/ShaderCollection.cs | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/Ryujinx.Graphics.Vulkan/ShaderCollection.cs b/Ryujinx.Graphics.Vulkan/ShaderCollection.cs index 82866f7b..ab0ea2e9 100644 --- a/Ryujinx.Graphics.Vulkan/ShaderCollection.cs +++ b/Ryujinx.Graphics.Vulkan/ShaderCollection.cs @@ -26,6 +26,8 @@ namespace Ryujinx.Graphics.Vulkan public ProgramLinkStatus LinkStatus { get; private set; } + public readonly SpecDescription[] SpecDescriptions; + public bool IsLinked { get @@ -40,7 +42,7 @@ namespace Ryujinx.Graphics.Vulkan } private HashTableSlim<PipelineUid, Auto<DisposablePipeline>> _graphicsPipelineCache; - private Auto<DisposablePipeline> _computePipeline; + private HashTableSlim<SpecData, Auto<DisposablePipeline>> _computePipelineCache; private VulkanRenderer _gd; private Device _device; @@ -52,17 +54,24 @@ namespace Ryujinx.Graphics.Vulkan private Task _compileTask; private bool _firstBackgroundUse; - public ShaderCollection(VulkanRenderer gd, Device device, ShaderSource[] shaders, bool isMinimal = false) + public ShaderCollection(VulkanRenderer gd, Device device, ShaderSource[] shaders, SpecDescription[] specDescription = null, bool isMinimal = false) { _gd = gd; _device = device; + if (specDescription != null && specDescription.Length != shaders.Length) + { + throw new ArgumentException($"{nameof(specDescription)} array length must match {nameof(shaders)} array if provided"); + } + gd.Shaders.Add(this); var internalShaders = new Shader[shaders.Length]; _infos = new PipelineShaderStageCreateInfo[shaders.Length]; + SpecDescriptions = specDescription; + LinkStatus = ProgramLinkStatus.Incomplete; uint stages = 0; @@ -314,14 +323,9 @@ namespace Ryujinx.Graphics.Vulkan return null; } - public void AddComputePipeline(Auto<DisposablePipeline> pipeline) + public void AddComputePipeline(ref SpecData key, Auto<DisposablePipeline> pipeline) { - _computePipeline = pipeline; - } - - public void RemoveComputePipeline() - { - _computePipeline = null; + (_computePipelineCache ??= new()).Add(ref key, pipeline); } public void AddGraphicsPipeline(ref PipelineUid key, Auto<DisposablePipeline> pipeline) @@ -329,10 +333,20 @@ namespace Ryujinx.Graphics.Vulkan (_graphicsPipelineCache ??= new()).Add(ref key, pipeline); } - public bool TryGetComputePipeline(out Auto<DisposablePipeline> pipeline) + public bool TryGetComputePipeline(ref SpecData key, out Auto<DisposablePipeline> pipeline) { - pipeline = _computePipeline; - return pipeline != null; + if (_computePipelineCache == null) + { + pipeline = default; + return false; + } + + if (_computePipelineCache.TryGetValue(ref key, out pipeline)) + { + return true; + } + + return false; } public bool TryGetGraphicsPipeline(ref PipelineUid key, out Auto<DisposablePipeline> pipeline) @@ -390,7 +404,14 @@ namespace Ryujinx.Graphics.Vulkan } } - _computePipeline?.Dispose(); + if (_computePipelineCache != null) + { + foreach (Auto<DisposablePipeline> pipeline in _computePipelineCache.Values) + { + pipeline.Dispose(); + } + } + if (_dummyRenderPass.Value.Handle != 0) { _dummyRenderPass.Dispose(); |