diff options
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); + } + } +} |