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