Home | History | Annotate | Download | only in api
      1 /*------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2015-2016 The Khronos Group Inc.
      6  * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd.
      7  *
      8  * Licensed under the Apache License, Version 2.0 (the "License");
      9  * you may not use this file except in compliance with the License.
     10  * You may obtain a copy of the License at
     11  *
     12  *      http://www.apache.org/licenses/LICENSE-2.0
     13  *
     14  * Unless required by applicable law or agreed to in writing, software
     15  * distributed under the License is distributed on an "AS IS" BASIS,
     16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     17  * See the License for the specific language governing permissions and
     18  * limitations under the License.
     19  *
     20  *//*!
     21  * \file
     22  * \brief Vulkan Copies And Blitting Tests
     23  *//*--------------------------------------------------------------------*/
     24 
     25 #include "vktApiCopiesAndBlittingTests.hpp"
     26 
     27 #include "deStringUtil.hpp"
     28 #include "deUniquePtr.hpp"
     29 
     30 #include "tcuImageCompare.hpp"
     31 #include "tcuTexture.hpp"
     32 #include "tcuTextureUtil.hpp"
     33 #include "tcuVectorType.hpp"
     34 #include "tcuVectorUtil.hpp"
     35 #include "tcuTestLog.hpp"
     36 #include "tcuTexLookupVerifier.hpp"
     37 
     38 #include "vkImageUtil.hpp"
     39 #include "vkMemUtil.hpp"
     40 #include "vkPrograms.hpp"
     41 #include "vkQueryUtil.hpp"
     42 #include "vkRefUtil.hpp"
     43 #include "vktTestCase.hpp"
     44 #include "vktTestCaseUtil.hpp"
     45 #include "vktTestGroupUtil.hpp"
     46 #include "vkTypeUtil.hpp"
     47 
     48 #include <set>
     49 
     50 namespace vkt
     51 {
     52 
     53 namespace api
     54 {
     55 
     56 namespace
     57 {
     58 enum MirrorMode
     59 {
     60 	MIRROR_MODE_NONE = 0,
     61 	MIRROR_MODE_X = (1<<0),
     62 	MIRROR_MODE_Y = (1<<1),
     63 	MIRROR_MODE_XY = MIRROR_MODE_X | MIRROR_MODE_Y,
     64 
     65 	MIRROR_MODE_LAST
     66 };
     67 
     68 enum AllocationKind
     69 {
     70 	ALLOCATION_KIND_SUBALLOCATED,
     71 	ALLOCATION_KIND_DEDICATED,
     72 };
     73 
     74 template <typename Type>
     75 class BinaryCompare
     76 {
     77 public:
     78 	bool operator() (const Type& a, const Type& b) const
     79 	{
     80 		return deMemCmp(&a, &b, sizeof(Type)) < 0;
     81 	}
     82 };
     83 
     84 typedef std::set<vk::VkFormat, BinaryCompare<vk::VkFormat> >	FormatSet;
     85 
     86 FormatSet dedicatedAllocationImageToImageFormatsToTestSet;
     87 FormatSet dedicatedAllocationBlittingFormatsToTestSet;
     88 
     89 using namespace vk;
     90 
     91 VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
     92 {
     93 	VkImageAspectFlags	aspectFlag	= 0;
     94 	aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
     95 	aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
     96 
     97 	if (!aspectFlag)
     98 		aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
     99 
    100 	return aspectFlag;
    101 }
    102 
    103 // This is effectively same as vk::isFloatFormat(mapTextureFormat(format))
    104 // except that it supports some formats that are not mappable to VkFormat.
    105 // When we are checking combined depth and stencil formats, each aspect is
    106 // checked separately, and in some cases we construct PBA with a format that
    107 // is not mappable to VkFormat.
    108 bool isFloatFormat (tcu::TextureFormat format)
    109 {
    110 	return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
    111 }
    112 
    113 union CopyRegion
    114 {
    115 	VkBufferCopy		bufferCopy;
    116 	VkImageCopy			imageCopy;
    117 	VkBufferImageCopy	bufferImageCopy;
    118 	VkImageBlit			imageBlit;
    119 	VkImageResolve		imageResolve;
    120 };
    121 
    122 struct ImageParms
    123 {
    124 	VkImageType		imageType;
    125 	VkFormat		format;
    126 	VkExtent3D		extent;
    127 	VkImageLayout	operationLayout;
    128 };
    129 
    130 struct TestParams
    131 {
    132 	union Data
    133 	{
    134 		struct Buffer
    135 		{
    136 			VkDeviceSize	size;
    137 		} buffer;
    138 
    139 		ImageParms	image;
    140 	} src, dst;
    141 
    142 	std::vector<CopyRegion>	regions;
    143 
    144 	union
    145 	{
    146 		VkFilter				filter;
    147 		VkSampleCountFlagBits	samples;
    148 	};
    149 
    150 	AllocationKind	allocationKind;
    151 	deUint32		mipLevels;
    152 	deBool			singleCommand;
    153 
    154 	TestParams (void)
    155 	{
    156 		mipLevels		= 1u;
    157 		singleCommand	= DE_TRUE;
    158 	}
    159 };
    160 
    161 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface&	vki,
    162 										const DeviceInterface&		vkd,
    163 										const VkPhysicalDevice&		physDevice,
    164 										const VkDevice				device,
    165 										const VkBuffer&				buffer,
    166 										const MemoryRequirement		requirement,
    167 										Allocator&					allocator,
    168 										AllocationKind				allocationKind)
    169 {
    170 	switch (allocationKind)
    171 	{
    172 		case ALLOCATION_KIND_SUBALLOCATED:
    173 		{
    174 			const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
    175 
    176 			return allocator.allocate(memoryRequirements, requirement);
    177 		}
    178 
    179 		case ALLOCATION_KIND_DEDICATED:
    180 		{
    181 			return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
    182 		}
    183 
    184 		default:
    185 		{
    186 			TCU_THROW(InternalError, "Invalid allocation kind");
    187 		}
    188 	}
    189 }
    190 
    191 de::MovePtr<Allocation> allocateImage (const InstanceInterface&		vki,
    192 									   const DeviceInterface&		vkd,
    193 									   const VkPhysicalDevice&		physDevice,
    194 									   const VkDevice				device,
    195 									   const VkImage&				image,
    196 									   const MemoryRequirement		requirement,
    197 									   Allocator&					allocator,
    198 									   AllocationKind				allocationKind)
    199 {
    200 	switch (allocationKind)
    201 	{
    202 		case ALLOCATION_KIND_SUBALLOCATED:
    203 		{
    204 			const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
    205 
    206 			return allocator.allocate(memoryRequirements, requirement);
    207 		}
    208 
    209 		case ALLOCATION_KIND_DEDICATED:
    210 		{
    211 			return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
    212 		}
    213 
    214 		default:
    215 		{
    216 			TCU_THROW(InternalError, "Invalid allocation kind");
    217 		}
    218 	}
    219 }
    220 
    221 
    222 inline deUint32 getArraySize(const ImageParms& parms)
    223 {
    224 	return (parms.imageType == VK_IMAGE_TYPE_2D) ? parms.extent.depth : 1u;
    225 }
    226 
    227 inline VkExtent3D getExtent3D(const ImageParms& parms)
    228 {
    229 	const VkExtent3D		extent					=
    230 	{
    231 		parms.extent.width,
    232 		parms.extent.height,
    233 		(parms.imageType == VK_IMAGE_TYPE_2D) ? 1u : parms.extent.depth
    234 	};
    235 	return extent;
    236 }
    237 
    238 const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat)
    239 {
    240 	tcu::TextureFormat format;
    241 	switch (combinedFormat.type)
    242 	{
    243 		case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
    244 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
    245 			break;
    246 		case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
    247 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
    248 			break;
    249 		case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
    250 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
    251 			break;
    252 		default:
    253 			DE_ASSERT(false);
    254 			break;
    255 	}
    256 	return format;
    257 }
    258 
    259 class CopiesAndBlittingTestInstance : public vkt::TestInstance
    260 {
    261 public:
    262 										CopiesAndBlittingTestInstance		(Context&	context,
    263 																			 TestParams	testParams);
    264 	virtual tcu::TestStatus				iterate								(void) = 0;
    265 
    266 	enum FillMode
    267 	{
    268 		FILL_MODE_GRADIENT = 0,
    269 		FILL_MODE_WHITE,
    270 		FILL_MODE_RED,
    271 		FILL_MODE_MULTISAMPLE,
    272 
    273 		FILL_MODE_LAST
    274 	};
    275 
    276 protected:
    277 	const TestParams					m_params;
    278 
    279 	Move<VkCommandPool>					m_cmdPool;
    280 	Move<VkCommandBuffer>				m_cmdBuffer;
    281 	Move<VkFence>						m_fence;
    282 	de::MovePtr<tcu::TextureLevel>		m_sourceTextureLevel;
    283 	de::MovePtr<tcu::TextureLevel>		m_destinationTextureLevel;
    284 	de::MovePtr<tcu::TextureLevel>		m_expectedTextureLevel[16];
    285 
    286 	VkCommandBufferBeginInfo			m_cmdBufferBeginInfo;
    287 
    288 	void								generateBuffer						(tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT);
    289 	virtual void						generateExpectedResult				(void);
    290 	void								uploadBuffer						(tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc);
    291 	void								uploadImage							(const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels = 1u);
    292 	virtual tcu::TestStatus				checkTestResult						(tcu::ConstPixelBufferAccess result);
    293 	virtual void						copyRegionToTextureLevel			(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) = 0;
    294 	deUint32							calculateSize						(tcu::ConstPixelBufferAccess src) const
    295 										{
    296 											return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
    297 										}
    298 
    299 	de::MovePtr<tcu::TextureLevel>		readImage							(vk::VkImage				image,
    300 																			 const ImageParms&			imageParms,
    301 																			 const deUint32				mipLevel = 0u);
    302 	void								submitCommandsAndWait				(const DeviceInterface&		vk,
    303 																			const VkDevice				device,
    304 																			const VkQueue				queue,
    305 																			const VkCommandBuffer&		cmdBuffer);
    306 
    307 private:
    308 	void								uploadImageAspect					(const tcu::ConstPixelBufferAccess&	src,
    309 																			 const VkImage&						dst,
    310 																			 const ImageParms&					parms,
    311 																			 const deUint32						mipLevels = 1u);
    312 	void								readImageAspect						(vk::VkImage						src,
    313 																			 const tcu::PixelBufferAccess&		dst,
    314 																			 const ImageParms&					parms,
    315 																			 const deUint32						mipLevel = 0u);
    316 };
    317 
    318 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams)
    319 	: vkt::TestInstance	(context)
    320 	, m_params			(testParams)
    321 {
    322 	const DeviceInterface&		vk					= context.getDeviceInterface();
    323 	const VkDevice				vkDevice			= context.getDevice();
    324 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
    325 
    326 	if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
    327 	{
    328 		if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_dedicated_allocation"))
    329 			TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
    330 	}
    331 
    332 	// Create command pool
    333 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
    334 
    335 	// Create command buffer
    336 	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
    337 
    338 	// Create fence
    339 	m_fence = createFence(vk, vkDevice);
    340 }
    341 
    342 void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
    343 {
    344 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(buffer.getFormat().type);
    345 	tcu::Vec4						maxValue		(1.0f);
    346 
    347 	if (buffer.getFormat().order == tcu::TextureFormat::S)
    348 	{
    349 		// Stencil-only is stored in the first component. Stencil is always 8 bits.
    350 		maxValue.x() = 1 << 8;
    351 	}
    352 	else if (buffer.getFormat().order == tcu::TextureFormat::DS)
    353 	{
    354 		// In a combined format, fillWithComponentGradients expects stencil in the fourth component.
    355 		maxValue.w() = 1 << 8;
    356 	}
    357 	else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
    358 	{
    359 		// The tcu::Vectors we use as pixels are 32-bit, so clamp to that.
    360 		const tcu::IVec4	bits	= tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32));
    361 		const int			signBit	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);
    362 
    363 		for (int i = 0; i < 4; ++i)
    364 		{
    365 			if (bits[i] != 0)
    366 				maxValue[i] = static_cast<float>((deUint64(1) << (bits[i] - signBit)) - 1);
    367 		}
    368 	}
    369 
    370 	if (mode == FILL_MODE_GRADIENT)
    371 	{
    372 		tcu::fillWithComponentGradients(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
    373 		return;
    374 	}
    375 
    376 	const tcu::Vec4		redColor	(maxValue.x(),	0.0,			0.0,			maxValue.w());
    377 	const tcu::Vec4		greenColor	(0.0,			maxValue.y(),	0.0,			maxValue.w());
    378 	const tcu::Vec4		blueColor	(0.0,			0.0,			maxValue.z(),	maxValue.w());
    379 	const tcu::Vec4		whiteColor	(maxValue.x(),	maxValue.y(),	maxValue.z(),	maxValue.w());
    380 
    381 	for (int z = 0; z < depth;  ++z)
    382 	for (int y = 0; y < height; ++y)
    383 	for (int x = 0; x < width;  ++x)
    384 	{
    385 		switch (mode)
    386 		{
    387 			case FILL_MODE_WHITE:
    388 				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
    389 				{
    390 					buffer.setPixDepth(1.0f, x, y, z);
    391 					if (tcu::hasStencilComponent(buffer.getFormat().order))
    392 						buffer.setPixStencil(255, x, y, z);
    393 				}
    394 				else
    395 					buffer.setPixel(whiteColor, x, y, z);
    396 				break;
    397 
    398 			case FILL_MODE_RED:
    399 				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
    400 				{
    401 					buffer.setPixDepth(redColor[0], x, y, z);
    402 					if (tcu::hasStencilComponent(buffer.getFormat().order))
    403 						buffer.setPixStencil((int)redColor[3], x, y, z);
    404 				}
    405 				else
    406 					buffer.setPixel(redColor, x, y, z);
    407 				break;
    408 
    409 			case FILL_MODE_MULTISAMPLE:
    410 			{
    411 				float xScaled = static_cast<float>(x) / static_cast<float>(width);
    412 				float yScaled = static_cast<float>(y) / static_cast<float>(height);
    413 				buffer.setPixel((xScaled == yScaled) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((xScaled > yScaled) ? greenColor : blueColor), x, y, z);
    414 				break;
    415 			}
    416 
    417 			default:
    418 				break;
    419 		}
    420 	}
    421 }
    422 
    423 void CopiesAndBlittingTestInstance::uploadBuffer (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc)
    424 {
    425 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
    426 	const VkDevice				vkDevice	= m_context.getDevice();
    427 	const deUint32				bufferSize	= calculateSize(bufferAccess);
    428 
    429 	// Write buffer data
    430 	deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
    431 	flushMappedMemoryRange(vk, vkDevice, bufferAlloc.getMemory(), bufferAlloc.getOffset(), bufferSize);
    432 }
    433 
    434 void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms, const deUint32 mipLevels)
    435 {
    436 	const InstanceInterface&		vki					= m_context.getInstanceInterface();
    437 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
    438 	const VkPhysicalDevice			vkPhysDevice		= m_context.getPhysicalDevice();
    439 	const VkDevice					vkDevice			= m_context.getDevice();
    440 	const VkQueue					queue				= m_context.getUniversalQueue();
    441 	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
    442 	Allocator&						memAlloc			= m_context.getDefaultAllocator();
    443 	Move<VkBuffer>					buffer;
    444 	const deUint32					bufferSize			= calculateSize(imageAccess);
    445 	de::MovePtr<Allocation>			bufferAlloc;
    446 	const deUint32					arraySize			= getArraySize(parms);
    447 	const VkExtent3D				imageExtent			= getExtent3D(parms);
    448 	std::vector <VkBufferImageCopy>	copyRegions;
    449 
    450 	// Create source buffer
    451 	{
    452 		const VkBufferCreateInfo	bufferParams		=
    453 		{
    454 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
    455 			DE_NULL,									// const void*			pNext;
    456 			0u,											// VkBufferCreateFlags	flags;
    457 			bufferSize,									// VkDeviceSize			size;
    458 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
    459 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
    460 			1u,											// deUint32				queueFamilyIndexCount;
    461 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
    462 		};
    463 
    464 		buffer		= createBuffer(vk, vkDevice, &bufferParams);
    465 		bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
    466 		VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
    467 	}
    468 
    469 	// Barriers for copying buffer to image
    470 	const VkBufferMemoryBarrier		preBufferBarrier	=
    471 	{
    472 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType	sType;
    473 		DE_NULL,										// const void*		pNext;
    474 		VK_ACCESS_HOST_WRITE_BIT,						// VkAccessFlags	srcAccessMask;
    475 		VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags	dstAccessMask;
    476 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
    477 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
    478 		*buffer,										// VkBuffer			buffer;
    479 		0u,												// VkDeviceSize		offset;
    480 		bufferSize										// VkDeviceSize		size;
    481 	};
    482 
    483 	const VkImageAspectFlags		formatAspect		= getAspectFlags(mapVkFormat(parms.format));
    484 	const bool						skipPreImageBarrier	= formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) &&
    485 														  getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT;
    486 	const VkImageMemoryBarrier		preImageBarrier		=
    487 	{
    488 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
    489 		DE_NULL,										// const void*				pNext;
    490 		0u,												// VkAccessFlags			srcAccessMask;
    491 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
    492 		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
    493 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
    494 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
    495 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
    496 		image,											// VkImage					image;
    497 		{												// VkImageSubresourceRange	subresourceRange;
    498 			formatAspect,	// VkImageAspectFlags	aspect;
    499 			0u,				// deUint32				baseMipLevel;
    500 			mipLevels,		// deUint32				mipLevels;
    501 			0u,				// deUint32				baseArraySlice;
    502 			arraySize,		// deUint32				arraySize;
    503 		}
    504 	};
    505 
    506 	const VkImageMemoryBarrier		postImageBarrier	=
    507 	{
    508 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
    509 		DE_NULL,										// const void*				pNext;
    510 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask;
    511 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
    512 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
    513 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
    514 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
    515 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
    516 		image,											// VkImage					image;
    517 		{												// VkImageSubresourceRange	subresourceRange;
    518 			formatAspect,				// VkImageAspectFlags	aspect;
    519 			0u,							// deUint32				baseMipLevel;
    520 			mipLevels,					// deUint32				mipLevels;
    521 			0u,							// deUint32				baseArraySlice;
    522 			arraySize,					// deUint32				arraySize;
    523 		}
    524 	};
    525 
    526 	for (deUint32 mipLevelNdx = 0; mipLevelNdx < mipLevels; mipLevelNdx++)
    527 	{
    528 		const VkExtent3D		copyExtent	=
    529 		{
    530 			imageExtent.width	>> mipLevelNdx,
    531 			imageExtent.height	>> mipLevelNdx,
    532 			imageExtent.depth
    533 		};
    534 
    535 		const VkBufferImageCopy	copyRegion	=
    536 		{
    537 			0u,												// VkDeviceSize				bufferOffset;
    538 			(deUint32)imageAccess.getWidth(),				// deUint32					bufferRowLength;
    539 			(deUint32)imageAccess.getHeight(),				// deUint32					bufferImageHeight;
    540 			{
    541 				getAspectFlags(imageAccess.getFormat()),		// VkImageAspectFlags	aspect;
    542 				mipLevelNdx,									// deUint32				mipLevel;
    543 				0u,												// deUint32				baseArrayLayer;
    544 				arraySize,										// deUint32				layerCount;
    545 			},												// VkImageSubresourceLayers	imageSubresource;
    546 			{ 0, 0, 0 },									// VkOffset3D				imageOffset;
    547 			copyExtent										// VkExtent3D				imageExtent;
    548 		};
    549 
    550 		copyRegions.push_back(copyRegion);
    551 	}
    552 
    553 	// Write buffer data
    554 	deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
    555 	flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
    556 
    557 	// Copy buffer to image
    558 	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
    559 	{
    560 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
    561 		DE_NULL,												// const void*						pNext;
    562 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
    563 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
    564 	};
    565 
    566 	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
    567 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
    568 						  1, &preBufferBarrier, (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier));
    569 	vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), &copyRegions[0]);
    570 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
    571 	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
    572 
    573 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
    574 }
    575 
    576 void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels)
    577 {
    578 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
    579 	{
    580 		if (tcu::hasDepthComponent(src.getFormat().order))
    581 		{
    582 			tcu::TextureLevel	depthTexture	(mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth());
    583 			tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
    584 			uploadImageAspect(depthTexture.getAccess(), dst, parms);
    585 		}
    586 
    587 		if (tcu::hasStencilComponent(src.getFormat().order))
    588 		{
    589 			tcu::TextureLevel	stencilTexture	(tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth());
    590 			tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
    591 			uploadImageAspect(stencilTexture.getAccess(), dst, parms);
    592 		}
    593 	}
    594 	else
    595 		uploadImageAspect(src, dst, parms, mipLevels);
    596 }
    597 
    598 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result)
    599 {
    600 	const tcu::ConstPixelBufferAccess	expected	= m_expectedTextureLevel[0]->getAccess();
    601 
    602 	if (isFloatFormat(result.getFormat()))
    603 	{
    604 		const tcu::Vec4	threshold (0.0f);
    605 		if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
    606 			return tcu::TestStatus::fail("CopiesAndBlitting test");
    607 	}
    608 	else
    609 	{
    610 		const tcu::UVec4 threshold (0u);
    611 		if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
    612 			return tcu::TestStatus::fail("CopiesAndBlitting test");
    613 	}
    614 
    615 	return tcu::TestStatus::pass("CopiesAndBlitting test");
    616 }
    617 
    618 void CopiesAndBlittingTestInstance::generateExpectedResult (void)
    619 {
    620 	const tcu::ConstPixelBufferAccess	src	= m_sourceTextureLevel->getAccess();
    621 	const tcu::ConstPixelBufferAccess	dst	= m_destinationTextureLevel->getAccess();
    622 
    623 	m_expectedTextureLevel[0]	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
    624 	tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
    625 
    626 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
    627 		copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), m_params.regions[i]);
    628 }
    629 
    630 class CopiesAndBlittingTestCase : public vkt::TestCase
    631 {
    632 public:
    633 							CopiesAndBlittingTestCase	(tcu::TestContext&			testCtx,
    634 														 const std::string&			name,
    635 														 const std::string&			description)
    636 								: vkt::TestCase	(testCtx, name, description)
    637 							{}
    638 
    639 	virtual TestInstance*	createInstance				(Context&					context) const = 0;
    640 };
    641 
    642 void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage					image,
    643 													 const tcu::PixelBufferAccess&	dst,
    644 													 const ImageParms&				imageParms,
    645 													 const deUint32					mipLevel)
    646 {
    647 	const InstanceInterface&	vki					= m_context.getInstanceInterface();
    648 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
    649 	const VkPhysicalDevice		physDevice			= m_context.getPhysicalDevice();
    650 	const VkDevice				device				= m_context.getDevice();
    651 	const VkQueue				queue				= m_context.getUniversalQueue();
    652 	Allocator&					allocator			= m_context.getDefaultAllocator();
    653 
    654 	Move<VkBuffer>				buffer;
    655 	de::MovePtr<Allocation>		bufferAlloc;
    656 	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
    657 	const VkDeviceSize			pixelDataSize		= calculateSize(dst);
    658 
    659 	const VkExtent3D			imageExtent			=
    660 	{
    661 		(deUint32)dst.getWidth(),
    662 		(deUint32)dst.getHeight(),
    663 		(imageParms.imageType == VK_IMAGE_TYPE_3D) ? (deUint32)dst.getDepth() : 1,
    664 	};
    665 
    666 	// Create destination buffer
    667 	{
    668 		const VkBufferCreateInfo			bufferParams			=
    669 		{
    670 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
    671 			DE_NULL,									// const void*			pNext;
    672 			0u,											// VkBufferCreateFlags	flags;
    673 			pixelDataSize,								// VkDeviceSize			size;
    674 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
    675 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
    676 			1u,											// deUint32				queueFamilyIndexCount;
    677 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
    678 		};
    679 
    680 		buffer		= createBuffer(vk, device, &bufferParams);
    681 		bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator, m_params.allocationKind);
    682 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
    683 
    684 		deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
    685 		flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
    686 	}
    687 
    688 	// Barriers for copying image to buffer
    689 	const VkImageAspectFlags				formatAspect			= getAspectFlags(mapVkFormat(imageParms.format));
    690 	const VkImageMemoryBarrier				imageBarrier			=
    691 	{
    692 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
    693 		DE_NULL,									// const void*				pNext;
    694 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
    695 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
    696 		imageParms.operationLayout,					// VkImageLayout			oldLayout;
    697 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
    698 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
    699 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
    700 		image,										// VkImage					image;
    701 		{											// VkImageSubresourceRange	subresourceRange;
    702 			formatAspect,			// VkImageAspectFlags	aspectMask;
    703 			mipLevel,				// deUint32				baseMipLevel;
    704 			1u,						// deUint32				mipLevels;
    705 			0u,						// deUint32				baseArraySlice;
    706 			getArraySize(imageParms)// deUint32				arraySize;
    707 		}
    708 	};
    709 
    710 	const VkBufferMemoryBarrier				bufferBarrier			=
    711 	{
    712 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
    713 		DE_NULL,									// const void*		pNext;
    714 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
    715 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
    716 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
    717 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
    718 		*buffer,									// VkBuffer			buffer;
    719 		0u,											// VkDeviceSize		offset;
    720 		pixelDataSize								// VkDeviceSize		size;
    721 	};
    722 
    723 	const VkImageMemoryBarrier				postImageBarrier		=
    724 	{
    725 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
    726 		DE_NULL,									// const void*				pNext;
    727 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
    728 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
    729 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			oldLayout;
    730 		imageParms.operationLayout,					// VkImageLayout			newLayout;
    731 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
    732 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
    733 		image,										// VkImage					image;
    734 		{
    735 			formatAspect,								// VkImageAspectFlags	aspectMask;
    736 			mipLevel,									// deUint32				baseMipLevel;
    737 			1u,											// deUint32				mipLevels;
    738 			0u,											// deUint32				baseArraySlice;
    739 			getArraySize(imageParms)					// deUint32				arraySize;
    740 		}											// VkImageSubresourceRange	subresourceRange;
    741 	};
    742 
    743 	// Copy image to buffer
    744 	const VkImageAspectFlags	aspect			= getAspectFlags(dst.getFormat());
    745 	const VkBufferImageCopy		copyRegion		=
    746 	{
    747 		0u,									// VkDeviceSize				bufferOffset;
    748 		(deUint32)dst.getWidth(),			// deUint32					bufferRowLength;
    749 		(deUint32)dst.getHeight(),			// deUint32					bufferImageHeight;
    750 		{
    751 			aspect,								// VkImageAspectFlags		aspect;
    752 			mipLevel,							// deUint32					mipLevel;
    753 			0u,									// deUint32					baseArrayLayer;
    754 			getArraySize(imageParms),			// deUint32					layerCount;
    755 		},									// VkImageSubresourceLayers	imageSubresource;
    756 		{ 0, 0, 0 },						// VkOffset3D				imageOffset;
    757 		imageExtent							// VkExtent3D				imageExtent;
    758 	};
    759 
    760 	const VkCommandBufferBeginInfo			cmdBufferBeginInfo		=
    761 	{
    762 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
    763 		DE_NULL,												// const void*						pNext;
    764 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
    765 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
    766 	};
    767 
    768 	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
    769 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
    770 	vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
    771 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT|VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 1, &postImageBarrier);
    772 	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
    773 
    774 	submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
    775 
    776 	// Read buffer data
    777 	invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
    778 	tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
    779 }
    780 
    781 void CopiesAndBlittingTestInstance::submitCommandsAndWait (const DeviceInterface& vk, const VkDevice device, const VkQueue queue, const VkCommandBuffer& cmdBuffer)
    782 {
    783 	const VkSubmitInfo						submitInfo				=
    784 	{
    785 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
    786 		DE_NULL,						// const void*				pNext;
    787 		0u,								// deUint32					waitSemaphoreCount;
    788 		DE_NULL,						// const VkSemaphore*		pWaitSemaphores;
    789 		(const VkPipelineStageFlags*)DE_NULL,
    790 		1u,								// deUint32					commandBufferCount;
    791 		&cmdBuffer,						// const VkCommandBuffer*	pCommandBuffers;
    792 		0u,								// deUint32					signalSemaphoreCount;
    793 		DE_NULL							// const VkSemaphore*		pSignalSemaphores;
    794 	};
    795 
    796 	VK_CHECK(vk.resetFences(device, 1, &m_fence.get()));
    797 	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
    798 	VK_CHECK(vk.waitForFences(device, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
    799 }
    800 
    801 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage	(vk::VkImage		image,
    802 																		 const ImageParms&	parms,
    803 																		 const deUint32		mipLevel)
    804 {
    805 	const tcu::TextureFormat		imageFormat	= mapVkFormat(parms.format);
    806 	de::MovePtr<tcu::TextureLevel>	resultLevel	(new tcu::TextureLevel(imageFormat, parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth));
    807 
    808 	if (tcu::isCombinedDepthStencilType(imageFormat.type))
    809 	{
    810 		if (tcu::hasDepthComponent(imageFormat.order))
    811 		{
    812 			tcu::TextureLevel	depthTexture	(mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width, parms.extent.height, parms.extent.depth);
    813 			readImageAspect(image, depthTexture.getAccess(), parms);
    814 			tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess());
    815 		}
    816 
    817 		if (tcu::hasStencilComponent(imageFormat.order))
    818 		{
    819 			tcu::TextureLevel	stencilTexture	(tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width, parms.extent.height, parms.extent.depth);
    820 			readImageAspect(image, stencilTexture.getAccess(), parms);
    821 			tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess());
    822 		}
    823 	}
    824 	else
    825 		readImageAspect(image, resultLevel->getAccess(), parms, mipLevel);
    826 
    827 	return resultLevel;
    828 }
    829 
    830 // Copy from image to image.
    831 
    832 class CopyImageToImage : public CopiesAndBlittingTestInstance
    833 {
    834 public:
    835 										CopyImageToImage			(Context&	context,
    836 																	 TestParams params);
    837 	virtual tcu::TestStatus				iterate						(void);
    838 
    839 protected:
    840 	virtual tcu::TestStatus				checkTestResult				(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
    841 
    842 private:
    843 	Move<VkImage>						m_source;
    844 	de::MovePtr<Allocation>				m_sourceImageAlloc;
    845 	Move<VkImage>						m_destination;
    846 	de::MovePtr<Allocation>				m_destinationImageAlloc;
    847 
    848 	virtual void						copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
    849 };
    850 
    851 CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
    852 	: CopiesAndBlittingTestInstance(context, params)
    853 {
    854 	const InstanceInterface&	vki					= context.getInstanceInterface();
    855 	const DeviceInterface&		vk					= context.getDeviceInterface();
    856 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
    857 	const VkDevice				vkDevice			= context.getDevice();
    858 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
    859 	Allocator&					memAlloc			= context.getDefaultAllocator();
    860 
    861 	if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
    862 		(m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
    863 	{
    864 		if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance1"))
    865 			TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
    866 	}
    867 
    868 	VkImageFormatProperties properties;
    869 	if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
    870 																				m_params.src.image.format,
    871 																				m_params.src.image.imageType,
    872 																				VK_IMAGE_TILING_OPTIMAL,
    873 																				VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
    874 																				0,
    875 																				&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
    876 		(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
    877 																				m_params.dst.image.format,
    878 																				m_params.dst.image.imageType,
    879 																				VK_IMAGE_TILING_OPTIMAL,
    880 																				VK_IMAGE_USAGE_TRANSFER_DST_BIT,
    881 																				0,
    882 																				&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
    883 	{
    884 		TCU_THROW(NotSupportedError, "Format not supported");
    885 	}
    886 
    887 	// Create source image
    888 	{
    889 		const VkImageCreateInfo	sourceImageParams		=
    890 		{
    891 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
    892 			DE_NULL,								// const void*			pNext;
    893 			0u,										// VkImageCreateFlags	flags;
    894 			m_params.src.image.imageType,			// VkImageType			imageType;
    895 			m_params.src.image.format,				// VkFormat				format;
    896 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
    897 			1u,										// deUint32				mipLevels;
    898 			getArraySize(m_params.src.image),		// deUint32				arraySize;
    899 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
    900 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
    901 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
    902 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
    903 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
    904 			1u,										// deUint32				queueFamilyCount;
    905 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
    906 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
    907 		};
    908 
    909 		m_source				= createImage(vk, vkDevice, &sourceImageParams);
    910 		m_sourceImageAlloc		= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
    911 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
    912 	}
    913 
    914 	// Create destination image
    915 	{
    916 		const VkImageCreateInfo	destinationImageParams	=
    917 		{
    918 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
    919 			DE_NULL,								// const void*			pNext;
    920 			0u,										// VkImageCreateFlags	flags;
    921 			m_params.dst.image.imageType,			// VkImageType			imageType;
    922 			m_params.dst.image.format,				// VkFormat				format;
    923 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
    924 			1u,										// deUint32				mipLevels;
    925 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
    926 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
    927 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
    928 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
    929 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
    930 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
    931 			1u,										// deUint32				queueFamilyCount;
    932 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
    933 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
    934 		};
    935 
    936 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
    937 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
    938 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
    939 	}
    940 }
    941 
    942 tcu::TestStatus CopyImageToImage::iterate (void)
    943 {
    944 	const tcu::TextureFormat	srcTcuFormat		= mapVkFormat(m_params.src.image.format);
    945 	const tcu::TextureFormat	dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
    946 
    947 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
    948 																				(int)m_params.src.image.extent.width,
    949 																				(int)m_params.src.image.extent.height,
    950 																				(int)m_params.src.image.extent.depth));
    951 	generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_RED);
    952 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
    953 																				(int)m_params.dst.image.extent.width,
    954 																				(int)m_params.dst.image.extent.height,
    955 																				(int)m_params.dst.image.extent.depth));
    956 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_GRADIENT);
    957 	generateExpectedResult();
    958 
    959 	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
    960 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
    961 
    962 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
    963 	const VkDevice				vkDevice			= m_context.getDevice();
    964 	const VkQueue				queue				= m_context.getUniversalQueue();
    965 
    966 	std::vector<VkImageCopy>	imageCopies;
    967 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
    968 	{
    969 		const VkImageCopy& ic = m_params.regions[i].imageCopy;
    970 		imageCopies.push_back(ic);
    971 	}
    972 
    973 	const VkImageMemoryBarrier	imageBarriers[]		=
    974 	{
    975 		// source image
    976 		{
    977 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
    978 			DE_NULL,									// const void*				pNext;
    979 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
    980 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
    981 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
    982 			m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
    983 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
    984 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
    985 			m_source.get(),								// VkImage					image;
    986 			{											// VkImageSubresourceRange	subresourceRange;
    987 				getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
    988 				0u,								// deUint32				baseMipLevel;
    989 				1u,								// deUint32				mipLevels;
    990 				0u,								// deUint32				baseArraySlice;
    991 				getArraySize(m_params.src.image)// deUint32				arraySize;
    992 			}
    993 		},
    994 		// destination image
    995 		{
    996 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
    997 			DE_NULL,									// const void*				pNext;
    998 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
    999 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
   1000 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
   1001 			m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
   1002 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
   1003 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
   1004 			m_destination.get(),						// VkImage					image;
   1005 			{											// VkImageSubresourceRange	subresourceRange;
   1006 				getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
   1007 				0u,								// deUint32				baseMipLevel;
   1008 				1u,								// deUint32				mipLevels;
   1009 				0u,								// deUint32				baseArraySlice;
   1010 				getArraySize(m_params.dst.image)// deUint32				arraySize;
   1011 			}
   1012 		},
   1013 	};
   1014 
   1015 	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
   1016 	{
   1017 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
   1018 		DE_NULL,												// const void*						pNext;
   1019 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
   1020 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
   1021 	};
   1022 
   1023 	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
   1024 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
   1025 	vk.cmdCopyImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
   1026 	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
   1027 
   1028 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
   1029 
   1030 	de::MovePtr<tcu::TextureLevel>	resultTextureLevel	= readImage(*m_destination, m_params.dst.image);
   1031 
   1032 	return checkTestResult(resultTextureLevel->getAccess());
   1033 }
   1034 
   1035 tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
   1036 {
   1037 	const tcu::Vec4	fThreshold (0.0f);
   1038 	const tcu::UVec4 uThreshold (0u);
   1039 
   1040 	if (tcu::isCombinedDepthStencilType(result.getFormat().type))
   1041 	{
   1042 		if (tcu::hasDepthComponent(result.getFormat().order))
   1043 		{
   1044 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
   1045 			const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
   1046 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
   1047 
   1048 			if (isFloatFormat(result.getFormat()))
   1049 			{
   1050 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
   1051 					return tcu::TestStatus::fail("CopiesAndBlitting test");
   1052 			}
   1053 			else
   1054 			{
   1055 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
   1056 					return tcu::TestStatus::fail("CopiesAndBlitting test");
   1057 			}
   1058 		}
   1059 
   1060 		if (tcu::hasStencilComponent(result.getFormat().order))
   1061 		{
   1062 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
   1063 			const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
   1064 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
   1065 
   1066 			if (isFloatFormat(result.getFormat()))
   1067 			{
   1068 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
   1069 					return tcu::TestStatus::fail("CopiesAndBlitting test");
   1070 			}
   1071 			else
   1072 			{
   1073 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
   1074 					return tcu::TestStatus::fail("CopiesAndBlitting test");
   1075 			}
   1076 		}
   1077 	}
   1078 	else
   1079 	{
   1080 		if (isFloatFormat(result.getFormat()))
   1081 		{
   1082 			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
   1083 				return tcu::TestStatus::fail("CopiesAndBlitting test");
   1084 		}
   1085 		else if (isSnormFormat(mapTextureFormat(result.getFormat())))
   1086 		{
   1087 			// There may be an ambiguity between two possible binary representations of 1.0.
   1088 			// Get rid of that by expanding the data to floats and re-normalizing again.
   1089 
   1090 			tcu::TextureLevel resultSnorm	(result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
   1091 			{
   1092 				tcu::TextureLevel resultFloat	(tcu::TextureFormat(resultSnorm.getFormat().order, tcu::TextureFormat::FLOAT), resultSnorm.getWidth(), resultSnorm.getHeight(), resultSnorm.getDepth());
   1093 
   1094 				tcu::copy(resultFloat.getAccess(), result);
   1095 				tcu::copy(resultSnorm, resultFloat.getAccess());
   1096 			}
   1097 
   1098 			tcu::TextureLevel expectedSnorm	(m_expectedTextureLevel[0]->getFormat(), m_expectedTextureLevel[0]->getWidth(), m_expectedTextureLevel[0]->getHeight(), m_expectedTextureLevel[0]->getDepth());
   1099 
   1100 			{
   1101 				tcu::TextureLevel expectedFloat	(tcu::TextureFormat(expectedSnorm.getFormat().order, tcu::TextureFormat::FLOAT), expectedSnorm.getWidth(), expectedSnorm.getHeight(), expectedSnorm.getDepth());
   1102 
   1103 				tcu::copy(expectedFloat.getAccess(), m_expectedTextureLevel[0]->getAccess());
   1104 				tcu::copy(expectedSnorm, expectedFloat.getAccess());
   1105 			}
   1106 
   1107 			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedSnorm.getAccess(), resultSnorm.getAccess(), uThreshold, tcu::COMPARE_LOG_RESULT))
   1108 				return tcu::TestStatus::fail("CopiesAndBlitting test");
   1109 		}
   1110 		else
   1111 		{
   1112 			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
   1113 				return tcu::TestStatus::fail("CopiesAndBlitting test");
   1114 		}
   1115 	}
   1116 
   1117 	return tcu::TestStatus::pass("CopiesAndBlitting test");
   1118 }
   1119 
   1120 void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
   1121 {
   1122 	VkOffset3D	srcOffset	= region.imageCopy.srcOffset;
   1123 	VkOffset3D	dstOffset	= region.imageCopy.dstOffset;
   1124 	VkExtent3D	extent		= region.imageCopy.extent;
   1125 
   1126 	if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
   1127 	{
   1128 		dstOffset.z = srcOffset.z;
   1129 		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
   1130 	}
   1131 	if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
   1132 	{
   1133 		srcOffset.z = dstOffset.z;
   1134 		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
   1135 	}
   1136 
   1137 
   1138 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
   1139 	{
   1140 		DE_ASSERT(src.getFormat() == dst.getFormat());
   1141 
   1142 		// Copy depth.
   1143 		if (tcu::hasDepthComponent(src.getFormat().order))
   1144 		{
   1145 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
   1146 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
   1147 			tcu::copy(dstSubRegion, srcSubRegion);
   1148 		}
   1149 
   1150 		// Copy stencil.
   1151 		if (tcu::hasStencilComponent(src.getFormat().order))
   1152 		{
   1153 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
   1154 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
   1155 			tcu::copy(dstSubRegion, srcSubRegion);
   1156 		}
   1157 	}
   1158 	else
   1159 	{
   1160 		const tcu::ConstPixelBufferAccess	srcSubRegion		= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
   1161 		// CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
   1162 		const tcu::PixelBufferAccess		dstWithSrcFormat	(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
   1163 		const tcu::PixelBufferAccess		dstSubRegion		= tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
   1164 
   1165 		tcu::copy(dstSubRegion, srcSubRegion);
   1166 	}
   1167 }
   1168 
   1169 class CopyImageToImageTestCase : public vkt::TestCase
   1170 {
   1171 public:
   1172 							CopyImageToImageTestCase	(tcu::TestContext&				testCtx,
   1173 														 const std::string&				name,
   1174 														 const std::string&				description,
   1175 														 const TestParams				params)
   1176 								: vkt::TestCase	(testCtx, name, description)
   1177 								, m_params		(params)
   1178 							{}
   1179 
   1180 	virtual TestInstance*	createInstance				(Context&						context) const
   1181 							{
   1182 								return new CopyImageToImage(context, m_params);
   1183 							}
   1184 private:
   1185 	TestParams				m_params;
   1186 };
   1187 
   1188 // Copy from buffer to buffer.
   1189 
   1190 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
   1191 {
   1192 public:
   1193 								CopyBufferToBuffer			(Context& context, TestParams params);
   1194 	virtual tcu::TestStatus		iterate						(void);
   1195 private:
   1196 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion);
   1197 	Move<VkBuffer>				m_source;
   1198 	de::MovePtr<Allocation>		m_sourceBufferAlloc;
   1199 	Move<VkBuffer>				m_destination;
   1200 	de::MovePtr<Allocation>		m_destinationBufferAlloc;
   1201 };
   1202 
   1203 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
   1204 	: CopiesAndBlittingTestInstance	(context, params)
   1205 {
   1206 	const InstanceInterface&	vki					= context.getInstanceInterface();
   1207 	const DeviceInterface&		vk					= context.getDeviceInterface();
   1208 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
   1209 	const VkDevice				vkDevice			= context.getDevice();
   1210 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
   1211 	Allocator&					memAlloc			= context.getDefaultAllocator();
   1212 
   1213 	// Create source buffer
   1214 	{
   1215 		const VkBufferCreateInfo	sourceBufferParams		=
   1216 		{
   1217 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
   1218 			DE_NULL,									// const void*			pNext;
   1219 			0u,											// VkBufferCreateFlags	flags;
   1220 			m_params.src.buffer.size,					// VkDeviceSize			size;
   1221 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
   1222 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
   1223 			1u,											// deUint32				queueFamilyIndexCount;
   1224 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
   1225 		};
   1226 
   1227 		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
   1228 		m_sourceBufferAlloc		= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
   1229 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
   1230 	}
   1231 
   1232 	// Create destination buffer
   1233 	{
   1234 		const VkBufferCreateInfo	destinationBufferParams	=
   1235 		{
   1236 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
   1237 			DE_NULL,									// const void*			pNext;
   1238 			0u,											// VkBufferCreateFlags	flags;
   1239 			m_params.dst.buffer.size,					// VkDeviceSize			size;
   1240 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
   1241 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
   1242 			1u,											// deUint32				queueFamilyIndexCount;
   1243 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
   1244 		};
   1245 
   1246 		m_destination				= createBuffer(vk, vkDevice, &destinationBufferParams);
   1247 		m_destinationBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
   1248 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
   1249 	}
   1250 }
   1251 
   1252 tcu::TestStatus CopyBufferToBuffer::iterate (void)
   1253 {
   1254 	const int srcLevelWidth		= (int)(m_params.src.buffer.size/4); // Here the format is VK_FORMAT_R32_UINT, we need to divide the buffer size by 4
   1255 	m_sourceTextureLevel		= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
   1256 	generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
   1257 
   1258 	const int dstLevelWidth		= (int)(m_params.dst.buffer.size/4);
   1259 	m_destinationTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
   1260 	generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_WHITE);
   1261 
   1262 	generateExpectedResult();
   1263 
   1264 	uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
   1265 	uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
   1266 
   1267 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
   1268 	const VkDevice				vkDevice	= m_context.getDevice();
   1269 	const VkQueue				queue		= m_context.getUniversalQueue();
   1270 
   1271 	const VkBufferMemoryBarrier		srcBufferBarrier	=
   1272 	{
   1273 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
   1274 		DE_NULL,									// const void*		pNext;
   1275 		VK_ACCESS_HOST_WRITE_BIT,					// VkAccessFlags	srcAccessMask;
   1276 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags	dstAccessMask;
   1277 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
   1278 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
   1279 		*m_source,									// VkBuffer			buffer;
   1280 		0u,											// VkDeviceSize		offset;
   1281 		m_params.src.buffer.size					// VkDeviceSize		size;
   1282 	};
   1283 
   1284 	const VkBufferMemoryBarrier		dstBufferBarrier	=
   1285 	{
   1286 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
   1287 		DE_NULL,									// const void*		pNext;
   1288 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
   1289 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
   1290 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
   1291 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
   1292 		*m_destination,								// VkBuffer			buffer;
   1293 		0u,											// VkDeviceSize		offset;
   1294 		m_params.dst.buffer.size					// VkDeviceSize		size;
   1295 	};
   1296 
   1297 	std::vector<VkBufferCopy>		bufferCopies;
   1298 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
   1299 		bufferCopies.push_back(m_params.regions[i].bufferCopy);
   1300 
   1301 	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
   1302 	{
   1303 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
   1304 		DE_NULL,												// const void*						pNext;
   1305 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
   1306 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
   1307 	};
   1308 
   1309 	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
   1310 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &srcBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
   1311 	vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]);
   1312 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &dstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
   1313 	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
   1314 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
   1315 
   1316 
   1317 
   1318 	// Read buffer data
   1319 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
   1320 	invalidateMappedMemoryRange(vk, vkDevice, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset(), m_params.dst.buffer.size);
   1321 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
   1322 
   1323 	return checkTestResult(resultLevel->getAccess());
   1324 }
   1325 
   1326 void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
   1327 {
   1328 	deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
   1329 			 (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
   1330 			 (size_t)region.bufferCopy.size);
   1331 }
   1332 
   1333 class BufferToBufferTestCase : public vkt::TestCase
   1334 {
   1335 public:
   1336 							BufferToBufferTestCase	(tcu::TestContext&	testCtx,
   1337 													 const std::string&	name,
   1338 													 const std::string&	description,
   1339 													 const TestParams	params)
   1340 								: vkt::TestCase	(testCtx, name, description)
   1341 								, m_params		(params)
   1342 							{}
   1343 
   1344 	virtual TestInstance*	createInstance			(Context& context) const
   1345 							{
   1346 								return new CopyBufferToBuffer(context, m_params);
   1347 							}
   1348 private:
   1349 	TestParams				m_params;
   1350 };
   1351 
   1352 // Copy from image to buffer.
   1353 
   1354 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
   1355 {
   1356 public:
   1357 								CopyImageToBuffer			(Context&	context,
   1358 															 TestParams	testParams);
   1359 	virtual tcu::TestStatus		iterate						(void);
   1360 private:
   1361 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
   1362 
   1363 	tcu::TextureFormat			m_textureFormat;
   1364 	VkDeviceSize				m_bufferSize;
   1365 
   1366 	Move<VkImage>				m_source;
   1367 	de::MovePtr<Allocation>		m_sourceImageAlloc;
   1368 	Move<VkBuffer>				m_destination;
   1369 	de::MovePtr<Allocation>		m_destinationBufferAlloc;
   1370 };
   1371 
   1372 CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
   1373 	: CopiesAndBlittingTestInstance(context, testParams)
   1374 	, m_textureFormat(mapVkFormat(testParams.src.image.format))
   1375 	, m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
   1376 {
   1377 	const InstanceInterface&	vki					= context.getInstanceInterface();
   1378 	const DeviceInterface&		vk					= context.getDeviceInterface();
   1379 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
   1380 	const VkDevice				vkDevice			= context.getDevice();
   1381 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
   1382 	Allocator&					memAlloc			= context.getDefaultAllocator();
   1383 
   1384 	// Create source image
   1385 	{
   1386 		const VkImageCreateInfo		sourceImageParams		=
   1387 		{
   1388 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
   1389 			DE_NULL,								// const void*			pNext;
   1390 			0u,										// VkImageCreateFlags	flags;
   1391 			m_params.src.image.imageType,			// VkImageType			imageType;
   1392 			m_params.src.image.format,				// VkFormat				format;
   1393 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
   1394 			1u,										// deUint32				mipLevels;
   1395 			getArraySize(m_params.src.image),		// deUint32				arraySize;
   1396 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
   1397 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
   1398 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
   1399 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
   1400 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
   1401 			1u,										// deUint32				queueFamilyCount;
   1402 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
   1403 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
   1404 		};
   1405 
   1406 		m_source			= createImage(vk, vkDevice, &sourceImageParams);
   1407 		m_sourceImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
   1408 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
   1409 	}
   1410 
   1411 	// Create destination buffer
   1412 	{
   1413 		const VkBufferCreateInfo	destinationBufferParams	=
   1414 		{
   1415 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
   1416 			DE_NULL,									// const void*			pNext;
   1417 			0u,											// VkBufferCreateFlags	flags;
   1418 			m_bufferSize,								// VkDeviceSize			size;
   1419 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
   1420 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
   1421 			1u,											// deUint32				queueFamilyIndexCount;
   1422 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
   1423 		};
   1424 
   1425 		m_destination				= createBuffer(vk, vkDevice, &destinationBufferParams);
   1426 		m_destinationBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
   1427 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
   1428 	}
   1429 }
   1430 
   1431 tcu::TestStatus CopyImageToBuffer::iterate (void)
   1432 {
   1433 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
   1434 																				m_params.src.image.extent.width,
   1435 																				m_params.src.image.extent.height,
   1436 																				m_params.src.image.extent.depth));
   1437 	generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
   1438 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
   1439 	generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
   1440 
   1441 	generateExpectedResult();
   1442 
   1443 	uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
   1444 	uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
   1445 
   1446 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
   1447 	const VkDevice				vkDevice	= m_context.getDevice();
   1448 	const VkQueue				queue		= m_context.getUniversalQueue();
   1449 
   1450 	// Barriers for copying image to buffer
   1451 	const VkImageMemoryBarrier		imageBarrier		=
   1452 	{
   1453 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
   1454 		DE_NULL,									// const void*				pNext;
   1455 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
   1456 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
   1457 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
   1458 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
   1459 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
   1460 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
   1461 		*m_source,									// VkImage					image;
   1462 		{											// VkImageSubresourceRange	subresourceRange;
   1463 			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
   1464 			0u,								// deUint32				baseMipLevel;
   1465 			1u,								// deUint32				mipLevels;
   1466 			0u,								// deUint32				baseArraySlice;
   1467 			1u								// deUint32				arraySize;
   1468 		}
   1469 	};
   1470 
   1471 	const VkBufferMemoryBarrier		bufferBarrier		=
   1472 	{
   1473 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
   1474 		DE_NULL,									// const void*		pNext;
   1475 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
   1476 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
   1477 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
   1478 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
   1479 		*m_destination,								// VkBuffer			buffer;
   1480 		0u,											// VkDeviceSize		offset;
   1481 		m_bufferSize								// VkDeviceSize		size;
   1482 	};
   1483 
   1484 	// Copy from image to buffer
   1485 	std::vector<VkBufferImageCopy>	bufferImageCopies;
   1486 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
   1487 		bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
   1488 
   1489 	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
   1490 	{
   1491 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
   1492 		DE_NULL,												// const void*						pNext;
   1493 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
   1494 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
   1495 	};
   1496 
   1497 	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
   1498 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
   1499 	vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), &bufferImageCopies[0]);
   1500 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
   1501 	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
   1502 
   1503 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
   1504 
   1505 	// Read buffer data
   1506 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
   1507 	invalidateMappedMemoryRange(vk, vkDevice, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset(), m_bufferSize);
   1508 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
   1509 
   1510 	return checkTestResult(resultLevel->getAccess());
   1511 }
   1512 
   1513 class CopyImageToBufferTestCase : public vkt::TestCase
   1514 {
   1515 public:
   1516 							CopyImageToBufferTestCase	(tcu::TestContext&		testCtx,
   1517 														 const std::string&		name,
   1518 														 const std::string&		description,
   1519 														 const TestParams		params)
   1520 								: vkt::TestCase	(testCtx, name, description)
   1521 								, m_params		(params)
   1522 							{}
   1523 
   1524 	virtual TestInstance*	createInstance				(Context&				context) const
   1525 							{
   1526 								return new CopyImageToBuffer(context, m_params);
   1527 							}
   1528 private:
   1529 	TestParams				m_params;
   1530 };
   1531 
   1532 void CopyImageToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
   1533 {
   1534 	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
   1535 	if (!rowLength)
   1536 		rowLength = region.bufferImageCopy.imageExtent.width;
   1537 
   1538 	deUint32			imageHeight	= region.bufferImageCopy.bufferImageHeight;
   1539 	if (!imageHeight)
   1540 		imageHeight = region.bufferImageCopy.imageExtent.height;
   1541 
   1542 	const int			texelSize	= src.getFormat().getPixelSize();
   1543 	const VkExtent3D	extent		= region.bufferImageCopy.imageExtent;
   1544 	const VkOffset3D	srcOffset	= region.bufferImageCopy.imageOffset;
   1545 	const int			texelOffset	= (int) region.bufferImageCopy.bufferOffset / texelSize;
   1546 
   1547 	for (deUint32 z = 0; z < extent.depth; z++)
   1548 	{
   1549 		for (deUint32 y = 0; y < extent.height; y++)
   1550 		{
   1551 			int									texelIndex		= texelOffset + (z * imageHeight + y) *	rowLength;
   1552 			const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z,
   1553 																					region.bufferImageCopy.imageExtent.width, 1, 1);
   1554 			const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
   1555 			tcu::copy(dstSubRegion, srcSubRegion);
   1556 		}
   1557 	}
   1558 }
   1559 
   1560 // Copy from buffer to image.
   1561 
   1562 class CopyBufferToImage : public CopiesAndBlittingTestInstance
   1563 {
   1564 public:
   1565 								CopyBufferToImage			(Context&	context,
   1566 															 TestParams	testParams);
   1567 	virtual tcu::TestStatus		iterate						(void);
   1568 private:
   1569 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
   1570 
   1571 	tcu::TextureFormat			m_textureFormat;
   1572 	VkDeviceSize				m_bufferSize;
   1573 
   1574 	Move<VkBuffer>				m_source;
   1575 	de::MovePtr<Allocation>		m_sourceBufferAlloc;
   1576 	Move<VkImage>				m_destination;
   1577 	de::MovePtr<Allocation>		m_destinationImageAlloc;
   1578 };
   1579 
   1580 CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
   1581 	: CopiesAndBlittingTestInstance(context, testParams)
   1582 	, m_textureFormat(mapVkFormat(testParams.dst.image.format))
   1583 	, m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
   1584 {
   1585 	const InstanceInterface&	vki					= context.getInstanceInterface();
   1586 	const DeviceInterface&		vk					= context.getDeviceInterface();
   1587 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
   1588 	const VkDevice				vkDevice			= context.getDevice();
   1589 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
   1590 	Allocator&					memAlloc			= context.getDefaultAllocator();
   1591 
   1592 	// Create source buffer
   1593 	{
   1594 		const VkBufferCreateInfo	sourceBufferParams		=
   1595 		{
   1596 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
   1597 			DE_NULL,									// const void*			pNext;
   1598 			0u,											// VkBufferCreateFlags	flags;
   1599 			m_bufferSize,								// VkDeviceSize			size;
   1600 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
   1601 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
   1602 			1u,											// deUint32				queueFamilyIndexCount;
   1603 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
   1604 		};
   1605 
   1606 		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
   1607 		m_sourceBufferAlloc		= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
   1608 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
   1609 	}
   1610 
   1611 	// Create destination image
   1612 	{
   1613 		const VkImageCreateInfo		destinationImageParams	=
   1614 		{
   1615 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
   1616 			DE_NULL,								// const void*			pNext;
   1617 			0u,										// VkImageCreateFlags	flags;
   1618 			m_params.dst.image.imageType,			// VkImageType			imageType;
   1619 			m_params.dst.image.format,				// VkFormat				format;
   1620 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
   1621 			1u,										// deUint32				mipLevels;
   1622 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
   1623 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
   1624 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
   1625 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
   1626 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
   1627 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
   1628 			1u,										// deUint32				queueFamilyCount;
   1629 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
   1630 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
   1631 		};
   1632 
   1633 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
   1634 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
   1635 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
   1636 	}
   1637 }
   1638 
   1639 tcu::TestStatus CopyBufferToImage::iterate (void)
   1640 {
   1641 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
   1642 	generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
   1643 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
   1644 																					m_params.dst.image.extent.width,
   1645 																					m_params.dst.image.extent.height,
   1646 																					m_params.dst.image.extent.depth));
   1647 
   1648 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
   1649 
   1650 	generateExpectedResult();
   1651 
   1652 	uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
   1653 	uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
   1654 
   1655 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
   1656 	const VkDevice				vkDevice	= m_context.getDevice();
   1657 	const VkQueue				queue		= m_context.getUniversalQueue();
   1658 
   1659 	const VkImageMemoryBarrier	imageBarrier	=
   1660 	{
   1661 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
   1662 		DE_NULL,									// const void*				pNext;
   1663 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
   1664 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
   1665 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
   1666 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
   1667 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
   1668 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
   1669 		*m_destination,								// VkImage					image;
   1670 		{											// VkImageSubresourceRange	subresourceRange;
   1671 			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
   1672 			0u,								// deUint32				baseMipLevel;
   1673 			1u,								// deUint32				mipLevels;
   1674 			0u,								// deUint32				baseArraySlice;
   1675 			1u								// deUint32				arraySize;
   1676 		}
   1677 	};
   1678 
   1679 	// Copy from buffer to image
   1680 	std::vector<VkBufferImageCopy>		bufferImageCopies;
   1681 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
   1682 		bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
   1683 
   1684 	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
   1685 	{
   1686 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
   1687 		DE_NULL,												// const void*						pNext;
   1688 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
   1689 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
   1690 	};
   1691 
   1692 	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
   1693 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
   1694 	vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
   1695 	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
   1696 
   1697 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
   1698 
   1699 	de::MovePtr<tcu::TextureLevel>	resultLevel	= readImage(*m_destination, m_params.dst.image);
   1700 
   1701 	return checkTestResult(resultLevel->getAccess());
   1702 }
   1703 
   1704 class CopyBufferToImageTestCase : public vkt::TestCase
   1705 {
   1706 public:
   1707 							CopyBufferToImageTestCase	(tcu::TestContext&		testCtx,
   1708 														 const std::string&		name,
   1709 														 const std::string&		description,
   1710 														 const TestParams		params)
   1711 								: vkt::TestCase	(testCtx, name, description)
   1712 								, m_params		(params)
   1713 							{}
   1714 
   1715 	virtual					~CopyBufferToImageTestCase	(void) {}
   1716 
   1717 	virtual TestInstance*	createInstance				(Context&				context) const
   1718 							{
   1719 								return new CopyBufferToImage(context, m_params);
   1720 							}
   1721 private:
   1722 	TestParams				m_params;
   1723 };
   1724 
   1725 void CopyBufferToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
   1726 {
   1727 	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
   1728 	if (!rowLength)
   1729 		rowLength = region.bufferImageCopy.imageExtent.width;
   1730 
   1731 	deUint32			imageHeight	= region.bufferImageCopy.bufferImageHeight;
   1732 	if (!imageHeight)
   1733 		imageHeight = region.bufferImageCopy.imageExtent.height;
   1734 
   1735 	const int			texelSize	= dst.getFormat().getPixelSize();
   1736 	const VkExtent3D	extent		= region.bufferImageCopy.imageExtent;
   1737 	const VkOffset3D	dstOffset	= region.bufferImageCopy.imageOffset;
   1738 	const int			texelOffset	= (int) region.bufferImageCopy.bufferOffset / texelSize;
   1739 
   1740 	for (deUint32 z = 0; z < extent.depth; z++)
   1741 	{
   1742 		for (deUint32 y = 0; y < extent.height; y++)
   1743 		{
   1744 			int									texelIndex		= texelOffset + (z * imageHeight + y) *	rowLength;
   1745 			const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
   1746 			const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
   1747 																					region.bufferImageCopy.imageExtent.width, 1, 1);
   1748 			tcu::copy(dstSubRegion, srcSubRegion);
   1749 		}
   1750 	}
   1751 }
   1752 
   1753 // Copy from image to image with scaling.
   1754 
   1755 class BlittingImages : public CopiesAndBlittingTestInstance
   1756 {
   1757 public:
   1758 										BlittingImages					(Context&	context,
   1759 																		 TestParams params);
   1760 	virtual tcu::TestStatus				iterate							(void);
   1761 protected:
   1762 	virtual tcu::TestStatus				checkTestResult					(tcu::ConstPixelBufferAccess result);
   1763 	virtual void						copyRegionToTextureLevel		(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
   1764 	virtual void						generateExpectedResult			(void);
   1765 private:
   1766 	bool								checkLinearFilteredResult		(const tcu::ConstPixelBufferAccess&	result,
   1767 																		 const tcu::ConstPixelBufferAccess&	clampedReference,
   1768 																		 const tcu::ConstPixelBufferAccess&	unclampedReference,
   1769 																		 const tcu::TextureFormat&			sourceFormat);
   1770 	bool								checkNearestFilteredResult		(const tcu::ConstPixelBufferAccess&	result,
   1771 																		 const tcu::ConstPixelBufferAccess& source);
   1772 
   1773 	Move<VkImage>						m_source;
   1774 	de::MovePtr<Allocation>				m_sourceImageAlloc;
   1775 	Move<VkImage>						m_destination;
   1776 	de::MovePtr<Allocation>				m_destinationImageAlloc;
   1777 
   1778 	de::MovePtr<tcu::TextureLevel>		m_unclampedExpectedTextureLevel;
   1779 };
   1780 
   1781 BlittingImages::BlittingImages (Context& context, TestParams params)
   1782 	: CopiesAndBlittingTestInstance(context, params)
   1783 {
   1784 	const InstanceInterface&	vki					= context.getInstanceInterface();
   1785 	const DeviceInterface&		vk					= context.getDeviceInterface();
   1786 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
   1787 	const VkDevice				vkDevice			= context.getDevice();
   1788 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
   1789 	Allocator&					memAlloc			= context.getDefaultAllocator();
   1790 
   1791 	VkImageFormatProperties properties;
   1792 	if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
   1793 																				m_params.src.image.format,
   1794 																				VK_IMAGE_TYPE_2D,
   1795 																				VK_IMAGE_TILING_OPTIMAL,
   1796 																				VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
   1797 																				0,
   1798 																				&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
   1799 		(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
   1800 																				m_params.dst.image.format,
   1801 																				VK_IMAGE_TYPE_2D,
   1802 																				VK_IMAGE_TILING_OPTIMAL,
   1803 																				VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   1804 																				0,
   1805 																				&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
   1806 	{
   1807 		TCU_THROW(NotSupportedError, "Format not supported");
   1808 	}
   1809 
   1810 	VkFormatProperties srcFormatProperties;
   1811 	context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties);
   1812 	if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
   1813 	{
   1814 		TCU_THROW(NotSupportedError, "Format feature blit source not supported");
   1815 	}
   1816 
   1817 	VkFormatProperties dstFormatProperties;
   1818 	context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties);
   1819 	if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
   1820 	{
   1821 		TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
   1822 	}
   1823 
   1824 	if (m_params.filter == VK_FILTER_LINEAR)
   1825 	{
   1826 		if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
   1827 			TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
   1828 		if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
   1829 			TCU_THROW(NotSupportedError, "Destination format feature sampled image filter linear not supported");
   1830 	}
   1831 
   1832 	// Create source image
   1833 	{
   1834 		const VkImageCreateInfo		sourceImageParams		=
   1835 		{
   1836 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
   1837 			DE_NULL,								// const void*			pNext;
   1838 			0u,										// VkImageCreateFlags	flags;
   1839 			m_params.src.image.imageType,			// VkImageType			imageType;
   1840 			m_params.src.image.format,				// VkFormat				format;
   1841 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
   1842 			1u,										// deUint32				mipLevels;
   1843 			getArraySize(m_params.src.image),		// deUint32				arraySize;
   1844 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
   1845 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
   1846 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
   1847 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
   1848 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
   1849 			1u,										// deUint32				queueFamilyCount;
   1850 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
   1851 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
   1852 		};
   1853 
   1854 		m_source = createImage(vk, vkDevice, &sourceImageParams);
   1855 		m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
   1856 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
   1857 	}
   1858 
   1859 	// Create destination image
   1860 	{
   1861 		const VkImageCreateInfo		destinationImageParams	=
   1862 		{
   1863 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
   1864 			DE_NULL,								// const void*			pNext;
   1865 			0u,										// VkImageCreateFlags	flags;
   1866 			m_params.dst.image.imageType,			// VkImageType			imageType;
   1867 			m_params.dst.image.format,				// VkFormat				format;
   1868 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
   1869 			1u,										// deUint32				mipLevels;
   1870 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
   1871 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
   1872 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
   1873 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
   1874 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
   1875 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
   1876 			1u,										// deUint32				queueFamilyCount;
   1877 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
   1878 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
   1879 		};
   1880 
   1881 		m_destination = createImage(vk, vkDevice, &destinationImageParams);
   1882 		m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
   1883 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
   1884 	}
   1885 }
   1886 
   1887 tcu::TestStatus BlittingImages::iterate (void)
   1888 {
   1889 	const tcu::TextureFormat	srcTcuFormat		= mapVkFormat(m_params.src.image.format);
   1890 	const tcu::TextureFormat	dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
   1891 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
   1892 																				m_params.src.image.extent.width,
   1893 																				m_params.src.image.extent.height,
   1894 																				m_params.src.image.extent.depth));
   1895 	generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_GRADIENT);
   1896 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
   1897 																					 (int)m_params.dst.image.extent.width,
   1898 																					 (int)m_params.dst.image.extent.height,
   1899 																					 (int)m_params.dst.image.extent.depth));
   1900 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_WHITE);
   1901 	generateExpectedResult();
   1902 
   1903 	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
   1904 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
   1905 
   1906 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
   1907 	const VkDevice				vkDevice			= m_context.getDevice();
   1908 	const VkQueue				queue				= m_context.getUniversalQueue();
   1909 
   1910 	std::vector<VkImageBlit>	regions;
   1911 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
   1912 		regions.push_back(m_params.regions[i].imageBlit);
   1913 
   1914 	// Barriers for copying image to buffer
   1915 	const VkImageMemoryBarrier		srcImageBarrier		=
   1916 	{
   1917 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
   1918 		DE_NULL,									// const void*				pNext;
   1919 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
   1920 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
   1921 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
   1922 		m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
   1923 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
   1924 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
   1925 		m_source.get(),								// VkImage					image;
   1926 		{											// VkImageSubresourceRange	subresourceRange;
   1927 			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
   1928 			0u,								// deUint32				baseMipLevel;
   1929 			1u,								// deUint32				mipLevels;
   1930 			0u,								// deUint32				baseArraySlice;
   1931 			1u								// deUint32				arraySize;
   1932 		}
   1933 	};
   1934 
   1935 	const VkImageMemoryBarrier		dstImageBarrier		=
   1936 	{
   1937 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
   1938 		DE_NULL,									// const void*				pNext;
   1939 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
   1940 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
   1941 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
   1942 		m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
   1943 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
   1944 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
   1945 		m_destination.get(),						// VkImage					image;
   1946 		{											// VkImageSubresourceRange	subresourceRange;
   1947 			getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
   1948 			0u,								// deUint32				baseMipLevel;
   1949 			1u,								// deUint32				mipLevels;
   1950 			0u,								// deUint32				baseArraySlice;
   1951 			1u								// deUint32				arraySize;
   1952 		}
   1953 	};
   1954 
   1955 	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
   1956 	{
   1957 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
   1958 		DE_NULL,												// const void*						pNext;
   1959 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
   1960 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
   1961 	};
   1962 
   1963 	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
   1964 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier);
   1965 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier);
   1966 	vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)m_params.regions.size(), &regions[0], m_params.filter);
   1967 	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
   1968 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
   1969 
   1970 	de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
   1971 
   1972 	return checkTestResult(resultTextureLevel->getAccess());
   1973 }
   1974 
   1975 static float calculateFloatConversionError (int srcBits)
   1976 {
   1977 	if (srcBits > 0)
   1978 	{
   1979 		const int	clampedBits	= de::clamp<int>(srcBits, 0, 32);
   1980 		const float	srcMaxValue	= de::max((float)(1ULL<<clampedBits) - 1.0f, 1.0f);
   1981 		const float	error		= 1.0f / srcMaxValue;
   1982 
   1983 		return de::clamp<float>(error, 0.0f, 1.0f);
   1984 	}
   1985 	else
   1986 		return 1.0f;
   1987 }
   1988 
   1989 tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
   1990 {
   1991 	tcu::Vec4 threshold(0.01f);
   1992 
   1993 	switch (format.type)
   1994 	{
   1995 	case tcu::TextureFormat::HALF_FLOAT:
   1996 		threshold = tcu::Vec4(0.005f);
   1997 		break;
   1998 
   1999 	case tcu::TextureFormat::FLOAT:
   2000 	case tcu::TextureFormat::FLOAT64:
   2001 		threshold = tcu::Vec4(0.001f);
   2002 		break;
   2003 
   2004 	case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
   2005 		threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
   2006 		break;
   2007 
   2008 	case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
   2009 		threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f);
   2010 		break;
   2011 
   2012 	default:
   2013 		const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format);
   2014 		threshold = tcu::Vec4(calculateFloatConversionError(bits.x()),
   2015 				      calculateFloatConversionError(bits.y()),
   2016 				      calculateFloatConversionError(bits.z()),
   2017 				      calculateFloatConversionError(bits.w()));
   2018 	}
   2019 
   2020 	// Return value matching the channel order specified by the format
   2021 	if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
   2022 		return threshold.swizzle(2, 1, 0, 3);
   2023 	else
   2024 		return threshold;
   2025 }
   2026 
   2027 bool BlittingImages::checkLinearFilteredResult (const tcu::ConstPixelBufferAccess&	result,
   2028 												const tcu::ConstPixelBufferAccess&	clampedExpected,
   2029 												const tcu::ConstPixelBufferAccess&	unclampedExpected,
   2030 												const tcu::TextureFormat&			srcFormat)
   2031 {
   2032 	tcu::TestLog&				log			(m_context.getTestContext().getLog());
   2033 	const tcu::TextureFormat	dstFormat	= result.getFormat();
   2034 	bool						isOk		= false;
   2035 
   2036 	log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
   2037 
   2038 	if (isFloatFormat(dstFormat))
   2039 	{
   2040 		const bool		srcIsSRGB	= tcu::isSRGB(srcFormat);
   2041 		const tcu::Vec4	srcMaxDiff	= getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
   2042 		const tcu::Vec4	dstMaxDiff	= getFormatThreshold(dstFormat);
   2043 		const tcu::Vec4	threshold	= tcu::max(srcMaxDiff, dstMaxDiff);
   2044 
   2045 		isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
   2046 		log << tcu::TestLog::EndSection;
   2047 
   2048 		if (!isOk)
   2049 		{
   2050 			log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
   2051 			isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
   2052 			log << tcu::TestLog::EndSection;
   2053 		}
   2054 	}
   2055 	else
   2056 	{
   2057 		tcu::UVec4	threshold;
   2058 		// Calculate threshold depending on channel width of destination format.
   2059 		const tcu::IVec4	bitDepth	= tcu::getTextureFormatBitDepth(dstFormat);
   2060 		for (deUint32 i = 0; i < 4; ++i)
   2061 			threshold[i] = de::max( (0x1 << bitDepth[i]) / 256, 1);
   2062 
   2063 		isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
   2064 		log << tcu::TestLog::EndSection;
   2065 
   2066 		if (!isOk)
   2067 		{
   2068 			log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
   2069 			isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
   2070 			log << tcu::TestLog::EndSection;
   2071 		}
   2072 	}
   2073 
   2074 	return isOk;
   2075 }
   2076 
   2077 //! Utility to encapsulate coordinate computation and loops.
   2078 struct CompareEachPixelInEachRegion
   2079 {
   2080 	virtual		 ~CompareEachPixelInEachRegion  (void) {}
   2081 	virtual bool compare						(const void* pUserData, const int x, const int y, const tcu::Vec2& srcNormCoord) const = 0;
   2082 
   2083 	bool forEach (const void*						pUserData,
   2084 				  const std::vector<CopyRegion>&	regions,
   2085 				  const int							sourceWidth,
   2086 				  const int							sourceHeight,
   2087 				  const tcu::PixelBufferAccess&		errorMask) const
   2088 	{
   2089 		bool compareOk = true;
   2090 
   2091 		for (std::vector<CopyRegion>::const_iterator regionIter = regions.begin(); regionIter != regions.end(); ++regionIter)
   2092 		{
   2093 			const VkImageBlit& blit = regionIter->imageBlit;
   2094 
   2095 			const int	dx		= deSign32(blit.dstOffsets[1].x - blit.dstOffsets[0].x);
   2096 			const int	dy		= deSign32(blit.dstOffsets[1].y - blit.dstOffsets[0].y);
   2097 			const float	xScale	= static_cast<float>(blit.srcOffsets[1].x - blit.srcOffsets[0].x) / static_cast<float>(blit.dstOffsets[1].x - blit.dstOffsets[0].x);
   2098 			const float	yScale	= static_cast<float>(blit.srcOffsets[1].y - blit.srcOffsets[0].y) / static_cast<float>(blit.dstOffsets[1].y - blit.dstOffsets[0].y);
   2099 			const float srcInvW	= 1.0f / static_cast<float>(sourceWidth);
   2100 			const float srcInvH	= 1.0f / static_cast<float>(sourceHeight);
   2101 
   2102 			for (int y = blit.dstOffsets[0].y; y < blit.dstOffsets[1].y; y += dy)
   2103 			for (int x = blit.dstOffsets[0].x; x < blit.dstOffsets[1].x; x += dx)
   2104 			{
   2105 				const tcu::Vec2 srcNormCoord
   2106 				(
   2107 					(xScale * (static_cast<float>(x - blit.dstOffsets[0].x) + 0.5f) + static_cast<float>(blit.srcOffsets[0].x)) * srcInvW,
   2108 					(yScale * (static_cast<float>(y - blit.dstOffsets[0].y) + 0.5f) + static_cast<float>(blit.srcOffsets[0].y)) * srcInvH
   2109 				);
   2110 
   2111 				if (!compare(pUserData, x, y, srcNormCoord))
   2112 				{
   2113 					errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
   2114 					compareOk = false;
   2115 				}
   2116 			}
   2117 		}
   2118 		return compareOk;
   2119 	}
   2120 };
   2121 
   2122 tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format)
   2123 {
   2124 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
   2125 	const tcu::IVec4				bitDepth		= tcu::getTextureFormatBitDepth(format);
   2126 
   2127 	if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
   2128 	{
   2129 		return getFormatThreshold(format);
   2130 	}
   2131 	else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
   2132 			 channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
   2133 	{
   2134 		const bool	isSigned	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT);
   2135 		const float	range		= isSigned ? 1.0f - (-1.0f)
   2136 										   : 1.0f -   0.0f;
   2137 
   2138 		tcu::Vec4 v;
   2139 		for (int i = 0; i < 4; ++i)
   2140 		{
   2141 			if (bitDepth[i] == 0)
   2142 				v[i] = 1.0f;
   2143 			else
   2144 				v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
   2145 		}
   2146 		return v;
   2147 	}
   2148 	else
   2149 	{
   2150 		DE_ASSERT(0);
   2151 		return tcu::Vec4();
   2152 	}
   2153 }
   2154 
   2155 bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess&	source,
   2156 							  const tcu::ConstPixelBufferAccess&	result,
   2157 							  const tcu::PixelBufferAccess&			errorMask,
   2158 							  const std::vector<CopyRegion>&		regions)
   2159 {
   2160 	const tcu::Sampler		sampler		(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
   2161 	tcu::LookupPrecision	precision;
   2162 
   2163 	{
   2164 		const tcu::IVec4	dstBitDepth	= tcu::getTextureFormatBitDepth(result.getFormat());
   2165 		const tcu::Vec4		srcMaxDiff	= getFloatOrFixedPointFormatThreshold(source.getFormat());
   2166 		const tcu::Vec4		dstMaxDiff	= getFloatOrFixedPointFormatThreshold(result.getFormat());
   2167 
   2168 		precision.colorMask		 = tcu::notEqual(dstBitDepth, tcu::IVec4(0));
   2169 		precision.colorThreshold = tcu::max(srcMaxDiff, dstMaxDiff);
   2170 	}
   2171 
   2172 	const struct Capture
   2173 	{
   2174 		const tcu::ConstPixelBufferAccess&	source;
   2175 		const tcu::ConstPixelBufferAccess&	result;
   2176 		const tcu::Sampler&					sampler;
   2177 		const tcu::LookupPrecision&			precision;
   2178 		const bool							isSRGB;
   2179 	} capture =
   2180 	{
   2181 		source, result, sampler, precision, tcu::isSRGB(result.getFormat())
   2182 	};
   2183 
   2184 	const struct Loop : CompareEachPixelInEachRegion
   2185 	{
   2186 		Loop (void) {}
   2187 
   2188 		bool compare (const void* pUserData, const int x, const int y, const tcu::Vec2& srcNormCoord) const
   2189 		{
   2190 			const Capture&					c					= *static_cast<const Capture*>(pUserData);
   2191 			const tcu::TexLookupScaleMode	lookupScaleDontCare	= tcu::TEX_LOOKUP_SCALE_MINIFY;
   2192 			tcu::Vec4						dstColor			= c.result.getPixel(x, y);
   2193 
   2194 			// TexLookupVerifier performs a conversion to linear space, so we have to as well
   2195 			if (c.isSRGB)
   2196 				dstColor = tcu::sRGBToLinear(dstColor);
   2197 
   2198 			return tcu::isLevel2DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, 0, dstColor);
   2199 		}
   2200 	} loop;
   2201 
   2202 	return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), errorMask);
   2203 }
   2204 
   2205 bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess&	source,
   2206 							const tcu::ConstPixelBufferAccess&	result,
   2207 							const tcu::PixelBufferAccess&		errorMask,
   2208 							const std::vector<CopyRegion>&		regions)
   2209 {
   2210 	const tcu::Sampler		sampler		(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
   2211 	tcu::IntLookupPrecision	precision;
   2212 
   2213 	{
   2214 		const tcu::IVec4	srcBitDepth	= tcu::getTextureFormatBitDepth(source.getFormat());
   2215 		const tcu::IVec4	dstBitDepth	= tcu::getTextureFormatBitDepth(result.getFormat());
   2216 
   2217 		for (deUint32 i = 0; i < 4; ++i) {
   2218 			precision.colorThreshold[i]	= de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1);
   2219 			precision.colorMask[i]		= dstBitDepth[i] != 0;
   2220 		}
   2221 	}
   2222 
   2223 	// Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that
   2224 	// does the conversion on the fly without wasting memory, but this approach is more straightforward.
   2225 	tcu::TextureLevel				convertedSourceTexture	(result.getFormat(), source.getWidth(), source.getHeight());
   2226 	const tcu::PixelBufferAccess	convertedSource			= convertedSourceTexture.getAccess();
   2227 
   2228 	for (int y = 0; y < source.getHeight(); ++y)
   2229 	for (int x = 0; x < source.getWidth();  ++x)
   2230 		convertedSource.setPixel(source.getPixelInt(x, y), x, y);	// will be clamped to max. representable value
   2231 
   2232 	const struct Capture
   2233 	{
   2234 		const tcu::ConstPixelBufferAccess&	source;
   2235 		const tcu::ConstPixelBufferAccess&	result;
   2236 		const tcu::Sampler&					sampler;
   2237 		const tcu::IntLookupPrecision&		precision;
   2238 	} capture =
   2239 	{
   2240 		convertedSource, result, sampler, precision
   2241 	};
   2242 
   2243 	const struct Loop : CompareEachPixelInEachRegion
   2244 	{
   2245 		Loop (void) {}
   2246 
   2247 		bool compare (const void* pUserData, const int x, const int y, const tcu::Vec2& srcNormCoord) const
   2248 		{
   2249 			const Capture&					c					= *static_cast<const Capture*>(pUserData);
   2250 			const tcu::TexLookupScaleMode	lookupScaleDontCare	= tcu::TEX_LOOKUP_SCALE_MINIFY;
   2251 			const tcu::IVec4				dstColor			= c.result.getPixelInt(x, y);
   2252 
   2253 			return tcu::isLevel2DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, 0, dstColor);
   2254 		}
   2255 	} loop;
   2256 
   2257 	return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), errorMask);
   2258 }
   2259 
   2260 bool BlittingImages::checkNearestFilteredResult (const tcu::ConstPixelBufferAccess&	result,
   2261 												 const tcu::ConstPixelBufferAccess& source)
   2262 {
   2263 	tcu::TestLog&					log				(m_context.getTestContext().getLog());
   2264 	const tcu::TextureFormat		dstFormat		= result.getFormat();
   2265 	const tcu::TextureChannelClass	dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
   2266 
   2267 	tcu::TextureLevel		errorMaskStorage	(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight());
   2268 	tcu::PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
   2269 	tcu::Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
   2270 	tcu::Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);
   2271 	bool					ok					= false;
   2272 
   2273 	tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
   2274 
   2275 	if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
   2276 		dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
   2277 	{
   2278 		ok = intNearestBlitCompare(source, result, errorMask, m_params.regions);
   2279 	}
   2280 	else
   2281 		ok = floatNearestBlitCompare(source, result, errorMask, m_params.regions);
   2282 
   2283 	if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
   2284 		tcu::computePixelScaleBias(result, pixelScale, pixelBias);
   2285 
   2286 	if (!ok)
   2287 	{
   2288 		log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
   2289 			<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
   2290 			<< tcu::TestLog::Image("ErrorMask",	"Error mask", errorMask)
   2291 			<< tcu::TestLog::EndImageSet;
   2292 	}
   2293 	else
   2294 	{
   2295 		log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
   2296 			<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
   2297 			<< tcu::TestLog::EndImageSet;
   2298 	}
   2299 
   2300 	return ok;
   2301 }
   2302 
   2303 tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result)
   2304 {
   2305 	DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR);
   2306 	const std::string failMessage("Result image is incorrect");
   2307 
   2308 	if (m_params.filter == VK_FILTER_LINEAR)
   2309 	{
   2310 		if (tcu::isCombinedDepthStencilType(result.getFormat().type))
   2311 		{
   2312 			if (tcu::hasDepthComponent(result.getFormat().order))
   2313 			{
   2314 				const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
   2315 				const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
   2316 				const tcu::ConstPixelBufferAccess		clampedExpected		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
   2317 				const tcu::ConstPixelBufferAccess		unclampedExpected	= tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
   2318 				const tcu::TextureFormat				sourceFormat		= tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
   2319 
   2320 				if (!checkLinearFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat))
   2321 					return tcu::TestStatus::fail(failMessage);
   2322 			}
   2323 
   2324 			if (tcu::hasStencilComponent(result.getFormat().order))
   2325 			{
   2326 				const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
   2327 				const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
   2328 				const tcu::ConstPixelBufferAccess		clampedExpected		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
   2329 				const tcu::ConstPixelBufferAccess		unclampedExpected	= tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
   2330 				const tcu::TextureFormat				sourceFormat		= tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
   2331 
   2332 				if (!checkLinearFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat))
   2333 					return tcu::TestStatus::fail(failMessage);
   2334 			}
   2335 		}
   2336 		else
   2337 		{
   2338 			const tcu::TextureFormat	sourceFormat	= mapVkFormat(m_params.src.image.format);
   2339 
   2340 			if (!checkLinearFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), sourceFormat))
   2341 				return tcu::TestStatus::fail(failMessage);
   2342 		}
   2343 	}
   2344 	else // NEAREST filtering
   2345 	{
   2346 		if (tcu::isCombinedDepthStencilType(result.getFormat().type))
   2347 		{
   2348 			if (tcu::hasDepthComponent(result.getFormat().order))
   2349 			{
   2350 				const tcu::Sampler::DepthStencilMode	mode			= tcu::Sampler::MODE_DEPTH;
   2351 				const tcu::ConstPixelBufferAccess		depthResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
   2352 				const tcu::ConstPixelBufferAccess		depthSource		= tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
   2353 
   2354 				if (!checkNearestFilteredResult(depthResult, depthSource))
   2355 					return tcu::TestStatus::fail(failMessage);
   2356 			}
   2357 
   2358 			if (tcu::hasStencilComponent(result.getFormat().order))
   2359 			{
   2360 				const tcu::Sampler::DepthStencilMode	mode			= tcu::Sampler::MODE_STENCIL;
   2361 				const tcu::ConstPixelBufferAccess		stencilResult	= tcu::getEffectiveDepthStencilAccess(result, mode);
   2362 				const tcu::ConstPixelBufferAccess		stencilSource	= tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
   2363 
   2364 				if (!checkNearestFilteredResult(stencilResult, stencilSource))
   2365 					return tcu::TestStatus::fail(failMessage);
   2366 			}
   2367 		}
   2368 		else
   2369 		{
   2370 			if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess()))
   2371 				return tcu::TestStatus::fail(failMessage);
   2372 		}
   2373 	}
   2374 
   2375 	return tcu::TestStatus::pass("Pass");
   2376 }
   2377 
   2378 tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
   2379 {
   2380 	return isSRGB(format) ? linearToSRGB(color) : color;
   2381 }
   2382 
   2383 void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter)
   2384 {
   2385 	DE_ASSERT(filter == tcu::Sampler::LINEAR);
   2386 	DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1);
   2387 
   2388 	tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
   2389 					filter, filter, 0.0f, false);
   2390 
   2391 	float sX = (float)regionExtent.x / (float)dst.getWidth();
   2392 	float sY = (float)regionExtent.y / (float)dst.getHeight();
   2393 
   2394 	for (int y = 0; y < dst.getHeight(); y++)
   2395 	for (int x = 0; x < dst.getWidth(); x++)
   2396 		dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, (float)regionOffset.x + ((float)x+0.5f)*sX, (float)regionOffset.y + ((float)y+0.5f)*sY, 0)), x, y);
   2397 }
   2398 
   2399 void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
   2400 {
   2401 	DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR);
   2402 
   2403 	tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
   2404 						 filter, filter, 0.0f, false);
   2405 
   2406 	const float sX = (float)src.getWidth() / (float)dst.getWidth();
   2407 	const float sY = (float)src.getHeight() / (float)dst.getHeight();
   2408 	const float sZ = (float)src.getDepth() / (float)dst.getDepth();
   2409 
   2410 	tcu::Mat2 rotMatrix;
   2411 	rotMatrix(0,0) = (mirrorMode & MIRROR_MODE_X) ? -1.0f : 1.0f;
   2412 	rotMatrix(0,1) = 0.0f;
   2413 	rotMatrix(1,0) = 0.0f;
   2414 	rotMatrix(1,1) = (mirrorMode & MIRROR_MODE_Y) ? -1.0f : 1.0f;
   2415 
   2416 	const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
   2417 	const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
   2418 
   2419 	if (dst.getDepth() == 1 && src.getDepth() == 1)
   2420 	{
   2421 		for (int y = 0; y < dst.getHeight(); ++y)
   2422 		for (int x = 0; x < dst.getWidth(); ++x)
   2423 		{
   2424 			const tcu::Vec2 xy = rotMatrix * tcu::Vec2((float)x,(float)y);
   2425 			dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, ((float)x+0.5f)*sX, ((float)y+0.5f)*sY, 0)), (int)round(xy[0]) + xOffset, (int)round(xy[1]) + yOffset);
   2426 		}
   2427 	}
   2428 	else
   2429 	{
   2430 		for (int z = 0; z < dst.getDepth(); ++z)
   2431 		for (int y = 0; y < dst.getHeight(); ++y)
   2432 		for (int x = 0; x < dst.getWidth(); ++x)
   2433 		{
   2434 			const tcu::Vec2 xy = rotMatrix * tcu::Vec2((float)x,(float)y);
   2435 			dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, ((float)x+0.5f)*sX, ((float)y+0.5f)*sY, ((float)z+0.5f)*sZ)), (int)round(xy[0]) + xOffset, (int)round(xy[1]) + yOffset, z);
   2436 		}
   2437 	}
   2438 }
   2439 
   2440 void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode)
   2441 {
   2442 	const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
   2443 	const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
   2444 	const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
   2445 	const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];
   2446 
   2447 	if (mirrorMode > MIRROR_MODE_NONE && mirrorMode < MIRROR_MODE_LAST)
   2448 	{
   2449 		//sourceRegion
   2450 		region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
   2451 		region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
   2452 
   2453 		region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
   2454 		region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
   2455 
   2456 		//destinationRegion
   2457 		region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
   2458 		region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
   2459 
   2460 		region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
   2461 		region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
   2462 	}
   2463 }
   2464 
   2465 MirrorMode getMirrorMode(const VkOffset3D x1, const VkOffset3D x2)
   2466 {
   2467 	if (x1.x >= x2.x && x1.y >= x2.y)
   2468 	{
   2469 		return MIRROR_MODE_XY;
   2470 	}
   2471 	else if (x1.x <= x2.x && x1.y <= x2.y)
   2472 	{
   2473 		return MIRROR_MODE_NONE;
   2474 	}
   2475 	else if (x1.x <= x2.x && x1.y >= x2.y)
   2476 	{
   2477 		return MIRROR_MODE_Y;
   2478 	}
   2479 	else if (x1.x >= x2.x && x1.y <= x2.y)
   2480 	{
   2481 		return MIRROR_MODE_X;
   2482 	}
   2483 	return MIRROR_MODE_LAST;
   2484 }
   2485 
   2486 MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
   2487 {
   2488 	const MirrorMode source		 = getMirrorMode(s1, s2);
   2489 	const MirrorMode destination = getMirrorMode(d1, d2);
   2490 
   2491 	if (source == destination)
   2492 	{
   2493 		return MIRROR_MODE_NONE;
   2494 	}
   2495 	else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_X)	  || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_X) ||
   2496 			 (source == MIRROR_MODE_Y && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_Y && source == MIRROR_MODE_NONE))
   2497 	{
   2498 		return MIRROR_MODE_Y;
   2499 	}
   2500 	else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_Y)	  || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_Y) ||
   2501 			 (source == MIRROR_MODE_X && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_X && source == MIRROR_MODE_NONE))
   2502 	{
   2503 		return MIRROR_MODE_X;
   2504 	}
   2505 	else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_NONE))
   2506 	{
   2507 		return MIRROR_MODE_XY;
   2508 	}
   2509 	return MIRROR_MODE_LAST;
   2510 }
   2511 
   2512 void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
   2513 {
   2514 	const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
   2515 												region.imageBlit.srcOffsets[1],
   2516 												region.imageBlit.dstOffsets[0],
   2517 												region.imageBlit.dstOffsets[1]);
   2518 
   2519 	flipCoordinates(region, mirrorMode);
   2520 
   2521 	const VkOffset3D					srcOffset		= region.imageBlit.srcOffsets[0];
   2522 	const VkOffset3D					srcExtent		=
   2523 	{
   2524 		region.imageBlit.srcOffsets[1].x - srcOffset.x,
   2525 		region.imageBlit.srcOffsets[1].y - srcOffset.y,
   2526 		region.imageBlit.srcOffsets[1].z - srcOffset.z
   2527 	};
   2528 	const VkOffset3D					dstOffset		= region.imageBlit.dstOffsets[0];
   2529 	const VkOffset3D					dstExtent		=
   2530 	{
   2531 		region.imageBlit.dstOffsets[1].x - dstOffset.x,
   2532 		region.imageBlit.dstOffsets[1].y - dstOffset.y,
   2533 		region.imageBlit.dstOffsets[1].z - dstOffset.z
   2534 	};
   2535 	const tcu::Sampler::FilterMode		filter			= (m_params.filter == VK_FILTER_LINEAR) ? tcu::Sampler::LINEAR : tcu::Sampler::NEAREST;
   2536 
   2537 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
   2538 	{
   2539 		DE_ASSERT(src.getFormat() == dst.getFormat());
   2540 		// Scale depth.
   2541 		if (tcu::hasDepthComponent(src.getFormat().order))
   2542 		{
   2543 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
   2544 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
   2545 			tcu::scale(dstSubRegion, srcSubRegion, filter);
   2546 
   2547 			if (filter == tcu::Sampler::LINEAR)
   2548 			{
   2549 				const tcu::ConstPixelBufferAccess	depthSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
   2550 				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
   2551 				scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
   2552 			}
   2553 		}
   2554 
   2555 		// Scale stencil.
   2556 		if (tcu::hasStencilComponent(src.getFormat().order))
   2557 		{
   2558 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
   2559 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
   2560 			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
   2561 
   2562 			if (filter == tcu::Sampler::LINEAR)
   2563 			{
   2564 				const tcu::ConstPixelBufferAccess	stencilSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
   2565 				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
   2566 				scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
   2567 			}
   2568 		}
   2569 	}
   2570 	else
   2571 	{
   2572 		const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y);
   2573 		const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y);
   2574 		blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
   2575 
   2576 		if (filter == tcu::Sampler::LINEAR)
   2577 		{
   2578 			const tcu::PixelBufferAccess	unclampedSubRegion	= tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y);
   2579 			scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter);
   2580 		}
   2581 	}
   2582 }
   2583 
   2584 void BlittingImages::generateExpectedResult (void)
   2585 {
   2586 	const tcu::ConstPixelBufferAccess	src	= m_sourceTextureLevel->getAccess();
   2587 	const tcu::ConstPixelBufferAccess	dst	= m_destinationTextureLevel->getAccess();
   2588 
   2589 	m_expectedTextureLevel[0]		= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
   2590 	tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
   2591 
   2592 	if (m_params.filter == VK_FILTER_LINEAR)
   2593 	{
   2594 		m_unclampedExpectedTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
   2595 		tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst);
   2596 	}
   2597 
   2598 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
   2599 	{
   2600 		CopyRegion region = m_params.regions[i];
   2601 		copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), region);
   2602 	}
   2603 }
   2604 
   2605 class BlitImageTestCase : public vkt::TestCase
   2606 {
   2607 public:
   2608 							BlitImageTestCase		(tcu::TestContext&				testCtx,
   2609 													 const std::string&				name,
   2610 													 const std::string&				description,
   2611 													 const TestParams				params)
   2612 								: vkt::TestCase	(testCtx, name, description)
   2613 								, m_params		(params)
   2614 							{}
   2615 
   2616 	virtual TestInstance*	createInstance			(Context&						context) const
   2617 							{
   2618 								return new BlittingImages(context, m_params);
   2619 							}
   2620 private:
   2621 	TestParams				m_params;
   2622 };
   2623 
   2624 class BlittingMipmaps : public CopiesAndBlittingTestInstance
   2625 {
   2626 public:
   2627 										BlittingMipmaps					(Context&   context,
   2628 																		 TestParams params);
   2629 	virtual tcu::TestStatus				iterate							(void);
   2630 protected:
   2631 	virtual tcu::TestStatus				checkTestResult					(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
   2632 	virtual void						copyRegionToTextureLevel		(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
   2633 	virtual void						generateExpectedResult			(void);
   2634 private:
   2635 	bool								checkLinearFilteredResult		(void);
   2636 	bool								checkNearestFilteredResult		(void);
   2637 
   2638 	Move<VkImage>						m_source;
   2639 	de::MovePtr<Allocation>				m_sourceImageAlloc;
   2640 	Move<VkImage>						m_destination;
   2641 	de::MovePtr<Allocation>				m_destinationImageAlloc;
   2642 
   2643 	de::MovePtr<tcu::TextureLevel>		m_unclampedExpectedTextureLevel[16];
   2644 };
   2645 
   2646 BlittingMipmaps::BlittingMipmaps (Context& context, TestParams params)
   2647 	: CopiesAndBlittingTestInstance (context, params)
   2648 {
   2649 	const InstanceInterface&	vki					= context.getInstanceInterface();
   2650 	const DeviceInterface&		vk					= context.getDeviceInterface();
   2651 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
   2652 	const VkDevice				vkDevice			= context.getDevice();
   2653 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
   2654 	Allocator&					memAlloc			= context.getDefaultAllocator();
   2655 
   2656 	{
   2657 		VkImageFormatProperties	properties;
   2658 		if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
   2659 																				   m_params.src.image.format,
   2660 																				   VK_IMAGE_TYPE_2D,
   2661 																				   VK_IMAGE_TILING_OPTIMAL,
   2662 																				   VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
   2663 																				   0,
   2664 																				   &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
   2665 		{
   2666 			TCU_THROW(NotSupportedError, "Format not supported");
   2667 		}
   2668 		else if ((m_params.src.image.extent.width	> properties.maxExtent.width)	||
   2669 				 (m_params.src.image.extent.height	> properties.maxExtent.height)	||
   2670 				 (m_params.src.image.extent.depth	> properties.maxExtent.depth))
   2671 		{
   2672 			TCU_THROW(NotSupportedError, "Image size not supported");
   2673 		}
   2674 	}
   2675 
   2676 	{
   2677 		VkImageFormatProperties	properties;
   2678 		if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
   2679 																				   m_params.dst.image.format,
   2680 																				   VK_IMAGE_TYPE_2D,
   2681 																				   VK_IMAGE_TILING_OPTIMAL,
   2682 																				   VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   2683 																				   0,
   2684 																				   &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
   2685 		{
   2686 			TCU_THROW(NotSupportedError, "Format not supported");
   2687 		}
   2688 		else if ((m_params.dst.image.extent.width	> properties.maxExtent.width)	||
   2689 				 (m_params.dst.image.extent.height	> properties.maxExtent.height)	||
   2690 				 (m_params.dst.image.extent.depth	> properties.maxExtent.depth))
   2691 		{
   2692 			TCU_THROW(NotSupportedError, "Image size not supported");
   2693 		}
   2694 		else if (m_params.mipLevels > properties.maxMipLevels)
   2695 		{
   2696 			TCU_THROW(NotSupportedError, "Number of mip levels not supported");
   2697 		}
   2698 	}
   2699 
   2700 	const VkFormatProperties	srcFormatProperties	= getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.src.image.format);
   2701 	if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
   2702 	{
   2703 		TCU_THROW(NotSupportedError, "Format feature blit source not supported");
   2704 	}
   2705 
   2706 	const VkFormatProperties	dstFormatProperties	= getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.dst.image.format);
   2707 	if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
   2708 	{
   2709 		TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
   2710 	}
   2711 
   2712 	if (m_params.filter == VK_FILTER_LINEAR)
   2713 	{
   2714 		if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
   2715 			TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
   2716 		if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
   2717 			TCU_THROW(NotSupportedError, "Destination format feature sampled image filter linear not supported");
   2718 	}
   2719 
   2720 	// Create source image
   2721 	{
   2722 		const VkImageCreateInfo		sourceImageParams		=
   2723 		{
   2724 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
   2725 			DE_NULL,								// const void*			pNext;
   2726 			0u,										// VkImageCreateFlags	flags;
   2727 			m_params.src.image.imageType,			// VkImageType			imageType;
   2728 			m_params.src.image.format,				// VkFormat				format;
   2729 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
   2730 			1u,										// deUint32				mipLevels;
   2731 			getArraySize(m_params.src.image),		// deUint32				arraySize;
   2732 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
   2733 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
   2734 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
   2735 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
   2736 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
   2737 			1u,										// deUint32				queueFamilyCount;
   2738 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
   2739 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
   2740 		};
   2741 
   2742 		m_source = createImage(vk, vkDevice, &sourceImageParams);
   2743 		m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
   2744 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
   2745 	}
   2746 
   2747 	// Create destination image
   2748 	{
   2749 		const VkImageCreateInfo		destinationImageParams  =
   2750 		{
   2751 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
   2752 			DE_NULL,								// const void*			pNext;
   2753 			0u,										// VkImageCreateFlags	flags;
   2754 			m_params.dst.image.imageType,			// VkImageType			imageType;
   2755 			m_params.dst.image.format,				// VkFormat				format;
   2756 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
   2757 			m_params.mipLevels,						// deUint32				mipLevels;
   2758 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
   2759 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
   2760 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
   2761 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
   2762 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
   2763 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
   2764 			1u,										// deUint32				queueFamilyCount;
   2765 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
   2766 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
   2767 		};
   2768 
   2769 		m_destination = createImage(vk, vkDevice, &destinationImageParams);
   2770 		m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
   2771 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
   2772 	}
   2773 }
   2774 
   2775 tcu::TestStatus BlittingMipmaps::iterate (void)
   2776 {
   2777 	const tcu::TextureFormat	srcTcuFormat		= mapVkFormat(m_params.src.image.format);
   2778 	const tcu::TextureFormat	dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
   2779 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
   2780 																				m_params.src.image.extent.width,
   2781 																				m_params.src.image.extent.height,
   2782 																				m_params.src.image.extent.depth));
   2783 	generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_GRADIENT);
   2784 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
   2785 																						(int)m_params.dst.image.extent.width,
   2786 																						(int)m_params.dst.image.extent.height,
   2787 																						(int)m_params.dst.image.extent.depth));
   2788 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_WHITE);
   2789 	generateExpectedResult();
   2790 
   2791 	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
   2792 
   2793 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
   2794 
   2795 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
   2796 	const VkDevice				vkDevice			= m_context.getDevice();
   2797 	const VkQueue				queue				= m_context.getUniversalQueue();
   2798 
   2799 	std::vector<VkImageBlit>	regions;
   2800 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
   2801 		regions.push_back(m_params.regions[i].imageBlit);
   2802 
   2803 	// Copy source image to mip level 0 when generating mipmaps with multiple blit commands
   2804 	if (!m_params.singleCommand)
   2805 		uploadImage(m_sourceTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, 1u);
   2806 
   2807 	const VkCommandBufferBeginInfo  cmdBufferBeginInfo  =
   2808 	{
   2809 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
   2810 		DE_NULL,												// const void*						pNext;
   2811 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
   2812 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
   2813 	};
   2814 
   2815 	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
   2816 
   2817 	// Blit all mip levels with a single blit command
   2818 	if (m_params.singleCommand)
   2819 	{
   2820 		{
   2821 			// Source image layout
   2822 			const VkImageMemoryBarrier		srcImageBarrier		=
   2823 			{
   2824 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
   2825 				DE_NULL,									// const void*				pNext;
   2826 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
   2827 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
   2828 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
   2829 				m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
   2830 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
   2831 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
   2832 				m_source.get(),								// VkImage					image;
   2833 				{											// VkImageSubresourceRange	subresourceRange;
   2834 					getAspectFlags(srcTcuFormat),	// VkImageAspectFlags   aspectMask;
   2835 					0u,								// deUint32				baseMipLevel;
   2836 					1u,								// deUint32				mipLevels;
   2837 					0u,								// deUint32				baseArraySlice;
   2838 					1u								// deUint32				arraySize;
   2839 				}
   2840 			};
   2841 
   2842 			// Destination image layout
   2843 			const VkImageMemoryBarrier		dstImageBarrier		=
   2844 			{
   2845 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
   2846 				DE_NULL,									// const void*				pNext;
   2847 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
   2848 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
   2849 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
   2850 				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
   2851 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
   2852 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
   2853 				m_destination.get(),						// VkImage					image;
   2854 				{											// VkImageSubresourceRange	subresourceRange;
   2855 					getAspectFlags(dstTcuFormat),	// VkImageAspectFlags   aspectMask;
   2856 					0u,								// deUint32				baseMipLevel;
   2857 					m_params.mipLevels,				// deUint32				mipLevels;
   2858 					0u,								// deUint32				baseArraySlice;
   2859 					1u								// deUint32				arraySize;
   2860 				}
   2861 			};
   2862 
   2863 			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier);
   2864 			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier);
   2865 			vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)regions.size(), &regions[0], m_params.filter);
   2866 		}
   2867 	}
   2868 	// Blit mip levels with multiple blit commands
   2869 	else
   2870 	{
   2871 		// Prepare all mip levels for reading
   2872 		{
   2873 			const VkImageMemoryBarrier		preImageBarrier		=
   2874 			{
   2875 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
   2876 				DE_NULL,									// const void*				pNext;
   2877 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
   2878 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
   2879 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
   2880 				m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
   2881 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
   2882 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
   2883 				m_destination.get(),						// VkImage					image;
   2884 				{											// VkImageSubresourceRange	subresourceRange;
   2885 					getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
   2886 					0u,								// deUint32				baseMipLevel;
   2887 					VK_REMAINING_MIP_LEVELS,		// deUint32				mipLevels;
   2888 					0u,								// deUint32				baseArraySlice;
   2889 					1u								// deUint32				arraySize;
   2890 				}
   2891 			};
   2892 
   2893 			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
   2894 		}
   2895 
   2896 		for (deUint32 regionNdx = 0u; regionNdx < (deUint32)regions.size(); regionNdx++)
   2897 		{
   2898 			const deUint32					mipLevel			= regions[regionNdx].dstSubresource.mipLevel;
   2899 
   2900 			// Prepare single mip level for writing
   2901 			const VkImageMemoryBarrier		preImageBarrier		=
   2902 			{
   2903 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
   2904 				DE_NULL,									// const void*					pNext;
   2905 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
   2906 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
   2907 				m_params.src.image.operationLayout,			// VkImageLayout			oldLayout;
   2908 				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
   2909 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
   2910 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
   2911 				m_destination.get(),						// VkImage					image;
   2912 				{											// VkImageSubresourceRange	subresourceRange;
   2913 					getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
   2914 					mipLevel,						// deUint32				baseMipLevel;
   2915 					1u,								// deUint32				mipLevels;
   2916 					0u,								// deUint32				baseArraySlice;
   2917 					1u								// deUint32				arraySize;
   2918 				}
   2919 			};
   2920 
   2921 			// Prepare single mip level for reading
   2922 			const VkImageMemoryBarrier		postImageBarrier	=
   2923 			{
   2924 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
   2925 				DE_NULL,									// const void*				pNext;
   2926 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
   2927 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
   2928 				m_params.dst.image.operationLayout,			// VkImageLayout			oldLayout;
   2929 				m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
   2930 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
   2931 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
   2932 				m_destination.get(),						// VkImage					image;
   2933 				{											// VkImageSubresourceRange	subresourceRange;
   2934 					getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
   2935 					mipLevel,						// deUint32				baseMipLevel;
   2936 					1u,								// deUint32				mipLevels;
   2937 					0u,								// deUint32				baseArraySlice;
   2938 					1u								// deUint32				arraySize;
   2939 				}
   2940 			};
   2941 
   2942 			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
   2943 			vk.cmdBlitImage(*m_cmdBuffer, m_destination.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, 1u, &regions[regionNdx], m_params.filter);
   2944 			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
   2945 		}
   2946 
   2947 		// Prepare all mip levels for writing
   2948 		{
   2949 			const VkImageMemoryBarrier		postImageBarrier		=
   2950 			{
   2951 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
   2952 				DE_NULL,									// const void*				pNext;
   2953 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
   2954 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
   2955 				m_params.src.image.operationLayout,			// VkImageLayout			oldLayout;
   2956 				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
   2957 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
   2958 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
   2959 				m_destination.get(),						// VkImage					image;
   2960 				{											// VkImageSubresourceRange	subresourceRange;
   2961 					getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
   2962 					0u,								// deUint32				baseMipLevel;
   2963 					VK_REMAINING_MIP_LEVELS,		// deUint32				mipLevels;
   2964 					0u,								// deUint32				baseArraySlice;
   2965 					1u								// deUint32				arraySize;
   2966 				}
   2967 			};
   2968 
   2969 			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
   2970 		}
   2971 	}
   2972 
   2973 	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
   2974 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
   2975 
   2976 	return checkTestResult();
   2977 }
   2978 
   2979 bool BlittingMipmaps::checkLinearFilteredResult (void)
   2980 {
   2981 	tcu::TestLog&				log				(m_context.getTestContext().getLog());
   2982 	bool						allLevelsOk		= true;
   2983 
   2984 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
   2985 	{
   2986 		de::MovePtr<tcu::TextureLevel>			resultLevel			= readImage(*m_destination, m_params.dst.image, mipLevelNdx);
   2987 		const tcu::ConstPixelBufferAccess&		resultAccess		= resultLevel->getAccess();
   2988 
   2989 		const tcu::Sampler::DepthStencilMode	mode				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::Sampler::MODE_DEPTH :
   2990 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
   2991 																																	tcu::Sampler::MODE_LAST;
   2992 		const tcu::ConstPixelBufferAccess		result				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(resultAccess, mode) :
   2993 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
   2994 																																	resultAccess;
   2995 		const tcu::ConstPixelBufferAccess		clampedLevel		= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
   2996 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
   2997 																																	m_expectedTextureLevel[mipLevelNdx]->getAccess();
   2998 		const tcu::ConstPixelBufferAccess		unclampedLevel		= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
   2999 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
   3000 																																	m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess();
   3001 		const tcu::TextureFormat				srcFormat			= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
   3002 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
   3003 																																	mapVkFormat(m_params.src.image.format);
   3004 
   3005 		const tcu::TextureFormat				dstFormat			= result.getFormat();
   3006 		bool									singleLevelOk		= false;
   3007 		std::vector <CopyRegion>				mipLevelRegions;
   3008 
   3009 		for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
   3010 			if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
   3011 				mipLevelRegions.push_back(m_params.regions.at(regionNdx));
   3012 
   3013 		log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
   3014 
   3015 		if (isFloatFormat(dstFormat))
   3016 		{
   3017 			const bool		srcIsSRGB   = tcu::isSRGB(srcFormat);
   3018 			const tcu::Vec4 srcMaxDiff  = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
   3019 			const tcu::Vec4 dstMaxDiff  = getFormatThreshold(dstFormat);
   3020 			const tcu::Vec4 threshold   = tcu::max(srcMaxDiff, dstMaxDiff);
   3021 
   3022 			singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
   3023 			log << tcu::TestLog::EndSection;
   3024 
   3025 			if (!singleLevelOk)
   3026 			{
   3027 				log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
   3028 				singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
   3029 				log << tcu::TestLog::EndSection;
   3030 			}
   3031 		}
   3032 		else
   3033 		{
   3034 			tcu::UVec4  threshold;
   3035 			// Calculate threshold depending on channel width of destination format.
   3036 			const tcu::IVec4	bitDepth	= tcu::getTextureFormatBitDepth(dstFormat);
   3037 			for (deUint32 i = 0; i < 4; ++i)
   3038 				threshold[i] = de::max( (0x1 << bitDepth[i]) / 256, 1);
   3039 
   3040 			singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
   3041 			log << tcu::TestLog::EndSection;
   3042 
   3043 			if (!singleLevelOk)
   3044 			{
   3045 				log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
   3046 				singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
   3047 				log << tcu::TestLog::EndSection;
   3048 			}
   3049 		}
   3050 		allLevelsOk &= singleLevelOk;
   3051 	}
   3052 
   3053 	return allLevelsOk;
   3054 }
   3055 
   3056 bool BlittingMipmaps::checkNearestFilteredResult (void)
   3057 {
   3058 	bool						allLevelsOk		= true;
   3059 	tcu::TestLog&				log				(m_context.getTestContext().getLog());
   3060 
   3061 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
   3062 	{
   3063 		de::MovePtr<tcu::TextureLevel>			resultLevel			= readImage(*m_destination, m_params.dst.image, mipLevelNdx);
   3064 		const tcu::ConstPixelBufferAccess&		resultAccess		= resultLevel->getAccess();
   3065 
   3066 		const tcu::Sampler::DepthStencilMode	mode				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::Sampler::MODE_DEPTH :
   3067 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
   3068 																																	tcu::Sampler::MODE_LAST;
   3069 		const tcu::ConstPixelBufferAccess		result				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(resultAccess, mode) :
   3070 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
   3071 																																	resultAccess;
   3072 		const tcu::ConstPixelBufferAccess		source				= (m_params.singleCommand || mipLevelNdx == 0) ?			//  Read from source image
   3073 																	  tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
   3074 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
   3075 																																	m_sourceTextureLevel->getAccess()
   3076 																																//  Read from destination image
   3077 																	: tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
   3078 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
   3079 																																	m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess();
   3080 		const tcu::TextureFormat				dstFormat			= result.getFormat();
   3081 		const tcu::TextureChannelClass			dstChannelClass		= tcu::getTextureChannelClass(dstFormat.type);
   3082 		bool									singleLevelOk		= false;
   3083 		std::vector <CopyRegion>				mipLevelRegions;
   3084 
   3085 		for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
   3086 			if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
   3087 				mipLevelRegions.push_back(m_params.regions.at(regionNdx));
   3088 
   3089 		tcu::TextureLevel				errorMaskStorage	(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight());
   3090 		tcu::PixelBufferAccess			errorMask			= errorMaskStorage.getAccess();
   3091 		tcu::Vec4						pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
   3092 		tcu::Vec4						pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);
   3093 
   3094 		tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
   3095 
   3096 		if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
   3097 			dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
   3098 		{
   3099 			singleLevelOk = intNearestBlitCompare(source, result, errorMask, mipLevelRegions);
   3100 		}
   3101 		else
   3102 			singleLevelOk = floatNearestBlitCompare(source, result, errorMask, mipLevelRegions);
   3103 
   3104 		if (dstFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
   3105 			tcu::computePixelScaleBias(result, pixelScale, pixelBias);
   3106 
   3107 		if (!singleLevelOk)
   3108 		{
   3109 			log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
   3110 				<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
   3111 				<< tcu::TestLog::Image("Reference", "Reference", source, pixelScale, pixelBias)
   3112 				<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
   3113 				<< tcu::TestLog::EndImageSet;
   3114 		}
   3115 		else
   3116 		{
   3117 			log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
   3118 				<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
   3119 				<< tcu::TestLog::EndImageSet;
   3120 		}
   3121 
   3122 		allLevelsOk &= singleLevelOk;
   3123 	}
   3124 
   3125 	return allLevelsOk;
   3126 }
   3127 
   3128 tcu::TestStatus BlittingMipmaps::checkTestResult (tcu::ConstPixelBufferAccess result)
   3129 {
   3130 	DE_UNREF(result);
   3131 	DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR);
   3132 	const std::string failMessage("Result image is incorrect");
   3133 
   3134 	if (m_params.filter == VK_FILTER_LINEAR)
   3135 	{
   3136 		if (!checkLinearFilteredResult())
   3137 			return tcu::TestStatus::fail(failMessage);
   3138 	}
   3139 	else // NEAREST filtering
   3140 	{
   3141 		if (!checkNearestFilteredResult())
   3142 			return tcu::TestStatus::fail(failMessage);
   3143 	}
   3144 
   3145 	return tcu::TestStatus::pass("Pass");
   3146 }
   3147 
   3148 void BlittingMipmaps::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
   3149 {
   3150 	const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
   3151 												region.imageBlit.srcOffsets[1],
   3152 												region.imageBlit.dstOffsets[0],
   3153 												region.imageBlit.dstOffsets[1]);
   3154 
   3155 	flipCoordinates(region, mirrorMode);
   3156 
   3157 	const VkOffset3D					srcOffset		= region.imageBlit.srcOffsets[0];
   3158 	const VkOffset3D					srcExtent		=
   3159 	{
   3160 		region.imageBlit.srcOffsets[1].x - srcOffset.x,
   3161 		region.imageBlit.srcOffsets[1].y - srcOffset.y,
   3162 		region.imageBlit.srcOffsets[1].z - srcOffset.z
   3163 	};
   3164 	const VkOffset3D					dstOffset		= region.imageBlit.dstOffsets[0];
   3165 	const VkOffset3D					dstExtent		=
   3166 	{
   3167 		region.imageBlit.dstOffsets[1].x - dstOffset.x,
   3168 		region.imageBlit.dstOffsets[1].y - dstOffset.y,
   3169 		region.imageBlit.dstOffsets[1].z - dstOffset.z
   3170 	};
   3171 	const tcu::Sampler::FilterMode		filter			= (m_params.filter == VK_FILTER_LINEAR) ? tcu::Sampler::LINEAR : tcu::Sampler::NEAREST;
   3172 
   3173 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
   3174 	{
   3175 		DE_ASSERT(src.getFormat() == dst.getFormat());
   3176 		// Scale depth.
   3177 		if (tcu::hasDepthComponent(src.getFormat().order))
   3178 		{
   3179 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
   3180 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
   3181 			tcu::scale(dstSubRegion, srcSubRegion, filter);
   3182 
   3183 			if (filter == tcu::Sampler::LINEAR)
   3184 			{
   3185 				const tcu::ConstPixelBufferAccess	depthSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
   3186 				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
   3187 				scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
   3188 			}
   3189 		}
   3190 
   3191 		// Scale stencil.
   3192 		if (tcu::hasStencilComponent(src.getFormat().order))
   3193 		{
   3194 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
   3195 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
   3196 			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
   3197 
   3198 			if (filter == tcu::Sampler::LINEAR)
   3199 			{
   3200 				const tcu::ConstPixelBufferAccess	stencilSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
   3201 				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
   3202 				scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
   3203 			}
   3204 		}
   3205 	}
   3206 	else
   3207 	{
   3208 		const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y);
   3209 		const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y);
   3210 		blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
   3211 
   3212 		if (filter == tcu::Sampler::LINEAR)
   3213 		{
   3214 			const tcu::PixelBufferAccess	unclampedSubRegion	= tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y);
   3215 			scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter);
   3216 		}
   3217 	}
   3218 }
   3219 
   3220 void BlittingMipmaps::generateExpectedResult (void)
   3221 {
   3222 	const tcu::ConstPixelBufferAccess	src	= m_sourceTextureLevel->getAccess();
   3223 	const tcu::ConstPixelBufferAccess	dst	= m_destinationTextureLevel->getAccess();
   3224 
   3225 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
   3226 		m_expectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
   3227 
   3228 	tcu::copy(m_expectedTextureLevel[0]->getAccess(), src);
   3229 
   3230 	if (m_params.filter == VK_FILTER_LINEAR)
   3231 	{
   3232 		for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
   3233 			m_unclampedExpectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
   3234 
   3235 		tcu::copy(m_unclampedExpectedTextureLevel[0]->getAccess(), dst);
   3236 	}
   3237 
   3238 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
   3239 	{
   3240 		CopyRegion region = m_params.regions[i];
   3241 		copyRegionToTextureLevel(m_expectedTextureLevel[m_params.regions[i].imageBlit.srcSubresource.mipLevel]->getAccess(), m_expectedTextureLevel[m_params.regions[i].imageBlit.dstSubresource.mipLevel]->getAccess(), region);
   3242 	}
   3243 }
   3244 
   3245 class BlitMipmapTestCase : public vkt::TestCase
   3246 {
   3247 public:
   3248 							BlitMipmapTestCase		(tcu::TestContext&				testCtx,
   3249 													 const std::string&				name,
   3250 													 const std::string&				description,
   3251 													 const TestParams				params)
   3252 								: vkt::TestCase	(testCtx, name, description)
   3253 								, m_params		(params)
   3254 							{}
   3255 
   3256 	virtual TestInstance*	createInstance			(Context&						context) const
   3257 							{
   3258 								return new BlittingMipmaps(context, m_params);
   3259 							}
   3260 private:
   3261 	TestParams				m_params;
   3262 };
   3263 
   3264 // Resolve image to image.
   3265 
   3266 enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION, COPY_MS_IMAGE_TO_MS_IMAGE, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE};
   3267 class ResolveImageToImage : public CopiesAndBlittingTestInstance
   3268 {
   3269 public:
   3270 												ResolveImageToImage			(Context&							context,
   3271 																			 TestParams							params,
   3272 																			 const ResolveImageToImageOptions	options);
   3273 	virtual tcu::TestStatus						iterate						(void);
   3274 protected:
   3275 	virtual tcu::TestStatus						checkTestResult				(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
   3276 	void										copyMSImageToMSImage		(void);
   3277 private:
   3278 	Move<VkImage>								m_multisampledImage;
   3279 	de::MovePtr<Allocation>						m_multisampledImageAlloc;
   3280 
   3281 	Move<VkImage>								m_destination;
   3282 	de::MovePtr<Allocation>						m_destinationImageAlloc;
   3283 
   3284 	Move<VkImage>								m_multisampledCopyImage;
   3285 	de::MovePtr<Allocation>						m_multisampledCopyImageAlloc;
   3286 
   3287 	const ResolveImageToImageOptions			m_options;
   3288 
   3289 	virtual void								copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess	src,
   3290 																			 tcu::PixelBufferAccess			dst,
   3291 																			 CopyRegion						region);
   3292 };
   3293 
   3294 ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options)
   3295 	: CopiesAndBlittingTestInstance	(context, params)
   3296 	, m_options						(options)
   3297 {
   3298 	const VkSampleCountFlagBits	rasterizationSamples	= m_params.samples;
   3299 
   3300 	if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
   3301 		throw tcu::NotSupportedError("Unsupported number of rasterization samples");
   3302 
   3303 	const InstanceInterface&	vki						= context.getInstanceInterface();
   3304 	const DeviceInterface&		vk						= context.getDeviceInterface();
   3305 	const VkPhysicalDevice		vkPhysDevice			= context.getPhysicalDevice();
   3306 	const VkDevice				vkDevice				= context.getDevice();
   3307 	const deUint32				queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
   3308 	Allocator&					memAlloc				= m_context.getDefaultAllocator();
   3309 
   3310 	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
   3311 	Move<VkRenderPass>			renderPass;
   3312 
   3313 	Move<VkShaderModule>		vertexShaderModule		= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
   3314 	Move<VkShaderModule>		fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
   3315 	std::vector<tcu::Vec4>		vertices;
   3316 
   3317 	Move<VkBuffer>				vertexBuffer;
   3318 	de::MovePtr<Allocation>		vertexBufferAlloc;
   3319 
   3320 	Move<VkPipelineLayout>		pipelineLayout;
   3321 	Move<VkPipeline>			graphicsPipeline;
   3322 
   3323 	VkImageFormatProperties properties;
   3324 	if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
   3325 																				m_params.src.image.format,
   3326 																				m_params.src.image.imageType,
   3327 																				VK_IMAGE_TILING_OPTIMAL,
   3328 																				VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
   3329 																				&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
   3330 		(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
   3331 																				m_params.dst.image.format,
   3332 																				m_params.dst.image.imageType,
   3333 																				VK_IMAGE_TILING_OPTIMAL,
   3334 																				VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
   3335 																				&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
   3336 	{
   3337 		TCU_THROW(NotSupportedError, "Format not supported");
   3338 	}
   3339 
   3340 	// Create color image.
   3341 	{
   3342 		VkImageCreateInfo	colorImageParams	=
   3343 		{
   3344 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
   3345 			DE_NULL,																// const void*				pNext;
   3346 			0u,																		// VkImageCreateFlags		flags;
   3347 			m_params.src.image.imageType,											// VkImageType				imageType;
   3348 			m_params.src.image.format,												// VkFormat					format;
   3349 			getExtent3D(m_params.src.image),										// VkExtent3D				extent;
   3350 			1u,																		// deUint32					mipLevels;
   3351 			getArraySize(m_params.src.image),										// deUint32					arrayLayers;
   3352 			rasterizationSamples,													// VkSampleCountFlagBits	samples;
   3353 			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
   3354 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage;
   3355 			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
   3356 			1u,																		// deUint32					queueFamilyIndexCount;
   3357 			&queueFamilyIndex,														// const deUint32*			pQueueFamilyIndices;
   3358 			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout			initialLayout;
   3359 		};
   3360 
   3361 		m_multisampledImage						= createImage(vk, vkDevice, &colorImageParams);
   3362 
   3363 		// Allocate and bind color image memory.
   3364 		m_multisampledImageAlloc				= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
   3365 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), m_multisampledImageAlloc->getOffset()));
   3366 
   3367 		switch (m_options)
   3368 		{
   3369 			case COPY_MS_IMAGE_TO_MS_IMAGE:
   3370 			{
   3371 				colorImageParams.usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   3372 				m_multisampledCopyImage			= createImage(vk, vkDevice, &colorImageParams);
   3373 				// Allocate and bind color image memory.
   3374 				m_multisampledCopyImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
   3375 				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
   3376 				break;
   3377 			}
   3378 
   3379 			case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
   3380 			{
   3381 				colorImageParams.usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   3382 				colorImageParams.arrayLayers	= getArraySize(m_params.dst.image);
   3383 				m_multisampledCopyImage			= createImage(vk, vkDevice, &colorImageParams);
   3384 				// Allocate and bind color image memory.
   3385 				m_multisampledCopyImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
   3386 				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
   3387 				break;
   3388 			}
   3389 
   3390 			default :
   3391 				break;
   3392 		}
   3393 	}
   3394 
   3395 	// Create destination image.
   3396 	{
   3397 		const VkImageCreateInfo	destinationImageParams	=
   3398 		{
   3399 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
   3400 			DE_NULL,								// const void*			pNext;
   3401 			0u,										// VkImageCreateFlags	flags;
   3402 			m_params.dst.image.imageType,			// VkImageType			imageType;
   3403 			m_params.dst.image.format,				// VkFormat				format;
   3404 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
   3405 			1u,										// deUint32				mipLevels;
   3406 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
   3407 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
   3408 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
   3409 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
   3410 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
   3411 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
   3412 			1u,										// deUint32				queueFamilyCount;
   3413 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
   3414 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
   3415 		};
   3416 
   3417 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
   3418 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
   3419 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
   3420 	}
   3421 
   3422 	// Barriers for copying image to buffer
   3423 	VkImageMemoryBarrier		srcImageBarrier		=
   3424 	{
   3425 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
   3426 		DE_NULL,									// const void*				pNext;
   3427 		0u,											// VkAccessFlags			srcAccessMask;
   3428 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
   3429 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
   3430 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
   3431 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
   3432 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
   3433 		m_multisampledImage.get(),					// VkImage					image;
   3434 		{											// VkImageSubresourceRange	subresourceRange;
   3435 			VK_IMAGE_ASPECT_COLOR_BIT,			// VkImageAspectFlags	aspectMask;
   3436 			0u,									// deUint32				baseMipLevel;
   3437 			1u,									// deUint32				mipLevels;
   3438 			0u,									// deUint32				baseArraySlice;
   3439 			getArraySize(m_params.src.image)	// deUint32				arraySize;
   3440 		}
   3441 	};
   3442 
   3443 		// Create render pass.
   3444 	{
   3445 		const VkAttachmentDescription	attachmentDescriptions[1]	=
   3446 		{
   3447 			{
   3448 				0u,											// VkAttachmentDescriptionFlags		flags;
   3449 				m_params.src.image.format,					// VkFormat							format;
   3450 				rasterizationSamples,						// VkSampleCountFlagBits			samples;
   3451 				VK_ATTACHMENT_LOAD_OP_CLEAR,				// VkAttachmentLoadOp				loadOp;
   3452 				VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				storeOp;
   3453 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp				stencilLoadOp;
   3454 				VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp				stencilStoreOp;
   3455 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout					initialLayout;
   3456 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout					finalLayout;
   3457 			},
   3458 		};
   3459 
   3460 		const VkAttachmentReference		colorAttachmentReference	=
   3461 		{
   3462 			0u,													// deUint32			attachment;
   3463 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
   3464 		};
   3465 
   3466 		const VkSubpassDescription		subpassDescription			=
   3467 		{
   3468 			0u,									// VkSubpassDescriptionFlags	flags;
   3469 			VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint			pipelineBindPoint;
   3470 			0u,									// deUint32						inputAttachmentCount;
   3471 			DE_NULL,							// const VkAttachmentReference*	pInputAttachments;
   3472 			1u,									// deUint32						colorAttachmentCount;
   3473 			&colorAttachmentReference,			// const VkAttachmentReference*	pColorAttachments;
   3474 			DE_NULL,							// const VkAttachmentReference*	pResolveAttachments;
   3475 			DE_NULL,							// const VkAttachmentReference*	pDepthStencilAttachment;
   3476 			0u,									// deUint32						preserveAttachmentCount;
   3477 			DE_NULL								// const VkAttachmentReference*	pPreserveAttachments;
   3478 		};
   3479 
   3480 		const VkRenderPassCreateInfo	renderPassParams			=
   3481 		{
   3482 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureType					sType;
   3483 			DE_NULL,									// const void*						pNext;
   3484 			0u,											// VkRenderPassCreateFlags			flags;
   3485 			1u,											// deUint32							attachmentCount;
   3486 			attachmentDescriptions,						// const VkAttachmentDescription*	pAttachments;
   3487 			1u,											// deUint32							subpassCount;
   3488 			&subpassDescription,						// const VkSubpassDescription*		pSubpasses;
   3489 			0u,											// deUint32							dependencyCount;
   3490 			DE_NULL										// const VkSubpassDependency*		pDependencies;
   3491 		};
   3492 
   3493 		renderPass	= createRenderPass(vk, vkDevice, &renderPassParams);
   3494 	}
   3495 
   3496 	// Create pipeline layout
   3497 	{
   3498 		const VkPipelineLayoutCreateInfo	pipelineLayoutParams	=
   3499 		{
   3500 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
   3501 			DE_NULL,											// const void*						pNext;
   3502 			0u,													// VkPipelineLayoutCreateFlags		flags;
   3503 			0u,													// deUint32							setLayoutCount;
   3504 			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
   3505 			0u,													// deUint32							pushConstantRangeCount;
   3506 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
   3507 		};
   3508 
   3509 		pipelineLayout	= createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
   3510 	}
   3511 
   3512 	// Create upper half triangle.
   3513 	{
   3514 		const tcu::Vec4	a	(-1.0, -1.0, 0.0, 1.0);
   3515 		const tcu::Vec4	b	(1.0, -1.0, 0.0, 1.0);
   3516 		const tcu::Vec4	c	(1.0, 1.0, 0.0, 1.0);
   3517 		// Add triangle.
   3518 		vertices.push_back(a);
   3519 		vertices.push_back(c);
   3520 		vertices.push_back(b);
   3521 	}
   3522 
   3523 	// Create vertex buffer.
   3524 	{
   3525 		const VkDeviceSize			vertexDataSize		= vertices.size() * sizeof(tcu::Vec4);
   3526 		const VkBufferCreateInfo	vertexBufferParams	=
   3527 		{
   3528 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
   3529 			DE_NULL,									// const void*			pNext;
   3530 			0u,											// VkBufferCreateFlags	flags;
   3531 			vertexDataSize,								// VkDeviceSize			size;
   3532 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
   3533 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
   3534 			1u,											// deUint32				queueFamilyIndexCount;
   3535 			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
   3536 		};
   3537 
   3538 		vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
   3539 		vertexBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
   3540 		VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
   3541 
   3542 		// Load vertices into vertex buffer.
   3543 		deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
   3544 		flushMappedMemoryRange(vk, vkDevice, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexDataSize);
   3545 	}
   3546 
   3547 	{
   3548 		Move<VkFramebuffer>		framebuffer;
   3549 		Move<VkImageView>		sourceAttachmentView;
   3550 
   3551 		// Create color attachment view.
   3552 		{
   3553 			const VkImageViewCreateInfo	colorAttachmentViewParams	=
   3554 			{
   3555 				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,				// VkStructureType			sType;
   3556 				DE_NULL,												// const void*				pNext;
   3557 				0u,														// VkImageViewCreateFlags	flags;
   3558 				*m_multisampledImage,									// VkImage					image;
   3559 				VK_IMAGE_VIEW_TYPE_2D,									// VkImageViewType			viewType;
   3560 				m_params.src.image.format,								// VkFormat					format;
   3561 				componentMappingRGBA,									// VkComponentMapping		components;
   3562 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
   3563 			};
   3564 			sourceAttachmentView	= createImageView(vk, vkDevice, &colorAttachmentViewParams);
   3565 		}
   3566 
   3567 		// Create framebuffer
   3568 		{
   3569 			const VkImageView				attachments[1]		=
   3570 			{
   3571 					*sourceAttachmentView,
   3572 			};
   3573 
   3574 			const VkFramebufferCreateInfo	framebufferParams	=
   3575 			{
   3576 					VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
   3577 					DE_NULL,											// const void*					pNext;
   3578 					0u,													// VkFramebufferCreateFlags		flags;
   3579 					*renderPass,										// VkRenderPass					renderPass;
   3580 					1u,													// deUint32						attachmentCount;
   3581 					attachments,										// const VkImageView*			pAttachments;
   3582 					m_params.src.image.extent.width,					// deUint32						width;
   3583 					m_params.src.image.extent.height,					// deUint32						height;
   3584 					1u													// deUint32						layers;
   3585 			};
   3586 
   3587 			framebuffer	= createFramebuffer(vk, vkDevice, &framebufferParams);
   3588 		}
   3589 
   3590 		// Create pipeline
   3591 		{
   3592 			const VkPipelineShaderStageCreateInfo			shaderStageParams[2]				=
   3593 			{
   3594 				{
   3595 					VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
   3596 					DE_NULL,													// const void*							pNext;
   3597 					0u,															// VkPipelineShaderStageCreateFlags		flags;
   3598 					VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStageFlagBits				stage;
   3599 					*vertexShaderModule,										// VkShaderModule						module;
   3600 					"main",														// const char*							pName;
   3601 					DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
   3602 				},
   3603 				{
   3604 					VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
   3605 					DE_NULL,													// const void*							pNext;
   3606 					0u,															// VkPipelineShaderStageCreateFlags		flags;
   3607 					VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlagBits				stage;
   3608 					*fragmentShaderModule,										// VkShaderModule						module;
   3609 					"main",														// const char*							pName;
   3610 					DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
   3611 				}
   3612 			};
   3613 
   3614 			const VkVertexInputBindingDescription			vertexInputBindingDescription		=
   3615 			{
   3616 					0u,									// deUint32				binding;
   3617 					sizeof(tcu::Vec4),					// deUint32				stride;
   3618 					VK_VERTEX_INPUT_RATE_VERTEX			// VkVertexInputRate	inputRate;
   3619 			};
   3620 
   3621 			const VkVertexInputAttributeDescription			vertexInputAttributeDescriptions[1]	=
   3622 			{
   3623 				{
   3624 					0u,									// deUint32	location;
   3625 					0u,									// deUint32	binding;
   3626 					VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
   3627 					0u									// deUint32	offset;
   3628 				}
   3629 			};
   3630 
   3631 			const VkPipelineVertexInputStateCreateInfo		vertexInputStateParams				=
   3632 			{
   3633 				VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType;
   3634 				DE_NULL,													// const void*								pNext;
   3635 				0u,															// VkPipelineVertexInputStateCreateFlags	flags;
   3636 				1u,															// deUint32									vertexBindingDescriptionCount;
   3637 				&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
   3638 				1u,															// deUint32									vertexAttributeDescriptionCount;
   3639 				vertexInputAttributeDescriptions							// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
   3640 			};
   3641 
   3642 			const VkPipelineInputAssemblyStateCreateInfo	inputAssemblyStateParams			=
   3643 			{
   3644 				VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
   3645 				DE_NULL,														// const void*								pNext;
   3646 				0u,																// VkPipelineInputAssemblyStateCreateFlags	flags;
   3647 				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// VkPrimitiveTopology						topology;
   3648 				false															// VkBool32									primitiveRestartEnable;
   3649 			};
   3650 
   3651 			const VkViewport	viewport	=
   3652 			{
   3653 				0.0f,									// float	x;
   3654 				0.0f,									// float	y;
   3655 				(float)m_params.src.image.extent.width,	// float	width;
   3656 				(float)m_params.src.image.extent.height,// float	height;
   3657 				0.0f,									// float	minDepth;
   3658 				1.0f									// float	maxDepth;
   3659 			};
   3660 
   3661 			const VkRect2D		scissor		=
   3662 			{
   3663 				{ 0, 0 },																// VkOffset2D	offset;
   3664 				{ m_params.src.image.extent.width, m_params.src.image.extent.height }	// VkExtent2D	extent;
   3665 			};
   3666 
   3667 			const VkPipelineViewportStateCreateInfo			viewportStateParams		=
   3668 			{
   3669 				VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType						sType;
   3670 				DE_NULL,												// const void*							pNext;
   3671 				0u,														// VkPipelineViewportStateCreateFlags	flags;
   3672 				1u,														// deUint32								viewportCount;
   3673 				&viewport,												// const VkViewport*					pViewports;
   3674 				1u,														// deUint32								scissorCount;
   3675 				&scissor												// const VkRect2D*						pScissors;
   3676 			};
   3677 
   3678 			const VkPipelineRasterizationStateCreateInfo	rasterStateParams		=
   3679 			{
   3680 				VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	// VkStructureType							sType;
   3681 				DE_NULL,													// const void*								pNext;
   3682 				0u,															// VkPipelineRasterizationStateCreateFlags	flags;
   3683 				false,														// VkBool32									depthClampEnable;
   3684 				false,														// VkBool32									rasterizerDiscardEnable;
   3685 				VK_POLYGON_MODE_FILL,										// VkPolygonMode							polygonMode;
   3686 				VK_CULL_MODE_NONE,											// VkCullModeFlags							cullMode;
   3687 				VK_FRONT_FACE_COUNTER_CLOCKWISE,							// VkFrontFace								frontFace;
   3688 				VK_FALSE,													// VkBool32									depthBiasEnable;
   3689 				0.0f,														// float									depthBiasConstantFactor;
   3690 				0.0f,														// float									depthBiasClamp;
   3691 				0.0f,														// float									depthBiasSlopeFactor;
   3692 				1.0f														// float									lineWidth;
   3693 			};
   3694 
   3695 			const VkPipelineMultisampleStateCreateInfo	multisampleStateParams		=
   3696 			{
   3697 				VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
   3698 				DE_NULL,													// const void*								pNext;
   3699 				0u,															// VkPipelineMultisampleStateCreateFlags	flags;
   3700 				rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
   3701 				VK_FALSE,													// VkBool32									sampleShadingEnable;
   3702 				0.0f,														// float									minSampleShading;
   3703 				DE_NULL,													// const VkSampleMask*						pSampleMask;
   3704 				VK_FALSE,													// VkBool32									alphaToCoverageEnable;
   3705 				VK_FALSE													// VkBool32									alphaToOneEnable;
   3706 			};
   3707 
   3708 			const VkPipelineColorBlendAttachmentState	colorBlendAttachmentState	=
   3709 			{
   3710 				false,							// VkBool32			blendEnable;
   3711 				VK_BLEND_FACTOR_ONE,			// VkBlend			srcBlendColor;
   3712 				VK_BLEND_FACTOR_ZERO,			// VkBlend			destBlendColor;
   3713 				VK_BLEND_OP_ADD,				// VkBlendOp		blendOpColor;
   3714 				VK_BLEND_FACTOR_ONE,			// VkBlend			srcBlendAlpha;
   3715 				VK_BLEND_FACTOR_ZERO,			// VkBlend			destBlendAlpha;
   3716 				VK_BLEND_OP_ADD,				// VkBlendOp		blendOpAlpha;
   3717 				(VK_COLOR_COMPONENT_R_BIT |
   3718 				VK_COLOR_COMPONENT_G_BIT |
   3719 				VK_COLOR_COMPONENT_B_BIT |
   3720 				VK_COLOR_COMPONENT_A_BIT)		// VkChannelFlags	channelWriteMask;
   3721 			};
   3722 
   3723 			const VkPipelineColorBlendStateCreateInfo	colorBlendStateParams	=
   3724 			{
   3725 				VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
   3726 				DE_NULL,													// const void*									pNext;
   3727 				0u,															// VkPipelineColorBlendStateCreateFlags			flags;
   3728 				false,														// VkBool32										logicOpEnable;
   3729 				VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
   3730 				1u,															// deUint32										attachmentCount;
   3731 				&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments;
   3732 				{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4];
   3733 			};
   3734 
   3735 			const VkGraphicsPipelineCreateInfo			graphicsPipelineParams	=
   3736 			{
   3737 				VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
   3738 				DE_NULL,											// const void*										pNext;
   3739 				0u,													// VkPipelineCreateFlags							flags;
   3740 				2u,													// deUint32											stageCount;
   3741 				shaderStageParams,									// const VkPipelineShaderStageCreateInfo*			pStages;
   3742 				&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
   3743 				&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
   3744 				DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
   3745 				&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*			pViewportState;
   3746 				&rasterStateParams,									// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
   3747 				&multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
   3748 				DE_NULL,											// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
   3749 				&colorBlendStateParams,								// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
   3750 				DE_NULL,											// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
   3751 				*pipelineLayout,									// VkPipelineLayout									layout;
   3752 				*renderPass,										// VkRenderPass										renderPass;
   3753 				0u,													// deUint32											subpass;
   3754 				0u,													// VkPipeline										basePipelineHandle;
   3755 				0u													// deInt32											basePipelineIndex;
   3756 			};
   3757 
   3758 			graphicsPipeline	= createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
   3759 		}
   3760 
   3761 		// Create command buffer
   3762 		{
   3763 			const VkCommandBufferBeginInfo cmdBufferBeginInfo =
   3764 			{
   3765 				VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
   3766 				DE_NULL,										// const void*						pNext;
   3767 				0u,												// VkCommandBufferUsageFlags		flags;
   3768 				(const VkCommandBufferInheritanceInfo*)DE_NULL,
   3769 			};
   3770 
   3771 			const VkClearValue clearValues[1] =
   3772 			{
   3773 				makeClearValueColorF32(0.0f, 0.0f, 1.0f, 1.0f),
   3774 			};
   3775 
   3776 			const VkRenderPassBeginInfo renderPassBeginInfo =
   3777 			{
   3778 				VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,				// VkStructureType		sType;
   3779 				DE_NULL,												// const void*			pNext;
   3780 				*renderPass,											// VkRenderPass			renderPass;
   3781 				*framebuffer,											// VkFramebuffer		framebuffer;
   3782 				{
   3783 					{ 0, 0 },
   3784 					{ m_params.src.image.extent.width, m_params.src.image.extent.height }
   3785 				},														// VkRect2D				renderArea;
   3786 				1u,														// deUint32				clearValueCount;
   3787 				clearValues												// const VkClearValue*	pClearValues;
   3788 			};
   3789 
   3790 			VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
   3791 			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier);
   3792 			vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
   3793 
   3794 			const VkDeviceSize	vertexBufferOffset	= 0u;
   3795 
   3796 			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
   3797 			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
   3798 			vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
   3799 
   3800 			vk.cmdEndRenderPass(*m_cmdBuffer);
   3801 			VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
   3802 		}
   3803 
   3804 		// Queue submit.
   3805 		{
   3806 			const VkQueue	queue	= m_context.getUniversalQueue();
   3807 			submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
   3808 		}
   3809 	}
   3810 }
   3811 
   3812 tcu::TestStatus ResolveImageToImage::iterate (void)
   3813 {
   3814 	const tcu::TextureFormat		srcTcuFormat		= mapVkFormat(m_params.src.image.format);
   3815 	const tcu::TextureFormat		dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
   3816 
   3817 	// upload the destination image
   3818 	m_destinationTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
   3819 																			(int)m_params.dst.image.extent.width,
   3820 																			(int)m_params.dst.image.extent.height,
   3821 																			(int)m_params.dst.image.extent.depth));
   3822 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
   3823 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
   3824 
   3825 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
   3826 																	(int)m_params.src.image.extent.width,
   3827 																	(int)m_params.src.image.extent.height,
   3828 																	(int)m_params.dst.image.extent.depth));
   3829 
   3830 	generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_MULTISAMPLE);
   3831 	generateExpectedResult();
   3832 
   3833 	switch (m_options)
   3834 	{
   3835 		case COPY_MS_IMAGE_TO_MS_IMAGE:
   3836 		case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
   3837 			copyMSImageToMSImage();
   3838 			break;
   3839 		default:
   3840 			break;
   3841 	}
   3842 
   3843 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
   3844 	const VkDevice					vkDevice			= m_context.getDevice();
   3845 	const VkQueue					queue				= m_context.getUniversalQueue();
   3846 
   3847 	std::vector<VkImageResolve>		imageResolves;
   3848 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
   3849 		imageResolves.push_back(m_params.regions[i].imageResolve);
   3850 
   3851 	const VkImageMemoryBarrier	imageBarriers[]		=
   3852 	{
   3853 		// source image
   3854 		{
   3855 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
   3856 			DE_NULL,									// const void*				pNext;
   3857 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask;
   3858 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
   3859 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			oldLayout;
   3860 			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
   3861 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
   3862 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
   3863 			m_multisampledImage.get(),					// VkImage					image;
   3864 			{											// VkImageSubresourceRange	subresourceRange;
   3865 				getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
   3866 				0u,									// deUint32				baseMipLevel;
   3867 				1u,									// deUint32				mipLevels;
   3868 				0u,									// deUint32				baseArraySlice;
   3869 				getArraySize(m_params.src.image)	// deUint32				arraySize;
   3870 			}
   3871 		},
   3872 		// destination image
   3873 		{
   3874 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
   3875 			DE_NULL,									// const void*				pNext;
   3876 			0u,											// VkAccessFlags			srcAccessMask;
   3877 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
   3878 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
   3879 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
   3880 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
   3881 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
   3882 			m_destination.get(),						// VkImage					image;
   3883 			{											// VkImageSubresourceRange	subresourceRange;
   3884 				getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
   3885 				0u,									// deUint32				baseMipLevel;
   3886 				1u,									// deUint32				mipLevels;
   3887 				0u,									// deUint32				baseArraySlice;
   3888 				getArraySize(m_params.dst.image)	// deUint32				arraySize;
   3889 			}
   3890 		},
   3891 	};
   3892 
   3893 	const VkImageMemoryBarrier postImageBarrier =
   3894 	{
   3895 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
   3896 		DE_NULL,								// const void*				pNext;
   3897 		VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			srcAccessMask;
   3898 		VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
   3899 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			oldLayout;
   3900 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			newLayout;
   3901 		VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
   3902 		VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
   3903 		m_destination.get(),					// VkImage					image;
   3904 		{										// VkImageSubresourceRange	subresourceRange;
   3905 			getAspectFlags(dstTcuFormat),		// VkImageAspectFlags		aspectMask;
   3906 			0u,									// deUint32					baseMipLevel;
   3907 			1u,									// deUint32					mipLevels;
   3908 			0u,									// deUint32					baseArraySlice;
   3909 			getArraySize(m_params.dst.image)	// deUint32					arraySize;
   3910 		}
   3911 	};
   3912 
   3913 	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
   3914 	{
   3915 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
   3916 		DE_NULL,												// const void*						pNext;
   3917 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
   3918 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
   3919 	};
   3920 
   3921 	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
   3922 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
   3923 	vk.cmdResolveImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), imageResolves.data());
   3924 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
   3925 	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
   3926 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
   3927 
   3928 	de::MovePtr<tcu::TextureLevel>	resultTextureLevel	= readImage(*m_destination, m_params.dst.image);
   3929 
   3930 	return checkTestResult(resultTextureLevel->getAccess());
   3931 }
   3932 
   3933 tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
   3934 {
   3935 	const tcu::ConstPixelBufferAccess	expected		= m_expectedTextureLevel[0]->getAccess();
   3936 	const float							fuzzyThreshold	= 0.01f;
   3937 
   3938 	for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
   3939 	{
   3940 		const tcu::ConstPixelBufferAccess	expectedSub	= getSubregion (expected, 0, 0, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
   3941 		const tcu::ConstPixelBufferAccess	resultSub	= getSubregion (result, 0, 0, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
   3942 		if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
   3943 			return tcu::TestStatus::fail("CopiesAndBlitting test");
   3944 	}
   3945 
   3946 	return tcu::TestStatus::pass("CopiesAndBlitting test");
   3947 }
   3948 
   3949 void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
   3950 {
   3951 	VkOffset3D srcOffset	= region.imageResolve.srcOffset;
   3952 			srcOffset.z		= region.imageResolve.srcSubresource.baseArrayLayer;
   3953 	VkOffset3D dstOffset	= region.imageResolve.dstOffset;
   3954 			dstOffset.z		= region.imageResolve.dstSubresource.baseArrayLayer;
   3955 	VkExtent3D extent		= region.imageResolve.extent;
   3956 
   3957 	const tcu::ConstPixelBufferAccess	srcSubRegion		= getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
   3958 	// CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
   3959 	const tcu::PixelBufferAccess		dstWithSrcFormat	(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
   3960 	const tcu::PixelBufferAccess		dstSubRegion		= getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
   3961 
   3962 	tcu::copy(dstSubRegion, srcSubRegion);
   3963 }
   3964 
   3965 void ResolveImageToImage::copyMSImageToMSImage (void)
   3966 {
   3967 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
   3968 	const VkDevice					vkDevice			= m_context.getDevice();
   3969 	const VkQueue					queue				= m_context.getUniversalQueue();
   3970 	const tcu::TextureFormat		srcTcuFormat		= mapVkFormat(m_params.src.image.format);
   3971 	std::vector<VkImageCopy>		imageCopies;
   3972 
   3973 	for (deUint32 layerNdx = 0; layerNdx < getArraySize(m_params.dst.image); ++layerNdx)
   3974 	{
   3975 		const VkImageSubresourceLayers	sourceSubresourceLayers	=
   3976 		{
   3977 			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
   3978 			0u,								// uint32_t				mipLevel;
   3979 			0u,								// uint32_t				baseArrayLayer;
   3980 			1u								// uint32_t				layerCount;
   3981 		};
   3982 
   3983 		const VkImageSubresourceLayers	destinationSubresourceLayers	=
   3984 		{
   3985 			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;//getAspectFlags(dstTcuFormat)
   3986 			0u,								// uint32_t				mipLevel;
   3987 			layerNdx,						// uint32_t				baseArrayLayer;
   3988 			1u								// uint32_t				layerCount;
   3989 		};
   3990 
   3991 		const VkImageCopy				imageCopy	=
   3992 		{
   3993 			sourceSubresourceLayers,			// VkImageSubresourceLayers	srcSubresource;
   3994 			{0, 0, 0},							// VkOffset3D				srcOffset;
   3995 			destinationSubresourceLayers,		// VkImageSubresourceLayers	dstSubresource;
   3996 			{0, 0, 0},							// VkOffset3D				dstOffset;
   3997 			 getExtent3D(m_params.src.image),	// VkExtent3D				extent;
   3998 		};
   3999 		imageCopies.push_back(imageCopy);
   4000 	}
   4001 
   4002 	const VkImageMemoryBarrier		imageBarriers[]		=
   4003 	{
   4004 		// source image
   4005 		{
   4006 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
   4007 			DE_NULL,									// const void*				pNext;
   4008 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask;
   4009 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
   4010 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			oldLayout;
   4011 			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
   4012 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
   4013 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
   4014 			m_multisampledImage.get(),					// VkImage					image;
   4015 			{											// VkImageSubresourceRange	subresourceRange;
   4016 				getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
   4017 				0u,									// deUint32				baseMipLevel;
   4018 				1u,									// deUint32				mipLevels;
   4019 				0u,									// deUint32				baseArraySlice;
   4020 				getArraySize(m_params.src.image)	// deUint32				arraySize;
   4021 			}
   4022 		},
   4023 		// destination image
   4024 		{
   4025 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
   4026 			DE_NULL,									// const void*				pNext;
   4027 			0,											// VkAccessFlags			srcAccessMask;
   4028 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
   4029 			VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
   4030 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
   4031 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
   4032 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
   4033 			m_multisampledCopyImage.get(),				// VkImage					image;
   4034 			{											// VkImageSubresourceRange	subresourceRange;
   4035 				getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
   4036 				0u,									// deUint32				baseMipLevel;
   4037 				1u,									// deUint32				mipLevels;
   4038 				0u,									// deUint32				baseArraySlice;
   4039 				getArraySize(m_params.dst.image)	// deUint32				arraySize;
   4040 			}
   4041 		},
   4042 	};
   4043 
   4044 	const VkImageMemoryBarrier	postImageBarriers		=
   4045 	// source image
   4046 	{
   4047 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
   4048 		DE_NULL,									// const void*				pNext;
   4049 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
   4050 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
   4051 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
   4052 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
   4053 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
   4054 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
   4055 		m_multisampledCopyImage.get(),				// VkImage					image;
   4056 		{											// VkImageSubresourceRange	subresourceRange;
   4057 			getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
   4058 			0u,									// deUint32				baseMipLevel;
   4059 			1u,									// deUint32				mipLevels;
   4060 			0u,									// deUint32				baseArraySlice;
   4061 			getArraySize(m_params.dst.image)	// deUint32				arraySize;
   4062 		}
   4063 	};
   4064 
   4065 	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
   4066 	{
   4067 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
   4068 		DE_NULL,												// const void*						pNext;
   4069 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
   4070 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
   4071 	};
   4072 
   4073 	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
   4074 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
   4075 	vk.cmdCopyImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_multisampledCopyImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)imageCopies.size(), imageCopies.data());
   4076 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarriers);
   4077 	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
   4078 
   4079 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
   4080 
   4081 	m_multisampledImage = m_multisampledCopyImage;
   4082 }
   4083 
   4084 class ResolveImageToImageTestCase : public vkt::TestCase
   4085 {
   4086 public:
   4087 							ResolveImageToImageTestCase	(tcu::TestContext&					testCtx,
   4088 														 const std::string&					name,
   4089 														 const std::string&					description,
   4090 														 const TestParams					params,
   4091 														 const ResolveImageToImageOptions	options = NO_OPTIONAL_OPERATION)
   4092 								: vkt::TestCase	(testCtx, name, description)
   4093 								, m_params		(params)
   4094 								, m_options		(options)
   4095 							{}
   4096 	virtual	void			initPrograms				(SourceCollections&		programCollection) const;
   4097 
   4098 	virtual TestInstance*	createInstance				(Context&				context) const
   4099 							{
   4100 								return new ResolveImageToImage(context, m_params, m_options);
   4101 							}
   4102 private:
   4103 	TestParams							m_params;
   4104 	const ResolveImageToImageOptions	m_options;
   4105 };
   4106 
   4107 void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const
   4108 {
   4109 	programCollection.glslSources.add("vert") << glu::VertexSource(
   4110 		"#version 310 es\n"
   4111 		"layout (location = 0) in highp vec4 a_position;\n"
   4112 		"void main()\n"
   4113 		"{\n"
   4114 		"	gl_Position = a_position;\n"
   4115 		"}\n");
   4116 
   4117 
   4118 	programCollection.glslSources.add("frag") << glu::FragmentSource(
   4119 		"#version 310 es\n"
   4120 		"layout (location = 0) out highp vec4 o_color;\n"
   4121 		"void main()\n"
   4122 		"{\n"
   4123 		"	o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
   4124 		"}\n");
   4125 }
   4126 
   4127 std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag)
   4128 {
   4129 	return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
   4130 }
   4131 
   4132 std::string getFormatCaseName (VkFormat format)
   4133 {
   4134 	return de::toLower(de::toString(getFormatStr(format)).substr(10));
   4135 }
   4136 
   4137 std::string getImageLayoutCaseName (VkImageLayout layout)
   4138 {
   4139 	switch (layout)
   4140 	{
   4141 		case VK_IMAGE_LAYOUT_GENERAL:
   4142 			return "general";
   4143 		case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
   4144 		case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
   4145 			return "optimal";
   4146 		default:
   4147 			DE_ASSERT(false);
   4148 			return "";
   4149 	}
   4150 }
   4151 
   4152 const deInt32					defaultSize				= 64;
   4153 const deInt32					defaultHalfSize			= defaultSize / 2;
   4154 const deInt32					defaultFourthSize		= defaultSize / 4;
   4155 const VkExtent3D				defaultExtent			= {defaultSize, defaultSize, 1};
   4156 const VkExtent3D				defaultHalfExtent		= {defaultHalfSize, defaultHalfSize, 1};
   4157 
   4158 const VkImageSubresourceLayers	defaultSourceLayer		=
   4159 {
   4160 	VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
   4161 	0u,							// uint32_t				mipLevel;
   4162 	0u,							// uint32_t				baseArrayLayer;
   4163 	1u,							// uint32_t				layerCount;
   4164 };
   4165 
   4166 void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   4167 {
   4168 	tcu::TestContext& testCtx	= group->getTestContext();
   4169 
   4170 	{
   4171 		TestParams	params;
   4172 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   4173 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
   4174 		params.src.image.extent				= defaultExtent;
   4175 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   4176 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   4177 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
   4178 		params.dst.image.extent				= defaultExtent;
   4179 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   4180 		params.allocationKind				= allocationKind;
   4181 
   4182 		{
   4183 			const VkImageCopy				testCopy	=
   4184 			{
   4185 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   4186 				{0, 0, 0},			// VkOffset3D				srcOffset;
   4187 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   4188 				{0, 0, 0},			// VkOffset3D				dstOffset;
   4189 				defaultExtent,		// VkExtent3D				extent;
   4190 			};
   4191 
   4192 			CopyRegion	imageCopy;
   4193 			imageCopy.imageCopy	= testCopy;
   4194 
   4195 			params.regions.push_back(imageCopy);
   4196 		}
   4197 
   4198 		group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params));
   4199 	}
   4200 
   4201 	{
   4202 		TestParams	params;
   4203 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   4204 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
   4205 		params.src.image.extent				= defaultExtent;
   4206 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   4207 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   4208 		params.dst.image.format				= VK_FORMAT_R32_UINT;
   4209 		params.dst.image.extent				= defaultExtent;
   4210 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   4211 		params.allocationKind				= allocationKind;
   4212 
   4213 		{
   4214 			const VkImageCopy				testCopy	=
   4215 			{
   4216 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   4217 				{0, 0, 0},			// VkOffset3D				srcOffset;
   4218 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   4219 				{0, 0, 0},			// VkOffset3D				dstOffset;
   4220 				defaultExtent,		// VkExtent3D				extent;
   4221 			};
   4222 
   4223 			CopyRegion	imageCopy;
   4224 			imageCopy.imageCopy	= testCopy;
   4225 
   4226 			params.regions.push_back(imageCopy);
   4227 		}
   4228 
   4229 		group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params));
   4230 	}
   4231 
   4232 	{
   4233 		TestParams	params;
   4234 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   4235 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
   4236 		params.src.image.extent				= defaultExtent;
   4237 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   4238 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   4239 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
   4240 		params.dst.image.extent				= defaultExtent;
   4241 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   4242 		params.allocationKind				= allocationKind;
   4243 
   4244 		{
   4245 			const VkImageCopy				testCopy	=
   4246 			{
   4247 				defaultSourceLayer,									// VkImageSubresourceLayers	srcSubresource;
   4248 				{0, 0, 0},											// VkOffset3D				srcOffset;
   4249 				defaultSourceLayer,									// VkImageSubresourceLayers	dstSubresource;
   4250 				{defaultFourthSize, defaultFourthSize / 2, 0},		// VkOffset3D				dstOffset;
   4251 				{defaultFourthSize / 2, defaultFourthSize / 2, 1},	// VkExtent3D				extent;
   4252 			};
   4253 
   4254 			CopyRegion	imageCopy;
   4255 			imageCopy.imageCopy	= testCopy;
   4256 
   4257 			params.regions.push_back(imageCopy);
   4258 		}
   4259 
   4260 		group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params));
   4261 	}
   4262 
   4263 	{
   4264 		TestParams	params;
   4265 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   4266 		params.src.image.format				= VK_FORMAT_D32_SFLOAT;
   4267 		params.src.image.extent				= defaultExtent;
   4268 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   4269 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   4270 		params.dst.image.format				= VK_FORMAT_D32_SFLOAT;
   4271 		params.dst.image.extent				= defaultExtent;
   4272 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   4273 		params.allocationKind				= allocationKind;
   4274 
   4275 		{
   4276 			const VkImageSubresourceLayers  sourceLayer =
   4277 			{
   4278 				VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags	aspectMask;
   4279 				0u,							// uint32_t				mipLevel;
   4280 				0u,							// uint32_t				baseArrayLayer;
   4281 				1u							// uint32_t				layerCount;
   4282 			};
   4283 			const VkImageCopy				testCopy	=
   4284 			{
   4285 				sourceLayer,										// VkImageSubresourceLayers	srcSubresource;
   4286 				{0, 0, 0},											// VkOffset3D				srcOffset;
   4287 				sourceLayer,										// VkImageSubresourceLayers	dstSubresource;
   4288 				{defaultFourthSize, defaultFourthSize / 2, 0},		// VkOffset3D				dstOffset;
   4289 				{defaultFourthSize / 2, defaultFourthSize / 2, 1},	// VkExtent3D				extent;
   4290 			};
   4291 
   4292 			CopyRegion	imageCopy;
   4293 			imageCopy.imageCopy	= testCopy;
   4294 
   4295 			params.regions.push_back(imageCopy);
   4296 		}
   4297 
   4298 		group->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params));
   4299 	}
   4300 
   4301 	{
   4302 		TestParams	params;
   4303 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   4304 		params.src.image.format				= VK_FORMAT_S8_UINT;
   4305 		params.src.image.extent				= defaultExtent;
   4306 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   4307 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   4308 		params.dst.image.format				= VK_FORMAT_S8_UINT;
   4309 		params.dst.image.extent				= defaultExtent;
   4310 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   4311 		params.allocationKind				= allocationKind;
   4312 
   4313 		{
   4314 			const VkImageSubresourceLayers  sourceLayer =
   4315 			{
   4316 				VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask;
   4317 				0u,								// uint32_t				mipLevel;
   4318 				0u,								// uint32_t				baseArrayLayer;
   4319 				1u								// uint32_t				layerCount;
   4320 			};
   4321 			const VkImageCopy				testCopy	=
   4322 			{
   4323 				sourceLayer,										// VkImageSubresourceLayers	srcSubresource;
   4324 				{0, 0, 0},											// VkOffset3D				srcOffset;
   4325 				sourceLayer,										// VkImageSubresourceLayers	dstSubresource;
   4326 				{defaultFourthSize, defaultFourthSize / 2, 0},		// VkOffset3D				dstOffset;
   4327 				{defaultFourthSize / 2, defaultFourthSize / 2, 1},	// VkExtent3D				extent;
   4328 			};
   4329 
   4330 			CopyRegion	imageCopy;
   4331 			imageCopy.imageCopy	= testCopy;
   4332 
   4333 			params.regions.push_back(imageCopy);
   4334 		}
   4335 
   4336 		group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params));
   4337 	}
   4338 }
   4339 
   4340 struct CopyColorTestParams
   4341 {
   4342 	TestParams		params;
   4343 	const VkFormat*	compatibleFormats;
   4344 };
   4345 
   4346 void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params)
   4347 {
   4348 	const VkImageLayout copySrcLayouts[]		=
   4349 	{
   4350 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   4351 		VK_IMAGE_LAYOUT_GENERAL
   4352 	};
   4353 	const VkImageLayout copyDstLayouts[]		=
   4354 	{
   4355 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   4356 		VK_IMAGE_LAYOUT_GENERAL
   4357 	};
   4358 
   4359 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
   4360 	{
   4361 		params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
   4362 
   4363 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
   4364 		{
   4365 			params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
   4366 
   4367 			const std::string testName	= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
   4368 										  getImageLayoutCaseName(params.dst.image.operationLayout);
   4369 			const std::string description	= "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
   4370 											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
   4371 			group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
   4372 		}
   4373 	}
   4374 }
   4375 
   4376 bool isAllowedImageToImageAllFormatsColorSrcFormatTests(CopyColorTestParams& testParams)
   4377 {
   4378 	bool result = true;
   4379 
   4380 	if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
   4381 	{
   4382 		DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty());
   4383 
   4384 		result =
   4385 			de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) ||
   4386 			de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format);
   4387 	}
   4388 
   4389 	return result;
   4390 }
   4391 
   4392 void addImageToImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, CopyColorTestParams testParams)
   4393 {
   4394 	for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
   4395 	{
   4396 		testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
   4397 		if (!isSupportedByFramework(testParams.params.dst.image.format))
   4398 			continue;
   4399 
   4400 		if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
   4401 			continue;
   4402 
   4403 		const std::string description	= "Copy to destination format " + getFormatCaseName(testParams.params.dst.image.format);
   4404 		addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addImageToImageAllFormatsColorSrcFormatDstFormatTests, testParams.params);
   4405 	}
   4406 }
   4407 
   4408 const VkFormat	compatibleFormats8Bit[]		=
   4409 {
   4410 	VK_FORMAT_R4G4_UNORM_PACK8,
   4411 	VK_FORMAT_R8_UNORM,
   4412 	VK_FORMAT_R8_SNORM,
   4413 	VK_FORMAT_R8_USCALED,
   4414 	VK_FORMAT_R8_SSCALED,
   4415 	VK_FORMAT_R8_UINT,
   4416 	VK_FORMAT_R8_SINT,
   4417 	VK_FORMAT_R8_SRGB,
   4418 
   4419 	VK_FORMAT_UNDEFINED
   4420 };
   4421 const VkFormat	compatibleFormats16Bit[]	=
   4422 {
   4423 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
   4424 	VK_FORMAT_B4G4R4A4_UNORM_PACK16,
   4425 	VK_FORMAT_R5G6B5_UNORM_PACK16,
   4426 	VK_FORMAT_B5G6R5_UNORM_PACK16,
   4427 	VK_FORMAT_R5G5B5A1_UNORM_PACK16,
   4428 	VK_FORMAT_B5G5R5A1_UNORM_PACK16,
   4429 	VK_FORMAT_A1R5G5B5_UNORM_PACK16,
   4430 	VK_FORMAT_R8G8_UNORM,
   4431 	VK_FORMAT_R8G8_SNORM,
   4432 	VK_FORMAT_R8G8_USCALED,
   4433 	VK_FORMAT_R8G8_SSCALED,
   4434 	VK_FORMAT_R8G8_UINT,
   4435 	VK_FORMAT_R8G8_SINT,
   4436 	VK_FORMAT_R8G8_SRGB,
   4437 	VK_FORMAT_R16_UNORM,
   4438 	VK_FORMAT_R16_SNORM,
   4439 	VK_FORMAT_R16_USCALED,
   4440 	VK_FORMAT_R16_SSCALED,
   4441 	VK_FORMAT_R16_UINT,
   4442 	VK_FORMAT_R16_SINT,
   4443 	VK_FORMAT_R16_SFLOAT,
   4444 
   4445 	VK_FORMAT_UNDEFINED
   4446 };
   4447 const VkFormat	compatibleFormats24Bit[]	=
   4448 {
   4449 	VK_FORMAT_R8G8B8_UNORM,
   4450 	VK_FORMAT_R8G8B8_SNORM,
   4451 	VK_FORMAT_R8G8B8_USCALED,
   4452 	VK_FORMAT_R8G8B8_SSCALED,
   4453 	VK_FORMAT_R8G8B8_UINT,
   4454 	VK_FORMAT_R8G8B8_SINT,
   4455 	VK_FORMAT_R8G8B8_SRGB,
   4456 	VK_FORMAT_B8G8R8_UNORM,
   4457 	VK_FORMAT_B8G8R8_SNORM,
   4458 	VK_FORMAT_B8G8R8_USCALED,
   4459 	VK_FORMAT_B8G8R8_SSCALED,
   4460 	VK_FORMAT_B8G8R8_UINT,
   4461 	VK_FORMAT_B8G8R8_SINT,
   4462 	VK_FORMAT_B8G8R8_SRGB,
   4463 
   4464 	VK_FORMAT_UNDEFINED
   4465 };
   4466 const VkFormat	compatibleFormats32Bit[]	=
   4467 {
   4468 	VK_FORMAT_R8G8B8A8_UNORM,
   4469 	VK_FORMAT_R8G8B8A8_SNORM,
   4470 	VK_FORMAT_R8G8B8A8_USCALED,
   4471 	VK_FORMAT_R8G8B8A8_SSCALED,
   4472 	VK_FORMAT_R8G8B8A8_UINT,
   4473 	VK_FORMAT_R8G8B8A8_SINT,
   4474 	VK_FORMAT_R8G8B8A8_SRGB,
   4475 	VK_FORMAT_B8G8R8A8_UNORM,
   4476 	VK_FORMAT_B8G8R8A8_SNORM,
   4477 	VK_FORMAT_B8G8R8A8_USCALED,
   4478 	VK_FORMAT_B8G8R8A8_SSCALED,
   4479 	VK_FORMAT_B8G8R8A8_UINT,
   4480 	VK_FORMAT_B8G8R8A8_SINT,
   4481 	VK_FORMAT_B8G8R8A8_SRGB,
   4482 	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
   4483 	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
   4484 	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
   4485 	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
   4486 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
   4487 	VK_FORMAT_A8B8G8R8_SINT_PACK32,
   4488 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
   4489 	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
   4490 	VK_FORMAT_A2R10G10B10_SNORM_PACK32,
   4491 	VK_FORMAT_A2R10G10B10_USCALED_PACK32,
   4492 	VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
   4493 	VK_FORMAT_A2R10G10B10_UINT_PACK32,
   4494 	VK_FORMAT_A2R10G10B10_SINT_PACK32,
   4495 	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
   4496 	VK_FORMAT_A2B10G10R10_SNORM_PACK32,
   4497 	VK_FORMAT_A2B10G10R10_USCALED_PACK32,
   4498 	VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
   4499 	VK_FORMAT_A2B10G10R10_UINT_PACK32,
   4500 	VK_FORMAT_A2B10G10R10_SINT_PACK32,
   4501 	VK_FORMAT_R16G16_UNORM,
   4502 	VK_FORMAT_R16G16_SNORM,
   4503 	VK_FORMAT_R16G16_USCALED,
   4504 	VK_FORMAT_R16G16_SSCALED,
   4505 	VK_FORMAT_R16G16_UINT,
   4506 	VK_FORMAT_R16G16_SINT,
   4507 	VK_FORMAT_R16G16_SFLOAT,
   4508 	VK_FORMAT_R32_UINT,
   4509 	VK_FORMAT_R32_SINT,
   4510 	VK_FORMAT_R32_SFLOAT,
   4511 
   4512 	VK_FORMAT_UNDEFINED
   4513 };
   4514 const VkFormat	compatibleFormats48Bit[]	=
   4515 {
   4516 	VK_FORMAT_R16G16B16_UNORM,
   4517 	VK_FORMAT_R16G16B16_SNORM,
   4518 	VK_FORMAT_R16G16B16_USCALED,
   4519 	VK_FORMAT_R16G16B16_SSCALED,
   4520 	VK_FORMAT_R16G16B16_UINT,
   4521 	VK_FORMAT_R16G16B16_SINT,
   4522 	VK_FORMAT_R16G16B16_SFLOAT,
   4523 
   4524 	VK_FORMAT_UNDEFINED
   4525 };
   4526 const VkFormat	compatibleFormats64Bit[]	=
   4527 {
   4528 	VK_FORMAT_R16G16B16A16_UNORM,
   4529 	VK_FORMAT_R16G16B16A16_SNORM,
   4530 	VK_FORMAT_R16G16B16A16_USCALED,
   4531 	VK_FORMAT_R16G16B16A16_SSCALED,
   4532 	VK_FORMAT_R16G16B16A16_UINT,
   4533 	VK_FORMAT_R16G16B16A16_SINT,
   4534 	VK_FORMAT_R16G16B16A16_SFLOAT,
   4535 	VK_FORMAT_R32G32_UINT,
   4536 	VK_FORMAT_R32G32_SINT,
   4537 	VK_FORMAT_R32G32_SFLOAT,
   4538 	VK_FORMAT_R64_UINT,
   4539 	VK_FORMAT_R64_SINT,
   4540 	VK_FORMAT_R64_SFLOAT,
   4541 
   4542 	VK_FORMAT_UNDEFINED
   4543 };
   4544 const VkFormat	compatibleFormats96Bit[]	=
   4545 {
   4546 	VK_FORMAT_R32G32B32_UINT,
   4547 	VK_FORMAT_R32G32B32_SINT,
   4548 	VK_FORMAT_R32G32B32_SFLOAT,
   4549 
   4550 	VK_FORMAT_UNDEFINED
   4551 };
   4552 const VkFormat	compatibleFormats128Bit[]	=
   4553 {
   4554 	VK_FORMAT_R32G32B32A32_UINT,
   4555 	VK_FORMAT_R32G32B32A32_SINT,
   4556 	VK_FORMAT_R32G32B32A32_SFLOAT,
   4557 	VK_FORMAT_R64G64_UINT,
   4558 	VK_FORMAT_R64G64_SINT,
   4559 	VK_FORMAT_R64G64_SFLOAT,
   4560 
   4561 	VK_FORMAT_UNDEFINED
   4562 };
   4563 const VkFormat	compatibleFormats192Bit[]	=
   4564 {
   4565 	VK_FORMAT_R64G64B64_UINT,
   4566 	VK_FORMAT_R64G64B64_SINT,
   4567 	VK_FORMAT_R64G64B64_SFLOAT,
   4568 
   4569 	VK_FORMAT_UNDEFINED
   4570 };
   4571 const VkFormat	compatibleFormats256Bit[]	=
   4572 {
   4573 	VK_FORMAT_R64G64B64A64_UINT,
   4574 	VK_FORMAT_R64G64B64A64_SINT,
   4575 	VK_FORMAT_R64G64B64A64_SFLOAT,
   4576 
   4577 	VK_FORMAT_UNDEFINED
   4578 };
   4579 
   4580 const VkFormat*	colorImageFormatsToTest[]	=
   4581 {
   4582 	compatibleFormats8Bit,
   4583 	compatibleFormats16Bit,
   4584 	compatibleFormats24Bit,
   4585 	compatibleFormats32Bit,
   4586 	compatibleFormats48Bit,
   4587 	compatibleFormats64Bit,
   4588 	compatibleFormats96Bit,
   4589 	compatibleFormats128Bit,
   4590 	compatibleFormats192Bit,
   4591 	compatibleFormats256Bit,
   4592 };
   4593 
   4594 const VkFormat	dedicatedAllocationImageToImageFormatsToTest[]	=
   4595 {
   4596 	// From compatibleFormats8Bit
   4597 	VK_FORMAT_R4G4_UNORM_PACK8,
   4598 	VK_FORMAT_R8_SRGB,
   4599 
   4600 	// From compatibleFormats16Bit
   4601 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
   4602 	VK_FORMAT_R16_SFLOAT,
   4603 
   4604 	// From compatibleFormats24Bit
   4605 	VK_FORMAT_R8G8B8_UNORM,
   4606 	VK_FORMAT_B8G8R8_SRGB,
   4607 
   4608 	// From compatibleFormats32Bit
   4609 	VK_FORMAT_R8G8B8A8_UNORM,
   4610 	VK_FORMAT_R32_SFLOAT,
   4611 
   4612 	// From compatibleFormats48Bit
   4613 	VK_FORMAT_R16G16B16_UNORM,
   4614 	VK_FORMAT_R16G16B16_SFLOAT,
   4615 
   4616 	// From compatibleFormats64Bit
   4617 	VK_FORMAT_R16G16B16A16_UNORM,
   4618 	VK_FORMAT_R64_SFLOAT,
   4619 
   4620 	// From compatibleFormats96Bit
   4621 	VK_FORMAT_R32G32B32_UINT,
   4622 	VK_FORMAT_R32G32B32_SFLOAT,
   4623 
   4624 	// From compatibleFormats128Bit
   4625 	VK_FORMAT_R32G32B32A32_UINT,
   4626 	VK_FORMAT_R64G64_SFLOAT,
   4627 
   4628 	// From compatibleFormats192Bit
   4629 	VK_FORMAT_R64G64B64_UINT,
   4630 	VK_FORMAT_R64G64B64_SFLOAT,
   4631 
   4632 	// From compatibleFormats256Bit
   4633 	VK_FORMAT_R64G64B64A64_UINT,
   4634 	VK_FORMAT_R64G64B64A64_SFLOAT,
   4635 };
   4636 
   4637 void addImageToImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   4638 {
   4639 	TestParams	params;
   4640 	params.src.image.imageType	= VK_IMAGE_TYPE_2D;
   4641 	params.src.image.extent		= defaultExtent;
   4642 	params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
   4643 	params.dst.image.extent		= defaultExtent;
   4644 	params.allocationKind		= allocationKind;
   4645 
   4646 	for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
   4647 	{
   4648 		const VkImageCopy				testCopy =
   4649 		{
   4650 			defaultSourceLayer,								// VkImageSubresourceLayers	srcSubresource;
   4651 			{0, 0, 0},										// VkOffset3D				srcOffset;
   4652 			defaultSourceLayer,								// VkImageSubresourceLayers	dstSubresource;
   4653 			{i, defaultSize - i - defaultFourthSize, 0},	// VkOffset3D				dstOffset;
   4654 			{defaultFourthSize, defaultFourthSize, 1},		// VkExtent3D				extent;
   4655 		};
   4656 
   4657 		CopyRegion	imageCopy;
   4658 		imageCopy.imageCopy = testCopy;
   4659 
   4660 		params.regions.push_back(imageCopy);
   4661 	}
   4662 
   4663 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
   4664 	{
   4665 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
   4666 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
   4667 			dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
   4668 	}
   4669 
   4670 	const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
   4671 	for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
   4672 	{
   4673 		const VkFormat*	compatibleFormats	= colorImageFormatsToTest[compatibleFormatsIndex];
   4674 		for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
   4675 		{
   4676 			params.src.image.format = compatibleFormats[srcFormatIndex];
   4677 			if (!isSupportedByFramework(params.src.image.format))
   4678 				continue;
   4679 
   4680 			CopyColorTestParams	testParams;
   4681 			testParams.params				= params;
   4682 			testParams.compatibleFormats	= compatibleFormats;
   4683 
   4684 			const std::string description	= "Copy from source format " + getFormatCaseName(params.src.image.format);
   4685 			addTestGroup(group, getFormatCaseName(params.src.image.format), description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
   4686 		}
   4687 	}
   4688 }
   4689 
   4690 void addImageToImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
   4691 {
   4692 	const VkImageLayout copySrcLayouts[]		=
   4693 	{
   4694 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   4695 		VK_IMAGE_LAYOUT_GENERAL
   4696 	};
   4697 	const VkImageLayout copyDstLayouts[]		=
   4698 	{
   4699 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   4700 		VK_IMAGE_LAYOUT_GENERAL
   4701 	};
   4702 
   4703 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
   4704 	{
   4705 		params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
   4706 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
   4707 		{
   4708 			params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
   4709 
   4710 			const std::string testName		= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
   4711 											  getImageLayoutCaseName(params.dst.image.operationLayout);
   4712 			const std::string description	= "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
   4713 											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
   4714 			group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
   4715 		}
   4716 	}
   4717 }
   4718 
   4719 void addImageToImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   4720 {
   4721 	const VkFormat	depthAndStencilFormats[]	=
   4722 	{
   4723 		VK_FORMAT_D16_UNORM,
   4724 		VK_FORMAT_X8_D24_UNORM_PACK32,
   4725 		VK_FORMAT_D32_SFLOAT,
   4726 		VK_FORMAT_S8_UINT,
   4727 		VK_FORMAT_D16_UNORM_S8_UINT,
   4728 		VK_FORMAT_D24_UNORM_S8_UINT,
   4729 		VK_FORMAT_D32_SFLOAT_S8_UINT,
   4730 	};
   4731 
   4732 	for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
   4733 	{
   4734 		TestParams	params;
   4735 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   4736 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   4737 		params.src.image.extent				= defaultExtent;
   4738 		params.dst.image.extent				= defaultExtent;
   4739 		params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
   4740 		params.dst.image.format				= params.src.image.format;
   4741 		params.allocationKind				= allocationKind;
   4742 
   4743 		const VkImageSubresourceLayers		defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
   4744 		const VkImageSubresourceLayers		defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
   4745 
   4746 		for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
   4747 		{
   4748 			CopyRegion			copyRegion;
   4749 			const VkOffset3D	srcOffset	= {0, 0, 0};
   4750 			const VkOffset3D	dstOffset	= {i, defaultSize - i - defaultFourthSize, 0};
   4751 			const VkExtent3D	extent		= {defaultFourthSize, defaultFourthSize, 1};
   4752 
   4753 			if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
   4754 			{
   4755 				const VkImageCopy				testCopy	=
   4756 				{
   4757 					defaultDepthSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   4758 					srcOffset,					// VkOffset3D				srcOffset;
   4759 					defaultDepthSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   4760 					dstOffset,					// VkOffset3D				dstOffset;
   4761 					extent,						// VkExtent3D				extent;
   4762 				};
   4763 
   4764 				copyRegion.imageCopy	= testCopy;
   4765 				params.regions.push_back(copyRegion);
   4766 			}
   4767 			if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
   4768 			{
   4769 				const VkImageCopy				testCopy	=
   4770 				{
   4771 					defaultStencilSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   4772 					srcOffset,					// VkOffset3D				srcOffset;
   4773 					defaultStencilSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   4774 					dstOffset,					// VkOffset3D				dstOffset;
   4775 					extent,						// VkExtent3D				extent;
   4776 				};
   4777 
   4778 				copyRegion.imageCopy	= testCopy;
   4779 				params.regions.push_back(copyRegion);
   4780 			}
   4781 		}
   4782 
   4783 		const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
   4784 		const std::string description	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
   4785 		addTestGroup(group, testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
   4786 	}
   4787 }
   4788 
   4789 void addImageToImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   4790 {
   4791 	addTestGroup(group, "color", "Copy image to image with color formats", addImageToImageAllFormatsColorTests, allocationKind);
   4792 	addTestGroup(group, "depth_stencil", "Copy image to image with depth/stencil formats", addImageToImageAllFormatsDepthStencilTests, allocationKind);
   4793 }
   4794 
   4795 void addImageToImage3dImagesTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   4796 {
   4797 	tcu::TestContext& testCtx	= group->getTestContext();
   4798 
   4799 	{
   4800 		TestParams	params3DTo2D;
   4801 		const deUint32	slicesLayers			= 16u;
   4802 		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
   4803 		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
   4804 		params3DTo2D.src.image.extent			= defaultHalfExtent;
   4805 		params3DTo2D.src.image.extent.depth		= slicesLayers;
   4806 		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   4807 		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
   4808 		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
   4809 		params3DTo2D.dst.image.extent			= defaultHalfExtent;
   4810 		params3DTo2D.dst.image.extent.depth		= slicesLayers;
   4811 		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   4812 		params3DTo2D.allocationKind				= allocationKind;
   4813 
   4814 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
   4815 		{
   4816 			const VkImageSubresourceLayers	sourceLayer	=
   4817 			{
   4818 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
   4819 				0u,							// uint32_t				mipLevel;
   4820 				0u,							// uint32_t				baseArrayLayer;
   4821 				1u							// uint32_t				layerCount;
   4822 			};
   4823 
   4824 			const VkImageSubresourceLayers	destinationLayer	=
   4825 			{
   4826 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
   4827 				0u,							// uint32_t				mipLevel;
   4828 				slicesLayersNdx,			// uint32_t				baseArrayLayer;
   4829 				1u							// uint32_t				layerCount;
   4830 			};
   4831 
   4832 			const VkImageCopy				testCopy	=
   4833 			{
   4834 				sourceLayer,						// VkImageSubresourceLayers	srcSubresource;
   4835 				{0, 0, (deInt32)slicesLayersNdx},	// VkOffset3D					srcOffset;
   4836 				destinationLayer,					// VkImageSubresourceLayers	dstSubresource;
   4837 				{0, 0, 0},							// VkOffset3D					dstOffset;
   4838 				defaultHalfExtent,					// VkExtent3D					extent;
   4839 			};
   4840 
   4841 			CopyRegion	imageCopy;
   4842 			imageCopy.imageCopy	= testCopy;
   4843 
   4844 			params3DTo2D.regions.push_back(imageCopy);
   4845 		}
   4846 		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D));
   4847 	}
   4848 
   4849 	{
   4850 		TestParams	params2DTo3D;
   4851 		const deUint32	slicesLayers			= 16u;
   4852 		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
   4853 		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
   4854 		params2DTo3D.src.image.extent			= defaultHalfExtent;
   4855 		params2DTo3D.src.image.extent.depth		= slicesLayers;
   4856 		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   4857 		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
   4858 		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
   4859 		params2DTo3D.dst.image.extent			= defaultHalfExtent;
   4860 		params2DTo3D.dst.image.extent.depth		= slicesLayers;
   4861 		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   4862 		params2DTo3D.allocationKind				= allocationKind;
   4863 
   4864 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
   4865 		{
   4866 			const VkImageSubresourceLayers	sourceLayer	=
   4867 			{
   4868 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
   4869 				0u,							// uint32_t				mipLevel;
   4870 				slicesLayersNdx,			// uint32_t				baseArrayLayer;
   4871 				1u							// uint32_t				layerCount;
   4872 			};
   4873 
   4874 			const VkImageSubresourceLayers	destinationLayer	=
   4875 			{
   4876 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
   4877 				0u,							// uint32_t				mipLevel;
   4878 				0u,							// uint32_t				baseArrayLayer;
   4879 				1u							// uint32_t				layerCount;
   4880 			};
   4881 
   4882 			const VkImageCopy				testCopy	=
   4883 			{
   4884 				sourceLayer,						// VkImageSubresourceLayers	srcSubresource;
   4885 				{0, 0, 0},							// VkOffset3D				srcOffset;
   4886 				destinationLayer,					// VkImageSubresourceLayers	dstSubresource;
   4887 				{0, 0, (deInt32)slicesLayersNdx},	// VkOffset3D				dstOffset;
   4888 				defaultHalfExtent,					// VkExtent3D				extent;
   4889 			};
   4890 
   4891 			CopyRegion	imageCopy;
   4892 			imageCopy.imageCopy	= testCopy;
   4893 
   4894 			params2DTo3D.regions.push_back(imageCopy);
   4895 		}
   4896 
   4897 		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D));
   4898 	}
   4899 
   4900 	{
   4901 		TestParams	params3DTo2D;
   4902 		const deUint32	slicesLayers			= 16u;
   4903 		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
   4904 		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
   4905 		params3DTo2D.src.image.extent			= defaultHalfExtent;
   4906 		params3DTo2D.src.image.extent.depth		= slicesLayers;
   4907 		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   4908 		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
   4909 		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
   4910 		params3DTo2D.dst.image.extent			= defaultHalfExtent;
   4911 		params3DTo2D.dst.image.extent.depth		= slicesLayers;
   4912 		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   4913 		params3DTo2D.allocationKind				= allocationKind;
   4914 
   4915 		{
   4916 			const VkImageSubresourceLayers	sourceLayer	=
   4917 			{
   4918 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
   4919 				0u,							// uint32_t				mipLevel;
   4920 				0u,							// uint32_t				baseArrayLayer;
   4921 				1u							// uint32_t				layerCount;
   4922 			};
   4923 
   4924 			const VkImageSubresourceLayers	destinationLayer	=
   4925 			{
   4926 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
   4927 				0u,							// uint32_t				mipLevel;
   4928 				0,							// uint32_t				baseArrayLayer;
   4929 				slicesLayers				// uint32_t				layerCount;
   4930 			};
   4931 
   4932 			const VkImageCopy				testCopy	=
   4933 			{
   4934 				sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
   4935 				{0, 0, 0},						// VkOffset3D				srcOffset;
   4936 				destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
   4937 				{0, 0, 0},						// VkOffset3D				dstOffset;
   4938 				params3DTo2D.src.image.extent	// VkExtent3D				extent;
   4939 			};
   4940 
   4941 			CopyRegion	imageCopy;
   4942 			imageCopy.imageCopy	= testCopy;
   4943 
   4944 			params3DTo2D.regions.push_back(imageCopy);
   4945 		}
   4946 		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D));
   4947 	}
   4948 
   4949 	{
   4950 		TestParams	params2DTo3D;
   4951 		const deUint32	slicesLayers			= 16u;
   4952 		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
   4953 		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
   4954 		params2DTo3D.src.image.extent			= defaultHalfExtent;
   4955 		params2DTo3D.src.image.extent.depth		= slicesLayers;
   4956 		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   4957 		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
   4958 		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
   4959 		params2DTo3D.dst.image.extent			= defaultHalfExtent;
   4960 		params2DTo3D.dst.image.extent.depth		= slicesLayers;
   4961 		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   4962 		params2DTo3D.allocationKind				= allocationKind;
   4963 
   4964 		{
   4965 			const VkImageSubresourceLayers	sourceLayer	=
   4966 			{
   4967 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
   4968 				0u,							// uint32_t				mipLevel;
   4969 				0u,							// uint32_t				baseArrayLayer;
   4970 				slicesLayers				// uint32_t				layerCount;
   4971 			};
   4972 
   4973 			const VkImageSubresourceLayers	destinationLayer	=
   4974 			{
   4975 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
   4976 				0u,							// uint32_t				mipLevel;
   4977 				0u,							// uint32_t				baseArrayLayer;
   4978 				1u							// uint32_t				layerCount;
   4979 			};
   4980 
   4981 			const VkImageCopy				testCopy	=
   4982 			{
   4983 				sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
   4984 				{0, 0, 0},						// VkOffset3D				srcOffset;
   4985 				destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
   4986 				{0, 0, 0},						// VkOffset3D				dstOffset;
   4987 				params2DTo3D.src.image.extent,	// VkExtent3D				extent;
   4988 			};
   4989 
   4990 			CopyRegion	imageCopy;
   4991 			imageCopy.imageCopy	= testCopy;
   4992 
   4993 			params2DTo3D.regions.push_back(imageCopy);
   4994 		}
   4995 
   4996 		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D));
   4997 	}
   4998 
   4999 	{
   5000 		TestParams	params3DTo2D;
   5001 		const deUint32	slicesLayers			= 16u;
   5002 		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
   5003 		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
   5004 		params3DTo2D.src.image.extent			= defaultHalfExtent;
   5005 		params3DTo2D.src.image.extent.depth		= slicesLayers;
   5006 		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   5007 		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
   5008 		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
   5009 		params3DTo2D.dst.image.extent			= defaultHalfExtent;
   5010 		params3DTo2D.dst.image.extent.depth		= slicesLayers;
   5011 		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   5012 		params3DTo2D.allocationKind				= allocationKind;
   5013 
   5014 		const deUint32 regionWidth				= defaultHalfExtent.width / slicesLayers -1;
   5015 		const deUint32 regionHeight				= defaultHalfExtent.height / slicesLayers -1 ;
   5016 
   5017 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
   5018 		{
   5019 			const VkImageSubresourceLayers	sourceLayer	=
   5020 			{
   5021 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
   5022 				0u,							// uint32_t				mipLevel;
   5023 				0u,							// uint32_t				baseArrayLayer;
   5024 				1u							// uint32_t				layerCount;
   5025 			};
   5026 
   5027 			const VkImageSubresourceLayers	destinationLayer	=
   5028 			{
   5029 					VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
   5030 					0u,								// uint32_t				mipLevel;
   5031 					slicesLayersNdx,				// uint32_t				baseArrayLayer;
   5032 					1u								// uint32_t				layerCount;
   5033 			};
   5034 
   5035 
   5036 			const VkImageCopy				testCopy	=
   5037 			{
   5038 				sourceLayer,															// VkImageSubresourceLayers	srcSubresource;
   5039 				{0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx},	// VkOffset3D				srcOffset;
   5040 					destinationLayer,													// VkImageSubresourceLayers	dstSubresource;
   5041 					{(deInt32)(regionWidth*slicesLayersNdx), 0, 0},						// VkOffset3D				dstOffset;
   5042 					{
   5043 						(defaultHalfExtent.width - regionWidth*slicesLayersNdx),
   5044 						(defaultHalfExtent.height - regionHeight*slicesLayersNdx),
   5045 						1
   5046 					}																	// VkExtent3D				extent;
   5047 			};
   5048 
   5049 			CopyRegion	imageCopy;
   5050 			imageCopy.imageCopy = testCopy;
   5051 			params3DTo2D.regions.push_back(imageCopy);
   5052 		}
   5053 		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D));
   5054 	}
   5055 
   5056 	{
   5057 		TestParams	params2DTo3D;
   5058 		const deUint32	slicesLayers			= 16u;
   5059 		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
   5060 		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
   5061 		params2DTo3D.src.image.extent			= defaultHalfExtent;
   5062 		params2DTo3D.src.image.extent.depth		= slicesLayers;
   5063 		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   5064 		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
   5065 		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
   5066 		params2DTo3D.dst.image.extent			= defaultHalfExtent;
   5067 		params2DTo3D.dst.image.extent.depth		= slicesLayers;
   5068 		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   5069 		params2DTo3D.allocationKind				= allocationKind;
   5070 
   5071 		const deUint32 regionWidth				= defaultHalfExtent.width / slicesLayers -1;
   5072 		const deUint32 regionHeight				= defaultHalfExtent.height / slicesLayers -1 ;
   5073 
   5074 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
   5075 		{
   5076 			const VkImageSubresourceLayers	sourceLayer	=
   5077 			{
   5078 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
   5079 				0u,							// uint32_t				mipLevel;
   5080 				slicesLayersNdx,			// uint32_t				baseArrayLayer;
   5081 				1u							// uint32_t				layerCount;
   5082 			};
   5083 
   5084 			const VkImageSubresourceLayers	destinationLayer	=
   5085 			{
   5086 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
   5087 				0u,							// uint32_t				mipLevel;
   5088 				0u,							// uint32_t				baseArrayLayer;
   5089 				1u							// uint32_t				layerCount;
   5090 			};
   5091 
   5092 			const VkImageCopy				testCopy	=
   5093 			{
   5094 				sourceLayer,																// VkImageSubresourceLayers	srcSubresource;
   5095 				{(deInt32)(regionWidth*slicesLayersNdx), 0, 0},								// VkOffset3D				srcOffset;
   5096 				destinationLayer,															// VkImageSubresourceLayers	dstSubresource;
   5097 				{0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)},	// VkOffset3D				dstOffset;
   5098 				{
   5099 					defaultHalfExtent.width - regionWidth*slicesLayersNdx,
   5100 					defaultHalfExtent.height - regionHeight*slicesLayersNdx,
   5101 					1
   5102 				}																			// VkExtent3D				extent;
   5103 			};
   5104 
   5105 			CopyRegion	imageCopy;
   5106 			imageCopy.imageCopy	= testCopy;
   5107 
   5108 			params2DTo3D.regions.push_back(imageCopy);
   5109 		}
   5110 
   5111 		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D));
   5112 	}
   5113 }
   5114 
   5115 void addImageToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   5116 {
   5117 	addTestGroup(group, "simple_tests", "Copy from image to image simple tests", addImageToImageSimpleTests, allocationKind);
   5118 	addTestGroup(group, "all_formats", "Copy from image to image with all compatible formats", addImageToImageAllFormatsTests, allocationKind);
   5119 	addTestGroup(group, "3d_images", "Coping operations on 3d images", addImageToImage3dImagesTests, allocationKind);
   5120 }
   5121 
   5122 void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   5123 {
   5124 	tcu::TestContext& testCtx	= group->getTestContext();
   5125 
   5126 	{
   5127 		TestParams	params;
   5128 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   5129 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   5130 		params.src.image.extent				= defaultExtent;
   5131 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   5132 		params.dst.buffer.size				= defaultSize * defaultSize;
   5133 		params.allocationKind				= allocationKind;
   5134 
   5135 		const VkBufferImageCopy	bufferImageCopy	=
   5136 		{
   5137 			0u,											// VkDeviceSize				bufferOffset;
   5138 			0u,											// uint32_t					bufferRowLength;
   5139 			0u,											// uint32_t					bufferImageHeight;
   5140 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
   5141 			{0, 0, 0},									// VkOffset3D				imageOffset;
   5142 			defaultExtent								// VkExtent3D				imageExtent;
   5143 		};
   5144 		CopyRegion	copyRegion;
   5145 		copyRegion.bufferImageCopy	= bufferImageCopy;
   5146 
   5147 		params.regions.push_back(copyRegion);
   5148 
   5149 		group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
   5150 	}
   5151 
   5152 	{
   5153 		TestParams	params;
   5154 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   5155 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   5156 		params.src.image.extent				= defaultExtent;
   5157 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   5158 		params.dst.buffer.size				= defaultSize * defaultSize;
   5159 		params.allocationKind				= allocationKind;
   5160 
   5161 		const VkBufferImageCopy	bufferImageCopy	=
   5162 		{
   5163 			defaultSize * defaultHalfSize,				// VkDeviceSize				bufferOffset;
   5164 			0u,											// uint32_t					bufferRowLength;
   5165 			0u,											// uint32_t					bufferImageHeight;
   5166 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
   5167 			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
   5168 			defaultHalfExtent							// VkExtent3D				imageExtent;
   5169 		};
   5170 		CopyRegion	copyRegion;
   5171 		copyRegion.bufferImageCopy	= bufferImageCopy;
   5172 
   5173 		params.regions.push_back(copyRegion);
   5174 
   5175 		group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
   5176 	}
   5177 
   5178 	{
   5179 		TestParams	params;
   5180 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   5181 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   5182 		params.src.image.extent				= defaultExtent;
   5183 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   5184 		params.dst.buffer.size				= defaultSize * defaultSize;
   5185 		params.allocationKind				= allocationKind;
   5186 
   5187 		const int			pixelSize	= tcu::getPixelSize(mapVkFormat(params.src.image.format));
   5188 		const VkDeviceSize	bufferSize	= pixelSize * params.dst.buffer.size;
   5189 		const VkDeviceSize	offsetSize	= pixelSize * defaultFourthSize * defaultFourthSize;
   5190 		deUint32			divisor		= 1;
   5191 		for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
   5192 		{
   5193 			const deUint32			bufferRowLength		= defaultFourthSize;
   5194 			const deUint32			bufferImageHeight	= defaultFourthSize;
   5195 			const VkExtent3D		imageExtent			= {defaultFourthSize / divisor, defaultFourthSize, 1};
   5196 			DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
   5197 			DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
   5198 			DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize);
   5199 
   5200 			CopyRegion				region;
   5201 			const VkBufferImageCopy	bufferImageCopy		=
   5202 			{
   5203 				offset,						// VkDeviceSize				bufferOffset;
   5204 				bufferRowLength,			// uint32_t					bufferRowLength;
   5205 				bufferImageHeight,			// uint32_t					bufferImageHeight;
   5206 				defaultSourceLayer,			// VkImageSubresourceLayers	imageSubresource;
   5207 				{0, 0, 0},					// VkOffset3D				imageOffset;
   5208 				imageExtent					// VkExtent3D				imageExtent;
   5209 			};
   5210 			region.bufferImageCopy	= bufferImageCopy;
   5211 			params.regions.push_back(region);
   5212 		}
   5213 
   5214 		group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
   5215 	}
   5216 }
   5217 
   5218 void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   5219 {
   5220 	tcu::TestContext& testCtx	= group->getTestContext();
   5221 
   5222 	{
   5223 		TestParams	params;
   5224 		params.src.buffer.size				= defaultSize * defaultSize;
   5225 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   5226 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
   5227 		params.dst.image.extent				= defaultExtent;
   5228 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   5229 		params.allocationKind				= allocationKind;
   5230 
   5231 		const VkBufferImageCopy	bufferImageCopy	=
   5232 		{
   5233 			0u,											// VkDeviceSize				bufferOffset;
   5234 			0u,											// uint32_t					bufferRowLength;
   5235 			0u,											// uint32_t					bufferImageHeight;
   5236 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
   5237 			{0, 0, 0},									// VkOffset3D				imageOffset;
   5238 			defaultExtent								// VkExtent3D				imageExtent;
   5239 		};
   5240 		CopyRegion	copyRegion;
   5241 		copyRegion.bufferImageCopy	= bufferImageCopy;
   5242 
   5243 		params.regions.push_back(copyRegion);
   5244 
   5245 		group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
   5246 	}
   5247 
   5248 	{
   5249 		TestParams	params;
   5250 		params.src.buffer.size				= defaultSize * defaultSize;
   5251 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   5252 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   5253 		params.dst.image.extent				= defaultExtent;
   5254 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   5255 		params.allocationKind				= allocationKind;
   5256 
   5257 		CopyRegion	region;
   5258 		deUint32	divisor	= 1;
   5259 		for (int offset = 0; (offset + defaultFourthSize / divisor < defaultSize) && (defaultFourthSize > divisor); offset += defaultFourthSize / divisor++)
   5260 		{
   5261 			const VkBufferImageCopy	bufferImageCopy	=
   5262 			{
   5263 				0u,																// VkDeviceSize				bufferOffset;
   5264 				0u,																// uint32_t					bufferRowLength;
   5265 				0u,																// uint32_t					bufferImageHeight;
   5266 				defaultSourceLayer,												// VkImageSubresourceLayers	imageSubresource;
   5267 				{offset, defaultHalfSize, 0},									// VkOffset3D				imageOffset;
   5268 				{defaultFourthSize / divisor, defaultFourthSize / divisor, 1}	// VkExtent3D				imageExtent;
   5269 			};
   5270 			region.bufferImageCopy	= bufferImageCopy;
   5271 			params.regions.push_back(region);
   5272 		}
   5273 
   5274 		group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
   5275 	}
   5276 
   5277 	{
   5278 		TestParams	params;
   5279 		params.src.buffer.size				= defaultSize * defaultSize;
   5280 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   5281 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   5282 		params.dst.image.extent				= defaultExtent;
   5283 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   5284 		params.allocationKind				= allocationKind;
   5285 
   5286 		const VkBufferImageCopy	bufferImageCopy	=
   5287 		{
   5288 			defaultFourthSize,							// VkDeviceSize				bufferOffset;
   5289 			defaultHalfSize + defaultFourthSize,		// uint32_t					bufferRowLength;
   5290 			defaultHalfSize + defaultFourthSize,		// uint32_t					bufferImageHeight;
   5291 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
   5292 			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
   5293 			defaultHalfExtent							// VkExtent3D				imageExtent;
   5294 		};
   5295 		CopyRegion	copyRegion;
   5296 		copyRegion.bufferImageCopy	= bufferImageCopy;
   5297 
   5298 		params.regions.push_back(copyRegion);
   5299 
   5300 		group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
   5301 	}
   5302 }
   5303 
   5304 void addBufferToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   5305 {
   5306 	tcu::TestContext&				testCtx					= group->getTestContext();
   5307 
   5308 	{
   5309 		TestParams			params;
   5310 		params.src.buffer.size	= defaultSize;
   5311 		params.dst.buffer.size	= defaultSize;
   5312 		params.allocationKind	= allocationKind;
   5313 
   5314 		const VkBufferCopy	bufferCopy	=
   5315 		{
   5316 			0u,				// VkDeviceSize	srcOffset;
   5317 			0u,				// VkDeviceSize	dstOffset;
   5318 			defaultSize,	// VkDeviceSize	size;
   5319 		};
   5320 
   5321 		CopyRegion	copyRegion;
   5322 		copyRegion.bufferCopy	= bufferCopy;
   5323 		params.regions.push_back(copyRegion);
   5324 
   5325 		group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
   5326 	}
   5327 
   5328 	// Filter is VK_FILTER_NEAREST.
   5329 	{
   5330 		TestParams			params;
   5331 		params.src.buffer.size	= defaultFourthSize;
   5332 		params.dst.buffer.size	= defaultFourthSize;
   5333 		params.allocationKind	= allocationKind;
   5334 
   5335 		const VkBufferCopy	bufferCopy	=
   5336 		{
   5337 			12u,	// VkDeviceSize	srcOffset;
   5338 			4u,		// VkDeviceSize	dstOffset;
   5339 			1u,		// VkDeviceSize	size;
   5340 		};
   5341 
   5342 		CopyRegion	copyRegion;
   5343 		copyRegion.bufferCopy = bufferCopy;
   5344 		params.regions.push_back(copyRegion);
   5345 
   5346 		group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
   5347 	}
   5348 
   5349 	{
   5350 		const deUint32		size		= 16;
   5351 		TestParams			params;
   5352 		params.src.buffer.size	= size;
   5353 		params.dst.buffer.size	= size * (size + 1);
   5354 		params.allocationKind	= allocationKind;
   5355 
   5356 		// Copy region with size 1..size
   5357 		for (unsigned int i = 1; i <= size; i++)
   5358 		{
   5359 			const VkBufferCopy	bufferCopy	=
   5360 			{
   5361 				0,			// VkDeviceSize	srcOffset;
   5362 				i * size,	// VkDeviceSize	dstOffset;
   5363 				i,			// VkDeviceSize	size;
   5364 			};
   5365 
   5366 			CopyRegion	copyRegion;
   5367 			copyRegion.bufferCopy = bufferCopy;
   5368 			params.regions.push_back(copyRegion);
   5369 		}
   5370 
   5371 		group->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params));
   5372 	}
   5373 }
   5374 
   5375 void addBlittingImageSimpleWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   5376 {
   5377 	tcu::TestContext&	testCtx			= group->getTestContext();
   5378 	TestParams			params;
   5379 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   5380 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   5381 	params.src.image.extent				= defaultExtent;
   5382 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   5383 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   5384 	params.dst.image.extent				= defaultExtent;
   5385 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   5386 	params.allocationKind				= allocationKind;
   5387 
   5388 	{
   5389 		const VkImageBlit				imageBlit =
   5390 		{
   5391 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   5392 			{
   5393 				{ 0, 0, 0 },
   5394 				{ defaultSize, defaultSize, 1 }
   5395 			},					// VkOffset3D				srcOffsets[2];
   5396 
   5397 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   5398 			{
   5399 				{ 0, 0, 0 },
   5400 				{ defaultSize, defaultSize, 1 }
   5401 			}					// VkOffset3D				dstOffset[2];
   5402 		};
   5403 
   5404 		CopyRegion	region;
   5405 		region.imageBlit = imageBlit;
   5406 		params.regions.push_back(region);
   5407 	}
   5408 
   5409 	// Filter is VK_FILTER_NEAREST.
   5410 	{
   5411 		params.filter					= VK_FILTER_NEAREST;
   5412 		const std::string description	= "Nearest filter";
   5413 
   5414 		params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
   5415 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
   5416 
   5417 		params.dst.image.format = VK_FORMAT_R32_SFLOAT;
   5418 		const std::string	descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
   5419 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
   5420 
   5421 		params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
   5422 		const std::string	descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   5423 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
   5424 	}
   5425 
   5426 	// Filter is VK_FILTER_LINEAR.
   5427 	{
   5428 		params.filter					= VK_FILTER_LINEAR;
   5429 		const std::string description	= "Linear filter";
   5430 
   5431 		params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
   5432 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
   5433 
   5434 		params.dst.image.format = VK_FORMAT_R32_SFLOAT;
   5435 		const std::string	descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
   5436 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
   5437 
   5438 		params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
   5439 		const std::string	descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   5440 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
   5441 	}
   5442 }
   5443 
   5444 void addBlittingImageSimpleMirrorXYTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   5445 {
   5446 	tcu::TestContext&	testCtx			= group->getTestContext();
   5447 	TestParams			params;
   5448 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   5449 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   5450 	params.src.image.extent				= defaultExtent;
   5451 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   5452 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   5453 	params.dst.image.extent				= defaultExtent;
   5454 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   5455 	params.allocationKind				= allocationKind;
   5456 
   5457 	{
   5458 		const VkImageBlit				imageBlit	=
   5459 		{
   5460 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   5461 			{
   5462 				{0, 0, 0},
   5463 				{defaultSize, defaultSize, 1}
   5464 			},					// VkOffset3D				srcOffsets[2];
   5465 
   5466 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   5467 			{
   5468 				{defaultSize, defaultSize, 0},
   5469 				{0, 0, 1}
   5470 			}					// VkOffset3D				dstOffset[2];
   5471 		};
   5472 
   5473 		CopyRegion	region;
   5474 		region.imageBlit = imageBlit;
   5475 		params.regions.push_back(region);
   5476 	}
   5477 
   5478 	// Filter is VK_FILTER_NEAREST.
   5479 	{
   5480 		params.filter					= VK_FILTER_NEAREST;
   5481 		const std::string description	= "Nearest filter";
   5482 
   5483 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
   5484 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
   5485 
   5486 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
   5487 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
   5488 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
   5489 
   5490 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
   5491 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   5492 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
   5493 	}
   5494 
   5495 	// Filter is VK_FILTER_LINEAR.
   5496 	{
   5497 		params.filter					= VK_FILTER_LINEAR;
   5498 		const std::string description	= "Linear filter";
   5499 
   5500 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
   5501 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
   5502 
   5503 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
   5504 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
   5505 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
   5506 
   5507 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
   5508 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   5509 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
   5510 	}
   5511 }
   5512 
   5513 void addBlittingImageSimpleMirrorXTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   5514 {
   5515 	tcu::TestContext&	testCtx			= group->getTestContext();
   5516 	TestParams			params;
   5517 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   5518 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   5519 	params.src.image.extent				= defaultExtent;
   5520 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   5521 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   5522 	params.dst.image.extent				= defaultExtent;
   5523 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   5524 	params.allocationKind				= allocationKind;
   5525 
   5526 	{
   5527 		const VkImageBlit				imageBlit	=
   5528 		{
   5529 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   5530 			{
   5531 				{0, 0, 0},
   5532 				{defaultSize, defaultSize, 1}
   5533 			},					// VkOffset3D				srcOffsets[2];
   5534 
   5535 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   5536 			{
   5537 				{defaultSize, 0, 0},
   5538 				{0, defaultSize, 1}
   5539 			}					// VkOffset3D				dstOffset[2];
   5540 		};
   5541 
   5542 		CopyRegion	region;
   5543 		region.imageBlit = imageBlit;
   5544 		params.regions.push_back(region);
   5545 	}
   5546 
   5547 	// Filter is VK_FILTER_NEAREST.
   5548 	{
   5549 		params.filter					= VK_FILTER_NEAREST;
   5550 		const std::string description	= "Nearest filter";
   5551 
   5552 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
   5553 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
   5554 
   5555 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
   5556 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
   5557 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
   5558 
   5559 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
   5560 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   5561 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
   5562 	}
   5563 
   5564 	// Filter is VK_FILTER_LINEAR.
   5565 	{
   5566 		params.filter					= VK_FILTER_LINEAR;
   5567 		const std::string description	= "Linear filter";
   5568 
   5569 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
   5570 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
   5571 
   5572 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
   5573 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
   5574 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
   5575 
   5576 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
   5577 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   5578 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
   5579 	}
   5580 }
   5581 
   5582 void addBlittingImageSimpleMirrorYTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   5583 {
   5584 	tcu::TestContext&	testCtx			= group->getTestContext();
   5585 	TestParams			params;
   5586 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   5587 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   5588 	params.src.image.extent				= defaultExtent;
   5589 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   5590 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   5591 	params.dst.image.extent				= defaultExtent;
   5592 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   5593 	params.allocationKind				= allocationKind;
   5594 
   5595 	{
   5596 		const VkImageBlit				imageBlit	=
   5597 		{
   5598 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   5599 			{
   5600 				{0, 0, 0},
   5601 				{defaultSize, defaultSize, 1}
   5602 			},					// VkOffset3D				srcOffsets[2];
   5603 
   5604 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   5605 			{
   5606 				{0, defaultSize, 0},
   5607 				{defaultSize, 0, 1}
   5608 			}					// VkOffset3D				dstOffset[2];
   5609 		};
   5610 
   5611 		CopyRegion	region;
   5612 		region.imageBlit = imageBlit;
   5613 		params.regions.push_back(region);
   5614 	}
   5615 
   5616 	// Filter is VK_FILTER_NEAREST.
   5617 	{
   5618 		params.filter					= VK_FILTER_NEAREST;
   5619 		const std::string description	= "Nearest filter";
   5620 
   5621 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
   5622 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
   5623 
   5624 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
   5625 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
   5626 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
   5627 
   5628 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
   5629 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   5630 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
   5631 	}
   5632 
   5633 	// Filter is VK_FILTER_LINEAR.
   5634 	{
   5635 		params.filter					= VK_FILTER_LINEAR;
   5636 		const std::string description	= "Linear filter";
   5637 
   5638 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
   5639 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
   5640 
   5641 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
   5642 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
   5643 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
   5644 
   5645 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
   5646 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   5647 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
   5648 	}
   5649 }
   5650 
   5651 void addBlittingImageSimpleMirrorSubregionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   5652 {
   5653 	tcu::TestContext&	testCtx			= group->getTestContext();
   5654 	TestParams			params;
   5655 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   5656 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   5657 	params.src.image.extent				= defaultExtent;
   5658 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   5659 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   5660 	params.dst.image.extent				= defaultExtent;
   5661 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   5662 	params.allocationKind				= allocationKind;
   5663 
   5664 	// No mirroring.
   5665 	{
   5666 		const VkImageBlit				imageBlit	=
   5667 		{
   5668 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   5669 			{
   5670 				{0, 0, 0},
   5671 				{defaultHalfSize, defaultHalfSize, 1}
   5672 			},					// VkOffset3D				srcOffsets[2];
   5673 
   5674 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   5675 			{
   5676 				{0, 0, 0},
   5677 				{defaultHalfSize, defaultHalfSize, 1}
   5678 			}					// VkOffset3D				dstOffset[2];
   5679 		};
   5680 
   5681 		CopyRegion	region;
   5682 		region.imageBlit = imageBlit;
   5683 		params.regions.push_back(region);
   5684 	}
   5685 
   5686 	// Flipping y coordinates.
   5687 	{
   5688 		const VkImageBlit				imageBlit	=
   5689 		{
   5690 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   5691 			{
   5692 				{defaultHalfSize, 0, 0},
   5693 				{defaultSize, defaultHalfSize, 1}
   5694 			},					// VkOffset3D				srcOffsets[2];
   5695 
   5696 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   5697 			{
   5698 				{defaultHalfSize, defaultHalfSize, 0},
   5699 				{defaultSize, 0, 1}
   5700 			}					// VkOffset3D				dstOffset[2];
   5701 		};
   5702 		CopyRegion	region;
   5703 		region.imageBlit = imageBlit;
   5704 		params.regions.push_back(region);
   5705 	}
   5706 
   5707 	// Flipping x coordinates.
   5708 	{
   5709 		const VkImageBlit				imageBlit	=
   5710 		{
   5711 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   5712 			{
   5713 				{0, defaultHalfSize, 0},
   5714 				{defaultHalfSize, defaultSize, 1}
   5715 			},					// VkOffset3D				srcOffsets[2];
   5716 
   5717 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   5718 			{
   5719 				{defaultHalfSize, defaultHalfSize, 0},
   5720 				{0, defaultSize, 1}
   5721 			}					// VkOffset3D				dstOffset[2];
   5722 		};
   5723 
   5724 		CopyRegion	region;
   5725 		region.imageBlit = imageBlit;
   5726 		params.regions.push_back(region);
   5727 	}
   5728 
   5729 	// Flipping x and y coordinates.
   5730 	{
   5731 		const VkImageBlit				imageBlit	=
   5732 		{
   5733 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   5734 			{
   5735 				{defaultHalfSize, defaultHalfSize, 0},
   5736 				{defaultSize, defaultSize, 1}
   5737 			},					// VkOffset3D				srcOffsets[2];
   5738 
   5739 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   5740 			{
   5741 				{defaultSize, defaultSize, 0},
   5742 				{defaultHalfSize, defaultHalfSize, 1}
   5743 			}					// VkOffset3D				dstOffset[2];
   5744 		};
   5745 
   5746 		CopyRegion	region;
   5747 		region.imageBlit = imageBlit;
   5748 		params.regions.push_back(region);
   5749 	}
   5750 
   5751 	// Filter is VK_FILTER_NEAREST.
   5752 	{
   5753 		params.filter					= VK_FILTER_NEAREST;
   5754 		const std::string description	= "Nearest filter";
   5755 
   5756 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
   5757 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
   5758 
   5759 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
   5760 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
   5761 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
   5762 
   5763 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
   5764 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   5765 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
   5766 	}
   5767 
   5768 	// Filter is VK_FILTER_LINEAR.
   5769 	{
   5770 		params.filter					= VK_FILTER_LINEAR;
   5771 		const std::string description	= "Linear filter";
   5772 
   5773 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
   5774 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
   5775 
   5776 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
   5777 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
   5778 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
   5779 
   5780 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
   5781 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   5782 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
   5783 	}
   5784 }
   5785 
   5786 void addBlittingImageSimpleScalingWhole1Tests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   5787 {
   5788 	tcu::TestContext&	testCtx			= group->getTestContext();
   5789 	TestParams			params;
   5790 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   5791 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   5792 	params.src.image.extent				= defaultExtent;
   5793 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   5794 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   5795 	params.dst.image.extent				= defaultHalfExtent;
   5796 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   5797 	params.allocationKind				= allocationKind;
   5798 
   5799 	{
   5800 		const VkImageBlit				imageBlit	=
   5801 		{
   5802 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   5803 			{
   5804 				{0, 0, 0},
   5805 				{defaultSize, defaultSize, 1}
   5806 			},					// VkOffset3D					srcOffsets[2];
   5807 
   5808 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   5809 			{
   5810 				{0, 0, 0},
   5811 				{defaultHalfSize, defaultHalfSize, 1}
   5812 			}					// VkOffset3D					dstOffset[2];
   5813 		};
   5814 
   5815 		CopyRegion	region;
   5816 		region.imageBlit	= imageBlit;
   5817 		params.regions.push_back(region);
   5818 	}
   5819 
   5820 	// Filter is VK_FILTER_NEAREST.
   5821 	{
   5822 		params.filter					= VK_FILTER_NEAREST;
   5823 		const std::string description	= "Nearest filter";
   5824 
   5825 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
   5826 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
   5827 
   5828 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
   5829 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
   5830 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
   5831 
   5832 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
   5833 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   5834 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
   5835 	}
   5836 
   5837 	// Filter is VK_FILTER_LINEAR.
   5838 	{
   5839 		params.filter					= VK_FILTER_LINEAR;
   5840 		const std::string description	= "Linear filter";
   5841 
   5842 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
   5843 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
   5844 
   5845 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
   5846 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)" );
   5847 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
   5848 
   5849 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
   5850 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   5851 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
   5852 	}
   5853 }
   5854 
   5855 void addBlittingImageSimpleScalingWhole2Tests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   5856 {
   5857 	tcu::TestContext&	testCtx			= group->getTestContext();
   5858 	TestParams			params;
   5859 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   5860 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   5861 	params.src.image.extent				= defaultHalfExtent;
   5862 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   5863 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   5864 	params.dst.image.extent				= defaultExtent;
   5865 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   5866 	params.allocationKind				= allocationKind;
   5867 
   5868 	{
   5869 		const VkImageBlit				imageBlit	=
   5870 		{
   5871 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   5872 			{
   5873 				{0, 0, 0},
   5874 				{defaultHalfSize, defaultHalfSize, 1}
   5875 			},					// VkOffset3D					srcOffsets[2];
   5876 
   5877 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   5878 			{
   5879 				{0, 0, 0},
   5880 				{defaultSize, defaultSize, 1}
   5881 			}					// VkOffset3D					dstOffset[2];
   5882 		};
   5883 
   5884 		CopyRegion	region;
   5885 		region.imageBlit	= imageBlit;
   5886 		params.regions.push_back(region);
   5887 	}
   5888 
   5889 	// Filter is VK_FILTER_NEAREST.
   5890 	{
   5891 		params.filter					= VK_FILTER_NEAREST;
   5892 		const std::string description	= "Nearest filter";
   5893 
   5894 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
   5895 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
   5896 
   5897 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
   5898 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
   5899 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
   5900 
   5901 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
   5902 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   5903 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
   5904 	}
   5905 
   5906 	// Filter is VK_FILTER_LINEAR.
   5907 	{
   5908 		params.filter					= VK_FILTER_LINEAR;
   5909 		const std::string description	= "Linear filter";
   5910 
   5911 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
   5912 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
   5913 
   5914 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
   5915 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
   5916 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
   5917 
   5918 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
   5919 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   5920 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
   5921 	}
   5922 }
   5923 
   5924 void addBlittingImageSimpleScalingAndOffsetTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   5925 {
   5926 	tcu::TestContext&	testCtx			= group->getTestContext();
   5927 	TestParams			params;
   5928 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   5929 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   5930 	params.src.image.extent				= defaultExtent;
   5931 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   5932 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   5933 	params.dst.image.extent				= defaultExtent;
   5934 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   5935 	params.allocationKind				= allocationKind;
   5936 
   5937 	{
   5938 		const VkImageBlit				imageBlit	=
   5939 		{
   5940 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   5941 			{
   5942 				{defaultFourthSize, defaultFourthSize, 0},
   5943 				{defaultFourthSize*3, defaultFourthSize*3, 1}
   5944 			},					// VkOffset3D					srcOffsets[2];
   5945 
   5946 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   5947 			{
   5948 				{0, 0, 0},
   5949 				{defaultSize, defaultSize, 1}
   5950 			}					// VkOffset3D					dstOffset[2];
   5951 		};
   5952 
   5953 		CopyRegion	region;
   5954 		region.imageBlit	= imageBlit;
   5955 		params.regions.push_back(region);
   5956 	}
   5957 
   5958 	// Filter is VK_FILTER_NEAREST.
   5959 	{
   5960 		params.filter					= VK_FILTER_NEAREST;
   5961 		const std::string description	= "Nearest filter";
   5962 
   5963 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
   5964 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
   5965 
   5966 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
   5967 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
   5968 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
   5969 
   5970 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
   5971 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   5972 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
   5973 	}
   5974 
   5975 	// Filter is VK_FILTER_LINEAR.
   5976 	{
   5977 		params.filter					= VK_FILTER_LINEAR;
   5978 		const std::string description	= "Linear filter";
   5979 
   5980 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
   5981 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
   5982 
   5983 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
   5984 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
   5985 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
   5986 
   5987 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
   5988 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   5989 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
   5990 	}
   5991 }
   5992 
   5993 void addBlittingImageSimpleWithoutScalingPartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   5994 {
   5995 	tcu::TestContext&	testCtx			= group->getTestContext();
   5996 	TestParams			params;
   5997 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   5998 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   5999 	params.src.image.extent				= defaultExtent;
   6000 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   6001 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   6002 	params.dst.image.extent				= defaultExtent;
   6003 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   6004 	params.allocationKind				= allocationKind;
   6005 
   6006 	{
   6007 		CopyRegion	region;
   6008 		for (int i = 0; i < defaultSize; i += defaultFourthSize)
   6009 		{
   6010 			const VkImageBlit			imageBlit	=
   6011 			{
   6012 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   6013 				{
   6014 					{defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, 0},
   6015 					{defaultSize - i, defaultSize - i, 1}
   6016 				},					// VkOffset3D					srcOffsets[2];
   6017 
   6018 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   6019 				{
   6020 					{i, i, 0},
   6021 					{i + defaultFourthSize, i + defaultFourthSize, 1}
   6022 				}					// VkOffset3D					dstOffset[2];
   6023 			};
   6024 			region.imageBlit	= imageBlit;
   6025 			params.regions.push_back(region);
   6026 		}
   6027 	}
   6028 
   6029 	// Filter is VK_FILTER_NEAREST.
   6030 	{
   6031 		params.filter					= VK_FILTER_NEAREST;
   6032 		const std::string description	= "Nearest filter";
   6033 
   6034 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
   6035 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
   6036 
   6037 
   6038 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
   6039 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
   6040 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
   6041 
   6042 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
   6043 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   6044 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
   6045 	}
   6046 
   6047 	// Filter is VK_FILTER_LINEAR.
   6048 	{
   6049 		params.filter					= VK_FILTER_LINEAR;
   6050 		const std::string description	= "Linear filter";
   6051 
   6052 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
   6053 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
   6054 
   6055 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
   6056 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
   6057 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
   6058 
   6059 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
   6060 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
   6061 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
   6062 	}
   6063 }
   6064 
   6065 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   6066 {
   6067 	addTestGroup(group, "whole", "Blit without scaling (whole)", addBlittingImageSimpleWholeTests, allocationKind);
   6068 	addTestGroup(group, "mirror_xy", "Flipping x and y coordinates (whole)", addBlittingImageSimpleMirrorXYTests, allocationKind);
   6069 	addTestGroup(group, "mirror_x", "Flipping x coordinates (whole)", addBlittingImageSimpleMirrorXTests, allocationKind);
   6070 	addTestGroup(group, "mirror_y", "Flipping y coordinates (whole)", addBlittingImageSimpleMirrorYTests, allocationKind);
   6071 	addTestGroup(group, "mirror_subregions", "Mirroring subregions in image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, allocationKind);
   6072 	addTestGroup(group, "scaling_whole1", "Blit with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, allocationKind);
   6073 	addTestGroup(group, "scaling_whole2", "Blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, allocationKind);
   6074 	addTestGroup(group, "scaling_and_offset", "Blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, allocationKind);
   6075 	addTestGroup(group, "without_scaling_partial", "Blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, allocationKind);
   6076 }
   6077 
   6078 struct BlitColorTestParams
   6079 {
   6080 	TestParams		params;
   6081 	const VkFormat*	compatibleFormats;
   6082 	bool			onlyNearest;
   6083 };
   6084 
   6085 bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams)
   6086 {
   6087 	bool result = true;
   6088 
   6089 	if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
   6090 	{
   6091 		DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty());
   6092 
   6093 		result =
   6094 			de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) ||
   6095 			de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format);
   6096 	}
   6097 
   6098 	return result;
   6099 }
   6100 
   6101 
   6102 void addBlittingImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
   6103 {
   6104 	tcu::TestContext& testCtx				= group->getTestContext();
   6105 
   6106 	const VkImageLayout blitSrcLayouts[]	=
   6107 	{
   6108 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   6109 		VK_IMAGE_LAYOUT_GENERAL
   6110 	};
   6111 	const VkImageLayout blitDstLayouts[]	=
   6112 	{
   6113 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   6114 		VK_IMAGE_LAYOUT_GENERAL
   6115 	};
   6116 
   6117 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
   6118 	{
   6119 		testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
   6120 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
   6121 		{
   6122 			testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
   6123 
   6124 			testParams.params.filter			= VK_FILTER_NEAREST;
   6125 			const std::string testName			= getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
   6126 												  getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
   6127 			const std::string description		= "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) +
   6128 												  " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
   6129 			group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest", description, testParams.params));
   6130 
   6131 			if (!testParams.onlyNearest)
   6132 			{
   6133 				testParams.params.filter		= VK_FILTER_LINEAR;
   6134 				group->addChild(new BlitImageTestCase(testCtx, testName + "_linear", description, testParams.params));
   6135 			}
   6136 		}
   6137 	}
   6138 }
   6139 
   6140 void addBlittingImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
   6141 {
   6142 	for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
   6143 	{
   6144 		testParams.params.dst.image.format	= testParams.compatibleFormats[dstFormatIndex];
   6145 		if (!isSupportedByFramework(testParams.params.dst.image.format))
   6146 			continue;
   6147 
   6148 		if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams))
   6149 			continue;
   6150 
   6151 		const std::string description	= "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format);
   6152 		addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
   6153 	}
   6154 }
   6155 
   6156 const VkFormat	compatibleFormatsUInts[]	=
   6157 {
   6158 	VK_FORMAT_R8_UINT,
   6159 	VK_FORMAT_R8G8_UINT,
   6160 	VK_FORMAT_R8G8B8_UINT,
   6161 	VK_FORMAT_B8G8R8_UINT,
   6162 	VK_FORMAT_R8G8B8A8_UINT,
   6163 	VK_FORMAT_B8G8R8A8_UINT,
   6164 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
   6165 	VK_FORMAT_A2R10G10B10_UINT_PACK32,
   6166 	VK_FORMAT_A2B10G10R10_UINT_PACK32,
   6167 	VK_FORMAT_R16_UINT,
   6168 	VK_FORMAT_R16G16_UINT,
   6169 	VK_FORMAT_R16G16B16_UINT,
   6170 	VK_FORMAT_R16G16B16A16_UINT,
   6171 	VK_FORMAT_R32_UINT,
   6172 	VK_FORMAT_R32G32_UINT,
   6173 	VK_FORMAT_R32G32B32_UINT,
   6174 	VK_FORMAT_R32G32B32A32_UINT,
   6175 	VK_FORMAT_R64_UINT,
   6176 	VK_FORMAT_R64G64_UINT,
   6177 	VK_FORMAT_R64G64B64_UINT,
   6178 	VK_FORMAT_R64G64B64A64_UINT,
   6179 
   6180 	VK_FORMAT_UNDEFINED
   6181 };
   6182 const VkFormat	compatibleFormatsSInts[]	=
   6183 {
   6184 	VK_FORMAT_R8_SINT,
   6185 	VK_FORMAT_R8G8_SINT,
   6186 	VK_FORMAT_R8G8B8_SINT,
   6187 	VK_FORMAT_B8G8R8_SINT,
   6188 	VK_FORMAT_R8G8B8A8_SINT,
   6189 	VK_FORMAT_B8G8R8A8_SINT,
   6190 	VK_FORMAT_A8B8G8R8_SINT_PACK32,
   6191 	VK_FORMAT_A2R10G10B10_SINT_PACK32,
   6192 	VK_FORMAT_A2B10G10R10_SINT_PACK32,
   6193 	VK_FORMAT_R16_SINT,
   6194 	VK_FORMAT_R16G16_SINT,
   6195 	VK_FORMAT_R16G16B16_SINT,
   6196 	VK_FORMAT_R16G16B16A16_SINT,
   6197 	VK_FORMAT_R32_SINT,
   6198 	VK_FORMAT_R32G32_SINT,
   6199 	VK_FORMAT_R32G32B32_SINT,
   6200 	VK_FORMAT_R32G32B32A32_SINT,
   6201 	VK_FORMAT_R64_SINT,
   6202 	VK_FORMAT_R64G64_SINT,
   6203 	VK_FORMAT_R64G64B64_SINT,
   6204 	VK_FORMAT_R64G64B64A64_SINT,
   6205 
   6206 	VK_FORMAT_UNDEFINED
   6207 };
   6208 const VkFormat	compatibleFormatsFloats[]	=
   6209 {
   6210 	VK_FORMAT_R4G4_UNORM_PACK8,
   6211 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
   6212 	VK_FORMAT_B4G4R4A4_UNORM_PACK16,
   6213 	VK_FORMAT_R5G6B5_UNORM_PACK16,
   6214 	VK_FORMAT_B5G6R5_UNORM_PACK16,
   6215 	VK_FORMAT_R5G5B5A1_UNORM_PACK16,
   6216 	VK_FORMAT_B5G5R5A1_UNORM_PACK16,
   6217 	VK_FORMAT_A1R5G5B5_UNORM_PACK16,
   6218 	VK_FORMAT_R8_UNORM,
   6219 	VK_FORMAT_R8_SNORM,
   6220 	VK_FORMAT_R8_USCALED,
   6221 	VK_FORMAT_R8_SSCALED,
   6222 	VK_FORMAT_R8G8_UNORM,
   6223 	VK_FORMAT_R8G8_SNORM,
   6224 	VK_FORMAT_R8G8_USCALED,
   6225 	VK_FORMAT_R8G8_SSCALED,
   6226 	VK_FORMAT_R8G8B8_UNORM,
   6227 	VK_FORMAT_R8G8B8_SNORM,
   6228 	VK_FORMAT_R8G8B8_USCALED,
   6229 	VK_FORMAT_R8G8B8_SSCALED,
   6230 	VK_FORMAT_B8G8R8_UNORM,
   6231 	VK_FORMAT_B8G8R8_SNORM,
   6232 	VK_FORMAT_B8G8R8_USCALED,
   6233 	VK_FORMAT_B8G8R8_SSCALED,
   6234 	VK_FORMAT_R8G8B8A8_UNORM,
   6235 	VK_FORMAT_R8G8B8A8_SNORM,
   6236 	VK_FORMAT_R8G8B8A8_USCALED,
   6237 	VK_FORMAT_R8G8B8A8_SSCALED,
   6238 	VK_FORMAT_B8G8R8A8_UNORM,
   6239 	VK_FORMAT_B8G8R8A8_SNORM,
   6240 	VK_FORMAT_B8G8R8A8_USCALED,
   6241 	VK_FORMAT_B8G8R8A8_SSCALED,
   6242 	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
   6243 	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
   6244 	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
   6245 	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
   6246 	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
   6247 	VK_FORMAT_A2R10G10B10_SNORM_PACK32,
   6248 	VK_FORMAT_A2R10G10B10_USCALED_PACK32,
   6249 	VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
   6250 	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
   6251 	VK_FORMAT_A2B10G10R10_SNORM_PACK32,
   6252 	VK_FORMAT_A2B10G10R10_USCALED_PACK32,
   6253 	VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
   6254 	VK_FORMAT_R16_UNORM,
   6255 	VK_FORMAT_R16_SNORM,
   6256 	VK_FORMAT_R16_USCALED,
   6257 	VK_FORMAT_R16_SSCALED,
   6258 	VK_FORMAT_R16_SFLOAT,
   6259 	VK_FORMAT_R16G16_UNORM,
   6260 	VK_FORMAT_R16G16_SNORM,
   6261 	VK_FORMAT_R16G16_USCALED,
   6262 	VK_FORMAT_R16G16_SSCALED,
   6263 	VK_FORMAT_R16G16_SFLOAT,
   6264 	VK_FORMAT_R16G16B16_UNORM,
   6265 	VK_FORMAT_R16G16B16_SNORM,
   6266 	VK_FORMAT_R16G16B16_USCALED,
   6267 	VK_FORMAT_R16G16B16_SSCALED,
   6268 	VK_FORMAT_R16G16B16_SFLOAT,
   6269 	VK_FORMAT_R16G16B16A16_UNORM,
   6270 	VK_FORMAT_R16G16B16A16_SNORM,
   6271 	VK_FORMAT_R16G16B16A16_USCALED,
   6272 	VK_FORMAT_R16G16B16A16_SSCALED,
   6273 	VK_FORMAT_R16G16B16A16_SFLOAT,
   6274 	VK_FORMAT_R32_SFLOAT,
   6275 	VK_FORMAT_R32G32_SFLOAT,
   6276 	VK_FORMAT_R32G32B32_SFLOAT,
   6277 	VK_FORMAT_R32G32B32A32_SFLOAT,
   6278 	VK_FORMAT_R64_SFLOAT,
   6279 	VK_FORMAT_R64G64_SFLOAT,
   6280 	VK_FORMAT_R64G64B64_SFLOAT,
   6281 	VK_FORMAT_R64G64B64A64_SFLOAT,
   6282 	VK_FORMAT_B10G11R11_UFLOAT_PACK32,
   6283 	VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
   6284 //	VK_FORMAT_BC1_RGB_UNORM_BLOCK,
   6285 //	VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
   6286 //	VK_FORMAT_BC2_UNORM_BLOCK,
   6287 //	VK_FORMAT_BC3_UNORM_BLOCK,
   6288 //	VK_FORMAT_BC4_UNORM_BLOCK,
   6289 //	VK_FORMAT_BC4_SNORM_BLOCK,
   6290 //	VK_FORMAT_BC5_UNORM_BLOCK,
   6291 //	VK_FORMAT_BC5_SNORM_BLOCK,
   6292 //	VK_FORMAT_BC6H_UFLOAT_BLOCK,
   6293 //	VK_FORMAT_BC6H_SFLOAT_BLOCK,
   6294 //	VK_FORMAT_BC7_UNORM_BLOCK,
   6295 //	VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
   6296 //	VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
   6297 //	VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
   6298 //	VK_FORMAT_EAC_R11_UNORM_BLOCK,
   6299 //	VK_FORMAT_EAC_R11_SNORM_BLOCK,
   6300 //	VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
   6301 //	VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
   6302 //	VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
   6303 //	VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
   6304 //	VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
   6305 //	VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
   6306 //	VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
   6307 //	VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
   6308 //	VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
   6309 //	VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
   6310 //	VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
   6311 //	VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
   6312 //	VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
   6313 //	VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
   6314 //	VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
   6315 //	VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
   6316 
   6317 	VK_FORMAT_UNDEFINED
   6318 };
   6319 const VkFormat	compatibleFormatsSrgb[]		=
   6320 {
   6321 	VK_FORMAT_R8_SRGB,
   6322 	VK_FORMAT_R8G8_SRGB,
   6323 	VK_FORMAT_R8G8B8_SRGB,
   6324 	VK_FORMAT_B8G8R8_SRGB,
   6325 	VK_FORMAT_R8G8B8A8_SRGB,
   6326 	VK_FORMAT_B8G8R8A8_SRGB,
   6327 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
   6328 //	VK_FORMAT_BC1_RGB_SRGB_BLOCK,
   6329 //	VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
   6330 //	VK_FORMAT_BC2_SRGB_BLOCK,
   6331 //	VK_FORMAT_BC3_SRGB_BLOCK,
   6332 //	VK_FORMAT_BC7_SRGB_BLOCK,
   6333 //	VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
   6334 //	VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
   6335 //	VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
   6336 //	VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
   6337 //	VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
   6338 //	VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
   6339 //	VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
   6340 //	VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
   6341 //	VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
   6342 //	VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
   6343 //	VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
   6344 //	VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
   6345 //	VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
   6346 //	VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
   6347 //	VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
   6348 //	VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
   6349 //	VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
   6350 
   6351 	VK_FORMAT_UNDEFINED
   6352 };
   6353 
   6354 const VkFormat	dedicatedAllocationBlittingFormatsToTest[]	=
   6355 {
   6356 	// compatibleFormatsUInts
   6357 	VK_FORMAT_R8_UINT,
   6358 	VK_FORMAT_R64G64B64A64_UINT,
   6359 
   6360 	// compatibleFormatsSInts
   6361 	VK_FORMAT_R8_SINT,
   6362 	VK_FORMAT_R64G64B64A64_SINT,
   6363 
   6364 	// compatibleFormatsFloats
   6365 	VK_FORMAT_R4G4_UNORM_PACK8,
   6366 	VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
   6367 
   6368 	// compatibleFormatsSrgb
   6369 	VK_FORMAT_R8_SRGB,
   6370 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
   6371 };
   6372 
   6373 void addBlittingImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   6374 {
   6375 	const struct {
   6376 		const VkFormat*	compatibleFormats;
   6377 		const bool		onlyNearest;
   6378 	}	colorImageFormatsToTestBlit[]			=
   6379 	{
   6380 		{ compatibleFormatsUInts,	true	},
   6381 		{ compatibleFormatsSInts,	true	},
   6382 		{ compatibleFormatsFloats,	false	},
   6383 		{ compatibleFormatsSrgb,	false	},
   6384 	};
   6385 
   6386 	const int	numOfColorImageFormatsToTest		= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
   6387 
   6388 	TestParams	params;
   6389 	params.src.image.imageType	= VK_IMAGE_TYPE_2D;
   6390 	params.src.image.extent		= defaultExtent;
   6391 	params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
   6392 	params.dst.image.extent		= defaultExtent;
   6393 	params.allocationKind		= allocationKind;
   6394 
   6395 	CopyRegion	region;
   6396 	for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
   6397 	{
   6398 		const VkImageBlit			imageBlit	=
   6399 		{
   6400 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   6401 			{
   6402 				{0, 0, 0},
   6403 				{defaultSize, defaultSize, 1}
   6404 			},					// VkOffset3D					srcOffsets[2];
   6405 
   6406 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   6407 			{
   6408 				{i, 0, 0},
   6409 				{i + defaultFourthSize / j, defaultFourthSize / j, 1}
   6410 			}					// VkOffset3D					dstOffset[2];
   6411 		};
   6412 		region.imageBlit	= imageBlit;
   6413 		params.regions.push_back(region);
   6414 	}
   6415 	for (int i = 0; i < defaultSize; i += defaultFourthSize)
   6416 	{
   6417 		const VkImageBlit			imageBlit	=
   6418 		{
   6419 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   6420 			{
   6421 				{i, i, 0},
   6422 				{i + defaultFourthSize, i + defaultFourthSize, 1}
   6423 			},					// VkOffset3D					srcOffsets[2];
   6424 
   6425 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   6426 			{
   6427 				{i, defaultSize / 2, 0},
   6428 				{i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1}
   6429 			}					// VkOffset3D					dstOffset[2];
   6430 		};
   6431 		region.imageBlit	= imageBlit;
   6432 		params.regions.push_back(region);
   6433 	}
   6434 
   6435 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
   6436 	{
   6437 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
   6438 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
   6439 			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
   6440 	}
   6441 
   6442 	for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
   6443 	{
   6444 		const VkFormat*	compatibleFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
   6445 		const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
   6446 		for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
   6447 		{
   6448 			params.src.image.format	= compatibleFormats[srcFormatIndex];
   6449 			if (!isSupportedByFramework(params.src.image.format))
   6450 				continue;
   6451 
   6452 			BlitColorTestParams		testParams;
   6453 			testParams.params				= params;
   6454 			testParams.compatibleFormats	= compatibleFormats;
   6455 			testParams.onlyNearest			= onlyNearest;
   6456 
   6457 			const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
   6458 			addTestGroup(group, getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
   6459 		}
   6460 	}
   6461 }
   6462 
   6463 void addBlittingImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
   6464 {
   6465 	const VkImageLayout blitSrcLayouts[]	=
   6466 	{
   6467 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   6468 		VK_IMAGE_LAYOUT_GENERAL
   6469 	};
   6470 	const VkImageLayout blitDstLayouts[]	=
   6471 	{
   6472 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   6473 		VK_IMAGE_LAYOUT_GENERAL
   6474 	};
   6475 
   6476 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
   6477 	{
   6478 		params.src.image.operationLayout	= blitSrcLayouts[srcLayoutNdx];
   6479 
   6480 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
   6481 		{
   6482 			params.dst.image.operationLayout	= blitDstLayouts[dstLayoutNdx];
   6483 			params.filter						= VK_FILTER_NEAREST;
   6484 
   6485 			const std::string testName		= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
   6486 											  getImageLayoutCaseName(params.dst.image.operationLayout);
   6487 			const std::string description	= "Blit from " + getImageLayoutCaseName(params.src.image.operationLayout) +
   6488 											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
   6489 
   6490 			group->addChild(new BlitImageTestCase(group->getTestContext(), testName + "_nearest", description, params));
   6491 		}
   6492 	}
   6493 }
   6494 
   6495 void addBlittingImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   6496 {
   6497 	const VkFormat	depthAndStencilFormats[]	=
   6498 	{
   6499 		VK_FORMAT_D16_UNORM,
   6500 		VK_FORMAT_X8_D24_UNORM_PACK32,
   6501 		VK_FORMAT_D32_SFLOAT,
   6502 		VK_FORMAT_S8_UINT,
   6503 		VK_FORMAT_D16_UNORM_S8_UINT,
   6504 		VK_FORMAT_D24_UNORM_S8_UINT,
   6505 		VK_FORMAT_D32_SFLOAT_S8_UINT,
   6506 	};
   6507 
   6508 	const VkImageSubresourceLayers	defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
   6509 	const VkImageSubresourceLayers	defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
   6510 
   6511 	for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
   6512 	{
   6513 		TestParams	params;
   6514 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   6515 		params.src.image.extent				= defaultExtent;
   6516 		params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
   6517 		params.dst.image.extent				= defaultExtent;
   6518 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   6519 		params.dst.image.format				= params.src.image.format;
   6520 		params.allocationKind				= allocationKind;
   6521 
   6522 		CopyRegion	region;
   6523 		for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
   6524 		{
   6525 			const VkOffset3D	srcOffset0	= {0, 0, 0};
   6526 			const VkOffset3D	srcOffset1	= {defaultSize, defaultSize, 1};
   6527 			const VkOffset3D	dstOffset0	= {i, 0, 0};
   6528 			const VkOffset3D	dstOffset1	= {i + defaultFourthSize / j, defaultFourthSize / j, 1};
   6529 
   6530 			if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
   6531 			{
   6532 				const VkImageBlit			imageBlit	=
   6533 				{
   6534 					defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
   6535 					{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
   6536 					defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
   6537 					{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
   6538 				};
   6539 				region.imageBlit	= imageBlit;
   6540 				params.regions.push_back(region);
   6541 			}
   6542 			if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
   6543 			{
   6544 				const VkImageBlit			imageBlit	=
   6545 				{
   6546 					defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
   6547 					{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
   6548 					defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
   6549 					{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
   6550 				};
   6551 				region.imageBlit	= imageBlit;
   6552 				params.regions.push_back(region);
   6553 			}
   6554 		}
   6555 		for (int i = 0; i < defaultSize; i += defaultFourthSize)
   6556 		{
   6557 			const VkOffset3D	srcOffset0	= {i, i, 0};
   6558 			const VkOffset3D	srcOffset1	= {i + defaultFourthSize, i + defaultFourthSize, 1};
   6559 			const VkOffset3D	dstOffset0	= {i, defaultSize / 2, 0};
   6560 			const VkOffset3D	dstOffset1	= {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1};
   6561 
   6562 			if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
   6563 			{
   6564 				const VkImageBlit			imageBlit	=
   6565 				{
   6566 					defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
   6567 					{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
   6568 					defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
   6569 					{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
   6570 				};
   6571 				region.imageBlit	= imageBlit;
   6572 				params.regions.push_back(region);
   6573 			}
   6574 			if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
   6575 			{
   6576 				const VkImageBlit			imageBlit	=
   6577 				{
   6578 					defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
   6579 					{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
   6580 					defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
   6581 					{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
   6582 				};
   6583 				region.imageBlit	= imageBlit;
   6584 				params.regions.push_back(region);
   6585 			}
   6586 		}
   6587 
   6588 		const std::string testName		= getFormatCaseName(params.src.image.format) + "_" +
   6589 										  getFormatCaseName(params.dst.image.format);
   6590 		const std::string description	= "Blit from " + getFormatCaseName(params.src.image.format) +
   6591 										  " to " + getFormatCaseName(params.dst.image.format);
   6592 		addTestGroup(group, testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
   6593 	}
   6594 }
   6595 
   6596 void addBlittingImageAllFormatsMipmapFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
   6597 {
   6598 	tcu::TestContext& testCtx				= group->getTestContext();
   6599 
   6600 	const VkImageLayout blitSrcLayouts[]	=
   6601 	{
   6602 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   6603 		VK_IMAGE_LAYOUT_GENERAL
   6604 	};
   6605 	const VkImageLayout blitDstLayouts[]	=
   6606 	{
   6607 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   6608 		VK_IMAGE_LAYOUT_GENERAL
   6609 	};
   6610 
   6611 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
   6612 	{
   6613 		testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
   6614 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
   6615 		{
   6616 			testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
   6617 
   6618 			testParams.params.filter			= VK_FILTER_NEAREST;
   6619 			const std::string testName			= getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
   6620 												  getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
   6621 			const std::string description		= "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) +
   6622 												  " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
   6623 			group->addChild(new BlitMipmapTestCase(testCtx, testName + "_nearest", description, testParams.params));
   6624 
   6625 			if (!testParams.onlyNearest)
   6626 			{
   6627 				testParams.params.filter		= VK_FILTER_LINEAR;
   6628 				group->addChild(new BlitMipmapTestCase(testCtx, testName + "_linear", description, testParams.params));
   6629 			}
   6630 		}
   6631 	}
   6632 }
   6633 
   6634 void addBlittingImageAllFormatsBaseLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   6635 {
   6636 	const struct
   6637 	{
   6638 		const VkFormat* const	compatibleFormats;
   6639 		const bool				onlyNearest;
   6640 	}	colorImageFormatsToTestBlit[]			=
   6641 	{
   6642 		{ compatibleFormatsUInts,	true	},
   6643 		{ compatibleFormatsSInts,	true	},
   6644 		{ compatibleFormatsFloats,	false	},
   6645 		{ compatibleFormatsSrgb,	false	},
   6646 	};
   6647 
   6648 	const int	numOfColorImageFormatsToTest		= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
   6649 
   6650 	TestParams	params;
   6651 	params.src.image.imageType	= VK_IMAGE_TYPE_2D;
   6652 	params.src.image.extent		= defaultExtent;
   6653 	params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
   6654 	params.dst.image.extent		= defaultExtent;
   6655 	params.allocationKind		= allocationKind;
   6656 	params.mipLevels			= deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u;
   6657 	params.singleCommand		= DE_TRUE;
   6658 
   6659 	CopyRegion	region;
   6660 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
   6661 	{
   6662 		VkImageSubresourceLayers	destLayer	= defaultSourceLayer;
   6663 		destLayer.mipLevel = mipLevelNdx;
   6664 
   6665 		const VkImageBlit			imageBlit	=
   6666 		{
   6667 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   6668 			{
   6669 				{0, 0, 0},
   6670 				{defaultSize, defaultSize, 1}
   6671 			},					// VkOffset3D					srcOffsets[2];
   6672 
   6673 			destLayer,			// VkImageSubresourceLayers	dstSubresource;
   6674 			{
   6675 				{0, 0, 0},
   6676 				{defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
   6677 			}					// VkOffset3D					dstOffset[2];
   6678 		};
   6679 		region.imageBlit	= imageBlit;
   6680 		params.regions.push_back(region);
   6681 	}
   6682 
   6683 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
   6684 	{
   6685 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
   6686 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
   6687 			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
   6688 	}
   6689 
   6690 	for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
   6691 	{
   6692 		const VkFormat*	compatibleFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
   6693 		const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
   6694 		for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
   6695 		{
   6696 			params.src.image.format	= compatibleFormats[srcFormatIndex];
   6697 			params.dst.image.format	= compatibleFormats[srcFormatIndex];
   6698 
   6699 			if (!isSupportedByFramework(params.src.image.format))
   6700 				continue;
   6701 
   6702 			BlitColorTestParams		testParams;
   6703 			testParams.params				= params;
   6704 			testParams.compatibleFormats	= compatibleFormats;
   6705 			testParams.onlyNearest			= onlyNearest;
   6706 
   6707 			const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
   6708 			addTestGroup(group, getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
   6709 		}
   6710 	}
   6711 }
   6712 
   6713 void addBlittingImageAllFormatsPreviousLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   6714 {
   6715 	const struct
   6716 	{
   6717 		const VkFormat* const	compatibleFormats;
   6718 		const bool				onlyNearest;
   6719 	}	colorImageFormatsToTestBlit[]			=
   6720 	{
   6721 		{ compatibleFormatsUInts,	true	},
   6722 		{ compatibleFormatsSInts,	true	},
   6723 		{ compatibleFormatsFloats,	false	},
   6724 		{ compatibleFormatsSrgb,	false	},
   6725 	};
   6726 
   6727 	const int	numOfColorImageFormatsToTest		= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
   6728 
   6729 	TestParams	params;
   6730 	params.src.image.imageType	= VK_IMAGE_TYPE_2D;
   6731 	params.src.image.extent		= defaultExtent;
   6732 	params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
   6733 	params.dst.image.extent		= defaultExtent;
   6734 	params.allocationKind		= allocationKind;
   6735 	params.mipLevels			= deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u;
   6736 	params.singleCommand		= DE_FALSE;
   6737 
   6738 	CopyRegion	region;
   6739 	for (deUint32 mipLevelNdx = 1u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
   6740 	{
   6741 		VkImageSubresourceLayers	srcLayer	= defaultSourceLayer;
   6742 		VkImageSubresourceLayers	destLayer	= defaultSourceLayer;
   6743 
   6744 		srcLayer.mipLevel	= mipLevelNdx - 1u;
   6745 		destLayer.mipLevel	= mipLevelNdx;
   6746 
   6747 		const VkImageBlit			imageBlit	=
   6748 		{
   6749 			srcLayer,			// VkImageSubresourceLayers	srcSubresource;
   6750 			{
   6751 				{0, 0, 0},
   6752 				{defaultSize >> (mipLevelNdx - 1u), defaultSize >> (mipLevelNdx - 1u), 1}
   6753 			},					// VkOffset3D					srcOffsets[2];
   6754 
   6755 			destLayer,			// VkImageSubresourceLayers	dstSubresource;
   6756 			{
   6757 				{0, 0, 0},
   6758 				{defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
   6759 			}					// VkOffset3D					dstOffset[2];
   6760 		};
   6761 		region.imageBlit	= imageBlit;
   6762 		params.regions.push_back(region);
   6763 	}
   6764 
   6765 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
   6766 	{
   6767 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
   6768 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
   6769 			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
   6770 	}
   6771 
   6772 	for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
   6773 	{
   6774 		const VkFormat*	compatibleFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
   6775 		const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
   6776 		for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
   6777 		{
   6778 			params.src.image.format	= compatibleFormats[srcFormatIndex];
   6779 			params.dst.image.format	= compatibleFormats[srcFormatIndex];
   6780 
   6781 			if (!isSupportedByFramework(params.src.image.format))
   6782 				continue;
   6783 
   6784 			BlitColorTestParams		testParams;
   6785 			testParams.params				= params;
   6786 			testParams.compatibleFormats	= compatibleFormats;
   6787 			testParams.onlyNearest			= onlyNearest;
   6788 
   6789 			const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
   6790 			addTestGroup(group, getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
   6791 		}
   6792 	}
   6793 }
   6794 
   6795 void addBlittingImageAllFormatsMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   6796 {
   6797 	addTestGroup(group, "from_base_level", "Generate all mipmap levels from base level", addBlittingImageAllFormatsBaseLevelMipmapTests, allocationKind);
   6798 	addTestGroup(group, "from_previous_level", "Generate next mipmap level from previous level", addBlittingImageAllFormatsPreviousLevelMipmapTests, allocationKind);
   6799 }
   6800 
   6801 void addBlittingImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   6802 {
   6803 	addTestGroup(group, "color", "Blitting image with color formats", addBlittingImageAllFormatsColorTests, allocationKind);
   6804 	addTestGroup(group, "depth_stencil", "Blitting image with depth/stencil formats", addBlittingImageAllFormatsDepthStencilTests, allocationKind);
   6805 	addTestGroup(group, "generate_mipmaps", "Generating mipmaps with vkCmdBlitImage()", addBlittingImageAllFormatsMipmapTests, allocationKind);
   6806 }
   6807 
   6808 void addBlittingImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   6809 {
   6810 	addTestGroup(group, "simple_tests", "Blitting image simple tests", addBlittingImageSimpleTests, allocationKind);
   6811 	addTestGroup(group, "all_formats", "Blitting image with all compatible formats", addBlittingImageAllFormatsTests, allocationKind);
   6812 }
   6813 
   6814 const VkSampleCountFlagBits	samples[]		=
   6815 {
   6816 	VK_SAMPLE_COUNT_2_BIT,
   6817 	VK_SAMPLE_COUNT_4_BIT,
   6818 	VK_SAMPLE_COUNT_8_BIT,
   6819 	VK_SAMPLE_COUNT_16_BIT,
   6820 	VK_SAMPLE_COUNT_32_BIT,
   6821 	VK_SAMPLE_COUNT_64_BIT
   6822 };
   6823 const VkExtent3D			resolveExtent	= {256u, 256u, 1};
   6824 
   6825 void addResolveImageWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   6826 {
   6827 	TestParams	params;
   6828 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   6829 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   6830 	params.src.image.extent				= resolveExtent;
   6831 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   6832 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   6833 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   6834 	params.dst.image.extent				= resolveExtent;
   6835 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   6836 	params.allocationKind				= allocationKind;
   6837 
   6838 	{
   6839 		const VkImageSubresourceLayers	sourceLayer	=
   6840 		{
   6841 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
   6842 			0u,							// uint32_t				mipLevel;
   6843 			0u,							// uint32_t				baseArrayLayer;
   6844 			1u							// uint32_t				layerCount;
   6845 		};
   6846 		const VkImageResolve			testResolve	=
   6847 		{
   6848 			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   6849 			{0, 0, 0},		// VkOffset3D				srcOffset;
   6850 			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   6851 			{0, 0, 0},		// VkOffset3D				dstOffset;
   6852 			resolveExtent,	// VkExtent3D				extent;
   6853 		};
   6854 
   6855 		CopyRegion	imageResolve;
   6856 		imageResolve.imageResolve	= testResolve;
   6857 		params.regions.push_back(imageResolve);
   6858 	}
   6859 
   6860 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
   6861 	{
   6862 		params.samples					= samples[samplesIndex];
   6863 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
   6864 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
   6865 	}
   6866 }
   6867 
   6868 void addResolveImagePartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   6869 {
   6870 	TestParams	params;
   6871 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   6872 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   6873 	params.src.image.extent				= resolveExtent;
   6874 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   6875 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   6876 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   6877 	params.dst.image.extent				= resolveExtent;
   6878 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   6879 	params.allocationKind				= allocationKind;
   6880 
   6881 	{
   6882 		const VkImageSubresourceLayers	sourceLayer	=
   6883 		{
   6884 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
   6885 			0u,							// uint32_t				mipLevel;
   6886 			0u,							// uint32_t				baseArrayLayer;
   6887 			1u							// uint32_t				layerCount;
   6888 		};
   6889 		const VkImageResolve			testResolve	=
   6890 		{
   6891 			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   6892 			{0, 0, 0},		// VkOffset3D				srcOffset;
   6893 			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   6894 			{64u, 64u, 0},		// VkOffset3D				dstOffset;
   6895 			{128u, 128u, 1u},	// VkExtent3D				extent;
   6896 		};
   6897 
   6898 		CopyRegion	imageResolve;
   6899 		imageResolve.imageResolve = testResolve;
   6900 		params.regions.push_back(imageResolve);
   6901 	}
   6902 
   6903 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
   6904 	{
   6905 		params.samples					= samples[samplesIndex];
   6906 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
   6907 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
   6908 	}
   6909 }
   6910 
   6911 void addResolveImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   6912 {
   6913 	TestParams	params;
   6914 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   6915 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   6916 	params.src.image.extent				= resolveExtent;
   6917 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   6918 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   6919 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   6920 	params.dst.image.extent				= resolveExtent;
   6921 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   6922 	params.allocationKind				= allocationKind;
   6923 
   6924 	{
   6925 		const VkImageSubresourceLayers	sourceLayer	=
   6926 		{
   6927 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
   6928 			0u,							// uint32_t				mipLevel;
   6929 			0u,							// uint32_t				baseArrayLayer;
   6930 			1u							// uint32_t				layerCount;
   6931 		};
   6932 
   6933 		for (int i = 0; i < 256; i += 64)
   6934 		{
   6935 			const VkImageResolve			testResolve	=
   6936 			{
   6937 				sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   6938 				{i, i, 0},		// VkOffset3D				srcOffset;
   6939 				sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   6940 				{i, 0, 0},		// VkOffset3D				dstOffset;
   6941 				{64u, 64u, 1u},	// VkExtent3D				extent;
   6942 			};
   6943 
   6944 			CopyRegion	imageResolve;
   6945 			imageResolve.imageResolve = testResolve;
   6946 			params.regions.push_back(imageResolve);
   6947 		}
   6948 	}
   6949 
   6950 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
   6951 	{
   6952 		params.samples					= samples[samplesIndex];
   6953 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
   6954 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
   6955 	}
   6956 }
   6957 
   6958 void addResolveImageWholeCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   6959 {
   6960 	TestParams	params;
   6961 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   6962 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   6963 	params.src.image.extent				= defaultExtent;
   6964 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   6965 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   6966 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   6967 	params.dst.image.extent				= defaultExtent;
   6968 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   6969 	params.allocationKind				= allocationKind;
   6970 
   6971 	{
   6972 		const VkImageSubresourceLayers	sourceLayer	=
   6973 		{
   6974 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
   6975 			0u,							// uint32_t				mipLevel;
   6976 			0u,							// uint32_t				baseArrayLayer;
   6977 			1u							// uint32_t				layerCount;
   6978 		};
   6979 
   6980 		const VkImageResolve			testResolve	=
   6981 		{
   6982 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
   6983 			{0, 0, 0},			// VkOffset3D				srcOffset;
   6984 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
   6985 			{0, 0, 0},			// VkOffset3D				dstOffset;
   6986 			defaultExtent,		// VkExtent3D				extent;
   6987 		};
   6988 
   6989 		CopyRegion	imageResolve;
   6990 		imageResolve.imageResolve	= testResolve;
   6991 		params.regions.push_back(imageResolve);
   6992 	}
   6993 
   6994 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
   6995 	{
   6996 		params.samples					= samples[samplesIndex];
   6997 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
   6998 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
   6999 	}
   7000 }
   7001 
   7002 void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   7003 {
   7004 	TestParams	params;
   7005 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   7006 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   7007 	params.src.image.extent				= defaultExtent;
   7008 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   7009 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   7010 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   7011 	params.dst.image.extent				= defaultExtent;
   7012 	params.dst.image.extent.depth		= 5u;
   7013 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   7014 	params.allocationKind				= allocationKind;
   7015 
   7016 	for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
   7017 	{
   7018 		const VkImageSubresourceLayers	sourceLayer	=
   7019 		{
   7020 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
   7021 			0u,								// uint32_t				mipLevel;
   7022 			layerNdx,						// uint32_t				baseArrayLayer;
   7023 			1u								// uint32_t				layerCount;
   7024 		};
   7025 
   7026 		const VkImageResolve			testResolve	=
   7027 		{
   7028 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
   7029 			{0, 0, 0},			// VkOffset3D				srcOffset;
   7030 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
   7031 			{0, 0, 0},			// VkOffset3D				dstOffset;
   7032 			defaultExtent,		// VkExtent3D				extent;
   7033 		};
   7034 
   7035 		CopyRegion	imageResolve;
   7036 		imageResolve.imageResolve	= testResolve;
   7037 		params.regions.push_back(imageResolve);
   7038 	}
   7039 
   7040 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
   7041 	{
   7042 		params.samples					= samples[samplesIndex];
   7043 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
   7044 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
   7045 	}
   7046 }
   7047 
   7048 void addResolveImageDiffImageSizeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   7049 {
   7050 	tcu::TestContext&	testCtx			= group->getTestContext();
   7051 	TestParams			params;
   7052 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
   7053 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   7054 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   7055 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
   7056 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
   7057 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   7058 	params.allocationKind				= allocationKind;
   7059 
   7060 	{
   7061 		const VkImageSubresourceLayers	sourceLayer	=
   7062 		{
   7063 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
   7064 			0u,							// uint32_t				mipLevel;
   7065 			0u,							// uint32_t				baseArrayLayer;
   7066 			1u							// uint32_t				layerCount;
   7067 		};
   7068 		const VkImageResolve			testResolve	=
   7069 		{
   7070 			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
   7071 			{0, 0, 0},		// VkOffset3D				srcOffset;
   7072 			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
   7073 			{0, 0, 0},		// VkOffset3D				dstOffset;
   7074 			resolveExtent,	// VkExtent3D				extent;
   7075 		};
   7076 		CopyRegion	imageResolve;
   7077 		imageResolve.imageResolve	= testResolve;
   7078 		params.regions.push_back(imageResolve);
   7079 	}
   7080 
   7081 	const VkExtent3D imageExtents[]		=
   7082 	{
   7083 		{ resolveExtent.width + 10,	resolveExtent.height,		resolveExtent.depth },
   7084 		{ resolveExtent.width,		resolveExtent.height * 2,	resolveExtent.depth },
   7085 		{ resolveExtent.width,		resolveExtent.height,		resolveExtent.depth + 10 }
   7086 	};
   7087 
   7088 	for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex)
   7089 	{
   7090 		const VkExtent3D&	srcImageSize	= imageExtents[srcImageExtentIndex];
   7091 		params.src.image.extent				= srcImageSize;
   7092 		params.dst.image.extent				= resolveExtent;
   7093 		for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
   7094 		{
   7095 			params.samples	= samples[samplesIndex];
   7096 			std::ostringstream testName;
   7097 			testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
   7098 			std::ostringstream description;
   7099 			description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and source image size ("
   7100 						<< srcImageSize.width << ", " << srcImageSize.height << ", " << srcImageSize.depth << ")";
   7101 			group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
   7102 		}
   7103 	}
   7104 	for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex)
   7105 	{
   7106 		const VkExtent3D&	dstImageSize	= imageExtents[dstImageExtentIndex];
   7107 		params.src.image.extent				= resolveExtent;
   7108 		params.dst.image.extent				= dstImageSize;
   7109 		for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
   7110 		{
   7111 			params.samples	= samples[samplesIndex];
   7112 			std::ostringstream testName;
   7113 			testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
   7114 			std::ostringstream description;
   7115 			description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and destination image size ("
   7116 						<< dstImageSize.width << ", " << dstImageSize.height << ", " << dstImageSize.depth << ")";
   7117 			group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
   7118 		}
   7119 	}
   7120 }
   7121 
   7122 void addResolveImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   7123 {
   7124 	addTestGroup(group, "whole", "Resolve from image to image (whole)", addResolveImageWholeTests, allocationKind);
   7125 	addTestGroup(group, "partial", "Resolve from image to image (partial)", addResolveImagePartialTests, allocationKind);
   7126 	addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind);
   7127 	addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind);
   7128 	addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind);
   7129 	addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind);
   7130 }
   7131 
   7132 void addCopiesAndBlittingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   7133 {
   7134 	addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind);
   7135 	addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind);
   7136 	addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind);
   7137 	addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind);
   7138 	addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind);
   7139 	addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind);
   7140 }
   7141 
   7142 void addCoreCopiesAndBlittingTests (tcu::TestCaseGroup* group)
   7143 {
   7144 	addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED);
   7145 }
   7146 
   7147 void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group)
   7148 {
   7149 	addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED);
   7150 }
   7151 
   7152 } // anonymous
   7153 
   7154 tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
   7155 {
   7156 	de::MovePtr<tcu::TestCaseGroup>	copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
   7157 
   7158 	copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core",					"Core Copies And Blitting Tests",								addCoreCopiesAndBlittingTests));
   7159 	copiesAndBlittingTests->addChild(createTestGroup(testCtx, "dedicated_allocation",	"Copies And Blitting Tests For Dedicated Memory Allocation",	addDedicatedAllocationCopiesAndBlittingTests));
   7160 
   7161 	return copiesAndBlittingTests.release();
   7162 }
   7163 
   7164 } // api
   7165 } // vkt
   7166