aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplate.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplate.cs')
-rw-r--r--src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplate.cs145
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);
+ }
+ }
+}