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 _data; public DescriptorSetTemplateWriter(Span data) { _data = data; } public void Push(ReadOnlySpan values) where T : unmanaged { Span target = MemoryMarshal.Cast(_data); values.CopyTo(target); _data = _data[(Unsafe.SizeOf() * values.Length)..]; } } unsafe class DescriptorSetTemplateUpdater : IDisposable { private const int SizeGranularity = 512; private DescriptorSetTemplate _activeTemplate; private NativeArray _data; private void EnsureSize(int size) { if (_data == null || _data.Length < size) { _data?.Dispose(); int dataSize = BitUtils.AlignUp(size, SizeGranularity); _data = new NativeArray(dataSize); } } public DescriptorSetTemplateWriter Begin(DescriptorSetTemplate template) { _activeTemplate = template; EnsureSize(template.Size); return new DescriptorSetTemplateWriter(new Span(_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(); } } }