• 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 #include "System/Types.hpp"
23 
24 #include <algorithm>
25 #include <cstring>
26 
27 namespace {
28 
UsesImmutableSamplers(const VkDescriptorSetLayoutBinding & binding)29 static bool UsesImmutableSamplers(const VkDescriptorSetLayoutBinding &binding)
30 {
31 	return (((binding.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
32 	         (binding.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)) &&
33 	        (binding.pImmutableSamplers != nullptr));
34 }
35 
36 }  // anonymous namespace
37 
38 namespace vk {
39 
DescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo * pCreateInfo,void * mem)40 DescriptorSetLayout::DescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo *pCreateInfo, void *mem)
41     : flags(pCreateInfo->flags)
42     , bindingCount(pCreateInfo->bindingCount)
43     , bindings(reinterpret_cast<VkDescriptorSetLayoutBinding *>(mem))
44 {
45 	uint8_t *hostMemory = static_cast<uint8_t *>(mem) + bindingCount * sizeof(VkDescriptorSetLayoutBinding);
46 	bindingOffsets = reinterpret_cast<size_t *>(hostMemory);
47 	hostMemory += bindingCount * sizeof(size_t);
48 
49 	size_t offset = 0;
50 	for(uint32_t i = 0; i < bindingCount; i++)
51 	{
52 		bindings[i] = pCreateInfo->pBindings[i];
53 		if(UsesImmutableSamplers(bindings[i]))
54 		{
55 			size_t immutableSamplersSize = bindings[i].descriptorCount * sizeof(VkSampler);
56 			bindings[i].pImmutableSamplers = reinterpret_cast<const VkSampler *>(hostMemory);
57 			hostMemory += immutableSamplersSize;
58 			memcpy(const_cast<VkSampler *>(bindings[i].pImmutableSamplers),
59 			       pCreateInfo->pBindings[i].pImmutableSamplers,
60 			       immutableSamplersSize);
61 		}
62 		else
63 		{
64 			bindings[i].pImmutableSamplers = nullptr;
65 		}
66 		bindingOffsets[i] = offset;
67 		offset += bindings[i].descriptorCount * GetDescriptorSize(bindings[i].descriptorType);
68 	}
69 	ASSERT_MSG(offset == getDescriptorSetDataSize(), "offset: %d, size: %d", int(offset), int(getDescriptorSetDataSize()));
70 }
71 
destroy(const VkAllocationCallbacks * pAllocator)72 void DescriptorSetLayout::destroy(const VkAllocationCallbacks *pAllocator)
73 {
74 	vk::deallocate(bindings, pAllocator);  // This allocation also contains pImmutableSamplers
75 }
76 
ComputeRequiredAllocationSize(const VkDescriptorSetLayoutCreateInfo * pCreateInfo)77 size_t DescriptorSetLayout::ComputeRequiredAllocationSize(const VkDescriptorSetLayoutCreateInfo *pCreateInfo)
78 {
79 	size_t allocationSize = pCreateInfo->bindingCount * (sizeof(VkDescriptorSetLayoutBinding) + sizeof(size_t));
80 
81 	for(uint32_t i = 0; i < pCreateInfo->bindingCount; i++)
82 	{
83 		if(UsesImmutableSamplers(pCreateInfo->pBindings[i]))
84 		{
85 			allocationSize += pCreateInfo->pBindings[i].descriptorCount * sizeof(VkSampler);
86 		}
87 	}
88 
89 	return allocationSize;
90 }
91 
GetDescriptorSize(VkDescriptorType type)92 size_t DescriptorSetLayout::GetDescriptorSize(VkDescriptorType type)
93 {
94 	switch(type)
95 	{
96 		case VK_DESCRIPTOR_TYPE_SAMPLER:
97 		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
98 		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
99 		case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
100 			return sizeof(SampledImageDescriptor);
101 		case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
102 		case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
103 		case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
104 			return sizeof(StorageImageDescriptor);
105 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
106 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
107 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
108 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
109 			return sizeof(BufferDescriptor);
110 		default:
111 			UNSUPPORTED("Unsupported Descriptor Type");
112 			return 0;
113 	}
114 }
115 
getDescriptorSetAllocationSize() const116 size_t DescriptorSetLayout::getDescriptorSetAllocationSize() const
117 {
118 	// vk::DescriptorSet has a layout member field.
119 	return sw::align<alignof(DescriptorSet)>(OFFSET(DescriptorSet, data) + getDescriptorSetDataSize());
120 }
121 
getDescriptorSetDataSize() const122 size_t DescriptorSetLayout::getDescriptorSetDataSize() const
123 {
124 	size_t size = 0;
125 	for(uint32_t i = 0; i < bindingCount; i++)
126 	{
127 		size += bindings[i].descriptorCount * GetDescriptorSize(bindings[i].descriptorType);
128 	}
129 
130 	return size;
131 }
132 
getBindingIndex(uint32_t binding) const133 uint32_t DescriptorSetLayout::getBindingIndex(uint32_t binding) const
134 {
135 	for(uint32_t i = 0; i < bindingCount; i++)
136 	{
137 		if(binding == bindings[i].binding)
138 		{
139 			return i;
140 		}
141 	}
142 
143 	DABORT("Invalid DescriptorSetLayout binding: %d", int(binding));
144 	return 0;
145 }
146 
initialize(DescriptorSet * descriptorSet)147 void DescriptorSetLayout::initialize(DescriptorSet *descriptorSet)
148 {
149 	// Use a pointer to this descriptor set layout as the descriptor set's header
150 	descriptorSet->header.layout = this;
151 	uint8_t *mem = descriptorSet->data;
152 
153 	for(uint32_t i = 0; i < bindingCount; i++)
154 	{
155 		size_t typeSize = GetDescriptorSize(bindings[i].descriptorType);
156 		if(UsesImmutableSamplers(bindings[i]))
157 		{
158 			for(uint32_t j = 0; j < bindings[i].descriptorCount; j++)
159 			{
160 				SampledImageDescriptor *imageSamplerDescriptor = reinterpret_cast<SampledImageDescriptor *>(mem);
161 				imageSamplerDescriptor->updateSampler(bindings[i].pImmutableSamplers[j]);
162 				mem += typeSize;
163 			}
164 		}
165 		else
166 		{
167 			mem += bindings[i].descriptorCount * typeSize;
168 		}
169 	}
170 }
171 
getBindingCount() const172 size_t DescriptorSetLayout::getBindingCount() const
173 {
174 	return bindingCount;
175 }
176 
hasBinding(uint32_t binding) const177 bool DescriptorSetLayout::hasBinding(uint32_t binding) const
178 {
179 	for(uint32_t i = 0; i < bindingCount; i++)
180 	{
181 		if(binding == bindings[i].binding)
182 		{
183 			return true;
184 		}
185 	}
186 	return false;
187 }
188 
getBindingStride(uint32_t binding) const189 size_t DescriptorSetLayout::getBindingStride(uint32_t binding) const
190 {
191 	uint32_t index = getBindingIndex(binding);
192 	return GetDescriptorSize(bindings[index].descriptorType);
193 }
194 
getBindingOffset(uint32_t binding,size_t arrayElement) const195 size_t DescriptorSetLayout::getBindingOffset(uint32_t binding, size_t arrayElement) const
196 {
197 	uint32_t index = getBindingIndex(binding);
198 	auto typeSize = GetDescriptorSize(bindings[index].descriptorType);
199 	return bindingOffsets[index] + OFFSET(DescriptorSet, data[0]) + (typeSize * arrayElement);
200 }
201 
isDynamic(VkDescriptorType type)202 bool DescriptorSetLayout::isDynamic(VkDescriptorType type)
203 {
204 	return type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
205 	       type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
206 }
207 
isBindingDynamic(uint32_t binding) const208 bool DescriptorSetLayout::isBindingDynamic(uint32_t binding) const
209 {
210 	uint32_t index = getBindingIndex(binding);
211 	return isDynamic(bindings[index].descriptorType);
212 }
213 
getDynamicDescriptorCount() const214 uint32_t DescriptorSetLayout::getDynamicDescriptorCount() const
215 {
216 	uint32_t count = 0;
217 	for(size_t i = 0; i < bindingCount; i++)
218 	{
219 		if(isDynamic(bindings[i].descriptorType))
220 		{
221 			count += bindings[i].descriptorCount;
222 		}
223 	}
224 	return count;
225 }
226 
getDynamicDescriptorOffset(uint32_t binding) const227 uint32_t DescriptorSetLayout::getDynamicDescriptorOffset(uint32_t binding) const
228 {
229 	uint32_t n = getBindingIndex(binding);
230 	ASSERT(isDynamic(bindings[n].descriptorType));
231 
232 	uint32_t index = 0;
233 	for(uint32_t i = 0; i < n; i++)
234 	{
235 		if(isDynamic(bindings[i].descriptorType))
236 		{
237 			index += bindings[i].descriptorCount;
238 		}
239 	}
240 	return index;
241 }
242 
getBindingLayout(uint32_t binding) const243 VkDescriptorSetLayoutBinding const &DescriptorSetLayout::getBindingLayout(uint32_t binding) const
244 {
245 	uint32_t index = getBindingIndex(binding);
246 	return bindings[index];
247 }
248 
getOffsetPointer(DescriptorSet * descriptorSet,uint32_t binding,uint32_t arrayElement,uint32_t count,size_t * typeSize) const249 uint8_t *DescriptorSetLayout::getOffsetPointer(DescriptorSet *descriptorSet, uint32_t binding, uint32_t arrayElement, uint32_t count, size_t *typeSize) const
250 {
251 	uint32_t index = getBindingIndex(binding);
252 	*typeSize = GetDescriptorSize(bindings[index].descriptorType);
253 	size_t byteOffset = bindingOffsets[index] + (*typeSize * arrayElement);
254 	ASSERT(((*typeSize * count) + byteOffset) <= getDescriptorSetDataSize());  // Make sure the operation will not go out of bounds
255 	return &descriptorSet->data[byteOffset];
256 }
257 
updateSampler(const VkSampler newSampler)258 void SampledImageDescriptor::updateSampler(const VkSampler newSampler)
259 {
260 	memcpy(reinterpret_cast<void *>(&sampler), vk::Cast(newSampler), sizeof(sampler));
261 }
262 
WriteDescriptorSet(Device * device,DescriptorSet * dstSet,VkDescriptorUpdateTemplateEntry const & entry,char const * src)263 void DescriptorSetLayout::WriteDescriptorSet(Device *device, DescriptorSet *dstSet, VkDescriptorUpdateTemplateEntry const &entry, char const *src)
264 {
265 	DescriptorSetLayout *dstLayout = dstSet->header.layout;
266 	auto &binding = dstLayout->bindings[dstLayout->getBindingIndex(entry.dstBinding)];
267 	ASSERT(dstLayout);
268 	ASSERT(binding.descriptorType == entry.descriptorType);
269 
270 	size_t typeSize = 0;
271 	uint8_t *memToWrite = dstLayout->getOffsetPointer(dstSet, entry.dstBinding, entry.dstArrayElement, entry.descriptorCount, &typeSize);
272 
273 	ASSERT(reinterpret_cast<intptr_t>(memToWrite) % 16 == 0);  // Each descriptor must be 16-byte aligned.
274 
275 	if(entry.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
276 	{
277 		SampledImageDescriptor *imageSampler = reinterpret_cast<SampledImageDescriptor *>(memToWrite);
278 
279 		for(uint32_t i = 0; i < entry.descriptorCount; i++)
280 		{
281 			auto update = reinterpret_cast<VkDescriptorImageInfo const *>(src + entry.offset + entry.stride * i);
282 			// "All consecutive bindings updated via a single VkWriteDescriptorSet structure, except those with a
283 			//  descriptorCount of zero, must all either use immutable samplers or must all not use immutable samplers."
284 			if(!binding.pImmutableSamplers)
285 			{
286 				imageSampler[i].updateSampler(update->sampler);
287 			}
288 			imageSampler[i].device = device;
289 		}
290 	}
291 	else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
292 	{
293 		SampledImageDescriptor *imageSampler = reinterpret_cast<SampledImageDescriptor *>(memToWrite);
294 
295 		for(uint32_t i = 0; i < entry.descriptorCount; i++)
296 		{
297 			auto update = reinterpret_cast<VkBufferView const *>(src + entry.offset + entry.stride * i);
298 			auto bufferView = vk::Cast(*update);
299 
300 			imageSampler[i].type = VK_IMAGE_VIEW_TYPE_1D;
301 			imageSampler[i].imageViewId = bufferView->id;
302 			imageSampler[i].swizzle = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
303 			imageSampler[i].format = bufferView->getFormat();
304 
305 			auto numElements = bufferView->getElementCount();
306 			imageSampler[i].extent = { numElements, 1, 1 };
307 			imageSampler[i].arrayLayers = 1;
308 			imageSampler[i].mipLevels = 1;
309 			imageSampler[i].sampleCount = 1;
310 			imageSampler[i].texture.widthWidthHeightHeight = sw::float4(static_cast<float>(numElements), static_cast<float>(numElements), 1, 1);
311 			imageSampler[i].texture.width = sw::float4(static_cast<float>(numElements));
312 			imageSampler[i].texture.height = sw::float4(1);
313 			imageSampler[i].texture.depth = sw::float4(1);
314 			imageSampler[i].device = device;
315 
316 			sw::Mipmap &mipmap = imageSampler[i].texture.mipmap[0];
317 			mipmap.buffer = bufferView->getPointer();
318 			mipmap.width[0] = mipmap.width[1] = mipmap.width[2] = mipmap.width[3] = numElements;
319 			mipmap.height[0] = mipmap.height[1] = mipmap.height[2] = mipmap.height[3] = 1;
320 			mipmap.depth[0] = mipmap.depth[1] = mipmap.depth[2] = mipmap.depth[3] = 1;
321 			mipmap.pitchP.x = mipmap.pitchP.y = mipmap.pitchP.z = mipmap.pitchP.w = numElements;
322 			mipmap.sliceP.x = mipmap.sliceP.y = mipmap.sliceP.z = mipmap.sliceP.w = 0;
323 			mipmap.onePitchP[0] = mipmap.onePitchP[2] = 1;
324 			mipmap.onePitchP[1] = mipmap.onePitchP[3] = static_cast<short>(numElements);
325 		}
326 	}
327 	else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
328 	        entry.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
329 	{
330 		SampledImageDescriptor *imageSampler = reinterpret_cast<SampledImageDescriptor *>(memToWrite);
331 
332 		for(uint32_t i = 0; i < entry.descriptorCount; i++)
333 		{
334 			auto update = reinterpret_cast<VkDescriptorImageInfo const *>(src + entry.offset + entry.stride * i);
335 
336 			vk::ImageView *imageView = vk::Cast(update->imageView);
337 			Format format = imageView->getFormat(ImageView::SAMPLING);
338 
339 			sw::Texture *texture = &imageSampler[i].texture;
340 
341 			if(entry.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
342 			{
343 				// "All consecutive bindings updated via a single VkWriteDescriptorSet structure, except those with a
344 				//  descriptorCount of zero, must all either use immutable samplers or must all not use immutable samplers."
345 				if(!binding.pImmutableSamplers)
346 				{
347 					imageSampler[i].updateSampler(update->sampler);
348 				}
349 			}
350 
351 			imageSampler[i].imageViewId = imageView->id;
352 			imageSampler[i].extent = imageView->getMipLevelExtent(0);
353 			imageSampler[i].arrayLayers = imageView->getSubresourceRange().layerCount;
354 			imageSampler[i].mipLevels = imageView->getSubresourceRange().levelCount;
355 			imageSampler[i].sampleCount = imageView->getSampleCount();
356 			imageSampler[i].type = imageView->getType();
357 			imageSampler[i].swizzle = imageView->getComponentMapping();
358 			imageSampler[i].format = format;
359 			imageSampler[i].device = device;
360 
361 			auto &subresourceRange = imageView->getSubresourceRange();
362 
363 			if(format.isYcbcrFormat())
364 			{
365 				ASSERT(subresourceRange.levelCount == 1);
366 
367 				// YCbCr images can only have one level, so we can store parameters for the
368 				// different planes in the descriptor's mipmap levels instead.
369 
370 				const int level = 0;
371 				VkOffset3D offset = { 0, 0, 0 };
372 				texture->mipmap[0].buffer = imageView->getOffsetPointer(offset, VK_IMAGE_ASPECT_PLANE_0_BIT, level, 0, ImageView::SAMPLING);
373 				texture->mipmap[1].buffer = imageView->getOffsetPointer(offset, VK_IMAGE_ASPECT_PLANE_1_BIT, level, 0, ImageView::SAMPLING);
374 				if(format.getAspects() & VK_IMAGE_ASPECT_PLANE_2_BIT)
375 				{
376 					texture->mipmap[2].buffer = imageView->getOffsetPointer(offset, VK_IMAGE_ASPECT_PLANE_2_BIT, level, 0, ImageView::SAMPLING);
377 				}
378 
379 				VkExtent3D extent = imageView->getMipLevelExtent(0);
380 
381 				int width = extent.width;
382 				int height = extent.height;
383 				int pitchP0 = imageView->rowPitchBytes(VK_IMAGE_ASPECT_PLANE_0_BIT, level, ImageView::SAMPLING) /
384 				              imageView->getFormat(VK_IMAGE_ASPECT_PLANE_0_BIT).bytes();
385 
386 				// Write plane 0 parameters to mipmap level 0.
387 				WriteTextureLevelInfo(texture, 0, width, height, 1, pitchP0, 0, 0, 0);
388 
389 				// Plane 2, if present, has equal parameters to plane 1, so we use mipmap level 1 for both.
390 				int pitchP1 = imageView->rowPitchBytes(VK_IMAGE_ASPECT_PLANE_1_BIT, level, ImageView::SAMPLING) /
391 				              imageView->getFormat(VK_IMAGE_ASPECT_PLANE_1_BIT).bytes();
392 
393 				WriteTextureLevelInfo(texture, 1, width / 2, height / 2, 1, pitchP1, 0, 0, 0);
394 			}
395 			else
396 			{
397 				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
398 				{
399 					int level = sw::clamp(mipmapLevel, 0, (int)subresourceRange.levelCount - 1);  // Level within the image view
400 
401 					VkImageAspectFlagBits aspect = static_cast<VkImageAspectFlagBits>(imageView->getSubresourceRange().aspectMask);
402 					sw::Mipmap &mipmap = texture->mipmap[mipmapLevel];
403 
404 					if((imageView->getType() == VK_IMAGE_VIEW_TYPE_CUBE) ||
405 					   (imageView->getType() == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY))
406 					{
407 						// Obtain the pointer to the corner of the level including the border, for seamless sampling.
408 						// This is taken into account in the sampling routine, which can't handle negative texel coordinates.
409 						VkOffset3D offset = { -1, -1, 0 };
410 						mipmap.buffer = imageView->getOffsetPointer(offset, aspect, level, 0, ImageView::SAMPLING);
411 					}
412 					else
413 					{
414 						VkOffset3D offset = { 0, 0, 0 };
415 						mipmap.buffer = imageView->getOffsetPointer(offset, aspect, level, 0, ImageView::SAMPLING);
416 					}
417 
418 					VkExtent3D extent = imageView->getMipLevelExtent(level);
419 
420 					int width = extent.width;
421 					int height = extent.height;
422 					int bytes = format.bytes();
423 					int layers = imageView->getSubresourceRange().layerCount;  // TODO(b/129523279): Untangle depth vs layers throughout the sampler
424 					int depth = layers > 1 ? layers : extent.depth;
425 					int pitchP = imageView->rowPitchBytes(aspect, level, ImageView::SAMPLING) / bytes;
426 					int sliceP = (layers > 1 ? imageView->layerPitchBytes(aspect, ImageView::SAMPLING) : imageView->slicePitchBytes(aspect, level, ImageView::SAMPLING)) / bytes;
427 					int samplePitchP = imageView->getMipLevelSize(aspect, level, ImageView::SAMPLING) / bytes;
428 					int sampleMax = imageView->getSampleCount() - 1;
429 
430 					WriteTextureLevelInfo(texture, mipmapLevel, width, height, depth, pitchP, sliceP, samplePitchP, sampleMax);
431 				}
432 			}
433 		}
434 	}
435 	else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
436 	        entry.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
437 	{
438 		auto descriptor = reinterpret_cast<StorageImageDescriptor *>(memToWrite);
439 		for(uint32_t i = 0; i < entry.descriptorCount; i++)
440 		{
441 			auto update = reinterpret_cast<VkDescriptorImageInfo const *>(src + entry.offset + entry.stride * i);
442 			auto imageView = vk::Cast(update->imageView);
443 			descriptor[i].ptr = imageView->getOffsetPointer({ 0, 0, 0 }, VK_IMAGE_ASPECT_COLOR_BIT, 0, 0);
444 			descriptor[i].extent = imageView->getMipLevelExtent(0);
445 			descriptor[i].rowPitchBytes = imageView->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
446 			descriptor[i].samplePitchBytes = imageView->getSubresourceRange().layerCount > 1
447 			                                     ? imageView->layerPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT)
448 			                                     : imageView->slicePitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
449 			descriptor[i].slicePitchBytes = descriptor[i].samplePitchBytes * imageView->getSampleCount();
450 			descriptor[i].arrayLayers = imageView->getSubresourceRange().layerCount;
451 			descriptor[i].sampleCount = imageView->getSampleCount();
452 			descriptor[i].sizeInBytes = static_cast<int>(imageView->getImageSizeInBytes());
453 
454 			if(imageView->getFormat().isStencil())
455 			{
456 				descriptor[i].stencilPtr = imageView->getOffsetPointer({ 0, 0, 0 }, VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0);
457 				descriptor[i].stencilRowPitchBytes = imageView->rowPitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT, 0);
458 				descriptor[i].stencilSamplePitchBytes = (imageView->getSubresourceRange().layerCount > 1)
459 				                                            ? imageView->layerPitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT)
460 				                                            : imageView->slicePitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT, 0);
461 				descriptor[i].stencilSlicePitchBytes = descriptor[i].stencilSamplePitchBytes * imageView->getSampleCount();
462 			}
463 		}
464 	}
465 	else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
466 	{
467 		auto descriptor = reinterpret_cast<StorageImageDescriptor *>(memToWrite);
468 		for(uint32_t i = 0; i < entry.descriptorCount; i++)
469 		{
470 			auto update = reinterpret_cast<VkBufferView const *>(src + entry.offset + entry.stride * i);
471 			auto bufferView = vk::Cast(*update);
472 			descriptor[i].ptr = bufferView->getPointer();
473 			descriptor[i].extent = { bufferView->getElementCount(), 1, 1 };
474 			descriptor[i].rowPitchBytes = 0;
475 			descriptor[i].slicePitchBytes = 0;
476 			descriptor[i].samplePitchBytes = 0;
477 			descriptor[i].arrayLayers = 1;
478 			descriptor[i].sampleCount = 1;
479 			descriptor[i].sizeInBytes = bufferView->getRangeInBytes();
480 		}
481 	}
482 	else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
483 	        entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
484 	        entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
485 	        entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
486 	{
487 		auto descriptor = reinterpret_cast<BufferDescriptor *>(memToWrite);
488 		for(uint32_t i = 0; i < entry.descriptorCount; i++)
489 		{
490 			auto update = reinterpret_cast<VkDescriptorBufferInfo const *>(src + entry.offset + entry.stride * i);
491 			auto buffer = vk::Cast(update->buffer);
492 			descriptor[i].ptr = buffer->getOffsetPointer(update->offset);
493 			descriptor[i].sizeInBytes = static_cast<int>((update->range == VK_WHOLE_SIZE) ? buffer->getSize() - update->offset : update->range);
494 			descriptor[i].robustnessSize = static_cast<int>(buffer->getSize() - update->offset);
495 		}
496 	}
497 }
498 
WriteTextureLevelInfo(sw::Texture * texture,int level,int width,int height,int depth,int pitchP,int sliceP,int samplePitchP,int sampleMax)499 void DescriptorSetLayout::WriteTextureLevelInfo(sw::Texture *texture, int level, int width, int height, int depth, int pitchP, int sliceP, int samplePitchP, int sampleMax)
500 {
501 	if(level == 0)
502 	{
503 		texture->widthWidthHeightHeight[0] =
504 		    texture->widthWidthHeightHeight[1] = static_cast<float>(width);
505 		texture->widthWidthHeightHeight[2] =
506 		    texture->widthWidthHeightHeight[3] = static_cast<float>(height);
507 
508 		texture->width[0] =
509 		    texture->width[1] =
510 		        texture->width[2] =
511 		            texture->width[3] = static_cast<float>(width);
512 
513 		texture->height[0] =
514 		    texture->height[1] =
515 		        texture->height[2] =
516 		            texture->height[3] = static_cast<float>(height);
517 
518 		texture->depth[0] =
519 		    texture->depth[1] =
520 		        texture->depth[2] =
521 		            texture->depth[3] = static_cast<float>(depth);
522 	}
523 
524 	sw::Mipmap &mipmap = texture->mipmap[level];
525 
526 	short halfTexelU = 0x8000 / width;
527 	short halfTexelV = 0x8000 / height;
528 	short halfTexelW = 0x8000 / depth;
529 
530 	mipmap.uHalf[0] =
531 	    mipmap.uHalf[1] =
532 	        mipmap.uHalf[2] =
533 	            mipmap.uHalf[3] = halfTexelU;
534 
535 	mipmap.vHalf[0] =
536 	    mipmap.vHalf[1] =
537 	        mipmap.vHalf[2] =
538 	            mipmap.vHalf[3] = halfTexelV;
539 
540 	mipmap.wHalf[0] =
541 	    mipmap.wHalf[1] =
542 	        mipmap.wHalf[2] =
543 	            mipmap.wHalf[3] = halfTexelW;
544 
545 	mipmap.width[0] =
546 	    mipmap.width[1] =
547 	        mipmap.width[2] =
548 	            mipmap.width[3] = width;
549 
550 	mipmap.height[0] =
551 	    mipmap.height[1] =
552 	        mipmap.height[2] =
553 	            mipmap.height[3] = height;
554 
555 	mipmap.depth[0] =
556 	    mipmap.depth[1] =
557 	        mipmap.depth[2] =
558 	            mipmap.depth[3] = depth;
559 
560 	mipmap.onePitchP[0] = 1;
561 	mipmap.onePitchP[1] = static_cast<short>(pitchP);
562 	mipmap.onePitchP[2] = 1;
563 	mipmap.onePitchP[3] = static_cast<short>(pitchP);
564 
565 	mipmap.pitchP[0] = pitchP;
566 	mipmap.pitchP[1] = pitchP;
567 	mipmap.pitchP[2] = pitchP;
568 	mipmap.pitchP[3] = pitchP;
569 
570 	mipmap.sliceP[0] = sliceP;
571 	mipmap.sliceP[1] = sliceP;
572 	mipmap.sliceP[2] = sliceP;
573 	mipmap.sliceP[3] = sliceP;
574 
575 	mipmap.samplePitchP[0] = samplePitchP;
576 	mipmap.samplePitchP[1] = samplePitchP;
577 	mipmap.samplePitchP[2] = samplePitchP;
578 	mipmap.samplePitchP[3] = samplePitchP;
579 
580 	mipmap.sampleMax[0] = sampleMax;
581 	mipmap.sampleMax[1] = sampleMax;
582 	mipmap.sampleMax[2] = sampleMax;
583 	mipmap.sampleMax[3] = sampleMax;
584 }
585 
WriteDescriptorSet(Device * device,const VkWriteDescriptorSet & writeDescriptorSet)586 void DescriptorSetLayout::WriteDescriptorSet(Device *device, const VkWriteDescriptorSet &writeDescriptorSet)
587 {
588 	DescriptorSet *dstSet = vk::Cast(writeDescriptorSet.dstSet);
589 	VkDescriptorUpdateTemplateEntry e;
590 	e.descriptorType = writeDescriptorSet.descriptorType;
591 	e.dstBinding = writeDescriptorSet.dstBinding;
592 	e.dstArrayElement = writeDescriptorSet.dstArrayElement;
593 	e.descriptorCount = writeDescriptorSet.descriptorCount;
594 	e.offset = 0;
595 	void const *ptr = nullptr;
596 	switch(writeDescriptorSet.descriptorType)
597 	{
598 		case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
599 		case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
600 			ptr = writeDescriptorSet.pTexelBufferView;
601 			e.stride = sizeof(VkBufferView);
602 			break;
603 
604 		case VK_DESCRIPTOR_TYPE_SAMPLER:
605 		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
606 		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
607 		case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
608 		case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
609 			ptr = writeDescriptorSet.pImageInfo;
610 			e.stride = sizeof(VkDescriptorImageInfo);
611 			break;
612 
613 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
614 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
615 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
616 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
617 			ptr = writeDescriptorSet.pBufferInfo;
618 			e.stride = sizeof(VkDescriptorBufferInfo);
619 			break;
620 
621 		default:
622 			UNSUPPORTED("descriptor type %u", writeDescriptorSet.descriptorType);
623 	}
624 
625 	WriteDescriptorSet(device, dstSet, e, reinterpret_cast<char const *>(ptr));
626 }
627 
CopyDescriptorSet(const VkCopyDescriptorSet & descriptorCopies)628 void DescriptorSetLayout::CopyDescriptorSet(const VkCopyDescriptorSet &descriptorCopies)
629 {
630 	DescriptorSet *srcSet = vk::Cast(descriptorCopies.srcSet);
631 	DescriptorSetLayout *srcLayout = srcSet->header.layout;
632 	ASSERT(srcLayout);
633 
634 	DescriptorSet *dstSet = vk::Cast(descriptorCopies.dstSet);
635 	DescriptorSetLayout *dstLayout = dstSet->header.layout;
636 	ASSERT(dstLayout);
637 
638 	size_t srcTypeSize = 0;
639 	uint8_t *memToRead = srcLayout->getOffsetPointer(srcSet, descriptorCopies.srcBinding, descriptorCopies.srcArrayElement, descriptorCopies.descriptorCount, &srcTypeSize);
640 
641 	size_t dstTypeSize = 0;
642 	uint8_t *memToWrite = dstLayout->getOffsetPointer(dstSet, descriptorCopies.dstBinding, descriptorCopies.dstArrayElement, descriptorCopies.descriptorCount, &dstTypeSize);
643 
644 	ASSERT(srcTypeSize == dstTypeSize);
645 	size_t writeSize = dstTypeSize * descriptorCopies.descriptorCount;
646 	memcpy(memToWrite, memToRead, writeSize);
647 }
648 
649 }  // namespace vk
650