diff options
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplateUpdater.cs')
-rw-r--r-- | src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplateUpdater.cs | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplateUpdater.cs b/src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplateUpdater.cs new file mode 100644 index 00000000..1eb9dce7 --- /dev/null +++ b/src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplateUpdater.cs @@ -0,0 +1,65 @@ +using Ryujinx.Common; +using Silk.NET.Vulkan; +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Ryujinx.Graphics.Vulkan +{ + ref struct DescriptorSetTemplateWriter + { + private Span<byte> _data; + + public DescriptorSetTemplateWriter(Span<byte> data) + { + _data = data; + } + + public void Push<T>(ReadOnlySpan<T> values) where T : unmanaged + { + Span<T> target = MemoryMarshal.Cast<byte, T>(_data); + + values.CopyTo(target); + + _data = _data[(Unsafe.SizeOf<T>() * values.Length)..]; + } + } + + unsafe class DescriptorSetTemplateUpdater : IDisposable + { + private const int SizeGranularity = 512; + + private DescriptorSetTemplate _activeTemplate; + private NativeArray<byte> _data; + + private void EnsureSize(int size) + { + if (_data == null || _data.Length < size) + { + _data?.Dispose(); + + int dataSize = BitUtils.AlignUp(size, SizeGranularity); + _data = new NativeArray<byte>(dataSize); + } + } + + public DescriptorSetTemplateWriter Begin(DescriptorSetTemplate template) + { + _activeTemplate = template; + + EnsureSize(template.Size); + + return new DescriptorSetTemplateWriter(new Span<byte>(_data.Pointer, template.Size)); + } + + public void Commit(VulkanRenderer gd, Device device, DescriptorSet set) + { + gd.Api.UpdateDescriptorSetWithTemplate(device, set, _activeTemplate.Template, _data.Pointer); + } + + public void Dispose() + { + _data?.Dispose(); + } + } +} |