1 // Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "VkDescriptorSetLayout.hpp"
16
17 #include "VkBuffer.hpp"
18 #include "VkBufferView.hpp"
19 #include "VkDescriptorSet.hpp"
20 #include "VkImageView.hpp"
21 #include "VkSampler.hpp"
22
23 #include "Reactor/Reactor.hpp"
24
25 #include <algorithm>
26 #include <cstddef>
27 #include <cstring>
28
29 namespace vk {
30
UsesImmutableSamplers(const VkDescriptorSetLayoutBinding & binding)31 static bool UsesImmutableSamplers(const VkDescriptorSetLayoutBinding &binding)
32 {
33 return (((binding.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
34 (binding.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)) &&
35 (binding.pImmutableSamplers != nullptr));
36 }
37
DescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo * pCreateInfo,void * mem)38 DescriptorSetLayout::DescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo *pCreateInfo, void *mem)
39 : flags(pCreateInfo->flags)
40 , bindings(reinterpret_cast<Binding *>(mem))
41 {
42 // The highest binding number determines the size of the direct-indexed array.
43 bindingsArraySize = 0;
44 for(uint32_t i = 0; i < pCreateInfo->bindingCount; i++)
45 {
46 bindingsArraySize = std::max(bindingsArraySize, pCreateInfo->pBindings[i].binding + 1);
47 }
48
49 uint8_t *immutableSamplersStorage = static_cast<uint8_t *>(mem) + bindingsArraySize * sizeof(Binding);
50
51 // pCreateInfo->pBindings[] can have gaps in the binding numbers, so first initialize the entire bindings array.
52 // "Bindings that are not specified have a descriptorCount and stageFlags of zero, and the value of descriptorType is undefined."
53 for(uint32_t i = 0; i < bindingsArraySize; i++)
54 {
55 bindings[i].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
56 bindings[i].descriptorCount = 0;
57 bindings[i].immutableSamplers = nullptr;
58 }
59
60 for(uint32_t i = 0; i < pCreateInfo->bindingCount; i++)
61 {
62 const VkDescriptorSetLayoutBinding &srcBinding = pCreateInfo->pBindings[i];
63 vk::DescriptorSetLayout::Binding &dstBinding = bindings[srcBinding.binding];
64
65 dstBinding.descriptorType = srcBinding.descriptorType;
66 dstBinding.descriptorCount = srcBinding.descriptorCount;
67
68 if(UsesImmutableSamplers(srcBinding))
69 {
70 size_t immutableSamplersSize = dstBinding.descriptorCount * sizeof(VkSampler);
71 dstBinding.immutableSamplers = reinterpret_cast<const vk::Sampler **>(immutableSamplersStorage);
72 immutableSamplersStorage += immutableSamplersSize;
73
74 for(uint32_t i = 0; i < dstBinding.descriptorCount; i++)
75 {
76 dstBinding.immutableSamplers[i] = vk::Cast(srcBinding.pImmutableSamplers[i]);
77 }
78 }
79 }
80
81 uint32_t offset = 0;
82 for(uint32_t i = 0; i < bindingsArraySize; i++)
83 {
84 bindings[i].offset = offset;
85 offset += bindings[i].descriptorCount * GetDescriptorSize(bindings[i].descriptorType);
86 }
87
88 ASSERT_MSG(offset == getDescriptorSetDataSize(0), "offset: %d, size: %d", int(offset), int(getDescriptorSetDataSize(0)));
89 }
90
destroy(const VkAllocationCallbacks * pAllocator)91 void DescriptorSetLayout::destroy(const VkAllocationCallbacks *pAllocator)
92 {
93 vk::freeHostMemory(bindings, pAllocator); // This allocation also contains pImmutableSamplers
94 }
95
ComputeRequiredAllocationSize(const VkDescriptorSetLayoutCreateInfo * pCreateInfo)96 size_t DescriptorSetLayout::ComputeRequiredAllocationSize(const VkDescriptorSetLayoutCreateInfo *pCreateInfo)
97 {
98 uint32_t bindingsArraySize = 0;
99 uint32_t immutableSamplerCount = 0;
100 for(uint32_t i = 0; i < pCreateInfo->bindingCount; i++)
101 {
102 bindingsArraySize = std::max(bindingsArraySize, pCreateInfo->pBindings[i].binding + 1);
103
104 if(UsesImmutableSamplers(pCreateInfo->pBindings[i]))
105 {
106 immutableSamplerCount += pCreateInfo->pBindings[i].descriptorCount;
107 }
108 }
109
110 return bindingsArraySize * sizeof(Binding) +
111 immutableSamplerCount * sizeof(VkSampler);
112 }
113
GetDescriptorSize(VkDescriptorType type)114 uint32_t DescriptorSetLayout::GetDescriptorSize(VkDescriptorType type)
115 {
116 switch(type)
117 {
118 case VK_DESCRIPTOR_TYPE_SAMPLER:
119 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
120 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
121 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
122 return static_cast<uint32_t>(sizeof(SampledImageDescriptor));
123 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
124 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
125 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
126 return static_cast<uint32_t>(sizeof(StorageImageDescriptor));
127 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
128 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
129 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
130 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
131 return static_cast<uint32_t>(sizeof(BufferDescriptor));
132 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK:
133 return 1;
134 default:
135 UNSUPPORTED("Unsupported Descriptor Type: %d", int(type));
136 return 0;
137 }
138 }
139
IsDescriptorDynamic(VkDescriptorType type)140 bool DescriptorSetLayout::IsDescriptorDynamic(VkDescriptorType type)
141 {
142 return type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
143 type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
144 }
145
getDescriptorSetAllocationSize(uint32_t variableDescriptorCount) const146 size_t DescriptorSetLayout::getDescriptorSetAllocationSize(uint32_t variableDescriptorCount) const
147 {
148 // vk::DescriptorSet has a header with a pointer to the layout.
149 return sw::align<alignof(DescriptorSet)>(sizeof(DescriptorSetHeader) + getDescriptorSetDataSize(variableDescriptorCount));
150 }
151
getDescriptorSetDataSize(uint32_t variableDescriptorCount) const152 size_t DescriptorSetLayout::getDescriptorSetDataSize(uint32_t variableDescriptorCount) const
153 {
154 size_t size = 0;
155 for(uint32_t i = 0; i < bindingsArraySize; i++)
156 {
157 uint32_t descriptorCount = bindings[i].descriptorCount;
158
159 if((i == (bindingsArraySize - 1)) && (variableDescriptorCount > 0))
160 {
161 descriptorCount = variableDescriptorCount;
162 }
163
164 size += descriptorCount * GetDescriptorSize(bindings[i].descriptorType);
165 }
166
167 return size;
168 }
169
initialize(DescriptorSet * descriptorSet,uint32_t variableDescriptorCount)170 void DescriptorSetLayout::initialize(DescriptorSet *descriptorSet, uint32_t variableDescriptorCount)
171 {
172 ASSERT(descriptorSet->header.layout == nullptr);
173
174 // Set a pointer to this descriptor set layout in the descriptor set's header.
175 descriptorSet->header.layout = this;
176 uint8_t *data = descriptorSet->getDataAddress(); // Descriptor payload
177
178 for(uint32_t i = 0; i < bindingsArraySize; i++)
179 {
180 size_t descriptorSize = GetDescriptorSize(bindings[i].descriptorType);
181
182 uint32_t descriptorCount = bindings[i].descriptorCount;
183
184 if((i == (bindingsArraySize - 1)) && (variableDescriptorCount > 0))
185 {
186 descriptorCount = variableDescriptorCount;
187 }
188
189 if(bindings[i].immutableSamplers)
190 {
191 for(uint32_t j = 0; j < descriptorCount; j++)
192 {
193 SampledImageDescriptor *imageSamplerDescriptor = reinterpret_cast<SampledImageDescriptor *>(data);
194 imageSamplerDescriptor->samplerId = bindings[i].immutableSamplers[j]->id;
195 imageSamplerDescriptor->memoryOwner = nullptr;
196 data += descriptorSize;
197 }
198 }
199 else
200 {
201 switch(bindings[i].descriptorType)
202 {
203 case VK_DESCRIPTOR_TYPE_SAMPLER:
204 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
205 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
206 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
207 for(uint32_t j = 0; j < descriptorCount; j++)
208 {
209 SampledImageDescriptor *imageSamplerDescriptor = reinterpret_cast<SampledImageDescriptor *>(data);
210 imageSamplerDescriptor->memoryOwner = nullptr;
211 data += descriptorSize;
212 }
213 break;
214 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
215 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
216 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
217 for(uint32_t j = 0; j < descriptorCount; j++)
218 {
219 StorageImageDescriptor *storageImage = reinterpret_cast<StorageImageDescriptor *>(data);
220 storageImage->memoryOwner = nullptr;
221 data += descriptorSize;
222 }
223 break;
224 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
225 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
226 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
227 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
228 data += descriptorCount * descriptorSize;
229 break;
230 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK:
231 data += descriptorCount;
232 break;
233 default:
234 UNSUPPORTED("Unsupported Descriptor Type: %d", int(bindings[i].descriptorType));
235 }
236 }
237 }
238 }
239
getBindingOffset(uint32_t bindingNumber) const240 uint32_t DescriptorSetLayout::getBindingOffset(uint32_t bindingNumber) const
241 {
242 ASSERT(bindingNumber < bindingsArraySize);
243 return bindings[bindingNumber].offset;
244 }
245
getDescriptorCount(uint32_t bindingNumber) const246 uint32_t DescriptorSetLayout::getDescriptorCount(uint32_t bindingNumber) const
247 {
248 ASSERT(bindingNumber < bindingsArraySize);
249 return bindings[bindingNumber].descriptorCount;
250 }
251
getDynamicDescriptorCount() const252 uint32_t DescriptorSetLayout::getDynamicDescriptorCount() const
253 {
254 uint32_t count = 0;
255 for(size_t i = 0; i < bindingsArraySize; i++)
256 {
257 if(IsDescriptorDynamic(bindings[i].descriptorType))
258 {
259 count += bindings[i].descriptorCount;
260 }
261 }
262
263 return count;
264 }
265
getDynamicOffsetIndex(uint32_t bindingNumber) const266 uint32_t DescriptorSetLayout::getDynamicOffsetIndex(uint32_t bindingNumber) const
267 {
268 ASSERT(bindingNumber < bindingsArraySize);
269 ASSERT(IsDescriptorDynamic(bindings[bindingNumber].descriptorType));
270
271 uint32_t index = 0;
272 for(uint32_t i = 0; i < bindingNumber; i++)
273 {
274 if(IsDescriptorDynamic(bindings[i].descriptorType))
275 {
276 index += bindings[i].descriptorCount;
277 }
278 }
279
280 return index;
281 }
282
getDescriptorType(uint32_t bindingNumber) const283 VkDescriptorType DescriptorSetLayout::getDescriptorType(uint32_t bindingNumber) const
284 {
285 ASSERT(bindingNumber < bindingsArraySize);
286 return bindings[bindingNumber].descriptorType;
287 }
288
getDescriptorPointer(DescriptorSet * descriptorSet,uint32_t bindingNumber,uint32_t arrayElement,uint32_t count,size_t * typeSize) const289 uint8_t *DescriptorSetLayout::getDescriptorPointer(DescriptorSet *descriptorSet, uint32_t bindingNumber, uint32_t arrayElement, uint32_t count, size_t *typeSize) const
290 {
291 ASSERT(bindingNumber < bindingsArraySize);
292 *typeSize = GetDescriptorSize(bindings[bindingNumber].descriptorType);
293 size_t byteOffset = bindings[bindingNumber].offset + (*typeSize * arrayElement);
294 ASSERT(((*typeSize * count) + byteOffset) <= getDescriptorSetDataSize(0)); // Make sure the operation will not go out of bounds
295
296 return descriptorSet->getDataAddress() + byteOffset;
297 }
298
WriteTextureLevelInfo(sw::Texture * texture,uint32_t level,uint32_t width,uint32_t height,uint32_t depth,uint32_t pitchP,uint32_t sliceP,uint32_t samplePitchP,uint32_t sampleMax)299 static void WriteTextureLevelInfo(sw::Texture *texture, uint32_t level, uint32_t width, uint32_t height, uint32_t depth, uint32_t pitchP, uint32_t sliceP, uint32_t samplePitchP, uint32_t sampleMax)
300 {
301 if(level == 0)
302 {
303 texture->widthWidthHeightHeight[0] = static_cast<float>(width);
304 texture->widthWidthHeightHeight[1] = static_cast<float>(width);
305 texture->widthWidthHeightHeight[2] = static_cast<float>(height);
306 texture->widthWidthHeightHeight[3] = static_cast<float>(height);
307
308 texture->width = sw::float4(static_cast<float>(width));
309 texture->height = sw::float4(static_cast<float>(height));
310 texture->depth = sw::float4(static_cast<float>(depth));
311 }
312
313 sw::Mipmap &mipmap = texture->mipmap[level];
314
315 uint16_t halfTexelU = 0x8000 / width;
316 uint16_t halfTexelV = 0x8000 / height;
317 uint16_t halfTexelW = 0x8000 / depth;
318
319 mipmap.uHalf = sw::ushort4(halfTexelU);
320 mipmap.vHalf = sw::ushort4(halfTexelV);
321 mipmap.wHalf = sw::ushort4(halfTexelW);
322
323 mipmap.width = sw::uint4(width);
324 mipmap.height = sw::uint4(height);
325 mipmap.depth = sw::uint4(depth);
326
327 mipmap.onePitchP[0] = 1;
328 mipmap.onePitchP[1] = sw::assert_cast<short>(pitchP);
329 mipmap.onePitchP[2] = 1;
330 mipmap.onePitchP[3] = sw::assert_cast<short>(pitchP);
331
332 mipmap.pitchP = sw::uint4(pitchP);
333 mipmap.sliceP = sw::uint4(sliceP);
334 mipmap.samplePitchP = sw::uint4(samplePitchP);
335 mipmap.sampleMax = sw::uint4(sampleMax);
336 }
337
WriteDescriptorSet(Device * device,DescriptorSet * dstSet,const VkDescriptorUpdateTemplateEntry & entry,const char * src)338 void DescriptorSetLayout::WriteDescriptorSet(Device *device, DescriptorSet *dstSet, const VkDescriptorUpdateTemplateEntry &entry, const char *src)
339 {
340 DescriptorSetLayout *dstLayout = dstSet->header.layout;
341 const DescriptorSetLayout::Binding &binding = dstLayout->bindings[entry.dstBinding];
342 ASSERT(dstLayout);
343 ASSERT(binding.descriptorType == entry.descriptorType);
344
345 size_t typeSize = 0;
346 uint8_t *memToWrite = dstLayout->getDescriptorPointer(dstSet, entry.dstBinding, entry.dstArrayElement, entry.descriptorCount, &typeSize);
347
348 ASSERT(reinterpret_cast<intptr_t>(memToWrite) % 16 == 0); // Each descriptor must be 16-byte aligned.
349
350 if(entry.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
351 {
352 SampledImageDescriptor *sampledImage = reinterpret_cast<SampledImageDescriptor *>(memToWrite);
353
354 for(uint32_t i = 0; i < entry.descriptorCount; i++)
355 {
356 const VkDescriptorImageInfo *update = reinterpret_cast<const VkDescriptorImageInfo *>(src + entry.offset + entry.stride * i);
357
358 // "All consecutive bindings updated via a single VkWriteDescriptorSet structure, except those with a
359 // descriptorCount of zero, must all either use immutable samplers or must all not use immutable samplers."
360 if(!binding.immutableSamplers)
361 {
362 sampledImage[i].samplerId = vk::Cast(update->sampler)->id;
363 }
364 }
365 }
366 else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
367 {
368 SampledImageDescriptor *sampledImage = reinterpret_cast<SampledImageDescriptor *>(memToWrite);
369
370 for(uint32_t i = 0; i < entry.descriptorCount; i++)
371 {
372 const VkBufferView *update = reinterpret_cast<const VkBufferView *>(src + entry.offset + entry.stride * i);
373 const vk::BufferView *bufferView = vk::Cast(*update);
374
375 sampledImage[i].imageViewId = bufferView->id;
376
377 uint32_t numElements = bufferView->getElementCount();
378 sampledImage[i].width = numElements;
379 sampledImage[i].height = 1;
380 sampledImage[i].depth = 1;
381 sampledImage[i].mipLevels = 1;
382 sampledImage[i].sampleCount = 1;
383 sampledImage[i].texture.widthWidthHeightHeight = sw::float4(static_cast<float>(numElements), static_cast<float>(numElements), 1, 1);
384 sampledImage[i].texture.width = sw::float4(static_cast<float>(numElements));
385 sampledImage[i].texture.height = sw::float4(1);
386 sampledImage[i].texture.depth = sw::float4(1);
387
388 sw::Mipmap &mipmap = sampledImage[i].texture.mipmap[0];
389 mipmap.buffer = bufferView->getPointer();
390 mipmap.width[0] = mipmap.width[1] = mipmap.width[2] = mipmap.width[3] = numElements;
391 mipmap.height[0] = mipmap.height[1] = mipmap.height[2] = mipmap.height[3] = 1;
392 mipmap.depth[0] = mipmap.depth[1] = mipmap.depth[2] = mipmap.depth[3] = 1;
393 mipmap.pitchP.x = mipmap.pitchP.y = mipmap.pitchP.z = mipmap.pitchP.w = numElements;
394 mipmap.sliceP.x = mipmap.sliceP.y = mipmap.sliceP.z = mipmap.sliceP.w = 0;
395 mipmap.onePitchP[0] = mipmap.onePitchP[2] = 1;
396 mipmap.onePitchP[1] = mipmap.onePitchP[3] = 0;
397 }
398 }
399 else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
400 entry.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
401 {
402 SampledImageDescriptor *sampledImage = reinterpret_cast<SampledImageDescriptor *>(memToWrite);
403
404 for(uint32_t i = 0; i < entry.descriptorCount; i++)
405 {
406 const VkDescriptorImageInfo *update = reinterpret_cast<const VkDescriptorImageInfo *>(src + entry.offset + entry.stride * i);
407
408 vk::ImageView *imageView = vk::Cast(update->imageView);
409 Format format = imageView->getFormat(ImageView::SAMPLING);
410
411 sw::Texture *texture = &sampledImage[i].texture;
412
413 if(entry.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
414 {
415 // "All consecutive bindings updated via a single VkWriteDescriptorSet structure, except those with a
416 // descriptorCount of zero, must all either use immutable samplers or must all not use immutable samplers."
417 if(!binding.immutableSamplers)
418 {
419 sampledImage[i].samplerId = vk::Cast(update->sampler)->id;
420 }
421 }
422
423 const auto &extent = imageView->getMipLevelExtent(0);
424
425 sampledImage[i].imageViewId = imageView->id;
426 sampledImage[i].width = extent.width;
427 sampledImage[i].height = extent.height;
428 sampledImage[i].depth = imageView->getDepthOrLayerCount(0);
429 sampledImage[i].mipLevels = imageView->getSubresourceRange().levelCount;
430 sampledImage[i].sampleCount = imageView->getSampleCount();
431 sampledImage[i].memoryOwner = imageView;
432
433 auto &subresourceRange = imageView->getSubresourceRange();
434
435 if(format.isYcbcrFormat())
436 {
437 ASSERT(subresourceRange.levelCount == 1);
438
439 // YCbCr images can only have one level, so we can store parameters for the
440 // different planes in the descriptor's mipmap levels instead.
441
442 const int level = 0;
443 VkOffset3D offset = { 0, 0, 0 };
444 texture->mipmap[0].buffer = imageView->getOffsetPointer(offset, VK_IMAGE_ASPECT_PLANE_0_BIT, level, 0, ImageView::SAMPLING);
445 texture->mipmap[1].buffer = imageView->getOffsetPointer(offset, VK_IMAGE_ASPECT_PLANE_1_BIT, level, 0, ImageView::SAMPLING);
446 if(format.getAspects() & VK_IMAGE_ASPECT_PLANE_2_BIT)
447 {
448 texture->mipmap[2].buffer = imageView->getOffsetPointer(offset, VK_IMAGE_ASPECT_PLANE_2_BIT, level, 0, ImageView::SAMPLING);
449 }
450
451 VkExtent2D extent = imageView->getMipLevelExtent(0);
452
453 uint32_t width = extent.width;
454 uint32_t height = extent.height;
455 uint32_t pitchP0 = imageView->rowPitchBytes(VK_IMAGE_ASPECT_PLANE_0_BIT, level, ImageView::SAMPLING) /
456 imageView->getFormat(VK_IMAGE_ASPECT_PLANE_0_BIT).bytes();
457
458 // Write plane 0 parameters to mipmap level 0.
459 WriteTextureLevelInfo(texture, 0, width, height, 1, pitchP0, 0, 0, 0);
460
461 // Plane 2, if present, has equal parameters to plane 1, so we use mipmap level 1 for both.
462 uint32_t pitchP1 = imageView->rowPitchBytes(VK_IMAGE_ASPECT_PLANE_1_BIT, level, ImageView::SAMPLING) /
463 imageView->getFormat(VK_IMAGE_ASPECT_PLANE_1_BIT).bytes();
464
465 WriteTextureLevelInfo(texture, 1, width / 2, height / 2, 1, pitchP1, 0, 0, 0);
466 }
467 else
468 {
469 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
470 {
471 int level = sw::clamp(mipmapLevel, 0, (int)subresourceRange.levelCount - 1); // Level within the image view
472
473 VkImageAspectFlagBits aspect = static_cast<VkImageAspectFlagBits>(imageView->getSubresourceRange().aspectMask);
474 sw::Mipmap &mipmap = texture->mipmap[mipmapLevel];
475
476 if((imageView->getType() == VK_IMAGE_VIEW_TYPE_CUBE) ||
477 (imageView->getType() == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY))
478 {
479 // Obtain the pointer to the corner of the level including the border, for seamless sampling.
480 // This is taken into account in the sampling routine, which can't handle negative texel coordinates.
481 VkOffset3D offset = { -1, -1, 0 };
482 mipmap.buffer = imageView->getOffsetPointer(offset, aspect, level, 0, ImageView::SAMPLING);
483 }
484 else
485 {
486 VkOffset3D offset = { 0, 0, 0 };
487 mipmap.buffer = imageView->getOffsetPointer(offset, aspect, level, 0, ImageView::SAMPLING);
488 }
489
490 VkExtent2D extent = imageView->getMipLevelExtent(level);
491
492 uint32_t width = extent.width;
493 uint32_t height = extent.height;
494 uint32_t layerCount = imageView->getSubresourceRange().layerCount;
495 uint32_t depth = imageView->getDepthOrLayerCount(level);
496 uint32_t bytes = format.bytes();
497 uint32_t pitchP = imageView->rowPitchBytes(aspect, level, ImageView::SAMPLING) / bytes;
498 uint32_t sliceP = (layerCount > 1 ? imageView->layerPitchBytes(aspect, ImageView::SAMPLING) : imageView->slicePitchBytes(aspect, level, ImageView::SAMPLING)) / bytes;
499 uint32_t samplePitchP = imageView->getMipLevelSize(aspect, level, ImageView::SAMPLING) / bytes;
500 uint32_t sampleMax = imageView->getSampleCount() - 1;
501
502 WriteTextureLevelInfo(texture, mipmapLevel, width, height, depth, pitchP, sliceP, samplePitchP, sampleMax);
503 }
504 }
505 }
506 }
507 else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
508 entry.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
509 {
510 StorageImageDescriptor *storageImage = reinterpret_cast<StorageImageDescriptor *>(memToWrite);
511
512 for(uint32_t i = 0; i < entry.descriptorCount; i++)
513 {
514 const VkDescriptorImageInfo *update = reinterpret_cast<const VkDescriptorImageInfo *>(src + entry.offset + entry.stride * i);
515 vk::ImageView *imageView = vk::Cast(update->imageView);
516 const auto &extent = imageView->getMipLevelExtent(0);
517 uint32_t layerCount = imageView->getSubresourceRange().layerCount;
518
519 storageImage[i].imageViewId = imageView->id;
520 storageImage[i].ptr = imageView->getOffsetPointer({ 0, 0, 0 }, VK_IMAGE_ASPECT_COLOR_BIT, 0, 0);
521 storageImage[i].width = extent.width;
522 storageImage[i].height = extent.height;
523 storageImage[i].depth = imageView->getDepthOrLayerCount(0);
524 storageImage[i].rowPitchBytes = imageView->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
525 storageImage[i].samplePitchBytes = imageView->slicePitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
526 storageImage[i].slicePitchBytes = layerCount > 1
527 ? imageView->layerPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT)
528 : imageView->slicePitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
529 storageImage[i].sampleCount = imageView->getSampleCount();
530 storageImage[i].sizeInBytes = static_cast<int>(imageView->getSizeInBytes());
531 storageImage[i].memoryOwner = imageView;
532
533 if(imageView->getFormat().isStencil())
534 {
535 storageImage[i].stencilPtr = imageView->getOffsetPointer({ 0, 0, 0 }, VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0);
536 storageImage[i].stencilRowPitchBytes = imageView->rowPitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT, 0);
537 storageImage[i].stencilSamplePitchBytes = imageView->slicePitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT, 0);
538 storageImage[i].stencilSlicePitchBytes = (imageView->getSubresourceRange().layerCount > 1)
539 ? imageView->layerPitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT)
540 : imageView->slicePitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT, 0);
541 }
542 }
543 }
544 else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
545 {
546 StorageImageDescriptor *storageImage = reinterpret_cast<StorageImageDescriptor *>(memToWrite);
547
548 for(uint32_t i = 0; i < entry.descriptorCount; i++)
549 {
550 const VkBufferView *update = reinterpret_cast<const VkBufferView *>(src + entry.offset + entry.stride * i);
551 const vk::BufferView *bufferView = vk::Cast(*update);
552
553 storageImage[i].imageViewId = bufferView->id;
554 storageImage[i].ptr = bufferView->getPointer();
555 storageImage[i].width = bufferView->getElementCount();
556 storageImage[i].height = 1;
557 storageImage[i].depth = 1;
558 storageImage[i].rowPitchBytes = 0;
559 storageImage[i].slicePitchBytes = 0;
560 storageImage[i].samplePitchBytes = 0;
561 storageImage[i].sampleCount = 1;
562 storageImage[i].sizeInBytes = bufferView->getRangeInBytes();
563 }
564 }
565 else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
566 entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
567 entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
568 entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
569 {
570 BufferDescriptor *bufferDescriptor = reinterpret_cast<BufferDescriptor *>(memToWrite);
571
572 for(uint32_t i = 0; i < entry.descriptorCount; i++)
573 {
574 const VkDescriptorBufferInfo *update = reinterpret_cast<const VkDescriptorBufferInfo *>(src + entry.offset + entry.stride * i);
575 const vk::Buffer *buffer = vk::Cast(update->buffer);
576 bufferDescriptor[i].ptr = buffer->getOffsetPointer(update->offset);
577 bufferDescriptor[i].sizeInBytes = static_cast<int>((update->range == VK_WHOLE_SIZE) ? buffer->getSize() - update->offset : update->range);
578
579 // TODO(b/195684837): The spec states that "vertexBufferRangeSize is the byte size of the memory
580 // range bound to the vertex buffer binding", while the code below uses the full size of the buffer.
581 bufferDescriptor[i].robustnessSize = static_cast<int>(buffer->getSize() - update->offset);
582 }
583 }
584 else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK)
585 {
586 memcpy(memToWrite, src + entry.offset, entry.descriptorCount);
587 }
588 }
589
WriteDescriptorSet(Device * device,const VkWriteDescriptorSet & writeDescriptorSet)590 void DescriptorSetLayout::WriteDescriptorSet(Device *device, const VkWriteDescriptorSet &writeDescriptorSet)
591 {
592 DescriptorSet *dstSet = vk::Cast(writeDescriptorSet.dstSet);
593 VkDescriptorUpdateTemplateEntry e;
594 e.descriptorType = writeDescriptorSet.descriptorType;
595 e.dstBinding = writeDescriptorSet.dstBinding;
596 e.dstArrayElement = writeDescriptorSet.dstArrayElement;
597 e.descriptorCount = writeDescriptorSet.descriptorCount;
598 e.offset = 0;
599 const void *ptr = nullptr;
600
601 switch(writeDescriptorSet.descriptorType)
602 {
603 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
604 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
605 ptr = writeDescriptorSet.pTexelBufferView;
606 e.stride = sizeof(VkBufferView);
607 break;
608
609 case VK_DESCRIPTOR_TYPE_SAMPLER:
610 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
611 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
612 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
613 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
614 ptr = writeDescriptorSet.pImageInfo;
615 e.stride = sizeof(VkDescriptorImageInfo);
616 break;
617
618 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
619 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
620 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
621 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
622 ptr = writeDescriptorSet.pBufferInfo;
623 e.stride = sizeof(VkDescriptorBufferInfo);
624 break;
625
626 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK:
627 {
628 const auto *inlineBlock = GetExtendedStruct<VkWriteDescriptorSetInlineUniformBlock>(writeDescriptorSet.pNext, VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK);
629 ASSERT(inlineBlock);
630
631 // "The descriptorCount of VkDescriptorSetLayoutBinding thus provides the total
632 // number of bytes a particular binding with an inline uniform block descriptor
633 // type can hold, while the srcArrayElement, dstArrayElement, and descriptorCount
634 // members of VkWriteDescriptorSet, VkCopyDescriptorSet, and
635 // VkDescriptorUpdateTemplateEntry (where applicable) specify the byte offset and
636 // number of bytes to write/copy to the binding's backing store. Additionally,
637 // the stride member of VkDescriptorUpdateTemplateEntry is ignored for inline
638 // uniform blocks and a default value of one is used, meaning that the data to
639 // update inline uniform block bindings with must be contiguous in memory."
640 ptr = inlineBlock->pData;
641 e.stride = 1;
642 }
643 break;
644
645 default:
646 UNSUPPORTED("descriptor type %u", writeDescriptorSet.descriptorType);
647 }
648
649 WriteDescriptorSet(device, dstSet, e, reinterpret_cast<const char *>(ptr));
650 }
651
CopyDescriptorSet(const VkCopyDescriptorSet & descriptorCopies)652 void DescriptorSetLayout::CopyDescriptorSet(const VkCopyDescriptorSet &descriptorCopies)
653 {
654 DescriptorSet *srcSet = vk::Cast(descriptorCopies.srcSet);
655 DescriptorSetLayout *srcLayout = srcSet->header.layout;
656 ASSERT(srcLayout);
657
658 DescriptorSet *dstSet = vk::Cast(descriptorCopies.dstSet);
659 DescriptorSetLayout *dstLayout = dstSet->header.layout;
660 ASSERT(dstLayout);
661
662 size_t srcTypeSize = 0;
663 uint8_t *memToRead = srcLayout->getDescriptorPointer(srcSet, descriptorCopies.srcBinding, descriptorCopies.srcArrayElement, descriptorCopies.descriptorCount, &srcTypeSize);
664
665 size_t dstTypeSize = 0;
666 uint8_t *memToWrite = dstLayout->getDescriptorPointer(dstSet, descriptorCopies.dstBinding, descriptorCopies.dstArrayElement, descriptorCopies.descriptorCount, &dstTypeSize);
667
668 ASSERT(srcTypeSize == dstTypeSize);
669 size_t writeSize = dstTypeSize * descriptorCopies.descriptorCount;
670 memcpy(memToWrite, memToRead, writeSize);
671 }
672
673 } // namespace vk
674