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 auto &srcBinding = pCreateInfo->pBindings[i];
63 auto &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(), "offset: %d, size: %d", int(offset), int(getDescriptorSetDataSize()));
89 }
90
destroy(const VkAllocationCallbacks * pAllocator)91 void DescriptorSetLayout::destroy(const VkAllocationCallbacks *pAllocator)
92 {
93 vk::deallocate(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 default:
133 UNSUPPORTED("Unsupported Descriptor Type: %d", int(type));
134 return 0;
135 }
136 }
137
IsDescriptorDynamic(VkDescriptorType type)138 bool DescriptorSetLayout::IsDescriptorDynamic(VkDescriptorType type)
139 {
140 return type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
141 type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
142 }
143
getDescriptorSetAllocationSize() const144 size_t DescriptorSetLayout::getDescriptorSetAllocationSize() const
145 {
146 // vk::DescriptorSet has a header with a pointer to the layout.
147 return sw::align<alignof(DescriptorSet)>(OFFSET(DescriptorSet, data) + getDescriptorSetDataSize());
148 }
149
getDescriptorSetDataSize() const150 size_t DescriptorSetLayout::getDescriptorSetDataSize() const
151 {
152 size_t size = 0;
153 for(uint32_t i = 0; i < bindingsArraySize; i++)
154 {
155 size += bindings[i].descriptorCount * GetDescriptorSize(bindings[i].descriptorType);
156 }
157
158 return size;
159 }
160
initialize(DescriptorSet * descriptorSet)161 void DescriptorSetLayout::initialize(DescriptorSet *descriptorSet)
162 {
163 ASSERT(descriptorSet->header.layout == nullptr);
164
165 // Use a pointer to this descriptor set layout as the descriptor set's header
166 descriptorSet->header.layout = this;
167 uint8_t *mem = descriptorSet->data;
168
169 for(uint32_t i = 0; i < bindingsArraySize; i++)
170 {
171 size_t descriptorSize = GetDescriptorSize(bindings[i].descriptorType);
172
173 if(bindings[i].immutableSamplers)
174 {
175 for(uint32_t j = 0; j < bindings[i].descriptorCount; j++)
176 {
177 SampledImageDescriptor *imageSamplerDescriptor = reinterpret_cast<SampledImageDescriptor *>(mem);
178 imageSamplerDescriptor->updateSampler(bindings[i].immutableSamplers[j]);
179 mem += descriptorSize;
180 }
181 }
182 else
183 {
184 mem += bindings[i].descriptorCount * descriptorSize;
185 }
186 }
187 }
188
getBindingOffset(uint32_t bindingNumber) const189 uint32_t DescriptorSetLayout::getBindingOffset(uint32_t bindingNumber) const
190 {
191 ASSERT(bindingNumber < bindingsArraySize);
192 return bindings[bindingNumber].offset;
193 }
194
getDescriptorCount(uint32_t bindingNumber) const195 uint32_t DescriptorSetLayout::getDescriptorCount(uint32_t bindingNumber) const
196 {
197 ASSERT(bindingNumber < bindingsArraySize);
198 return bindings[bindingNumber].descriptorCount;
199 }
200
getDynamicDescriptorCount() const201 uint32_t DescriptorSetLayout::getDynamicDescriptorCount() const
202 {
203 uint32_t count = 0;
204 for(size_t i = 0; i < bindingsArraySize; i++)
205 {
206 if(IsDescriptorDynamic(bindings[i].descriptorType))
207 {
208 count += bindings[i].descriptorCount;
209 }
210 }
211
212 return count;
213 }
214
getDynamicOffsetIndex(uint32_t bindingNumber) const215 uint32_t DescriptorSetLayout::getDynamicOffsetIndex(uint32_t bindingNumber) const
216 {
217 ASSERT(bindingNumber < bindingsArraySize);
218 ASSERT(IsDescriptorDynamic(bindings[bindingNumber].descriptorType));
219
220 uint32_t index = 0;
221 for(uint32_t i = 0; i < bindingNumber; i++)
222 {
223 if(IsDescriptorDynamic(bindings[i].descriptorType))
224 {
225 index += bindings[i].descriptorCount;
226 }
227 }
228
229 return index;
230 }
231
getDescriptorType(uint32_t bindingNumber) const232 VkDescriptorType DescriptorSetLayout::getDescriptorType(uint32_t bindingNumber) const
233 {
234 ASSERT(bindingNumber < bindingsArraySize);
235 return bindings[bindingNumber].descriptorType;
236 }
237
getDescriptorPointer(DescriptorSet * descriptorSet,uint32_t bindingNumber,uint32_t arrayElement,uint32_t count,size_t * typeSize) const238 uint8_t *DescriptorSetLayout::getDescriptorPointer(DescriptorSet *descriptorSet, uint32_t bindingNumber, uint32_t arrayElement, uint32_t count, size_t *typeSize) const
239 {
240 ASSERT(bindingNumber < bindingsArraySize);
241 *typeSize = GetDescriptorSize(bindings[bindingNumber].descriptorType);
242 size_t byteOffset = bindings[bindingNumber].offset + (*typeSize * arrayElement);
243 ASSERT(((*typeSize * count) + byteOffset) <= getDescriptorSetDataSize()); // Make sure the operation will not go out of bounds
244
245 return &descriptorSet->data[byteOffset];
246 }
247
updateSampler(const vk::Sampler * newSampler)248 void SampledImageDescriptor::updateSampler(const vk::Sampler *newSampler)
249 {
250 memcpy(reinterpret_cast<void *>(&sampler), newSampler, sizeof(sampler));
251 }
252
WriteDescriptorSet(Device * device,DescriptorSet * dstSet,VkDescriptorUpdateTemplateEntry const & entry,char const * src)253 void DescriptorSetLayout::WriteDescriptorSet(Device *device, DescriptorSet *dstSet, VkDescriptorUpdateTemplateEntry const &entry, char const *src)
254 {
255 DescriptorSetLayout *dstLayout = dstSet->header.layout;
256 auto &binding = dstLayout->bindings[entry.dstBinding];
257 ASSERT(dstLayout);
258 ASSERT(binding.descriptorType == entry.descriptorType);
259
260 size_t typeSize = 0;
261 uint8_t *memToWrite = dstLayout->getDescriptorPointer(dstSet, entry.dstBinding, entry.dstArrayElement, entry.descriptorCount, &typeSize);
262
263 ASSERT(reinterpret_cast<intptr_t>(memToWrite) % 16 == 0); // Each descriptor must be 16-byte aligned.
264
265 if(entry.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
266 {
267 SampledImageDescriptor *sampledImage = reinterpret_cast<SampledImageDescriptor *>(memToWrite);
268
269 for(uint32_t i = 0; i < entry.descriptorCount; i++)
270 {
271 auto update = reinterpret_cast<VkDescriptorImageInfo const *>(src + entry.offset + entry.stride * i);
272 // "All consecutive bindings updated via a single VkWriteDescriptorSet structure, except those with a
273 // descriptorCount of zero, must all either use immutable samplers or must all not use immutable samplers."
274 if(!binding.immutableSamplers)
275 {
276 sampledImage[i].updateSampler(vk::Cast(update->sampler));
277 }
278 sampledImage[i].device = device;
279 }
280 }
281 else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
282 {
283 SampledImageDescriptor *sampledImage = reinterpret_cast<SampledImageDescriptor *>(memToWrite);
284
285 for(uint32_t i = 0; i < entry.descriptorCount; i++)
286 {
287 auto update = reinterpret_cast<VkBufferView const *>(src + entry.offset + entry.stride * i);
288 auto bufferView = vk::Cast(*update);
289
290 sampledImage[i].type = VK_IMAGE_VIEW_TYPE_1D;
291 sampledImage[i].imageViewId = bufferView->id;
292 constexpr VkComponentMapping identityMapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
293 sampledImage[i].swizzle = ResolveComponentMapping(identityMapping, bufferView->getFormat());
294 sampledImage[i].format = bufferView->getFormat();
295
296 auto numElements = bufferView->getElementCount();
297 sampledImage[i].width = numElements;
298 sampledImage[i].height = 1;
299 sampledImage[i].depth = 1;
300 sampledImage[i].mipLevels = 1;
301 sampledImage[i].sampleCount = 1;
302 sampledImage[i].texture.widthWidthHeightHeight = sw::float4(static_cast<float>(numElements), static_cast<float>(numElements), 1, 1);
303 sampledImage[i].texture.width = sw::float4(static_cast<float>(numElements));
304 sampledImage[i].texture.height = sw::float4(1);
305 sampledImage[i].texture.depth = sw::float4(1);
306 sampledImage[i].device = device;
307
308 sw::Mipmap &mipmap = sampledImage[i].texture.mipmap[0];
309 mipmap.buffer = bufferView->getPointer();
310 mipmap.width[0] = mipmap.width[1] = mipmap.width[2] = mipmap.width[3] = numElements;
311 mipmap.height[0] = mipmap.height[1] = mipmap.height[2] = mipmap.height[3] = 1;
312 mipmap.depth[0] = mipmap.depth[1] = mipmap.depth[2] = mipmap.depth[3] = 1;
313 mipmap.pitchP.x = mipmap.pitchP.y = mipmap.pitchP.z = mipmap.pitchP.w = numElements;
314 mipmap.sliceP.x = mipmap.sliceP.y = mipmap.sliceP.z = mipmap.sliceP.w = 0;
315 mipmap.onePitchP[0] = mipmap.onePitchP[2] = 1;
316 mipmap.onePitchP[1] = mipmap.onePitchP[3] = 0;
317 }
318 }
319 else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
320 entry.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
321 {
322 SampledImageDescriptor *sampledImage = reinterpret_cast<SampledImageDescriptor *>(memToWrite);
323
324 for(uint32_t i = 0; i < entry.descriptorCount; i++)
325 {
326 auto *update = reinterpret_cast<VkDescriptorImageInfo const *>(src + entry.offset + entry.stride * i);
327
328 vk::ImageView *imageView = vk::Cast(update->imageView);
329 Format format = imageView->getFormat(ImageView::SAMPLING);
330
331 sw::Texture *texture = &sampledImage[i].texture;
332
333 if(entry.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
334 {
335 // "All consecutive bindings updated via a single VkWriteDescriptorSet structure, except those with a
336 // descriptorCount of zero, must all either use immutable samplers or must all not use immutable samplers."
337 if(!binding.immutableSamplers)
338 {
339 sampledImage[i].updateSampler(vk::Cast(update->sampler));
340 }
341 }
342
343 const auto &extent = imageView->getMipLevelExtent(0);
344
345 sampledImage[i].imageViewId = imageView->id;
346 sampledImage[i].width = extent.width;
347 sampledImage[i].height = extent.height;
348 sampledImage[i].depth = imageView->getDepthOrLayerCount(0);
349 sampledImage[i].mipLevels = imageView->getSubresourceRange().levelCount;
350 sampledImage[i].sampleCount = imageView->getSampleCount();
351 sampledImage[i].type = imageView->getType();
352 sampledImage[i].swizzle = imageView->getComponentMapping();
353 sampledImage[i].format = format;
354 sampledImage[i].device = device;
355 sampledImage[i].memoryOwner = imageView;
356
357 auto &subresourceRange = imageView->getSubresourceRange();
358
359 if(format.isYcbcrFormat())
360 {
361 ASSERT(subresourceRange.levelCount == 1);
362
363 // YCbCr images can only have one level, so we can store parameters for the
364 // different planes in the descriptor's mipmap levels instead.
365
366 const int level = 0;
367 VkOffset3D offset = { 0, 0, 0 };
368 texture->mipmap[0].buffer = imageView->getOffsetPointer(offset, VK_IMAGE_ASPECT_PLANE_0_BIT, level, 0, ImageView::SAMPLING);
369 texture->mipmap[1].buffer = imageView->getOffsetPointer(offset, VK_IMAGE_ASPECT_PLANE_1_BIT, level, 0, ImageView::SAMPLING);
370 if(format.getAspects() & VK_IMAGE_ASPECT_PLANE_2_BIT)
371 {
372 texture->mipmap[2].buffer = imageView->getOffsetPointer(offset, VK_IMAGE_ASPECT_PLANE_2_BIT, level, 0, ImageView::SAMPLING);
373 }
374
375 VkExtent2D extent = imageView->getMipLevelExtent(0);
376
377 int width = extent.width;
378 int height = extent.height;
379 int pitchP0 = imageView->rowPitchBytes(VK_IMAGE_ASPECT_PLANE_0_BIT, level, ImageView::SAMPLING) /
380 imageView->getFormat(VK_IMAGE_ASPECT_PLANE_0_BIT).bytes();
381
382 // Write plane 0 parameters to mipmap level 0.
383 WriteTextureLevelInfo(texture, 0, width, height, 1, pitchP0, 0, 0, 0);
384
385 // Plane 2, if present, has equal parameters to plane 1, so we use mipmap level 1 for both.
386 int pitchP1 = imageView->rowPitchBytes(VK_IMAGE_ASPECT_PLANE_1_BIT, level, ImageView::SAMPLING) /
387 imageView->getFormat(VK_IMAGE_ASPECT_PLANE_1_BIT).bytes();
388
389 WriteTextureLevelInfo(texture, 1, width / 2, height / 2, 1, pitchP1, 0, 0, 0);
390 }
391 else
392 {
393 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
394 {
395 int level = sw::clamp(mipmapLevel, 0, (int)subresourceRange.levelCount - 1); // Level within the image view
396
397 VkImageAspectFlagBits aspect = static_cast<VkImageAspectFlagBits>(imageView->getSubresourceRange().aspectMask);
398 sw::Mipmap &mipmap = texture->mipmap[mipmapLevel];
399
400 if((imageView->getType() == VK_IMAGE_VIEW_TYPE_CUBE) ||
401 (imageView->getType() == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY))
402 {
403 // Obtain the pointer to the corner of the level including the border, for seamless sampling.
404 // This is taken into account in the sampling routine, which can't handle negative texel coordinates.
405 VkOffset3D offset = { -1, -1, 0 };
406 mipmap.buffer = imageView->getOffsetPointer(offset, aspect, level, 0, ImageView::SAMPLING);
407 }
408 else
409 {
410 VkOffset3D offset = { 0, 0, 0 };
411 mipmap.buffer = imageView->getOffsetPointer(offset, aspect, level, 0, ImageView::SAMPLING);
412 }
413
414 VkExtent2D extent = imageView->getMipLevelExtent(level);
415
416 int width = extent.width;
417 int height = extent.height;
418 int layerCount = imageView->getSubresourceRange().layerCount;
419 int depth = imageView->getDepthOrLayerCount(level);
420 int bytes = format.bytes();
421 int pitchP = imageView->rowPitchBytes(aspect, level, ImageView::SAMPLING) / bytes;
422 int sliceP = (layerCount > 1 ? imageView->layerPitchBytes(aspect, ImageView::SAMPLING) : imageView->slicePitchBytes(aspect, level, ImageView::SAMPLING)) / bytes;
423 int samplePitchP = imageView->getMipLevelSize(aspect, level, ImageView::SAMPLING) / bytes;
424 int sampleMax = imageView->getSampleCount() - 1;
425
426 WriteTextureLevelInfo(texture, mipmapLevel, width, height, depth, pitchP, sliceP, samplePitchP, sampleMax);
427 }
428 }
429 }
430 }
431 else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
432 entry.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
433 {
434 auto storageImage = reinterpret_cast<StorageImageDescriptor *>(memToWrite);
435 for(uint32_t i = 0; i < entry.descriptorCount; i++)
436 {
437 auto *update = reinterpret_cast<VkDescriptorImageInfo const *>(src + entry.offset + entry.stride * i);
438 auto *imageView = vk::Cast(update->imageView);
439 const auto &extent = imageView->getMipLevelExtent(0);
440 auto layerCount = imageView->getSubresourceRange().layerCount;
441
442 storageImage[i].ptr = imageView->getOffsetPointer({ 0, 0, 0 }, VK_IMAGE_ASPECT_COLOR_BIT, 0, 0);
443 storageImage[i].width = extent.width;
444 storageImage[i].height = extent.height;
445 storageImage[i].depth = imageView->getDepthOrLayerCount(0);
446 storageImage[i].rowPitchBytes = imageView->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
447 storageImage[i].samplePitchBytes = imageView->slicePitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
448 storageImage[i].slicePitchBytes = layerCount > 1
449 ? imageView->layerPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT)
450 : imageView->slicePitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
451 storageImage[i].sampleCount = imageView->getSampleCount();
452 storageImage[i].sizeInBytes = static_cast<int>(imageView->getSizeInBytes());
453 storageImage[i].memoryOwner = imageView;
454
455 if(imageView->getFormat().isStencil())
456 {
457 storageImage[i].stencilPtr = imageView->getOffsetPointer({ 0, 0, 0 }, VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0);
458 storageImage[i].stencilRowPitchBytes = imageView->rowPitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT, 0);
459 storageImage[i].stencilSamplePitchBytes = imageView->slicePitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT, 0);
460 storageImage[i].stencilSlicePitchBytes = (imageView->getSubresourceRange().layerCount > 1)
461 ? imageView->layerPitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT)
462 : imageView->slicePitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT, 0);
463 }
464 }
465 }
466 else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
467 {
468 auto *storageImage = reinterpret_cast<StorageImageDescriptor *>(memToWrite);
469 for(uint32_t i = 0; i < entry.descriptorCount; i++)
470 {
471 auto update = reinterpret_cast<VkBufferView const *>(src + entry.offset + entry.stride * i);
472 auto bufferView = vk::Cast(*update);
473 storageImage[i].ptr = bufferView->getPointer();
474 storageImage[i].width = bufferView->getElementCount();
475 storageImage[i].height = 1;
476 storageImage[i].depth = 1;
477 storageImage[i].rowPitchBytes = 0;
478 storageImage[i].slicePitchBytes = 0;
479 storageImage[i].samplePitchBytes = 0;
480 storageImage[i].sampleCount = 1;
481 storageImage[i].sizeInBytes = bufferView->getRangeInBytes();
482 }
483 }
484 else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
485 entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
486 entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
487 entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
488 {
489 auto *bufferDescriptor = reinterpret_cast<BufferDescriptor *>(memToWrite);
490 for(uint32_t i = 0; i < entry.descriptorCount; i++)
491 {
492 auto update = reinterpret_cast<VkDescriptorBufferInfo const *>(src + entry.offset + entry.stride * i);
493 auto buffer = vk::Cast(update->buffer);
494 bufferDescriptor[i].ptr = buffer->getOffsetPointer(update->offset);
495 bufferDescriptor[i].sizeInBytes = static_cast<int>((update->range == VK_WHOLE_SIZE) ? buffer->getSize() - update->offset : update->range);
496 bufferDescriptor[i].robustnessSize = static_cast<int>(buffer->getSize() - update->offset);
497 }
498 }
499 }
500
WriteTextureLevelInfo(sw::Texture * texture,int level,int width,int height,int depth,int pitchP,int sliceP,int samplePitchP,int sampleMax)501 void DescriptorSetLayout::WriteTextureLevelInfo(sw::Texture *texture, int level, int width, int height, int depth, int pitchP, int sliceP, int samplePitchP, int sampleMax)
502 {
503 if(level == 0)
504 {
505 texture->widthWidthHeightHeight[0] = static_cast<float>(width);
506 texture->widthWidthHeightHeight[1] = static_cast<float>(width);
507 texture->widthWidthHeightHeight[2] = static_cast<float>(height);
508 texture->widthWidthHeightHeight[3] = static_cast<float>(height);
509
510 texture->width = sw::float4(static_cast<float>(width));
511 texture->height = sw::float4(static_cast<float>(height));
512 texture->depth = sw::float4(static_cast<float>(depth));
513 }
514
515 sw::Mipmap &mipmap = texture->mipmap[level];
516
517 short halfTexelU = 0x8000 / width;
518 short halfTexelV = 0x8000 / height;
519 short halfTexelW = 0x8000 / depth;
520
521 mipmap.uHalf = sw::short4(halfTexelU);
522 mipmap.vHalf = sw::short4(halfTexelV);
523 mipmap.wHalf = sw::short4(halfTexelW);
524
525 mipmap.width = sw::int4(width);
526 mipmap.height = sw::int4(height);
527 mipmap.depth = sw::int4(depth);
528
529 mipmap.onePitchP[0] = 1;
530 mipmap.onePitchP[1] = static_cast<short>(pitchP);
531 mipmap.onePitchP[2] = 1;
532 mipmap.onePitchP[3] = static_cast<short>(pitchP);
533
534 mipmap.pitchP = sw::int4(pitchP);
535 mipmap.sliceP = sw::int4(sliceP);
536 mipmap.samplePitchP = sw::int4(samplePitchP);
537 mipmap.sampleMax = sw::int4(sampleMax);
538 }
539
WriteDescriptorSet(Device * device,const VkWriteDescriptorSet & writeDescriptorSet)540 void DescriptorSetLayout::WriteDescriptorSet(Device *device, const VkWriteDescriptorSet &writeDescriptorSet)
541 {
542 DescriptorSet *dstSet = vk::Cast(writeDescriptorSet.dstSet);
543 VkDescriptorUpdateTemplateEntry e;
544 e.descriptorType = writeDescriptorSet.descriptorType;
545 e.dstBinding = writeDescriptorSet.dstBinding;
546 e.dstArrayElement = writeDescriptorSet.dstArrayElement;
547 e.descriptorCount = writeDescriptorSet.descriptorCount;
548 e.offset = 0;
549 void const *ptr = nullptr;
550 switch(writeDescriptorSet.descriptorType)
551 {
552 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
553 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
554 ptr = writeDescriptorSet.pTexelBufferView;
555 e.stride = sizeof(VkBufferView);
556 break;
557
558 case VK_DESCRIPTOR_TYPE_SAMPLER:
559 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
560 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
561 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
562 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
563 ptr = writeDescriptorSet.pImageInfo;
564 e.stride = sizeof(VkDescriptorImageInfo);
565 break;
566
567 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
568 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
569 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
570 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
571 ptr = writeDescriptorSet.pBufferInfo;
572 e.stride = sizeof(VkDescriptorBufferInfo);
573 break;
574
575 default:
576 UNSUPPORTED("descriptor type %u", writeDescriptorSet.descriptorType);
577 }
578
579 WriteDescriptorSet(device, dstSet, e, reinterpret_cast<char const *>(ptr));
580 }
581
CopyDescriptorSet(const VkCopyDescriptorSet & descriptorCopies)582 void DescriptorSetLayout::CopyDescriptorSet(const VkCopyDescriptorSet &descriptorCopies)
583 {
584 DescriptorSet *srcSet = vk::Cast(descriptorCopies.srcSet);
585 DescriptorSetLayout *srcLayout = srcSet->header.layout;
586 ASSERT(srcLayout);
587
588 DescriptorSet *dstSet = vk::Cast(descriptorCopies.dstSet);
589 DescriptorSetLayout *dstLayout = dstSet->header.layout;
590 ASSERT(dstLayout);
591
592 size_t srcTypeSize = 0;
593 uint8_t *memToRead = srcLayout->getDescriptorPointer(srcSet, descriptorCopies.srcBinding, descriptorCopies.srcArrayElement, descriptorCopies.descriptorCount, &srcTypeSize);
594
595 size_t dstTypeSize = 0;
596 uint8_t *memToWrite = dstLayout->getDescriptorPointer(dstSet, descriptorCopies.dstBinding, descriptorCopies.dstArrayElement, descriptorCopies.descriptorCount, &dstTypeSize);
597
598 ASSERT(srcTypeSize == dstTypeSize);
599 size_t writeSize = dstTypeSize * descriptorCopies.descriptorCount;
600 memcpy(memToWrite, memToRead, writeSize);
601 }
602
603 } // namespace vk
604