diff options
author | riperiperi <rhy3756547@hotmail.com> | 2024-01-20 14:07:33 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-20 11:07:33 -0300 |
commit | 331c07807fd0db5d4452d6ef02962a6d19a56d7f (patch) | |
tree | a306b0b43f50c58abb649e45057008f60b5da656 /src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplate.cs | |
parent | a772b073ecb5c753acbddbf5861051d878f5153b (diff) |
Vulkan: Use templates for descriptor updates (#6014)1.1.1116
* WIP: Descriptor template update
* Make configurable
* Wording
* Simplify template creation
* Whitespace
* UTF-8 whatever
* Leave only templated path, better template updater
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplate.cs')
-rw-r--r-- | src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplate.cs | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplate.cs b/src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplate.cs new file mode 100644 index 00000000..0c0004b9 --- /dev/null +++ b/src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplate.cs @@ -0,0 +1,145 @@ +using Ryujinx.Graphics.GAL; +using Silk.NET.Vulkan; +using System; +using System.Runtime.CompilerServices; + +namespace Ryujinx.Graphics.Vulkan +{ + class DescriptorSetTemplate : IDisposable + { + private readonly VulkanRenderer _gd; + private readonly Device _device; + + public readonly DescriptorUpdateTemplate Template; + public readonly int Size; + + public unsafe DescriptorSetTemplate(VulkanRenderer gd, Device device, ResourceBindingSegment[] segments, PipelineLayoutCacheEntry plce, PipelineBindPoint pbp, int setIndex) + { + _gd = gd; + _device = device; + + // Create a template from the set usages. Assumes the descriptor set is updated in segment order then binding order. + + DescriptorUpdateTemplateEntry* entries = stackalloc DescriptorUpdateTemplateEntry[segments.Length]; + nuint structureOffset = 0; + + for (int seg = 0; seg < segments.Length; seg++) + { + ResourceBindingSegment segment = segments[seg]; + + int binding = segment.Binding; + int count = segment.Count; + + if (setIndex == PipelineBase.UniformSetIndex) + { + entries[seg] = new DescriptorUpdateTemplateEntry() + { + DescriptorType = DescriptorType.UniformBuffer, + DstBinding = (uint)binding, + DescriptorCount = (uint)count, + Offset = structureOffset, + Stride = (nuint)Unsafe.SizeOf<DescriptorBufferInfo>() + }; + + structureOffset += (nuint)(Unsafe.SizeOf<DescriptorBufferInfo>() * count); + } + else if (setIndex == PipelineBase.StorageSetIndex) + { + entries[seg] = new DescriptorUpdateTemplateEntry() + { + DescriptorType = DescriptorType.StorageBuffer, + DstBinding = (uint)binding, + DescriptorCount = (uint)count, + Offset = structureOffset, + Stride = (nuint)Unsafe.SizeOf<DescriptorBufferInfo>() + }; + + structureOffset += (nuint)(Unsafe.SizeOf<DescriptorBufferInfo>() * count); + } + else if (setIndex == PipelineBase.TextureSetIndex) + { + if (segment.Type != ResourceType.BufferTexture) + { + entries[seg] = new DescriptorUpdateTemplateEntry() + { + DescriptorType = DescriptorType.CombinedImageSampler, + DstBinding = (uint)binding, + DescriptorCount = (uint)count, + Offset = structureOffset, + Stride = (nuint)Unsafe.SizeOf<DescriptorImageInfo>() + }; + + structureOffset += (nuint)(Unsafe.SizeOf<DescriptorImageInfo>() * count); + } + else + { + entries[seg] = new DescriptorUpdateTemplateEntry() + { + DescriptorType = DescriptorType.UniformTexelBuffer, + DstBinding = (uint)binding, + DescriptorCount = (uint)count, + Offset = structureOffset, + Stride = (nuint)Unsafe.SizeOf<BufferView>() + }; + + structureOffset += (nuint)(Unsafe.SizeOf<BufferView>() * count); + } + } + else if (setIndex == PipelineBase.ImageSetIndex) + { + if (segment.Type != ResourceType.BufferImage) + { + entries[seg] = new DescriptorUpdateTemplateEntry() + { + DescriptorType = DescriptorType.StorageImage, + DstBinding = (uint)binding, + DescriptorCount = (uint)count, + Offset = structureOffset, + Stride = (nuint)Unsafe.SizeOf<DescriptorImageInfo>() + }; + + structureOffset += (nuint)(Unsafe.SizeOf<DescriptorImageInfo>() * count); + } + else + { + entries[seg] = new DescriptorUpdateTemplateEntry() + { + DescriptorType = DescriptorType.StorageTexelBuffer, + DstBinding = (uint)binding, + DescriptorCount = (uint)count, + Offset = structureOffset, + Stride = (nuint)Unsafe.SizeOf<BufferView>() + }; + + structureOffset += (nuint)(Unsafe.SizeOf<BufferView>() * count); + } + } + } + + Size = (int)structureOffset; + + var info = new DescriptorUpdateTemplateCreateInfo() + { + SType = StructureType.DescriptorUpdateTemplateCreateInfo, + DescriptorUpdateEntryCount = (uint)segments.Length, + PDescriptorUpdateEntries = entries, + + TemplateType = DescriptorUpdateTemplateType.DescriptorSet, + DescriptorSetLayout = plce.DescriptorSetLayouts[setIndex], + PipelineBindPoint = pbp, + PipelineLayout = plce.PipelineLayout, + Set = (uint)setIndex, + }; + + DescriptorUpdateTemplate result; + gd.Api.CreateDescriptorUpdateTemplate(device, &info, null, &result).ThrowOnError(); + + Template = result; + } + + public unsafe void Dispose() + { + _gd.Api.DestroyDescriptorUpdateTemplate(_device, Template, null); + } + } +} |