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