/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015-2020 The Khronos Group Inc.
 * Copyright (c) 2020 Google Inc.
 * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Vulkan Copies And Blitting Tests
 *//*--------------------------------------------------------------------*/

#include "vktApiCopiesAndBlittingTests.hpp"

#include "deStringUtil.hpp"
#include "deUniquePtr.hpp"

#include "tcuImageCompare.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuVectorType.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuTestLog.hpp"
#include "tcuTexLookupVerifier.hpp"

#include "vkImageUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkPrograms.hpp"
#include "vkQueryUtil.hpp"
#include "vkRefUtil.hpp"
#include "vktTestCase.hpp"
#include "vktTestCaseUtil.hpp"
#include "vktTestGroupUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkBufferWithMemory.hpp"
#include "vkBarrierUtil.hpp"

#include <set>
#include <array>
#include <algorithm>
#include <iterator>
#include <sstream>

namespace vkt
{

namespace api
{

namespace
{

enum FillMode
{
	FILL_MODE_GRADIENT = 0,
	FILL_MODE_WHITE,
	FILL_MODE_RED,
	FILL_MODE_MULTISAMPLE,
	FILL_MODE_BLUE_RED_X,
	FILL_MODE_BLUE_RED_Y,
	FILL_MODE_BLUE_RED_Z,

	FILL_MODE_LAST
};

enum MirrorModeBits
{
	MIRROR_MODE_X		= (1<<0),
	MIRROR_MODE_Y		= (1<<1),
	MIRROR_MODE_Z		= (1<<2),
	MIRROR_MODE_LAST	= (1<<3),
};

using MirrorMode = deUint32;

enum AllocationKind
{
	ALLOCATION_KIND_SUBALLOCATED,
	ALLOCATION_KIND_DEDICATED,
};

enum ExtensionUse
{
	EXTENSION_USE_NONE,
	EXTENSION_USE_COPY_COMMANDS2,
};

template <typename Type>
class BinaryCompare
{
public:
	bool operator() (const Type& a, const Type& b) const
	{
		return deMemCmp(&a, &b, sizeof(Type)) < 0;
	}
};

typedef std::set<vk::VkFormat, BinaryCompare<vk::VkFormat> >	FormatSet;

FormatSet dedicatedAllocationImageToImageFormatsToTestSet;
FormatSet dedicatedAllocationBlittingFormatsToTestSet;

using namespace vk;

VkImageCopy2KHR convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)
{
	const VkImageCopy2KHR	imageCopy2 =
	{
		VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR,		// VkStructureType				sType;
		DE_NULL,								// const void*					pNext;
		imageCopy.srcSubresource,				// VkImageSubresourceLayers		srcSubresource;
		imageCopy.srcOffset,					// VkOffset3D					srcOffset;
		imageCopy.dstSubresource,				// VkImageSubresourceLayers		dstSubresource;
		imageCopy.dstOffset,					// VkOffset3D					dstOffset;
		imageCopy.extent						// VkExtent3D					extent;
	};
	return imageCopy2;
}
VkBufferCopy2KHR convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)
{
	const VkBufferCopy2KHR	bufferCopy2 =
	{
		VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR,	// VkStructureType				sType;
		DE_NULL,								// const void*					pNext;
		bufferCopy.srcOffset,					// VkDeviceSize					srcOffset;
		bufferCopy.dstOffset,					// VkDeviceSize					dstOffset;
		bufferCopy.size,						// VkDeviceSize					size;
	};
	return bufferCopy2;
}

VkBufferImageCopy2KHR convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)
{
	const VkBufferImageCopy2KHR	bufferImageCopy2 =
	{
		VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR,	// VkStructureType				sType;
		DE_NULL,									// const void*					pNext;
		bufferImageCopy.bufferOffset,				// VkDeviceSize					bufferOffset;
		bufferImageCopy.bufferRowLength,			// uint32_t						bufferRowLength;
		bufferImageCopy.bufferImageHeight,			// uint32_t						bufferImageHeight;
		bufferImageCopy.imageSubresource,			// VkImageSubresourceLayers		imageSubresource;
		bufferImageCopy.imageOffset,				// VkOffset3D					imageOffset;
		bufferImageCopy.imageExtent					// VkExtent3D					imageExtent;
	};
	return bufferImageCopy2;
}

VkImageBlit2KHR convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)
{
	const VkImageBlit2KHR	imageBlit2 =
	{
		VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR,			// VkStructureType				sType;
		DE_NULL,									// const void*					pNext;
		imageBlit.srcSubresource,					// VkImageSubresourceLayers		srcSubresource;
		{											// VkOffset3D					srcOffsets[2];
			{
				imageBlit.srcOffsets[0].x,				// VkOffset3D			srcOffsets[0].x;
				imageBlit.srcOffsets[0].y,				// VkOffset3D			srcOffsets[0].y;
				imageBlit.srcOffsets[0].z				// VkOffset3D			srcOffsets[0].z;
			},
			{
				imageBlit.srcOffsets[1].x,				// VkOffset3D			srcOffsets[1].x;
				imageBlit.srcOffsets[1].y,				// VkOffset3D			srcOffsets[1].y;
				imageBlit.srcOffsets[1].z				// VkOffset3D			srcOffsets[1].z;
			}
		},
		imageBlit.dstSubresource,					// VkImageSubresourceLayers		dstSubresource;
		{											// VkOffset3D					srcOffsets[2];
			{
				imageBlit.dstOffsets[0].x,				// VkOffset3D			dstOffsets[0].x;
				imageBlit.dstOffsets[0].y,				// VkOffset3D			dstOffsets[0].y;
				imageBlit.dstOffsets[0].z				// VkOffset3D			dstOffsets[0].z;
			},
			{
				imageBlit.dstOffsets[1].x,				// VkOffset3D			dstOffsets[1].x;
				imageBlit.dstOffsets[1].y,				// VkOffset3D			dstOffsets[1].y;
				imageBlit.dstOffsets[1].z				// VkOffset3D			dstOffsets[1].z;
			}
		}
	};
	return imageBlit2;
}

VkImageResolve2KHR convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)
{
	const VkImageResolve2KHR	imageResolve2 =
	{
		VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR,		// VkStructureType				sType;
		DE_NULL,									// const void*					pNext;
		imageResolve.srcSubresource,				// VkImageSubresourceLayers		srcSubresource;
		imageResolve.srcOffset,						// VkOffset3D					srcOffset;
		imageResolve.dstSubresource,				// VkImageSubresourceLayers		dstSubresource;
		imageResolve.dstOffset,						// VkOffset3D					dstOffset;
		imageResolve.extent							// VkExtent3D					extent;
	};
	return imageResolve2;
}

VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
{
	VkImageAspectFlags	aspectFlag	= 0;
	aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
	aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);

	if (!aspectFlag)
		aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;

	return aspectFlag;
}

VkImageAspectFlags getAspectFlags (VkFormat format)
{
	if (isCompressedFormat(format))
		return VK_IMAGE_ASPECT_COLOR_BIT;
	else
		return getAspectFlags(mapVkFormat(format));
}

tcu::TextureFormat getSizeCompatibleTcuTextureFormat (VkFormat format)
{
	if (isCompressedFormat(format))
		return (getBlockSizeInBytes(format) == 8) ? mapVkFormat(VK_FORMAT_R16G16B16A16_UINT) : mapVkFormat(VK_FORMAT_R32G32B32A32_UINT);
	else
		return mapVkFormat(format);
}

// This is effectively same as vk::isFloatFormat(mapTextureFormat(format))
// except that it supports some formats that are not mappable to VkFormat.
// When we are checking combined depth and stencil formats, each aspect is
// checked separately, and in some cases we construct PBA with a format that
// is not mappable to VkFormat.
bool isFloatFormat (tcu::TextureFormat format)
{
	return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
}

union CopyRegion
{
	VkBufferCopy			bufferCopy;
	VkImageCopy				imageCopy;
	VkBufferImageCopy		bufferImageCopy;
	VkImageBlit				imageBlit;
	VkImageResolve			imageResolve;
};

struct ImageParms
{
	VkImageType			imageType;
	VkFormat			format;
	VkExtent3D			extent;
	VkImageTiling		tiling;
	VkImageLayout		operationLayout;
	VkImageCreateFlags	createFlags;
	FillMode			fillMode;
};

struct TestParams
{
	union Data
	{
		struct Buffer
		{
			VkDeviceSize	size;
		} buffer;

		ImageParms	image;
	} src, dst;

	std::vector<CopyRegion>	regions;

	union
	{
		VkFilter				filter;
		VkSampleCountFlagBits	samples;
	};

	AllocationKind	allocationKind;
	ExtensionUse	extensionUse;
	deUint32		mipLevels;
	deBool			singleCommand;
	deUint32		barrierCount;
	deBool			separateDepthStencilLayouts;
	deBool			clearDestination;

	TestParams (void)
	{
		allocationKind				= ALLOCATION_KIND_DEDICATED;
		extensionUse				= EXTENSION_USE_NONE;
		mipLevels					= 1u;
		singleCommand				= DE_TRUE;
		barrierCount				= 1u;
		separateDepthStencilLayouts	= DE_FALSE;
		src.image.createFlags		= VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
		dst.image.createFlags		= VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
		src.image.fillMode			= FILL_MODE_GRADIENT;
		dst.image.fillMode			= FILL_MODE_WHITE;
		clearDestination			= DE_FALSE;
	}
};

de::MovePtr<Allocation> allocateBuffer (const InstanceInterface&	vki,
										const DeviceInterface&		vkd,
										const VkPhysicalDevice&		physDevice,
										const VkDevice				device,
										const VkBuffer&				buffer,
										const MemoryRequirement		requirement,
										Allocator&					allocator,
										AllocationKind				allocationKind)
{
	switch (allocationKind)
	{
		case ALLOCATION_KIND_SUBALLOCATED:
		{
			const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);

			return allocator.allocate(memoryRequirements, requirement);
		}

		case ALLOCATION_KIND_DEDICATED:
		{
			return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
		}

		default:
		{
			TCU_THROW(InternalError, "Invalid allocation kind");
		}
	}
}

de::MovePtr<Allocation> allocateImage (const InstanceInterface&		vki,
									   const DeviceInterface&		vkd,
									   const VkPhysicalDevice&		physDevice,
									   const VkDevice				device,
									   const VkImage&				image,
									   const MemoryRequirement		requirement,
									   Allocator&					allocator,
									   AllocationKind				allocationKind)
{
	switch (allocationKind)
	{
		case ALLOCATION_KIND_SUBALLOCATED:
		{
			const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);

			return allocator.allocate(memoryRequirements, requirement);
		}

		case ALLOCATION_KIND_DEDICATED:
		{
			return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
		}

		default:
		{
			TCU_THROW(InternalError, "Invalid allocation kind");
		}
	}
}


inline deUint32 getArraySize(const ImageParms& parms)
{
	return (parms.imageType != VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u;
}

inline VkImageCreateFlags  getCreateFlags(const ImageParms& parms)
{
	if (parms.createFlags == VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM)
		return parms.imageType == VK_IMAGE_TYPE_2D && parms.extent.depth % 6 == 0 ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
	else
		return parms.createFlags;
}

inline VkExtent3D getExtent3D(const ImageParms& parms, deUint32 mipLevel = 0u)
{
	const bool			isCompressed	= isCompressedFormat(parms.format);
	const deUint32		blockWidth		= (isCompressed) ? getBlockWidth(parms.format) : 1u;
	const deUint32		blockHeight		= (isCompressed) ? getBlockHeight(parms.format) : 1u;

	if (isCompressed && mipLevel != 0u)
		DE_FATAL("Not implemented");

	const VkExtent3D	extent			=
	{
		(parms.extent.width >> mipLevel) * blockWidth,
		(parms.imageType != VK_IMAGE_TYPE_1D) ? ((parms.extent.height >> mipLevel) * blockHeight) : 1u,
		(parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
	};
	return extent;
}

const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat)
{
	tcu::TextureFormat format;
	switch (combinedFormat.type)
	{
		case tcu::TextureFormat::UNORM_INT16:
		case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
			break;
		case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
			break;
		case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
		case tcu::TextureFormat::FLOAT:
			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
			break;
		default:
			DE_ASSERT(false);
			break;
	}
	return format;
}

class CopiesAndBlittingTestInstance : public vkt::TestInstance
{
public:
										CopiesAndBlittingTestInstance		(Context&	context,
																			 TestParams	testParams);
	virtual tcu::TestStatus				iterate								(void) = 0;

protected:
	const TestParams					m_params;

	Move<VkCommandPool>					m_cmdPool;
	Move<VkCommandBuffer>				m_cmdBuffer;
	Move<VkFence>						m_fence;
	de::MovePtr<tcu::TextureLevel>		m_sourceTextureLevel;
	de::MovePtr<tcu::TextureLevel>		m_destinationTextureLevel;
	de::MovePtr<tcu::TextureLevel>		m_expectedTextureLevel[16];

	VkCommandBufferBeginInfo			m_cmdBufferBeginInfo;

	void								generateBuffer						(tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT);
	virtual void						generateExpectedResult				(void);
	void								uploadBuffer						(tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc);
	void								uploadImage							(const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels = 1u);
	virtual tcu::TestStatus				checkTestResult						(tcu::ConstPixelBufferAccess result);
	virtual void						copyRegionToTextureLevel			(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u) = 0;
	deUint32							calculateSize						(tcu::ConstPixelBufferAccess src) const
										{
											return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
										}

	de::MovePtr<tcu::TextureLevel>		readImage							(vk::VkImage				image,
																			 const ImageParms&			imageParms,
																			 const deUint32				mipLevel = 0u);

private:
	void								uploadImageAspect					(const tcu::ConstPixelBufferAccess&	src,
																			 const VkImage&						dst,
																			 const ImageParms&					parms,
																			 const deUint32						mipLevels = 1u);
	void								readImageAspect						(vk::VkImage						src,
																			 const tcu::PixelBufferAccess&		dst,
																			 const ImageParms&					parms,
																			 const deUint32						mipLevel = 0u);
};

CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams)
	: vkt::TestInstance	(context)
	, m_params			(testParams)
{
	const DeviceInterface&		vk					= context.getDeviceInterface();
	const VkDevice				vkDevice			= context.getDevice();
	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();

	// Create command pool
	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);

	// Create command buffer
	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

	// Create fence
	m_fence = createFence(vk, vkDevice);
}

void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
{
	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(buffer.getFormat().type);
	tcu::Vec4						maxValue		(1.0f);

	if (buffer.getFormat().order == tcu::TextureFormat::S)
	{
		// Stencil-only is stored in the first component. Stencil is always 8 bits.
		maxValue.x() = 1 << 8;
	}
	else if (buffer.getFormat().order == tcu::TextureFormat::DS)
	{
		// In a combined format, fillWithComponentGradients expects stencil in the fourth component.
		maxValue.w() = 1 << 8;
	}
	else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
	{
		// The tcu::Vectors we use as pixels are 32-bit, so clamp to that.
		const tcu::IVec4	bits	= tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32));
		const int			signBit	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);

		for (int i = 0; i < 4; ++i)
		{
			if (bits[i] != 0)
				maxValue[i] = static_cast<float>((deUint64(1) << (bits[i] - signBit)) - 1);
		}
	}

	if (mode == FILL_MODE_GRADIENT)
	{
		tcu::fillWithComponentGradients2(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
		return;
	}

	const tcu::Vec4		redColor	(maxValue.x(),	0.0,			0.0,			maxValue.w());
	const tcu::Vec4		greenColor	(0.0,			maxValue.y(),	0.0,			maxValue.w());
	const tcu::Vec4		blueColor	(0.0,			0.0,			maxValue.z(),	maxValue.w());
	const tcu::Vec4		whiteColor	(maxValue.x(),	maxValue.y(),	maxValue.z(),	maxValue.w());

	for (int z = 0; z < depth;  ++z)
	for (int y = 0; y < height; ++y)
	for (int x = 0; x < width;  ++x)
	{
		switch (mode)
		{
			case FILL_MODE_WHITE:
				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
				{
					buffer.setPixDepth(1.0f, x, y, z);
					if (tcu::hasStencilComponent(buffer.getFormat().order))
						buffer.setPixStencil(255, x, y, z);
				}
				else
					buffer.setPixel(whiteColor, x, y, z);
				break;

			case FILL_MODE_RED:
				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
				{
					buffer.setPixDepth(redColor[0], x, y, z);
					if (tcu::hasStencilComponent(buffer.getFormat().order))
						buffer.setPixStencil((int)redColor[3], x, y, z);
				}
				else
					buffer.setPixel(redColor, x, y, z);
				break;

			case FILL_MODE_BLUE_RED_X:
			case FILL_MODE_BLUE_RED_Y:
			case FILL_MODE_BLUE_RED_Z:
				bool useBlue;
				switch (mode)
				{
					case FILL_MODE_BLUE_RED_X: useBlue = (x & 1); break;
					case FILL_MODE_BLUE_RED_Y: useBlue = (y & 1); break;
					case FILL_MODE_BLUE_RED_Z: useBlue = (z & 1); break;
					default: DE_ASSERT(false); break;
				}
				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
				{
					buffer.setPixDepth((useBlue ? blueColor[0] : redColor[0]), x, y, z);
					if (tcu::hasStencilComponent(buffer.getFormat().order))
						buffer.setPixStencil((useBlue ? (int) blueColor[3] : (int)redColor[3]), x, y, z);
				}
				else
					buffer.setPixel((useBlue ? blueColor : redColor), x, y, z);
				break;

			case FILL_MODE_MULTISAMPLE:
			{
				float xScaled = static_cast<float>(x) / static_cast<float>(width);
				float yScaled = static_cast<float>(y) / static_cast<float>(height);
				buffer.setPixel((xScaled == yScaled) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((xScaled > yScaled) ? greenColor : blueColor), x, y, z);
				break;
			}

			default:
				break;
		}
	}
}

void CopiesAndBlittingTestInstance::uploadBuffer (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc)
{
	const DeviceInterface&		vk			= m_context.getDeviceInterface();
	const VkDevice				vkDevice	= m_context.getDevice();
	const deUint32				bufferSize	= calculateSize(bufferAccess);

	// Write buffer data
	deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
	flushAlloc(vk, vkDevice, bufferAlloc);
}

void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms, const deUint32 mipLevels)
{
	const InstanceInterface&		vki					= m_context.getInstanceInterface();
	const DeviceInterface&			vk					= m_context.getDeviceInterface();
	const VkPhysicalDevice			vkPhysDevice		= m_context.getPhysicalDevice();
	const VkDevice					vkDevice			= m_context.getDevice();
	const VkQueue					queue				= m_context.getUniversalQueue();
	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	Allocator&						memAlloc			= m_context.getDefaultAllocator();
	Move<VkBuffer>					buffer;
	const deUint32					bufferSize			= calculateSize(imageAccess);
	de::MovePtr<Allocation>			bufferAlloc;
	const deUint32					arraySize			= getArraySize(parms);
	const VkExtent3D				imageExtent			= getExtent3D(parms);
	std::vector <VkBufferImageCopy>	copyRegions;

	// Create source buffer
	{
		const VkBufferCreateInfo	bufferParams		=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			bufferSize,									// VkDeviceSize			size;
			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyIndexCount;
			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
		};

		buffer		= createBuffer(vk, vkDevice, &bufferParams);
		bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
	}

	// Barriers for copying buffer to image
	const VkBufferMemoryBarrier		preBufferBarrier	=
	{
		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType	sType;
		DE_NULL,										// const void*		pNext;
		VK_ACCESS_HOST_WRITE_BIT,						// VkAccessFlags	srcAccessMask;
		VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags	dstAccessMask;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
		*buffer,										// VkBuffer			buffer;
		0u,												// VkDeviceSize		offset;
		bufferSize										// VkDeviceSize		size;
	};

	const VkImageAspectFlags		formatAspect		= (m_params.separateDepthStencilLayouts) ? getAspectFlags(imageAccess.getFormat()) : getAspectFlags(parms.format);
	const bool						skipPreImageBarrier	= (m_params.separateDepthStencilLayouts) ? false : ((formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) &&
														  getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT));

	const VkImageMemoryBarrier		preImageBarrier		=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
		DE_NULL,										// const void*				pNext;
		0u,												// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
		image,											// VkImage					image;
		{												// VkImageSubresourceRange	subresourceRange;
			formatAspect,	// VkImageAspectFlags	aspect;
			0u,				// deUint32				baseMipLevel;
			mipLevels,		// deUint32				mipLevels;
			0u,				// deUint32				baseArraySlice;
			arraySize,		// deUint32				arraySize;
		}
	};

	const VkImageMemoryBarrier		postImageBarrier	=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
		DE_NULL,										// const void*				pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
		image,											// VkImage					image;
		{												// VkImageSubresourceRange	subresourceRange;
			formatAspect,				// VkImageAspectFlags	aspect;
			0u,							// deUint32				baseMipLevel;
			mipLevels,					// deUint32				mipLevels;
			0u,							// deUint32				baseArraySlice;
			arraySize,					// deUint32				arraySize;
		}
	};

	for (deUint32 mipLevelNdx = 0; mipLevelNdx < mipLevels; mipLevelNdx++)
	{
		const VkExtent3D		copyExtent	=
		{
			imageExtent.width	>> mipLevelNdx,
			imageExtent.height	>> mipLevelNdx,
			imageExtent.depth
		};

		const VkBufferImageCopy	copyRegion	=
		{
			0u,												// VkDeviceSize				bufferOffset;
			copyExtent.width,								// deUint32					bufferRowLength;
			copyExtent.height,								// deUint32					bufferImageHeight;
			{
				getAspectFlags(imageAccess.getFormat()),		// VkImageAspectFlags	aspect;
				mipLevelNdx,									// deUint32				mipLevel;
				0u,												// deUint32				baseArrayLayer;
				arraySize,										// deUint32				layerCount;
			},												// VkImageSubresourceLayers	imageSubresource;
			{ 0, 0, 0 },									// VkOffset3D				imageOffset;
			copyExtent										// VkExtent3D				imageExtent;
		};

		copyRegions.push_back(copyRegion);
	}

	// Write buffer data
	deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
	flushAlloc(vk, vkDevice, *bufferAlloc);

	// Copy buffer to image
	beginCommandBuffer(vk, *m_cmdBuffer);
	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
						  1, &preBufferBarrier, (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier));
	vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), &copyRegions[0]);
	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);
	endCommandBuffer(vk, *m_cmdBuffer);

	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
}

void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels)
{
	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
	{
		if (tcu::hasDepthComponent(src.getFormat().order))
		{
			tcu::TextureLevel	depthTexture	(mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth());
			tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
			uploadImageAspect(depthTexture.getAccess(), dst, parms);
		}

		if (tcu::hasStencilComponent(src.getFormat().order))
		{
			tcu::TextureLevel	stencilTexture	(tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth());
			tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
			uploadImageAspect(stencilTexture.getAccess(), dst, parms);
		}
	}
	else
		uploadImageAspect(src, dst, parms, mipLevels);
}

tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result)
{
	const tcu::ConstPixelBufferAccess	expected	= m_expectedTextureLevel[0]->getAccess();

	if (isFloatFormat(result.getFormat()))
	{
		const tcu::Vec4	threshold (0.0f);
		if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
			return tcu::TestStatus::fail("CopiesAndBlitting test");
	}
	else
	{
		const tcu::UVec4 threshold (0u);
		if (tcu::hasDepthComponent(result.getFormat().order) || tcu::hasStencilComponent(result.getFormat().order))
		{
			if (!tcu::dsThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, 0.1f, tcu::COMPARE_LOG_RESULT))
				return tcu::TestStatus::fail("CopiesAndBlitting test");
		}
		else
		{
			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
				return tcu::TestStatus::fail("CopiesAndBlitting test");
		}
	}

	return tcu::TestStatus::pass("CopiesAndBlitting test");
}

void CopiesAndBlittingTestInstance::generateExpectedResult (void)
{
	const tcu::ConstPixelBufferAccess	src	= m_sourceTextureLevel->getAccess();
	const tcu::ConstPixelBufferAccess	dst	= m_destinationTextureLevel->getAccess();

	m_expectedTextureLevel[0]	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
	tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);

	for (deUint32 i = 0; i < m_params.regions.size(); i++)
		copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), m_params.regions[i]);
}

class CopiesAndBlittingTestCase : public vkt::TestCase
{
public:
							CopiesAndBlittingTestCase	(tcu::TestContext&			testCtx,
														 const std::string&			name,
														 const std::string&			description)
								: vkt::TestCase	(testCtx, name, description)
							{}

	virtual TestInstance*	createInstance				(Context&					context) const = 0;
};

void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage					image,
													 const tcu::PixelBufferAccess&	dst,
													 const ImageParms&				imageParms,
													 const deUint32					mipLevel)
{
	const InstanceInterface&	vki					= m_context.getInstanceInterface();
	const DeviceInterface&		vk					= m_context.getDeviceInterface();
	const VkPhysicalDevice		physDevice			= m_context.getPhysicalDevice();
	const VkDevice				device				= m_context.getDevice();
	const VkQueue				queue				= m_context.getUniversalQueue();
	Allocator&					allocator			= m_context.getDefaultAllocator();

	Move<VkBuffer>				buffer;
	de::MovePtr<Allocation>		bufferAlloc;
	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	const VkDeviceSize			pixelDataSize		= calculateSize(dst);
	const VkExtent3D			imageExtent			= getExtent3D(imageParms, mipLevel);

	// Create destination buffer
	{
		const VkBufferCreateInfo			bufferParams			=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			pixelDataSize,								// VkDeviceSize			size;
			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyIndexCount;
			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
		};

		buffer		= createBuffer(vk, device, &bufferParams);
		bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator, m_params.allocationKind);
		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));

		deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
		flushAlloc(vk, device, *bufferAlloc);
	}

	// Barriers for copying image to buffer
	const VkImageAspectFlags				formatAspect			= getAspectFlags(imageParms.format);
	const VkImageMemoryBarrier				imageBarrier			=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
		imageParms.operationLayout,					// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
		image,										// VkImage					image;
		{											// VkImageSubresourceRange	subresourceRange;
			formatAspect,			// VkImageAspectFlags	aspectMask;
			mipLevel,				// deUint32				baseMipLevel;
			1u,						// deUint32				mipLevels;
			0u,						// deUint32				baseArraySlice;
			getArraySize(imageParms)// deUint32				arraySize;
		}
	};

	const VkBufferMemoryBarrier				bufferBarrier			=
	{
		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
		DE_NULL,									// const void*		pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
		*buffer,									// VkBuffer			buffer;
		0u,											// VkDeviceSize		offset;
		pixelDataSize								// VkDeviceSize		size;
	};

	const VkImageMemoryBarrier				postImageBarrier		=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			oldLayout;
		imageParms.operationLayout,					// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
		image,										// VkImage					image;
		{
			formatAspect,								// VkImageAspectFlags	aspectMask;
			mipLevel,									// deUint32				baseMipLevel;
			1u,											// deUint32				mipLevels;
			0u,											// deUint32				baseArraySlice;
			getArraySize(imageParms)					// deUint32				arraySize;
		}											// VkImageSubresourceRange	subresourceRange;
	};

	// Copy image to buffer
	const VkImageAspectFlags	aspect			= getAspectFlags(dst.getFormat());
	const VkBufferImageCopy		copyRegion		=
	{
		0u,								// VkDeviceSize				bufferOffset;
		imageExtent.width,				// deUint32					bufferRowLength;
		imageExtent.height,				// deUint32					bufferImageHeight;
		{
			aspect,							// VkImageAspectFlags		aspect;
			mipLevel,						// deUint32					mipLevel;
			0u,								// deUint32					baseArrayLayer;
			getArraySize(imageParms),		// deUint32					layerCount;
		},								// VkImageSubresourceLayers	imageSubresource;
		{ 0, 0, 0 },					// VkOffset3D				imageOffset;
		imageExtent						// VkExtent3D				imageExtent;
	};

	beginCommandBuffer(vk, *m_cmdBuffer);
	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);
	vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
	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);
	endCommandBuffer(vk, *m_cmdBuffer);

	submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);

	// Read buffer data
	invalidateAlloc(vk, device, *bufferAlloc);
	tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
}

de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage	(vk::VkImage		image,
																		 const ImageParms&	parms,
																		 const deUint32		mipLevel)
{
	const tcu::TextureFormat		imageFormat	= getSizeCompatibleTcuTextureFormat(parms.format);
	de::MovePtr<tcu::TextureLevel>	resultLevel	(new tcu::TextureLevel(imageFormat, parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth));

	if (tcu::isCombinedDepthStencilType(imageFormat.type))
	{
		if (tcu::hasDepthComponent(imageFormat.order))
		{
			tcu::TextureLevel	depthTexture	(mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width, parms.extent.height, parms.extent.depth);
			readImageAspect(image, depthTexture.getAccess(), parms);
			tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess());
		}

		if (tcu::hasStencilComponent(imageFormat.order))
		{
			tcu::TextureLevel	stencilTexture	(tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width, parms.extent.height, parms.extent.depth);
			readImageAspect(image, stencilTexture.getAccess(), parms);
			tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess());
		}
	}
	else
		readImageAspect(image, resultLevel->getAccess(), parms, mipLevel);

	return resultLevel;
}

// Copy from image to image.

class CopyImageToImage : public CopiesAndBlittingTestInstance
{
public:
										CopyImageToImage			(Context&	context,
																	 TestParams params);
	virtual tcu::TestStatus				iterate						(void);

protected:
	virtual tcu::TestStatus				checkTestResult				(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());

private:
	Move<VkImage>						m_source;
	de::MovePtr<Allocation>				m_sourceImageAlloc;
	Move<VkImage>						m_destination;
	de::MovePtr<Allocation>				m_destinationImageAlloc;

	virtual void						copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
};

CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
	: CopiesAndBlittingTestInstance(context, params)
{
	const InstanceInterface&	vki					= context.getInstanceInterface();
	const DeviceInterface&		vk					= context.getDeviceInterface();
	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
	const VkDevice				vkDevice			= context.getDevice();
	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	Allocator&					memAlloc			= context.getDefaultAllocator();

	// Create source image
	{
		const VkImageCreateInfo	sourceImageParams		=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
			m_params.src.image.imageType,			// VkImageType			imageType;
			m_params.src.image.format,				// VkFormat				format;
			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
			1u,										// deUint32				mipLevels;
			getArraySize(m_params.src.image),		// deUint32				arraySize;
			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
		};

		m_source				= createImage(vk, vkDevice, &sourceImageParams);
		m_sourceImageAlloc		= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
	}

	// Create destination image
	{
		const VkImageCreateInfo	destinationImageParams	=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
			m_params.dst.image.imageType,			// VkImageType			imageType;
			m_params.dst.image.format,				// VkFormat				format;
			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
			1u,										// deUint32				mipLevels;
			getArraySize(m_params.dst.image),		// deUint32				arraySize;
			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
		};

		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
	}
}

tcu::TestStatus CopyImageToImage::iterate (void)
{
	const bool					srcCompressed		= isCompressedFormat(m_params.src.image.format);
	const bool					dstCompressed		= isCompressedFormat(m_params.dst.image.format);

	const tcu::TextureFormat	srcTcuFormat		= getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
	const tcu::TextureFormat	dstTcuFormat		= getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);

	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
																				(int)m_params.src.image.extent.width,
																				(int)m_params.src.image.extent.height,
																				(int)m_params.src.image.extent.depth));
	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);
	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
																				(int)m_params.dst.image.extent.width,
																				(int)m_params.dst.image.extent.height,
																				(int)m_params.dst.image.extent.depth));
	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, m_params.clearDestination ? FILL_MODE_WHITE : FILL_MODE_GRADIENT);
	generateExpectedResult();

	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);

	const DeviceInterface&		vk					= m_context.getDeviceInterface();
	const VkDevice				vkDevice			= m_context.getDevice();
	const VkQueue				queue				= m_context.getUniversalQueue();

	std::vector<VkImageCopy>		imageCopies;
	std::vector<VkImageCopy2KHR>	imageCopies2KHR;
	for (deUint32 i = 0; i < m_params.regions.size(); i++)
	{
		VkImageCopy imageCopy = m_params.regions[i].imageCopy;

		// When copying between compressed and uncompressed formats the extent
		// members represent the texel dimensions of the source image.
		if (srcCompressed)
		{
			const deUint32	blockWidth	= getBlockWidth(m_params.src.image.format);
			const deUint32	blockHeight	= getBlockHeight(m_params.src.image.format);

			imageCopy.srcOffset.x *= blockWidth;
			imageCopy.srcOffset.y *= blockHeight;
			imageCopy.extent.width *= blockWidth;
			imageCopy.extent.height *= blockHeight;
		}

		if (dstCompressed)
		{
			const deUint32	blockWidth	= getBlockWidth(m_params.dst.image.format);
			const deUint32	blockHeight	= getBlockHeight(m_params.dst.image.format);

			imageCopy.dstOffset.x *= blockWidth;
			imageCopy.dstOffset.y *= blockHeight;
		}

		if (m_params.extensionUse == EXTENSION_USE_NONE)
		{
			imageCopies.push_back(imageCopy);
		}
		else
		{
			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
			imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
		}
	}

	const VkImageMemoryBarrier	imageBarriers[]		=
	{
		// source image
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
			DE_NULL,									// const void*				pNext;
			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
			m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
			m_source.get(),								// VkImage					image;
			{											// VkImageSubresourceRange	subresourceRange;
				getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
				0u,								// deUint32				baseMipLevel;
				1u,								// deUint32				mipLevels;
				0u,								// deUint32				baseArraySlice;
				getArraySize(m_params.src.image)// deUint32				arraySize;
			}
		},
		// destination image
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
			DE_NULL,									// const void*				pNext;
			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
			m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
			m_destination.get(),						// VkImage					image;
			{											// VkImageSubresourceRange	subresourceRange;
				getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
				0u,								// deUint32				baseMipLevel;
				1u,								// deUint32				mipLevels;
				0u,								// deUint32				baseArraySlice;
				getArraySize(m_params.dst.image)// deUint32				arraySize;
			}
		},
	};

	beginCommandBuffer(vk, *m_cmdBuffer);
	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);

	if (m_params.clearDestination)
	{
		VkImageSubresourceRange	range		= { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u };
		VkClearColorValue		clearColor;

		clearColor.float32[0] = 1.0f;
		clearColor.float32[1] = 1.0f;
		clearColor.float32[2] = 1.0f;
		clearColor.float32[3] = 1.0f;
		vk.cmdClearColorImage(*m_cmdBuffer, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1u, &range);
	}

	if (m_params.extensionUse == EXTENSION_USE_NONE)
	{
		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());
	}
	else
	{
		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
		const VkCopyImageInfo2KHR copyImageInfo2KHR =
		{
			VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
			DE_NULL,									// const void*				pNext;
			m_source.get(),								// VkImage					srcImage;
			m_params.src.image.operationLayout,			// VkImageLayout			srcImageLayout;
			m_destination.get(),						// VkImage					dstImage;
			m_params.dst.image.operationLayout,			// VkImageLayout			dstImageLayout;
			(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
			imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
		};

		vk.cmdCopyImage2KHR(*m_cmdBuffer, &copyImageInfo2KHR);
	}

	endCommandBuffer(vk, *m_cmdBuffer);

	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);

	de::MovePtr<tcu::TextureLevel>	resultTextureLevel	= readImage(*m_destination, m_params.dst.image);

	return checkTestResult(resultTextureLevel->getAccess());
}

tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
{
	const tcu::Vec4	fThreshold (0.0f);
	const tcu::UVec4 uThreshold (0u);

	if (tcu::isCombinedDepthStencilType(result.getFormat().type))
	{
		if (tcu::hasDepthComponent(result.getFormat().order))
		{
			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
			const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);

			if (isFloatFormat(result.getFormat()))
			{
				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
					return tcu::TestStatus::fail("CopiesAndBlitting test");
			}
			else
			{
				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
					return tcu::TestStatus::fail("CopiesAndBlitting test");
			}
		}

		if (tcu::hasStencilComponent(result.getFormat().order))
		{
			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
			const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);

			if (isFloatFormat(result.getFormat()))
			{
				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
					return tcu::TestStatus::fail("CopiesAndBlitting test");
			}
			else
			{
				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
					return tcu::TestStatus::fail("CopiesAndBlitting test");
			}
		}
	}
	else
	{
		if (isFloatFormat(result.getFormat()))
		{
			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
				return tcu::TestStatus::fail("CopiesAndBlitting test");
		}
		else
		{
			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
				return tcu::TestStatus::fail("CopiesAndBlitting test");
		}
	}

	return tcu::TestStatus::pass("CopiesAndBlitting test");
}

void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
{
	DE_UNREF(mipLevel);

	VkOffset3D	srcOffset	= region.imageCopy.srcOffset;
	VkOffset3D	dstOffset	= region.imageCopy.dstOffset;
	VkExtent3D	extent		= region.imageCopy.extent;

	if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
	{
		dstOffset.z = srcOffset.z;
		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
	}
	if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
	{
		srcOffset.z = dstOffset.z;
		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
	}


	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
	{
		DE_ASSERT(src.getFormat() == dst.getFormat());

		// Copy depth.
		if (tcu::hasDepthComponent(src.getFormat().order))
		{
			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
			tcu::copy(dstSubRegion, srcSubRegion);
		}

		// Copy stencil.
		if (tcu::hasStencilComponent(src.getFormat().order))
		{
			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
			tcu::copy(dstSubRegion, srcSubRegion);
		}
	}
	else
	{
		const tcu::ConstPixelBufferAccess	srcSubRegion		= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
		// CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
		const tcu::PixelBufferAccess		dstWithSrcFormat	(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
		const tcu::PixelBufferAccess		dstSubRegion		= tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);

		tcu::copy(dstSubRegion, srcSubRegion);
	}
}

class CopyImageToImageTestCase : public vkt::TestCase
{
public:
							CopyImageToImageTestCase	(tcu::TestContext&				testCtx,
														 const std::string&				name,
														 const std::string&				description,
														 const TestParams				params)
								: vkt::TestCase	(testCtx, name, description)
								, m_params		(params)
	{}

	virtual TestInstance*	createInstance				(Context&						context) const
	{
		return new CopyImageToImage(context, m_params);
	}

	virtual void			checkSupport				(Context&						context) const
	{
		if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
		{
			if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
				TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
		}

		if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
		{
			if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
				TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
		}

		if (m_params.separateDepthStencilLayouts)
			if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
				TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");

		if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
			(m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
		{
			if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
				TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
		}

		const VkPhysicalDeviceLimits	limits		= context.getDeviceProperties().limits;
		VkImageFormatProperties			properties;

		if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
																					m_params.src.image.format,
																					m_params.src.image.imageType,
																					VK_IMAGE_TILING_OPTIMAL,
																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
																					0,
																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
			(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
																					m_params.dst.image.format,
																					m_params.dst.image.imageType,
																					VK_IMAGE_TILING_OPTIMAL,
																					VK_IMAGE_USAGE_TRANSFER_DST_BIT,
																					0,
																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
		{
			TCU_THROW(NotSupportedError, "Format not supported");
		}

		// Check maxImageDimension1D
		{
			if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
				TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");

			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
				TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
		}

		// Check maxImageDimension2D
		{
			if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
				|| m_params.src.image.extent.height > limits.maxImageDimension2D))
			{
				TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
			}

			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
				|| m_params.dst.image.extent.height > limits.maxImageDimension2D))
			{
				TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
			}
		}

		// Check maxImageDimension3D
		{
			if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
				|| m_params.src.image.extent.height > limits.maxImageDimension3D
				|| m_params.src.image.extent.depth > limits.maxImageDimension3D))
			{
				TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
			}

			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
				|| m_params.dst.image.extent.height > limits.maxImageDimension3D
				|| m_params.src.image.extent.depth > limits.maxImageDimension3D))
			{
				TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
			}
		}
	}

private:
	TestParams				m_params;
};

// Copy from buffer to buffer.

class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
{
public:
								CopyBufferToBuffer			(Context& context, TestParams params);
	virtual tcu::TestStatus		iterate						(void);
private:
	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion, deUint32 mipLevel = 0u);
	Move<VkBuffer>				m_source;
	de::MovePtr<Allocation>		m_sourceBufferAlloc;
	Move<VkBuffer>				m_destination;
	de::MovePtr<Allocation>		m_destinationBufferAlloc;
};

CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
	: CopiesAndBlittingTestInstance	(context, params)
{
	const InstanceInterface&	vki					= context.getInstanceInterface();
	const DeviceInterface&		vk					= context.getDeviceInterface();
	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
	const VkDevice				vkDevice			= context.getDevice();
	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	Allocator&					memAlloc			= context.getDefaultAllocator();

	// Create source buffer
	{
		const VkBufferCreateInfo	sourceBufferParams		=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			m_params.src.buffer.size,					// VkDeviceSize			size;
			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyIndexCount;
			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
		};

		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
		m_sourceBufferAlloc		= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
	}

	// Create destination buffer
	{
		const VkBufferCreateInfo	destinationBufferParams	=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			m_params.dst.buffer.size,					// VkDeviceSize			size;
			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyIndexCount;
			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
		};

		m_destination				= createBuffer(vk, vkDevice, &destinationBufferParams);
		m_destinationBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
	}
}

tcu::TestStatus CopyBufferToBuffer::iterate (void)
{
	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
	m_sourceTextureLevel		= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
	generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);

	const int dstLevelWidth		= (int)(m_params.dst.buffer.size/4);
	m_destinationTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
	generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_WHITE);

	generateExpectedResult();

	uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
	uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);

	const DeviceInterface&		vk			= m_context.getDeviceInterface();
	const VkDevice				vkDevice	= m_context.getDevice();
	const VkQueue				queue		= m_context.getUniversalQueue();

	const VkBufferMemoryBarrier		srcBufferBarrier	=
	{
		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
		DE_NULL,									// const void*		pNext;
		VK_ACCESS_HOST_WRITE_BIT,					// VkAccessFlags	srcAccessMask;
		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags	dstAccessMask;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
		*m_source,									// VkBuffer			buffer;
		0u,											// VkDeviceSize		offset;
		m_params.src.buffer.size					// VkDeviceSize		size;
	};

	const VkBufferMemoryBarrier		dstBufferBarrier	=
	{
		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
		DE_NULL,									// const void*		pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
		*m_destination,								// VkBuffer			buffer;
		0u,											// VkDeviceSize		offset;
		m_params.dst.buffer.size					// VkDeviceSize		size;
	};

	std::vector<VkBufferCopy>		bufferCopies;
	std::vector<VkBufferCopy2KHR>	bufferCopies2KHR;
	for (deUint32 i = 0; i < m_params.regions.size(); i++)
	{
		if (m_params.extensionUse == EXTENSION_USE_NONE)
		{
			bufferCopies.push_back(m_params.regions[i].bufferCopy);
		}
		else
		{
			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
			bufferCopies2KHR.push_back(convertvkBufferCopyTovkBufferCopy2KHR(m_params.regions[i].bufferCopy));
		}
	}

	beginCommandBuffer(vk, *m_cmdBuffer);
	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);

	if (m_params.extensionUse == EXTENSION_USE_NONE)
	{
		vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]);
	}
	else
	{
		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
		const VkCopyBufferInfo2KHR copyBufferInfo2KHR =
		{
			VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR,	// VkStructureType			sType;
			DE_NULL,									// const void*				pNext;
			m_source.get(),								// VkBuffer					srcBuffer;
			m_destination.get(),						// VkBuffer					dstBuffer;
			(deUint32)m_params.regions.size(),			// uint32_t					regionCount;
			&bufferCopies2KHR[0]						// const VkBufferCopy2KHR*	pRegions;
		};

		vk.cmdCopyBuffer2KHR(*m_cmdBuffer, &copyBufferInfo2KHR);
	}

	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &dstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
	endCommandBuffer(vk, *m_cmdBuffer);
	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);

	// Read buffer data
	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
	invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));

	return checkTestResult(resultLevel->getAccess());
}

void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
{
	DE_UNREF(mipLevel);

	deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
			 (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
			 (size_t)region.bufferCopy.size);
}

class BufferToBufferTestCase : public vkt::TestCase
{
public:
							BufferToBufferTestCase	(tcu::TestContext&	testCtx,
													 const std::string&	name,
													 const std::string&	description,
													 const TestParams	params)
								: vkt::TestCase	(testCtx, name, description)
								, m_params		(params)
							{}

	virtual TestInstance*	createInstance			(Context& context) const
							{
								return new CopyBufferToBuffer(context, m_params);
							}

	virtual void			checkSupport(Context&	context) const
	{
							if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
							{
								if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
								{
									TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
								}
							}
	}

	private:
	TestParams				m_params;
};

// Copy from image to buffer.

class CopyImageToBuffer : public CopiesAndBlittingTestInstance
{
public:
								CopyImageToBuffer			(Context&	context,
															 TestParams	testParams);
	virtual tcu::TestStatus		iterate						(void);
private:
	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);

	tcu::TextureFormat			m_textureFormat;
	VkDeviceSize				m_bufferSize;

	Move<VkImage>				m_source;
	de::MovePtr<Allocation>		m_sourceImageAlloc;
	Move<VkBuffer>				m_destination;
	de::MovePtr<Allocation>		m_destinationBufferAlloc;
};

CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
	: CopiesAndBlittingTestInstance(context, testParams)
	, m_textureFormat(mapVkFormat(testParams.src.image.format))
	, m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
{
	const InstanceInterface&	vki					= context.getInstanceInterface();
	const DeviceInterface&		vk					= context.getDeviceInterface();
	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
	const VkDevice				vkDevice			= context.getDevice();
	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	Allocator&					memAlloc			= context.getDefaultAllocator();

	// Create source image
	{
		const VkImageCreateInfo		sourceImageParams		=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
			m_params.src.image.imageType,			// VkImageType			imageType;
			m_params.src.image.format,				// VkFormat				format;
			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
			1u,										// deUint32				mipLevels;
			getArraySize(m_params.src.image),		// deUint32				arraySize;
			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
		};

		m_source			= createImage(vk, vkDevice, &sourceImageParams);
		m_sourceImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
	}

	// Create destination buffer
	{
		const VkBufferCreateInfo	destinationBufferParams	=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			m_bufferSize,								// VkDeviceSize			size;
			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyIndexCount;
			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
		};

		m_destination				= createBuffer(vk, vkDevice, &destinationBufferParams);
		m_destinationBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
	}
}

tcu::TestStatus CopyImageToBuffer::iterate (void)
{
	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
																				m_params.src.image.extent.width,
																				m_params.src.image.extent.height,
																				m_params.src.image.extent.depth));
	generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
	generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);

	generateExpectedResult();

	uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
	uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);

	const DeviceInterface&		vk			= m_context.getDeviceInterface();
	const VkDevice				vkDevice	= m_context.getDevice();
	const VkQueue				queue		= m_context.getUniversalQueue();

	// Barriers for copying image to buffer
	const VkImageMemoryBarrier		imageBarrier		=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
		*m_source,									// VkImage					image;
		{											// VkImageSubresourceRange	subresourceRange;
			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
			0u,									// deUint32				baseMipLevel;
			1u,									// deUint32				mipLevels;
			0u,									// deUint32				baseArraySlice;
			getArraySize(m_params.src.image)	// deUint32				arraySize;
		}
	};

	const VkBufferMemoryBarrier		bufferBarrier		=
	{
		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
		DE_NULL,									// const void*		pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
		*m_destination,								// VkBuffer			buffer;
		0u,											// VkDeviceSize		offset;
		m_bufferSize								// VkDeviceSize		size;
	};

	// Copy from image to buffer
	std::vector<VkBufferImageCopy>		bufferImageCopies;
	std::vector<VkBufferImageCopy2KHR>	bufferImageCopies2KHR;
	for (deUint32 i = 0; i < m_params.regions.size(); i++)
	{
		if (m_params.extensionUse == EXTENSION_USE_NONE)
		{
			bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
		}
		else
		{
			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
			bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
		}
	}

	beginCommandBuffer(vk, *m_cmdBuffer);
	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);

	if (m_params.extensionUse == EXTENSION_USE_NONE)
	{
		vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), &bufferImageCopies[0]);
	}
	else
	{
		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
		const VkCopyImageToBufferInfo2KHR copyImageToBufferInfo2KHR =
		{
			VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR,	// VkStructureType				sType;
			DE_NULL,											// const void*					pNext;
			m_source.get(),										// VkImage						srcImage;
			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,				// VkImageLayout				srcImageLayout;
			m_destination.get(),								// VkBuffer						dstBuffer;
			(deUint32)m_params.regions.size(),					// uint32_t						regionCount;
			&bufferImageCopies2KHR[0]							// const VkBufferImageCopy2KHR*	pRegions;
		};

		vk.cmdCopyImageToBuffer2KHR(*m_cmdBuffer, &copyImageToBufferInfo2KHR);
	}

	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
	endCommandBuffer(vk, *m_cmdBuffer);

	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);

	// Read buffer data
	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
	invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));

	return checkTestResult(resultLevel->getAccess());
}

class CopyImageToBufferTestCase : public vkt::TestCase
{
public:
							CopyImageToBufferTestCase	(tcu::TestContext&		testCtx,
														 const std::string&		name,
														 const std::string&		description,
														 const TestParams		params)
								: vkt::TestCase	(testCtx, name, description)
								, m_params		(params)
							{}

	virtual TestInstance*	createInstance				(Context&				context) const
							{
								return new CopyImageToBuffer(context, m_params);
							}

	virtual void			checkSupport				(Context&				context) const
							{
								if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
									(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
								{
									TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
								}
							}

private:
	TestParams				m_params;
};

void CopyImageToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
{
	DE_UNREF(mipLevel);

	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
	if (!rowLength)
		rowLength = region.bufferImageCopy.imageExtent.width;

	deUint32			imageHeight	= region.bufferImageCopy.bufferImageHeight;
	if (!imageHeight)
		imageHeight = region.bufferImageCopy.imageExtent.height;

	const int			texelSize		= src.getFormat().getPixelSize();
	const VkExtent3D	extent			= region.bufferImageCopy.imageExtent;
	const VkOffset3D	srcOffset		= region.bufferImageCopy.imageOffset;
	const int			texelOffset		= (int) region.bufferImageCopy.bufferOffset / texelSize;
	const deUint32		baseArrayLayer	= region.bufferImageCopy.imageSubresource.baseArrayLayer;

	for (deUint32 z = 0; z < extent.depth; z++)
	{
		for (deUint32 y = 0; y < extent.height; y++)
		{
			int									texelIndex		= texelOffset + (z * imageHeight + y) *	rowLength;
			const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z + baseArrayLayer,
																					region.bufferImageCopy.imageExtent.width, 1, 1);
			const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
			tcu::copy(dstSubRegion, srcSubRegion);
		}
	}
}

// Copy from buffer to image.

class CopyBufferToImage : public CopiesAndBlittingTestInstance
{
public:
								CopyBufferToImage			(Context&	context,
															 TestParams	testParams);
	virtual tcu::TestStatus		iterate						(void);

private:
	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);

	tcu::TextureFormat			m_textureFormat;
	VkDeviceSize				m_bufferSize;

	Move<VkBuffer>				m_source;
	de::MovePtr<Allocation>		m_sourceBufferAlloc;
	Move<VkImage>				m_destination;
	de::MovePtr<Allocation>		m_destinationImageAlloc;
};

CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
	: CopiesAndBlittingTestInstance(context, testParams)
	, m_textureFormat(mapVkFormat(testParams.dst.image.format))
	, m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
{
	const InstanceInterface&	vki					= context.getInstanceInterface();
	const DeviceInterface&		vk					= context.getDeviceInterface();
	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
	const VkDevice				vkDevice			= context.getDevice();
	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	Allocator&					memAlloc			= context.getDefaultAllocator();

	// Create source buffer
	{
		const VkBufferCreateInfo	sourceBufferParams		=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			m_bufferSize,								// VkDeviceSize			size;
			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyIndexCount;
			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
		};

		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
		m_sourceBufferAlloc		= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
	}

	// Create destination image
	{
		const VkImageCreateInfo		destinationImageParams	=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
			m_params.dst.image.imageType,			// VkImageType			imageType;
			m_params.dst.image.format,				// VkFormat				format;
			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
			1u,										// deUint32				mipLevels;
			getArraySize(m_params.dst.image),		// deUint32				arraySize;
			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
		};

		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
	}
}

tcu::TestStatus CopyBufferToImage::iterate (void)
{
	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
	generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
																					m_params.dst.image.extent.width,
																					m_params.dst.image.extent.height,
																					m_params.dst.image.extent.depth));

	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);

	generateExpectedResult();

	uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
	uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);

	const DeviceInterface&		vk			= m_context.getDeviceInterface();
	const VkDevice				vkDevice	= m_context.getDevice();
	const VkQueue				queue		= m_context.getUniversalQueue();

	const VkImageMemoryBarrier	imageBarrier	=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
		*m_destination,								// VkImage					image;
		{											// VkImageSubresourceRange	subresourceRange;
			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
			0u,								// deUint32				baseMipLevel;
			1u,								// deUint32				mipLevels;
			0u,								// deUint32				baseArraySlice;
			getArraySize(m_params.dst.image)								// deUint32				arraySize;
		}
	};

	// Copy from buffer to image
	std::vector<VkBufferImageCopy>		bufferImageCopies;
	std::vector<VkBufferImageCopy2KHR>	bufferImageCopies2KHR;
	for (deUint32 i = 0; i < m_params.regions.size(); i++)
	{
		if (m_params.extensionUse == EXTENSION_USE_NONE)
		{
			bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
		}
		else
		{
			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
			bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
		}
	}

	beginCommandBuffer(vk, *m_cmdBuffer);
	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);

	if (m_params.extensionUse == EXTENSION_USE_NONE)
	{
		vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
	}
	else
	{
		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
		const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
		{
			VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
			DE_NULL,											// const void*					pNext;
			m_source.get(),										// VkBuffer						srcBuffer;
			m_destination.get(),								// VkImage						dstImage;
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout				dstImageLayout;
			(deUint32)m_params.regions.size(),					// uint32_t						regionCount;
			bufferImageCopies2KHR.data()						// const VkBufferImageCopy2KHR*	pRegions;
		};

		vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
	}


	endCommandBuffer(vk, *m_cmdBuffer);

	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);

	de::MovePtr<tcu::TextureLevel>	resultLevel	= readImage(*m_destination, m_params.dst.image);

	return checkTestResult(resultLevel->getAccess());
}

class CopyBufferToImageTestCase : public vkt::TestCase
{
public:
							CopyBufferToImageTestCase	(tcu::TestContext&		testCtx,
														 const std::string&		name,
														 const std::string&		description,
														 const TestParams		params)
								: vkt::TestCase	(testCtx, name, description)
								, m_params		(params)
							{}

	virtual					~CopyBufferToImageTestCase	(void) {}

	virtual TestInstance*	createInstance				(Context&				context) const
							{
								return new CopyBufferToImage(context, m_params);
							}

	virtual void			checkSupport				(Context&				context) const
							{
								if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
									(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
								{
									TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
								}
							}


private:
	TestParams				m_params;
};

void CopyBufferToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
{
	DE_UNREF(mipLevel);

	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
	if (!rowLength)
		rowLength = region.bufferImageCopy.imageExtent.width;

	deUint32			imageHeight	= region.bufferImageCopy.bufferImageHeight;
	if (!imageHeight)
		imageHeight = region.bufferImageCopy.imageExtent.height;

	const int			texelSize		= dst.getFormat().getPixelSize();
	const VkExtent3D	extent			= region.bufferImageCopy.imageExtent;
	const VkOffset3D	dstOffset		= region.bufferImageCopy.imageOffset;
	const int			texelOffset		= (int) region.bufferImageCopy.bufferOffset / texelSize;
	const deUint32		baseArrayLayer	= region.bufferImageCopy.imageSubresource.baseArrayLayer;

	for (deUint32 z = 0; z < extent.depth; z++)
	{
		for (deUint32 y = 0; y < extent.height; y++)
		{
			int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
			const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
			const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z + baseArrayLayer,
																		  region.bufferImageCopy.imageExtent.width, 1, 1);
			tcu::copy(dstSubRegion, srcSubRegion);
		}
	}
}

class CopyBufferToDepthStencil : public CopiesAndBlittingTestInstance
{
public:
								CopyBufferToDepthStencil	(Context& context,
															 TestParams	testParams);
	virtual tcu::TestStatus		iterate						(void);
private:
	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);

	tcu::TextureFormat			m_textureFormat;
	VkDeviceSize				m_bufferSize;

	Move<VkBuffer>				m_source;
	de::MovePtr<Allocation>		m_sourceBufferAlloc;
	Move<VkImage>				m_destination;
	de::MovePtr<Allocation>		m_destinationImageAlloc;
};

void CopyBufferToDepthStencil::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
{
	DE_UNREF(mipLevel);

	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
	if (!rowLength)
		rowLength = region.bufferImageCopy.imageExtent.width;

	deUint32			imageHeight = region.bufferImageCopy.bufferImageHeight;
	if (!imageHeight)
		imageHeight = region.bufferImageCopy.imageExtent.height;

	const int			texelSize	= dst.getFormat().getPixelSize();
	const VkExtent3D	extent		= region.bufferImageCopy.imageExtent;
	const VkOffset3D	dstOffset	= region.bufferImageCopy.imageOffset;
	const int			texelOffset = (int)region.bufferImageCopy.bufferOffset / texelSize;

	for (deUint32 z = 0; z < extent.depth; z++)
	{
		for (deUint32 y = 0; y < extent.height; y++)
		{
			int									texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
			const tcu::ConstPixelBufferAccess	srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
			const tcu::PixelBufferAccess		dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
				region.bufferImageCopy.imageExtent.width, 1, 1);

			if (region.bufferImageCopy.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
			{
				tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_DEPTH), DE_FALSE);
			}
			else
			{
				tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_STENCIL), DE_FALSE);
			}
		}
	}
}

bool isSupportedDepthStencilFormat(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
{
	VkFormatProperties formatProps;
	vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
}

CopyBufferToDepthStencil::CopyBufferToDepthStencil(Context& context, TestParams testParams)
	: CopiesAndBlittingTestInstance(context, testParams)
	, m_textureFormat(mapVkFormat(testParams.dst.image.format))
	, m_bufferSize(0)
{
	const InstanceInterface&	vki					= context.getInstanceInterface();
	const DeviceInterface&		vk					= context.getDeviceInterface();
	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
	const VkDevice				vkDevice			= context.getDevice();
	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	Allocator&					memAlloc			= context.getDefaultAllocator();
	const bool					hasDepth			= tcu::hasDepthComponent(mapVkFormat(m_params.dst.image.format).order);
	const bool					hasStencil			= tcu::hasStencilComponent(mapVkFormat(m_params.dst.image.format).order);

	if (!isSupportedDepthStencilFormat(vki, vkPhysDevice, testParams.dst.image.format))
	{
		TCU_THROW(NotSupportedError, "Image format not supported.");
	}

	if (hasDepth)
	{
		glw::GLuint texelSize = m_textureFormat.getPixelSize();
		if (texelSize > sizeof(float))
		{
			// We must have D32F_S8 format, depth must be packed so we only need
			// to allocate space for the D32F part. Stencil will be separate
			texelSize = sizeof(float);
		}
		m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height) * static_cast<VkDeviceSize>(texelSize);
	}
	if (hasStencil)
	{
		// Stencil is always 8bits and packed.
		m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height);
	}

	// Create source buffer, this is where the depth & stencil data will go that's used by test's regions.
	{
		const VkBufferCreateInfo	sourceBufferParams		=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			m_bufferSize,								// VkDeviceSize			size;
			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyIndexCount;
			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
		};

		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
		m_sourceBufferAlloc		= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
	}

	// Create destination image
	{
		const VkImageCreateInfo		destinationImageParams	=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
			m_params.dst.image.imageType,			// VkImageType			imageType;
			m_params.dst.image.format,				// VkFormat				format;
			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
			1u,										// deUint32				mipLevels;
			getArraySize(m_params.dst.image),		// deUint32				arraySize;
			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
		};

		m_destination				= createImage(vk, vkDevice, &destinationImageParams);
		m_destinationImageAlloc		= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
	}
}

tcu::TestStatus CopyBufferToDepthStencil::iterate(void)
{
	// Create source depth/stencil content. Treat as 1D texture to get different pattern
	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
	// Fill buffer with linear gradiant
	generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);

	// Create image layer for depth/stencil
	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
		m_params.dst.image.extent.width,
		m_params.dst.image.extent.height,
		m_params.dst.image.extent.depth));

	// Fill image layer with 2D gradiant
	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);

	// Fill m_extendedTextureLevel with copy of m_destinationTextureLevel
	// Then iterate over each of the regions given in m_params.regions and copy m_sourceTextureLevel content to m_extendedTextureLevel
	// This emulates what the HW will be doing.
	generateExpectedResult();

	// Upload our source depth/stencil content to the source buffer
	// This is the buffer that will be used by region commands
	std::vector<VkBufferImageCopy>		bufferImageCopies;
	std::vector<VkBufferImageCopy2KHR>	bufferImageCopies2KHR;
	VkDeviceSize					bufferOffset	= 0;
	const VkDevice					vkDevice		= m_context.getDevice();
	const DeviceInterface&			vk				= m_context.getDeviceInterface();
	const VkQueue					queue			= m_context.getUniversalQueue();
	char*							dstPtr			= reinterpret_cast<char*>(m_sourceBufferAlloc->getHostPtr());
	bool							depthLoaded		= DE_FALSE;
	bool							stencilLoaded	= DE_FALSE;
	VkDeviceSize					depthOffset		= 0;
	VkDeviceSize					stencilOffset	= 0;

	// To be able to test ordering depth & stencil differently
	// we take the given copy regions and use that as the desired order
	// and copy the appropriate data into place and compute the appropriate
	// data offsets to be used in the copy command.
	for (deUint32 i = 0; i < m_params.regions.size(); i++)
	{
		tcu::ConstPixelBufferAccess bufferAccess	= m_sourceTextureLevel->getAccess();
		deUint32					bufferSize		= bufferAccess.getWidth() * bufferAccess.getHeight() * bufferAccess.getDepth();
		VkBufferImageCopy			copyData		= m_params.regions[i].bufferImageCopy;
		char*						srcPtr;

		if (copyData.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT && !depthLoaded)
		{
			// Create level that is same component as depth buffer (e.g. D16, D24, D32F)
			tcu::TextureLevel	depthTexture(mapCombinedToDepthTransferFormat(bufferAccess.getFormat()), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
			bufferSize *= tcu::getPixelSize(depthTexture.getFormat());
			// Copy depth component only from source data. This gives us packed depth-only data.
			tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_DEPTH));
			srcPtr = (char*)depthTexture.getAccess().getDataPtr();
			// Copy packed depth-only data to output buffer
			deMemcpy(dstPtr, srcPtr, bufferSize);
			depthLoaded = DE_TRUE;
			depthOffset = bufferOffset;
			dstPtr += bufferSize;
			bufferOffset += bufferSize;
			copyData.bufferOffset += depthOffset;
		}
		else if (!stencilLoaded)
		{
			// Create level that is same component as stencil buffer (always 8-bits)
			tcu::TextureLevel	stencilTexture(tcu::getEffectiveDepthStencilTextureFormat(bufferAccess.getFormat(), tcu::Sampler::MODE_STENCIL), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
			// Copy stencil component only from source data. This gives us packed stencil-only data.
			tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_STENCIL));
			srcPtr = (char*)stencilTexture.getAccess().getDataPtr();
			// Copy packed stencil-only data to output buffer
			deMemcpy(dstPtr, srcPtr, bufferSize);
			stencilLoaded = DE_TRUE;
			stencilOffset = bufferOffset;
			dstPtr += bufferSize;
			bufferOffset += bufferSize;

			// Reference image generation uses pixel offsets based on buffer offset.
			// We need to adjust the offset now that the stencil data is not interleaved.
			copyData.bufferOffset /= tcu::getPixelSize(m_textureFormat);

			copyData.bufferOffset += stencilOffset;
		}

		if (m_params.extensionUse == EXTENSION_USE_NONE)
		{
			bufferImageCopies.push_back(copyData);
		}
		else
		{
			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
			bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(copyData));
		}
	}

	flushAlloc(vk, vkDevice, *m_sourceBufferAlloc);

	// Upload the depth/stencil data from m_destinationTextureLevel to initialize
	// depth and stencil to known values.
	// Uses uploadImageAspect so makes its own buffers for depth and stencil
	// aspects (as needed) and copies them with independent vkCmdCopyBufferToImage commands.
	uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);

	const VkImageMemoryBarrier	imageBarrier	=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
		*m_destination,								// VkImage					image;
		{											// VkImageSubresourceRange	subresourceRange;
			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
			0u,								// deUint32				baseMipLevel;
			1u,								// deUint32				mipLevels;
			0u,								// deUint32				baseArraySlice;
			1u								// deUint32				arraySize;
		}
	};

	// Copy from buffer to depth/stencil image

	beginCommandBuffer(vk, *m_cmdBuffer);
	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);

	if (m_params.extensionUse == EXTENSION_USE_NONE)
	{
		if (m_params.singleCommand)
		{
			// Issue a single copy command with regions defined by the test.
			vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
		}
		else
		{
			// Issue a a copy command per region defined by the test.
			for (deUint32 i = 0; i < bufferImageCopies.size(); i++)
			{
				vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopies[i]);
			}
		}
	}
	else
	{
		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);

		if (m_params.singleCommand)
		{
			// Issue a single copy command with regions defined by the test.
			const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
			{
				VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
				DE_NULL,											// const void*					pNext;
				m_source.get(),										// VkBuffer						srcBuffer;
				m_destination.get(),								// VkImage						dstImage;
				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout				dstImageLayout;
				(deUint32)m_params.regions.size(),					// uint32_t						regionCount;
				bufferImageCopies2KHR.data()						// const VkBufferImageCopy2KHR*	pRegions;
			};
			vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
		}
		else
		{
			// Issue a a copy command per region defined by the test.
			for (deUint32 i = 0; i < bufferImageCopies2KHR.size(); i++)
			{
				const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
				{
					VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
					DE_NULL,											// const void*					pNext;
					m_source.get(),										// VkBuffer						srcBuffer;
					m_destination.get(),								// VkImage						dstImage;
					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout				dstImageLayout;
					1,													// uint32_t						regionCount;
					&bufferImageCopies2KHR[i]							// const VkBufferImageCopy2KHR*	pRegions;
				};
				// Issue a single copy command with regions defined by the test.
				vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
			}
		}
	}
	endCommandBuffer(vk, *m_cmdBuffer);

	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);

	de::MovePtr<tcu::TextureLevel>	resultLevel = readImage(*m_destination, m_params.dst.image);

	// For combined depth/stencil formats both aspects are checked even when the test only
	// copies one. Clear such aspects here for both the result and the reference.
	if (tcu::hasDepthComponent(m_textureFormat.order) && !depthLoaded)
	{
		tcu::clearDepth(m_expectedTextureLevel[0]->getAccess(), 0.0f);
		tcu::clearDepth(resultLevel->getAccess(), 0.0f);
	}
	if (tcu::hasStencilComponent(m_textureFormat.order) && !stencilLoaded)
	{
		tcu::clearStencil(m_expectedTextureLevel[0]->getAccess(), 0);
		tcu::clearStencil(resultLevel->getAccess(), 0);
	}

	return checkTestResult(resultLevel->getAccess());
}

class CopyBufferToDepthStencilTestCase : public vkt::TestCase
{
public:
							CopyBufferToDepthStencilTestCase	(tcu::TestContext&		testCtx,
																 const std::string&		name,
																 const std::string&		description,
																 const TestParams		params)
								: vkt::TestCase(testCtx, name, description)
								, m_params(params)
							{}

	virtual					~CopyBufferToDepthStencilTestCase	(void) {}

	virtual TestInstance*	createInstance						(Context&				context) const
							{
								return new CopyBufferToDepthStencil(context, m_params);
							}

	virtual void			checkSupport						(Context&				context) const
							{
								if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
									(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
								{
									TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
								}
							}

private:
	TestParams				m_params;
};

// Copy from image to image with scaling.

class BlittingImages : public CopiesAndBlittingTestInstance
{
public:
										BlittingImages					(Context&	context,
																		 TestParams params);
	virtual tcu::TestStatus				iterate							(void);
protected:
	virtual tcu::TestStatus				checkTestResult					(tcu::ConstPixelBufferAccess result);
	virtual void						copyRegionToTextureLevel		(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
	virtual void						generateExpectedResult			(void);
private:
	bool								checkNonNearestFilteredResult	(const tcu::ConstPixelBufferAccess&	result,
																		 const tcu::ConstPixelBufferAccess&	clampedReference,
																		 const tcu::ConstPixelBufferAccess&	unclampedReference,
																		 const tcu::TextureFormat&			sourceFormat);
	bool								checkNearestFilteredResult		(const tcu::ConstPixelBufferAccess&	result,
																		 const tcu::ConstPixelBufferAccess& source);

	Move<VkImage>						m_source;
	de::MovePtr<Allocation>				m_sourceImageAlloc;
	Move<VkImage>						m_destination;
	de::MovePtr<Allocation>				m_destinationImageAlloc;

	de::MovePtr<tcu::TextureLevel>		m_unclampedExpectedTextureLevel;
};

BlittingImages::BlittingImages (Context& context, TestParams params)
	: CopiesAndBlittingTestInstance(context, params)
{
	const InstanceInterface&	vki					= context.getInstanceInterface();
	const DeviceInterface&		vk					= context.getDeviceInterface();
	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
	const VkDevice				vkDevice			= context.getDevice();
	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	Allocator&					memAlloc			= context.getDefaultAllocator();

	// Create source image
	{
		const VkImageCreateInfo		sourceImageParams		=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
			m_params.src.image.imageType,			// VkImageType			imageType;
			m_params.src.image.format,				// VkFormat				format;
			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
			1u,										// deUint32				mipLevels;
			getArraySize(m_params.src.image),		// deUint32				arraySize;
			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
			m_params.src.image.tiling,				// VkImageTiling		tiling;
			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
		};

		m_source = createImage(vk, vkDevice, &sourceImageParams);
		m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
	}

	// Create destination image
	{
		const VkImageCreateInfo		destinationImageParams	=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
			m_params.dst.image.imageType,			// VkImageType			imageType;
			m_params.dst.image.format,				// VkFormat				format;
			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
			1u,										// deUint32				mipLevels;
			getArraySize(m_params.dst.image),		// deUint32				arraySize;
			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
			m_params.dst.image.tiling,				// VkImageTiling		tiling;
			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
		};

		m_destination = createImage(vk, vkDevice, &destinationImageParams);
		m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
	}
}

tcu::TestStatus BlittingImages::iterate (void)
{
	const tcu::TextureFormat	srcTcuFormat		= mapVkFormat(m_params.src.image.format);
	const tcu::TextureFormat	dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
																				m_params.src.image.extent.width,
																				m_params.src.image.extent.height,
																				m_params.src.image.extent.depth));
	generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, m_params.src.image.fillMode);
	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
																					 (int)m_params.dst.image.extent.width,
																					 (int)m_params.dst.image.extent.height,
																					 (int)m_params.dst.image.extent.depth));
	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, m_params.dst.image.fillMode);
	generateExpectedResult();

	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);

	const DeviceInterface&		vk					= m_context.getDeviceInterface();
	const VkDevice				vkDevice			= m_context.getDevice();
	const VkQueue				queue				= m_context.getUniversalQueue();

	std::vector<VkImageBlit>		regions;
	std::vector<VkImageBlit2KHR>	regions2KHR;
	for (deUint32 i = 0; i < m_params.regions.size(); i++)
	{
		if (m_params.extensionUse == EXTENSION_USE_NONE)
		{
			regions.push_back(m_params.regions[i].imageBlit);
		}
		else
		{
			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
			regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(m_params.regions[i].imageBlit));
		}
	}

	// Barriers for copying image to buffer
	const VkImageMemoryBarrier		srcImageBarrier		=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
		m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
		m_source.get(),								// VkImage					image;
		{											// VkImageSubresourceRange	subresourceRange;
			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
			0u,								// deUint32				baseMipLevel;
			1u,								// deUint32				mipLevels;
			0u,								// deUint32				baseArraySlice;
			1u								// deUint32				arraySize;
		}
	};

	const VkImageMemoryBarrier		dstImageBarrier		=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
		m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
		m_destination.get(),						// VkImage					image;
		{											// VkImageSubresourceRange	subresourceRange;
			getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
			0u,								// deUint32				baseMipLevel;
			1u,								// deUint32				mipLevels;
			0u,								// deUint32				baseArraySlice;
			1u								// deUint32				arraySize;
		}
	};

	beginCommandBuffer(vk, *m_cmdBuffer);
	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);
	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);

	if (m_params.extensionUse == EXTENSION_USE_NONE)
	{
		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);
	}
	else
	{
		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
		const VkBlitImageInfo2KHR BlitImageInfo2KHR =
		{
			VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
			DE_NULL,									// const void*					pNext;
			m_source.get(),								// VkImage						srcImage;
			m_params.src.image.operationLayout,			// VkImageLayout				srcImageLayout;
			m_destination.get(),						// VkImage						dstImage;
			m_params.dst.image.operationLayout,			// VkImageLayout				dstImageLayout;
			(deUint32)m_params.regions.size(),			// uint32_t						regionCount;
			&regions2KHR[0],							// const VkImageBlit2KHR*		pRegions;
			m_params.filter,							// VkFilter						filter;
		};
		vk.cmdBlitImage2KHR(*m_cmdBuffer, &BlitImageInfo2KHR);
	}

	endCommandBuffer(vk, *m_cmdBuffer);
	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);

	de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);

	return checkTestResult(resultTextureLevel->getAccess());
}

static float calculateFloatConversionError (int srcBits)
{
	if (srcBits > 0)
	{
		const int	clampedBits	= de::clamp<int>(srcBits, 0, 32);
		const float	srcMaxValue	= de::max((float)(1ULL<<clampedBits) - 1.0f, 1.0f);
		const float	error		= 1.0f / srcMaxValue;

		return de::clamp<float>(error, 0.0f, 1.0f);
	}
	else
		return 1.0f;
}

tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
{
	tcu::Vec4 threshold(0.01f);

	switch (format.type)
	{
	case tcu::TextureFormat::HALF_FLOAT:
		threshold = tcu::Vec4(0.005f);
		break;

	case tcu::TextureFormat::FLOAT:
	case tcu::TextureFormat::FLOAT64:
		threshold = tcu::Vec4(0.001f);
		break;

	case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
		threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
		break;

	case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
		threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f);
		break;

	case tcu::TextureFormat::UNORM_INT_1010102_REV:
		threshold = tcu::Vec4(0.002f, 0.002f, 0.002f, 0.3f);
		break;

	case tcu:: TextureFormat::UNORM_INT8:
		threshold = tcu::Vec4(0.008f, 0.008f, 0.008f, 0.008f);
		break;

	default:
		const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format);
		threshold = tcu::Vec4(calculateFloatConversionError(bits.x()),
				      calculateFloatConversionError(bits.y()),
				      calculateFloatConversionError(bits.z()),
				      calculateFloatConversionError(bits.w()));
	}

	// Return value matching the channel order specified by the format
	if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
		return threshold.swizzle(2, 1, 0, 3);
	else
		return threshold;
}

bool BlittingImages::checkNonNearestFilteredResult (const tcu::ConstPixelBufferAccess&	result,
													const tcu::ConstPixelBufferAccess&	clampedExpected,
													const tcu::ConstPixelBufferAccess&	unclampedExpected,
													const tcu::TextureFormat&			srcFormat)
{
	tcu::TestLog&					log				(m_context.getTestContext().getLog());
	const tcu::TextureFormat		dstFormat		= result.getFormat();
	const tcu::TextureChannelClass	dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
	const tcu::TextureChannelClass	srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
	bool							isOk			= false;

	log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");

	// if either of srcImage or dstImage stores values as a signed/unsigned integer,
	// the other must also store values a signed/unsigned integer
	// e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
	// despite the fact that both formats are sampled as floats
	bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
							  dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
	bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
							  srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
	if (dstImageIsIntClass != srcImageIsIntClass)
	{
		log << tcu::TestLog::EndSection;
		return false;
	}

	if (isFloatFormat(dstFormat))
	{
		const bool		srcIsSRGB	= tcu::isSRGB(srcFormat);
		const tcu::Vec4	srcMaxDiff	= getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
		const tcu::Vec4	dstMaxDiff	= getFormatThreshold(dstFormat);
		const tcu::Vec4	threshold	= ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f);

		isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
		log << tcu::TestLog::EndSection;

		if (!isOk)
		{
			log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
			isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
			log << tcu::TestLog::EndSection;
		}
	}
	else
	{
		tcu::UVec4	threshold;
		// Calculate threshold depending on channel width of destination format.
		const tcu::IVec4	dstBitDepth	= tcu::getTextureFormatBitDepth(dstFormat);
		const tcu::IVec4	srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
		for (deUint32 i = 0; i < 4; ++i)
			threshold[i] = 1 + de::max( ( ( 1 << dstBitDepth[i] ) - 1 ) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);

		isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
		log << tcu::TestLog::EndSection;

		if (!isOk)
		{
			log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
			isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
			log << tcu::TestLog::EndSection;
		}
	}

	return isOk;
}

//! Utility to encapsulate coordinate computation and loops.
struct CompareEachPixelInEachRegion
{
	virtual		 ~CompareEachPixelInEachRegion  (void) {}
	virtual bool compare								(const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const = 0;

	bool forEach (const void*							pUserData,
				  const std::vector<CopyRegion>&		regions,
				  const int								sourceWidth,
				  const int								sourceHeight,
				  const int								sourceDepth,
				  const tcu::PixelBufferAccess&			errorMask) const
	{
		bool compareOk = true;

		for (std::vector<CopyRegion>::const_iterator regionIter = regions.begin(); regionIter != regions.end(); ++regionIter)
		{
			const VkImageBlit& blit = regionIter->imageBlit;

			const int	xStart	= deMin32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
			const int	yStart	= deMin32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
			const int	zStart	= deMin32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
			const int	xEnd	= deMax32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
			const int	yEnd	= deMax32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
			const int	zEnd	= deMax32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
			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);
			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);
			const float	zScale	= static_cast<float>(blit.srcOffsets[1].z - blit.srcOffsets[0].z) / static_cast<float>(blit.dstOffsets[1].z - blit.dstOffsets[0].z);
			const float srcInvW	= 1.0f / static_cast<float>(sourceWidth);
			const float srcInvH	= 1.0f / static_cast<float>(sourceHeight);
			const float srcInvD	= 1.0f / static_cast<float>(sourceDepth);

			for (int z = zStart; z < zEnd; z++)
			for (int y = yStart; y < yEnd; y++)
			for (int x = xStart; x < xEnd; x++)
			{
				const tcu::Vec3 srcNormCoord
				(
					(xScale * (static_cast<float>(x - blit.dstOffsets[0].x) + 0.5f) + static_cast<float>(blit.srcOffsets[0].x)) * srcInvW,
					(yScale * (static_cast<float>(y - blit.dstOffsets[0].y) + 0.5f) + static_cast<float>(blit.srcOffsets[0].y)) * srcInvH,
					(zScale * (static_cast<float>(z - blit.dstOffsets[0].z) + 0.5f) + static_cast<float>(blit.srcOffsets[0].z)) * srcInvD
				);

				if (!compare(pUserData, x, y, z, srcNormCoord))
				{
					errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
					compareOk = false;
				}
			}
		}
		return compareOk;
	}
};

tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format)
{
	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
	const tcu::IVec4				bitDepth		= tcu::getTextureFormatBitDepth(format);

	if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
	{
		return getFormatThreshold(format);
	}
	else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
			 channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
	{
		const bool	isSigned	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT);
		const float	range		= isSigned ? 1.0f - (-1.0f)
										   : 1.0f -   0.0f;

		tcu::Vec4 v;
		for (int i = 0; i < 4; ++i)
		{
			if (bitDepth[i] == 0)
				v[i] = 1.0f;
			else
				v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
		}
		return v;
	}
	else
	{
		DE_ASSERT(0);
		return tcu::Vec4();
	}
}

bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess&	source,
							  const tcu::ConstPixelBufferAccess&	result,
							  const tcu::PixelBufferAccess&			errorMask,
							  const std::vector<CopyRegion>&		regions)
{
	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);
	tcu::LookupPrecision	precision;

	{
		const tcu::IVec4	dstBitDepth	= tcu::getTextureFormatBitDepth(result.getFormat());
		const tcu::Vec4		srcMaxDiff	= getFloatOrFixedPointFormatThreshold(source.getFormat());
		const tcu::Vec4		dstMaxDiff	= getFloatOrFixedPointFormatThreshold(result.getFormat());

		precision.colorMask		 = tcu::notEqual(dstBitDepth, tcu::IVec4(0));
		precision.colorThreshold = tcu::max(srcMaxDiff, dstMaxDiff);
	}

	const struct Capture
	{
		const tcu::ConstPixelBufferAccess&	source;
		const tcu::ConstPixelBufferAccess&	result;
		const tcu::Sampler&					sampler;
		const tcu::LookupPrecision&			precision;
		const bool							isSRGB;
	} capture =
	{
		source, result, sampler, precision, tcu::isSRGB(result.getFormat())
	};

	const struct Loop : CompareEachPixelInEachRegion
	{
		Loop (void) {}

		bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
		{
			const Capture&					c					= *static_cast<const Capture*>(pUserData);
			const tcu::TexLookupScaleMode	lookupScaleDontCare	= tcu::TEX_LOOKUP_SCALE_MINIFY;
			tcu::Vec4						dstColor			= c.result.getPixel(x, y, z);

			// TexLookupVerifier performs a conversion to linear space, so we have to as well
			if (c.isSRGB)
				dstColor = tcu::sRGBToLinear(dstColor);

			return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
		}
	} loop;

	return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
}

bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess&	source,
							const tcu::ConstPixelBufferAccess&	result,
							const tcu::PixelBufferAccess&		errorMask,
							const std::vector<CopyRegion>&		regions)
{
	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);
	tcu::IntLookupPrecision	precision;

	{
		const tcu::IVec4	srcBitDepth	= tcu::getTextureFormatBitDepth(source.getFormat());
		const tcu::IVec4	dstBitDepth	= tcu::getTextureFormatBitDepth(result.getFormat());

		for (deUint32 i = 0; i < 4; ++i) {
			precision.colorThreshold[i]	= de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1);
			precision.colorMask[i]		= dstBitDepth[i] != 0;
		}
	}

	// Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that
	// does the conversion on the fly without wasting memory, but this approach is more straightforward.
	tcu::TextureLevel				convertedSourceTexture	(result.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
	const tcu::PixelBufferAccess	convertedSource			= convertedSourceTexture.getAccess();

	for (int z = 0; z < source.getDepth();	++z)
	for (int y = 0; y < source.getHeight(); ++y)
	for (int x = 0; x < source.getWidth();  ++x)
		convertedSource.setPixel(source.getPixelInt(x, y, z), x, y, z);	// will be clamped to max. representable value

	const struct Capture
	{
		const tcu::ConstPixelBufferAccess&	source;
		const tcu::ConstPixelBufferAccess&	result;
		const tcu::Sampler&					sampler;
		const tcu::IntLookupPrecision&		precision;
	} capture =
	{
		convertedSource, result, sampler, precision
	};

	const struct Loop : CompareEachPixelInEachRegion
	{
		Loop (void) {}

		bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
		{
			const Capture&					c					= *static_cast<const Capture*>(pUserData);
			const tcu::TexLookupScaleMode	lookupScaleDontCare	= tcu::TEX_LOOKUP_SCALE_MINIFY;
			const tcu::IVec4				dstColor			= c.result.getPixelInt(x, y, z);

			return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
		}
	} loop;

	return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
}

bool BlittingImages::checkNearestFilteredResult (const tcu::ConstPixelBufferAccess&	result,
												 const tcu::ConstPixelBufferAccess& source)
{
	tcu::TestLog&					log				(m_context.getTestContext().getLog());
	const tcu::TextureFormat		dstFormat		= result.getFormat();
	const tcu::TextureFormat		srcFormat		= source.getFormat();
	const tcu::TextureChannelClass	dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
	const tcu::TextureChannelClass	srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);

	tcu::TextureLevel		errorMaskStorage	(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
	tcu::PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
	tcu::Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
	tcu::Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);
	bool					ok					= false;

	tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));

	// if either of srcImage or dstImage stores values as a signed/unsigned integer,
	// the other must also store values a signed/unsigned integer
	// e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
	// despite the fact that both formats are sampled as floats
	bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
							  dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
	bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
							  srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
	if (dstImageIsIntClass != srcImageIsIntClass)
		return false;

	if (dstImageIsIntClass)
	{
		ok = intNearestBlitCompare(source, result, errorMask, m_params.regions);
	}
	else
		ok = floatNearestBlitCompare(source, result, errorMask, m_params.regions);

	if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
		tcu::computePixelScaleBias(result, pixelScale, pixelBias);

	if (!ok)
	{
		log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
			<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
			<< tcu::TestLog::Image("ErrorMask",	"Error mask", errorMask)
			<< tcu::TestLog::EndImageSet;
	}
	else
	{
		log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
			<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
			<< tcu::TestLog::EndImageSet;
	}

	return ok;
}

tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result)
{
	DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
	const std::string failMessage("Result image is incorrect");

	if (m_params.filter != VK_FILTER_NEAREST)
	{
		if (tcu::isCombinedDepthStencilType(result.getFormat().type))
		{
			if (tcu::hasDepthComponent(result.getFormat().order))
			{
				const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
				const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
				const tcu::ConstPixelBufferAccess		clampedExpected		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
				const tcu::ConstPixelBufferAccess		unclampedExpected	= tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
				const tcu::TextureFormat				sourceFormat		= tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);

				if (!checkNonNearestFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat))
					return tcu::TestStatus::fail(failMessage);
			}

			if (tcu::hasStencilComponent(result.getFormat().order))
			{
				const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
				const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
				const tcu::ConstPixelBufferAccess		clampedExpected		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
				const tcu::ConstPixelBufferAccess		unclampedExpected	= tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
				const tcu::TextureFormat				sourceFormat		= tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);

				if (!checkNonNearestFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat))
					return tcu::TestStatus::fail(failMessage);
			}
		}
		else
		{
			const tcu::TextureFormat	sourceFormat	= mapVkFormat(m_params.src.image.format);

			if (!checkNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), sourceFormat))
				return tcu::TestStatus::fail(failMessage);
		}
	}
	else // NEAREST filtering
	{
		if (tcu::isCombinedDepthStencilType(result.getFormat().type))
		{
			if (tcu::hasDepthComponent(result.getFormat().order))
			{
				const tcu::Sampler::DepthStencilMode	mode			= tcu::Sampler::MODE_DEPTH;
				const tcu::ConstPixelBufferAccess		depthResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
				const tcu::ConstPixelBufferAccess		depthSource		= tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);

				if (!checkNearestFilteredResult(depthResult, depthSource))
					return tcu::TestStatus::fail(failMessage);
			}

			if (tcu::hasStencilComponent(result.getFormat().order))
			{
				const tcu::Sampler::DepthStencilMode	mode			= tcu::Sampler::MODE_STENCIL;
				const tcu::ConstPixelBufferAccess		stencilResult	= tcu::getEffectiveDepthStencilAccess(result, mode);
				const tcu::ConstPixelBufferAccess		stencilSource	= tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);

				if (!checkNearestFilteredResult(stencilResult, stencilSource))
					return tcu::TestStatus::fail(failMessage);
			}
		}
		else
		{
			if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess()))
				return tcu::TestStatus::fail(failMessage);
		}
	}

	return tcu::TestStatus::pass("Pass");
}

tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
{
	return isSRGB(format) ? linearToSRGB(color) : color;
}

void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode = 0u)
{
	DE_ASSERT(filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);

	tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
					filter, filter, 0.0f, false);

	float sX = (float)regionExtent.x / (float)dst.getWidth();
	float sY = (float)regionExtent.y / (float)dst.getHeight();
	float sZ = (float)regionExtent.z / (float)dst.getDepth();

	for (int z = 0; z < dst.getDepth(); z++)
	for (int y = 0; y < dst.getHeight(); y++)
	for (int x = 0; x < dst.getWidth(); x++)
	{
		float srcX = ((mirrorMode & MIRROR_MODE_X) != 0) ? (float)regionExtent.x + (float)regionOffset.x - ((float)x+0.5f)*sX : (float)regionOffset.x + ((float)x+0.5f)*sX;
		float srcY = ((mirrorMode & MIRROR_MODE_Y) != 0) ? (float)regionExtent.y + (float)regionOffset.y - ((float)y+0.5f)*sY : (float)regionOffset.y + ((float)y+0.5f)*sY;
		float srcZ = ((mirrorMode & MIRROR_MODE_Z) != 0) ? (float)regionExtent.z + (float)regionOffset.z - ((float)z+0.5f)*sZ : (float)regionOffset.z + ((float)z+0.5f)*sZ;
		if (dst.getDepth() > 1)
			dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, srcX, srcY, srcZ)), x, y, z);
		else
			dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, srcX, srcY, 0)), x, y);
	}
}

void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
{
	DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);

	tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
			filter, filter, 0.0f, false);

	const float sX = (float)src.getWidth() / (float)dst.getWidth();
	const float sY = (float)src.getHeight() / (float)dst.getHeight();
	const float sZ = (float)src.getDepth() / (float)dst.getDepth();

	const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
	const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
	const int zOffset = (mirrorMode & MIRROR_MODE_Z) ? dst.getDepth() - 1 : 0;

	const int xScale = (mirrorMode & MIRROR_MODE_X) ? -1 : 1;
	const int yScale = (mirrorMode & MIRROR_MODE_Y) ? -1 : 1;
	const int zScale = (mirrorMode & MIRROR_MODE_Z) ? -1 : 1;

	for (int z = 0; z < dst.getDepth(); ++z)
	for (int y = 0; y < dst.getHeight(); ++y)
	for (int x = 0; x < dst.getWidth(); ++x)
	{
		dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, ((float)x + 0.5f) * sX, ((float)y + 0.5f) * sY, ((float)z + 0.5f) * sZ)), x * xScale + xOffset, y * yScale + yOffset, z * zScale + zOffset);
	}
}

void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode)
{
	const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
	const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
	const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
	const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];

	if (mirrorMode != 0u)
	{
		//sourceRegion
		region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
		region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
		region.imageBlit.srcOffsets[0].z = std::min(srcOffset0.z, srcOffset1.z);

		region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
		region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
		region.imageBlit.srcOffsets[1].z = std::max(srcOffset0.z, srcOffset1.z);

		//destinationRegion
		region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
		region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
		region.imageBlit.dstOffsets[0].z = std::min(dstOffset0.z, dstOffset1.z);

		region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
		region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
		region.imageBlit.dstOffsets[1].z = std::max(dstOffset0.z, dstOffset1.z);
	}
}

// Mirror X, Y and Z as required by the offset values in the 3 axes.
MirrorMode getMirrorMode(const VkOffset3D from, const VkOffset3D to)
{
	MirrorMode mode = 0u;

	if (from.x > to.x)
		mode |= MIRROR_MODE_X;

	if (from.y > to.y)
		mode |= MIRROR_MODE_Y;

	if (from.z > to.z)
		mode |= MIRROR_MODE_Z;

	return mode;
}

// Mirror the axes that are mirrored either in the source or destination, but not both.
MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
{
	static const MirrorModeBits kBits[] = { MIRROR_MODE_X, MIRROR_MODE_Y, MIRROR_MODE_Z };

	const MirrorMode source		 = getMirrorMode(s1, s2);
	const MirrorMode destination = getMirrorMode(d1, d2);

	MirrorMode mode = 0u;

	for (int i = 0; i < DE_LENGTH_OF_ARRAY(kBits); ++i)
	{
		const MirrorModeBits bit = kBits[i];
		if ((source & bit) != (destination & bit))
			mode |= bit;
	}

	return mode;
}

void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
{
	DE_UNREF(mipLevel);

	const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
												region.imageBlit.srcOffsets[1],
												region.imageBlit.dstOffsets[0],
												region.imageBlit.dstOffsets[1]);

	flipCoordinates(region, mirrorMode);

	const VkOffset3D					srcOffset		= region.imageBlit.srcOffsets[0];
	const VkOffset3D					srcExtent		=
	{
		region.imageBlit.srcOffsets[1].x - srcOffset.x,
		region.imageBlit.srcOffsets[1].y - srcOffset.y,
		region.imageBlit.srcOffsets[1].z - srcOffset.z,
	};
	const VkOffset3D					dstOffset		= region.imageBlit.dstOffsets[0];
	const VkOffset3D					dstExtent		=
	{
		region.imageBlit.dstOffsets[1].x - dstOffset.x,
		region.imageBlit.dstOffsets[1].y - dstOffset.y,
		region.imageBlit.dstOffsets[1].z - dstOffset.z,
	};

	tcu::Sampler::FilterMode		filter;
	switch (m_params.filter)
	{
		case VK_FILTER_LINEAR:		filter = tcu::Sampler::LINEAR; break;
		case VK_FILTER_CUBIC_EXT:	filter = tcu::Sampler::CUBIC;  break;
		case VK_FILTER_NEAREST:
		default:					filter = tcu::Sampler::NEAREST;  break;
	}

	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
	{
		DE_ASSERT(src.getFormat() == dst.getFormat());

		// Scale depth.
		if (tcu::hasDepthComponent(src.getFormat().order))
		{
			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_DEPTH);
			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_DEPTH);
			tcu::scale(dstSubRegion, srcSubRegion, filter);

			if (filter != tcu::Sampler::NEAREST)
			{
				const tcu::ConstPixelBufferAccess	depthSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_DEPTH);
				scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter, mirrorMode);
			}
		}

		// Scale stencil.
		if (tcu::hasStencilComponent(src.getFormat().order))
		{
			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_STENCIL);
			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_STENCIL);
			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);

			if (filter != tcu::Sampler::NEAREST)
			{
				const tcu::ConstPixelBufferAccess	stencilSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_STENCIL);
				scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter, mirrorMode);
			}
		}
	}
	else
	{
		const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z);
		const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
		blit(dstSubRegion, srcSubRegion, filter, mirrorMode);

		if (filter != tcu::Sampler::NEAREST)
		{
			const tcu::PixelBufferAccess	unclampedSubRegion	= tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
			scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter, mirrorMode);
		}
	}
}

void BlittingImages::generateExpectedResult (void)
{
	const tcu::ConstPixelBufferAccess	src	= m_sourceTextureLevel->getAccess();
	const tcu::ConstPixelBufferAccess	dst	= m_destinationTextureLevel->getAccess();

	m_expectedTextureLevel[0]		= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
	tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);

	if (m_params.filter != VK_FILTER_NEAREST)
	{
		m_unclampedExpectedTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
		tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst);
	}

	for (deUint32 i = 0; i < m_params.regions.size(); i++)
	{
		CopyRegion region = m_params.regions[i];
		copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), region);
	}
}

class BlitImageTestCase : public vkt::TestCase
{
public:
							BlitImageTestCase		(tcu::TestContext&				testCtx,
													 const std::string&				name,
													 const std::string&				description,
													 const TestParams				params)
								: vkt::TestCase	(testCtx, name, description)
								, m_params		(params)
	{}

	virtual TestInstance*	createInstance			(Context&						context) const
	{
		return new BlittingImages(context, m_params);
	}

	virtual void			checkSupport			(Context&						context) const
	{
		VkImageFormatProperties properties;
		if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
																					m_params.src.image.format,
																					m_params.src.image.imageType,
																					m_params.src.image.tiling,
																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
																					0,
																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
			(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
																					m_params.dst.image.format,
																					m_params.dst.image.imageType,
																					m_params.dst.image.tiling,
																					VK_IMAGE_USAGE_TRANSFER_DST_BIT,
																					0,
																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
		{
			TCU_THROW(NotSupportedError, "Format not supported");
		}

		VkFormatProperties srcFormatProperties;
		context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties);
		VkFormatFeatureFlags srcFormatFeatures = m_params.src.image.tiling == VK_IMAGE_TILING_LINEAR ? srcFormatProperties.linearTilingFeatures : srcFormatProperties.optimalTilingFeatures;
		if (!(srcFormatFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
		{
			TCU_THROW(NotSupportedError, "Format feature blit source not supported");
		}

		VkFormatProperties dstFormatProperties;
		context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties);
		VkFormatFeatureFlags dstFormatFeatures = m_params.dst.image.tiling == VK_IMAGE_TILING_LINEAR ? dstFormatProperties.linearTilingFeatures : dstFormatProperties.optimalTilingFeatures;
		if (!(dstFormatFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
		{
			TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
		}

		if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
		{
			TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
		}

		if (m_params.filter == VK_FILTER_CUBIC_EXT)
		{
			context.requireDeviceFunctionality("VK_EXT_filter_cubic");

			if (!(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
			{
				TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
			}
		}

		if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
		{
			if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
			{
				TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
			}
		}
	}

private:
	TestParams				m_params;
};

class BlittingMipmaps : public CopiesAndBlittingTestInstance
{
public:
										BlittingMipmaps					(Context&   context,
																		 TestParams params);
	virtual tcu::TestStatus				iterate							(void);
protected:
	virtual tcu::TestStatus				checkTestResult					(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
	virtual void						copyRegionToTextureLevel		(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
	virtual void						generateExpectedResult			(void);
private:
	bool								checkNonNearestFilteredResult	(void);
	bool								checkNearestFilteredResult		(void);

	Move<VkImage>						m_source;
	de::MovePtr<Allocation>				m_sourceImageAlloc;
	Move<VkImage>						m_destination;
	de::MovePtr<Allocation>				m_destinationImageAlloc;

	de::MovePtr<tcu::TextureLevel>		m_unclampedExpectedTextureLevel[16];
};

BlittingMipmaps::BlittingMipmaps (Context& context, TestParams params)
	: CopiesAndBlittingTestInstance (context, params)
{
	const InstanceInterface&	vki					= context.getInstanceInterface();
	const DeviceInterface&		vk					= context.getDeviceInterface();
	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
	const VkDevice				vkDevice			= context.getDevice();
	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	Allocator&					memAlloc			= context.getDefaultAllocator();

	// Create source image
	{
		const VkImageCreateInfo		sourceImageParams		=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
			m_params.src.image.imageType,			// VkImageType			imageType;
			m_params.src.image.format,				// VkFormat				format;
			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
			1u,										// deUint32				mipLevels;
			getArraySize(m_params.src.image),		// deUint32				arraySize;
			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
		};

		m_source = createImage(vk, vkDevice, &sourceImageParams);
		m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
	}

	// Create destination image
	{
		const VkImageCreateInfo		destinationImageParams  =
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
			m_params.dst.image.imageType,			// VkImageType			imageType;
			m_params.dst.image.format,				// VkFormat				format;
			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
			m_params.mipLevels,						// deUint32				mipLevels;
			getArraySize(m_params.dst.image),		// deUint32				arraySize;
			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
		};

		m_destination = createImage(vk, vkDevice, &destinationImageParams);
		m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
	}
}

tcu::TestStatus BlittingMipmaps::iterate (void)
{
	const tcu::TextureFormat	srcTcuFormat		= mapVkFormat(m_params.src.image.format);
	const tcu::TextureFormat	dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
																				m_params.src.image.extent.width,
																				m_params.src.image.extent.height,
																				m_params.src.image.extent.depth));
	generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, m_params.src.image.fillMode);
	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
																						(int)m_params.dst.image.extent.width,
																						(int)m_params.dst.image.extent.height,
																						(int)m_params.dst.image.extent.depth));
	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, m_params.dst.image.fillMode);
	generateExpectedResult();

	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);

	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);

	const DeviceInterface&		vk					= m_context.getDeviceInterface();
	const VkDevice				vkDevice			= m_context.getDevice();
	const VkQueue				queue				= m_context.getUniversalQueue();

	std::vector<VkImageBlit>		regions;
	std::vector<VkImageBlit2KHR>	regions2KHR;
	for (deUint32 i = 0; i < m_params.regions.size(); i++)
	{
		if (m_params.extensionUse == EXTENSION_USE_NONE)
		{
			regions.push_back(m_params.regions[i].imageBlit);
		}
		else
		{
			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
			regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(m_params.regions[i].imageBlit));
		}
	}

	// Copy source image to mip level 0 when generating mipmaps with multiple blit commands
	if (!m_params.singleCommand)
		uploadImage(m_sourceTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, 1u);

	beginCommandBuffer(vk, *m_cmdBuffer);

	// Blit all mip levels with a single blit command
	if (m_params.singleCommand)
	{
		{
			// Source image layout
			const VkImageMemoryBarrier		srcImageBarrier		=
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
				DE_NULL,									// const void*				pNext;
				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
				m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
				m_source.get(),								// VkImage					image;
				{											// VkImageSubresourceRange	subresourceRange;
					getAspectFlags(srcTcuFormat),		// VkImageAspectFlags   aspectMask;
					0u,									// deUint32				baseMipLevel;
					1u,									// deUint32				mipLevels;
					0u,									// deUint32				baseArraySlice;
					getArraySize(m_params.src.image)	// deUint32				arraySize;
				}
			};

			// Destination image layout
			const VkImageMemoryBarrier		dstImageBarrier		=
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
				DE_NULL,									// const void*				pNext;
				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
				m_destination.get(),						// VkImage					image;
				{											// VkImageSubresourceRange	subresourceRange;
					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags   aspectMask;
					0u,									// deUint32				baseMipLevel;
					m_params.mipLevels,					// deUint32				mipLevels;
					0u,									// deUint32				baseArraySlice;
					getArraySize(m_params.dst.image)	// deUint32				arraySize;
				}
			};

			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);
			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);

			if (m_params.extensionUse == EXTENSION_USE_NONE)
			{
				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);
			}
			else
			{
				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
				const VkBlitImageInfo2KHR BlitImageInfo2KHR =
				{
					VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
					DE_NULL,									// const void*					pNext;
					m_source.get(),								// VkImage						srcImage;
					m_params.src.image.operationLayout,			// VkImageLayout				srcImageLayout;
					m_destination.get(),						// VkImage						dstImage;
					m_params.dst.image.operationLayout,			// VkImageLayout				dstImageLayout;
					(deUint32)m_params.regions.size(),			// uint32_t						regionCount;
					&regions2KHR[0],							// const VkImageBlit2KHR*		pRegions;
					m_params.filter								// VkFilter						filter;
				};
				vk.cmdBlitImage2KHR(*m_cmdBuffer, &BlitImageInfo2KHR);
			}
		}
	}
	// Blit mip levels with multiple blit commands
	else
	{
		// Prepare all mip levels for reading
		{
			for (deUint32 barrierno = 0; barrierno < m_params.barrierCount; barrierno++)
			{
				VkImageMemoryBarrier preImageBarrier =
				{
					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,									// VkStructureType	sType;
					DE_NULL,																// const void*		pNext;
					VK_ACCESS_TRANSFER_WRITE_BIT,											// VkAccessFlags	srcAccessMask;
					VK_ACCESS_TRANSFER_READ_BIT,											// VkAccessFlags	dstAccessMask;
					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,									// VkImageLayout	oldLayout;
					m_params.src.image.operationLayout,										// VkImageLayout	newLayout;
					VK_QUEUE_FAMILY_IGNORED,												// deUint32			srcQueueFamilyIndex;
					VK_QUEUE_FAMILY_IGNORED,												// deUint32			dstQueueFamilyIndex;
					m_destination.get(),													// VkImage			image;
					{																		// VkImageSubresourceRange	subresourceRange;
						getAspectFlags(dstTcuFormat),										// VkImageAspectFlags	aspectMask;
							0u,																// deUint32				baseMipLevel;
							VK_REMAINING_MIP_LEVELS,										// deUint32				mipLevels;
							0u,																// deUint32				baseArraySlice;
							getArraySize(m_params.src.image)								// deUint32				arraySize;
					}
				};

				if (getArraySize(m_params.src.image) == 1)
				{
					DE_ASSERT(barrierno < m_params.mipLevels);
					preImageBarrier.subresourceRange.baseMipLevel	= barrierno;
					preImageBarrier.subresourceRange.levelCount		= (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_MIP_LEVELS;
				}
				else
				{
					preImageBarrier.subresourceRange.baseArrayLayer	= barrierno;
					preImageBarrier.subresourceRange.layerCount		= (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_ARRAY_LAYERS;
				}
				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);
			}
		}

		for (deUint32 regionNdx = 0u; regionNdx < (deUint32)m_params.regions.size(); regionNdx++)
		{
			const deUint32	mipLevel	= m_params.regions[regionNdx].imageBlit.dstSubresource.mipLevel;

			// Prepare single mip level for writing
			const VkImageMemoryBarrier		preImageBarrier		=
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
				DE_NULL,									// const void*					pNext;
				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
				m_params.src.image.operationLayout,			// VkImageLayout			oldLayout;
				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
				m_destination.get(),						// VkImage					image;
				{											// VkImageSubresourceRange	subresourceRange;
					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
					mipLevel,							// deUint32				baseMipLevel;
					1u,									// deUint32				mipLevels;
					0u,									// deUint32				baseArraySlice;
					getArraySize(m_params.dst.image)	// deUint32				arraySize;
				}
			};

			// Prepare single mip level for reading
			const VkImageMemoryBarrier		postImageBarrier	=
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
				DE_NULL,									// const void*				pNext;
				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
				m_params.dst.image.operationLayout,			// VkImageLayout			oldLayout;
				m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
				m_destination.get(),						// VkImage					image;
				{											// VkImageSubresourceRange	subresourceRange;
					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
					mipLevel,							// deUint32				baseMipLevel;
					1u,									// deUint32				mipLevels;
					0u,									// deUint32				baseArraySlice;
					getArraySize(m_params.src.image)	// deUint32				arraySize;
				}
			};

			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);

			if (m_params.extensionUse == EXTENSION_USE_NONE)
			{
				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);
			}
			else
			{
				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
				const VkBlitImageInfo2KHR BlitImageInfo2KHR =
				{
					VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
					DE_NULL,									// const void*					pNext;
					m_destination.get(),						// VkImage						srcImage;
					m_params.src.image.operationLayout,			// VkImageLayout				srcImageLayout;
					m_destination.get(),						// VkImage						dstImage;
					m_params.dst.image.operationLayout,			// VkImageLayout				dstImageLayout;
					1u,											// uint32_t						regionCount;
					&regions2KHR[regionNdx],					// const VkImageBlit2KHR*		pRegions;
					m_params.filter								// VkFilter						filter;
				};
				vk.cmdBlitImage2KHR(*m_cmdBuffer, &BlitImageInfo2KHR);
			}

			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);
		}

		// Prepare all mip levels for writing
		{
			const VkImageMemoryBarrier		postImageBarrier		=
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
				DE_NULL,									// const void*				pNext;
				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
				m_params.src.image.operationLayout,			// VkImageLayout			oldLayout;
				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
				m_destination.get(),						// VkImage					image;
				{											// VkImageSubresourceRange	subresourceRange;
					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
					0u,									// deUint32				baseMipLevel;
					VK_REMAINING_MIP_LEVELS,			// deUint32				mipLevels;
					0u,									// deUint32				baseArraySlice;
					getArraySize(m_params.dst.image)	// deUint32				arraySize;
				}
			};

			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);
		}
	}

	endCommandBuffer(vk, *m_cmdBuffer);
	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);

	return checkTestResult();
}

bool BlittingMipmaps::checkNonNearestFilteredResult (void)
{
	tcu::TestLog&				log				(m_context.getTestContext().getLog());
	bool						allLevelsOk		= true;

	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
	{
		// Update reference results with previous results that have been verified.
		// This needs to be done such that accumulated errors don't exceed the fixed threshold.
		for (deUint32 i = 0; i < m_params.regions.size(); i++)
		{
			const CopyRegion region = m_params.regions[i];
			const deUint32 srcMipLevel = m_params.regions[i].imageBlit.srcSubresource.mipLevel;
			const deUint32 dstMipLevel = m_params.regions[i].imageBlit.dstSubresource.mipLevel;
			de::MovePtr<tcu::TextureLevel>	prevResultLevel;
			tcu::ConstPixelBufferAccess src;
			if (srcMipLevel < mipLevelNdx)
			{
				// Generate expected result from rendered result that was previously verified
				prevResultLevel	= readImage(*m_destination, m_params.dst.image, srcMipLevel);
				src = prevResultLevel->getAccess();
			}
			else
			{
				// Previous reference mipmaps might have changed, so recompute expected result
				src = m_expectedTextureLevel[srcMipLevel]->getAccess();
			}
			copyRegionToTextureLevel(src, m_expectedTextureLevel[dstMipLevel]->getAccess(), region, dstMipLevel);
		}

		de::MovePtr<tcu::TextureLevel>			resultLevel			= readImage(*m_destination, m_params.dst.image, mipLevelNdx);
		const tcu::ConstPixelBufferAccess&		resultAccess		= resultLevel->getAccess();

		const tcu::Sampler::DepthStencilMode	mode				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::Sampler::MODE_DEPTH :
																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
																																	tcu::Sampler::MODE_LAST;
		const tcu::ConstPixelBufferAccess		result				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(resultAccess, mode) :
																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
																																	resultAccess;
		const tcu::ConstPixelBufferAccess		clampedLevel		= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
																																	m_expectedTextureLevel[mipLevelNdx]->getAccess();
		const tcu::ConstPixelBufferAccess		unclampedLevel		= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
																																	m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess();
		const tcu::TextureFormat				srcFormat			= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
																																	mapVkFormat(m_params.src.image.format);

		const tcu::TextureFormat				dstFormat			= result.getFormat();
		bool									singleLevelOk		= false;
		std::vector <CopyRegion>				mipLevelRegions;

		for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
			if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
				mipLevelRegions.push_back(m_params.regions.at(regionNdx));

		log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");

		if (isFloatFormat(dstFormat))
		{
			const bool		srcIsSRGB   = tcu::isSRGB(srcFormat);
			const tcu::Vec4 srcMaxDiff  = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
			const tcu::Vec4 dstMaxDiff  = getFormatThreshold(dstFormat);
			const tcu::Vec4 threshold   = ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT)? 1.5f : 1.0f);

			singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
			log << tcu::TestLog::EndSection;

			if (!singleLevelOk)
			{
				log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
				singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
				log << tcu::TestLog::EndSection;
			}
		}
		else
		{
			tcu::UVec4  threshold;
			// Calculate threshold depending on channel width of destination format.
			const tcu::IVec4	dstBitDepth	= tcu::getTextureFormatBitDepth(dstFormat);
			const tcu::IVec4	srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
			for (deUint32 i = 0; i < 4; ++i)
				threshold[i] = 1 + de::max(((1 << dstBitDepth[i]) - 1) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);

			singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
			log << tcu::TestLog::EndSection;

			if (!singleLevelOk)
			{
				log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
				singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
				log << tcu::TestLog::EndSection;
			}
		}
		allLevelsOk &= singleLevelOk;
	}

	return allLevelsOk;
}

bool BlittingMipmaps::checkNearestFilteredResult (void)
{
	bool						allLevelsOk		= true;
	tcu::TestLog&				log				(m_context.getTestContext().getLog());

	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
	{
		de::MovePtr<tcu::TextureLevel>			resultLevel			= readImage(*m_destination, m_params.dst.image, mipLevelNdx);
		const tcu::ConstPixelBufferAccess&		resultAccess		= resultLevel->getAccess();

		const tcu::Sampler::DepthStencilMode	mode				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::Sampler::MODE_DEPTH :
																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
																																	tcu::Sampler::MODE_LAST;
		const tcu::ConstPixelBufferAccess		result				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(resultAccess, mode) :
																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
																																	resultAccess;
		const tcu::ConstPixelBufferAccess		source				= (m_params.singleCommand || mipLevelNdx == 0) ?			//  Read from source image
																	  tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
																																	m_sourceTextureLevel->getAccess()
																																//  Read from destination image
																	: tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
																																	m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess();
		const tcu::TextureFormat				dstFormat			= result.getFormat();
		const tcu::TextureChannelClass			dstChannelClass		= tcu::getTextureChannelClass(dstFormat.type);
		bool									singleLevelOk		= false;
		std::vector <CopyRegion>				mipLevelRegions;

		for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
			if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
				mipLevelRegions.push_back(m_params.regions.at(regionNdx));

		tcu::TextureLevel				errorMaskStorage	(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
		tcu::PixelBufferAccess			errorMask			= errorMaskStorage.getAccess();
		tcu::Vec4						pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
		tcu::Vec4						pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);

		tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));

		if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
			dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
		{
			singleLevelOk = intNearestBlitCompare(source, result, errorMask, mipLevelRegions);
		}
		else
			singleLevelOk = floatNearestBlitCompare(source, result, errorMask, mipLevelRegions);

		if (dstFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
			tcu::computePixelScaleBias(result, pixelScale, pixelBias);

		if (!singleLevelOk)
		{
			log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
				<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
				<< tcu::TestLog::Image("Reference", "Reference", source, pixelScale, pixelBias)
				<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
				<< tcu::TestLog::EndImageSet;
		}
		else
		{
			log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
				<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
				<< tcu::TestLog::EndImageSet;
		}

		allLevelsOk &= singleLevelOk;
	}

	return allLevelsOk;
}

tcu::TestStatus BlittingMipmaps::checkTestResult (tcu::ConstPixelBufferAccess result)
{
	DE_UNREF(result);
	DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
	const std::string failMessage("Result image is incorrect");

	if (m_params.filter != VK_FILTER_NEAREST)
	{
		if (!checkNonNearestFilteredResult())
			return tcu::TestStatus::fail(failMessage);
	}
	else // NEAREST filtering
	{
		if (!checkNearestFilteredResult())
			return tcu::TestStatus::fail(failMessage);
	}

	return tcu::TestStatus::pass("Pass");
}

void BlittingMipmaps::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
{
	DE_ASSERT(src.getDepth() == dst.getDepth());

	const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
												region.imageBlit.srcOffsets[1],
												region.imageBlit.dstOffsets[0],
												region.imageBlit.dstOffsets[1]);

	flipCoordinates(region, mirrorMode);

	const VkOffset3D					srcOffset		= region.imageBlit.srcOffsets[0];
	const VkOffset3D					srcExtent		=
	{
		region.imageBlit.srcOffsets[1].x - srcOffset.x,
		region.imageBlit.srcOffsets[1].y - srcOffset.y,
		region.imageBlit.srcOffsets[1].z - srcOffset.z
	};
	const VkOffset3D					dstOffset		= region.imageBlit.dstOffsets[0];
	const VkOffset3D					dstExtent		=
	{
		region.imageBlit.dstOffsets[1].x - dstOffset.x,
		region.imageBlit.dstOffsets[1].y - dstOffset.y,
		region.imageBlit.dstOffsets[1].z - dstOffset.z
	};

	tcu::Sampler::FilterMode		filter;
	switch (m_params.filter)
	{
	case VK_FILTER_LINEAR:		filter = tcu::Sampler::LINEAR; break;
	case VK_FILTER_CUBIC_EXT:	filter = tcu::Sampler::CUBIC;  break;
	case VK_FILTER_NEAREST:
	default:					filter = tcu::Sampler::NEAREST;  break;
	}

	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
	{
		DE_ASSERT(src.getFormat() == dst.getFormat());
		// Scale depth.
		if (tcu::hasDepthComponent(src.getFormat().order))
		{
			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
			tcu::scale(dstSubRegion, srcSubRegion, filter);

			if (filter != tcu::Sampler::NEAREST)
			{
				const tcu::ConstPixelBufferAccess	depthSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
				scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
			}
		}

		// Scale stencil.
		if (tcu::hasStencilComponent(src.getFormat().order))
		{
			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);

			if (filter != tcu::Sampler::NEAREST)
			{
				const tcu::ConstPixelBufferAccess	stencilSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
				scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
			}
		}
	}
	else
	{
		for (int layerNdx = 0u; layerNdx < src.getDepth(); layerNdx++)
		{
			const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y, layerNdx, srcExtent.x, srcExtent.y, 1);
			const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);

			if (filter != tcu::Sampler::NEAREST)
			{
				const tcu::PixelBufferAccess	unclampedSubRegion	= tcu::getSubregion(m_unclampedExpectedTextureLevel[mipLevel]->getAccess(), dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
				scaleFromWholeSrcBuffer(unclampedSubRegion, srcSubRegion, srcOffset, srcExtent, filter);
			}
		}
	}
}

void BlittingMipmaps::generateExpectedResult (void)
{
	const tcu::ConstPixelBufferAccess	src	= m_sourceTextureLevel->getAccess();
	const tcu::ConstPixelBufferAccess	dst	= m_destinationTextureLevel->getAccess();

	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
		m_expectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));

	tcu::copy(m_expectedTextureLevel[0]->getAccess(), src);

	if (m_params.filter != VK_FILTER_NEAREST)
	{
		for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
			m_unclampedExpectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));

		tcu::copy(m_unclampedExpectedTextureLevel[0]->getAccess(), src);
	}

	for (deUint32 i = 0; i < m_params.regions.size(); i++)
	{
		CopyRegion region = m_params.regions[i];
		copyRegionToTextureLevel(m_expectedTextureLevel[m_params.regions[i].imageBlit.srcSubresource.mipLevel]->getAccess(), m_expectedTextureLevel[m_params.regions[i].imageBlit.dstSubresource.mipLevel]->getAccess(), region, m_params.regions[i].imageBlit.dstSubresource.mipLevel);
	}
}

class BlitMipmapTestCase : public vkt::TestCase
{
public:
							BlitMipmapTestCase		(tcu::TestContext&				testCtx,
													 const std::string&				name,
													 const std::string&				description,
													 const TestParams				params)
								: vkt::TestCase	(testCtx, name, description)
								, m_params		(params)
	{}

	virtual TestInstance*	createInstance			(Context&						context) const
	{
		return new BlittingMipmaps(context, m_params);
	}

	virtual void			checkSupport			(Context&						context) const
	{
		const InstanceInterface&	vki					= context.getInstanceInterface();
		const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
		{
			VkImageFormatProperties	properties;
			if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
																						m_params.src.image.format,
																						VK_IMAGE_TYPE_2D,
																						VK_IMAGE_TILING_OPTIMAL,
																						VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
																						0,
																						&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
			{
				TCU_THROW(NotSupportedError, "Format not supported");
			}
			else if ((m_params.src.image.extent.width	> properties.maxExtent.width)	||
						(m_params.src.image.extent.height	> properties.maxExtent.height)	||
						(m_params.src.image.extent.depth	> properties.maxArrayLayers))
			{
				TCU_THROW(NotSupportedError, "Image size not supported");
			}
		}

		{
			VkImageFormatProperties	properties;
			if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
																						m_params.dst.image.format,
																						VK_IMAGE_TYPE_2D,
																						VK_IMAGE_TILING_OPTIMAL,
																						VK_IMAGE_USAGE_TRANSFER_DST_BIT,
																						0,
																						&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
			{
				TCU_THROW(NotSupportedError, "Format not supported");
			}
			else if ((m_params.dst.image.extent.width	> properties.maxExtent.width)	||
						(m_params.dst.image.extent.height	> properties.maxExtent.height)	||
						(m_params.dst.image.extent.depth	> properties.maxArrayLayers))
			{
				TCU_THROW(NotSupportedError, "Image size not supported");
			}
			else if (m_params.mipLevels > properties.maxMipLevels)
			{
				TCU_THROW(NotSupportedError, "Number of mip levels not supported");
			}
			else if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)	&&
					 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
			{
				TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
			}
		}

		const VkFormatProperties	srcFormatProperties	= getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.src.image.format);
		if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
		{
			TCU_THROW(NotSupportedError, "Format feature blit source not supported");
		}

		const VkFormatProperties	dstFormatProperties	= getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.dst.image.format);
		if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
		{
			TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
		}

		if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
			TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");

		if (m_params.filter == VK_FILTER_CUBIC_EXT)
		{
			context.requireDeviceFunctionality("VK_EXT_filter_cubic");

			if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
			{
				TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
			}
		}
	}

private:
	TestParams				m_params;
};

// Resolve image to image.

enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION, COPY_MS_IMAGE_TO_MS_IMAGE, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE};
class ResolveImageToImage : public CopiesAndBlittingTestInstance
{
public:
												ResolveImageToImage			(Context&							context,
																			 TestParams							params,
																			 const ResolveImageToImageOptions	options);
	virtual tcu::TestStatus						iterate						(void);
protected:
	virtual tcu::TestStatus						checkTestResult				(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
	void										copyMSImageToMSImage		(deUint32 copyArraySize);
	tcu::TestStatus								checkIntermediateCopy		(void);
private:
	Move<VkImage>								m_multisampledImage;
	de::MovePtr<Allocation>						m_multisampledImageAlloc;

	Move<VkImage>								m_destination;
	de::MovePtr<Allocation>						m_destinationImageAlloc;

	Move<VkImage>								m_multisampledCopyImage;
	de::MovePtr<Allocation>						m_multisampledCopyImageAlloc;

	const ResolveImageToImageOptions			m_options;

	virtual void								copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess	src,
																			 tcu::PixelBufferAccess			dst,
																			 CopyRegion						region,
																			 deUint32						mipLevel = 0u);
};

ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options)
	: CopiesAndBlittingTestInstance	(context, params)
	, m_options						(options)
{
	const InstanceInterface&	vki						= m_context.getInstanceInterface();
	const DeviceInterface&		vk						= m_context.getDeviceInterface();
	const VkPhysicalDevice		vkPhysDevice			= m_context.getPhysicalDevice();
	const VkDevice				vkDevice				= m_context.getDevice();
	const deUint32				queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	Allocator&					memAlloc				= m_context.getDefaultAllocator();

	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
	Move<VkRenderPass>			renderPass;

	Move<VkShaderModule>		vertexShaderModule		= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
	Move<VkShaderModule>		fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
	std::vector<tcu::Vec4>		vertices;

	Move<VkBuffer>				vertexBuffer;
	de::MovePtr<Allocation>		vertexBufferAlloc;

	Move<VkPipelineLayout>		pipelineLayout;
	Move<VkPipeline>			graphicsPipeline;

	const VkSampleCountFlagBits	rasterizationSamples	= m_params.samples;

	// Create color image.
	{
		VkImageCreateInfo	colorImageParams	=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
			DE_NULL,																// const void*				pNext;
			getCreateFlags(m_params.src.image),										// VkImageCreateFlags		flags;
			m_params.src.image.imageType,											// VkImageType				imageType;
			m_params.src.image.format,												// VkFormat					format;
			getExtent3D(m_params.src.image),										// VkExtent3D				extent;
			1u,																		// deUint32					mipLevels;
			getArraySize(m_params.src.image),										// deUint32					arrayLayers;
			rasterizationSamples,													// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT										// VkImageUsageFlags		usage;
				| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
				| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
			1u,																		// deUint32					queueFamilyIndexCount;
			&queueFamilyIndex,														// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout			initialLayout;
		};

		m_multisampledImage						= createImage(vk, vkDevice, &colorImageParams);

		// Allocate and bind color image memory.
		m_multisampledImageAlloc				= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), m_multisampledImageAlloc->getOffset()));

		switch (m_options)
		{
			case COPY_MS_IMAGE_TO_MS_IMAGE:
			{
				colorImageParams.usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
				m_multisampledCopyImage			= createImage(vk, vkDevice, &colorImageParams);
				// Allocate and bind color image memory.
				m_multisampledCopyImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
				break;
			}

			case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
			{
				colorImageParams.usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
				colorImageParams.arrayLayers	= getArraySize(m_params.dst.image);
				m_multisampledCopyImage			= createImage(vk, vkDevice, &colorImageParams);
				// Allocate and bind color image memory.
				m_multisampledCopyImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
				break;
			}

			default :
				break;
		}
	}

	// Create destination image.
	{
		const VkImageCreateInfo	destinationImageParams	=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
			m_params.dst.image.imageType,			// VkImageType			imageType;
			m_params.dst.image.format,				// VkFormat				format;
			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
			1u,										// deUint32				mipLevels;
			getArraySize(m_params.dst.image),		// deUint32				arraySize;
			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
		};

		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
	}

	// Barriers for copying image to buffer
	VkImageMemoryBarrier		srcImageBarrier		=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		0u,											// VkAccessFlags			srcAccessMask;
		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
		m_multisampledImage.get(),					// VkImage					image;
		{											// VkImageSubresourceRange	subresourceRange;
			VK_IMAGE_ASPECT_COLOR_BIT,			// VkImageAspectFlags	aspectMask;
			0u,									// deUint32				baseMipLevel;
			1u,									// deUint32				mipLevels;
			0u,									// deUint32				baseArraySlice;
			getArraySize(m_params.src.image)	// deUint32				arraySize;
		}
	};

	// Create render pass.
	{
		const VkAttachmentDescription	attachmentDescriptions[1]	=
		{
			{
				0u,											// VkAttachmentDescriptionFlags		flags;
				m_params.src.image.format,					// VkFormat							format;
				rasterizationSamples,						// VkSampleCountFlagBits			samples;
				VK_ATTACHMENT_LOAD_OP_CLEAR,				// VkAttachmentLoadOp				loadOp;
				VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				storeOp;
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp				stencilLoadOp;
				VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp				stencilStoreOp;
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout					initialLayout;
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout					finalLayout;
			},
		};

		const VkAttachmentReference		colorAttachmentReference	=
		{
			0u,													// deUint32			attachment;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
		};

		const VkSubpassDescription		subpassDescription			=
		{
			0u,									// VkSubpassDescriptionFlags	flags;
			VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint			pipelineBindPoint;
			0u,									// deUint32						inputAttachmentCount;
			DE_NULL,							// const VkAttachmentReference*	pInputAttachments;
			1u,									// deUint32						colorAttachmentCount;
			&colorAttachmentReference,			// const VkAttachmentReference*	pColorAttachments;
			DE_NULL,							// const VkAttachmentReference*	pResolveAttachments;
			DE_NULL,							// const VkAttachmentReference*	pDepthStencilAttachment;
			0u,									// deUint32						preserveAttachmentCount;
			DE_NULL								// const VkAttachmentReference*	pPreserveAttachments;
		};

		const VkRenderPassCreateInfo	renderPassParams			=
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureType					sType;
			DE_NULL,									// const void*						pNext;
			0u,											// VkRenderPassCreateFlags			flags;
			1u,											// deUint32							attachmentCount;
			attachmentDescriptions,						// const VkAttachmentDescription*	pAttachments;
			1u,											// deUint32							subpassCount;
			&subpassDescription,						// const VkSubpassDescription*		pSubpasses;
			0u,											// deUint32							dependencyCount;
			DE_NULL										// const VkSubpassDependency*		pDependencies;
		};

		renderPass	= createRenderPass(vk, vkDevice, &renderPassParams);
	}

	// Create pipeline layout
	{
		const VkPipelineLayoutCreateInfo	pipelineLayoutParams	=
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
			DE_NULL,											// const void*						pNext;
			0u,													// VkPipelineLayoutCreateFlags		flags;
			0u,													// deUint32							setLayoutCount;
			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
			0u,													// deUint32							pushConstantRangeCount;
			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
		};

		pipelineLayout	= createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
	}

	// Create upper half triangle.
	{
		const tcu::Vec4	a	(-1.0, -1.0, 0.0, 1.0);
		const tcu::Vec4	b	(1.0, -1.0, 0.0, 1.0);
		const tcu::Vec4	c	(1.0, 1.0, 0.0, 1.0);
		// Add triangle.
		vertices.push_back(a);
		vertices.push_back(c);
		vertices.push_back(b);
	}

	// Create vertex buffer.
	{
		const VkDeviceSize			vertexDataSize		= vertices.size() * sizeof(tcu::Vec4);
		const VkBufferCreateInfo	vertexBufferParams	=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			vertexDataSize,								// VkDeviceSize			size;
			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyIndexCount;
			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
		};

		vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
		vertexBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
		VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));

		// Load vertices into vertex buffer.
		deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
		flushAlloc(vk, vkDevice, *vertexBufferAlloc);
	}

	{
		Move<VkFramebuffer>		framebuffer;
		Move<VkImageView>		sourceAttachmentView;

		// Create color attachment view.
		{
			const VkImageViewCreateInfo	colorAttachmentViewParams	=
			{
				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,				// VkStructureType			sType;
				DE_NULL,												// const void*				pNext;
				0u,														// VkImageViewCreateFlags	flags;
				*m_multisampledImage,									// VkImage					image;
				VK_IMAGE_VIEW_TYPE_2D,									// VkImageViewType			viewType;
				m_params.src.image.format,								// VkFormat					format;
				componentMappingRGBA,									// VkComponentMapping		components;
				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
			};
			sourceAttachmentView	= createImageView(vk, vkDevice, &colorAttachmentViewParams);
		}

		// Create framebuffer
		{
			const VkImageView				attachments[1]		=
			{
					*sourceAttachmentView,
			};

			const VkFramebufferCreateInfo	framebufferParams	=
			{
					VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
					DE_NULL,											// const void*					pNext;
					0u,													// VkFramebufferCreateFlags		flags;
					*renderPass,										// VkRenderPass					renderPass;
					1u,													// deUint32						attachmentCount;
					attachments,										// const VkImageView*			pAttachments;
					m_params.src.image.extent.width,					// deUint32						width;
					m_params.src.image.extent.height,					// deUint32						height;
					1u													// deUint32						layers;
			};

			framebuffer	= createFramebuffer(vk, vkDevice, &framebufferParams);
		}

		// Create pipeline
		{
			const std::vector<VkViewport>	viewports	(1, makeViewport(m_params.src.image.extent));
			const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_params.src.image.extent));

			const VkPipelineMultisampleStateCreateInfo	multisampleStateParams		=
			{
				VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
				DE_NULL,													// const void*								pNext;
				0u,															// VkPipelineMultisampleStateCreateFlags	flags;
				rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
				VK_FALSE,													// VkBool32									sampleShadingEnable;
				0.0f,														// float									minSampleShading;
				DE_NULL,													// const VkSampleMask*						pSampleMask;
				VK_FALSE,													// VkBool32									alphaToCoverageEnable;
				VK_FALSE													// VkBool32									alphaToOneEnable;
			};

			graphicsPipeline = makeGraphicsPipeline(vk,										// const DeviceInterface&                        vk
													vkDevice,								// const VkDevice                                device
													*pipelineLayout,						// const VkPipelineLayout                        pipelineLayout
													*vertexShaderModule,					// const VkShaderModule                          vertexShaderModule
													DE_NULL,								// const VkShaderModule                          tessellationControlModule
													DE_NULL,								// const VkShaderModule                          tessellationEvalModule
													DE_NULL,								// const VkShaderModule                          geometryShaderModule
													*fragmentShaderModule,					// const VkShaderModule                          fragmentShaderModule
													*renderPass,							// const VkRenderPass                            renderPass
													viewports,								// const std::vector<VkViewport>&                viewports
													scissors,								// const std::vector<VkRect2D>&                  scissors
													VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
													0u,										// const deUint32                                subpass
													0u,										// const deUint32                                patchControlPoints
													DE_NULL,								// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
													DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
													&multisampleStateParams);				// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
		}

		// Create command buffer
		{
			beginCommandBuffer(vk, *m_cmdBuffer, 0u);
			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);
			beginRenderPass(vk, *m_cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, m_params.src.image.extent.width, m_params.src.image.extent.height), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));

			const VkDeviceSize	vertexBufferOffset	= 0u;

			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
			vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);

			endRenderPass(vk, *m_cmdBuffer);
			endCommandBuffer(vk, *m_cmdBuffer);
		}

		// Queue submit.
		{
			const VkQueue	queue	= m_context.getUniversalQueue();
			submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
		}
	}
}

tcu::TestStatus ResolveImageToImage::iterate (void)
{
	const tcu::TextureFormat		srcTcuFormat		= mapVkFormat(m_params.src.image.format);
	const tcu::TextureFormat		dstTcuFormat		= mapVkFormat(m_params.dst.image.format);

	// upload the destination image
	m_destinationTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
																			(int)m_params.dst.image.extent.width,
																			(int)m_params.dst.image.extent.height,
																			(int)m_params.dst.image.extent.depth));
	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);

	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
																	(int)m_params.src.image.extent.width,
																	(int)m_params.src.image.extent.height,
																	(int)m_params.dst.image.extent.depth));

	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);
	generateExpectedResult();

	VkImage		sourceImage		= m_multisampledImage.get();
	deUint32	sourceArraySize	= getArraySize(m_params.src.image);

	switch (m_options)
	{
		case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
			// Duplicate the multisampled image to a multisampled image array
			sourceArraySize	= getArraySize(m_params.dst.image); // fall through
		case COPY_MS_IMAGE_TO_MS_IMAGE:
			copyMSImageToMSImage(sourceArraySize);
			sourceImage	= m_multisampledCopyImage.get();
			break;
		default:
			break;
	}

	const DeviceInterface&			vk					= m_context.getDeviceInterface();
	const VkDevice					vkDevice			= m_context.getDevice();
	const VkQueue					queue				= m_context.getUniversalQueue();

	std::vector<VkImageResolve>		imageResolves;
	std::vector<VkImageResolve2KHR>	imageResolves2KHR;
	for (deUint32 i = 0; i < m_params.regions.size(); i++)
	{
		if (m_params.extensionUse == EXTENSION_USE_NONE)
		{
			imageResolves.push_back(m_params.regions[i].imageResolve);
		}
		else
		{
			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
			imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(m_params.regions[i].imageResolve));
		}
	}

	const VkImageMemoryBarrier	imageBarriers[]		=
	{
		// source image
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
			DE_NULL,									// const void*				pNext;
			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask;
			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			oldLayout;
			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
			sourceImage,								// VkImage					image;
			{											// VkImageSubresourceRange	subresourceRange;
				getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
				0u,									// deUint32				baseMipLevel;
				1u,									// deUint32				mipLevels;
				0u,									// deUint32				baseArraySlice;
				sourceArraySize						// deUint32				arraySize;
			}
		},
		// destination image
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
			DE_NULL,									// const void*				pNext;
			0u,											// VkAccessFlags			srcAccessMask;
			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
			m_destination.get(),						// VkImage					image;
			{											// VkImageSubresourceRange	subresourceRange;
				getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
				0u,									// deUint32				baseMipLevel;
				1u,									// deUint32				mipLevels;
				0u,									// deUint32				baseArraySlice;
				getArraySize(m_params.dst.image)	// deUint32				arraySize;
			}
		},
	};

	const VkImageMemoryBarrier postImageBarrier =
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
		DE_NULL,								// const void*				pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			srcAccessMask;
		VK_ACCESS_HOST_READ_BIT,				// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
		m_destination.get(),					// VkImage					image;
		{										// VkImageSubresourceRange	subresourceRange;
			getAspectFlags(dstTcuFormat),		// VkImageAspectFlags		aspectMask;
			0u,									// deUint32					baseMipLevel;
			1u,									// deUint32					mipLevels;
			0u,									// deUint32					baseArraySlice;
			getArraySize(m_params.dst.image)	// deUint32					arraySize;
		}
	};

	beginCommandBuffer(vk, *m_cmdBuffer);
	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);

	if (m_params.extensionUse == EXTENSION_USE_NONE)
	{
		vk.cmdResolveImage(*m_cmdBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), imageResolves.data());
	}
	else
	{
		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
		const VkResolveImageInfo2KHR ResolveImageInfo2KHR =
		{
			VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
			DE_NULL,									// const void*					pNext;
			sourceImage,								// VkImage						srcImage;
			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout				srcImageLayout;
			m_destination.get(),						// VkImage						dstImage;
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout				dstImageLayout;
			(deUint32)m_params.regions.size(),			// uint32_t						regionCount;
			imageResolves2KHR.data()					// const  VkImageResolve2KHR*	pRegions;
		};
		vk.cmdResolveImage2KHR(*m_cmdBuffer, &ResolveImageInfo2KHR);
	}

	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);
	endCommandBuffer(vk, *m_cmdBuffer);
	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);

	de::MovePtr<tcu::TextureLevel>	resultTextureLevel	= readImage(*m_destination, m_params.dst.image);

	if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE)
	{
		// Verify the intermediate multisample copy operation happens properly instead of, for example, shuffling samples around or
		// resolving the image and giving every sample the same value.
		const auto intermediateResult = checkIntermediateCopy();
		if (intermediateResult.getCode() != QP_TEST_RESULT_PASS)
			return intermediateResult;
	}

	return checkTestResult(resultTextureLevel->getAccess());
}

tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
{
	const tcu::ConstPixelBufferAccess	expected		= m_expectedTextureLevel[0]->getAccess();
	const float							fuzzyThreshold	= 0.01f;

	for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
	{
		const tcu::ConstPixelBufferAccess	expectedSub	= getSubregion (expected, 0, 0, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
		const tcu::ConstPixelBufferAccess	resultSub	= getSubregion (result, 0, 0, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
		if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
			return tcu::TestStatus::fail("CopiesAndBlitting test");
	}

	return tcu::TestStatus::pass("CopiesAndBlitting test");
}

void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
{
	DE_UNREF(mipLevel);

	VkOffset3D srcOffset	= region.imageResolve.srcOffset;
			srcOffset.z		= region.imageResolve.srcSubresource.baseArrayLayer;
	VkOffset3D dstOffset	= region.imageResolve.dstOffset;
			dstOffset.z		= region.imageResolve.dstSubresource.baseArrayLayer;
	VkExtent3D extent		= region.imageResolve.extent;
			extent.depth		= region.imageResolve.srcSubresource.layerCount;

	const tcu::ConstPixelBufferAccess	srcSubRegion		= getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
	// CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
	const tcu::PixelBufferAccess		dstWithSrcFormat	(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
	const tcu::PixelBufferAccess		dstSubRegion		= getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);

	tcu::copy(dstSubRegion, srcSubRegion);
}

tcu::TestStatus ResolveImageToImage::checkIntermediateCopy (void)
{
	const		auto&	vkd					= m_context.getDeviceInterface();
	const		auto	device				= m_context.getDevice();
	const		auto	queue				= m_context.getUniversalQueue();
	const		auto	queueIndex			= m_context.getUniversalQueueFamilyIndex();
				auto&	alloc				= m_context.getDefaultAllocator();
	const		auto	currentLayout		= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
	const		auto	numDstLayers		= getArraySize(m_params.dst.image);
	const		auto	numInputAttachments	= numDstLayers + 1u; // For the source image.
	constexpr	auto	numSets				= 2u; // 1 for the output buffer, 1 for the input attachments.
	const		auto	fbWidth				= m_params.src.image.extent.width;
	const		auto	fbHeight			= m_params.src.image.extent.height;

	// Push constants.
	const std::array<int, 3> pushConstantData =
	{{
		static_cast<int>(fbWidth),
		static_cast<int>(fbHeight),
		static_cast<int>(m_params.samples),
	}};
	const auto pushConstantSize = static_cast<deUint32>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));

	// Shader modules.
	const auto vertexModule			= createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
	const auto verificationModule	= createShaderModule(vkd, device, m_context.getBinaryCollection().get("verify"), 0u);

	// Descriptor sets.
	DescriptorPoolBuilder poolBuilder;
	poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
	poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
	const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);

	DescriptorSetLayoutBuilder layoutBuilderBuffer;
	layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
	const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);

	DescriptorSetLayoutBuilder layoutBuilderAttachments;
	for (deUint32 i = 0u; i < numInputAttachments; ++i)
		layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
	const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);

	const auto descriptorSetBuffer		= makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
	const auto descriptorSetAttachments	= makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());

	// Array with raw descriptor sets.
	const std::array<VkDescriptorSet, numSets> descriptorSets =
	{{
		descriptorSetBuffer.get(),
		descriptorSetAttachments.get(),
	}};

	// Pipeline layout.
	const std::array<VkDescriptorSetLayout, numSets> setLayouts =
	{{
		outputBufferSetLayout.get(),
		inputAttachmentsSetLayout.get(),
	}};

	const VkPushConstantRange pushConstantRange =
	{
		VK_SHADER_STAGE_FRAGMENT_BIT,	//	VkShaderStageFlags	stageFlags;
		0u,								//	deUint32			offset;
		pushConstantSize,				//	deUint32			size;
	};

	const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	//	VkStructureType					sType;
		nullptr,										//	const void*						pNext;
		0u,												//	VkPipelineLayoutCreateFlags		flags;
		static_cast<deUint32>(setLayouts.size()),		//	deUint32						setLayoutCount;
		setLayouts.data(),								//	const VkDescriptorSetLayout*	pSetLayouts;
		1u,												//	deUint32						pushConstantRangeCount;
		&pushConstantRange,								//	const VkPushConstantRange*		pPushConstantRanges;
	};

	const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);

	// Render pass.
	const VkAttachmentDescription commonAttachmentDescription =
	{
		0u,									//	VkAttachmentDescriptionFlags	flags;
		m_params.src.image.format,			//	VkFormat						format;
		m_params.samples,					//	VkSampleCountFlagBits			samples;
		VK_ATTACHMENT_LOAD_OP_LOAD,			//	VkAttachmentLoadOp				loadOp;
		VK_ATTACHMENT_STORE_OP_STORE,		//	VkAttachmentStoreOp				storeOp;
		VK_ATTACHMENT_LOAD_OP_DONT_CARE,	//	VkAttachmentLoadOp				stencilLoadOp;
		VK_ATTACHMENT_STORE_OP_DONT_CARE,	//	VkAttachmentStoreOp				stencilStoreOp;
		currentLayout,						//	VkImageLayout					initialLayout;
		currentLayout,						//	VkImageLayout					finalLayout;
	};
	const std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);

	std::vector<VkAttachmentReference> inputAttachmentReferences;
	inputAttachmentReferences.reserve(numInputAttachments);
	for (deUint32 i = 0u; i < numInputAttachments; ++i)
	{
		const VkAttachmentReference reference = { i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
		inputAttachmentReferences.push_back(reference);
	}

	const VkSubpassDescription subpassDescription =
	{
		0u,															//	VkSubpassDescriptionFlags		flags;
		VK_PIPELINE_BIND_POINT_GRAPHICS,							//	VkPipelineBindPoint				pipelineBindPoint;
		static_cast<deUint32>(inputAttachmentReferences.size()),	//	deUint32						inputAttachmentCount;
		inputAttachmentReferences.data(),							//	const VkAttachmentReference*	pInputAttachments;
		0u,															//	deUint32						colorAttachmentCount;
		nullptr,													//	const VkAttachmentReference*	pColorAttachments;
		nullptr,													//	const VkAttachmentReference*	pResolveAttachments;
		nullptr,													//	const VkAttachmentReference*	pDepthStencilAttachment;
		0u,															//	deUint32						preserveAttachmentCount;
		nullptr,													//	const deUint32*					pPreserveAttachments;
	};

	const VkRenderPassCreateInfo renderPassInfo =
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,				//	VkStructureType					sType;
		nullptr,												//	const void*						pNext;
		0u,														//	VkRenderPassCreateFlags			flags;
		static_cast<deUint32>(attachmentDescriptions.size()),	//	deUint32						attachmentCount;
		attachmentDescriptions.data(),							//	const VkAttachmentDescription*	pAttachments;
		1u,														//	deUint32						subpassCount;
		&subpassDescription,									//	const VkSubpassDescription*		pSubpasses;
		0u,														//	deUint32						dependencyCount;
		nullptr,												//	const VkSubpassDependency*		pDependencies;
	};

	const auto renderPass = createRenderPass(vkd, device, &renderPassInfo);

	// Framebuffer.
	std::vector<Move<VkImageView>>	imageViews;
	std::vector<VkImageView>		imageViewsRaw;

	imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)));
	for (deUint32 i = 0u; i < numDstLayers; ++i)
	{
		const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, i, 1u);
		imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.dst.image.format, subresourceRange));
	}

	imageViewsRaw.reserve(imageViews.size());
	std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw), [](const Move<VkImageView>& ptr) { return ptr.get(); });

	const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), static_cast<deUint32>(imageViewsRaw.size()), imageViewsRaw.data(), fbWidth, fbHeight);

	// Storage buffer.
	const auto			bufferCount	= static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
	const auto			bufferSize	= static_cast<VkDeviceSize>(bufferCount * sizeof(deInt32));
	BufferWithMemory	buffer		(vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
	auto&				bufferAlloc	= buffer.getAllocation();
	void*				bufferData	= bufferAlloc.getHostPtr();

	// Update descriptor sets.
	DescriptorSetUpdateBuilder updater;

	const auto bufferInfo = makeDescriptorBufferInfo(buffer.get(), 0ull, bufferSize);
	updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo);

	std::vector<VkDescriptorImageInfo> imageInfos;
	imageInfos.reserve(imageViewsRaw.size());
	for (size_t i = 0; i < imageViewsRaw.size(); ++i)
		imageInfos.push_back(makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));

	for (size_t i = 0; i < imageInfos.size(); ++i)
		updater.writeSingle(descriptorSetAttachments.get(), DescriptorSetUpdateBuilder::Location::binding(static_cast<deUint32>(i)), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);

	updater.update(vkd, device);

	// Vertex buffer.
	std::vector<tcu::Vec4> fullScreenQuad;
	{
		// Full screen quad so every framebuffer pixel and sample location is verified by the shader.
		const tcu::Vec4 topLeft		(-1.0f, -1.0f, 0.0f, 1.0f);
		const tcu::Vec4 topRight	( 1.0f, -1.0f, 0.0f, 1.0f);
		const tcu::Vec4 bottomLeft	(-1.0f,  1.0f, 0.0f, 1.0f);
		const tcu::Vec4 bottomRight	( 1.0f,  1.0f, 0.0f, 1.0f);

		fullScreenQuad.reserve(6u);
		fullScreenQuad.push_back(topLeft);
		fullScreenQuad.push_back(topRight);
		fullScreenQuad.push_back(bottomRight);
		fullScreenQuad.push_back(topLeft);
		fullScreenQuad.push_back(bottomRight);
		fullScreenQuad.push_back(bottomLeft);
	}

	const auto				vertexBufferSize	= static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
	const auto				vertexBufferInfo	= makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
	const BufferWithMemory	vertexBuffer		(vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
	const auto				vertexBufferHandler	= vertexBuffer.get();
	auto&					vertexBufferAlloc	= vertexBuffer.getAllocation();
	void*					vertexBufferData	= vertexBufferAlloc.getHostPtr();
	const VkDeviceSize		vertexBufferOffset	= 0ull;

	deMemcpy(vertexBufferData, fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
	flushAlloc(vkd, device, vertexBufferAlloc);

	// Graphics pipeline.
	const std::vector<VkViewport>	viewports	(1, makeViewport(m_params.src.image.extent));
	const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_params.src.image.extent));

	const VkPipelineMultisampleStateCreateInfo	multisampleStateParams		=
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
		nullptr,													// const void*								pNext;
		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
		VK_FALSE,													// VkBool32									sampleShadingEnable;
		0.0f,														// float									minSampleShading;
		nullptr,													// const VkSampleMask*						pSampleMask;
		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
		VK_FALSE													// VkBool32									alphaToOneEnable;
	};

	const auto graphicsPipeline = makeGraphicsPipeline(
		vkd,									// const DeviceInterface&                        vk
		device,									// const VkDevice                                device
		pipelineLayout.get(),					// const VkPipelineLayout                        pipelineLayout
		vertexModule.get(),						// const VkShaderModule                          vertexShaderModule
		DE_NULL,								// const VkShaderModule                          tessellationControlModule
		DE_NULL,								// const VkShaderModule                          tessellationEvalModule
		DE_NULL,								// const VkShaderModule                          geometryShaderModule
		verificationModule.get(),				// const VkShaderModule                          fragmentShaderModule
		renderPass.get(),						// const VkRenderPass                            renderPass
		viewports,								// const std::vector<VkViewport>&                viewports
		scissors,								// const std::vector<VkRect2D>&                  scissors
		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
		0u,										// const deUint32                                subpass
		0u,										// const deUint32                                patchControlPoints
		nullptr,								// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
		nullptr,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
		&multisampleStateParams);				// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo

	// Command buffer.
	const auto cmdPool		= makeCommandPool(vkd, device, queueIndex);
	const auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
	const auto cmdBuffer	= cmdBufferPtr.get();

	// Make sure multisample copy data is available to the fragment shader.
	const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);

	// Make sure verification buffer data is available on the host.
	const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);

	// Record and submit command buffer.
	beginCommandBuffer(vkd, cmdBuffer);
	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u, &imagesBarrier, 0u, nullptr, 0u, nullptr);
	beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_params.src.image.extent));
	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
	vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBufferHandler, &vertexBufferOffset);
	vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize, pushConstantData.data());
	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, static_cast<deUint32>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
	vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(fullScreenQuad.size()), 1u, 0u, 0u);
	endRenderPass(vkd, cmdBuffer);
	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &bufferBarrier, 0u, nullptr, 0u, nullptr);
	endCommandBuffer(vkd, cmdBuffer);
	submitCommandsAndWait(vkd, device, queue, cmdBuffer);

	// Verify intermediate results.
	invalidateAlloc(vkd, device, bufferAlloc);
	std::vector<deInt32> outputFlags (bufferCount, 0);
	deMemcpy(outputFlags.data(), bufferData, static_cast<size_t>(bufferSize));

	auto& log = m_context.getTestContext().getLog();
	log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;

	const auto sampleCount = static_cast<deUint32>(m_params.samples);

	for (deUint32 x = 0u; x < fbWidth; ++x)
	for (deUint32 y = 0u; y < fbHeight; ++y)
	for (deUint32 s = 0u; s < sampleCount; ++s)
	{
		const auto index = (y * fbWidth + x) * sampleCount + s;
		if (!outputFlags[index])
		{
			std::ostringstream msg;
			msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s;
			return tcu::TestStatus::fail(msg.str());
		}
	}

	log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
	return tcu::TestStatus::pass("Pass");
}

void ResolveImageToImage::copyMSImageToMSImage (deUint32 copyArraySize)
{
	const DeviceInterface&			vk					= m_context.getDeviceInterface();
	const VkDevice					vkDevice			= m_context.getDevice();
	const VkQueue					queue				= m_context.getUniversalQueue();
	const tcu::TextureFormat		srcTcuFormat		= mapVkFormat(m_params.src.image.format);
	std::vector<VkImageCopy>		imageCopies;
	std::vector<VkImageCopy2KHR>	imageCopies2KHR;

	for (deUint32 layerNdx = 0; layerNdx < copyArraySize; ++layerNdx)
	{
		const VkImageSubresourceLayers	sourceSubresourceLayers	=
		{
			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
			0u,								// deUint32				mipLevel;
			0u,								// deUint32				baseArrayLayer;
			1u								// deUint32				layerCount;
		};

		const VkImageSubresourceLayers	destinationSubresourceLayers	=
		{
			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;//getAspectFlags(dstTcuFormat)
			0u,								// deUint32				mipLevel;
			layerNdx,						// deUint32				baseArrayLayer;
			1u								// deUint32				layerCount;
		};

		const VkImageCopy				imageCopy	=
		{
			sourceSubresourceLayers,			// VkImageSubresourceLayers	srcSubresource;
			{0, 0, 0},							// VkOffset3D				srcOffset;
			destinationSubresourceLayers,		// VkImageSubresourceLayers	dstSubresource;
			{0, 0, 0},							// VkOffset3D				dstOffset;
			 getExtent3D(m_params.src.image),	// VkExtent3D				extent;
		};

		if (m_params.extensionUse == EXTENSION_USE_NONE)
		{
			imageCopies.push_back(imageCopy);
		}
		else
		{
			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
			imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
		}
	}

	const VkImageMemoryBarrier		imageBarriers[]		=
	{
		// source image
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
			DE_NULL,									// const void*				pNext;
			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask;
			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			oldLayout;
			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
			m_multisampledImage.get(),					// VkImage					image;
			{											// VkImageSubresourceRange	subresourceRange;
				getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
				0u,									// deUint32				baseMipLevel;
				1u,									// deUint32				mipLevels;
				0u,									// deUint32				baseArraySlice;
				getArraySize(m_params.src.image)	// deUint32				arraySize;
			}
		},
		// destination image
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
			DE_NULL,									// const void*				pNext;
			0,											// VkAccessFlags			srcAccessMask;
			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
			m_multisampledCopyImage.get(),				// VkImage					image;
			{											// VkImageSubresourceRange	subresourceRange;
				getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
				0u,									// deUint32				baseMipLevel;
				1u,									// deUint32				mipLevels;
				0u,									// deUint32				baseArraySlice;
				copyArraySize						// deUint32				arraySize;
			}
		},
	};

	const VkImageMemoryBarrier	postImageBarriers		=
	// destination image
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
		m_multisampledCopyImage.get(),				// VkImage					image;
		{											// VkImageSubresourceRange	subresourceRange;
			getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
			0u,									// deUint32				baseMipLevel;
			1u,									// deUint32				mipLevels;
			0u,									// deUint32				baseArraySlice;
			copyArraySize						// deUint32				arraySize;
		}
	};

	beginCommandBuffer(vk, *m_cmdBuffer);
	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);

	if (m_params.extensionUse == EXTENSION_USE_NONE)
	{
		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());
	}
	else
	{
		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
		const VkCopyImageInfo2KHR copyImageInfo2KHR =
		{
			VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
			DE_NULL,									// const void*				pNext;
			m_multisampledImage.get(),					// VkImage					srcImage;
			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			srcImageLayout;
			m_multisampledCopyImage.get(),				// VkImage					dstImage;
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			dstImageLayout;
			(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
			imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
		};

		vk.cmdCopyImage2KHR(*m_cmdBuffer, &copyImageInfo2KHR);
	}

	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarriers);
	endCommandBuffer(vk, *m_cmdBuffer);

	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
}

class ResolveImageToImageTestCase : public vkt::TestCase
{
public:
							ResolveImageToImageTestCase	(tcu::TestContext&					testCtx,
														 const std::string&					name,
														 const std::string&					description,
														 const TestParams					params,
														 const ResolveImageToImageOptions	options = NO_OPTIONAL_OPERATION)
								: vkt::TestCase	(testCtx, name, description)
								, m_params		(params)
								, m_options		(options)
	{}

							virtual	void			initPrograms				(SourceCollections&		programCollection) const;

	virtual TestInstance*	createInstance				(Context&				context) const
	{
		return new ResolveImageToImage(context, m_params, m_options);
	}

	virtual void			checkSupport				(Context&				context) const
	{
		const VkSampleCountFlagBits	rasterizationSamples = m_params.samples;

		if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
			throw tcu::NotSupportedError("Unsupported number of rasterization samples");

		VkImageFormatProperties properties;
		if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
																					m_params.src.image.format,
																					m_params.src.image.imageType,
																					VK_IMAGE_TILING_OPTIMAL,
																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
			(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
																					m_params.dst.image.format,
																					m_params.dst.image.imageType,
																					VK_IMAGE_TILING_OPTIMAL,
																					VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
		{
			TCU_THROW(NotSupportedError, "Format not supported");
		}

		if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)	&&
			(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
		{
			TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
		}
	}

private:
	TestParams							m_params;
	const ResolveImageToImageOptions	m_options;
};

void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const
{
	programCollection.glslSources.add("vert") << glu::VertexSource(
		"#version 310 es\n"
		"layout (location = 0) in highp vec4 a_position;\n"
		"void main()\n"
		"{\n"
		"	gl_Position = a_position;\n"
		"}\n");


	programCollection.glslSources.add("frag") << glu::FragmentSource(
		"#version 310 es\n"
		"layout (location = 0) out highp vec4 o_color;\n"
		"void main()\n"
		"{\n"
		"	o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
		"}\n");

	if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE)
	{
		// The shader verifies all layers in the copied image are the same as the source image.
		// This needs an image view per layer in the copied image.
		// Set 0 contains the output buffer.
		// Set 1 contains the input attachments.

		std::ostringstream verificationShader;

		verificationShader
			<< "#version 450\n"
			<< "\n"
			<< "layout (push_constant, std430) uniform PushConstants {\n"
			<< "    int width;\n"
			<< "    int height;\n"
			<< "    int samples;\n"
			<< "};\n"
			<< "layout (set=0, binding=0) buffer VerificationResults {\n"
			<< "    int verificationFlags[];\n"
			<< "};\n"
			<< "layout (input_attachment_index=0, set=1, binding=0) uniform subpassInputMS attachment0;\n"
			;

		const auto dstLayers = getArraySize(m_params.dst.image);
		for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
		{
			const auto i = layerNdx + 1u;
			verificationShader << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform subpassInputMS attachment" << i << ";\n";
		}

		// Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
		// created with a single sample.
		verificationShader
			<< "\n"
			<< "void main() {\n"
			<< "    for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
			<< "        vec4 orig = subpassLoad(attachment0, sampleID);\n"
			;

		for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
		{
			const auto i = layerNdx + 1u;
			verificationShader << "        vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
		}

		std::ostringstream testCondition;
		for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
		{
			const auto i = layerNdx + 1u;
			testCondition << (layerNdx == 0u ? "" : " && ") << "orig == copy" << i;
		}

		verificationShader
			<< "\n"
			<< "        ivec3 coords  = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
			<< "        int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
			<< "\n"
			<< "        verificationFlags[bufferPos] = ((" << testCondition.str() << ") ? 1 : 0); \n"
			<< "    }\n"
			<< "}\n"
			;

		programCollection.glslSources.add("verify") << glu::FragmentSource(verificationShader.str());
	}
}

struct BufferOffsetParams
{
	static constexpr deUint32 kMaxOffset = 8u;

	deUint32 srcOffset;
	deUint32 dstOffset;
};

void checkZerosAt(const std::vector<deUint8>& bufferData, deUint32 from, deUint32 count)
{
	constexpr deUint8 zero{0};
	for (deUint32 i = 0; i < count; ++i)
	{
		const auto& val = bufferData[from + i];
		if (val != zero)
		{
			std::ostringstream msg;
			msg << "Unexpected non-zero byte found at position " << (from + i) << ": " << static_cast<int>(val);
			TCU_FAIL(msg.str());
		}
	}
}

tcu::TestStatus bufferOffsetTest (Context& ctx, BufferOffsetParams params)
{
	// Try to copy blocks of sizes 1 to kMaxOffset. Each copy region will use a block of kMaxOffset*2 bytes to take into account srcOffset and dstOffset.
	constexpr auto kMaxOffset	= BufferOffsetParams::kMaxOffset;
	constexpr auto kBlockSize	= kMaxOffset * 2u;
	constexpr auto kBufferSize	= kMaxOffset * kBlockSize;

	DE_ASSERT(params.srcOffset < kMaxOffset);
	DE_ASSERT(params.dstOffset < kMaxOffset);

	const auto&	vkd		= ctx.getDeviceInterface();
	const auto	device	= ctx.getDevice();
	auto&		alloc	= ctx.getDefaultAllocator();
	const auto	qIndex	= ctx.getUniversalQueueFamilyIndex();
	const auto	queue	= ctx.getUniversalQueue();

	const auto srcBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
	const auto dstBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);

	BufferWithMemory	srcBuffer	(vkd, device, alloc, srcBufferInfo, MemoryRequirement::HostVisible);
	BufferWithMemory	dstBuffer	(vkd, device, alloc, dstBufferInfo, MemoryRequirement::HostVisible);
	auto&				srcAlloc	= srcBuffer.getAllocation();
	auto&				dstAlloc	= dstBuffer.getAllocation();

	// Zero-out destination buffer.
	deMemset(dstAlloc.getHostPtr(), 0, kBufferSize);
	flushAlloc(vkd, device, dstAlloc);

	// Fill source buffer with nonzero bytes.
	std::vector<deUint8> srcData;
	srcData.reserve(kBufferSize);
	for (deUint32 i = 0; i < kBufferSize; ++i)
		srcData.push_back(static_cast<deUint8>(100u + i));
	deMemcpy(srcAlloc.getHostPtr(), srcData.data(), de::dataSize(srcData));
	flushAlloc(vkd, device, srcAlloc);

	// Copy regions.
	std::vector<VkBufferCopy> copies;
	copies.reserve(kMaxOffset);
	for (deUint32 i = 0; i < kMaxOffset; ++i)
	{
		const auto blockStart	= kBlockSize * i;
		const auto copySize		= i + 1u;
		const auto bufferCopy	= makeBufferCopy(params.srcOffset + blockStart, params.dstOffset + blockStart, copySize);
		copies.push_back(bufferCopy);
	}

	const auto cmdPool		= makeCommandPool(vkd, device, qIndex);
	const auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
	const auto cmdBuffer	= cmdBufferPtr.get();

	beginCommandBuffer(vkd, cmdBuffer);
	vkd.cmdCopyBuffer(cmdBuffer, srcBuffer.get(), dstBuffer.get(), static_cast<deUint32>(copies.size()), copies.data());
	const auto barrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &barrier, 0u, nullptr, 0u, nullptr);
	endCommandBuffer(vkd, cmdBuffer);
	submitCommandsAndWait(vkd, device, queue, cmdBuffer);
	invalidateAlloc(vkd, device, dstAlloc);

	// Verify destination buffer data.
	std::vector<deUint8> dstData(kBufferSize);
	deMemcpy(dstData.data(), dstAlloc.getHostPtr(), de::dataSize(dstData));

	for (deUint32 blockIdx = 0; blockIdx < kMaxOffset; ++blockIdx)
	{
		const auto blockStart	= kBlockSize * blockIdx;
		const auto copySize		= blockIdx + 1u;

		// Verify no data has been written before dstOffset.
		checkZerosAt(dstData, blockStart, params.dstOffset);

		// Verify copied block.
		for (deUint32 i = 0; i < copySize; ++i)
		{
			const auto& dstVal = dstData[blockStart + params.dstOffset + i];
			const auto& srcVal = srcData[blockStart + params.srcOffset + i];
			if (dstVal != srcVal)
			{
				std::ostringstream msg;
				msg << "Unexpected value found at position " << (blockStart + params.dstOffset + i) << ": expected " << static_cast<int>(srcVal) << " but found " << static_cast<int>(dstVal);
				TCU_FAIL(msg.str());
			}
		}

		// Verify no data has been written after copy block.
		checkZerosAt(dstData, blockStart + params.dstOffset + copySize, kBlockSize - (params.dstOffset + copySize));
	}

	return tcu::TestStatus::pass("Pass");
}

std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag)
{
	return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
}

std::string getFormatCaseName (VkFormat format)
{
	return de::toLower(de::toString(getFormatStr(format)).substr(10));
}

std::string getImageLayoutCaseName (VkImageLayout layout)
{
	switch (layout)
	{
		case VK_IMAGE_LAYOUT_GENERAL:
			return "general";
		case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
		case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
			return "optimal";
		default:
			DE_ASSERT(false);
			return "";
	}
}

const deInt32					defaultSize				= 64;
const deInt32					defaultHalfSize			= defaultSize / 2;
const deInt32					defaultFourthSize		= defaultSize / 4;
const deInt32					defaultSixteenthSize	= defaultSize / 16;
const VkExtent3D				defaultExtent			= {defaultSize, defaultSize, 1};
const VkExtent3D				defaultHalfExtent		= {defaultHalfSize, defaultHalfSize, 1};
const VkExtent3D				default1dExtent			= {defaultSize, 1, 1};
const VkExtent3D				default3dExtent			= {defaultFourthSize, defaultFourthSize, defaultFourthSize};

const VkImageSubresourceLayers	defaultSourceLayer		=
{
	VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
	0u,							// deUint32				mipLevel;
	0u,							// deUint32				baseArrayLayer;
	1u,							// deUint32				layerCount;
};

void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	tcu::TestContext& testCtx	= group->getTestContext();

	{
		TestParams	params;
		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
		params.src.image.extent				= defaultExtent;
		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
		params.dst.image.extent				= defaultExtent;
		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		{
			const VkImageCopy				testCopy	=
			{
				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
				{0, 0, 0},			// VkOffset3D				srcOffset;
				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
				{0, 0, 0},			// VkOffset3D				dstOffset;
				defaultExtent,		// VkExtent3D				extent;
			};

			CopyRegion	imageCopy;
			imageCopy.imageCopy	= testCopy;
			params.regions.push_back(imageCopy);
		}

		group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params));
	}

	{
		TestParams	params;
		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
		params.src.image.extent				= defaultExtent;
		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
		params.dst.image.format				= VK_FORMAT_R32_UINT;
		params.dst.image.extent				= defaultExtent;
		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		{
			const VkImageCopy				testCopy	=
			{
				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
				{0, 0, 0},			// VkOffset3D				srcOffset;
				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
				{0, 0, 0},			// VkOffset3D				dstOffset;
				defaultExtent,		// VkExtent3D				extent;
			};

			CopyRegion	imageCopy;
			imageCopy.imageCopy = testCopy;
			params.regions.push_back(imageCopy);
		}

		group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params));
	}

	{
		TestParams	params;
		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
		params.src.image.extent				= defaultExtent;
		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
		params.dst.image.extent				= defaultExtent;
		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		{
			const VkImageCopy				testCopy	=
			{
				defaultSourceLayer,									// VkImageSubresourceLayers	srcSubresource;
				{0, 0, 0},											// VkOffset3D				srcOffset;
				defaultSourceLayer,									// VkImageSubresourceLayers	dstSubresource;
				{defaultFourthSize, defaultFourthSize / 2, 0},		// VkOffset3D				dstOffset;
				{defaultFourthSize / 2, defaultFourthSize / 2, 1},	// VkExtent3D				extent;
			};

			CopyRegion	imageCopy;
			imageCopy.imageCopy = testCopy;
			params.regions.push_back(imageCopy);
		}

		group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params));
	}

	static const struct
	{
		std::string		name;
		vk::VkFormat	format1;
		vk::VkFormat	format2;
	} formats [] =
	{
		{ "diff_format",	vk::VK_FORMAT_R32_UINT,			vk::VK_FORMAT_R8G8B8A8_UNORM	},
		{ "same_format",	vk::VK_FORMAT_R8G8B8A8_UNORM,	vk::VK_FORMAT_R8G8B8A8_UNORM	}
	};
	static const struct
	{
		std::string		name;
		vk::VkBool32	clear;
	} clears [] =
	{
		{ "clear",		VK_TRUE		},
		{ "noclear",	VK_FALSE	}
	};
	static const struct
	{
		std::string		name;
		VkExtent3D		extent;
	} extents [] =
	{
		{ "npot",	{65u, 63u, 1u}	},
		{ "pot",	{64u, 64u, 1u}	}
	};

	for (const auto& format : formats)
	{
		for (const auto& clear : clears)
		{
			for (const auto& extent : extents)
			{
				TestParams	params;
				params.src.image.imageType			= VK_IMAGE_TYPE_2D;
				params.src.image.format				= format.format1;
				params.src.image.extent				= extent.extent;
				params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
				params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
				params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
				params.dst.image.format				= format.format2;
				params.dst.image.extent				= extent.extent;
				params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
				params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
				params.allocationKind				= allocationKind;
				params.extensionUse					= extensionUse;
				params.clearDestination				= clear.clear;

				{
					VkImageCopy	testCopy	=
					{
						defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
						{34, 34, 0},		// VkOffset3D				srcOffset;
						defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
						{0, 0, 0},			// VkOffset3D				dstOffset;
						{31, 29, 1}			// VkExtent3D				extent;
					};

					if (extent.name == "pot")
					{
						testCopy.srcOffset	= { 16, 16, 0 };
						testCopy.extent		= { 32, 32, 1 };
					}

					CopyRegion	imageCopy;
					imageCopy.imageCopy = testCopy;
					params.regions.push_back(imageCopy);
				}

				// Example test case name: "partial_image_npot_diff_format_clear"
				const std::string testCaseName = "partial_image_" + extent.name + "_" + format.name + "_" + clear.name;

				group->addChild(new CopyImageToImageTestCase(testCtx, testCaseName, "", params));
			}
		}
	}

	{
		TestParams	params;
		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
		params.src.image.format				= VK_FORMAT_D32_SFLOAT;
		params.src.image.extent				= defaultExtent;
		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
		params.dst.image.format				= VK_FORMAT_D32_SFLOAT;
		params.dst.image.extent				= defaultExtent;
		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		{
			const VkImageSubresourceLayers  sourceLayer =
			{
				VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags	aspectMask;
				0u,							// deUint32				mipLevel;
				0u,							// deUint32				baseArrayLayer;
				1u							// deUint32				layerCount;
			};
			const VkImageCopy				testCopy	=
			{
				sourceLayer,										// VkImageSubresourceLayers	srcSubresource;
				{0, 0, 0},											// VkOffset3D				srcOffset;
				sourceLayer,										// VkImageSubresourceLayers	dstSubresource;
				{defaultFourthSize, defaultFourthSize / 2, 0},		// VkOffset3D				dstOffset;
				{defaultFourthSize / 2, defaultFourthSize / 2, 1},	// VkExtent3D				extent;
			};

			CopyRegion	imageCopy;
			imageCopy.imageCopy = testCopy;
			params.regions.push_back(imageCopy);
		}

		group->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params));
	}

	{
		TestParams	params;
		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
		params.src.image.format				= VK_FORMAT_S8_UINT;
		params.src.image.extent				= defaultExtent;
		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
		params.dst.image.format				= VK_FORMAT_S8_UINT;
		params.dst.image.extent				= defaultExtent;
		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		{
			const VkImageSubresourceLayers  sourceLayer =
			{
				VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask;
				0u,								// deUint32				mipLevel;
				0u,								// deUint32				baseArrayLayer;
				1u								// deUint32				layerCount;
			};
			const VkImageCopy				testCopy	=
			{
				sourceLayer,										// VkImageSubresourceLayers	srcSubresource;
				{0, 0, 0},											// VkOffset3D				srcOffset;
				sourceLayer,										// VkImageSubresourceLayers	dstSubresource;
				{defaultFourthSize, defaultFourthSize / 2, 0},		// VkOffset3D				dstOffset;
				{defaultFourthSize / 2, defaultFourthSize / 2, 1},	// VkExtent3D				extent;
			};

			CopyRegion	imageCopy;
			imageCopy.imageCopy = testCopy;
			params.regions.push_back(imageCopy);
		}

		group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params));
	}
}

struct CopyColorTestParams
{
	TestParams		params;
	const VkFormat*	compatibleFormats;
};

void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params)
{
	const VkImageLayout copySrcLayouts[]		=
	{
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
		VK_IMAGE_LAYOUT_GENERAL
	};
	const VkImageLayout copyDstLayouts[]		=
	{
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
		VK_IMAGE_LAYOUT_GENERAL
	};

	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
	{
		params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];

		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
		{
			params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];

			const std::string testName	= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
										  getImageLayoutCaseName(params.dst.image.operationLayout);
			const std::string description	= "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
			group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
		}
	}
}

bool isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams& testParams)
{
	bool result = true;

	if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
	{
		DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty());

		result =
			de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) ||
			de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format);
	}

	return result;
}

void addImageToImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, CopyColorTestParams testParams)
{
	// If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format.
	const VkFormat	srcFormatOnly[2]	= { testParams.params.src.image.format, VK_FORMAT_UNDEFINED };
	const VkFormat*	formatList			= (testParams.compatibleFormats ? testParams.compatibleFormats : srcFormatOnly);

	for (int dstFormatIndex = 0; formatList[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
	{
		testParams.params.dst.image.format = formatList[dstFormatIndex];

		const VkFormat		srcFormat	= testParams.params.src.image.format;
		const VkFormat		dstFormat	= testParams.params.dst.image.format;

		if (!isSupportedByFramework(dstFormat) && !isCompressedFormat(dstFormat))
			continue;

		if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
			continue;

		if (isCompressedFormat(srcFormat) && isCompressedFormat(dstFormat))
			if ((getBlockWidth(srcFormat) != getBlockWidth(dstFormat)) || (getBlockHeight(srcFormat) != getBlockHeight(dstFormat)))
				continue;

		const std::string	description	= "Copy to destination format " + getFormatCaseName(dstFormat);
		addTestGroup(group, getFormatCaseName(dstFormat), description, addImageToImageAllFormatsColorSrcFormatDstFormatTests, testParams.params);
	}
}

const VkFormat	compatibleFormats8Bit[]		=
{
	VK_FORMAT_R4G4_UNORM_PACK8,
	VK_FORMAT_R8_UNORM,
	VK_FORMAT_R8_SNORM,
	VK_FORMAT_R8_USCALED,
	VK_FORMAT_R8_SSCALED,
	VK_FORMAT_R8_UINT,
	VK_FORMAT_R8_SINT,
	VK_FORMAT_R8_SRGB,

	VK_FORMAT_UNDEFINED
};
const VkFormat	compatibleFormats16Bit[]	=
{
	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
	VK_FORMAT_B4G4R4A4_UNORM_PACK16,
	VK_FORMAT_R5G6B5_UNORM_PACK16,
	VK_FORMAT_B5G6R5_UNORM_PACK16,
	VK_FORMAT_R5G5B5A1_UNORM_PACK16,
	VK_FORMAT_B5G5R5A1_UNORM_PACK16,
	VK_FORMAT_A1R5G5B5_UNORM_PACK16,
	VK_FORMAT_R8G8_UNORM,
	VK_FORMAT_R8G8_SNORM,
	VK_FORMAT_R8G8_USCALED,
	VK_FORMAT_R8G8_SSCALED,
	VK_FORMAT_R8G8_UINT,
	VK_FORMAT_R8G8_SINT,
	VK_FORMAT_R8G8_SRGB,
	VK_FORMAT_R16_UNORM,
	VK_FORMAT_R16_SNORM,
	VK_FORMAT_R16_USCALED,
	VK_FORMAT_R16_SSCALED,
	VK_FORMAT_R16_UINT,
	VK_FORMAT_R16_SINT,
	VK_FORMAT_R16_SFLOAT,
	VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
	VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,

	VK_FORMAT_UNDEFINED
};
const VkFormat	compatibleFormats24Bit[]	=
{
	VK_FORMAT_R8G8B8_UNORM,
	VK_FORMAT_R8G8B8_SNORM,
	VK_FORMAT_R8G8B8_USCALED,
	VK_FORMAT_R8G8B8_SSCALED,
	VK_FORMAT_R8G8B8_UINT,
	VK_FORMAT_R8G8B8_SINT,
	VK_FORMAT_R8G8B8_SRGB,
	VK_FORMAT_B8G8R8_UNORM,
	VK_FORMAT_B8G8R8_SNORM,
	VK_FORMAT_B8G8R8_USCALED,
	VK_FORMAT_B8G8R8_SSCALED,
	VK_FORMAT_B8G8R8_UINT,
	VK_FORMAT_B8G8R8_SINT,
	VK_FORMAT_B8G8R8_SRGB,

	VK_FORMAT_UNDEFINED
};
const VkFormat	compatibleFormats32Bit[]	=
{
	VK_FORMAT_R8G8B8A8_UNORM,
	VK_FORMAT_R8G8B8A8_SNORM,
	VK_FORMAT_R8G8B8A8_USCALED,
	VK_FORMAT_R8G8B8A8_SSCALED,
	VK_FORMAT_R8G8B8A8_UINT,
	VK_FORMAT_R8G8B8A8_SINT,
	VK_FORMAT_R8G8B8A8_SRGB,
	VK_FORMAT_B8G8R8A8_UNORM,
	VK_FORMAT_B8G8R8A8_SNORM,
	VK_FORMAT_B8G8R8A8_USCALED,
	VK_FORMAT_B8G8R8A8_SSCALED,
	VK_FORMAT_B8G8R8A8_UINT,
	VK_FORMAT_B8G8R8A8_SINT,
	VK_FORMAT_B8G8R8A8_SRGB,
	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
	VK_FORMAT_A8B8G8R8_UINT_PACK32,
	VK_FORMAT_A8B8G8R8_SINT_PACK32,
	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
	VK_FORMAT_A2R10G10B10_SNORM_PACK32,
	VK_FORMAT_A2R10G10B10_USCALED_PACK32,
	VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
	VK_FORMAT_A2R10G10B10_UINT_PACK32,
	VK_FORMAT_A2R10G10B10_SINT_PACK32,
	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
	VK_FORMAT_A2B10G10R10_SNORM_PACK32,
	VK_FORMAT_A2B10G10R10_USCALED_PACK32,
	VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
	VK_FORMAT_A2B10G10R10_UINT_PACK32,
	VK_FORMAT_A2B10G10R10_SINT_PACK32,
	VK_FORMAT_R16G16_UNORM,
	VK_FORMAT_R16G16_SNORM,
	VK_FORMAT_R16G16_USCALED,
	VK_FORMAT_R16G16_SSCALED,
	VK_FORMAT_R16G16_UINT,
	VK_FORMAT_R16G16_SINT,
	VK_FORMAT_R16G16_SFLOAT,
	VK_FORMAT_R32_UINT,
	VK_FORMAT_R32_SINT,
	VK_FORMAT_R32_SFLOAT,

	VK_FORMAT_UNDEFINED
};
const VkFormat	compatibleFormats48Bit[]	=
{
	VK_FORMAT_R16G16B16_UNORM,
	VK_FORMAT_R16G16B16_SNORM,
	VK_FORMAT_R16G16B16_USCALED,
	VK_FORMAT_R16G16B16_SSCALED,
	VK_FORMAT_R16G16B16_UINT,
	VK_FORMAT_R16G16B16_SINT,
	VK_FORMAT_R16G16B16_SFLOAT,

	VK_FORMAT_UNDEFINED
};
const VkFormat	compatibleFormats64Bit[]	=
{
	VK_FORMAT_R16G16B16A16_UNORM,
	VK_FORMAT_R16G16B16A16_SNORM,
	VK_FORMAT_R16G16B16A16_USCALED,
	VK_FORMAT_R16G16B16A16_SSCALED,
	VK_FORMAT_R16G16B16A16_UINT,
	VK_FORMAT_R16G16B16A16_SINT,
	VK_FORMAT_R16G16B16A16_SFLOAT,
	VK_FORMAT_R32G32_UINT,
	VK_FORMAT_R32G32_SINT,
	VK_FORMAT_R32G32_SFLOAT,
	VK_FORMAT_R64_UINT,
	VK_FORMAT_R64_SINT,
	VK_FORMAT_R64_SFLOAT,

	VK_FORMAT_BC1_RGB_UNORM_BLOCK,
	VK_FORMAT_BC1_RGB_SRGB_BLOCK,
	VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
	VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
	VK_FORMAT_BC4_UNORM_BLOCK,
	VK_FORMAT_BC4_SNORM_BLOCK,

	VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
	VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
	VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
	VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,

	VK_FORMAT_EAC_R11_UNORM_BLOCK,
	VK_FORMAT_EAC_R11_SNORM_BLOCK,

	VK_FORMAT_UNDEFINED
};
const VkFormat	compatibleFormats96Bit[]	=
{
	VK_FORMAT_R32G32B32_UINT,
	VK_FORMAT_R32G32B32_SINT,
	VK_FORMAT_R32G32B32_SFLOAT,

	VK_FORMAT_UNDEFINED
};
const VkFormat	compatibleFormats128Bit[]	=
{
	VK_FORMAT_R32G32B32A32_UINT,
	VK_FORMAT_R32G32B32A32_SINT,
	VK_FORMAT_R32G32B32A32_SFLOAT,
	VK_FORMAT_R64G64_UINT,
	VK_FORMAT_R64G64_SINT,
	VK_FORMAT_R64G64_SFLOAT,

	VK_FORMAT_BC2_UNORM_BLOCK,
	VK_FORMAT_BC2_SRGB_BLOCK,
	VK_FORMAT_BC3_UNORM_BLOCK,
	VK_FORMAT_BC3_SRGB_BLOCK,
	VK_FORMAT_BC5_UNORM_BLOCK,
	VK_FORMAT_BC5_SNORM_BLOCK,
	VK_FORMAT_BC6H_UFLOAT_BLOCK,
	VK_FORMAT_BC6H_SFLOAT_BLOCK,
	VK_FORMAT_BC7_UNORM_BLOCK,
	VK_FORMAT_BC7_SRGB_BLOCK,

	VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
	VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,

	VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
	VK_FORMAT_EAC_R11G11_SNORM_BLOCK,

	VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
	VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
	VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
	VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
	VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
	VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
	VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
	VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
	VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
	VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
	VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
	VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
	VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
	VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
	VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
	VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
	VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
	VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
	VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
	VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
	VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
	VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
	VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
	VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
	VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
	VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
	VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
	VK_FORMAT_ASTC_12x12_SRGB_BLOCK,

	VK_FORMAT_UNDEFINED
};
const VkFormat	compatibleFormats192Bit[]	=
{
	VK_FORMAT_R64G64B64_UINT,
	VK_FORMAT_R64G64B64_SINT,
	VK_FORMAT_R64G64B64_SFLOAT,

	VK_FORMAT_UNDEFINED
};
const VkFormat	compatibleFormats256Bit[]	=
{
	VK_FORMAT_R64G64B64A64_UINT,
	VK_FORMAT_R64G64B64A64_SINT,
	VK_FORMAT_R64G64B64A64_SFLOAT,

	VK_FORMAT_UNDEFINED
};

const VkFormat*	colorImageFormatsToTest[]	=
{
	compatibleFormats8Bit,
	compatibleFormats16Bit,
	compatibleFormats24Bit,
	compatibleFormats32Bit,
	compatibleFormats48Bit,
	compatibleFormats64Bit,
	compatibleFormats96Bit,
	compatibleFormats128Bit,
	compatibleFormats192Bit,
	compatibleFormats256Bit
};

const VkFormat	dedicatedAllocationImageToImageFormatsToTest[]	=
{
	// From compatibleFormats8Bit
	VK_FORMAT_R4G4_UNORM_PACK8,
	VK_FORMAT_R8_SRGB,

	// From compatibleFormats16Bit
	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
	VK_FORMAT_R16_SFLOAT,

	// From compatibleFormats24Bit
	VK_FORMAT_R8G8B8_UNORM,
	VK_FORMAT_B8G8R8_SRGB,

	// From compatibleFormats32Bit
	VK_FORMAT_R8G8B8A8_UNORM,
	VK_FORMAT_R32_SFLOAT,

	// From compatibleFormats48Bit
	VK_FORMAT_R16G16B16_UNORM,
	VK_FORMAT_R16G16B16_SFLOAT,

	// From compatibleFormats64Bit
	VK_FORMAT_R16G16B16A16_UNORM,
	VK_FORMAT_R64_SFLOAT,

	// From compatibleFormats96Bit
	VK_FORMAT_R32G32B32_UINT,
	VK_FORMAT_R32G32B32_SFLOAT,

	// From compatibleFormats128Bit
	VK_FORMAT_R32G32B32A32_UINT,
	VK_FORMAT_R64G64_SFLOAT,

	// From compatibleFormats192Bit
	VK_FORMAT_R64G64B64_UINT,
	VK_FORMAT_R64G64B64_SFLOAT,

	// From compatibleFormats256Bit
	VK_FORMAT_R64G64B64A64_UINT,
	VK_FORMAT_R64G64B64A64_SFLOAT,
};

void addImageToImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	if (allocationKind == ALLOCATION_KIND_DEDICATED)
	{
		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
			dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
	}

	// 2D tests.
	{
		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));

		TestParams	params;
		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
		params.src.image.extent		= defaultExtent;
		params.dst.image.extent		= defaultExtent;
		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
		params.allocationKind		= allocationKind;
		params.extensionUse			= extensionUse;

		for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
		{
			const VkImageCopy				testCopy =
			{
				defaultSourceLayer,								// VkImageSubresourceLayers	srcSubresource;
				{0, 0, 0},										// VkOffset3D				srcOffset;
				defaultSourceLayer,								// VkImageSubresourceLayers	dstSubresource;
				{i, defaultSize - i - defaultFourthSize, 0},	// VkOffset3D				dstOffset;
				{defaultFourthSize, defaultFourthSize, 1},		// VkExtent3D				extent;
			};

			CopyRegion	imageCopy;
			imageCopy.imageCopy = testCopy;

			params.regions.push_back(imageCopy);
		}

		const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
		{
			const VkFormat*	compatibleFormats	= colorImageFormatsToTest[compatibleFormatsIndex];
			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
			{
				params.src.image.format = compatibleFormats[srcFormatIndex];
				if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
					continue;

				CopyColorTestParams	testParams;
				testParams.params				= params;
				testParams.compatibleFormats	= compatibleFormats;

				const std::string testName		= getFormatCaseName(params.src.image.format);
				const std::string description	= "Copy from source format " + getFormatCaseName(params.src.image.format);
				addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
			}
		}

		group->addChild(subGroup.release());
	}

	// 1D tests.
	{
		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));

		TestParams	params;
		params.src.image.imageType	= VK_IMAGE_TYPE_1D;
		params.dst.image.imageType	= VK_IMAGE_TYPE_1D;
		params.src.image.extent		= default1dExtent;
		params.dst.image.extent		= default1dExtent;
		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
		params.allocationKind		= allocationKind;
		params.extensionUse			= extensionUse;

		for (deInt32 i = defaultFourthSize; i < defaultSize; i += defaultSize / 2)
		{
			const VkImageCopy				testCopy =
			{
				defaultSourceLayer,			// VkImageSubresourceLayers	srcSubresource;
				{0, 0, 0},					// VkOffset3D				srcOffset;
				defaultSourceLayer,			// VkImageSubresourceLayers	dstSubresource;
				{i, 0, 0},					// VkOffset3D				dstOffset;
				{defaultFourthSize, 1, 1},	// VkExtent3D				extent;
			};

			CopyRegion	imageCopy;
			imageCopy.imageCopy = testCopy;

			params.regions.push_back(imageCopy);
		}

		const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
		{
			const VkFormat*	compatibleFormats	= colorImageFormatsToTest[compatibleFormatsIndex];
			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
			{
				params.src.image.format = compatibleFormats[srcFormatIndex];
				if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
					continue;

				CopyColorTestParams	testParams;
				testParams.params				= params;
				testParams.compatibleFormats	= nullptr;

				const std::string testName		= getFormatCaseName(params.src.image.format);
				const std::string description	= "Copy from source format " + getFormatCaseName(params.src.image.format);
				addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
			}
		}

		group->addChild(subGroup.release());
	}

	// 3D tests. Note we use smaller dimensions here for performance reasons.
	{
		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));

		TestParams	params;
		params.src.image.imageType	= VK_IMAGE_TYPE_3D;
		params.dst.image.imageType	= VK_IMAGE_TYPE_3D;
		params.src.image.extent		= default3dExtent;
		params.dst.image.extent		= default3dExtent;
		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
		params.allocationKind		= allocationKind;
		params.extensionUse			= extensionUse;

		for (deInt32 i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
		{
			const VkImageCopy				testCopy =
			{
				defaultSourceLayer,													// VkImageSubresourceLayers	srcSubresource;
				{0, 0, 0},															// VkOffset3D				srcOffset;
				defaultSourceLayer,													// VkImageSubresourceLayers	dstSubresource;
				{i, defaultFourthSize - i - defaultSixteenthSize, i},				// VkOffset3D				dstOffset;
				{defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize},	// VkExtent3D				extent;
			};

			CopyRegion	imageCopy;
			imageCopy.imageCopy = testCopy;

			params.regions.push_back(imageCopy);
		}

		const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
		{
			const VkFormat*	compatibleFormats	= colorImageFormatsToTest[compatibleFormatsIndex];
			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
			{
				params.src.image.format = compatibleFormats[srcFormatIndex];
				if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
					continue;

				CopyColorTestParams	testParams;
				testParams.params				= params;
				testParams.compatibleFormats	= nullptr;

				const std::string testName		= getFormatCaseName(params.src.image.format);
				const std::string description	= "Copy from source format " + getFormatCaseName(params.src.image.format);
				addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
			}
		}

		group->addChild(subGroup.release());
	}
}

void addImageToImageDimensionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	tcu::TestContext&		testCtx				= group->getTestContext();

	const VkFormat			testFormats[][2]	=
	{
		// From compatibleFormats8Bit
		{
			VK_FORMAT_R4G4_UNORM_PACK8,
			VK_FORMAT_R8_SRGB
		},
		// From compatibleFormats16Bit
		{
			VK_FORMAT_R4G4B4A4_UNORM_PACK16,
			VK_FORMAT_R16_SFLOAT,
		},
		// From compatibleFormats24Bit
		{
			VK_FORMAT_R8G8B8_UNORM,
			VK_FORMAT_B8G8R8_SRGB
		},
		// From compatibleFormats32Bit
		{
			VK_FORMAT_R8G8B8A8_UNORM,
			VK_FORMAT_R32_SFLOAT
		},
		// From compatibleFormats48Bit
		{
			VK_FORMAT_R16G16B16_UNORM,
			VK_FORMAT_R16G16B16_SFLOAT
		},
		// From compatibleFormats64Bit
		{
			VK_FORMAT_R16G16B16A16_UNORM,
			VK_FORMAT_R64_SFLOAT
		},
		// From compatibleFormats96Bit
		{
			VK_FORMAT_R32G32B32_UINT,
			VK_FORMAT_R32G32B32_SFLOAT
		},
		// From compatibleFormats128Bit
		{
			VK_FORMAT_R32G32B32A32_UINT,
			VK_FORMAT_R64G64_SFLOAT
		},
		// From compatibleFormats192Bit
		{
			VK_FORMAT_R64G64B64_UINT,
			VK_FORMAT_R64G64B64_SFLOAT,
		},
		// From compatibleFormats256Bit
		{
			VK_FORMAT_R64G64B64A64_UINT,
			VK_FORMAT_R64G64B64A64_SFLOAT
		}
	};

	const tcu::UVec2		imageDimensions[]	=
	{
		// large pot x small pot
		tcu::UVec2(4096,	4u),
		tcu::UVec2(8192,	4u),
		tcu::UVec2(16384,	4u),
		tcu::UVec2(32768,	4u),

		// large pot x small npot
		tcu::UVec2(4096,	6u),
		tcu::UVec2(8192,	6u),
		tcu::UVec2(16384,	6u),
		tcu::UVec2(32768,	6u),

		// small pot x large pot
		tcu::UVec2(4u, 4096),
		tcu::UVec2(4u, 8192),
		tcu::UVec2(4u, 16384),
		tcu::UVec2(4u, 32768),

		// small npot x large pot
		tcu::UVec2(6u, 4096),
		tcu::UVec2(6u, 8192),
		tcu::UVec2(6u, 16384),
		tcu::UVec2(6u, 32768)
	};

	const VkImageLayout		copySrcLayouts[]	=
	{
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
		VK_IMAGE_LAYOUT_GENERAL
	};

	const VkImageLayout		copyDstLayouts[]	=
	{
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
		VK_IMAGE_LAYOUT_GENERAL
	};

	if (allocationKind == ALLOCATION_KIND_DEDICATED)
	{
		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats); compatibleFormatsIndex++)
			dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
	}

	// Image dimensions
	for (size_t dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(imageDimensions); dimensionNdx++)
	{
		CopyRegion				copyRegion;
		CopyColorTestParams		testParams;

		const VkExtent3D		extent			= { imageDimensions[dimensionNdx].x(), imageDimensions[dimensionNdx].y(), 1 };

		const VkImageCopy		testCopy		=
		{
			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
			{0, 0, 0},			// VkOffset3D				srcOffset;
			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
			{0, 0, 0},			// VkOffset3D				dstOffset;
			extent,				// VkExtent3D				extent;
		};

		testParams.params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
		testParams.params.src.image.imageType	= VK_IMAGE_TYPE_2D;
		testParams.params.src.image.extent		= extent;

		testParams.params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
		testParams.params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
		testParams.params.dst.image.extent		= extent;

		copyRegion.imageCopy					= testCopy;
		testParams.params.allocationKind		= allocationKind;
		testParams.params.extensionUse			= extensionUse;

		testParams.params.regions.push_back(copyRegion);

		const std::string	dimensionStr		= "src" + de::toString(testParams.params.src.image.extent.width) + "x" + de::toString(testParams.params.src.image.extent.height)
												  + "_dst" + de::toString(testParams.params.dst.image.extent.width) + "x" + de::toString(testParams.params.dst.image.extent.height);
		tcu::TestCaseGroup*	imageSizeGroup		= new tcu::TestCaseGroup(testCtx, dimensionStr.c_str(), ("Image sizes " + dimensionStr).c_str());

		// Compatible formats for copying
		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats); compatibleFormatsIndex++)
		{
			const VkFormat* compatibleFormats = testFormats[compatibleFormatsIndex];

			testParams.compatibleFormats = compatibleFormats;

			// Source image format
			for (int srcFormatIndex = 0; srcFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); srcFormatIndex++)
			{
				testParams.params.src.image.format = testParams.compatibleFormats[srcFormatIndex];

				if (!isSupportedByFramework(testParams.params.src.image.format) && !isCompressedFormat(testParams.params.src.image.format))
					continue;

				const std::string	srcDescription	= "Copy from source format " + getFormatCaseName(testParams.params.src.image.format);
				tcu::TestCaseGroup*	srcFormatGroup	= new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.src.image.format).c_str(), srcDescription.c_str());

				// Destination image format
				for (int dstFormatIndex = 0; dstFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); dstFormatIndex++)
				{
					testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];

					if (!isSupportedByFramework(testParams.params.dst.image.format) && !isCompressedFormat(testParams.params.dst.image.format))
						continue;

					if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
						continue;

					if (isCompressedFormat(testParams.params.src.image.format) && isCompressedFormat(testParams.params.dst.image.format))
					{
						if ((getBlockWidth(testParams.params.src.image.format) != getBlockWidth(testParams.params.dst.image.format))
							|| (getBlockHeight(testParams.params.src.image.format) != getBlockHeight(testParams.params.dst.image.format)))
							continue;
					}

					const std::string	dstDescription	= "Copy to destination format " + getFormatCaseName(testParams.params.dst.image.format);
					tcu::TestCaseGroup*	dstFormatGroup	= new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.dst.image.format).c_str(), dstDescription.c_str());

					// Source/destionation image layouts
					for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); srcLayoutNdx++)
					{
						testParams.params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];

						for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); dstLayoutNdx++)
						{
							testParams.params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];

							const std::string	testName	= getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
							const std::string	description	= "From layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) + " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
							const TestParams	params		= testParams.params;

							dstFormatGroup->addChild(new CopyImageToImageTestCase(testCtx, testName, description, params));
						}
					}

					srcFormatGroup->addChild(dstFormatGroup);
				}

				imageSizeGroup->addChild(srcFormatGroup);
			}
		}

		group->addChild(imageSizeGroup);
	}
}

void addImageToImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
{
	const VkImageLayout copySrcLayouts[]		=
	{
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
		VK_IMAGE_LAYOUT_GENERAL
	};
	const VkImageLayout copyDstLayouts[]		=
	{
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
		VK_IMAGE_LAYOUT_GENERAL
	};

	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
	{
		params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
		{
			params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];

			const std::string testName		= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
											  getImageLayoutCaseName(params.dst.image.operationLayout);
			const std::string description	= "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
			group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
		}
	}
}

void addImageToImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	const VkFormat	depthAndStencilFormats[]	=
	{
		VK_FORMAT_D16_UNORM,
		VK_FORMAT_X8_D24_UNORM_PACK32,
		VK_FORMAT_D32_SFLOAT,
		VK_FORMAT_S8_UINT,
		VK_FORMAT_D16_UNORM_S8_UINT,
		VK_FORMAT_D24_UNORM_S8_UINT,
		VK_FORMAT_D32_SFLOAT_S8_UINT,
	};

	// 2D tests.
	{
		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));

		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
		{
			TestParams	params;
			params.src.image.imageType			= VK_IMAGE_TYPE_2D;
			params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
			params.src.image.extent				= defaultExtent;
			params.dst.image.extent				= defaultExtent;
			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
			params.dst.image.format				= params.src.image.format;
			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
			params.allocationKind				= allocationKind;
			params.extensionUse					= extensionUse;
			params.separateDepthStencilLayouts	= DE_FALSE;

			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);

			const VkImageSubresourceLayers		defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
			const VkImageSubresourceLayers		defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
			const VkImageSubresourceLayers		defaultDSSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };

			for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
			{
				CopyRegion			copyRegion;
				const VkOffset3D	srcOffset	= {0, 0, 0};
				const VkOffset3D	dstOffset	= {i, defaultSize - i - defaultFourthSize, 0};
				const VkExtent3D	extent		= {defaultFourthSize, defaultFourthSize, 1};

				if (hasDepth)
				{
					const VkImageCopy				testCopy	=
					{
						defaultDepthSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
						srcOffset,					// VkOffset3D				srcOffset;
						defaultDepthSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
						dstOffset,					// VkOffset3D				dstOffset;
						extent,						// VkExtent3D				extent;
					};

					copyRegion.imageCopy	= testCopy;
					params.regions.push_back(copyRegion);
				}
				if (hasStencil)
				{
					const VkImageCopy				testCopy	=
					{
						defaultStencilSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
						srcOffset,					// VkOffset3D				srcOffset;
						defaultStencilSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
						dstOffset,					// VkOffset3D				dstOffset;
						extent,						// VkExtent3D				extent;
					};

					copyRegion.imageCopy	= testCopy;
					params.regions.push_back(copyRegion);
				}
			}

			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
			const std::string description	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
			addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);

			if (hasDepth && hasStencil)
			{
				params.separateDepthStencilLayouts	= DE_TRUE;
				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
				const std::string description2	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
				addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);

				// DS Image copy
				{
					params.separateDepthStencilLayouts	= DE_FALSE;
					// Clear previous vkImageCopy elements
					params.regions.clear();

					for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
					{
						CopyRegion			copyRegion;
						const VkOffset3D	srcOffset	= {0, 0, 0};
						const VkOffset3D	dstOffset	= {i, defaultSize - i - defaultFourthSize, 0};
						const VkExtent3D	extent		= {defaultFourthSize, defaultFourthSize, 1};

						const VkImageCopy				testCopy	=
						{
							defaultDSSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
							srcOffset,					// VkOffset3D				srcOffset;
							defaultDSSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
							dstOffset,					// VkOffset3D				dstOffset;
							extent,						// VkExtent3D				extent;
						};

						copyRegion.imageCopy	= testCopy;
						params.regions.push_back(copyRegion);
					}

					const std::string testName3		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_depth_stencil_aspects";
					const std::string description3	= "Copy both depth and stencil aspects from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
					addTestGroup(subGroup.get(), testName3, description3, addImageToImageAllFormatsDepthStencilFormatsTests, params);
				}
			}
		}

		group->addChild(subGroup.release());
	}

	// 1D tests.
	{
		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));

		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
		{
			TestParams	params;
			params.src.image.imageType			= VK_IMAGE_TYPE_1D;
			params.dst.image.imageType			= VK_IMAGE_TYPE_1D;
			params.src.image.extent				= default1dExtent;
			params.dst.image.extent				= default1dExtent;
			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
			params.dst.image.format				= params.src.image.format;
			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
			params.allocationKind				= allocationKind;
			params.extensionUse					= extensionUse;

			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);

			const VkImageSubresourceLayers		defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
			const VkImageSubresourceLayers		defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };

			for (deInt32 i = defaultFourthSize; i < defaultSize; i += defaultSize / 2)
			{
				CopyRegion			copyRegion;
				const VkOffset3D	srcOffset	= {0, 0, 0};
				const VkOffset3D	dstOffset	= {i, 0, 0};
				const VkExtent3D	extent		= {defaultFourthSize, 1, 1};

				if (hasDepth)
				{
					const VkImageCopy				testCopy	=
					{
						defaultDepthSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
						srcOffset,					// VkOffset3D				srcOffset;
						defaultDepthSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
						dstOffset,					// VkOffset3D				dstOffset;
						extent,						// VkExtent3D				extent;
					};

					copyRegion.imageCopy	= testCopy;
					params.regions.push_back(copyRegion);
				}
				if (hasStencil)
				{
					const VkImageCopy				testCopy	=
					{
						defaultStencilSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
						srcOffset,					// VkOffset3D				srcOffset;
						defaultStencilSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
						dstOffset,					// VkOffset3D				dstOffset;
						extent,						// VkExtent3D				extent;
					};

					copyRegion.imageCopy	= testCopy;
					params.regions.push_back(copyRegion);
				}
			}

			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
			const std::string description	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
			addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);

			if (hasDepth && hasStencil)
			{
				params.separateDepthStencilLayouts	= DE_TRUE;
				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
				const std::string description2	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
				addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
			}
		}

		group->addChild(subGroup.release());
	}

	// 3D tests. Note we use smaller dimensions here for performance reasons.
	{
		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));

		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
		{
			TestParams	params;
			params.src.image.imageType			= VK_IMAGE_TYPE_3D;
			params.dst.image.imageType			= VK_IMAGE_TYPE_3D;
			params.src.image.extent				= default3dExtent;
			params.dst.image.extent				= default3dExtent;
			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
			params.dst.image.format				= params.src.image.format;
			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
			params.allocationKind				= allocationKind;
			params.extensionUse					= extensionUse;

			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);

			const VkImageSubresourceLayers		defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
			const VkImageSubresourceLayers		defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };

			for (deInt32 i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
			{
				CopyRegion			copyRegion;
				const VkOffset3D	srcOffset	= {0, 0, 0};
				const VkOffset3D	dstOffset	= {i, defaultFourthSize - i - defaultSixteenthSize, i};
				const VkExtent3D	extent		= {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize};

				if (hasDepth)
				{
					const VkImageCopy				testCopy	=
					{
						defaultDepthSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
						srcOffset,					// VkOffset3D				srcOffset;
						defaultDepthSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
						dstOffset,					// VkOffset3D				dstOffset;
						extent,						// VkExtent3D				extent;
					};

					copyRegion.imageCopy	= testCopy;
					params.regions.push_back(copyRegion);
				}
				if (hasStencil)
				{
					const VkImageCopy				testCopy	=
					{
						defaultStencilSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
						srcOffset,					// VkOffset3D				srcOffset;
						defaultStencilSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
						dstOffset,					// VkOffset3D				dstOffset;
						extent,						// VkExtent3D				extent;
					};

					copyRegion.imageCopy	= testCopy;
					params.regions.push_back(copyRegion);
				}
			}

			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
			const std::string description	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
			addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);

			if (hasDepth && hasStencil)
			{
				params.separateDepthStencilLayouts	= DE_TRUE;
				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
				const std::string description2	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
				addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
			}
		}

		group->addChild(subGroup.release());
	}
}

void addImageToImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	addTestGroup(group, "color", "Copy image to image with color formats", addImageToImageAllFormatsColorTests, allocationKind, extensionUse);
	addTestGroup(group, "depth_stencil", "Copy image to image with depth/stencil formats", addImageToImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
}

void addImageToImage3dImagesTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	tcu::TestContext& testCtx	= group->getTestContext();

	{
		TestParams	params3DTo2D;
		const deUint32	slicesLayers			= 16u;
		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		params3DTo2D.src.image.extent			= defaultHalfExtent;
		params3DTo2D.src.image.extent.depth		= slicesLayers;
		params3DTo2D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		params3DTo2D.dst.image.extent			= defaultHalfExtent;
		params3DTo2D.dst.image.extent.depth		= slicesLayers;
		params3DTo2D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params3DTo2D.allocationKind				= allocationKind;
		params3DTo2D.extensionUse				= extensionUse;

		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
		{
			const VkImageSubresourceLayers	sourceLayer	=
			{
				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
				0u,							// deUint32				mipLevel;
				0u,							// deUint32				baseArrayLayer;
				1u							// deUint32				layerCount;
			};

			const VkImageSubresourceLayers	destinationLayer	=
			{
				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
				0u,							// deUint32				mipLevel;
				slicesLayersNdx,			// deUint32				baseArrayLayer;
				1u							// deUint32				layerCount;
			};

			const VkImageCopy				testCopy	=
			{
				sourceLayer,						// VkImageSubresourceLayers	srcSubresource;
				{0, 0, (deInt32)slicesLayersNdx},	// VkOffset3D				srcOffset;
				destinationLayer,					// VkImageSubresourceLayers	dstSubresource;
				{0, 0, 0},							// VkOffset3D				dstOffset;
				defaultHalfExtent,					// VkExtent3D				extent;
			};

			CopyRegion	imageCopy;
			imageCopy.imageCopy	= testCopy;

			params3DTo2D.regions.push_back(imageCopy);
		}
		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D));
	}

	{
		TestParams	params2DTo3D;
		const deUint32	slicesLayers			= 16u;
		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		params2DTo3D.src.image.extent			= defaultHalfExtent;
		params2DTo3D.src.image.extent.depth		= slicesLayers;
		params2DTo3D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		params2DTo3D.dst.image.extent			= defaultHalfExtent;
		params2DTo3D.dst.image.extent.depth		= slicesLayers;
		params2DTo3D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params2DTo3D.allocationKind				= allocationKind;
		params2DTo3D.extensionUse				= extensionUse;

		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
		{
			const VkImageSubresourceLayers	sourceLayer	=
			{
				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
				0u,							// deUint32				mipLevel;
				slicesLayersNdx,			// deUint32				baseArrayLayer;
				1u							// deUint32				layerCount;
			};

			const VkImageSubresourceLayers	destinationLayer	=
			{
				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
				0u,							// deUint32				mipLevel;
				0u,							// deUint32				baseArrayLayer;
				1u							// deUint32				layerCount;
			};

			const VkImageCopy				testCopy	=
			{
				sourceLayer,						// VkImageSubresourceLayers	srcSubresource;
				{0, 0, 0},							// VkOffset3D				srcOffset;
				destinationLayer,					// VkImageSubresourceLayers	dstSubresource;
				{0, 0, (deInt32)slicesLayersNdx},	// VkOffset3D				dstOffset;
				defaultHalfExtent,					// VkExtent3D				extent;
			};

			CopyRegion	imageCopy;
			imageCopy.imageCopy	= testCopy;

			params2DTo3D.regions.push_back(imageCopy);
		}

		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D));
	}

	{
		TestParams	params3DTo2D;
		const deUint32	slicesLayers			= 16u;
		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		params3DTo2D.src.image.extent			= defaultHalfExtent;
		params3DTo2D.src.image.extent.depth		= slicesLayers;
		params3DTo2D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		params3DTo2D.dst.image.extent			= defaultHalfExtent;
		params3DTo2D.dst.image.extent.depth		= slicesLayers;
		params3DTo2D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params3DTo2D.allocationKind				= allocationKind;
		params3DTo2D.extensionUse				= extensionUse;

		{
			const VkImageSubresourceLayers	sourceLayer	=
			{
				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
				0u,							// deUint32				mipLevel;
				0u,							// deUint32				baseArrayLayer;
				1u							// deUint32				layerCount;
			};

			const VkImageSubresourceLayers	destinationLayer	=
			{
				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
				0u,							// deUint32				mipLevel;
				0,							// deUint32				baseArrayLayer;
				slicesLayers				// deUint32				layerCount;
			};

			const VkImageCopy				testCopy	=
			{
				sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
				{0, 0, 0},						// VkOffset3D				srcOffset;
				destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
				{0, 0, 0},						// VkOffset3D				dstOffset;
				params3DTo2D.src.image.extent	// VkExtent3D				extent;
			};

			CopyRegion	imageCopy;
			imageCopy.imageCopy	= testCopy;

			params3DTo2D.regions.push_back(imageCopy);
		}
		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D));
	}

	{
		TestParams	params2DTo3D;
		const deUint32	slicesLayers			= 16u;
		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		params2DTo3D.src.image.extent			= defaultHalfExtent;
		params2DTo3D.src.image.extent.depth		= slicesLayers;
		params2DTo3D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		params2DTo3D.dst.image.extent			= defaultHalfExtent;
		params2DTo3D.dst.image.extent.depth		= slicesLayers;
		params2DTo3D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params2DTo3D.allocationKind				= allocationKind;
		params2DTo3D.extensionUse				= extensionUse;

		{
			const VkImageSubresourceLayers	sourceLayer	=
			{
				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
				0u,							// deUint32				mipLevel;
				0u,							// deUint32				baseArrayLayer;
				slicesLayers				// deUint32				layerCount;
			};

			const VkImageSubresourceLayers	destinationLayer	=
			{
				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
				0u,							// deUint32				mipLevel;
				0u,							// deUint32				baseArrayLayer;
				1u							// deUint32				layerCount;
			};

			const VkImageCopy				testCopy	=
			{
				sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
				{0, 0, 0},						// VkOffset3D				srcOffset;
				destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
				{0, 0, 0},						// VkOffset3D				dstOffset;
				params2DTo3D.src.image.extent,	// VkExtent3D				extent;
			};

			CopyRegion	imageCopy;
			imageCopy.imageCopy	= testCopy;

			params2DTo3D.regions.push_back(imageCopy);
		}

		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D));
	}

	{
		TestParams	params3DTo2D;
		const deUint32	slicesLayers			= 16u;
		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		params3DTo2D.src.image.extent			= defaultHalfExtent;
		params3DTo2D.src.image.extent.depth		= slicesLayers;
		params3DTo2D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		params3DTo2D.dst.image.extent			= defaultHalfExtent;
		params3DTo2D.dst.image.extent.depth		= slicesLayers;
		params3DTo2D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params3DTo2D.allocationKind				= allocationKind;
		params3DTo2D.extensionUse				= extensionUse;

		const deUint32 regionWidth				= defaultHalfExtent.width / slicesLayers -1;
		const deUint32 regionHeight				= defaultHalfExtent.height / slicesLayers -1 ;

		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
		{
			const VkImageSubresourceLayers	sourceLayer	=
			{
				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
				0u,							// deUint32				mipLevel;
				0u,							// deUint32				baseArrayLayer;
				1u							// deUint32				layerCount;
			};

			const VkImageSubresourceLayers	destinationLayer	=
			{
					VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
					0u,								// deUint32				mipLevel;
					slicesLayersNdx,				// deUint32				baseArrayLayer;
					1u								// deUint32				layerCount;
			};


			const VkImageCopy				testCopy	=
			{
				sourceLayer,															// VkImageSubresourceLayers	srcSubresource;
				{0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx},	// VkOffset3D				srcOffset;
					destinationLayer,													// VkImageSubresourceLayers	dstSubresource;
					{(deInt32)(regionWidth*slicesLayersNdx), 0, 0},						// VkOffset3D				dstOffset;
					{
						(defaultHalfExtent.width - regionWidth*slicesLayersNdx),
						(defaultHalfExtent.height - regionHeight*slicesLayersNdx),
						1
					}																	// VkExtent3D				extent;
			};

			CopyRegion	imageCopy;
			imageCopy.imageCopy = testCopy;
			params3DTo2D.regions.push_back(imageCopy);
		}
		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D));
	}

	{
		TestParams	params2DTo3D;
		const deUint32	slicesLayers			= 16u;
		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		params2DTo3D.src.image.extent			= defaultHalfExtent;
		params2DTo3D.src.image.extent.depth		= slicesLayers;
		params2DTo3D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		params2DTo3D.dst.image.extent			= defaultHalfExtent;
		params2DTo3D.dst.image.extent.depth		= slicesLayers;
		params2DTo3D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params2DTo3D.allocationKind				= allocationKind;
		params2DTo3D.extensionUse				= extensionUse;

		const deUint32 regionWidth				= defaultHalfExtent.width / slicesLayers -1;
		const deUint32 regionHeight				= defaultHalfExtent.height / slicesLayers -1 ;

		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
		{
			const VkImageSubresourceLayers	sourceLayer	=
			{
				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
				0u,							// deUint32				mipLevel;
				slicesLayersNdx,			// deUint32				baseArrayLayer;
				1u							// deUint32				layerCount;
			};

			const VkImageSubresourceLayers	destinationLayer	=
			{
				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
				0u,							// deUint32				mipLevel;
				0u,							// deUint32				baseArrayLayer;
				1u							// deUint32				layerCount;
			};

			const VkImageCopy				testCopy	=
			{
				sourceLayer,																// VkImageSubresourceLayers	srcSubresource;
				{(deInt32)(regionWidth*slicesLayersNdx), 0, 0},								// VkOffset3D				srcOffset;
				destinationLayer,															// VkImageSubresourceLayers	dstSubresource;
				{0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)},	// VkOffset3D				dstOffset;
				{
					defaultHalfExtent.width - regionWidth*slicesLayersNdx,
					defaultHalfExtent.height - regionHeight*slicesLayersNdx,
					1
				}																			// VkExtent3D				extent;
			};

			CopyRegion	imageCopy;
			imageCopy.imageCopy	= testCopy;

			params2DTo3D.regions.push_back(imageCopy);
		}

		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D));
	}
}

void addImageToImageCubeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	tcu::TestContext& testCtx	= group->getTestContext();

	{
		TestParams	paramsCubeToArray;
		const deUint32	arrayLayers					= 6u;
		paramsCubeToArray.src.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
		paramsCubeToArray.src.image.imageType		= VK_IMAGE_TYPE_2D;
		paramsCubeToArray.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		paramsCubeToArray.src.image.extent			= defaultHalfExtent;
		paramsCubeToArray.src.image.extent.depth	= arrayLayers;
		paramsCubeToArray.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		paramsCubeToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		paramsCubeToArray.dst.image.createFlags		= 0;
		paramsCubeToArray.dst.image.imageType		= VK_IMAGE_TYPE_2D;
		paramsCubeToArray.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		paramsCubeToArray.dst.image.extent			= defaultHalfExtent;
		paramsCubeToArray.dst.image.extent.depth	= arrayLayers;
		paramsCubeToArray.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		paramsCubeToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		paramsCubeToArray.allocationKind			= allocationKind;
		paramsCubeToArray.extensionUse				= extensionUse;

		for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
		{
			const VkImageSubresourceLayers	sourceLayer	=
				{
					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
					0u,							// deUint32				mipLevel;
					arrayLayersNdx,				// deUint32				baseArrayLayer;
					1u							// deUint32				layerCount;
				};

			const VkImageSubresourceLayers	destinationLayer	=
				{
					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
					0u,							// deUint32				mipLevel;
					arrayLayersNdx,				// deUint32				baseArrayLayer;
					1u							// deUint32				layerCount;
				};

			const VkImageCopy				testCopy	=
				{
					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
					{0, 0, 0},					// VkOffset3D				srcOffset;
					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
					{0, 0, 0},					// VkOffset3D				dstOffset;
					defaultHalfExtent				// VkExtent3D				extent;
				};

			CopyRegion	imageCopy;
			imageCopy.imageCopy	= testCopy;

			paramsCubeToArray.regions.push_back(imageCopy);
		}

		group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_layers", "copy cube compatible image to 2d layers layer by layer", paramsCubeToArray));
	}

	{
		TestParams	paramsCubeToArray;
		const deUint32	arrayLayers					= 6u;
		paramsCubeToArray.src.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
		paramsCubeToArray.src.image.imageType		= VK_IMAGE_TYPE_2D;
		paramsCubeToArray.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		paramsCubeToArray.src.image.extent			= defaultHalfExtent;
		paramsCubeToArray.src.image.extent.depth	= arrayLayers;
		paramsCubeToArray.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		paramsCubeToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		paramsCubeToArray.dst.image.createFlags		= 0;
		paramsCubeToArray.dst.image.imageType		= VK_IMAGE_TYPE_2D;
		paramsCubeToArray.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		paramsCubeToArray.dst.image.extent			= defaultHalfExtent;
		paramsCubeToArray.dst.image.extent.depth	= arrayLayers;
		paramsCubeToArray.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		paramsCubeToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		paramsCubeToArray.allocationKind			= allocationKind;
		paramsCubeToArray.extensionUse				= extensionUse;

		{
			const VkImageSubresourceLayers	sourceLayer	=
				{
					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
					0u,							// deUint32				mipLevel;
					0u,							// deUint32				baseArrayLayer;
					arrayLayers					// deUint32				layerCount;
				};

			const VkImageSubresourceLayers	destinationLayer	=
				{
					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
					0u,							// deUint32				mipLevel;
					0u,							// deUint32				baseArrayLayer;
					arrayLayers					// deUint32				layerCount;
				};

			const VkImageCopy				testCopy	=
				{
					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
					{0, 0, 0},					// VkOffset3D				srcOffset;
					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
					{0, 0, 0},					// VkOffset3D				dstOffset;
					defaultHalfExtent			// VkExtent3D				extent;
				};

			CopyRegion	imageCopy;
			imageCopy.imageCopy	= testCopy;

			paramsCubeToArray.regions.push_back(imageCopy);
		}

		group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_whole", "copy cube compatible image to 2d layers all at once", paramsCubeToArray));
	}

	{
		TestParams	paramsArrayToCube;
		const deUint32	arrayLayers					= 6u;
		paramsArrayToCube.src.image.createFlags		= 0;
		paramsArrayToCube.src.image.imageType		= VK_IMAGE_TYPE_2D;
		paramsArrayToCube.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		paramsArrayToCube.src.image.extent			= defaultHalfExtent;
		paramsArrayToCube.src.image.extent.depth	= arrayLayers;
		paramsArrayToCube.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		paramsArrayToCube.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		paramsArrayToCube.dst.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
		paramsArrayToCube.dst.image.imageType		= VK_IMAGE_TYPE_2D;
		paramsArrayToCube.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		paramsArrayToCube.dst.image.extent			= defaultHalfExtent;
		paramsArrayToCube.dst.image.extent.depth	= arrayLayers;
		paramsArrayToCube.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		paramsArrayToCube.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		paramsArrayToCube.allocationKind			= allocationKind;
		paramsArrayToCube.extensionUse				= extensionUse;

		for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
		{
			const VkImageSubresourceLayers	sourceLayer	=
				{
					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
					0u,							// deUint32				mipLevel;
					arrayLayersNdx,				// deUint32				baseArrayLayer;
					1u							// deUint32				layerCount;
				};

			const VkImageSubresourceLayers	destinationLayer =
				{
					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
					0u,							// deUint32				mipLevel;
					arrayLayersNdx,				// deUint32				baseArrayLayer;
					1u							// deUint32				layerCount;
				};

			const VkImageCopy				testCopy =
				{
					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
					{0, 0, 0},					// VkOffset3D				srcOffset;
					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
					{0, 0, 0},					// VkOffset3D				dstOffset;
					defaultHalfExtent			// VkExtent3D				extent;
				};

			CopyRegion	imageCopy;
			imageCopy.imageCopy	= testCopy;

			paramsArrayToCube.regions.push_back(imageCopy);
		}

		group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_layers", "copy 2d layers to cube compatible image layer by layer", paramsArrayToCube));
	}

	{
		TestParams	paramsArrayToCube;
		const deUint32	arrayLayers					= 6u;
		paramsArrayToCube.src.image.createFlags		= 0;
		paramsArrayToCube.src.image.imageType		= VK_IMAGE_TYPE_2D;
		paramsArrayToCube.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		paramsArrayToCube.src.image.extent			= defaultHalfExtent;
		paramsArrayToCube.src.image.extent.depth	= arrayLayers;
		paramsArrayToCube.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		paramsArrayToCube.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		paramsArrayToCube.dst.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
		paramsArrayToCube.dst.image.imageType		= VK_IMAGE_TYPE_2D;
		paramsArrayToCube.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		paramsArrayToCube.dst.image.extent			= defaultHalfExtent;
		paramsArrayToCube.dst.image.extent.depth	= arrayLayers;
		paramsArrayToCube.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		paramsArrayToCube.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		paramsArrayToCube.allocationKind			= allocationKind;
		paramsArrayToCube.extensionUse				= extensionUse;

		{
			const VkImageSubresourceLayers sourceLayer =
				{
					VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
					0u,								// deUint32				mipLevel;
					0u,								// deUint32				baseArrayLayer;
					arrayLayers						// deUint32				layerCount;
				};

			const VkImageSubresourceLayers destinationLayer =
				{
					VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
					0u,								// deUint32				mipLevel;
					0u,								// deUint32				baseArrayLayer;
					arrayLayers						// deUint32				layerCount;
				};

			const VkImageCopy				testCopy =
				{
					sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
					{0, 0, 0},						// VkOffset3D				srcOffset;
					destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
					{0, 0, 0},						// VkOffset3D				dstOffset;
					defaultHalfExtent				// VkExtent3D				extent;
				};

			CopyRegion imageCopy;
			imageCopy.imageCopy = testCopy;

			paramsArrayToCube.regions.push_back(imageCopy);
		}

		group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_whole", "copy 2d layers to cube compatible image all at once", paramsArrayToCube));
	}

	{
		TestParams	paramsCubeToArray;
		const deUint32	arrayLayers					= 6u;
		paramsCubeToArray.src.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
		paramsCubeToArray.src.image.imageType		= VK_IMAGE_TYPE_2D;
		paramsCubeToArray.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		paramsCubeToArray.src.image.extent			= defaultHalfExtent;
		paramsCubeToArray.src.image.extent.depth	= arrayLayers;
		paramsCubeToArray.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		paramsCubeToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		paramsCubeToArray.dst.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
		paramsCubeToArray.dst.image.imageType		= VK_IMAGE_TYPE_2D;
		paramsCubeToArray.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		paramsCubeToArray.dst.image.extent			= defaultHalfExtent;
		paramsCubeToArray.dst.image.extent.depth	= arrayLayers;
		paramsCubeToArray.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		paramsCubeToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		paramsCubeToArray.allocationKind			= allocationKind;
		paramsCubeToArray.extensionUse				= extensionUse;

		for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
		{
			const VkImageSubresourceLayers	sourceLayer	=
				{
					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
					0u,							// deUint32				mipLevel;
					arrayLayersNdx,				// deUint32				baseArrayLayer;
					1u							// deUint32				layerCount;
				};

			const VkImageSubresourceLayers	destinationLayer	=
				{
					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
					0u,							// deUint32				mipLevel;
					arrayLayersNdx,				// deUint32				baseArrayLayer;
					1u							// deUint32				layerCount;
				};

			const VkImageCopy				testCopy	=
				{
					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
					{0, 0, 0},					// VkOffset3D				srcOffset;
					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
					{0, 0, 0},					// VkOffset3D				dstOffset;
					defaultHalfExtent				// VkExtent3D				extent;
				};

			CopyRegion	imageCopy;
			imageCopy.imageCopy	= testCopy;

			paramsCubeToArray.regions.push_back(imageCopy);
		}

		group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_layers", "copy cube compatible image to cube compatible image layer by layer", paramsCubeToArray));
	}

	{
		TestParams	paramsCubeToCube;
		const deUint32	arrayLayers					= 6u;
		paramsCubeToCube.src.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
		paramsCubeToCube.src.image.imageType		= VK_IMAGE_TYPE_2D;
		paramsCubeToCube.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		paramsCubeToCube.src.image.extent			= defaultHalfExtent;
		paramsCubeToCube.src.image.extent.depth		= arrayLayers;
		paramsCubeToCube.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		paramsCubeToCube.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		paramsCubeToCube.dst.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
		paramsCubeToCube.dst.image.imageType		= VK_IMAGE_TYPE_2D;
		paramsCubeToCube.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		paramsCubeToCube.dst.image.extent			= defaultHalfExtent;
		paramsCubeToCube.dst.image.extent.depth		= arrayLayers;
		paramsCubeToCube.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		paramsCubeToCube.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		paramsCubeToCube.allocationKind				= allocationKind;
		paramsCubeToCube.extensionUse				= extensionUse;

		{
			const VkImageSubresourceLayers	sourceLayer	=
				{
					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
					0u,							// deUint32				mipLevel;
					0u,							// deUint32				baseArrayLayer;
					arrayLayers					// deUint32				layerCount;
				};

			const VkImageSubresourceLayers	destinationLayer	=
				{
					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
					0u,							// deUint32				mipLevel;
					0u,							// deUint32				baseArrayLayer;
					arrayLayers					// deUint32				layerCount;
				};

			const VkImageCopy				testCopy	=
				{
					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
					{0, 0, 0},					// VkOffset3D				srcOffset;
					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
					{0, 0, 0},					// VkOffset3D				dstOffset;
					defaultHalfExtent			// VkExtent3D				extent;
				};

			CopyRegion	imageCopy;
			imageCopy.imageCopy	= testCopy;

			paramsCubeToCube.regions.push_back(imageCopy);
		}

		group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_whole", "copy cube compatible image to cube compatible image all at once", paramsCubeToCube));
	}
}

void addImageToImageArrayTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	tcu::TestContext& testCtx	= group->getTestContext();

	{
		TestParams	paramsArrayToArray;
		const deUint32	arrayLayers					= 16u;
		paramsArrayToArray.src.image.imageType		= VK_IMAGE_TYPE_2D;
		paramsArrayToArray.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		paramsArrayToArray.src.image.extent			= defaultHalfExtent;
		paramsArrayToArray.src.image.extent.depth	= arrayLayers;
		paramsArrayToArray.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		paramsArrayToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		paramsArrayToArray.dst.image.imageType		= VK_IMAGE_TYPE_2D;
		paramsArrayToArray.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
		paramsArrayToArray.dst.image.extent			= defaultHalfExtent;
		paramsArrayToArray.dst.image.extent.depth	= arrayLayers;
		paramsArrayToArray.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
		paramsArrayToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		paramsArrayToArray.allocationKind			= allocationKind;
		paramsArrayToArray.extensionUse				= extensionUse;

		for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
		{
			const VkImageSubresourceLayers	sourceLayer	=
					{
							VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
							0u,							// deUint32				mipLevel;
							arrayLayersNdx,				// deUint32				baseArrayLayer;
							1u							// deUint32				layerCount;
					};

			const VkImageSubresourceLayers	destinationLayer =
					{
							VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
							0u,							// deUint32				mipLevel;
							arrayLayersNdx,				// deUint32				baseArrayLayer;
							1u							// deUint32				layerCount;
					};

			const VkImageCopy				testCopy =
					{
							sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
							{0, 0, 0},					// VkOffset3D				srcOffset;
							destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
							{0, 0, 0},					// VkOffset3D				dstOffset;
							defaultHalfExtent			// VkExtent3D				extent;
					};

			CopyRegion	imageCopy;
			imageCopy.imageCopy	= testCopy;

			paramsArrayToArray.regions.push_back(imageCopy);
		}

		group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_layers", "copy 2d array image to 2d array image layer by layer", paramsArrayToArray));
	}

	{
		TestParams	paramsArrayToArray;
		const deUint32	arrayLayers						= 16u;
		paramsArrayToArray.src.image.imageType			= VK_IMAGE_TYPE_2D;
		paramsArrayToArray.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
		paramsArrayToArray.src.image.extent				= defaultHalfExtent;
		paramsArrayToArray.src.image.extent.depth		= arrayLayers;
		paramsArrayToArray.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		paramsArrayToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		paramsArrayToArray.dst.image.imageType			= VK_IMAGE_TYPE_2D;
		paramsArrayToArray.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
		paramsArrayToArray.dst.image.extent				= defaultHalfExtent;
		paramsArrayToArray.dst.image.extent.depth		= arrayLayers;
		paramsArrayToArray.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		paramsArrayToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		paramsArrayToArray.allocationKind				= allocationKind;
		paramsArrayToArray.extensionUse					= extensionUse;

		{
			const VkImageSubresourceLayers sourceLayer =
					{
							VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
							0u,								// deUint32				mipLevel;
							0u,								// deUint32				baseArrayLayer;
							arrayLayers						// deUint32				layerCount;
					};

			const VkImageSubresourceLayers destinationLayer =
					{
							VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
							0u,								// deUint32				mipLevel;
							0u,								// deUint32				baseArrayLayer;
							arrayLayers						// deUint32				layerCount;
					};

			const VkImageCopy				testCopy =
					{
							sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
							{0, 0, 0},						// VkOffset3D				srcOffset;
							destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
							{0, 0, 0},						// VkOffset3D				dstOffset;
							defaultHalfExtent				// VkExtent3D				extent;
					};

			CopyRegion imageCopy;
			imageCopy.imageCopy = testCopy;

			paramsArrayToArray.regions.push_back(imageCopy);
		}

		group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_whole", "copy 2d array image to 2d array image all at once", paramsArrayToArray));
	}
};

void addImageToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	addTestGroup(group, "simple_tests", "Copy from image to image simple tests", addImageToImageSimpleTests, allocationKind, extensionUse);
	addTestGroup(group, "all_formats", "Copy from image to image with all compatible formats", addImageToImageAllFormatsTests, allocationKind, extensionUse);
	addTestGroup(group, "3d_images", "Coping operations on 3d images", addImageToImage3dImagesTests, allocationKind, extensionUse);
	addTestGroup(group, "dimensions", "Copying operations on different image dimensions", addImageToImageDimensionsTests, allocationKind, extensionUse);
	addTestGroup(group, "cube", "Coping operations on cube compatible images", addImageToImageCubeTests, allocationKind, extensionUse);
	addTestGroup(group, "array", "Copying operations on array of images", addImageToImageArrayTests, allocationKind, extensionUse);
}

void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	tcu::TestContext& testCtx	= group->getTestContext();

	{
		TestParams	params;
		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
		params.src.image.extent				= defaultExtent;
		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		params.dst.buffer.size				= defaultSize * defaultSize;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		const VkBufferImageCopy	bufferImageCopy	=
		{
			0u,											// VkDeviceSize				bufferOffset;
			0u,											// deUint32					bufferRowLength;
			0u,											// deUint32					bufferImageHeight;
			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
			{0, 0, 0},									// VkOffset3D				imageOffset;
			defaultExtent								// VkExtent3D				imageExtent;
		};
		CopyRegion	copyRegion;
		copyRegion.bufferImageCopy	= bufferImageCopy;

		params.regions.push_back(copyRegion);

		group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
	}

	{
		TestParams	params;
		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
		params.src.image.extent				= defaultExtent;
		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		params.dst.buffer.size				= defaultSize * defaultSize;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		const VkBufferImageCopy	bufferImageCopy	=
		{
			defaultSize * defaultHalfSize,				// VkDeviceSize				bufferOffset;
			0u,											// deUint32					bufferRowLength;
			0u,											// deUint32					bufferImageHeight;
			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
			defaultHalfExtent							// VkExtent3D				imageExtent;
		};
		CopyRegion	copyRegion;
		copyRegion.bufferImageCopy	= bufferImageCopy;

		params.regions.push_back(copyRegion);

		group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
	}

	{
		TestParams	params;
		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
		params.src.image.format				= VK_FORMAT_R8_UNORM;
		params.src.image.extent				= defaultExtent;
		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		params.dst.buffer.size				= defaultSize * defaultSize;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		const VkBufferImageCopy	bufferImageCopy	=
		{
			defaultSize * defaultHalfSize + 1u,		// VkDeviceSize				bufferOffset;
			0u,											// deUint32					bufferRowLength;
			0u,											// deUint32					bufferImageHeight;
			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
			defaultHalfExtent							// VkExtent3D				imageExtent;
		};
		CopyRegion	copyRegion;
		copyRegion.bufferImageCopy	= bufferImageCopy;

		params.regions.push_back(copyRegion);

		group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset_relaxed", "Copy from image to buffer with buffer offset not a multiple of 4", params));
	}

	{
		TestParams	params;
		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
		params.src.image.extent				= defaultExtent;
		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		params.dst.buffer.size				= defaultSize * defaultSize;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		const int			pixelSize	= tcu::getPixelSize(mapVkFormat(params.src.image.format));
		const VkDeviceSize	bufferSize	= pixelSize * params.dst.buffer.size;
		const VkDeviceSize	offsetSize	= pixelSize * defaultFourthSize * defaultFourthSize;
		deUint32			divisor		= 1;
		for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
		{
			const deUint32			bufferRowLength		= defaultFourthSize;
			const deUint32			bufferImageHeight	= defaultFourthSize;
			const VkExtent3D		imageExtent			= {defaultFourthSize / divisor, defaultFourthSize, 1};
			DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
			DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
			DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize);

			CopyRegion				region;
			const VkBufferImageCopy	bufferImageCopy		=
			{
				offset,						// VkDeviceSize				bufferOffset;
				bufferRowLength,			// deUint32					bufferRowLength;
				bufferImageHeight,			// deUint32					bufferImageHeight;
				defaultSourceLayer,			// VkImageSubresourceLayers	imageSubresource;
				{0, 0, 0},					// VkOffset3D				imageOffset;
				imageExtent					// VkExtent3D				imageExtent;
			};
			region.bufferImageCopy	= bufferImageCopy;
			params.regions.push_back(region);
		}

		group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
	}

	{
		TestParams				params;
		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
		params.src.image.extent				= defaultExtent;
		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		params.dst.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		const VkBufferImageCopy	bufferImageCopy	=
		{
			0u,											// VkDeviceSize				bufferOffset;
			defaultSize,								// deUint32					bufferRowLength;
			defaultSize,								// deUint32					bufferImageHeight;
			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
			defaultHalfExtent							// VkExtent3D				imageExtent;
		};
		CopyRegion				copyRegion;
		copyRegion.bufferImageCopy	= bufferImageCopy;

		params.regions.push_back(copyRegion);

		group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", "Copy from image to a buffer that is just large enough to contain the data", params));
	}

	{
		TestParams				params;
		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
		params.src.image.extent				= defaultExtent;
		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		params.dst.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		const VkBufferImageCopy	bufferImageCopy	=
		{
			defaultFourthSize,							// VkDeviceSize				bufferOffset;
			defaultSize,								// deUint32					bufferRowLength;
			defaultSize,								// deUint32					bufferImageHeight;
			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
			defaultHalfExtent							// VkExtent3D				imageExtent;
		};
		CopyRegion				copyRegion;
		copyRegion.bufferImageCopy	= bufferImageCopy;

		params.regions.push_back(copyRegion);

		group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer_offset", "Copy from image to a buffer that is just large enough to contain the data", params));
	}

	{
		TestParams				params;
		deUint32				arrayLayers = 16u;
		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
		params.src.image.extent				= defaultHalfExtent;
		params.src.image.extent.depth		= arrayLayers;
		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params.dst.buffer.size				= defaultHalfSize * defaultHalfSize * arrayLayers;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		const int pixelSize	= tcu::getPixelSize(mapVkFormat(params.src.image.format));
		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
		{
			const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
			const VkBufferImageCopy bufferImageCopy =
				{
					offset,													// VkDeviceSize				bufferOffset;
					0u,														// deUint32					bufferRowLength;
					0u,														// deUint32					bufferImageHeight;
					{
						VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
						0u,												// deUint32				mipLevel;
						arrayLayerNdx,									// deUint32				baseArrayLayer;
						1u,												// deUint32				layerCount;
					},														// VkImageSubresourceLayers	imageSubresource;
					{0, 0, 0},												// VkOffset3D				imageOffset;
					defaultHalfExtent										// VkExtent3D				imageExtent;
				};
			CopyRegion copyRegion;
			copyRegion.bufferImageCopy = bufferImageCopy;

			params.regions.push_back(copyRegion);
		}
		group->addChild(new CopyImageToBufferTestCase(testCtx, "array", "Copy each layer from array to buffer", params));
	}

	{
		TestParams				params;
		deUint32				arrayLayers = 16u;
		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
		params.src.image.extent				= defaultHalfExtent;
		params.src.image.extent.depth		= arrayLayers;
		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params.dst.buffer.size				= defaultHalfSize * defaultHalfSize * arrayLayers;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		const int pixelSize	= tcu::getPixelSize(mapVkFormat(params.src.image.format));
		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
		{
			const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
			const VkBufferImageCopy bufferImageCopy =
				{
					offset,													// VkDeviceSize				bufferOffset;
					defaultHalfSize,										// deUint32					bufferRowLength;
					defaultHalfSize,										// deUint32					bufferImageHeight;
					{
						VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
						0u,												// deUint32				mipLevel;
						arrayLayerNdx,									// deUint32				baseArrayLayer;
						1u,												// deUint32				layerCount;
					},														// VkImageSubresourceLayers	imageSubresource;
					{0, 0, 0},												// VkOffset3D				imageOffset;
					defaultHalfExtent										// VkExtent3D				imageExtent;
				};
			CopyRegion copyRegion;
			copyRegion.bufferImageCopy = bufferImageCopy;

			params.regions.push_back(copyRegion);
		}
		group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", "Copy each layer from array to tightly sized buffer", params));
	}
}

void addBufferToDepthStencilTests(tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	tcu::TestContext& testCtx = group->getTestContext();

	const struct
	{
		const char*		name;
		const VkFormat	format;
	} depthAndStencilFormats[] =
	{
		{ "d16_unorm",				VK_FORMAT_D16_UNORM				},
		{ "x8_d24_unorm_pack32",	VK_FORMAT_X8_D24_UNORM_PACK32	},
		{ "d32_sfloat",				VK_FORMAT_D32_SFLOAT			},
		{ "d16_unorm_s8_uint",		VK_FORMAT_D16_UNORM_S8_UINT		},
		{ "d24_unorm_s8_uint",		VK_FORMAT_D24_UNORM_S8_UINT		},
		{ "d32_sfloat_s8_uint",		VK_FORMAT_D32_SFLOAT_S8_UINT	}
	};

	const VkImageSubresourceLayers	depthSourceLayer		=
	{
		VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags	aspectMask;
		0u,							// deUint32				mipLevel;
		0u,							// deUint32				baseArrayLayer;
		1u,							// deUint32				layerCount;
	};

	const VkBufferImageCopy			bufferDepthCopy			=
	{
		0u,											// VkDeviceSize				bufferOffset;
		0u,											// deUint32					bufferRowLength;
		0u,											// deUint32					bufferImageHeight;
		depthSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
		{0, 0, 0},									// VkOffset3D				imageOffset;
		defaultExtent								// VkExtent3D				imageExtent;
	};

	const VkBufferImageCopy			bufferDepthCopyOffset	=
	{
		32,											// VkDeviceSize				bufferOffset;
		defaultHalfSize + defaultFourthSize,		// deUint32					bufferRowLength;
		defaultHalfSize + defaultFourthSize,		// deUint32					bufferImageHeight;
		depthSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
		{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
		defaultHalfExtent							// VkExtent3D				imageExtent;
	};

	const VkImageSubresourceLayers	stencilSourceLayer		=
	{
		VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask;
		0u,								// deUint32				mipLevel;
		0u,								// deUint32				baseArrayLayer;
		1u,								// deUint32				layerCount;
	};

	const VkBufferImageCopy			bufferStencilCopy		=
	{
		0u,					// VkDeviceSize				bufferOffset;
		0u,					// deUint32					bufferRowLength;
		0u,					// deUint32					bufferImageHeight;
		stencilSourceLayer,	// VkImageSubresourceLayers	imageSubresource;
		{0, 0, 0},			// VkOffset3D				imageOffset;
		defaultExtent		// VkExtent3D				imageExtent;
	};

    const VkBufferImageCopy			bufferStencilCopyOffset	=
	{
		32,											// VkDeviceSize				bufferOffset;
		defaultHalfSize + defaultFourthSize,		// deUint32					bufferRowLength;
		defaultHalfSize + defaultFourthSize,		// deUint32					bufferImageHeight;
		stencilSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
		{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
		defaultHalfExtent							// VkExtent3D				imageExtent;
	};

    const bool						useOffset[]				= {false, true};

	// Note: Depth stencil tests I want to do
	// Formats: D16, D24S8, D32FS8
	// Test writing each component with separate CopyBufferToImage commands
	// Test writing both components in one CopyBufferToImage command
	// Swap order of writes of Depth & Stencil
	// whole surface, subimages?
	// Similar tests as BufferToImage?
	for (const auto config : depthAndStencilFormats)
		for (const auto offset : useOffset)
		{
			// TODO: Check that this format is supported before creating tests?
			//if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))

			CopyRegion					copyDepthRegion;
			CopyRegion					copyStencilRegion;
			TestParams					params;
			const tcu::TextureFormat	format		= mapVkFormat(config.format);
			const bool					hasDepth	= tcu::hasDepthComponent(format.order);
			const bool					hasStencil	= tcu::hasStencilComponent(format.order);
			std::string					description	= config.name;

			if (offset)
			{
				copyDepthRegion.bufferImageCopy = bufferDepthCopyOffset;
				copyStencilRegion.bufferImageCopy = bufferStencilCopyOffset;
				description = "buffer_offset_" + description;
				params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
			}
			else
			{
				copyDepthRegion.bufferImageCopy = bufferDepthCopy;
				copyStencilRegion.bufferImageCopy = bufferStencilCopy;
				params.src.buffer.size = defaultSize * defaultSize;
			}

			params.dst.image.imageType = VK_IMAGE_TYPE_2D;
			params.dst.image.format = config.format;
			params.dst.image.extent = defaultExtent;
			params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
			params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
			params.allocationKind = allocationKind;
			params.extensionUse = extensionUse;

			if (hasDepth && hasStencil)
			{
				params.singleCommand = DE_TRUE;

				params.regions.push_back(copyDepthRegion);
				params.regions.push_back(copyStencilRegion);

				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_DS", "Copy from depth&stencil to image", params));

				params.singleCommand = DE_FALSE;

				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D_S", "Copy from depth then stencil to image", params));

				params.regions.clear();
				params.regions.push_back(copyStencilRegion);
				params.regions.push_back(copyDepthRegion);

				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S_D", "Copy from depth then stencil to image", params));

				params.singleCommand = DE_TRUE;
				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_SD", "Copy from depth&stencil to image", params));
			}

			if (hasStencil)
			{
				params.regions.clear();
				params.regions.push_back(copyStencilRegion);

				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S", "Copy from stencil to image", params));
			}

			if (hasDepth)
			{
				params.regions.clear();
				params.regions.push_back(copyDepthRegion);

				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D", "Copy from depth to image", params));
			}
		}
}

void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	tcu::TestContext& testCtx	= group->getTestContext();

	{
		TestParams	params;
		params.src.buffer.size				= defaultSize * defaultSize;
		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
		params.dst.image.extent				= defaultExtent;
		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		const VkBufferImageCopy	bufferImageCopy	=
		{
			0u,											// VkDeviceSize				bufferOffset;
			0u,											// deUint32					bufferRowLength;
			0u,											// deUint32					bufferImageHeight;
			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
			{0, 0, 0},									// VkOffset3D				imageOffset;
			defaultExtent								// VkExtent3D				imageExtent;
		};
		CopyRegion	copyRegion;
		copyRegion.bufferImageCopy	= bufferImageCopy;

		params.regions.push_back(copyRegion);

		group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
	}

	{
		TestParams	params;
		params.src.buffer.size				= defaultSize * defaultSize;
		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
		params.dst.image.extent				= defaultExtent;
		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		CopyRegion	region;
		deUint32	divisor	= 1;
		for (int offset = 0; (offset + defaultFourthSize / divisor < defaultSize) && (defaultFourthSize > divisor); offset += defaultFourthSize / divisor++)
		{
			const VkBufferImageCopy	bufferImageCopy	=
			{
				0u,																// VkDeviceSize				bufferOffset;
				0u,																// deUint32					bufferRowLength;
				0u,																// deUint32					bufferImageHeight;
				defaultSourceLayer,												// VkImageSubresourceLayers	imageSubresource;
				{offset, defaultHalfSize, 0},									// VkOffset3D				imageOffset;
				{defaultFourthSize / divisor, defaultFourthSize / divisor, 1}	// VkExtent3D				imageExtent;
			};
			region.bufferImageCopy	= bufferImageCopy;
			params.regions.push_back(region);
		}

		group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
	}

	{
		TestParams	params;
		params.src.buffer.size				= defaultSize * defaultSize;
		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
		params.dst.image.extent				= defaultExtent;
		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		const VkBufferImageCopy	bufferImageCopy	=
		{
			defaultFourthSize,							// VkDeviceSize				bufferOffset;
			defaultHalfSize + defaultFourthSize,		// deUint32					bufferRowLength;
			defaultHalfSize + defaultFourthSize,		// deUint32					bufferImageHeight;
			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
			defaultHalfExtent							// VkExtent3D				imageExtent;
		};
		CopyRegion	copyRegion;
		copyRegion.bufferImageCopy	= bufferImageCopy;

		params.regions.push_back(copyRegion);

		group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
	}

	{
		TestParams	params;
		params.src.buffer.size				= defaultSize * defaultSize;
		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
		params.dst.image.format				= VK_FORMAT_R8_UNORM;
		params.dst.image.extent				= defaultExtent;
		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		const VkBufferImageCopy	bufferImageCopy	=
		{
			defaultFourthSize + 1u,						// VkDeviceSize				bufferOffset;
			defaultHalfSize + defaultFourthSize,		// deUint32					bufferRowLength;
			defaultHalfSize + defaultFourthSize,		// deUint32					bufferImageHeight;
			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
			defaultHalfExtent							// VkExtent3D				imageExtent;
		};
		CopyRegion	copyRegion;
		copyRegion.bufferImageCopy	= bufferImageCopy;

		params.regions.push_back(copyRegion);

		group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset_relaxed", "Copy from buffer to image with buffer offset not a multiple of 4", params));
	}

	{
		TestParams				params;
		params.src.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
		params.dst.image.extent				= defaultExtent;
		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		const VkBufferImageCopy	bufferImageCopy	=
		{
			0u,											// VkDeviceSize				bufferOffset;
			defaultSize,								// deUint32					bufferRowLength;
			defaultSize,								// deUint32					bufferImageHeight;
			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
			defaultHalfExtent							// VkExtent3D				imageExtent;
		};
		CopyRegion				copyRegion;
		copyRegion.bufferImageCopy	= bufferImageCopy;

		params.regions.push_back(copyRegion);

		group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", "Copy from buffer that is just large enough to contain the accessed elements", params));
	}

	{
		TestParams				params;
		params.src.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
		params.dst.image.extent				= defaultExtent;
		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		const VkBufferImageCopy	bufferImageCopy	=
		{
			defaultFourthSize,							// VkDeviceSize				bufferOffset;
			defaultSize,								// deUint32					bufferRowLength;
			defaultSize,								// deUint32					bufferImageHeight;
			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
			defaultHalfExtent							// VkExtent3D				imageExtent;
		};
		CopyRegion				copyRegion;
		copyRegion.bufferImageCopy	= bufferImageCopy;

		params.regions.push_back(copyRegion);

		group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer_offset", "Copy from buffer that is just large enough to contain the accessed elements", params));
	}

	{
		TestParams				params;
		deUint32				arrayLayers = 16u;
		params.src.buffer.size				= defaultHalfSize * defaultHalfSize * arrayLayers;
		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
		params.dst.image.extent				= defaultHalfExtent;
		params.dst.image.extent.depth		= arrayLayers;
		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		const int pixelSize	= tcu::getPixelSize(mapVkFormat(params.dst.image.format));
		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
		{
			const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
			const VkBufferImageCopy bufferImageCopy =
				{
					offset,													// VkDeviceSize				bufferOffset;
					0u,														// deUint32					bufferRowLength;
					0u,														// deUint32					bufferImageHeight;
					{
						VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
						0u,												// deUint32				mipLevel;
						arrayLayerNdx,									// deUint32				baseArrayLayer;
						1u,												// deUint32				layerCount;
					},														// VkImageSubresourceLayers	imageSubresource;
					{0, 0, 0},												// VkOffset3D				imageOffset;
					defaultHalfExtent										// VkExtent3D				imageExtent;
				};
			CopyRegion copyRegion;
			copyRegion.bufferImageCopy = bufferImageCopy;

			params.regions.push_back(copyRegion);
		}
		group->addChild(new CopyBufferToImageTestCase(testCtx, "array", "Copy from a different part of the buffer to each layer", params));
	}

	{
		TestParams				params;
		deUint32				arrayLayers = 16u;
		params.src.buffer.size				= defaultHalfSize * defaultHalfSize * arrayLayers;
		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
		params.dst.image.extent				= defaultHalfExtent;
		params.dst.image.extent.depth		= arrayLayers;
		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		params.allocationKind				= allocationKind;
		params.extensionUse					= extensionUse;

		const int pixelSize	= tcu::getPixelSize(mapVkFormat(params.dst.image.format));
		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
		{
			const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
			const VkBufferImageCopy bufferImageCopy =
				{
					offset,													// VkDeviceSize				bufferOffset;
					defaultHalfSize,										// deUint32					bufferRowLength;
					defaultHalfSize,										// deUint32					bufferImageHeight;
					{
						VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
						0u,												// deUint32				mipLevel;
						arrayLayerNdx,									// deUint32				baseArrayLayer;
						1u,												// deUint32				layerCount;
					},														// VkImageSubresourceLayers	imageSubresource;
					{0, 0, 0},												// VkOffset3D				imageOffset;
					defaultHalfExtent										// VkExtent3D				imageExtent;
				};
			CopyRegion copyRegion;
			copyRegion.bufferImageCopy = bufferImageCopy;

			params.regions.push_back(copyRegion);
		}
		group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", "Copy from different part of tightly sized buffer to each layer", params));
	}
}

void addBufferToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	tcu::TestContext&				testCtx					= group->getTestContext();

	{
		TestParams			params;
		params.src.buffer.size	= defaultSize;
		params.dst.buffer.size	= defaultSize;
		params.allocationKind	= allocationKind;
		params.extensionUse		= extensionUse;

		const VkBufferCopy	bufferCopy	=
		{
			0u,				// VkDeviceSize	srcOffset;
			0u,				// VkDeviceSize	dstOffset;
			defaultSize,	// VkDeviceSize	size;
		};

		CopyRegion	copyRegion;
		copyRegion.bufferCopy	= bufferCopy;
		params.regions.push_back(copyRegion);

		group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
	}

	// Filter is VK_FILTER_NEAREST.
	{
		TestParams			params;
		params.src.buffer.size	= defaultFourthSize;
		params.dst.buffer.size	= defaultFourthSize;
		params.allocationKind	= allocationKind;
		params.extensionUse		= extensionUse;

		const VkBufferCopy	bufferCopy	=
		{
			12u,	// VkDeviceSize	srcOffset;
			4u,		// VkDeviceSize	dstOffset;
			1u,		// VkDeviceSize	size;
		};

		CopyRegion	copyRegion;
		copyRegion.bufferCopy = bufferCopy;
		params.regions.push_back(copyRegion);

		group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
	}

	{
		const deUint32		size		= 16;
		TestParams			params;
		params.src.buffer.size	= size;
		params.dst.buffer.size	= size * (size + 1);
		params.allocationKind	= allocationKind;
		params.extensionUse		= extensionUse;

		// Copy region with size 1..size
		for (unsigned int i = 1; i <= size; i++)
		{
			const VkBufferCopy	bufferCopy	=
			{
				0,			// VkDeviceSize	srcOffset;
				i * size,	// VkDeviceSize	dstOffset;
				i,			// VkDeviceSize	size;
			};

			CopyRegion	copyRegion;
			copyRegion.bufferCopy = bufferCopy;
			params.regions.push_back(copyRegion);
		}

		group->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params));
	}
}

void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, TestParams& params)
{
	tcu::TestContext& testCtx = group->getTestContext();

	// Filter is VK_FILTER_NEAREST.
	{
		params.filter					= VK_FILTER_NEAREST;
		const std::string description	= "Nearest filter";

		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));

		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));

		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
	}

	// Filter is VK_FILTER_LINEAR.
	{
		params.filter					= VK_FILTER_LINEAR;
		const std::string description	= "Linear filter";

		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));

		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));

		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
	}

	// Filter is VK_FILTER_CUBIC_EXT.
	// Cubic filtering can only be used with 2D images.
	if (params.dst.image.imageType == VK_IMAGE_TYPE_2D)
	{
		params.filter					= VK_FILTER_CUBIC_EXT;
		const std::string description	= "Cubic filter";

		params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
		group->addChild(new BlitImageTestCase(testCtx, "cubic", description, params));

		params.dst.image.format = VK_FORMAT_R32_SFLOAT;
		const std::string	descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToR32, params));

		params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
		const std::string	descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToBGRA, params));
	}
}

void addBlittingImageSimpleWholeTests (tcu::TestCaseGroup* group, TestParams params)
{
	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
	params.src.image.extent			= defaultExtent;
	params.dst.image.extent			= defaultExtent;
	params.src.image.extent.depth	= imageDepth;
	params.dst.image.extent.depth	= imageDepth;

	{
		const VkImageBlit imageBlit =
		{
			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
			{
				{ 0, 0, 0 },
				{ defaultSize, defaultSize, imageDepth }
			},					// VkOffset3D				srcOffsets[2];

			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
			{
				{ 0, 0, 0 },
				{ defaultSize, defaultSize, imageDepth }
			}					// VkOffset3D				dstOffset[2];
		};

		CopyRegion region;
		region.imageBlit = imageBlit;
		params.regions.push_back(region);
	}

	addBlittingImageSimpleTests(group, params);
}

void addBlittingImageSimpleMirrorXYTests (tcu::TestCaseGroup* group, TestParams params)
{
	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
	params.src.image.extent			= defaultExtent;
	params.dst.image.extent			= defaultExtent;
	params.src.image.extent.depth	= imageDepth;
	params.dst.image.extent.depth	= imageDepth;

	{
		const VkImageBlit imageBlit =
		{
			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
			{
				{0, 0, 0},
				{defaultSize, defaultSize, imageDepth}
			},					// VkOffset3D				srcOffsets[2];

			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
			{
				{defaultSize, defaultSize, 0},
				{0, 0, imageDepth}
			}					// VkOffset3D				dstOffset[2];
		};

		CopyRegion region;
		region.imageBlit = imageBlit;
		params.regions.push_back(region);
	}

	addBlittingImageSimpleTests(group, params);
}

void addBlittingImageSimpleMirrorXTests (tcu::TestCaseGroup* group, TestParams params)
{
	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
	params.src.image.extent			= defaultExtent;
	params.dst.image.extent			= defaultExtent;
	params.src.image.extent.depth	= imageDepth;
	params.dst.image.extent.depth	= imageDepth;

	{
		const VkImageBlit imageBlit =
		{
			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
			{
				{0, 0, 0},
				{defaultSize, defaultSize, imageDepth}
			},					// VkOffset3D				srcOffsets[2];

			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
			{
				{defaultSize, 0, 0},
				{0, defaultSize, imageDepth}
			}					// VkOffset3D				dstOffset[2];
		};

		CopyRegion region;
		region.imageBlit = imageBlit;
		params.regions.push_back(region);
	}

	addBlittingImageSimpleTests(group, params);
}

void addBlittingImageSimpleMirrorYTests (tcu::TestCaseGroup* group, TestParams params)
{
	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
	params.src.image.extent			= defaultExtent;
	params.dst.image.extent			= defaultExtent;
	params.src.image.extent.depth	= imageDepth;
	params.dst.image.extent.depth	= imageDepth;

	{
		const VkImageBlit imageBlit =
		{
			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
			{
				{0, 0, 0},
				{defaultSize, defaultSize, imageDepth}
			},					// VkOffset3D				srcOffsets[2];

			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
			{
				{0, defaultSize, 0},
				{defaultSize, 0, imageDepth}
			}					// VkOffset3D				dstOffset[2];
		};

		CopyRegion region;
		region.imageBlit = imageBlit;
		params.regions.push_back(region);
	}

	addBlittingImageSimpleTests(group, params);
}

void addBlittingImageSimpleMirrorZTests (tcu::TestCaseGroup* group, TestParams params)
{
	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
	DE_ASSERT(params.src.image.imageType == VK_IMAGE_TYPE_3D);
	params.src.image.extent			= defaultExtent;
	params.dst.image.extent			= defaultExtent;
	params.src.image.extent.depth	= defaultSize;
	params.dst.image.extent.depth	= defaultSize;

	{
		const VkImageBlit imageBlit =
		{
			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
			{
				{0, 0, 0},
				{defaultSize, defaultSize, defaultSize}
			},					// VkOffset3D				srcOffsets[2];

			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
			{
				{0, 0, defaultSize},
				{defaultSize, defaultSize, 0}
			}					// VkOffset3D				dstOffset[2];
		};

		CopyRegion region;
		region.imageBlit = imageBlit;
		params.regions.push_back(region);
	}

	addBlittingImageSimpleTests(group, params);
}

void addBlittingImageSimpleMirrorSubregionsTests (tcu::TestCaseGroup* group, TestParams params)
{
	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
	params.src.image.extent			= defaultExtent;
	params.dst.image.extent			= defaultExtent;
	params.src.image.extent.depth	= imageDepth;
	params.dst.image.extent.depth	= imageDepth;

	// No mirroring.
	{
		const VkImageBlit imageBlit =
		{
			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
			{
				{0, 0, 0},
				{defaultHalfSize, defaultHalfSize, imageDepth}
			},					// VkOffset3D				srcOffsets[2];

			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
			{
				{0, 0, 0},
				{defaultHalfSize, defaultHalfSize, imageDepth}
			}					// VkOffset3D				dstOffset[2];
		};

		CopyRegion region;
		region.imageBlit = imageBlit;
		params.regions.push_back(region);
	}

	// Flipping y coordinates.
	{
		const VkImageBlit imageBlit =
		{
			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
			{
				{defaultHalfSize, 0, 0},
				{defaultSize, defaultHalfSize, imageDepth}
			},					// VkOffset3D				srcOffsets[2];

			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
			{
				{defaultHalfSize, defaultHalfSize, 0},
				{defaultSize, 0, imageDepth}
			}					// VkOffset3D				dstOffset[2];
		};
		CopyRegion region;
		region.imageBlit = imageBlit;
		params.regions.push_back(region);
	}

	// Flipping x coordinates.
	{
		const VkImageBlit imageBlit =
		{
			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
			{
				{0, defaultHalfSize, 0},
				{defaultHalfSize, defaultSize, imageDepth}
			},					// VkOffset3D				srcOffsets[2];

			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
			{
				{defaultHalfSize, defaultHalfSize, 0},
				{0, defaultSize, imageDepth}
			}					// VkOffset3D				dstOffset[2];
		};

		CopyRegion region;
		region.imageBlit = imageBlit;
		params.regions.push_back(region);
	}

	// Flipping x and y coordinates.
	{
		const VkImageBlit imageBlit =
		{
			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
			{
				{defaultHalfSize, defaultHalfSize, 0},
				{defaultSize, defaultSize, imageDepth}
			},					// VkOffset3D				srcOffsets[2];

			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
			{
				{defaultSize, defaultSize, 0},
				{defaultHalfSize, defaultHalfSize, imageDepth}
			}					// VkOffset3D				dstOffset[2];
		};

		CopyRegion region;
		region.imageBlit = imageBlit;
		params.regions.push_back(region);
	}

	addBlittingImageSimpleTests(group, params);
}

void addBlittingImageSimpleScalingWhole1Tests (tcu::TestCaseGroup* group, TestParams params)
{
	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
	const deInt32	imageDepth		= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
	const deInt32	halfImageDepth	= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
	params.src.image.extent			= defaultExtent;
	params.dst.image.extent			= defaultHalfExtent;
	params.src.image.extent.depth	= imageDepth;
	params.dst.image.extent.depth	= halfImageDepth;

	{
		const VkImageBlit imageBlit =
		{
			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
			{
				{0, 0, 0},
				{defaultSize, defaultSize, imageDepth}
			},					// VkOffset3D					srcOffsets[2];

			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
			{
				{0, 0, 0},
				{defaultHalfSize, defaultHalfSize, halfImageDepth}
			}					// VkOffset3D					dstOffset[2];
		};

		CopyRegion region;
		region.imageBlit = imageBlit;
		params.regions.push_back(region);
	}

	addBlittingImageSimpleTests(group, params);
}

void addBlittingImageSimpleScalingWhole2Tests (tcu::TestCaseGroup* group, TestParams params)
{
	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
	const deInt32	imageDepth		= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
	const deInt32	halfImageDepth	= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
	params.src.image.extent			= defaultHalfExtent;
	params.dst.image.extent			= defaultExtent;
	params.src.image.extent.depth	= halfImageDepth;
	params.dst.image.extent.depth	= imageDepth;

	{
		const VkImageBlit imageBlit =
		{
			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
			{
				{0, 0, 0},
				{defaultHalfSize, defaultHalfSize, halfImageDepth}
			},					// VkOffset3D					srcOffsets[2];

			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
			{
				{0, 0, 0},
				{defaultSize, defaultSize, imageDepth}
			}					// VkOffset3D					dstOffset[2];
		};

		CopyRegion region;
		region.imageBlit = imageBlit;
		params.regions.push_back(region);
	}

	addBlittingImageSimpleTests(group, params);
}

void addBlittingImageSimpleScalingAndOffsetTests (tcu::TestCaseGroup* group, TestParams params)
{
	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
	const deInt32	imageDepth		= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
	const deInt32	srcDepthOffset	= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultFourthSize : 0;
	const deInt32	srcDepthSize	= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultFourthSize * 3 : 1;
	params.src.image.extent			= defaultExtent;
	params.dst.image.extent			= defaultExtent;
	params.src.image.extent.depth	= imageDepth;
	params.dst.image.extent.depth	= imageDepth;

	{
		const VkImageBlit imageBlit =
		{
			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
			{
				{defaultFourthSize, defaultFourthSize, srcDepthOffset},
				{defaultFourthSize*3, defaultFourthSize*3, srcDepthSize}
			},					// VkOffset3D					srcOffsets[2];

			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
			{
				{0, 0, 0},
				{defaultSize, defaultSize, imageDepth}
			}					// VkOffset3D					dstOffset[2];
		};

		CopyRegion region;
		region.imageBlit = imageBlit;
		params.regions.push_back(region);
	}

	addBlittingImageSimpleTests(group, params);
}

void addBlittingImageSimpleWithoutScalingPartialTests (tcu::TestCaseGroup* group, TestParams params)
{
	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
	const bool is3dBlit = params.src.image.imageType == VK_IMAGE_TYPE_3D;
	params.src.image.extent	= defaultExtent;
	params.dst.image.extent	= defaultExtent;

	if (is3dBlit)
	{
		params.src.image.extent.depth = defaultSize;
		params.dst.image.extent.depth = defaultSize;
	}

	{
		CopyRegion region;
		for (int i = 0; i < defaultSize; i += defaultFourthSize)
		{
			const VkImageBlit imageBlit =
			{
				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
				{
					{defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, is3dBlit ? defaultSize - defaultFourthSize - i : 0},
					{defaultSize - i, defaultSize - i, is3dBlit ? defaultSize - i : 1}
				},					// VkOffset3D					srcOffsets[2];

				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
				{
					{i, i, is3dBlit ? i : 0},
					{i + defaultFourthSize, i + defaultFourthSize, is3dBlit ? i + defaultFourthSize : 1}
				}					// VkOffset3D					dstOffset[2];
			};
			region.imageBlit = imageBlit;
			params.regions.push_back(region);
		}
	}

	addBlittingImageSimpleTests(group, params);
}

void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	TestParams params;
	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
	params.allocationKind				= allocationKind;
	params.extensionUse					= extensionUse;
	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
	addTestGroup(group, "whole", "Blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
	addTestGroup(group, "mirror_xy", "Flipping x and y coordinates (whole)", addBlittingImageSimpleMirrorXYTests, params);
	addTestGroup(group, "mirror_x", "Flipping x coordinates (whole)", addBlittingImageSimpleMirrorXTests, params);
	addTestGroup(group, "mirror_y", "Flipping y coordinates (whole)", addBlittingImageSimpleMirrorYTests, params);
	addTestGroup(group, "mirror_subregions", "Mirroring subregions in image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
	addTestGroup(group, "scaling_whole1", "Blit with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
	addTestGroup(group, "scaling_whole2", "Blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
	addTestGroup(group, "scaling_and_offset", "Blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
	addTestGroup(group, "without_scaling_partial", "Blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);

	params.src.image.imageType			= VK_IMAGE_TYPE_3D;
	params.dst.image.imageType			= VK_IMAGE_TYPE_3D;
	addTestGroup(group, "whole_3d", "3D blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
	addTestGroup(group, "mirror_xy_3d", "Flipping x and y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXYTests, params);
	addTestGroup(group, "mirror_x_3d", "Flipping x coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXTests, params);
	addTestGroup(group, "mirror_y_3d", "Flipping y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorYTests, params);
	addTestGroup(group, "mirror_z_3d", "Flipping z coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorZTests, params);
	addTestGroup(group, "mirror_subregions_3d", "Mirroring subregions in a 3D image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
	addTestGroup(group, "scaling_whole1_3d", "3D blit a with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
	addTestGroup(group, "scaling_whole2_3d", "3D blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
	addTestGroup(group, "scaling_and_offset_3d", "3D blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
	addTestGroup(group, "without_scaling_partial_3d", "3D blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
}

enum FilterMaskBits
{
	FILTER_MASK_NEAREST	= 0,			// Always tested.
	FILTER_MASK_LINEAR	= (1u << 0),
	FILTER_MASK_CUBIC	= (1u << 1),
};

using FilterMask = deUint32;

FilterMask makeFilterMask (bool onlyNearest, bool discardCubicFilter)
{
	FilterMask mask = FILTER_MASK_NEAREST;

	if (!onlyNearest)
	{
		mask |= FILTER_MASK_LINEAR;
		if (!discardCubicFilter)
			mask |= FILTER_MASK_CUBIC;
	}

	return mask;
}

struct BlitColorTestParams
{
	TestParams		params;
	const VkFormat*	compatibleFormats;
	FilterMask		testFilters;
};

bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams)
{
	bool result = true;

	if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
	{
		DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty());

		result =
			de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) ||
			de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format);
	}

	return result;
}

const VkFormat	linearOtherImageFormatsToTest[]	=
{
	// From compatibleFormats8Bit
	VK_FORMAT_R4G4_UNORM_PACK8,
	VK_FORMAT_R8_SRGB,

	// From compatibleFormats16Bit
	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
	VK_FORMAT_R16_SFLOAT,

	// From compatibleFormats24Bit
	VK_FORMAT_R8G8B8_UNORM,
	VK_FORMAT_B8G8R8_SRGB,

	// From compatibleFormats32Bit
	VK_FORMAT_R8G8B8A8_UNORM,
	VK_FORMAT_R32_SFLOAT,

	// From compatibleFormats48Bit
	VK_FORMAT_R16G16B16_UNORM,
	VK_FORMAT_R16G16B16_SFLOAT,

	// From compatibleFormats64Bit
	VK_FORMAT_R16G16B16A16_UNORM,
	VK_FORMAT_R64_SFLOAT,

	// From compatibleFormats96Bit
	VK_FORMAT_R32G32B32_UINT,
	VK_FORMAT_R32G32B32_SFLOAT,

	// From compatibleFormats128Bit
	VK_FORMAT_R32G32B32A32_UINT,
	VK_FORMAT_R64G64_SFLOAT,

	// From compatibleFormats192Bit
	VK_FORMAT_R64G64B64_UINT,
	VK_FORMAT_R64G64B64_SFLOAT,

	// From compatibleFormats256Bit
	VK_FORMAT_R64G64B64A64_UINT,
	VK_FORMAT_R64G64B64A64_SFLOAT,
};

std::string getBlitImageTilingLayoutCaseName (VkImageTiling tiling, VkImageLayout layout)
{
	switch (tiling)
	{
		case VK_IMAGE_TILING_OPTIMAL:
			return getImageLayoutCaseName(layout);
		case VK_IMAGE_TILING_LINEAR:
			return "linear";
		default:
			DE_ASSERT(false);
			return "";
	}
}

void addBlittingImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
{
	tcu::TestContext& testCtx				= group->getTestContext();

	FormatSet linearOtherImageFormatsToTestSet;
	const int numOfOtherImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(linearOtherImageFormatsToTest);
	for (int otherImageFormatsIndex = 0; otherImageFormatsIndex < numOfOtherImageFormatsToTestFilter; ++otherImageFormatsIndex)
		linearOtherImageFormatsToTestSet.insert(linearOtherImageFormatsToTest[otherImageFormatsIndex]);

	const VkImageTiling blitSrcTilings[]	=
	{
		VK_IMAGE_TILING_OPTIMAL,
		VK_IMAGE_TILING_LINEAR,
	};
	const VkImageLayout blitSrcLayouts[]	=
	{
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
		VK_IMAGE_LAYOUT_GENERAL
	};
	const VkImageTiling blitDstTilings[]	=
	{
		VK_IMAGE_TILING_OPTIMAL,
		VK_IMAGE_TILING_LINEAR,
	};
	const VkImageLayout blitDstLayouts[]	=
	{
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
		VK_IMAGE_LAYOUT_GENERAL
	};

	for (int srcTilingNdx = 0u; srcTilingNdx < DE_LENGTH_OF_ARRAY(blitSrcTilings); ++srcTilingNdx)
	{
		testParams.params.src.image.tiling = blitSrcTilings[srcTilingNdx];

		for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
		{
			testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];

			// Don't bother testing VK_IMAGE_TILING_LINEAR + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL as it's likely to be the same as VK_IMAGE_LAYOUT_GENERAL
			if (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
				continue;

			for (int dstTilingNdx = 0u; dstTilingNdx < DE_LENGTH_OF_ARRAY(blitDstTilings); ++dstTilingNdx)
			{
				testParams.params.dst.image.tiling = blitDstTilings[dstTilingNdx];

				for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
				{
					testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];

					// Don't bother testing VK_IMAGE_TILING_LINEAR + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL as it's likely to be the same as VK_IMAGE_LAYOUT_GENERAL
					if (testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
						continue;

					if ((testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.src.image.format)) ||
					    (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.dst.image.format)))
						continue;

					testParams.params.filter			= VK_FILTER_NEAREST;
					const std::string testName			= getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) + "_" +
														  getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
					const std::string description		= "Blit from layout " + getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) +
														  " to " + getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
					group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest", description, testParams.params));

					if (testParams.testFilters & FILTER_MASK_LINEAR)
					{
						testParams.params.filter = VK_FILTER_LINEAR;
						group->addChild(new BlitImageTestCase(testCtx, testName + "_linear", description, testParams.params));
					}

					if (testParams.testFilters & FILTER_MASK_CUBIC)
					{
						testParams.params.filter = VK_FILTER_CUBIC_EXT;
						group->addChild(new BlitImageTestCase(testCtx, testName + "_cubic", description, testParams.params));
					}

					if (testParams.params.src.image.imageType == VK_IMAGE_TYPE_3D)
					{
						const struct
						{
							FillMode	mode;
							const char*	name;
						} modeList[] =
						{
							{ FILL_MODE_BLUE_RED_X, "x" },
							{ FILL_MODE_BLUE_RED_Y, "y" },
							{ FILL_MODE_BLUE_RED_Z, "z" },
						};

						auto otherParams = testParams;
						otherParams.params.dst.image.fillMode = FILL_MODE_WHITE;

						for (int i = 0; i < DE_LENGTH_OF_ARRAY(modeList); ++i)
						{
							otherParams.params.src.image.fillMode = modeList[i].mode;

							otherParams.params.filter = VK_FILTER_LINEAR;
							group->addChild(new BlitImageTestCase(testCtx, testName + "_linear_stripes_" + modeList[i].name, description, otherParams.params));

							otherParams.params.filter = VK_FILTER_NEAREST;
							group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest_stripes_" + modeList[i].name, description, otherParams.params));
						}
					}
				}
			}
		}
	}
}

void addBlittingImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
{
	// If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format.
	const VkFormat	srcFormatOnly[2]	= { testParams.params.src.image.format, VK_FORMAT_UNDEFINED };
	const VkFormat*	formatList			= (testParams.compatibleFormats ? testParams.compatibleFormats : srcFormatOnly);

	for (int dstFormatIndex = 0; formatList[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
	{
		testParams.params.dst.image.format	= formatList[dstFormatIndex];
		if (!isSupportedByFramework(testParams.params.dst.image.format))
			continue;

		if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams))
			continue;

		const std::string description	= "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format);
		addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
	}
}

const VkFormat	compatibleFormatsUInts[]	=
{
	VK_FORMAT_R8_UINT,
	VK_FORMAT_R8G8_UINT,
	VK_FORMAT_R8G8B8_UINT,
	VK_FORMAT_B8G8R8_UINT,
	VK_FORMAT_R8G8B8A8_UINT,
	VK_FORMAT_B8G8R8A8_UINT,
	VK_FORMAT_A8B8G8R8_UINT_PACK32,
	VK_FORMAT_A2R10G10B10_UINT_PACK32,
	VK_FORMAT_A2B10G10R10_UINT_PACK32,
	VK_FORMAT_R16_UINT,
	VK_FORMAT_R16G16_UINT,
	VK_FORMAT_R16G16B16_UINT,
	VK_FORMAT_R16G16B16A16_UINT,
	VK_FORMAT_R32_UINT,
	VK_FORMAT_R32G32_UINT,
	VK_FORMAT_R32G32B32_UINT,
	VK_FORMAT_R32G32B32A32_UINT,
	VK_FORMAT_R64_UINT,
	VK_FORMAT_R64G64_UINT,
	VK_FORMAT_R64G64B64_UINT,
	VK_FORMAT_R64G64B64A64_UINT,

	VK_FORMAT_UNDEFINED
};
const VkFormat	compatibleFormatsSInts[]	=
{
	VK_FORMAT_R8_SINT,
	VK_FORMAT_R8G8_SINT,
	VK_FORMAT_R8G8B8_SINT,
	VK_FORMAT_B8G8R8_SINT,
	VK_FORMAT_R8G8B8A8_SINT,
	VK_FORMAT_B8G8R8A8_SINT,
	VK_FORMAT_A8B8G8R8_SINT_PACK32,
	VK_FORMAT_A2R10G10B10_SINT_PACK32,
	VK_FORMAT_A2B10G10R10_SINT_PACK32,
	VK_FORMAT_R16_SINT,
	VK_FORMAT_R16G16_SINT,
	VK_FORMAT_R16G16B16_SINT,
	VK_FORMAT_R16G16B16A16_SINT,
	VK_FORMAT_R32_SINT,
	VK_FORMAT_R32G32_SINT,
	VK_FORMAT_R32G32B32_SINT,
	VK_FORMAT_R32G32B32A32_SINT,
	VK_FORMAT_R64_SINT,
	VK_FORMAT_R64G64_SINT,
	VK_FORMAT_R64G64B64_SINT,
	VK_FORMAT_R64G64B64A64_SINT,

	VK_FORMAT_UNDEFINED
};
const VkFormat	compatibleFormatsFloats[]	=
{
	VK_FORMAT_R4G4_UNORM_PACK8,
	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
	VK_FORMAT_B4G4R4A4_UNORM_PACK16,
	VK_FORMAT_R5G6B5_UNORM_PACK16,
	VK_FORMAT_B5G6R5_UNORM_PACK16,
	VK_FORMAT_R5G5B5A1_UNORM_PACK16,
	VK_FORMAT_B5G5R5A1_UNORM_PACK16,
	VK_FORMAT_A1R5G5B5_UNORM_PACK16,
	VK_FORMAT_R8_UNORM,
	VK_FORMAT_R8_SNORM,
	VK_FORMAT_R8_USCALED,
	VK_FORMAT_R8_SSCALED,
	VK_FORMAT_R8G8_UNORM,
	VK_FORMAT_R8G8_SNORM,
	VK_FORMAT_R8G8_USCALED,
	VK_FORMAT_R8G8_SSCALED,
	VK_FORMAT_R8G8B8_UNORM,
	VK_FORMAT_R8G8B8_SNORM,
	VK_FORMAT_R8G8B8_USCALED,
	VK_FORMAT_R8G8B8_SSCALED,
	VK_FORMAT_B8G8R8_UNORM,
	VK_FORMAT_B8G8R8_SNORM,
	VK_FORMAT_B8G8R8_USCALED,
	VK_FORMAT_B8G8R8_SSCALED,
	VK_FORMAT_R8G8B8A8_UNORM,
	VK_FORMAT_R8G8B8A8_SNORM,
	VK_FORMAT_R8G8B8A8_USCALED,
	VK_FORMAT_R8G8B8A8_SSCALED,
	VK_FORMAT_B8G8R8A8_UNORM,
	VK_FORMAT_B8G8R8A8_SNORM,
	VK_FORMAT_B8G8R8A8_USCALED,
	VK_FORMAT_B8G8R8A8_SSCALED,
	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
	VK_FORMAT_A2R10G10B10_SNORM_PACK32,
	VK_FORMAT_A2R10G10B10_USCALED_PACK32,
	VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
	VK_FORMAT_A2B10G10R10_SNORM_PACK32,
	VK_FORMAT_A2B10G10R10_USCALED_PACK32,
	VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
	VK_FORMAT_R16_UNORM,
	VK_FORMAT_R16_SNORM,
	VK_FORMAT_R16_USCALED,
	VK_FORMAT_R16_SSCALED,
	VK_FORMAT_R16_SFLOAT,
	VK_FORMAT_R16G16_UNORM,
	VK_FORMAT_R16G16_SNORM,
	VK_FORMAT_R16G16_USCALED,
	VK_FORMAT_R16G16_SSCALED,
	VK_FORMAT_R16G16_SFLOAT,
	VK_FORMAT_R16G16B16_UNORM,
	VK_FORMAT_R16G16B16_SNORM,
	VK_FORMAT_R16G16B16_USCALED,
	VK_FORMAT_R16G16B16_SSCALED,
	VK_FORMAT_R16G16B16_SFLOAT,
	VK_FORMAT_R16G16B16A16_UNORM,
	VK_FORMAT_R16G16B16A16_SNORM,
	VK_FORMAT_R16G16B16A16_USCALED,
	VK_FORMAT_R16G16B16A16_SSCALED,
	VK_FORMAT_R16G16B16A16_SFLOAT,
	VK_FORMAT_R32_SFLOAT,
	VK_FORMAT_R32G32_SFLOAT,
	VK_FORMAT_R32G32B32_SFLOAT,
	VK_FORMAT_R32G32B32A32_SFLOAT,
	VK_FORMAT_R64_SFLOAT,
	VK_FORMAT_R64G64_SFLOAT,
	VK_FORMAT_R64G64B64_SFLOAT,
	VK_FORMAT_R64G64B64A64_SFLOAT,
	VK_FORMAT_B10G11R11_UFLOAT_PACK32,
	VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
//	VK_FORMAT_BC1_RGB_UNORM_BLOCK,
//	VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
//	VK_FORMAT_BC2_UNORM_BLOCK,
//	VK_FORMAT_BC3_UNORM_BLOCK,
//	VK_FORMAT_BC4_UNORM_BLOCK,
//	VK_FORMAT_BC4_SNORM_BLOCK,
//	VK_FORMAT_BC5_UNORM_BLOCK,
//	VK_FORMAT_BC5_SNORM_BLOCK,
//	VK_FORMAT_BC6H_UFLOAT_BLOCK,
//	VK_FORMAT_BC6H_SFLOAT_BLOCK,
//	VK_FORMAT_BC7_UNORM_BLOCK,
//	VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
//	VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
//	VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
//	VK_FORMAT_EAC_R11_UNORM_BLOCK,
//	VK_FORMAT_EAC_R11_SNORM_BLOCK,
//	VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
//	VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
//	VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
//	VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
//	VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
//	VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
//	VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
//	VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
//	VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
//	VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
//	VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
//	VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
//	VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
//	VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
//	VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
//	VK_FORMAT_ASTC_12x12_UNORM_BLOCK,

	VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
	VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,

	VK_FORMAT_UNDEFINED
};
const VkFormat	compatibleFormatsSrgb[]		=
{
	VK_FORMAT_R8_SRGB,
	VK_FORMAT_R8G8_SRGB,
	VK_FORMAT_R8G8B8_SRGB,
	VK_FORMAT_B8G8R8_SRGB,
	VK_FORMAT_R8G8B8A8_SRGB,
	VK_FORMAT_B8G8R8A8_SRGB,
	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
//	VK_FORMAT_BC1_RGB_SRGB_BLOCK,
//	VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
//	VK_FORMAT_BC2_SRGB_BLOCK,
//	VK_FORMAT_BC3_SRGB_BLOCK,
//	VK_FORMAT_BC7_SRGB_BLOCK,
//	VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
//	VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
//	VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
//	VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
//	VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
//	VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
//	VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
//	VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
//	VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
//	VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
//	VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
//	VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
//	VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
//	VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
//	VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
//	VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
//	VK_FORMAT_ASTC_12x12_SRGB_BLOCK,

	VK_FORMAT_UNDEFINED
};

const VkFormat	dedicatedAllocationBlittingFormatsToTest[]	=
{
	// compatibleFormatsUInts
	VK_FORMAT_R8_UINT,
	VK_FORMAT_R64G64B64A64_UINT,

	// compatibleFormatsSInts
	VK_FORMAT_R8_SINT,
	VK_FORMAT_R64G64B64A64_SINT,

	// compatibleFormatsFloats
	VK_FORMAT_R4G4_UNORM_PACK8,
	VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,

	// compatibleFormatsSrgb
	VK_FORMAT_R8_SRGB,
	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
};

// skip cubic filtering test for the following data formats
const FormatSet	onlyNearestAndLinearFormatsToTest =
{
	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
	VK_FORMAT_A8B8G8R8_UINT_PACK32,
	VK_FORMAT_A8B8G8R8_SINT_PACK32
};

void addBlittingImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	const struct {
		const VkFormat*	compatibleFormats;
		const bool		onlyNearest;
	}	colorImageFormatsToTestBlit[]			=
	{
		{ compatibleFormatsUInts,	true	},
		{ compatibleFormatsSInts,	true	},
		{ compatibleFormatsFloats,	false	},
		{ compatibleFormatsSrgb,	false	},
	};

	const int	numOfColorImageFormatsToTest		= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);

	if (allocationKind == ALLOCATION_KIND_DEDICATED)
	{
		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
	}

	// 2D tests.
	{
		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));

		TestParams	params;
		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
		params.src.image.extent		= defaultExtent;
		params.dst.image.extent		= defaultExtent;
		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
		params.allocationKind		= allocationKind;
		params.extensionUse			= extensionUse;

		CopyRegion	region;
		for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
		{
			const VkImageBlit			imageBlit	=
			{
				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
				{
					{0, 0, 0},
					{defaultSize, defaultSize, 1}
				},					// VkOffset3D					srcOffsets[2];

				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
				{
					{i, 0, 0},
					{i + defaultFourthSize / j, defaultFourthSize / j, 1}
				}					// VkOffset3D					dstOffset[2];
			};
			region.imageBlit	= imageBlit;
			params.regions.push_back(region);
		}
		for (int i = 0; i < defaultSize; i += defaultFourthSize)
		{
			const VkImageBlit			imageBlit	=
			{
				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
				{
					{i, i, 0},
					{i + defaultFourthSize, i + defaultFourthSize, 1}
				},					// VkOffset3D					srcOffsets[2];

				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
				{
					{i, defaultSize / 2, 0},
					{i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1}
				}					// VkOffset3D					dstOffset[2];
			};
			region.imageBlit	= imageBlit;
			params.regions.push_back(region);
		}

		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
		{
			const VkFormat*	compatibleFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
			{
				params.src.image.format	= compatibleFormats[srcFormatIndex];
				if (!isSupportedByFramework(params.src.image.format))
					continue;

				const bool onlyNearestAndLinear	= de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);

				BlitColorTestParams		testParams;
				testParams.params				= params;
				testParams.compatibleFormats	= compatibleFormats;
				testParams.testFilters			= makeFilterMask(onlyNearest, onlyNearestAndLinear);

				const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
				addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
			}
		}

		group->addChild(subGroup.release());
	}

	// 1D tests.
	{
		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));

		TestParams	params;
		params.src.image.imageType	= VK_IMAGE_TYPE_1D;
		params.dst.image.imageType	= VK_IMAGE_TYPE_1D;
		params.src.image.extent		= default1dExtent;
		params.dst.image.extent		= default1dExtent;
		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
		params.allocationKind		= allocationKind;
		params.extensionUse			= extensionUse;

		CopyRegion	region;
		for (int i = 0; i < defaultSize; i += defaultSize / 2)
		{
			const VkImageBlit			imageBlit	=
			{
				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
				{
					{0, 0, 0},
					{defaultSize, 1, 1}
				},					// VkOffset3D					srcOffsets[2];

				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
				{
					{i, 0, 0},
					{i + defaultFourthSize, 1, 1}
				}					// VkOffset3D					dstOffset[2];
			};
			region.imageBlit	= imageBlit;
			params.regions.push_back(region);
		}

		{
			const VkImageBlit			imageBlit	=
			{
				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
				{
					{0, 0, 0},
					{defaultFourthSize, 1, 1}
				},					// VkOffset3D					srcOffsets[2];

				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
				{
					{defaultFourthSize, 0, 0},
					{2 * defaultFourthSize, 1, 1}
				}					// VkOffset3D					dstOffset[2];
			};
			region.imageBlit	= imageBlit;
			params.regions.push_back(region);
		}

		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
		{
			const VkFormat*	compatibleFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
			{
				params.src.image.format	= compatibleFormats[srcFormatIndex];
				if (!isSupportedByFramework(params.src.image.format))
					continue;

				// Cubic filtering can only be used with 2D images.
				const bool onlyNearestAndLinear	= true;

				BlitColorTestParams	testParams;
				testParams.params				= params;
				testParams.compatibleFormats	= nullptr;
				testParams.testFilters			= makeFilterMask(onlyNearest, onlyNearestAndLinear);

				const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
				addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
			}
		}

		group->addChild(subGroup.release());
	}

	// 3D tests. Note we use smaller dimensions here for performance reasons.
	{
		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));

		TestParams	params;
		params.src.image.imageType	= VK_IMAGE_TYPE_3D;
		params.dst.image.imageType	= VK_IMAGE_TYPE_3D;
		params.src.image.extent		= default3dExtent;
		params.dst.image.extent		= default3dExtent;
		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
		params.allocationKind		= allocationKind;
		params.extensionUse			= extensionUse;

		CopyRegion	region;
		for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultFourthSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
		{
			const VkImageBlit			imageBlit	=
			{
				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
				{
					{0, 0, 0},
					{defaultFourthSize, defaultFourthSize, defaultFourthSize}
				},					// VkOffset3D					srcOffsets[2];

				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
				{
					{i, 0, i},
					{i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j}
				}					// VkOffset3D					dstOffset[2];
			};
			region.imageBlit	= imageBlit;
			params.regions.push_back(region);
		}
		for (int i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
		{
			const VkImageBlit			imageBlit	=
			{
				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
				{
					{i, i, i},
					{i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize}
				},					// VkOffset3D					srcOffsets[2];

				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
				{
					{i, defaultFourthSize / 2, i},
					{i + defaultSixteenthSize, defaultFourthSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize}
				}					// VkOffset3D					dstOffset[2];
			};
			region.imageBlit	= imageBlit;
			params.regions.push_back(region);
		}

		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
		{
			const VkFormat*	compatibleFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
			{
				params.src.image.format	= compatibleFormats[srcFormatIndex];
				if (!isSupportedByFramework(params.src.image.format))
					continue;

				// Cubic filtering can only be used with 2D images.
				const bool onlyNearestAndLinear	= true;

				BlitColorTestParams	testParams;
				testParams.params				= params;
				testParams.compatibleFormats	= nullptr;
				testParams.testFilters			= makeFilterMask(onlyNearest, onlyNearestAndLinear);

				const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
				addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
			}
		}

		group->addChild(subGroup.release());
	}
}

void addBlittingImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
{
	const VkImageLayout blitSrcLayouts[]	=
	{
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
		VK_IMAGE_LAYOUT_GENERAL
	};
	const VkImageLayout blitDstLayouts[]	=
	{
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
		VK_IMAGE_LAYOUT_GENERAL
	};

	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
	{
		params.src.image.operationLayout	= blitSrcLayouts[srcLayoutNdx];

		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
		{
			params.dst.image.operationLayout	= blitDstLayouts[dstLayoutNdx];
			params.filter						= VK_FILTER_NEAREST;

			const std::string testName		= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
											  getImageLayoutCaseName(params.dst.image.operationLayout);
			const std::string description	= "Blit from " + getImageLayoutCaseName(params.src.image.operationLayout) +
											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);

			group->addChild(new BlitImageTestCase(group->getTestContext(), testName + "_nearest", description, params));
		}
	}
}

void addBlittingImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	const VkFormat	depthAndStencilFormats[]	=
	{
		VK_FORMAT_D16_UNORM,
		VK_FORMAT_X8_D24_UNORM_PACK32,
		VK_FORMAT_D32_SFLOAT,
		VK_FORMAT_S8_UINT,
		VK_FORMAT_D16_UNORM_S8_UINT,
		VK_FORMAT_D24_UNORM_S8_UINT,
		VK_FORMAT_D32_SFLOAT_S8_UINT,
	};

	const VkImageSubresourceLayers	defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
	const VkImageSubresourceLayers	defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
	const VkImageSubresourceLayers	defaultDSSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };

	// 2D tests
	{
		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));

		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
		{
			TestParams	params;
			params.src.image.imageType			= VK_IMAGE_TYPE_2D;
			params.src.image.extent				= defaultExtent;
			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
			params.dst.image.extent				= defaultExtent;
			params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
			params.dst.image.format				= params.src.image.format;
			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
			params.allocationKind				= allocationKind;
			params.extensionUse					= extensionUse;
			params.separateDepthStencilLayouts	= DE_FALSE;

			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);

			CopyRegion	region;
			for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
			{
				const VkOffset3D	srcOffset0	= {0, 0, 0};
				const VkOffset3D	srcOffset1	= {defaultSize, defaultSize, 1};
				const VkOffset3D	dstOffset0	= {i, 0, 0};
				const VkOffset3D	dstOffset1	= {i + defaultFourthSize / j, defaultFourthSize / j, 1};

				if (hasDepth)
				{
					const VkImageBlit			imageBlit	=
					{
						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
					};
					region.imageBlit	= imageBlit;
					params.regions.push_back(region);
				}
				if (hasStencil)
				{
					const VkImageBlit			imageBlit	=
					{
						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
					};
					region.imageBlit	= imageBlit;
					params.regions.push_back(region);
				}
			}
			for (int i = 0; i < defaultSize; i += defaultFourthSize)
			{
				const VkOffset3D	srcOffset0	= {i, i, 0};
				const VkOffset3D	srcOffset1	= {i + defaultFourthSize, i + defaultFourthSize, 1};
				const VkOffset3D	dstOffset0	= {i, defaultSize / 2, 0};
				const VkOffset3D	dstOffset1	= {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1};

				if (hasDepth)
				{
					const VkImageBlit			imageBlit	=
					{
						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
					};
					region.imageBlit	= imageBlit;
					params.regions.push_back(region);
				}
				if (hasStencil)
				{
					const VkImageBlit			imageBlit	=
					{
						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
					};
					region.imageBlit	= imageBlit;
					params.regions.push_back(region);
				}
				if (hasDepth && hasStencil)
				{
					const VkOffset3D			dstDSOffset0	= {i, 3 * defaultFourthSize, 0};
					const VkOffset3D			dstDSOffset1	= {i + defaultFourthSize, defaultSize, 1};
					const VkImageBlit			imageBlit	=
					{
						defaultDSSourceLayer,			// VkImageSubresourceLayers	srcSubresource;
						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
						defaultDSSourceLayer,			// VkImageSubresourceLayers	dstSubresource;
						{ dstDSOffset0, dstDSOffset1 }	// VkOffset3D					dstOffset[2];
					};
					region.imageBlit	= imageBlit;
					params.regions.push_back(region);
				}
			}

			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
			const std::string description	= "Blit from " + getFormatCaseName(params.src.image.format) +
											" to " + getFormatCaseName(params.dst.image.format);
			addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);

			if (hasDepth && hasStencil)
			{
				params.separateDepthStencilLayouts	= DE_TRUE;
				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" +
												getFormatCaseName(params.dst.image.format) + "_separate_layouts";
				const std::string description2	= "Blit from " + getFormatCaseName(params.src.image.format) +
												" to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
				addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
			}
		}

		group->addChild(subGroup.release());
	}

	// 1D tests
	{
		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));

		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
		{
			TestParams	params;
			params.src.image.imageType			= VK_IMAGE_TYPE_1D;
			params.dst.image.imageType			= VK_IMAGE_TYPE_1D;
			params.src.image.extent				= default1dExtent;
			params.dst.image.extent				= default1dExtent;
			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
			params.dst.image.format				= params.src.image.format;
			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
			params.allocationKind				= allocationKind;
			params.extensionUse					= extensionUse;

			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);

			CopyRegion	region;
			for (int i = 0; i < defaultSize; i += defaultSize / 2)
			{
				const VkOffset3D	srcOffset0	= {0, 0, 0};
				const VkOffset3D	srcOffset1	= {defaultSize, 1, 1};
				const VkOffset3D	dstOffset0	= {i, 0, 0};
				const VkOffset3D	dstOffset1	= {i + defaultFourthSize, 1, 1};

				if (hasDepth)
				{
					const VkImageBlit			imageBlit	=
					{
						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
					};
					region.imageBlit	= imageBlit;
					params.regions.push_back(region);
				}
				if (hasStencil)
				{
					const VkImageBlit			imageBlit	=
					{
						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
					};
					region.imageBlit	= imageBlit;
					params.regions.push_back(region);
				}
			}

			{
				const VkOffset3D	srcOffset0	= {0, 0, 0};
				const VkOffset3D	srcOffset1	= {defaultFourthSize, 1, 1};
				const VkOffset3D	dstOffset0	= {defaultFourthSize, 0, 0};
				const VkOffset3D	dstOffset1	= {2 * defaultFourthSize, 1, 1};

				if (hasDepth)
				{
					const VkImageBlit			imageBlit	=
					{
						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
					};
					region.imageBlit	= imageBlit;
					params.regions.push_back(region);
				}
				if (hasStencil)
				{
					const VkImageBlit			imageBlit	=
					{
						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
					};
					region.imageBlit	= imageBlit;
					params.regions.push_back(region);
				}
				if (hasDepth && hasStencil)
				{
					const VkOffset3D			dstDSOffset0	= {3 * defaultFourthSize, 0, 0};
					const VkOffset3D			dstDSOffset1	= {3 * defaultFourthSize + defaultFourthSize / 2, 1, 1};
					const VkImageBlit			imageBlit	=
					{
						defaultDSSourceLayer,			// VkImageSubresourceLayers	srcSubresource;
						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
						defaultDSSourceLayer,			// VkImageSubresourceLayers	dstSubresource;
						{ dstDSOffset0, dstDSOffset1 }	// VkOffset3D					dstOffset[2];
					};
					region.imageBlit	= imageBlit;
					params.regions.push_back(region);
				}
			}

			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
			const std::string description	= "Blit from " + getFormatCaseName(params.src.image.format) +
											" to " + getFormatCaseName(params.dst.image.format);
			addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);

			if (hasDepth && hasStencil)
			{
				params.separateDepthStencilLayouts	= DE_TRUE;
				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" +
												getFormatCaseName(params.dst.image.format) + "_separate_layouts";
				const std::string description2	= "Blit from " + getFormatCaseName(params.src.image.format) +
												" to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
				addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
			}
		}

		group->addChild(subGroup.release());
	}

	// 3D tests. Note we use smaller dimensions here for performance reasons.
	{
		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));

		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
		{
			TestParams	params;
			params.src.image.imageType			= VK_IMAGE_TYPE_3D;
			params.dst.image.imageType			= VK_IMAGE_TYPE_3D;
			params.src.image.extent				= default3dExtent;
			params.dst.image.extent				= default3dExtent;
			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
			params.dst.image.format				= params.src.image.format;
			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
			params.allocationKind				= allocationKind;
			params.extensionUse					= extensionUse;

			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);

			CopyRegion	region;
			for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultFourthSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
			{
				const VkOffset3D	srcOffset0	= {0, 0, 0};
				const VkOffset3D	srcOffset1	= {defaultFourthSize, defaultFourthSize, defaultFourthSize};
				const VkOffset3D	dstOffset0	= {i, 0, i};
				const VkOffset3D	dstOffset1	= {i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j};

				if (hasDepth)
				{
					const VkImageBlit			imageBlit	=
					{
						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
					};
					region.imageBlit	= imageBlit;
					params.regions.push_back(region);
				}
				if (hasStencil)
				{
					const VkImageBlit			imageBlit	=
					{
						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
					};
					region.imageBlit	= imageBlit;
					params.regions.push_back(region);
				}
			}
			for (int i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
			{
				const VkOffset3D	srcOffset0	= {i, i, i};
				const VkOffset3D	srcOffset1	= {i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize};
				const VkOffset3D	dstOffset0	= {i, defaultFourthSize / 2, i};
				const VkOffset3D	dstOffset1	= {i + defaultSixteenthSize, defaultFourthSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize};

				if (hasDepth)
				{
					const VkImageBlit			imageBlit	=
					{
						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
					};
					region.imageBlit	= imageBlit;
					params.regions.push_back(region);
				}
				if (hasStencil)
				{
					const VkImageBlit			imageBlit	=
					{
						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
					};
					region.imageBlit	= imageBlit;
					params.regions.push_back(region);
				}
				if (hasDepth && hasStencil)
				{
					const VkOffset3D			dstDSOffset0	= {i, 3 * defaultSixteenthSize, i};
					const VkOffset3D			dstDSOffset1	= {i + defaultSixteenthSize, defaultFourthSize, i + defaultSixteenthSize};
					const VkImageBlit			imageBlit	=
					{
						defaultDSSourceLayer,			// VkImageSubresourceLayers	srcSubresource;
						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
						defaultDSSourceLayer,			// VkImageSubresourceLayers	dstSubresource;
						{ dstDSOffset0, dstDSOffset1 }	// VkOffset3D					dstOffset[2];
					};
					region.imageBlit	= imageBlit;
					params.regions.push_back(region);
				}
			}

			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
			const std::string description	= "Blit from " + getFormatCaseName(params.src.image.format) +
											" to " + getFormatCaseName(params.dst.image.format);
			addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);

			if (hasDepth && hasStencil)
			{
				params.separateDepthStencilLayouts	= DE_TRUE;
				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" +
												getFormatCaseName(params.dst.image.format) + "_separate_layouts";
				const std::string description2	= "Blit from " + getFormatCaseName(params.src.image.format) +
												" to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
				addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
			}
		}

		group->addChild(subGroup.release());
	}
}

void addBlittingImageAllFormatsMipmapFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
{
	tcu::TestContext& testCtx				= group->getTestContext();

	const VkImageLayout blitSrcLayouts[]	=
	{
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
		VK_IMAGE_LAYOUT_GENERAL
	};
	const VkImageLayout blitDstLayouts[]	=
	{
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
		VK_IMAGE_LAYOUT_GENERAL
	};

	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
	{
		testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
		{
			testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];

			testParams.params.filter			= VK_FILTER_NEAREST;
			const std::string testName			= getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
												  getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
			const std::string description		= "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) +
												  " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
			group->addChild(new BlitMipmapTestCase(testCtx, testName + "_nearest", description, testParams.params));

			if (testParams.testFilters & FILTER_MASK_LINEAR)
			{
				testParams.params.filter = VK_FILTER_LINEAR;
				group->addChild(new BlitMipmapTestCase(testCtx, testName + "_linear", description, testParams.params));
			}

			if (testParams.testFilters & FILTER_MASK_CUBIC)
			{
				testParams.params.filter = VK_FILTER_CUBIC_EXT;
				group->addChild(new BlitMipmapTestCase(testCtx, testName + "_cubic", description, testParams.params));
			}
		}
	}
}

void addBlittingImageAllFormatsBaseLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	const struct
	{
		const VkFormat* const	compatibleFormats;
		const bool				onlyNearest;
	}	colorImageFormatsToTestBlit[]			=
	{
		{ compatibleFormatsUInts,	true	},
		{ compatibleFormatsSInts,	true	},
		{ compatibleFormatsFloats,	false	},
		{ compatibleFormatsSrgb,	false	},
	};

	const int	numOfColorImageFormatsToTest	= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);

	const int	layerCountsToTest[]				=
	{
		1,
		6
	};

	TestParams	params;
	params.src.image.imageType	= VK_IMAGE_TYPE_2D;
	params.src.image.extent		= defaultExtent;
	params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
	params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
	params.dst.image.extent		= defaultExtent;
	params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
	params.allocationKind		= allocationKind;
	params.extensionUse			= extensionUse;
	params.mipLevels			= deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u;
	params.singleCommand		= DE_TRUE;

	CopyRegion	region;
	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
	{
		VkImageSubresourceLayers	destLayer	= defaultSourceLayer;
		destLayer.mipLevel = mipLevelNdx;

		const VkImageBlit			imageBlit	=
		{
			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
			{
				{0, 0, 0},
				{defaultSize, defaultSize, 1}
			},					// VkOffset3D					srcOffsets[2];

			destLayer,			// VkImageSubresourceLayers	dstSubresource;
			{
				{0, 0, 0},
				{defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
			}					// VkOffset3D					dstOffset[2];
		};
		region.imageBlit	= imageBlit;
		params.regions.push_back(region);
	}

	if (allocationKind == ALLOCATION_KIND_DEDICATED)
	{
		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
	}

	for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
	{
		const int						layerCount		= layerCountsToTest[layerCountIndex];
		const std::string				layerGroupName	= "layercount_" + de::toString(layerCount);
		const std::string				layerGroupDesc	= "Blit mipmaps with layerCount = " + de::toString(layerCount);

		de::MovePtr<tcu::TestCaseGroup>	layerCountGroup	(new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));

		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
		{
			const VkFormat*	compatibleFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;

			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
			{
				params.src.image.format	= compatibleFormats[srcFormatIndex];
				params.dst.image.format	= compatibleFormats[srcFormatIndex];

				if (!isSupportedByFramework(params.src.image.format))
					continue;

				const bool onlyNearestAndLinear	= de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);

				const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);

				BlitColorTestParams testParams;
				testParams.params				= params;
				testParams.compatibleFormats	= compatibleFormats;
				testParams.testFilters			= makeFilterMask(onlyNearest, onlyNearestAndLinear);

				testParams.params.src.image.extent.depth = layerCount;
				testParams.params.dst.image.extent.depth = layerCount;

				for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
				{
					testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
					testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
				}

				addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
			}
		}
		group->addChild(layerCountGroup.release());
	}
}

void addBlittingImageAllFormatsPreviousLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	const struct
	{
		const VkFormat* const	compatibleFormats;
		const bool				onlyNearest;
	}	colorImageFormatsToTestBlit[]			=
	{
		{ compatibleFormatsUInts,	true	},
		{ compatibleFormatsSInts,	true	},
		{ compatibleFormatsFloats,	false	},
		{ compatibleFormatsSrgb,	false	},
	};

	const int	numOfColorImageFormatsToTest	= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);

	const int	layerCountsToTest[]				=
	{
		1,
		6
	};

	TestParams	params;
	params.src.image.imageType	= VK_IMAGE_TYPE_2D;
	params.src.image.extent		= defaultExtent;
	params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
	params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
	params.dst.image.extent		= defaultExtent;
	params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
	params.allocationKind		= allocationKind;
	params.extensionUse			= extensionUse;
	params.mipLevels			= deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u;
	params.singleCommand		= DE_FALSE;

	CopyRegion	region;
	for (deUint32 mipLevelNdx = 1u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
	{
		VkImageSubresourceLayers	srcLayer	= defaultSourceLayer;
		VkImageSubresourceLayers	destLayer	= defaultSourceLayer;

		srcLayer.mipLevel	= mipLevelNdx - 1u;
		destLayer.mipLevel	= mipLevelNdx;

		const VkImageBlit			imageBlit	=
		{
			srcLayer,			// VkImageSubresourceLayers	srcSubresource;
			{
				{0, 0, 0},
				{defaultSize >> (mipLevelNdx - 1u), defaultSize >> (mipLevelNdx - 1u), 1}
			},					// VkOffset3D					srcOffsets[2];

			destLayer,			// VkImageSubresourceLayers	dstSubresource;
			{
				{0, 0, 0},
				{defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
			}					// VkOffset3D					dstOffset[2];
		};
		region.imageBlit	= imageBlit;
		params.regions.push_back(region);
	}

	if (allocationKind == ALLOCATION_KIND_DEDICATED)
	{
		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
	}

	for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
	{
		const int						layerCount		= layerCountsToTest[layerCountIndex];
		const std::string				layerGroupName	= "layercount_" + de::toString(layerCount);
		const std::string				layerGroupDesc	= "Blit mipmaps with layerCount = " + de::toString(layerCount);

		de::MovePtr<tcu::TestCaseGroup>	layerCountGroup	(new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));

		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
		{
			const VkFormat*	compatibleFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;

			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
			{
				params.src.image.format						= compatibleFormats[srcFormatIndex];
				params.dst.image.format						= compatibleFormats[srcFormatIndex];

				if (!isSupportedByFramework(params.src.image.format))
					continue;

				const bool			onlyNearestAndLinear	= de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);

				const std::string	description				= "Blit source format " + getFormatCaseName(params.src.image.format);

				BlitColorTestParams	testParams;
				testParams.params							= params;
				testParams.compatibleFormats				= compatibleFormats;
				testParams.testFilters						= makeFilterMask(onlyNearest, onlyNearestAndLinear);

				testParams.params.src.image.extent.depth	= layerCount;
				testParams.params.dst.image.extent.depth	= layerCount;

				for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
				{
					testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
					testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
				}

				addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
			}
		}
		group->addChild(layerCountGroup.release());
	}

	for (int multiLayer = 0; multiLayer < 2; multiLayer++)
	{
		const int layerCount = multiLayer ? 6 : 1;

		for (int barrierCount = 1; barrierCount < 4; barrierCount++)
		{
			if (layerCount != 1 || barrierCount != 1)
			{
				const std::string				barrierGroupName = (multiLayer ? "layerbarriercount_" : "mipbarriercount_") + de::toString(barrierCount);
				const std::string				barrierGroupDesc = "Use " + de::toString(barrierCount) + " image barriers";

				de::MovePtr<tcu::TestCaseGroup>	barrierCountGroup(new tcu::TestCaseGroup(group->getTestContext(), barrierGroupName.c_str(), barrierGroupDesc.c_str()));

				params.barrierCount = barrierCount;

				// Only go through a few common formats
				for (int srcFormatIndex = 2; srcFormatIndex < 6; ++srcFormatIndex)
				{
					params.src.image.format						= compatibleFormatsUInts[srcFormatIndex];
					params.dst.image.format						= compatibleFormatsUInts[srcFormatIndex];

					if (!isSupportedByFramework(params.src.image.format))
						continue;

					const std::string description				= "Blit source format " + getFormatCaseName(params.src.image.format);

					BlitColorTestParams testParams;
					testParams.params							= params;
					testParams.compatibleFormats				= compatibleFormatsUInts;
					testParams.testFilters						= FILTER_MASK_NEAREST;

					testParams.params.src.image.extent.depth	= layerCount;
					testParams.params.dst.image.extent.depth	= layerCount;

					for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
					{
						testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
						testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
					}

					addTestGroup(barrierCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
				}
				group->addChild(barrierCountGroup.release());
			}
		}
	}
}

void addBlittingImageAllFormatsMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	addTestGroup(group, "from_base_level", "Generate all mipmap levels from base level", addBlittingImageAllFormatsBaseLevelMipmapTests, allocationKind, extensionUse);
	addTestGroup(group, "from_previous_level", "Generate next mipmap level from previous level", addBlittingImageAllFormatsPreviousLevelMipmapTests, allocationKind, extensionUse);
}

void addBlittingImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	addTestGroup(group, "color", "Blitting image with color formats", addBlittingImageAllFormatsColorTests, allocationKind, extensionUse);
	addTestGroup(group, "depth_stencil", "Blitting image with depth/stencil formats", addBlittingImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
	addTestGroup(group, "generate_mipmaps", "Generating mipmaps with vkCmdBlitImage()", addBlittingImageAllFormatsMipmapTests, allocationKind, extensionUse);
}

void addBlittingImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	addTestGroup(group, "simple_tests", "Blitting image simple tests", addBlittingImageSimpleTests, allocationKind, extensionUse);
	addTestGroup(group, "all_formats", "Blitting image with all compatible formats", addBlittingImageAllFormatsTests, allocationKind, extensionUse);
}

const VkSampleCountFlagBits	samples[]		=
{
	VK_SAMPLE_COUNT_2_BIT,
	VK_SAMPLE_COUNT_4_BIT,
	VK_SAMPLE_COUNT_8_BIT,
	VK_SAMPLE_COUNT_16_BIT,
	VK_SAMPLE_COUNT_32_BIT,
	VK_SAMPLE_COUNT_64_BIT
};
const VkExtent3D			resolveExtent	= {256u, 256u, 1};

void addResolveImageWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	TestParams	params;
	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
	params.src.image.extent				= resolveExtent;
	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
	params.dst.image.extent				= resolveExtent;
	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
	params.allocationKind				= allocationKind;
	params.extensionUse					= extensionUse;

	{
		const VkImageSubresourceLayers	sourceLayer	=
		{
			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
			0u,							// deUint32				mipLevel;
			0u,							// deUint32				baseArrayLayer;
			1u							// deUint32				layerCount;
		};
		const VkImageResolve			testResolve	=
		{
			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
			{0, 0, 0},		// VkOffset3D				srcOffset;
			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
			{0, 0, 0},		// VkOffset3D				dstOffset;
			resolveExtent,	// VkExtent3D				extent;
		};

		CopyRegion	imageResolve;
		imageResolve.imageResolve	= testResolve;
		params.regions.push_back(imageResolve);
	}

	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
	{
		params.samples					= samples[samplesIndex];
		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
	}
}

void addResolveImagePartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	TestParams	params;
	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
	params.src.image.extent				= resolveExtent;
	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
	params.dst.image.extent				= resolveExtent;
	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
	params.allocationKind				= allocationKind;
	params.extensionUse					= extensionUse;

	{
		const VkImageSubresourceLayers	sourceLayer	=
		{
			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
			0u,							// deUint32				mipLevel;
			0u,							// deUint32				baseArrayLayer;
			1u							// deUint32				layerCount;
		};
		const VkImageResolve			testResolve	=
		{
			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
			{0, 0, 0},		// VkOffset3D				srcOffset;
			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
			{64u, 64u, 0},		// VkOffset3D				dstOffset;
			{128u, 128u, 1u},	// VkExtent3D				extent;
		};

		CopyRegion	imageResolve;
		imageResolve.imageResolve = testResolve;
		params.regions.push_back(imageResolve);
	}

	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
	{
		params.samples					= samples[samplesIndex];
		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
	}
}

void addResolveImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	TestParams	params;
	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
	params.src.image.extent				= resolveExtent;
	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
	params.dst.image.extent				= resolveExtent;
	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
	params.allocationKind				= allocationKind;
	params.extensionUse					= extensionUse;

	{
		const VkImageSubresourceLayers	sourceLayer	=
		{
			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
			0u,							// deUint32				mipLevel;
			0u,							// deUint32				baseArrayLayer;
			1u							// deUint32				layerCount;
		};

		for (int i = 0; i < 256; i += 64)
		{
			const VkImageResolve			testResolve	=
			{
				sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
				{i, i, 0},		// VkOffset3D				srcOffset;
				sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
				{i, 0, 0},		// VkOffset3D				dstOffset;
				{64u, 64u, 1u},	// VkExtent3D				extent;
			};

			CopyRegion	imageResolve;
			imageResolve.imageResolve = testResolve;
			params.regions.push_back(imageResolve);
		}
	}

	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
	{
		params.samples					= samples[samplesIndex];
		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
	}
}

void addResolveImageWholeCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	TestParams	params;
	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
	params.src.image.extent				= defaultExtent;
	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
	params.dst.image.extent				= defaultExtent;
	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
	params.allocationKind				= allocationKind;
	params.extensionUse					= extensionUse;

	{
		const VkImageSubresourceLayers	sourceLayer	=
		{
			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
			0u,							// deUint32				mipLevel;
			0u,							// deUint32				baseArrayLayer;
			1u							// deUint32				layerCount;
		};

		const VkImageResolve			testResolve	=
		{
			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
			{0, 0, 0},			// VkOffset3D				srcOffset;
			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
			{0, 0, 0},			// VkOffset3D				dstOffset;
			defaultExtent,		// VkExtent3D				extent;
		};

		CopyRegion	imageResolve;
		imageResolve.imageResolve	= testResolve;
		params.regions.push_back(imageResolve);
	}

	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
	{
		params.samples					= samples[samplesIndex];
		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
	}
}

void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	TestParams	params;
	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
	params.src.image.extent				= defaultExtent;
	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
	params.dst.image.extent				= defaultExtent;
	params.dst.image.extent.depth		= 5u;
	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
	params.allocationKind				= allocationKind;
	params.extensionUse					= extensionUse;

	for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
	{
		const VkImageSubresourceLayers	sourceLayer	=
		{
			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
			0u,								// deUint32				mipLevel;
			layerNdx,						// deUint32				baseArrayLayer;
			1u								// deUint32				layerCount;
		};

		const VkImageResolve			testResolve	=
		{
			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
			{0, 0, 0},			// VkOffset3D				srcOffset;
			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
			{0, 0, 0},			// VkOffset3D				dstOffset;
			defaultExtent,		// VkExtent3D				extent;
		};

		CopyRegion	imageResolve;
		imageResolve.imageResolve	= testResolve;
		params.regions.push_back(imageResolve);
	}

	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
	{
		params.samples					= samples[samplesIndex];
		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
	}
}

void addResolveImageWholeArrayImageSingleRegionTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	TestParams	params;
	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
	params.src.image.extent				= defaultExtent;
	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
	params.dst.image.extent				= defaultExtent;
	params.dst.image.extent.depth		= 5u;
	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
	params.allocationKind				= allocationKind;
	params.extensionUse					= extensionUse;

	const VkImageSubresourceLayers	sourceLayer	=
	{
		VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
		0u,								// uint32_t				mipLevel;
		0,						// uint32_t				baseArrayLayer;
		params.dst.image.extent.depth			// uint32_t				layerCount;
	};

	const VkImageResolve			testResolve	=
	{
		sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
		{0, 0, 0},			// VkOffset3D				srcOffset;
		sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
		{0, 0, 0},			// VkOffset3D				dstOffset;
		defaultExtent,		// VkExtent3D				extent;
	};

	CopyRegion	imageResolve;
	imageResolve.imageResolve	= testResolve;
	params.regions.push_back(imageResolve);

	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
	{
		params.samples					= samples[samplesIndex];
		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
	}
}

void addResolveImageDiffImageSizeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	tcu::TestContext&	testCtx			= group->getTestContext();
	TestParams			params;
	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
	params.allocationKind				= allocationKind;
	params.extensionUse					= extensionUse;

	{
		const VkImageSubresourceLayers	sourceLayer	=
		{
			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
			0u,							// deUint32				mipLevel;
			0u,							// deUint32				baseArrayLayer;
			1u							// deUint32				layerCount;
		};
		const VkImageResolve			testResolve	=
		{
			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
			{0, 0, 0},		// VkOffset3D				srcOffset;
			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
			{0, 0, 0},		// VkOffset3D				dstOffset;
			resolveExtent,	// VkExtent3D				extent;
		};
		CopyRegion	imageResolve;
		imageResolve.imageResolve	= testResolve;
		params.regions.push_back(imageResolve);
	}

	const VkExtent3D imageExtents[]		=
	{
		{ resolveExtent.width + 10,	resolveExtent.height,		resolveExtent.depth },
		{ resolveExtent.width,		resolveExtent.height * 2,	resolveExtent.depth },
		{ resolveExtent.width,		resolveExtent.height,		resolveExtent.depth + 10 }
	};

	for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex)
	{
		const VkExtent3D&	srcImageSize	= imageExtents[srcImageExtentIndex];
		params.src.image.extent				= srcImageSize;
		params.dst.image.extent				= resolveExtent;
		for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
		{
			params.samples	= samples[samplesIndex];
			std::ostringstream testName;
			testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
			std::ostringstream description;
			description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and source image size ("
						<< srcImageSize.width << ", " << srcImageSize.height << ", " << srcImageSize.depth << ")";
			group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
		}
	}
	for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex)
	{
		const VkExtent3D&	dstImageSize	= imageExtents[dstImageExtentIndex];
		params.src.image.extent				= resolveExtent;
		params.dst.image.extent				= dstImageSize;
		for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
		{
			params.samples	= samples[samplesIndex];
			std::ostringstream testName;
			testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
			std::ostringstream description;
			description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and destination image size ("
						<< dstImageSize.width << ", " << dstImageSize.height << ", " << dstImageSize.depth << ")";
			group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
		}
	}
}

void addBufferCopyOffsetTests (tcu::TestCaseGroup* group)
{
	de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "buffer_to_buffer_with_offset", "Copy from buffer to buffer using different offsets in the source and destination buffers"));

	for (deUint32 srcOffset = 0u; srcOffset < BufferOffsetParams::kMaxOffset; ++srcOffset)
	for (deUint32 dstOffset = 0u; dstOffset < BufferOffsetParams::kMaxOffset; ++dstOffset)
	{
		BufferOffsetParams params{srcOffset, dstOffset};
		addFunctionCase(subGroup.get(), de::toString(srcOffset) + "_" + de::toString(dstOffset), "", bufferOffsetTest, params);
	}

	group->addChild(subGroup.release());
}

void addResolveImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	addTestGroup(group, "whole", "Resolve from image to image (whole)", addResolveImageWholeTests, allocationKind, extensionUse);
	addTestGroup(group, "partial", "Resolve from image to image (partial)", addResolveImagePartialTests, allocationKind, extensionUse);
	addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind, extensionUse);
	addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind, extensionUse);
	addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind, extensionUse);
	addTestGroup(group, "whole_array_image_one_region", "Resolve from image to image (whole array image with single region)", addResolveImageWholeArrayImageSingleRegionTests, allocationKind, extensionUse);
	addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind, extensionUse);
}

void addCopiesAndBlittingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
	addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind, extensionUse);
	addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind, extensionUse);
	addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind, extensionUse);
	addTestGroup(group, "buffer_to_depthstencil", "Copy from buffer to depth/Stencil", addBufferToDepthStencilTests, allocationKind, extensionUse);
	addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind, extensionUse);
	addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind, extensionUse);
	addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind, extensionUse);
}

void addCoreCopiesAndBlittingTests(tcu::TestCaseGroup* group)
{
	addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED, EXTENSION_USE_NONE);
	addBufferCopyOffsetTests(group);
}


void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group)
{
	addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_NONE);
}

void addExtensionCopiesAndBlittingTests(tcu::TestCaseGroup* group)
{
	addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_COPY_COMMANDS2);
}

} // anonymous

tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup>	copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));

	copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core", "Core Copies And Blitting Tests", addCoreCopiesAndBlittingTests));
	copiesAndBlittingTests->addChild(createTestGroup(testCtx, "dedicated_allocation",	"Copies And Blitting Tests For Dedicated Memory Allocation",	addDedicatedAllocationCopiesAndBlittingTests));
	copiesAndBlittingTests->addChild(createTestGroup(testCtx, "copy_commands2", "Copies And Blitting Tests using KHR_copy_commands2", addExtensionCopiesAndBlittingTests));

	return copiesAndBlittingTests.release();
}

} // api
} // vkt
