/ src / Ryujinx.Graphics.Vulkan / DescriptorSetCollection.cs
DescriptorSetCollection.cs
  1  using Silk.NET.Vulkan;
  2  using System;
  3  using VkBuffer = Silk.NET.Vulkan.Buffer;
  4  
  5  namespace Ryujinx.Graphics.Vulkan
  6  {
  7      struct DescriptorSetCollection : IDisposable
  8      {
  9          private DescriptorSetManager.DescriptorPoolHolder _holder;
 10          private readonly DescriptorSet[] _descriptorSets;
 11          public readonly int SetsCount => _descriptorSets.Length;
 12  
 13          public DescriptorSetCollection(DescriptorSetManager.DescriptorPoolHolder holder, DescriptorSet[] descriptorSets)
 14          {
 15              _holder = holder;
 16              _descriptorSets = descriptorSets;
 17          }
 18  
 19          public void InitializeBuffers(int setIndex, int baseBinding, int count, DescriptorType type, VkBuffer dummyBuffer)
 20          {
 21              Span<DescriptorBufferInfo> infos = stackalloc DescriptorBufferInfo[count];
 22  
 23              infos.Fill(new DescriptorBufferInfo
 24              {
 25                  Buffer = dummyBuffer,
 26                  Range = Vk.WholeSize,
 27              });
 28  
 29              UpdateBuffers(setIndex, baseBinding, infos, type);
 30          }
 31  
 32          public unsafe void UpdateBuffer(int setIndex, int bindingIndex, DescriptorBufferInfo bufferInfo, DescriptorType type)
 33          {
 34              if (bufferInfo.Buffer.Handle != 0UL)
 35              {
 36                  var writeDescriptorSet = new WriteDescriptorSet
 37                  {
 38                      SType = StructureType.WriteDescriptorSet,
 39                      DstSet = _descriptorSets[setIndex],
 40                      DstBinding = (uint)bindingIndex,
 41                      DescriptorType = type,
 42                      DescriptorCount = 1,
 43                      PBufferInfo = &bufferInfo,
 44                  };
 45  
 46                  _holder.Api.UpdateDescriptorSets(_holder.Device, 1, in writeDescriptorSet, 0, null);
 47              }
 48          }
 49  
 50          public unsafe void UpdateBuffers(int setIndex, int baseBinding, ReadOnlySpan<DescriptorBufferInfo> bufferInfo, DescriptorType type)
 51          {
 52              if (bufferInfo.Length == 0)
 53              {
 54                  return;
 55              }
 56  
 57              fixed (DescriptorBufferInfo* pBufferInfo = bufferInfo)
 58              {
 59                  var writeDescriptorSet = new WriteDescriptorSet
 60                  {
 61                      SType = StructureType.WriteDescriptorSet,
 62                      DstSet = _descriptorSets[setIndex],
 63                      DstBinding = (uint)baseBinding,
 64                      DescriptorType = type,
 65                      DescriptorCount = (uint)bufferInfo.Length,
 66                      PBufferInfo = pBufferInfo,
 67                  };
 68  
 69                  _holder.Api.UpdateDescriptorSets(_holder.Device, 1, in writeDescriptorSet, 0, null);
 70              }
 71          }
 72  
 73          public unsafe void UpdateImage(int setIndex, int bindingIndex, DescriptorImageInfo imageInfo, DescriptorType type)
 74          {
 75              if (imageInfo.ImageView.Handle != 0UL)
 76              {
 77                  var writeDescriptorSet = new WriteDescriptorSet
 78                  {
 79                      SType = StructureType.WriteDescriptorSet,
 80                      DstSet = _descriptorSets[setIndex],
 81                      DstBinding = (uint)bindingIndex,
 82                      DescriptorType = type,
 83                      DescriptorCount = 1,
 84                      PImageInfo = &imageInfo,
 85                  };
 86  
 87                  _holder.Api.UpdateDescriptorSets(_holder.Device, 1, in writeDescriptorSet, 0, null);
 88              }
 89          }
 90  
 91          public unsafe void UpdateImages(int setIndex, int baseBinding, ReadOnlySpan<DescriptorImageInfo> imageInfo, DescriptorType type)
 92          {
 93              if (imageInfo.Length == 0)
 94              {
 95                  return;
 96              }
 97  
 98              fixed (DescriptorImageInfo* pImageInfo = imageInfo)
 99              {
100                  var writeDescriptorSet = new WriteDescriptorSet
101                  {
102                      SType = StructureType.WriteDescriptorSet,
103                      DstSet = _descriptorSets[setIndex],
104                      DstBinding = (uint)baseBinding,
105                      DescriptorType = type,
106                      DescriptorCount = (uint)imageInfo.Length,
107                      PImageInfo = pImageInfo,
108                  };
109  
110                  _holder.Api.UpdateDescriptorSets(_holder.Device, 1, in writeDescriptorSet, 0, null);
111              }
112          }
113  
114          public unsafe void UpdateImagesCombined(int setIndex, int baseBinding, ReadOnlySpan<DescriptorImageInfo> imageInfo, DescriptorType type)
115          {
116              if (imageInfo.Length == 0)
117              {
118                  return;
119              }
120  
121              fixed (DescriptorImageInfo* pImageInfo = imageInfo)
122              {
123                  for (int i = 0; i < imageInfo.Length; i++)
124                  {
125                      bool nonNull = imageInfo[i].ImageView.Handle != 0 && imageInfo[i].Sampler.Handle != 0;
126                      if (nonNull)
127                      {
128                          int count = 1;
129  
130                          while (i + count < imageInfo.Length &&
131                              imageInfo[i + count].ImageView.Handle != 0 &&
132                              imageInfo[i + count].Sampler.Handle != 0)
133                          {
134                              count++;
135                          }
136  
137                          var writeDescriptorSet = new WriteDescriptorSet
138                          {
139                              SType = StructureType.WriteDescriptorSet,
140                              DstSet = _descriptorSets[setIndex],
141                              DstBinding = (uint)(baseBinding + i),
142                              DescriptorType = DescriptorType.CombinedImageSampler,
143                              DescriptorCount = (uint)count,
144                              PImageInfo = pImageInfo,
145                          };
146  
147                          _holder.Api.UpdateDescriptorSets(_holder.Device, 1, in writeDescriptorSet, 0, null);
148  
149                          i += count - 1;
150                      }
151                  }
152              }
153          }
154  
155          public unsafe void UpdateBufferImage(int setIndex, int bindingIndex, BufferView texelBufferView, DescriptorType type)
156          {
157              if (texelBufferView.Handle != 0UL)
158              {
159                  var writeDescriptorSet = new WriteDescriptorSet
160                  {
161                      SType = StructureType.WriteDescriptorSet,
162                      DstSet = _descriptorSets[setIndex],
163                      DstBinding = (uint)bindingIndex,
164                      DescriptorType = type,
165                      DescriptorCount = 1,
166                      PTexelBufferView = &texelBufferView,
167                  };
168  
169                  _holder.Api.UpdateDescriptorSets(_holder.Device, 1, in writeDescriptorSet, 0, null);
170              }
171          }
172  
173          public unsafe void UpdateBufferImages(int setIndex, int baseBinding, ReadOnlySpan<BufferView> texelBufferView, DescriptorType type)
174          {
175              if (texelBufferView.Length == 0)
176              {
177                  return;
178              }
179  
180              fixed (BufferView* pTexelBufferView = texelBufferView)
181              {
182                  for (uint i = 0; i < texelBufferView.Length;)
183                  {
184                      uint count = 1;
185  
186                      if (texelBufferView[(int)i].Handle != 0UL)
187                      {
188                          while (i + count < texelBufferView.Length && texelBufferView[(int)(i + count)].Handle != 0UL)
189                          {
190                              count++;
191                          }
192  
193                          var writeDescriptorSet = new WriteDescriptorSet
194                          {
195                              SType = StructureType.WriteDescriptorSet,
196                              DstSet = _descriptorSets[setIndex],
197                              DstBinding = (uint)baseBinding + i,
198                              DescriptorType = type,
199                              DescriptorCount = count,
200                              PTexelBufferView = pTexelBufferView + i,
201                          };
202  
203                          _holder.Api.UpdateDescriptorSets(_holder.Device, 1, in writeDescriptorSet, 0, null);
204                      }
205  
206                      i += count;
207                  }
208              }
209          }
210  
211          public readonly DescriptorSet[] GetSets()
212          {
213              return _descriptorSets;
214          }
215  
216          public void Dispose()
217          {
218              _holder?.FreeDescriptorSets(this);
219              _holder = null;
220          }
221      }
222  }