/ src / Ryujinx.Graphics.Vulkan / VertexBufferUpdater.cs
VertexBufferUpdater.cs
 1  using System;
 2  using VkBuffer = Silk.NET.Vulkan.Buffer;
 3  
 4  namespace Ryujinx.Graphics.Vulkan
 5  {
 6      internal class VertexBufferUpdater : IDisposable
 7      {
 8          private readonly VulkanRenderer _gd;
 9  
10          private uint _baseBinding;
11          private uint _count;
12  
13          private readonly NativeArray<VkBuffer> _buffers;
14          private readonly NativeArray<ulong> _offsets;
15          private readonly NativeArray<ulong> _sizes;
16          private readonly NativeArray<ulong> _strides;
17  
18          public VertexBufferUpdater(VulkanRenderer gd)
19          {
20              _gd = gd;
21  
22              _buffers = new NativeArray<VkBuffer>(Constants.MaxVertexBuffers);
23              _offsets = new NativeArray<ulong>(Constants.MaxVertexBuffers);
24              _sizes = new NativeArray<ulong>(Constants.MaxVertexBuffers);
25              _strides = new NativeArray<ulong>(Constants.MaxVertexBuffers);
26          }
27  
28          public void BindVertexBuffer(CommandBufferScoped cbs, uint binding, VkBuffer buffer, ulong offset, ulong size, ulong stride)
29          {
30              if (_count == 0)
31              {
32                  _baseBinding = binding;
33              }
34              else if (_baseBinding + _count != binding)
35              {
36                  Commit(cbs);
37                  _baseBinding = binding;
38              }
39  
40              int index = (int)_count;
41  
42              _buffers[index] = buffer;
43              _offsets[index] = offset;
44              _sizes[index] = size;
45              _strides[index] = stride;
46  
47              _count++;
48          }
49  
50          public unsafe void Commit(CommandBufferScoped cbs)
51          {
52              if (_count != 0)
53              {
54                  if (_gd.Capabilities.SupportsExtendedDynamicState)
55                  {
56                      _gd.ExtendedDynamicStateApi.CmdBindVertexBuffers2(
57                          cbs.CommandBuffer,
58                          _baseBinding,
59                          _count,
60                          _buffers.Pointer,
61                          _offsets.Pointer,
62                          _sizes.Pointer,
63                          _strides.Pointer);
64                  }
65                  else
66                  {
67                      _gd.Api.CmdBindVertexBuffers(cbs.CommandBuffer, _baseBinding, _count, _buffers.Pointer, _offsets.Pointer);
68                  }
69  
70                  _count = 0;
71              }
72          }
73  
74          public void Dispose()
75          {
76              _buffers.Dispose();
77              _offsets.Dispose();
78              _sizes.Dispose();
79              _strides.Dispose();
80          }
81      }
82  }