Home | History | Annotate | Download | only in sparse_resources
      1 /*------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2016 The Khronos Group Inc.
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file  vktSparseResourcesTestsUtil.cpp
     21  * \brief Sparse Resources Tests Utility Classes
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "vktSparseResourcesTestsUtil.hpp"
     25 #include "vkQueryUtil.hpp"
     26 #include "vkTypeUtil.hpp"
     27 #include "tcuTextureUtil.hpp"
     28 
     29 #include <deMath.h>
     30 
     31 using namespace vk;
     32 
     33 namespace vkt
     34 {
     35 namespace sparse
     36 {
     37 
     38 tcu::UVec3 getShaderGridSize (const ImageType imageType, const tcu::UVec3& imageSize, const deUint32 mipLevel)
     39 {
     40 	const deUint32 mipLevelX = std::max(imageSize.x() >> mipLevel, 1u);
     41 	const deUint32 mipLevelY = std::max(imageSize.y() >> mipLevel, 1u);
     42 	const deUint32 mipLevelZ = std::max(imageSize.z() >> mipLevel, 1u);
     43 
     44 	switch (imageType)
     45 	{
     46 	case IMAGE_TYPE_1D:
     47 		return tcu::UVec3(mipLevelX, 1u, 1u);
     48 
     49 	case IMAGE_TYPE_BUFFER:
     50 		return tcu::UVec3(imageSize.x(), 1u, 1u);
     51 
     52 	case IMAGE_TYPE_1D_ARRAY:
     53 		return tcu::UVec3(mipLevelX, imageSize.z(), 1u);
     54 
     55 	case IMAGE_TYPE_2D:
     56 		return tcu::UVec3(mipLevelX, mipLevelY, 1u);
     57 
     58 	case IMAGE_TYPE_2D_ARRAY:
     59 		return tcu::UVec3(mipLevelX, mipLevelY, imageSize.z());
     60 
     61 	case IMAGE_TYPE_3D:
     62 		return tcu::UVec3(mipLevelX, mipLevelY, mipLevelZ);
     63 
     64 	case IMAGE_TYPE_CUBE:
     65 		return tcu::UVec3(mipLevelX, mipLevelY, 6u);
     66 
     67 	case IMAGE_TYPE_CUBE_ARRAY:
     68 		return tcu::UVec3(mipLevelX, mipLevelY, 6u * imageSize.z());
     69 
     70 	default:
     71 		DE_FATAL("Unknown image type");
     72 		return tcu::UVec3(1u, 1u, 1u);
     73 	}
     74 }
     75 
     76 tcu::UVec3 getLayerSize (const ImageType imageType, const tcu::UVec3& imageSize)
     77 {
     78 	switch (imageType)
     79 	{
     80 	case IMAGE_TYPE_1D:
     81 	case IMAGE_TYPE_1D_ARRAY:
     82 	case IMAGE_TYPE_BUFFER:
     83 		return tcu::UVec3(imageSize.x(), 1u, 1u);
     84 
     85 	case IMAGE_TYPE_2D:
     86 	case IMAGE_TYPE_2D_ARRAY:
     87 	case IMAGE_TYPE_CUBE:
     88 	case IMAGE_TYPE_CUBE_ARRAY:
     89 		return tcu::UVec3(imageSize.x(), imageSize.y(), 1u);
     90 
     91 	case IMAGE_TYPE_3D:
     92 		return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z());
     93 
     94 	default:
     95 		DE_FATAL("Unknown image type");
     96 		return tcu::UVec3(1u, 1u, 1u);
     97 	}
     98 }
     99 
    100 deUint32 getNumLayers (const ImageType imageType, const tcu::UVec3& imageSize)
    101 {
    102 	switch (imageType)
    103 	{
    104 	case IMAGE_TYPE_1D:
    105 	case IMAGE_TYPE_2D:
    106 	case IMAGE_TYPE_3D:
    107 	case IMAGE_TYPE_BUFFER:
    108 		return 1u;
    109 
    110 	case IMAGE_TYPE_1D_ARRAY:
    111 	case IMAGE_TYPE_2D_ARRAY:
    112 		return imageSize.z();
    113 
    114 	case IMAGE_TYPE_CUBE:
    115 		return 6u;
    116 
    117 	case IMAGE_TYPE_CUBE_ARRAY:
    118 		return imageSize.z() * 6u;
    119 
    120 	default:
    121 		DE_FATAL("Unknown image type");
    122 		return 0u;
    123 	}
    124 }
    125 
    126 deUint32 getNumPixels (const ImageType imageType, const tcu::UVec3& imageSize)
    127 {
    128 	const tcu::UVec3 gridSize = getShaderGridSize(imageType, imageSize);
    129 
    130 	return gridSize.x() * gridSize.y() * gridSize.z();
    131 }
    132 
    133 deUint32 getDimensions (const ImageType imageType)
    134 {
    135 	switch (imageType)
    136 	{
    137 	case IMAGE_TYPE_1D:
    138 	case IMAGE_TYPE_BUFFER:
    139 		return 1u;
    140 
    141 	case IMAGE_TYPE_1D_ARRAY:
    142 	case IMAGE_TYPE_2D:
    143 		return 2u;
    144 
    145 	case IMAGE_TYPE_2D_ARRAY:
    146 	case IMAGE_TYPE_CUBE:
    147 	case IMAGE_TYPE_CUBE_ARRAY:
    148 	case IMAGE_TYPE_3D:
    149 		return 3u;
    150 
    151 	default:
    152 		DE_FATAL("Unknown image type");
    153 		return 0u;
    154 	}
    155 }
    156 
    157 deUint32 getLayerDimensions (const ImageType imageType)
    158 {
    159 	switch (imageType)
    160 	{
    161 	case IMAGE_TYPE_1D:
    162 	case IMAGE_TYPE_BUFFER:
    163 	case IMAGE_TYPE_1D_ARRAY:
    164 		return 1u;
    165 
    166 	case IMAGE_TYPE_2D:
    167 	case IMAGE_TYPE_2D_ARRAY:
    168 	case IMAGE_TYPE_CUBE:
    169 	case IMAGE_TYPE_CUBE_ARRAY:
    170 		return 2u;
    171 
    172 	case IMAGE_TYPE_3D:
    173 		return 3u;
    174 
    175 	default:
    176 		DE_FATAL("Unknown image type");
    177 		return 0u;
    178 	}
    179 }
    180 
    181 bool isImageSizeSupported (const InstanceInterface& instance, const VkPhysicalDevice physicalDevice, const ImageType imageType, const tcu::UVec3& imageSize)
    182 {
    183 	const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
    184 
    185 	switch (imageType)
    186 	{
    187 		case IMAGE_TYPE_1D:
    188 			return	imageSize.x() <= deviceProperties.limits.maxImageDimension1D;
    189 		case IMAGE_TYPE_1D_ARRAY:
    190 			return	imageSize.x() <= deviceProperties.limits.maxImageDimension1D &&
    191 					imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
    192 		case IMAGE_TYPE_2D:
    193 			return	imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
    194 					imageSize.y() <= deviceProperties.limits.maxImageDimension2D;
    195 		case IMAGE_TYPE_2D_ARRAY:
    196 			return	imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
    197 					imageSize.y() <= deviceProperties.limits.maxImageDimension2D &&
    198 					imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
    199 		case IMAGE_TYPE_CUBE:
    200 			return	imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
    201 					imageSize.y() <= deviceProperties.limits.maxImageDimensionCube;
    202 		case IMAGE_TYPE_CUBE_ARRAY:
    203 			return	imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
    204 					imageSize.y() <= deviceProperties.limits.maxImageDimensionCube &&
    205 					imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
    206 		case IMAGE_TYPE_3D:
    207 			return	imageSize.x() <= deviceProperties.limits.maxImageDimension3D &&
    208 					imageSize.y() <= deviceProperties.limits.maxImageDimension3D &&
    209 					imageSize.z() <= deviceProperties.limits.maxImageDimension3D;
    210 		case IMAGE_TYPE_BUFFER:
    211 			return true;
    212 		default:
    213 			DE_FATAL("Unknown image type");
    214 			return false;
    215 	}
    216 }
    217 
    218 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize			bufferSize,
    219 										 const VkBufferUsageFlags	usage)
    220 {
    221 	const VkBufferCreateInfo bufferCreateInfo =
    222 	{
    223 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
    224 		DE_NULL,								// const void*			pNext;
    225 		0u,										// VkBufferCreateFlags	flags;
    226 		bufferSize,								// VkDeviceSize			size;
    227 		usage,									// VkBufferUsageFlags	usage;
    228 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
    229 		0u,										// deUint32				queueFamilyIndexCount;
    230 		DE_NULL,								// const deUint32*		pQueueFamilyIndices;
    231 	};
    232 	return bufferCreateInfo;
    233 }
    234 
    235 VkBufferImageCopy makeBufferImageCopy (const VkExtent3D		extent,
    236 									   const deUint32		layerCount,
    237 									   const deUint32		mipmapLevel,
    238 									   const VkDeviceSize	bufferOffset)
    239 {
    240 	const VkBufferImageCopy copyParams =
    241 	{
    242 		bufferOffset,																		//	VkDeviceSize				bufferOffset;
    243 		0u,																					//	deUint32					bufferRowLength;
    244 		0u,																					//	deUint32					bufferImageHeight;
    245 		makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, mipmapLevel, 0u, layerCount),	//	VkImageSubresourceLayers	imageSubresource;
    246 		makeOffset3D(0, 0, 0),																//	VkOffset3D					imageOffset;
    247 		extent,																				//	VkExtent3D					imageExtent;
    248 	};
    249 	return copyParams;
    250 }
    251 
    252 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
    253 {
    254 	const VkCommandPoolCreateInfo commandPoolParams =
    255 	{
    256 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// VkStructureType			sType;
    257 		DE_NULL,											// const void*				pNext;
    258 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// VkCommandPoolCreateFlags	flags;
    259 		queueFamilyIndex,									// deUint32					queueFamilyIndex;
    260 	};
    261 	return createCommandPool(vk, device, &commandPoolParams);
    262 }
    263 
    264 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
    265 {
    266 	const VkCommandBufferAllocateInfo bufferAllocateParams =
    267 	{
    268 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,		// VkStructureType			sType;
    269 		DE_NULL,											// const void*				pNext;
    270 		commandPool,										// VkCommandPool			commandPool;
    271 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,					// VkCommandBufferLevel		level;
    272 		1u,													// deUint32					bufferCount;
    273 	};
    274 	return allocateCommandBuffer(vk, device, &bufferAllocateParams);
    275 }
    276 
    277 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&		vk,
    278 										   const VkDevice				device,
    279 										   const VkDescriptorSetLayout	descriptorSetLayout)
    280 {
    281 	const VkPipelineLayoutCreateInfo pipelineLayoutParams =
    282 	{
    283 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,						// VkStructureType					sType;
    284 		DE_NULL,															// const void*						pNext;
    285 		0u,																	// VkPipelineLayoutCreateFlags		flags;
    286 		(descriptorSetLayout != DE_NULL ? 1u : 0u),							// deUint32							setLayoutCount;
    287 		(descriptorSetLayout != DE_NULL ? &descriptorSetLayout : DE_NULL),	// const VkDescriptorSetLayout*		pSetLayouts;
    288 		0u,																	// deUint32							pushConstantRangeCount;
    289 		DE_NULL,															// const VkPushConstantRange*		pPushConstantRanges;
    290 	};
    291 	return createPipelineLayout(vk, device, &pipelineLayoutParams);
    292 }
    293 
    294 Move<VkPipeline> makeComputePipeline (const DeviceInterface&		vk,
    295 									  const VkDevice				device,
    296 									  const VkPipelineLayout		pipelineLayout,
    297 									  const VkShaderModule			shaderModule,
    298 									  const VkSpecializationInfo*	specializationInfo)
    299 {
    300 	const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
    301 	{
    302 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
    303 		DE_NULL,												// const void*							pNext;
    304 		0u,														// VkPipelineShaderStageCreateFlags		flags;
    305 		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
    306 		shaderModule,											// VkShaderModule						module;
    307 		"main",													// const char*							pName;
    308 		specializationInfo,										// const VkSpecializationInfo*			pSpecializationInfo;
    309 	};
    310 	const VkComputePipelineCreateInfo pipelineCreateInfo =
    311 	{
    312 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,		// VkStructureType					sType;
    313 		DE_NULL,											// const void*						pNext;
    314 		0u,													// VkPipelineCreateFlags			flags;
    315 		pipelineShaderStageParams,							// VkPipelineShaderStageCreateInfo	stage;
    316 		pipelineLayout,										// VkPipelineLayout					layout;
    317 		DE_NULL,											// VkPipeline						basePipelineHandle;
    318 		0,													// deInt32							basePipelineIndex;
    319 	};
    320 	return createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo);
    321 }
    322 
    323 Move<VkBufferView> makeBufferView (const DeviceInterface&	vk,
    324 								   const VkDevice			vkDevice,
    325 								   const VkBuffer			buffer,
    326 								   const VkFormat			format,
    327 								   const VkDeviceSize		offset,
    328 								   const VkDeviceSize		size)
    329 {
    330 	const VkBufferViewCreateInfo bufferViewParams =
    331 	{
    332 		VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,	// VkStructureType			sType;
    333 		DE_NULL,									// const void*				pNext;
    334 		0u,											// VkBufferViewCreateFlags	flags;
    335 		buffer,										// VkBuffer					buffer;
    336 		format,										// VkFormat					format;
    337 		offset,										// VkDeviceSize				offset;
    338 		size,										// VkDeviceSize				range;
    339 	};
    340 	return createBufferView(vk, vkDevice, &bufferViewParams);
    341 }
    342 
    343 Move<VkImageView> makeImageView (const DeviceInterface&			vk,
    344 								 const VkDevice					vkDevice,
    345 								 const VkImage					image,
    346 								 const VkImageViewType			imageViewType,
    347 								 const VkFormat					format,
    348 								 const VkImageSubresourceRange	subresourceRange)
    349 {
    350 	const VkImageViewCreateInfo imageViewParams =
    351 	{
    352 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
    353 		DE_NULL,										// const void*				pNext;
    354 		0u,												// VkImageViewCreateFlags	flags;
    355 		image,											// VkImage					image;
    356 		imageViewType,									// VkImageViewType			viewType;
    357 		format,											// VkFormat					format;
    358 		makeComponentMappingRGBA(),						// VkComponentMapping		components;
    359 		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
    360 	};
    361 	return createImageView(vk, vkDevice, &imageViewParams);
    362 }
    363 
    364 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&			vk,
    365 										 const VkDevice					device,
    366 										 const VkDescriptorPool			descriptorPool,
    367 										 const VkDescriptorSetLayout	setLayout)
    368 {
    369 	const VkDescriptorSetAllocateInfo allocateParams =
    370 	{
    371 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType				sType;
    372 		DE_NULL,											// const void*					pNext;
    373 		descriptorPool,										// VkDescriptorPool				descriptorPool;
    374 		1u,													// deUint32						setLayoutCount;
    375 		&setLayout,											// const VkDescriptorSetLayout*	pSetLayouts;
    376 	};
    377 	return allocateDescriptorSet(vk, device, &allocateParams);
    378 }
    379 
    380 Move<VkSemaphore> makeSemaphore (const DeviceInterface& vk, const VkDevice device)
    381 {
    382 	const VkSemaphoreCreateInfo semaphoreCreateInfo =
    383 	{
    384 		VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
    385 		DE_NULL,
    386 		0u
    387 	};
    388 
    389 	return createSemaphore(vk, device, &semaphoreCreateInfo);
    390 }
    391 
    392 Move<VkFence> makeFence (const DeviceInterface& vk, const VkDevice device, const VkFenceCreateFlags flags)
    393 {
    394 	const VkFenceCreateInfo fenceCreateInfo =
    395 	{
    396 		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	// VkStructureType       sType;
    397 		DE_NULL,								// const void*           pNext;
    398 		flags,									// VkFenceCreateFlags    flags;
    399 	};
    400 	return createFence(vk, device, &fenceCreateInfo);
    401 }
    402 
    403 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface&		vk,
    404 									 const VkDevice				device,
    405 									 const VkRenderPass			renderPass,
    406 									 const deUint32				attachmentCount,
    407 									 const VkImageView*			pAttachments,
    408 									 const deUint32				width,
    409 									 const deUint32				height,
    410 									 const deUint32				layers)
    411 {
    412 	const VkFramebufferCreateInfo framebufferInfo =
    413 	{
    414 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType                             sType;
    415 		DE_NULL,										// const void*                                 pNext;
    416 		(VkFramebufferCreateFlags)0,					// VkFramebufferCreateFlags                    flags;
    417 		renderPass,										// VkRenderPass                                renderPass;
    418 		attachmentCount,								// uint32_t                                    attachmentCount;
    419 		pAttachments,									// const VkImageView*                          pAttachments;
    420 		width,											// uint32_t                                    width;
    421 		height,											// uint32_t                                    height;
    422 		layers,											// uint32_t                                    layers;
    423 	};
    424 
    425 	return createFramebuffer(vk, device, &framebufferInfo);
    426 }
    427 
    428 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags	srcAccessMask,
    429 											   const VkAccessFlags	dstAccessMask,
    430 											   const VkBuffer		buffer,
    431 											   const VkDeviceSize	offset,
    432 											   const VkDeviceSize	bufferSizeBytes)
    433 {
    434 	const VkBufferMemoryBarrier barrier =
    435 	{
    436 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
    437 		DE_NULL,									// const void*		pNext;
    438 		srcAccessMask,								// VkAccessFlags	srcAccessMask;
    439 		dstAccessMask,								// VkAccessFlags	dstAccessMask;
    440 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
    441 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			destQueueFamilyIndex;
    442 		buffer,										// VkBuffer			buffer;
    443 		offset,										// VkDeviceSize		offset;
    444 		bufferSizeBytes,							// VkDeviceSize		size;
    445 	};
    446 	return barrier;
    447 }
    448 
    449 VkImageMemoryBarrier makeImageMemoryBarrier	(const VkAccessFlags			srcAccessMask,
    450 											 const VkAccessFlags			dstAccessMask,
    451 											 const VkImageLayout			oldLayout,
    452 											 const VkImageLayout			newLayout,
    453 											 const VkImage					image,
    454 											 const VkImageSubresourceRange	subresourceRange)
    455 {
    456 	const VkImageMemoryBarrier barrier =
    457 	{
    458 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
    459 		DE_NULL,								// const void*				pNext;
    460 		srcAccessMask,							// VkAccessFlags			outputMask;
    461 		dstAccessMask,							// VkAccessFlags			inputMask;
    462 		oldLayout,								// VkImageLayout			oldLayout;
    463 		newLayout,								// VkImageLayout			newLayout;
    464 		VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
    465 		VK_QUEUE_FAMILY_IGNORED,				// deUint32					destQueueFamilyIndex;
    466 		image,									// VkImage					image;
    467 		subresourceRange,						// VkImageSubresourceRange	subresourceRange;
    468 	};
    469 	return barrier;
    470 }
    471 
    472 VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags			srcAccessMask,
    473 											 const VkAccessFlags			dstAccessMask,
    474 											 const VkImageLayout			oldLayout,
    475 											 const VkImageLayout			newLayout,
    476 											 const deUint32					srcQueueFamilyIndex,
    477 											 const deUint32					destQueueFamilyIndex,
    478 											 const VkImage					image,
    479 											 const VkImageSubresourceRange	subresourceRange)
    480 {
    481 	const VkImageMemoryBarrier barrier =
    482 	{
    483 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
    484 		DE_NULL,								// const void*				pNext;
    485 		srcAccessMask,							// VkAccessFlags			outputMask;
    486 		dstAccessMask,							// VkAccessFlags			inputMask;
    487 		oldLayout,								// VkImageLayout			oldLayout;
    488 		newLayout,								// VkImageLayout			newLayout;
    489 		srcQueueFamilyIndex,					// deUint32					srcQueueFamilyIndex;
    490 		destQueueFamilyIndex,					// deUint32					destQueueFamilyIndex;
    491 		image,									// VkImage					image;
    492 		subresourceRange,						// VkImageSubresourceRange	subresourceRange;
    493 	};
    494 	return barrier;
    495 }
    496 
    497 VkMemoryBarrier makeMemoryBarrier (const VkAccessFlags	srcAccessMask,
    498 									   const VkAccessFlags	dstAccessMask)
    499 {
    500 	const VkMemoryBarrier barrier =
    501 	{
    502 		VK_STRUCTURE_TYPE_MEMORY_BARRIER,	// VkStructureType			sType;
    503 		DE_NULL,							// const void*				pNext;
    504 		srcAccessMask,						// VkAccessFlags			outputMask;
    505 		dstAccessMask,						// VkAccessFlags			inputMask;
    506 	};
    507 	return barrier;
    508 }
    509 
    510 de::MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
    511 {
    512 	de::MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
    513 	VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
    514 	return alloc;
    515 }
    516 
    517 de::MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
    518 {
    519 	de::MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
    520 	VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
    521 	return alloc;
    522 }
    523 
    524 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
    525 {
    526 	const VkCommandBufferBeginInfo commandBufBeginParams =
    527 	{
    528 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
    529 		DE_NULL,										// const void*						pNext;
    530 		0u,												// VkCommandBufferUsageFlags		flags;
    531 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
    532 	};
    533 	VK_CHECK(vk.beginCommandBuffer(commandBuffer, &commandBufBeginParams));
    534 }
    535 
    536 void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
    537 {
    538 	VK_CHECK(vk.endCommandBuffer(commandBuffer));
    539 }
    540 
    541 void submitCommands (const DeviceInterface&			vk,
    542 					 const VkQueue					queue,
    543 					 const VkCommandBuffer			commandBuffer,
    544 					 const deUint32					waitSemaphoreCount,
    545 					 const VkSemaphore*				pWaitSemaphores,
    546 					 const VkPipelineStageFlags*	pWaitDstStageMask,
    547 					 const deUint32					signalSemaphoreCount,
    548 					 const VkSemaphore*				pSignalSemaphores)
    549 {
    550 	const VkSubmitInfo submitInfo =
    551 	{
    552 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType				sType;
    553 		DE_NULL,						// const void*					pNext;
    554 		waitSemaphoreCount,				// deUint32						waitSemaphoreCount;
    555 		pWaitSemaphores,				// const VkSemaphore*			pWaitSemaphores;
    556 		pWaitDstStageMask,				// const VkPipelineStageFlags*	pWaitDstStageMask;
    557 		1u,								// deUint32						commandBufferCount;
    558 		&commandBuffer,					// const VkCommandBuffer*		pCommandBuffers;
    559 		signalSemaphoreCount,			// deUint32						signalSemaphoreCount;
    560 		pSignalSemaphores,				// const VkSemaphore*			pSignalSemaphores;
    561 	};
    562 
    563 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
    564 }
    565 
    566 void submitCommandsAndWait (const DeviceInterface&		vk,
    567 							const VkDevice				device,
    568 							const VkQueue				queue,
    569 							const VkCommandBuffer		commandBuffer,
    570 							const deUint32				waitSemaphoreCount,
    571 							const VkSemaphore*			pWaitSemaphores,
    572 							const VkPipelineStageFlags*	pWaitDstStageMask,
    573 							const deUint32				signalSemaphoreCount,
    574 							const VkSemaphore*			pSignalSemaphores)
    575 {
    576 	const VkFenceCreateInfo	fenceParams =
    577 	{
    578 		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	// VkStructureType		sType;
    579 		DE_NULL,								// const void*			pNext;
    580 		0u,										// VkFenceCreateFlags	flags;
    581 	};
    582 	const Unique<VkFence> fence(createFence(vk, device, &fenceParams));
    583 
    584 	const VkSubmitInfo submitInfo =
    585 	{
    586 		VK_STRUCTURE_TYPE_SUBMIT_INFO,		// VkStructureType				sType;
    587 		DE_NULL,							// const void*					pNext;
    588 		waitSemaphoreCount,					// deUint32						waitSemaphoreCount;
    589 		pWaitSemaphores,					// const VkSemaphore*			pWaitSemaphores;
    590 		pWaitDstStageMask,					// const VkPipelineStageFlags*	pWaitDstStageMask;
    591 		1u,									// deUint32						commandBufferCount;
    592 		&commandBuffer,						// const VkCommandBuffer*		pCommandBuffers;
    593 		signalSemaphoreCount,				// deUint32						signalSemaphoreCount;
    594 		pSignalSemaphores,					// const VkSemaphore*			pSignalSemaphores;
    595 	};
    596 
    597 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
    598 	VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
    599 }
    600 
    601 VkImageType	mapImageType (const ImageType imageType)
    602 {
    603 	switch (imageType)
    604 	{
    605 		case IMAGE_TYPE_1D:
    606 		case IMAGE_TYPE_1D_ARRAY:
    607 		case IMAGE_TYPE_BUFFER:
    608 			return VK_IMAGE_TYPE_1D;
    609 
    610 		case IMAGE_TYPE_2D:
    611 		case IMAGE_TYPE_2D_ARRAY:
    612 		case IMAGE_TYPE_CUBE:
    613 		case IMAGE_TYPE_CUBE_ARRAY:
    614 			return VK_IMAGE_TYPE_2D;
    615 
    616 		case IMAGE_TYPE_3D:
    617 			return VK_IMAGE_TYPE_3D;
    618 
    619 		default:
    620 			DE_ASSERT(false);
    621 			return VK_IMAGE_TYPE_LAST;
    622 	}
    623 }
    624 
    625 VkImageViewType	mapImageViewType (const ImageType imageType)
    626 {
    627 	switch (imageType)
    628 	{
    629 		case IMAGE_TYPE_1D:			return VK_IMAGE_VIEW_TYPE_1D;
    630 		case IMAGE_TYPE_1D_ARRAY:	return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
    631 		case IMAGE_TYPE_2D:			return VK_IMAGE_VIEW_TYPE_2D;
    632 		case IMAGE_TYPE_2D_ARRAY:	return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
    633 		case IMAGE_TYPE_3D:			return VK_IMAGE_VIEW_TYPE_3D;
    634 		case IMAGE_TYPE_CUBE:		return VK_IMAGE_VIEW_TYPE_CUBE;
    635 		case IMAGE_TYPE_CUBE_ARRAY:	return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
    636 
    637 		default:
    638 			DE_ASSERT(false);
    639 			return VK_IMAGE_VIEW_TYPE_LAST;
    640 	}
    641 }
    642 
    643 std::string getImageTypeName (const ImageType imageType)
    644 {
    645 	switch (imageType)
    646 	{
    647 		case IMAGE_TYPE_1D:			return "1d";
    648 		case IMAGE_TYPE_1D_ARRAY:	return "1d_array";
    649 		case IMAGE_TYPE_2D:			return "2d";
    650 		case IMAGE_TYPE_2D_ARRAY:	return "2d_array";
    651 		case IMAGE_TYPE_3D:			return "3d";
    652 		case IMAGE_TYPE_CUBE:		return "cube";
    653 		case IMAGE_TYPE_CUBE_ARRAY:	return "cube_array";
    654 		case IMAGE_TYPE_BUFFER:		return "buffer";
    655 
    656 		default:
    657 			DE_ASSERT(false);
    658 			return "";
    659 	}
    660 }
    661 
    662 std::string getShaderImageType (const tcu::TextureFormat& format, const ImageType imageType)
    663 {
    664 	std::string formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" :
    665 							 tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER   ? "i" : "";
    666 
    667 	std::string imageTypePart;
    668 	switch (imageType)
    669 	{
    670 		case IMAGE_TYPE_1D:			imageTypePart = "1D";			break;
    671 		case IMAGE_TYPE_1D_ARRAY:	imageTypePart = "1DArray";		break;
    672 		case IMAGE_TYPE_2D:			imageTypePart = "2D";			break;
    673 		case IMAGE_TYPE_2D_ARRAY:	imageTypePart = "2DArray";		break;
    674 		case IMAGE_TYPE_3D:			imageTypePart = "3D";			break;
    675 		case IMAGE_TYPE_CUBE:		imageTypePart = "Cube";			break;
    676 		case IMAGE_TYPE_CUBE_ARRAY:	imageTypePart = "CubeArray";	break;
    677 		case IMAGE_TYPE_BUFFER:		imageTypePart = "Buffer";		break;
    678 
    679 		default:
    680 			DE_ASSERT(false);
    681 	}
    682 
    683 	return formatPart + "image" + imageTypePart;
    684 }
    685 
    686 
    687 std::string getShaderImageDataType(const tcu::TextureFormat& format)
    688 {
    689 	switch (tcu::getTextureChannelClass(format.type))
    690 	{
    691 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
    692 			return "uvec4";
    693 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
    694 			return "ivec4";
    695 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
    696 			return "vec4";
    697 		default:
    698 			DE_ASSERT(false);
    699 			return "";
    700 	}
    701 }
    702 
    703 
    704 std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format)
    705 {
    706 	const char* orderPart;
    707 	const char* typePart;
    708 
    709 	switch (format.order)
    710 	{
    711 		case tcu::TextureFormat::R:		orderPart = "r";	break;
    712 		case tcu::TextureFormat::RG:	orderPart = "rg";	break;
    713 		case tcu::TextureFormat::RGB:	orderPart = "rgb";	break;
    714 		case tcu::TextureFormat::RGBA:	orderPart = "rgba";	break;
    715 
    716 		default:
    717 			DE_ASSERT(false);
    718 			orderPart = DE_NULL;
    719 	}
    720 
    721 	switch (format.type)
    722 	{
    723 		case tcu::TextureFormat::FLOAT:				typePart = "32f";		break;
    724 		case tcu::TextureFormat::HALF_FLOAT:		typePart = "16f";		break;
    725 
    726 		case tcu::TextureFormat::UNSIGNED_INT32:	typePart = "32ui";		break;
    727 		case tcu::TextureFormat::UNSIGNED_INT16:	typePart = "16ui";		break;
    728 		case tcu::TextureFormat::UNSIGNED_INT8:		typePart = "8ui";		break;
    729 
    730 		case tcu::TextureFormat::SIGNED_INT32:		typePart = "32i";		break;
    731 		case tcu::TextureFormat::SIGNED_INT16:		typePart = "16i";		break;
    732 		case tcu::TextureFormat::SIGNED_INT8:		typePart = "8i";		break;
    733 
    734 		case tcu::TextureFormat::UNORM_INT16:		typePart = "16";		break;
    735 		case tcu::TextureFormat::UNORM_INT8:		typePart = "8";			break;
    736 
    737 		case tcu::TextureFormat::SNORM_INT16:		typePart = "16_snorm";	break;
    738 		case tcu::TextureFormat::SNORM_INT8:		typePart = "8_snorm";	break;
    739 
    740 		default:
    741 			DE_ASSERT(false);
    742 			typePart = DE_NULL;
    743 	}
    744 
    745 	return std::string() + orderPart + typePart;
    746 }
    747 
    748 std::string getShaderImageCoordinates	(const ImageType	imageType,
    749 										 const std::string&	x,
    750 										 const std::string&	xy,
    751 										 const std::string&	xyz)
    752 {
    753 	switch (imageType)
    754 	{
    755 		case IMAGE_TYPE_1D:
    756 		case IMAGE_TYPE_BUFFER:
    757 			return x;
    758 
    759 		case IMAGE_TYPE_1D_ARRAY:
    760 		case IMAGE_TYPE_2D:
    761 			return xy;
    762 
    763 		case IMAGE_TYPE_2D_ARRAY:
    764 		case IMAGE_TYPE_3D:
    765 		case IMAGE_TYPE_CUBE:
    766 		case IMAGE_TYPE_CUBE_ARRAY:
    767 			return xyz;
    768 
    769 		default:
    770 			DE_ASSERT(0);
    771 			return "";
    772 	}
    773 }
    774 
    775 VkExtent3D mipLevelExtents (const VkExtent3D& baseExtents, const deUint32 mipLevel)
    776 {
    777 	VkExtent3D result;
    778 
    779 	result.width	= std::max(baseExtents.width  >> mipLevel, 1u);
    780 	result.height	= std::max(baseExtents.height >> mipLevel, 1u);
    781 	result.depth	= std::max(baseExtents.depth  >> mipLevel, 1u);
    782 
    783 	return result;
    784 }
    785 
    786 deUint32 getImageMaxMipLevels (const VkImageFormatProperties& imageFormatProperties, const VkExtent3D& extent)
    787 {
    788 	const deUint32 widestEdge = std::max(std::max(extent.width, extent.height), extent.depth);
    789 
    790 	return std::min(static_cast<deUint32>(deFloatLog2(static_cast<float>(widestEdge))) + 1u, imageFormatProperties.maxMipLevels);
    791 }
    792 
    793 deUint32 getImageMipLevelSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
    794 {
    795 	const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
    796 
    797 	return deAlign32(extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format), mipmapMemoryAlignment);
    798 }
    799 
    800 deUint32 getImageSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment)
    801 {
    802 	deUint32 imageSizeInBytes = 0;
    803 	for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
    804 		imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, mipmapMemoryAlignment);
    805 
    806 	return imageSizeInBytes;
    807 }
    808 
    809 VkSparseImageMemoryBind	makeSparseImageMemoryBind  (const DeviceInterface&		vk,
    810 													const VkDevice				device,
    811 													const VkDeviceSize			allocationSize,
    812 													const deUint32				memoryType,
    813 													const VkImageSubresource&	subresource,
    814 													const VkOffset3D&			offset,
    815 													const VkExtent3D&			extent)
    816 {
    817 	const VkMemoryAllocateInfo	allocInfo =
    818 	{
    819 		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType			sType;
    820 		DE_NULL,								//	const void*				pNext;
    821 		allocationSize,							//	VkDeviceSize			allocationSize;
    822 		memoryType,								//	deUint32				memoryTypeIndex;
    823 	};
    824 
    825 	VkDeviceMemory deviceMemory = 0;
    826 	VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
    827 
    828 	VkSparseImageMemoryBind imageMemoryBind;
    829 
    830 	imageMemoryBind.subresource		= subresource;
    831 	imageMemoryBind.memory			= deviceMemory;
    832 	imageMemoryBind.memoryOffset	= 0u;
    833 	imageMemoryBind.flags			= 0u;
    834 	imageMemoryBind.offset			= offset;
    835 	imageMemoryBind.extent			= extent;
    836 
    837 	return imageMemoryBind;
    838 }
    839 
    840 VkSparseMemoryBind makeSparseMemoryBind	(const DeviceInterface&	vk,
    841 										 const VkDevice			device,
    842 										 const VkDeviceSize		allocationSize,
    843 										 const deUint32			memoryType,
    844 										 const VkDeviceSize		resourceOffset)
    845 {
    846 	const VkMemoryAllocateInfo allocInfo =
    847 	{
    848 		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType	sType;
    849 		DE_NULL,								//	const void*		pNext;
    850 		allocationSize,							//	VkDeviceSize	allocationSize;
    851 		memoryType,								//	deUint32		memoryTypeIndex;
    852 	};
    853 
    854 	VkDeviceMemory deviceMemory = 0;
    855 	VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
    856 
    857 	VkSparseMemoryBind memoryBind;
    858 
    859 	memoryBind.resourceOffset	= resourceOffset;
    860 	memoryBind.size				= allocationSize;
    861 	memoryBind.memory			= deviceMemory;
    862 	memoryBind.memoryOffset		= 0u;
    863 	memoryBind.flags			= 0u;
    864 
    865 	return memoryBind;
    866 }
    867 
    868 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
    869 {
    870 	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
    871 
    872 	if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
    873 		throw tcu::NotSupportedError("Tessellation shader not supported");
    874 
    875 	if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
    876 		throw tcu::NotSupportedError("Geometry shader not supported");
    877 
    878 	if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
    879 		throw tcu::NotSupportedError("Double-precision floats not supported");
    880 
    881 	if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
    882 		throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
    883 
    884 	if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
    885 		throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
    886 
    887 	if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
    888 		throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
    889 }
    890 
    891 deUint32 findMatchingMemoryType (const InstanceInterface&		instance,
    892 								 const VkPhysicalDevice			physicalDevice,
    893 								 const VkMemoryRequirements&	objectMemoryRequirements,
    894 								 const MemoryRequirement&		memoryRequirement)
    895 {
    896 	const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
    897 
    898 	for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx)
    899 	{
    900 		if ((objectMemoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 &&
    901 			memoryRequirement.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags))
    902 		{
    903 			return memoryTypeNdx;
    904 		}
    905 	}
    906 
    907 	return NO_MATCH_FOUND;
    908 }
    909 
    910 bool checkSparseSupportForImageType (const InstanceInterface&	instance,
    911 									 const VkPhysicalDevice		physicalDevice,
    912 									 const ImageType			imageType)
    913 {
    914 	const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice);
    915 
    916 	if (!deviceFeatures.sparseBinding)
    917 		return false;
    918 
    919 	switch (mapImageType(imageType))
    920 	{
    921 		case VK_IMAGE_TYPE_2D:
    922 			return deviceFeatures.sparseResidencyImage2D == VK_TRUE;
    923 		case VK_IMAGE_TYPE_3D:
    924 			return deviceFeatures.sparseResidencyImage3D == VK_TRUE;
    925 		default:
    926 			DE_ASSERT(0);
    927 			return false;
    928 	};
    929 }
    930 
    931 bool checkSparseSupportForImageFormat (const InstanceInterface&	instance,
    932 									   const VkPhysicalDevice	physicalDevice,
    933 									   const VkImageCreateInfo&	imageInfo)
    934 {
    935 	const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties(
    936 		instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling);
    937 
    938 	return sparseImageFormatPropVec.size() > 0u;
    939 }
    940 
    941 bool checkImageFormatFeatureSupport (const InstanceInterface&	instance,
    942 									 const VkPhysicalDevice		physicalDevice,
    943 									 const VkFormat				format,
    944 									 const VkFormatFeatureFlags	featureFlags)
    945 {
    946 	const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format);
    947 
    948 	return (formatProperties.optimalTilingFeatures & featureFlags) == featureFlags;
    949 }
    950 
    951 deUint32 getSparseAspectRequirementsIndex (const std::vector<VkSparseImageMemoryRequirements>&	requirements,
    952 										   const VkImageAspectFlags								aspectFlags)
    953 {
    954 	for (deUint32 memoryReqNdx = 0; memoryReqNdx < requirements.size(); ++memoryReqNdx)
    955 	{
    956 		if (requirements[memoryReqNdx].formatProperties.aspectMask & aspectFlags)
    957 			return memoryReqNdx;
    958 	}
    959 
    960 	return NO_MATCH_FOUND;
    961 }
    962 
    963 } // sparse
    964 } // vkt
    965