DescriptorSetCollection.cs 8.1 KB

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