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 }