diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2024-06-02 22:40:28 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-02 22:40:28 -0300 |
| commit | c0f2491eaee7eb1088605f5bda8055b941a14f99 (patch) | |
| tree | 4f52becd1f06d3f2dc2209be8e802f505b1d1eca /src/Ryujinx.Graphics.Vulkan/PipelineLayoutFactory.cs | |
| parent | d7c6474729ee36875cf387629afe1389655311f8 (diff) | |
Vulkan separate descriptor set fixes (#6895)
* Ensure descriptor sets are only re-used when all command buffers using it have completed
* Fix some SPIR-V capabilities
* Set update after bind flag if we exceed limits
* Simpler fix for Intel
* Format whitespace
* Make struct readonly
* Add barriers for extra set arrays too
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan/PipelineLayoutFactory.cs')
| -rw-r--r-- | src/Ryujinx.Graphics.Vulkan/PipelineLayoutFactory.cs | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineLayoutFactory.cs b/src/Ryujinx.Graphics.Vulkan/PipelineLayoutFactory.cs index 8bf286c6..bca119f6 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineLayoutFactory.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineLayoutFactory.cs @@ -1,18 +1,23 @@ +using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; +using System; using System.Collections.ObjectModel; namespace Ryujinx.Graphics.Vulkan { + record struct ResourceLayouts(DescriptorSetLayout[] DescriptorSetLayouts, bool[] DescriptorSetLayoutsUpdateAfterBind, PipelineLayout PipelineLayout); + static class PipelineLayoutFactory { - public static unsafe (DescriptorSetLayout[], PipelineLayout) Create( + public static unsafe ResourceLayouts Create( VulkanRenderer gd, Device device, ReadOnlyCollection<ResourceDescriptorCollection> setDescriptors, bool usePushDescriptors) { DescriptorSetLayout[] layouts = new DescriptorSetLayout[setDescriptors.Count]; + bool[] updateAfterBindFlags = new bool[setDescriptors.Count]; bool isMoltenVk = gd.IsMoltenVk; @@ -32,10 +37,11 @@ namespace Ryujinx.Graphics.Vulkan DescriptorSetLayoutBinding[] layoutBindings = new DescriptorSetLayoutBinding[rdc.Descriptors.Count]; + bool hasArray = false; + for (int descIndex = 0; descIndex < rdc.Descriptors.Count; descIndex++) { ResourceDescriptor descriptor = rdc.Descriptors[descIndex]; - ResourceStages stages = descriptor.Stages; if (descriptor.Type == ResourceType.StorageBuffer && isMoltenVk) @@ -52,16 +58,37 @@ namespace Ryujinx.Graphics.Vulkan DescriptorCount = (uint)descriptor.Count, StageFlags = stages.Convert(), }; + + if (descriptor.Count > 1) + { + hasArray = true; + } } fixed (DescriptorSetLayoutBinding* pLayoutBindings = layoutBindings) { + DescriptorSetLayoutCreateFlags flags = DescriptorSetLayoutCreateFlags.None; + + if (usePushDescriptors && setIndex == 0) + { + flags = DescriptorSetLayoutCreateFlags.PushDescriptorBitKhr; + } + + if (gd.Vendor == Vendor.Intel && hasArray) + { + // Some vendors (like Intel) have low per-stage limits. + // We must set the flag if we exceed those limits. + flags |= DescriptorSetLayoutCreateFlags.UpdateAfterBindPoolBit; + + updateAfterBindFlags[setIndex] = true; + } + var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo { SType = StructureType.DescriptorSetLayoutCreateInfo, PBindings = pLayoutBindings, BindingCount = (uint)layoutBindings.Length, - Flags = usePushDescriptors && setIndex == 0 ? DescriptorSetLayoutCreateFlags.PushDescriptorBitKhr : DescriptorSetLayoutCreateFlags.None, + Flags = flags, }; gd.Api.CreateDescriptorSetLayout(device, descriptorSetLayoutCreateInfo, null, out layouts[setIndex]).ThrowOnError(); @@ -82,7 +109,7 @@ namespace Ryujinx.Graphics.Vulkan gd.Api.CreatePipelineLayout(device, &pipelineLayoutCreateInfo, null, out layout).ThrowOnError(); } - return (layouts, layout); + return new ResourceLayouts(layouts, updateAfterBindFlags, layout); } } } |
