From 53d096e392d85106a41d8edad1dcda5cce7446a2 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 26 May 2024 13:30:19 -0300 Subject: Allow texture arrays to use separate descriptor sets on Vulkan (#6870) * Report base and extra sets from the backend * Pass texture set index everywhere * Key textures using set and binding (rather than just binding) * Start using extra sets for array textures * Shader cache version bump * Separate new commands, some PR feedback * Introduce new manual descriptor set reservation method that prevents it from being used by something else while owned by an array * Move bind extra sets logic to new method * Should only use separate array is MaximumExtraSets is not zero * Format whitespace --- src/Ryujinx.Graphics.Vulkan/ImageArray.cs | 75 ++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) (limited to 'src/Ryujinx.Graphics.Vulkan/ImageArray.cs') diff --git a/src/Ryujinx.Graphics.Vulkan/ImageArray.cs b/src/Ryujinx.Graphics.Vulkan/ImageArray.cs index 38a5b6b4..3c7f321f 100644 --- a/src/Ryujinx.Graphics.Vulkan/ImageArray.cs +++ b/src/Ryujinx.Graphics.Vulkan/ImageArray.cs @@ -2,6 +2,7 @@ using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; using System.Collections.Generic; +using System.Diagnostics; namespace Ryujinx.Graphics.Vulkan { @@ -24,12 +25,18 @@ namespace Ryujinx.Graphics.Vulkan private HashSet _storages; + private DescriptorSet[] _cachedDescriptorSets; + private int _cachedCommandBufferIndex; private int _cachedSubmissionCount; + private ShaderCollection _cachedDscProgram; + private int _cachedDscSetIndex; + private int _cachedDscIndex; + private readonly bool _isBuffer; - public bool Bound; + private int _bindCount; public ImageArray(VulkanRenderer gd, int size, bool isBuffer) { @@ -97,8 +104,12 @@ namespace Ryujinx.Graphics.Vulkan { _cachedCommandBufferIndex = -1; _storages = null; + _cachedDescriptorSets = null; - _gd.PipelineInternal.ForceImageDirty(); + if (_bindCount != 0) + { + _gd.PipelineInternal.ForceImageDirty(); + } } public void QueueWriteToReadBarriers(CommandBufferScoped cbs, PipelineStageFlags stageFlags) @@ -175,5 +186,65 @@ namespace Ryujinx.Graphics.Vulkan return bufferTextures; } + + public DescriptorSet[] GetDescriptorSets( + Device device, + CommandBufferScoped cbs, + DescriptorSetTemplateUpdater templateUpdater, + ShaderCollection program, + int setIndex, + TextureView dummyTexture) + { + if (_cachedDescriptorSets != null) + { + // We still need to ensure the current command buffer holds a reference to all used textures. + + if (!_isBuffer) + { + GetImageInfos(_gd, cbs, dummyTexture); + } + else + { + GetBufferViews(cbs); + } + + return _cachedDescriptorSets; + } + + _cachedDscProgram?.ReleaseManualDescriptorSetCollection(_cachedDscSetIndex, _cachedDscIndex); + var dsc = program.GetNewManualDescriptorSetCollection(cbs.CommandBufferIndex, setIndex, out _cachedDscIndex).Get(cbs); + + DescriptorSetTemplate template = program.Templates[setIndex]; + + DescriptorSetTemplateWriter tu = templateUpdater.Begin(template); + + if (!_isBuffer) + { + tu.Push(GetImageInfos(_gd, cbs, dummyTexture)); + } + else + { + tu.Push(GetBufferViews(cbs)); + } + + var sets = dsc.GetSets(); + templateUpdater.Commit(_gd, device, sets[0]); + _cachedDescriptorSets = sets; + _cachedDscProgram = program; + _cachedDscSetIndex = setIndex; + + return sets; + } + + public void IncrementBindCount() + { + _bindCount++; + } + + public void DecrementBindCount() + { + int newBindCount = --_bindCount; + Debug.Assert(newBindCount >= 0); + } } } -- cgit v1.2.3