/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2017 The Khronos Group Inc.
 *
 * 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  vktImageCompressionTranscodingSupport.cpp
 * \brief Compression transcoding support
 *//*--------------------------------------------------------------------*/

#include "vktImageCompressionTranscodingSupport.hpp"
#include "vktImageLoadStoreUtil.hpp"

#include "deUniquePtr.hpp"
#include "deStringUtil.hpp"
#include "deSharedPtr.hpp"
#include "deRandom.hpp"

#include "vktTestCaseUtil.hpp"
#include "vkPrograms.hpp"
#include "vkImageUtil.hpp"
#include "vkBarrierUtil.hpp"
#include "vktImageTestsUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"

#include "tcuTextureUtil.hpp"
#include "tcuTexture.hpp"
#include "tcuCompressedTexture.hpp"
#include "tcuVectorType.hpp"
#include "tcuResource.hpp"
#include "tcuImageIO.hpp"
#include "tcuImageCompare.hpp"
#include "tcuTestLog.hpp"
#include "tcuRGBA.hpp"
#include "tcuSurface.hpp"

#include <vector>

using namespace vk;
namespace vkt
{
namespace image
{
namespace
{
using std::string;
using std::vector;
using tcu::TestContext;
using tcu::TestStatus;
using tcu::UVec3;
using tcu::IVec3;
using tcu::CompressedTexFormat;
using tcu::CompressedTexture;
using tcu::Resource;
using tcu::Archive;
using tcu::ConstPixelBufferAccess;
using de::MovePtr;
using de::SharedPtr;
using de::Random;

typedef SharedPtr<MovePtr<Image> >			ImageSp;
typedef SharedPtr<Move<VkImageView> >		ImageViewSp;
typedef SharedPtr<Move<VkDescriptorSet> >	SharedVkDescriptorSet;

enum ShaderType
{
	SHADER_TYPE_COMPUTE,
	SHADER_TYPE_FRAGMENT,
	SHADER_TYPE_LAST
};

enum Operation
{
	OPERATION_IMAGE_LOAD,
	OPERATION_TEXEL_FETCH,
	OPERATION_TEXTURE,
	OPERATION_IMAGE_STORE,
	OPERATION_ATTACHMENT_READ,
	OPERATION_ATTACHMENT_WRITE,
	OPERATION_TEXTURE_READ,
	OPERATION_TEXTURE_WRITE,
	OPERATION_LAST
};

struct TestParameters
{
	Operation			operation;
	ShaderType			shader;
	UVec3				size;
	deUint32			layers;
	ImageType			imageType;
	VkFormat			formatCompressed;
	VkFormat			formatUncompressed;
	deUint32			imagesCount;
	VkImageUsageFlags	compressedImageUsage;
	VkImageUsageFlags	compressedImageViewUsage;
	VkImageUsageFlags	uncompressedImageUsage;
	bool				useMipmaps;
	VkFormat			formatForVerify;
	bool				formatIsASTC;
};

template<typename T>
inline SharedPtr<Move<T> > makeVkSharedPtr (Move<T> move)
{
	return SharedPtr<Move<T> >(new Move<T>(move));
}

template<typename T>
inline SharedPtr<MovePtr<T> > makeVkSharedPtr (MovePtr<T> movePtr)
{
	return SharedPtr<MovePtr<T> >(new MovePtr<T>(movePtr));
}

const deUint32 SINGLE_LEVEL = 1u;
const deUint32 SINGLE_LAYER = 1u;

enum BinaryCompareMode
{
	COMPARE_MODE_NORMAL,
	COMPARE_MODE_ALLOW_ASTC_ERROR_COLOUR_WARNING,
};

enum BinaryCompareResult
{
	COMPARE_RESULT_OK,
	COMPARE_RESULT_ASTC_QUALITY_WARNING,
	COMPARE_RESULT_FAILED,
};

const deUint32 ASTC_LDR_ERROR_COLOUR = 0xFFFF00FF;
const deUint32 ASTC_HDR_ERROR_COLOUR = 0x00000000;

static BinaryCompareResult BinaryCompare(const void				*reference,
										 const void				*result,
										 VkDeviceSize			sizeInBytes,
										 VkFormat				formatForVerify,
										 BinaryCompareMode		mode)
{
	DE_UNREF(formatForVerify);

	// Compare quickly using deMemCmp
	if (deMemCmp(reference, result, (size_t)sizeInBytes) == 0)
	{
		return COMPARE_RESULT_OK;
	}
	// If deMemCmp indicated a mismatch, we can re-check with a manual comparison of
	// the ref and res images that allows for ASTC error colour mismatches if the ASTC
	// comparison mode was selected. This slows down the affected ASTC tests if you
	// didn't pass in the first comparison, but means in the general case the
	// comparion is still fast.
	else if (mode == COMPARE_MODE_ALLOW_ASTC_ERROR_COLOUR_WARNING)
	{
		bool bWarn = false;
		bool bFail = false;
		const deUint32 *pui32RefVal = (deUint32*)reference;
		const deUint32 *pui32ResVal = (deUint32*)result;

		DE_ASSERT(formatForVerify == VK_FORMAT_R8G8B8A8_UNORM);
		size_t numPixels = (size_t)(sizeInBytes / 4) /* bytes */;
		for (size_t i = 0; i < numPixels; i++)
		{
			const deUint32 ref = *pui32RefVal++;
			const deUint32 res = *pui32ResVal++;

			if (ref != res)
			{
				// QualityWarning !1231: If the astc pixel was the ASTC LDR error colour
				// and the result image has the HDR error colour (or vice versa as the test
				// cases below sometimes reverse the operands) then issue a quality warning
				// instead of a failure.
				if ((ref == ASTC_LDR_ERROR_COLOUR && res == ASTC_HDR_ERROR_COLOUR) ||
					(ref == ASTC_HDR_ERROR_COLOUR && res == ASTC_LDR_ERROR_COLOUR))
				{
					bWarn = true;
				}
				else
				{
					bFail = true;
				}
			}
		}

		if (!bFail)
		{
			return (bWarn)
				? (COMPARE_RESULT_ASTC_QUALITY_WARNING)
				: (COMPARE_RESULT_OK);
		}
	}

	return COMPARE_RESULT_FAILED;
}

static bool FormatIsASTC(VkFormat format)
{
	return deInRange32(format, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_FORMAT_ASTC_12x12_SRGB_BLOCK);
}

static TestStatus TestStatusASTCQualityWarning()
{
	return TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "ASTC HDR error colour output instead of LDR error colour");
}

class BasicTranscodingTestInstance : public TestInstance
{
public:
							BasicTranscodingTestInstance	(Context&						context,
															 const TestParameters&			parameters);
	virtual TestStatus		iterate							(void) = 0;
protected:
	void					generateData					(deUint8*						toFill,
															 const size_t					size,
															 const VkFormat					format,
															 const deUint32					layer = 0u,
															 const deUint32					level = 0u);
	deUint32				getLevelCount					();
	deUint32				getLayerCount					();
	UVec3					getLayerDims					();
	vector<UVec3>			getMipLevelSizes				(UVec3							baseSize);
	vector<UVec3>			getCompressedMipLevelSizes		(const VkFormat					compressedFormat,
															 const vector<UVec3>&			uncompressedSizes);

	const TestParameters	m_parameters;
	const deUint32			m_blockWidth;
	const deUint32			m_blockHeight;
	const deUint32			m_levelCount;
	const UVec3				m_layerSize;

	// Detected error colour mismatch while verifying image. Output
	// the ASTC quality warning instead of a pass
	bool					m_bASTCErrorColourMismatch;

private:
	deUint32				findMipMapLevelCount			();
};

deUint32 BasicTranscodingTestInstance::findMipMapLevelCount ()
{
	deUint32 levelCount = 1;

	// We cannot use mipmap levels which have resolution below block size.
	// Reduce number of mipmap levels
	if (m_parameters.useMipmaps)
	{
		deUint32 w = m_parameters.size.x();
		deUint32 h = m_parameters.size.y();

		DE_ASSERT(m_blockWidth > 0u && m_blockHeight > 0u);

		while (w > m_blockWidth && h > m_blockHeight)
		{
			w >>= 1;
			h >>= 1;

			if (w > m_blockWidth && h > m_blockHeight)
				levelCount++;
		}

		DE_ASSERT((m_parameters.size.x() >> (levelCount - 1u)) >= m_blockWidth);
		DE_ASSERT((m_parameters.size.y() >> (levelCount - 1u)) >= m_blockHeight);
	}

	return levelCount;
}

BasicTranscodingTestInstance::BasicTranscodingTestInstance (Context& context, const TestParameters& parameters)
	: TestInstance	(context)
	, m_parameters	(parameters)
	, m_blockWidth	(getBlockWidth(m_parameters.formatCompressed))
	, m_blockHeight	(getBlockHeight(m_parameters.formatCompressed))
	, m_levelCount	(findMipMapLevelCount())
	, m_layerSize	(getLayerSize(m_parameters.imageType, m_parameters.size))
	, m_bASTCErrorColourMismatch(false)
{
	DE_ASSERT(deLog2Floor32(m_parameters.size.x()) == deLog2Floor32(m_parameters.size.y()));
}

deUint32 BasicTranscodingTestInstance::getLevelCount()
{
	return m_levelCount;
}

deUint32 BasicTranscodingTestInstance::getLayerCount()
{
	return m_parameters.layers;
}

UVec3 BasicTranscodingTestInstance::getLayerDims()
{
	return m_layerSize;
}

vector<UVec3> BasicTranscodingTestInstance::getMipLevelSizes (UVec3 baseSize)
{
	vector<UVec3>	levelSizes;
	const deUint32	levelCount = getLevelCount();

	baseSize.z() = 1u;

	levelSizes.push_back(baseSize);

	if (m_parameters.imageType == IMAGE_TYPE_1D)
	{
		baseSize.y() = 1u;

		while (levelSizes.size() < levelCount && (baseSize.x() != 1))
		{
			baseSize.x() = deMax32(baseSize.x() >> 1, 1);
			levelSizes.push_back(baseSize);
		}
	}
	else
	{
		while (levelSizes.size() < levelCount && (baseSize.x() != 1 || baseSize.y() != 1))
		{
			baseSize.x() = deMax32(baseSize.x() >> 1, 1);
			baseSize.y() = deMax32(baseSize.y() >> 1, 1);
			levelSizes.push_back(baseSize);
		}
	}

	DE_ASSERT(levelSizes.size() == getLevelCount());

	return levelSizes;
}

vector<UVec3> BasicTranscodingTestInstance::getCompressedMipLevelSizes (const VkFormat compressedFormat, const vector<UVec3>& uncompressedSizes)
{
	vector<UVec3> levelSizes;
	vector<UVec3>::const_iterator it;

	for (it = uncompressedSizes.begin(); it != uncompressedSizes.end(); it++)
		levelSizes.push_back(getCompressedImageResolutionInBlocks(compressedFormat, *it));

	return levelSizes;
}

void BasicTranscodingTestInstance::generateData (deUint8*		toFill,
												 const size_t	size,
												 const VkFormat format,
												 const deUint32 layer,
												 const deUint32 level)
{
	const deUint8 pattern[] =
	{
		// 64-bit values
		0x11, 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x22,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
		0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		// Positive infinity
		0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		// Negative infinity
		0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,		// Start of a signalling NaN (NANS)
		0x7F, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,		// End of a signalling NaN (NANS)
		0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,		// Start of a signalling NaN (NANS)
		0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,		// End of a signalling NaN (NANS)
		0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		// Start of a quiet NaN (NANQ)
		0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,		// End of of a quiet NaN (NANQ)
		0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		// Start of a quiet NaN (NANQ)
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,		// End of a quiet NaN (NANQ)
		// 32-bit values
		0x7F, 0x80, 0x00, 0x00,								// Positive infinity
		0xFF, 0x80, 0x00, 0x00,								// Negative infinity
		0x7F, 0x80, 0x00, 0x01,								// Start of a signalling NaN (NANS)
		0x7F, 0xBF, 0xFF, 0xFF,								// End of a signalling NaN (NANS)
		0xFF, 0x80, 0x00, 0x01,								// Start of a signalling NaN (NANS)
		0xFF, 0xBF, 0xFF, 0xFF,								// End of a signalling NaN (NANS)
		0x7F, 0xC0, 0x00, 0x00,								// Start of a quiet NaN (NANQ)
		0x7F, 0xFF, 0xFF, 0xFF,								// End of of a quiet NaN (NANQ)
		0xFF, 0xC0, 0x00, 0x00,								// Start of a quiet NaN (NANQ)
		0xFF, 0xFF, 0xFF, 0xFF,								// End of a quiet NaN (NANQ)
		0xAA, 0xAA, 0xAA, 0xAA,
		0x55, 0x55, 0x55, 0x55,
	};

	deUint8*	start		= toFill;
	size_t		sizeToRnd	= size;

	// Pattern part
	if (layer == 0 && level == 0 && size >= 2 * sizeof(pattern))
	{
		// Rotated pattern
		for (size_t i = 0; i < sizeof(pattern); i++)
			start[sizeof(pattern) - i - 1] = pattern[i];

		start		+= sizeof(pattern);
		sizeToRnd	-= sizeof(pattern);

		// Direct pattern
		deMemcpy(start, pattern, sizeof(pattern));

		start		+= sizeof(pattern);
		sizeToRnd	-= sizeof(pattern);
	}

	// Random part
	{
		DE_ASSERT(sizeToRnd % sizeof(deUint32) == 0);

		deUint32*	start32		= reinterpret_cast<deUint32*>(start);
		size_t		sizeToRnd32	= sizeToRnd / sizeof(deUint32);
		deUint32	seed		= (layer << 24) ^ (level << 16) ^ static_cast<deUint32>(format);
		Random		rnd			(seed);

		for (size_t i = 0; i < sizeToRnd32; i++)
			start32[i] = rnd.getUint32();
	}

	{
		// Remove certain values that may not be preserved based on the uncompressed view format
		if (isSnormFormat(m_parameters.formatUncompressed))
		{
			for (size_t i = 0; i < size; i += 2)
			{
				// SNORM fix: due to write operation in SNORM format
				// replaces 0x00 0x80 to 0x01 0x80
				if (toFill[i] == 0x00 && toFill[i+1] == 0x80)
					toFill[i+1] = 0x81;
			}
		}
		else if (isFloatFormat(m_parameters.formatUncompressed))
		{
			tcu::TextureFormat textureFormat = mapVkFormat(m_parameters.formatUncompressed);

			if (textureFormat.type == tcu::TextureFormat::HALF_FLOAT)
			{
				for (size_t i = 0; i < size; i += 2)
				{
					// HALF_FLOAT fix: remove INF and NaN
					if ((toFill[i+1] & 0x7C) == 0x7C)
						toFill[i+1] = 0x00;
				}
			}
			else if (textureFormat.type == tcu::TextureFormat::FLOAT)
			{
				for (size_t i = 0; i < size; i += 4)
				{
					// HALF_FLOAT fix: remove INF and NaN
					if ((toFill[i+1] & 0x7C) == 0x7C)
						toFill[i+1] = 0x00;
				}

				for (size_t i = 0; i < size; i += 4)
				{
					// FLOAT fix: remove INF, NaN, and denorm
					// Little endian fix
					if (((toFill[i+3] & 0x7F) == 0x7F && (toFill[i+2] & 0x80) == 0x80) || ((toFill[i+3] & 0x7F) == 0x00 && (toFill[i+2] & 0x80) == 0x00))
						toFill[i+3] = 0x01;
					// Big endian fix
					if (((toFill[i+0] & 0x7F) == 0x7F && (toFill[i+1] & 0x80) == 0x80) || ((toFill[i+0] & 0x7F) == 0x00 && (toFill[i+1] & 0x80) == 0x00))
						toFill[i+0] = 0x01;
				}
			}
		}
	}
}

class BasicComputeTestInstance : public BasicTranscodingTestInstance
{
public:
					BasicComputeTestInstance	(Context&							context,
												const TestParameters&				parameters);
	TestStatus		iterate						(void);
protected:
	struct ImageData
	{
		deUint32			getImagesCount		(void)									{ return static_cast<deUint32>(images.size());		}
		deUint32			getImageViewCount	(void)									{ return static_cast<deUint32>(imagesViews.size());	}
		deUint32			getImageInfoCount	(void)									{ return static_cast<deUint32>(imagesInfos.size());	}
		VkImage				getImage			(const deUint32				ndx)		{ return **images[ndx]->get();						}
		VkImageView			getImageView		(const deUint32				ndx)		{ return **imagesViews[ndx];						}
		VkImageCreateInfo	getImageInfo		(const deUint32				ndx)		{ return imagesInfos[ndx];							}
		void				addImage			(MovePtr<Image>				image)		{ images.push_back(makeVkSharedPtr(image));			}
		void				addImageView		(Move<VkImageView>			imageView)	{ imagesViews.push_back(makeVkSharedPtr(imageView));}
		void				addImageInfo		(const VkImageCreateInfo	imageInfo)	{ imagesInfos.push_back(imageInfo);					}
		void				resetViews			()										{ imagesViews.clear();								}
	private:
		vector<ImageSp>				images;
		vector<ImageViewSp>			imagesViews;
		vector<VkImageCreateInfo>	imagesInfos;
	};
	void			copyDataToImage				(const VkCommandBuffer&				cmdBuffer,
												 ImageData&							imageData,
												 const vector<UVec3>&				mipMapSizes,
												 const bool							isCompressed);
	virtual void	executeShader				(const VkCommandBuffer&				cmdBuffer,
												 const VkDescriptorSetLayout&		descriptorSetLayout,
												 const VkDescriptorPool&			descriptorPool,
												vector<ImageData>&					imageData);
	bool			copyResultAndCompare		(const VkCommandBuffer&				cmdBuffer,
												 const VkImage&						uncompressed,
												 const VkDeviceSize					offset,
												 const UVec3&						size);
	void			descriptorSetUpdate			(VkDescriptorSet					descriptorSet,
												 const VkDescriptorImageInfo*		descriptorImageInfos);
	void			createImageInfos			(ImageData&							imageData,
												 const vector<UVec3>&				mipMapSizes,
												 const bool							isCompressed);
	bool			decompressImage				(const VkCommandBuffer&				cmdBuffer,
												 vector<ImageData>&					imageData,
												 const vector<UVec3>&				mipMapSizes);
	vector<deUint8>	m_data;
};


BasicComputeTestInstance::BasicComputeTestInstance (Context& context, const TestParameters& parameters)
	:BasicTranscodingTestInstance	(context, parameters)
{
}

TestStatus BasicComputeTestInstance::iterate (void)
{
	const DeviceInterface&					vk					= m_context.getDeviceInterface();
	const VkDevice							device				= m_context.getDevice();
	const deUint32							queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	Allocator&								allocator			= m_context.getDefaultAllocator();
	const Unique<VkCommandPool>				cmdPool				(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>			cmdBuffer			(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	const UVec3								fullSize			(m_parameters.size.x(), m_parameters.size.y(), 1);
	const vector<UVec3>						mipMapSizes			= m_parameters.useMipmaps ? getMipLevelSizes (getLayerDims()) : vector<UVec3>(1, fullSize);
	vector<ImageData>						imageData			(m_parameters.imagesCount);
	const deUint32							compressedNdx		= 0u;
	const deUint32							resultImageNdx		= m_parameters.imagesCount -1u;

	for (deUint32 imageNdx = 0u; imageNdx < m_parameters.imagesCount; ++imageNdx)
	{
		const bool isCompressed = compressedNdx == imageNdx ? true : false;
		createImageInfos(imageData[imageNdx], mipMapSizes, isCompressed);
		for (deUint32 infoNdx = 0u; infoNdx < imageData[imageNdx].getImageInfoCount(); ++infoNdx)
		{
			imageData[imageNdx].addImage(MovePtr<Image>(new Image(vk, device, allocator, imageData[imageNdx].getImageInfo(infoNdx), MemoryRequirement::Any)));
			if (isCompressed)
			{
				const VkImageViewUsageCreateInfo	imageViewUsageKHR	=
				{
					VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR,				//VkStructureType		sType;
					DE_NULL,														//const void*			pNext;
					m_parameters.compressedImageUsage,								//VkImageUsageFlags		usage;
				};
				for (deUint32 mipNdx = 0u; mipNdx < mipMapSizes.size(); ++mipNdx)
				for (deUint32 layerNdx = 0u; layerNdx < getLayerCount(); ++layerNdx)
				{
					imageData[imageNdx].addImageView(makeImageView(vk, device, imageData[imageNdx].getImage(infoNdx),
														mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed,
														makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipNdx, 1u, layerNdx, 1u),
														&imageViewUsageKHR));
				}
			}
			else
			{
				imageData[imageNdx].addImageView(makeImageView(vk, device, imageData[imageNdx].getImage(infoNdx),
													mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed,
													makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)));
			}
		}
	}

	{
		size_t size = 0ull;
		for(deUint32 mipNdx = 0u; mipNdx < mipMapSizes.size(); ++mipNdx)
		{
			size += static_cast<size_t>(getCompressedImageSizeInBytes(m_parameters.formatCompressed, mipMapSizes[mipNdx]) * getLayerCount());
		}
		m_data.resize(size);
		generateData (&m_data[0], m_data.size(), m_parameters.formatCompressed);
	}

	switch(m_parameters.operation)
	{
		case OPERATION_IMAGE_LOAD:
		case OPERATION_TEXEL_FETCH:
		case OPERATION_TEXTURE:
			copyDataToImage(*cmdBuffer, imageData[compressedNdx], mipMapSizes, true);
			break;
		case OPERATION_IMAGE_STORE:
			copyDataToImage(*cmdBuffer, imageData[1], mipMapSizes, false);
			break;
		default:
			DE_ASSERT(false);
			break;
	}

	{
		Move<VkDescriptorSetLayout>	descriptorSetLayout;
		Move<VkDescriptorPool>		descriptorPool;

		DescriptorSetLayoutBuilder	descriptorSetLayoutBuilder;
		DescriptorPoolBuilder		descriptorPoolBuilder;
		for (deUint32 imageNdx = 0u; imageNdx < m_parameters.imagesCount; ++imageNdx)
		{
			switch(m_parameters.operation)
			{
				case OPERATION_IMAGE_LOAD:
				case OPERATION_IMAGE_STORE:
					descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT);
					descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, imageData[0].getImageViewCount());
					break;
				case OPERATION_TEXEL_FETCH:
				case OPERATION_TEXTURE:
					descriptorSetLayoutBuilder.addSingleBinding((compressedNdx == imageNdx) ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT);
					descriptorPoolBuilder.addType((compressedNdx == imageNdx) ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, imageData[0].getImageViewCount());
					break;
				default:
					DE_ASSERT(false);
					break;
			}
		}
		descriptorSetLayout	= descriptorSetLayoutBuilder.build(vk, device);
		descriptorPool		= descriptorPoolBuilder.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, imageData[0].getImageViewCount());
		executeShader(*cmdBuffer, *descriptorSetLayout, *descriptorPool, imageData);

		{
			VkDeviceSize offset = 0ull;
			for (deUint32 mipNdx = 0u; mipNdx < mipMapSizes.size(); ++mipNdx)
			for (deUint32 layerNdx = 0u; layerNdx < getLayerCount(); ++layerNdx)
			{
				const deUint32	imageNdx	= layerNdx + mipNdx * getLayerCount();
				const UVec3		size		= UVec3(imageData[resultImageNdx].getImageInfo(imageNdx).extent.width,
													imageData[resultImageNdx].getImageInfo(imageNdx).extent.height,
													imageData[resultImageNdx].getImageInfo(imageNdx).extent.depth);
				if (!copyResultAndCompare(*cmdBuffer, imageData[resultImageNdx].getImage(imageNdx), offset, size))
					return TestStatus::fail("Fail");
				offset += getCompressedImageSizeInBytes(m_parameters.formatCompressed, mipMapSizes[mipNdx]);
			}
		}
	};
	if (!decompressImage(*cmdBuffer, imageData, mipMapSizes))
			return TestStatus::fail("Fail");

	if (m_bASTCErrorColourMismatch)
	{
		DE_ASSERT(m_parameters.formatIsASTC);
		return TestStatusASTCQualityWarning();
	}

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

void BasicComputeTestInstance::copyDataToImage (const VkCommandBuffer&	cmdBuffer,
												ImageData&				imageData,
												const vector<UVec3>&	mipMapSizes,
												const bool				isCompressed)
{
	const DeviceInterface&		vk			= m_context.getDeviceInterface();
	const VkDevice				device		= m_context.getDevice();
	const VkQueue				queue		= m_context.getUniversalQueue();
	Allocator&					allocator	= m_context.getDefaultAllocator();

	Buffer						imageBuffer	(vk, device, allocator,
												makeBufferCreateInfo(m_data.size(), VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
												MemoryRequirement::HostVisible);
	VkDeviceSize				offset		= 0ull;
	{
		const Allocation& alloc = imageBuffer.getAllocation();
		deMemcpy(alloc.getHostPtr(), &m_data[0], m_data.size());
		flushAlloc(vk, device, alloc);
	}

	beginCommandBuffer(vk, cmdBuffer);
	const VkImageSubresourceRange	subresourceRange		=
	{
		VK_IMAGE_ASPECT_COLOR_BIT,					//VkImageAspectFlags	aspectMask
		0u,											//deUint32				baseMipLevel
		imageData.getImageInfo(0u).mipLevels,		//deUint32				levelCount
		0u,											//deUint32				baseArrayLayer
		imageData.getImageInfo(0u).arrayLayers		//deUint32				layerCount
	};

	for (deUint32 imageNdx = 0u; imageNdx < imageData.getImagesCount(); ++imageNdx)
	{
		const VkImageMemoryBarrier		preCopyImageBarrier		= makeImageMemoryBarrier(
																	0u, VK_ACCESS_TRANSFER_WRITE_BIT,
																	VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
																	imageData.getImage(imageNdx), subresourceRange);

		const VkBufferMemoryBarrier		FlushHostCopyBarrier	= makeBufferMemoryBarrier(
																	VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
																	imageBuffer.get(), 0ull, m_data.size());

		vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
				(VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 1u, &FlushHostCopyBarrier, 1u, &preCopyImageBarrier);

		for (deUint32 mipNdx = 0u; mipNdx < imageData.getImageInfo(imageNdx).mipLevels; ++mipNdx)
		{
			const VkExtent3D				imageExtent				= isCompressed ?
																		makeExtent3D(mipMapSizes[mipNdx]) :
																		imageData.getImageInfo(imageNdx).extent;
			const VkBufferImageCopy			copyRegion				=
			{
				offset,																												//VkDeviceSize				bufferOffset;
				0u,																													//deUint32					bufferRowLength;
				0u,																													//deUint32					bufferImageHeight;
				makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, mipNdx, 0u, imageData.getImageInfo(imageNdx).arrayLayers),	//VkImageSubresourceLayers	imageSubresource;
				makeOffset3D(0, 0, 0),																								//VkOffset3D				imageOffset;
				imageExtent,																										//VkExtent3D				imageExtent;
			};

			vk.cmdCopyBufferToImage(cmdBuffer, imageBuffer.get(), imageData.getImage(imageNdx), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
			offset += getCompressedImageSizeInBytes(m_parameters.formatCompressed,
						UVec3(isCompressed ? imageExtent.width : imageExtent.width * m_blockWidth, isCompressed? imageExtent.height :imageExtent.height * m_blockHeight,imageExtent.depth)) *
						imageData.getImageInfo(imageNdx).arrayLayers;
		}
	}
	endCommandBuffer(vk, cmdBuffer);
	submitCommandsAndWait(vk, device, queue, cmdBuffer);
}

void BasicComputeTestInstance::executeShader (const VkCommandBuffer&		cmdBuffer,
											  const VkDescriptorSetLayout&	descriptorSetLayout,
											  const VkDescriptorPool&		descriptorPool,
											  vector<ImageData>&			imageData)
{
	const DeviceInterface&			vk						= m_context.getDeviceInterface();
	const VkDevice					device					= m_context.getDevice();
	const VkQueue					queue					= m_context.getUniversalQueue();
	const Unique<VkShaderModule>	shaderModule			(createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0));
	vector<SharedVkDescriptorSet>	descriptorSets			(imageData[0].getImageViewCount());
	const Unique<VkPipelineLayout>	pipelineLayout			(makePipelineLayout(vk, device, descriptorSetLayout));
	const Unique<VkPipeline>		pipeline				(makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));
	Move<VkSampler>					sampler;
	{
		const VkSamplerCreateInfo createInfo =
		{
			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		//VkStructureType		sType;
			DE_NULL,									//const void*			pNext;
			0u,											//VkSamplerCreateFlags	flags;
			VK_FILTER_NEAREST,							//VkFilter				magFilter;
			VK_FILTER_NEAREST,							//VkFilter				minFilter;
			VK_SAMPLER_MIPMAP_MODE_NEAREST,				//VkSamplerMipmapMode	mipmapMode;
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		//VkSamplerAddressMode	addressModeU;
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		//VkSamplerAddressMode	addressModeV;
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		//VkSamplerAddressMode	addressModeW;
			0.0f,										//float					mipLodBias;
			VK_FALSE,									//VkBool32				anisotropyEnable;
			1.0f,										//float					maxAnisotropy;
			VK_FALSE,									//VkBool32				compareEnable;
			VK_COMPARE_OP_EQUAL,						//VkCompareOp			compareOp;
			0.0f,										//float					minLod;
			0.0f,										//float					maxLod;
			VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,	//VkBorderColor			borderColor;
			VK_FALSE,									//VkBool32				unnormalizedCoordinates;
		};
		sampler = createSampler(vk, device, &createInfo);
	}

	vector<VkDescriptorImageInfo>	descriptorImageInfos	(descriptorSets.size() * m_parameters.imagesCount);
	for (deUint32 viewNdx = 0u; viewNdx < descriptorSets.size(); ++viewNdx)
	{
		const deUint32 descriptorNdx = viewNdx * m_parameters.imagesCount;
		for (deUint32 imageNdx = 0; imageNdx < m_parameters.imagesCount; ++imageNdx)
		{
			descriptorImageInfos[descriptorNdx+imageNdx] = makeDescriptorImageInfo(*sampler,
															imageData[imageNdx].getImageView(viewNdx), VK_IMAGE_LAYOUT_GENERAL);
		}
	}

	for (deUint32 ndx = 0u; ndx < descriptorSets.size(); ++ndx)
		descriptorSets[ndx] = makeVkSharedPtr(makeDescriptorSet(vk, device, descriptorPool, descriptorSetLayout));

	beginCommandBuffer(vk, cmdBuffer);
	{
		const VkImageSubresourceRange	compressedRange				=
		{
			VK_IMAGE_ASPECT_COLOR_BIT,					//VkImageAspectFlags	aspectMask
			0u,											//deUint32				baseMipLevel
			imageData[0].getImageInfo(0u).mipLevels,	//deUint32				levelCount
			0u,											//deUint32				baseArrayLayer
			imageData[0].getImageInfo(0u).arrayLayers	//deUint32				layerCount
		};
		const VkImageSubresourceRange	uncompressedRange			=
		{
			VK_IMAGE_ASPECT_COLOR_BIT,					//VkImageAspectFlags	aspectMask
			0u,											//deUint32				baseMipLevel
			1u,											//deUint32				levelCount
			0u,											//deUint32				baseArrayLayer
			1u											//deUint32				layerCount
		};

		vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);

		vector<VkImageMemoryBarrier>		preShaderImageBarriers;
		preShaderImageBarriers.resize(descriptorSets.size() + 1u);
		for (deUint32 imageNdx = 0u; imageNdx < imageData[1].getImagesCount(); ++imageNdx)
		{
			preShaderImageBarriers[imageNdx]= makeImageMemoryBarrier(
												VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT,
												VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
												imageData[1].getImage(imageNdx), uncompressedRange);
		}

		preShaderImageBarriers[descriptorSets.size()] = makeImageMemoryBarrier(
															VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
															VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
															imageData[0].getImage(0), compressedRange);

		vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
			(VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 0u, (const VkBufferMemoryBarrier*)DE_NULL,
			static_cast<deUint32>(preShaderImageBarriers.size()), &preShaderImageBarriers[0]);

		for (deUint32 ndx = 0u; ndx <descriptorSets.size(); ++ndx)
		{
			descriptorSetUpdate (**descriptorSets[ndx], &descriptorImageInfos[ndx* m_parameters.imagesCount]);
			vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &(**descriptorSets[ndx]), 0u, DE_NULL);
			vk.cmdDispatch(cmdBuffer,	imageData[1].getImageInfo(ndx).extent.width,
										imageData[1].getImageInfo(ndx).extent.height,
										imageData[1].getImageInfo(ndx).extent.depth);
		}
	}
	endCommandBuffer(vk, cmdBuffer);
	submitCommandsAndWait(vk, device, queue, cmdBuffer);
}

bool BasicComputeTestInstance::copyResultAndCompare (const VkCommandBuffer&	cmdBuffer,
													 const VkImage&			uncompressed,
													 const VkDeviceSize		offset,
													 const UVec3&			size)
{
	const DeviceInterface&	vk					= m_context.getDeviceInterface();
	const VkQueue			queue				= m_context.getUniversalQueue();
	const VkDevice			device				= m_context.getDevice();
	Allocator&				allocator			= m_context.getDefaultAllocator();

	VkDeviceSize			imageResultSize		= getImageSizeBytes (tcu::IVec3(size.x(), size.y(), size.z()), m_parameters.formatUncompressed);
	Buffer					imageBufferResult	(vk, device, allocator,
													makeBufferCreateInfo(imageResultSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT),
													MemoryRequirement::HostVisible);

	beginCommandBuffer(vk, cmdBuffer);
	{
		const VkImageSubresourceRange	subresourceRange	=
		{
			VK_IMAGE_ASPECT_COLOR_BIT,											//VkImageAspectFlags	aspectMask
			0u,																	//deUint32				baseMipLevel
			1u,																	//deUint32				levelCount
			0u,																	//deUint32				baseArrayLayer
			1u																	//deUint32				layerCount
		};

		const VkBufferImageCopy			copyRegion			=
		{
			0ull,																//	VkDeviceSize				bufferOffset;
			0u,																	//	deUint32					bufferRowLength;
			0u,																	//	deUint32					bufferImageHeight;
			makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),	//	VkImageSubresourceLayers	imageSubresource;
			makeOffset3D(0, 0, 0),												//	VkOffset3D					imageOffset;
			makeExtent3D(size),													//	VkExtent3D					imageExtent;
		};

		const VkImageMemoryBarrier prepareForTransferBarrier = makeImageMemoryBarrier(
																VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
																VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
																uncompressed, subresourceRange);

		const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier(
													VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
													imageBufferResult.get(), 0ull, imageResultSize);

		vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &prepareForTransferBarrier);
		vk.cmdCopyImageToBuffer(cmdBuffer, uncompressed, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, imageBufferResult.get(), 1u, &copyRegion);
		vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 1, &copyBarrier, 0u, (const VkImageMemoryBarrier*)DE_NULL);
	}
	endCommandBuffer(vk, cmdBuffer);
	submitCommandsAndWait(vk, device, queue, cmdBuffer);

	const Allocation& allocResult = imageBufferResult.getAllocation();
	invalidateAlloc(vk, device, allocResult);
	if (deMemCmp((const void *)allocResult.getHostPtr(), (const void *)&m_data[static_cast<size_t>(offset)], static_cast<size_t>(imageResultSize)) == 0ull)
		return true;
	return false;
}

void BasicComputeTestInstance::descriptorSetUpdate (VkDescriptorSet descriptorSet, const VkDescriptorImageInfo* descriptorImageInfos)
{
	const DeviceInterface&		vk		= m_context.getDeviceInterface();
	const VkDevice				device	= m_context.getDevice();
	DescriptorSetUpdateBuilder	descriptorSetUpdateBuilder;

	switch(m_parameters.operation)
	{
		case OPERATION_IMAGE_LOAD:
		case OPERATION_IMAGE_STORE:
		{
			for (deUint32 bindingNdx = 0u; bindingNdx < m_parameters.imagesCount; ++bindingNdx)
				descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(bindingNdx), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfos[bindingNdx]);

			break;
		}

		case OPERATION_TEXEL_FETCH:
		case OPERATION_TEXTURE:
		{
			for (deUint32 bindingNdx = 0u; bindingNdx < m_parameters.imagesCount; ++bindingNdx)
			{
				descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(bindingNdx),
					bindingNdx == 0u ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfos[bindingNdx]);
			}

			break;
		}

		default:
			DE_ASSERT(false);
	}
	descriptorSetUpdateBuilder.update(vk, device);
}

void BasicComputeTestInstance::createImageInfos (ImageData& imageData, const vector<UVec3>& mipMapSizes, const bool isCompressed)
{
	const VkImageType		imageType			= mapImageType(m_parameters.imageType);

	if (isCompressed)
	{
		VkFormatProperties properties;
		m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), m_parameters.formatCompressed, &properties);
		if (!(properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
			TCU_THROW(NotSupportedError, "Format storage feature not supported");

		const VkExtent3D	extentCompressed	= makeExtent3D(getLayerSize(m_parameters.imageType, m_parameters.size));
		const VkImageCreateInfo compressedInfo =
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,					// VkStructureType			sType;
			DE_NULL,												// const void*				pNext;
			VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT |
			VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR |
			VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR,					// VkImageCreateFlags		flags;
			imageType,												// VkImageType				imageType;
			m_parameters.formatCompressed,							// VkFormat					format;
			extentCompressed,										// VkExtent3D				extent;
			static_cast<deUint32>(mipMapSizes.size()),				// deUint32					mipLevels;
			getLayerCount(),										// deUint32					arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,								// VkImageTiling			tiling;
			VK_IMAGE_USAGE_SAMPLED_BIT |
			VK_IMAGE_USAGE_STORAGE_BIT |
			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
			VK_IMAGE_USAGE_TRANSFER_DST_BIT,						// VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,								// VkSharingMode			sharingMode;
			0u,														// deUint32					queueFamilyIndexCount;
			DE_NULL,												// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout			initialLayout;
		};
		imageData.addImageInfo(compressedInfo);
	}
	else
	{
		UVec3 size = m_parameters.size;
		if (m_parameters.imageType == IMAGE_TYPE_1D) {
			size.y() = 1;
		}
		size.z() = 1;
		const VkExtent3D originalResolutionInBlocks = makeExtent3D(getCompressedImageResolutionInBlocks(m_parameters.formatCompressed, size));

		for (size_t mipNdx = 0ull; mipNdx < mipMapSizes.size(); ++mipNdx)
		for (size_t layerNdx = 0ull; layerNdx < getLayerCount(); ++layerNdx)
		{
			const VkExtent3D		extentUncompressed	= m_parameters.useMipmaps ?
															makeExtent3D(getCompressedImageResolutionInBlocks(m_parameters.formatCompressed, mipMapSizes[mipNdx])) :
															originalResolutionInBlocks;
			const VkImageCreateInfo	uncompressedInfo	=
			{
				VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,				// VkStructureType			sType;
				DE_NULL,											// const void*				pNext;
				0u,													// VkImageCreateFlags		flags;
				imageType,											// VkImageType				imageType;
				m_parameters.formatUncompressed,					// VkFormat					format;
				extentUncompressed,									// VkExtent3D				extent;
				1u,													// deUint32					mipLevels;
				1u,													// deUint32					arrayLayers;
				VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits	samples;
				VK_IMAGE_TILING_OPTIMAL,							// VkImageTiling			tiling;
				m_parameters.uncompressedImageUsage |
				VK_IMAGE_USAGE_SAMPLED_BIT,							// VkImageUsageFlags		usage;
				VK_SHARING_MODE_EXCLUSIVE,							// VkSharingMode			sharingMode;
				0u,													// deUint32					queueFamilyIndexCount;
				DE_NULL,											// const deUint32*			pQueueFamilyIndices;
				VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			initialLayout;
			};
			imageData.addImageInfo(uncompressedInfo);
		}
	}
}

bool BasicComputeTestInstance::decompressImage (const VkCommandBuffer&	cmdBuffer,
												 vector<ImageData>&		imageData,
												 const vector<UVec3>&	mipMapSizes)
{
	const DeviceInterface&			vk						= m_context.getDeviceInterface();
	const VkDevice					device					= m_context.getDevice();
	const VkQueue					queue					= m_context.getUniversalQueue();
	Allocator&						allocator				= m_context.getDefaultAllocator();
	const Unique<VkShaderModule>	shaderModule			(createShaderModule(vk, device, m_context.getBinaryCollection().get("decompress"), 0));
	const VkImage&					compressed				= imageData[0].getImage(0);
	const VkImageType				imageType				= mapImageType(m_parameters.imageType);

	for (deUint32 ndx = 0u; ndx < imageData.size(); ndx++)
		imageData[ndx].resetViews();

	for (deUint32 mipNdx = 0u; mipNdx < mipMapSizes.size(); ++mipNdx)
	for (deUint32 layerNdx = 0u; layerNdx < getLayerCount(); ++layerNdx)
	{
		const bool						layoutShaderReadOnly	= (layerNdx % 2u) == 1;
		const deUint32					imageNdx				= layerNdx + mipNdx * getLayerCount();
		const VkExtent3D				extentCompressed		= imageType == VK_IMAGE_TYPE_1D ? makeExtent3D(mipMapSizes[mipNdx].x(), 1, mipMapSizes[mipNdx].z()) : makeExtent3D(mipMapSizes[mipNdx]);
		const VkImage&					uncompressed			= imageData[m_parameters.imagesCount -1].getImage(imageNdx);
		const VkExtent3D				extentUncompressed		= imageData[m_parameters.imagesCount -1].getImageInfo(imageNdx).extent;
		const VkDeviceSize				bufferSizeComp			= getCompressedImageSizeInBytes(m_parameters.formatCompressed, mipMapSizes[mipNdx]);

		VkFormatProperties properties;
		m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), m_parameters.formatForVerify, &properties);
		if (!(properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
			TCU_THROW(NotSupportedError, "Format storage feature not supported");

		const VkImageCreateInfo			decompressedImageInfo	=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,								// VkStructureType			sType;
			DE_NULL,															// const void*				pNext;
			0u,																	// VkImageCreateFlags		flags;
			imageType,															// VkImageType				imageType;
			m_parameters.formatForVerify,										// VkFormat					format;
			extentCompressed,													// VkExtent3D				extent;
			1u,																	// deUint32					mipLevels;
			1u,																	// deUint32					arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,												// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,											// VkImageTiling			tiling;
			VK_IMAGE_USAGE_SAMPLED_BIT |
			VK_IMAGE_USAGE_STORAGE_BIT |
			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
			VK_IMAGE_USAGE_TRANSFER_DST_BIT,									// VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,											// VkSharingMode			sharingMode;
			0u,																	// deUint32					queueFamilyIndexCount;
			DE_NULL,															// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,											// VkImageLayout			initialLayout;
		};

		const VkImageCreateInfo			compressedImageInfo		=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,								// VkStructureType			sType;
			DE_NULL,															// const void*				pNext;
			0u,																	// VkImageCreateFlags		flags;
			imageType,															// VkImageType				imageType;
			m_parameters.formatCompressed,										// VkFormat					format;
			extentCompressed,													// VkExtent3D				extent;
			1u,																	// deUint32					mipLevels;
			1u,																	// deUint32					arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,												// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,											// VkImageTiling			tiling;
			VK_IMAGE_USAGE_SAMPLED_BIT |
			VK_IMAGE_USAGE_TRANSFER_DST_BIT,									// VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,											// VkSharingMode			sharingMode;
			0u,																	// deUint32					queueFamilyIndexCount;
			DE_NULL,															// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,											// VkImageLayout			initialLayout;
		};
		const VkImageUsageFlags				compressedViewUsageFlags	= VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
		const VkImageViewUsageCreateInfo	compressedViewUsageCI		=
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR,					//VkStructureType		sType;
			DE_NULL,															//const void*			pNext;
			compressedViewUsageFlags,											//VkImageUsageFlags		usage;
		};
		const VkImageViewType			imageViewType			(mapImageViewType(m_parameters.imageType));
		Image							resultImage				(vk, device, allocator, decompressedImageInfo, MemoryRequirement::Any);
		Image							referenceImage			(vk, device, allocator, decompressedImageInfo, MemoryRequirement::Any);
		Image							uncompressedImage		(vk, device, allocator, compressedImageInfo, MemoryRequirement::Any);
		Move<VkImageView>				resultView				= makeImageView(vk, device, resultImage.get(), imageViewType, decompressedImageInfo.format,
																	makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, decompressedImageInfo.extent.depth, 0u, decompressedImageInfo.arrayLayers));
		Move<VkImageView>				referenceView			= makeImageView(vk, device, referenceImage.get(), imageViewType, decompressedImageInfo.format,
																	makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, decompressedImageInfo.extent.depth, 0u, decompressedImageInfo.arrayLayers));
		Move<VkImageView>				uncompressedView		= makeImageView(vk, device, uncompressedImage.get(), imageViewType, m_parameters.formatCompressed,
																	makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, compressedImageInfo.extent.depth, 0u, compressedImageInfo.arrayLayers));
		Move<VkImageView>				compressedView			= makeImageView(vk, device, compressed, imageViewType, m_parameters.formatCompressed,
																	makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipNdx, 1u, layerNdx, 1u), &compressedViewUsageCI);
		Move<VkDescriptorSetLayout>		descriptorSetLayout		= DescriptorSetLayoutBuilder()
																	.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT)
																	.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT)
																	.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
																	.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
																	.build(vk, device);
		Move<VkDescriptorPool>			descriptorPool			= DescriptorPoolBuilder()
																	.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, decompressedImageInfo.arrayLayers)
																	.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, decompressedImageInfo.arrayLayers)
																	.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, decompressedImageInfo.arrayLayers)
																	.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, decompressedImageInfo.arrayLayers)
																	.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, decompressedImageInfo.arrayLayers);

		Move<VkDescriptorSet>			descriptorSet			= makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
		const Unique<VkPipelineLayout>	pipelineLayout			(makePipelineLayout(vk, device, *descriptorSetLayout));
		const Unique<VkPipeline>		pipeline				(makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));
		const VkDeviceSize				bufferSize				= getImageSizeBytes(IVec3((int)extentCompressed.width, (int)extentCompressed.height, (int)extentCompressed.depth), m_parameters.formatForVerify);
		Buffer							resultBuffer			(vk, device, allocator,
																	makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible);
		Buffer							referenceBuffer			(vk, device, allocator,
																	makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible);
		Buffer							transferBuffer			(vk, device, allocator,
																	makeBufferCreateInfo(bufferSizeComp, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible);
		Move<VkSampler>					sampler;
		{
			const VkSamplerCreateInfo createInfo	=
			{
				VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,							//VkStructureType		sType;
				DE_NULL,														//const void*			pNext;
				0u,																//VkSamplerCreateFlags	flags;
				VK_FILTER_NEAREST,												//VkFilter				magFilter;
				VK_FILTER_NEAREST,												//VkFilter				minFilter;
				VK_SAMPLER_MIPMAP_MODE_NEAREST,									//VkSamplerMipmapMode	mipmapMode;
				VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,							//VkSamplerAddressMode	addressModeU;
				VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,							//VkSamplerAddressMode	addressModeV;
				VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,							//VkSamplerAddressMode	addressModeW;
				0.0f,															//float					mipLodBias;
				VK_FALSE,														//VkBool32				anisotropyEnable;
				1.0f,															//float					maxAnisotropy;
				VK_FALSE,														//VkBool32				compareEnable;
				VK_COMPARE_OP_EQUAL,											//VkCompareOp			compareOp;
				0.0f,															//float					minLod;
				1.0f,															//float					maxLod;
				VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,						//VkBorderColor			borderColor;
				VK_FALSE,														//VkBool32				unnormalizedCoordinates;
			};
			sampler = createSampler(vk, device, &createInfo);
		}

		VkDescriptorImageInfo			descriptorImageInfos[]	=
		{
			makeDescriptorImageInfo(*sampler,	*uncompressedView,	layoutShaderReadOnly ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL),
			makeDescriptorImageInfo(*sampler,	*compressedView,	layoutShaderReadOnly ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL),
			makeDescriptorImageInfo(DE_NULL,	*resultView,		VK_IMAGE_LAYOUT_GENERAL),
			makeDescriptorImageInfo(DE_NULL,	*referenceView,		VK_IMAGE_LAYOUT_GENERAL)
		};
		DescriptorSetUpdateBuilder()
			.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfos[0])
			.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfos[1])
			.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfos[2])
			.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(3u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfos[3])
			.update(vk, device);


		beginCommandBuffer(vk, cmdBuffer);
		{
			const VkImageSubresourceRange	subresourceRange		=
			{
				VK_IMAGE_ASPECT_COLOR_BIT,											//VkImageAspectFlags			aspectMask
				0u,																	//deUint32						baseMipLevel
				1u,																	//deUint32						levelCount
				0u,																	//deUint32						baseArrayLayer
				1u																	//deUint32						layerCount
			};

			const VkImageSubresourceRange	subresourceRangeComp	=
			{
				VK_IMAGE_ASPECT_COLOR_BIT,											//VkImageAspectFlags			aspectMask
				mipNdx,																//deUint32						baseMipLevel
				1u,																	//deUint32						levelCount
				layerNdx,															//deUint32						baseArrayLayer
				1u																	//deUint32						layerCount
			};

			const VkBufferImageCopy			copyRegion				=
			{
				0ull,																//	VkDeviceSize				bufferOffset;
				0u,																	//	deUint32					bufferRowLength;
				0u,																	//	deUint32					bufferImageHeight;
				makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),	//	VkImageSubresourceLayers	imageSubresource;
				makeOffset3D(0, 0, 0),												//	VkOffset3D					imageOffset;
				decompressedImageInfo.extent,										//	VkExtent3D					imageExtent;
			};

			const VkBufferImageCopy			compressedCopyRegion	=
			{
				0ull,																//	VkDeviceSize				bufferOffset;
				0u,																	//	deUint32					bufferRowLength;
				0u,																	//	deUint32					bufferImageHeight;
				makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),	//	VkImageSubresourceLayers	imageSubresource;
				makeOffset3D(0, 0, 0),												//	VkOffset3D					imageOffset;
				extentUncompressed,													//	VkExtent3D					imageExtent;
			};

			{

				const VkBufferMemoryBarrier		preCopyBufferBarriers	= makeBufferMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
																			transferBuffer.get(), 0ull, bufferSizeComp);

				vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
					(VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &preCopyBufferBarriers, 0u, (const VkImageMemoryBarrier*)DE_NULL);
			}

			vk.cmdCopyImageToBuffer(cmdBuffer, uncompressed, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, transferBuffer.get(), 1u, &compressedCopyRegion);

			{
				const VkBufferMemoryBarrier		postCopyBufferBarriers	= makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
																			transferBuffer.get(), 0ull, bufferSizeComp);

				const VkImageMemoryBarrier		preCopyImageBarriers	= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
																			VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, uncompressedImage.get(), subresourceRange);

				vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
					(VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 1u, &postCopyBufferBarriers, 1u, &preCopyImageBarriers);
			}

			vk.cmdCopyBufferToImage(cmdBuffer, transferBuffer.get(), uncompressedImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);

			vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
			vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);

			{
				const VkImageMemoryBarrier		preShaderImageBarriers[]	=
				{

					makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
						VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, layoutShaderReadOnly ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL,
						uncompressedImage.get(), subresourceRange),

					makeImageMemoryBarrier(0, VK_ACCESS_SHADER_READ_BIT,
						VK_IMAGE_LAYOUT_GENERAL, layoutShaderReadOnly ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL,
						compressed, subresourceRangeComp),

					makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_WRITE_BIT,
						VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
						resultImage.get(), subresourceRange),

					makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_WRITE_BIT,
						VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
						referenceImage.get(), subresourceRange)
				};

				vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
					(VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, (const VkBufferMemoryBarrier*)DE_NULL,
					DE_LENGTH_OF_ARRAY(preShaderImageBarriers), preShaderImageBarriers);
			}

			vk.cmdDispatch(cmdBuffer, extentCompressed.width, extentCompressed.height, extentCompressed.depth);

			{
				const VkImageMemoryBarrier		postShaderImageBarriers[]	=
				{
					makeImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
					VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
					resultImage.get(), subresourceRange),

					makeImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
						VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
						referenceImage.get(), subresourceRange)
				};

				vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
					(VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 0u, (const VkBufferMemoryBarrier*)DE_NULL,
					DE_LENGTH_OF_ARRAY(postShaderImageBarriers), postShaderImageBarriers);
			}

			vk.cmdCopyImageToBuffer(cmdBuffer, resultImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, resultBuffer.get(), 1u, &copyRegion);
			vk.cmdCopyImageToBuffer(cmdBuffer, referenceImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, referenceBuffer.get(), 1u, &copyRegion);

			{
				const VkBufferMemoryBarrier		postCopyBufferBarrier[]		=
				{
					makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
						resultBuffer.get(), 0ull, bufferSize),

					makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
						referenceBuffer.get(), 0ull, bufferSize),
				};

				vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
					(VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(postCopyBufferBarrier), postCopyBufferBarrier,
					0u, (const VkImageMemoryBarrier*)DE_NULL);
			}
		}
		endCommandBuffer(vk, cmdBuffer);
		submitCommandsAndWait(vk, device, queue, cmdBuffer);

		const Allocation&		resultAlloc		= resultBuffer.getAllocation();
		const Allocation&		referenceAlloc	= referenceBuffer.getAllocation();
		invalidateAlloc(vk, device, resultAlloc);
		invalidateAlloc(vk, device, referenceAlloc);

		BinaryCompareMode compareMode =
			(m_parameters.formatIsASTC)
				?(COMPARE_MODE_ALLOW_ASTC_ERROR_COLOUR_WARNING)
				:(COMPARE_MODE_NORMAL);

		BinaryCompareResult res = BinaryCompare(referenceAlloc.getHostPtr(),
												resultAlloc.getHostPtr(),
												(size_t)bufferSize,
												m_parameters.formatForVerify,
												compareMode);

		if (res == COMPARE_RESULT_FAILED)
		{
			ConstPixelBufferAccess	resultPixels		(mapVkFormat(decompressedImageInfo.format), decompressedImageInfo.extent.width, decompressedImageInfo.extent.height, decompressedImageInfo.extent.depth, resultAlloc.getHostPtr());
			ConstPixelBufferAccess	referencePixels		(mapVkFormat(decompressedImageInfo.format), decompressedImageInfo.extent.width, decompressedImageInfo.extent.height, decompressedImageInfo.extent.depth, referenceAlloc.getHostPtr());

			if(!fuzzyCompare(m_context.getTestContext().getLog(), "Image Comparison", "Image Comparison", resultPixels, referencePixels, 0.001f, tcu::COMPARE_LOG_EVERYTHING))
				return false;
		}
		else if (res == COMPARE_RESULT_ASTC_QUALITY_WARNING)
		{
			m_bASTCErrorColourMismatch = true;
		}
	}

	return true;
}

class ImageStoreComputeTestInstance : public BasicComputeTestInstance
{
public:
					ImageStoreComputeTestInstance	(Context&							context,
													 const TestParameters&				parameters);
protected:
	virtual void	executeShader					(const VkCommandBuffer&				cmdBuffer,
													 const VkDescriptorSetLayout&		descriptorSetLayout,
													 const VkDescriptorPool&			descriptorPool,
													 vector<ImageData>&					imageData);
private:
};

ImageStoreComputeTestInstance::ImageStoreComputeTestInstance (Context& context, const TestParameters& parameters)
	:BasicComputeTestInstance	(context, parameters)
{
}

void ImageStoreComputeTestInstance::executeShader (const VkCommandBuffer&		cmdBuffer,
												   const VkDescriptorSetLayout&	descriptorSetLayout,
												   const VkDescriptorPool&		descriptorPool,
												   vector<ImageData>&			imageData)
{
	const DeviceInterface&			vk						= m_context.getDeviceInterface();
	const VkDevice					device					= m_context.getDevice();
	const VkQueue					queue					= m_context.getUniversalQueue();
	const Unique<VkShaderModule>	shaderModule			(createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0));
	vector<SharedVkDescriptorSet>	descriptorSets			(imageData[0].getImageViewCount());
	const Unique<VkPipelineLayout>	pipelineLayout			(makePipelineLayout(vk, device, descriptorSetLayout));
	const Unique<VkPipeline>		pipeline				(makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));
	Move<VkSampler>					sampler;
	{
		const VkSamplerCreateInfo createInfo =
		{
			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		//VkStructureType		sType;
			DE_NULL,									//const void*			pNext;
			0u,											//VkSamplerCreateFlags	flags;
			VK_FILTER_NEAREST,							//VkFilter				magFilter;
			VK_FILTER_NEAREST,							//VkFilter				minFilter;
			VK_SAMPLER_MIPMAP_MODE_NEAREST,				//VkSamplerMipmapMode	mipmapMode;
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		//VkSamplerAddressMode	addressModeU;
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		//VkSamplerAddressMode	addressModeV;
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		//VkSamplerAddressMode	addressModeW;
			0.0f,										//float					mipLodBias;
			VK_FALSE,									//VkBool32				anisotropyEnable;
			1.0f,										//float					maxAnisotropy;
			VK_FALSE,									//VkBool32				compareEnable;
			VK_COMPARE_OP_EQUAL,						//VkCompareOp			compareOp;
			0.0f,										//float					minLod;
			0.0f,										//float					maxLod;
			VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,	//VkBorderColor			borderColor;
			VK_TRUE,									//VkBool32				unnormalizedCoordinates;
		};
		sampler = createSampler(vk, device, &createInfo);
	}

	vector<VkDescriptorImageInfo>	descriptorImageInfos	(descriptorSets.size() * m_parameters.imagesCount);
	for (deUint32 viewNdx = 0u; viewNdx < descriptorSets.size(); ++viewNdx)
	{
		const deUint32 descriptorNdx = viewNdx * m_parameters.imagesCount;
		for (deUint32 imageNdx = 0u; imageNdx < m_parameters.imagesCount; ++imageNdx)
		{
			descriptorImageInfos[descriptorNdx+imageNdx] = makeDescriptorImageInfo(*sampler,
															imageData[imageNdx].getImageView(viewNdx), VK_IMAGE_LAYOUT_GENERAL);
		}
	}

	for (deUint32 ndx = 0u; ndx < descriptorSets.size(); ++ndx)
		descriptorSets[ndx] = makeVkSharedPtr(makeDescriptorSet(vk, device, descriptorPool, descriptorSetLayout));

	beginCommandBuffer(vk, cmdBuffer);
	{
		const VkImageSubresourceRange	compressedRange				=
		{
			VK_IMAGE_ASPECT_COLOR_BIT,					//VkImageAspectFlags	aspectMask
			0u,											//deUint32				baseMipLevel
			imageData[0].getImageInfo(0).mipLevels,		//deUint32				levelCount
			0u,											//deUint32				baseArrayLayer
			imageData[0].getImageInfo(0).arrayLayers	//deUint32				layerCount
		};

		const VkImageSubresourceRange	uncompressedRange			=
		{
			VK_IMAGE_ASPECT_COLOR_BIT,					//VkImageAspectFlags	aspectMask
			0u,											//deUint32				baseMipLevel
			1u,											//deUint32				levelCount
			0u,											//deUint32				baseArrayLayer
			1u											//deUint32				layerCount
		};

		vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);

		vector<VkImageMemoryBarrier>		preShaderImageBarriers	(descriptorSets.size() * 2u + 1u);
		for (deUint32 imageNdx = 0u; imageNdx < imageData[1].getImagesCount(); ++imageNdx)
		{
			preShaderImageBarriers[imageNdx]									= makeImageMemoryBarrier(
																					VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT,
																					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
																					imageData[1].getImage(imageNdx), uncompressedRange);

			preShaderImageBarriers[imageNdx + imageData[1].getImagesCount()]	= makeImageMemoryBarrier(
																					VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT,
																					VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
																					imageData[2].getImage(imageNdx), uncompressedRange);
		}

		preShaderImageBarriers[preShaderImageBarriers.size()-1] = makeImageMemoryBarrier(
																	VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
																	VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
																	imageData[0].getImage(0u), compressedRange);

		vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
			(VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 0u, (const VkBufferMemoryBarrier*)DE_NULL,
			static_cast<deUint32>(preShaderImageBarriers.size()), &preShaderImageBarriers[0]);

		for (deUint32 ndx = 0u; ndx <descriptorSets.size(); ++ndx)
		{
			descriptorSetUpdate (**descriptorSets[ndx], &descriptorImageInfos[ndx* m_parameters.imagesCount]);
			vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &(**descriptorSets[ndx]), 0u, DE_NULL);
			vk.cmdDispatch(cmdBuffer,	imageData[1].getImageInfo(ndx).extent.width,
										imageData[1].getImageInfo(ndx).extent.height,
										imageData[1].getImageInfo(ndx).extent.depth);
		}
	}
	endCommandBuffer(vk, cmdBuffer);
	submitCommandsAndWait(vk, device, queue, cmdBuffer);
}

class GraphicsAttachmentsTestInstance : public BasicTranscodingTestInstance
{
public:
										GraphicsAttachmentsTestInstance	(Context& context, const TestParameters& parameters);
	virtual TestStatus					iterate							(void);

protected:
	virtual bool						isWriteToCompressedOperation	();
	VkImageCreateInfo					makeCreateImageInfo				(const VkFormat					format,
																		 const ImageType				type,
																		 const UVec3&					size,
																		 const VkImageUsageFlags		usageFlags,
																		 const VkImageCreateFlags*		createFlags,
																		 const deUint32					levels,
																		 const deUint32					layers);
	VkDeviceSize						getCompressedImageData			(const VkFormat					format,
																		 const UVec3&					size,
																		 std::vector<deUint8>&			data,
																		 const deUint32					layer,
																		 const deUint32					level);
	VkDeviceSize						getUncompressedImageData		(const VkFormat					format,
																		 const UVec3&					size,
																		 std::vector<deUint8>&			data,
																		 const deUint32					layer,
																		 const deUint32					level);
	virtual void						prepareData						();
	virtual void						prepareVertexBuffer				();
	virtual void						transcodeRead					();
	virtual void						transcodeWrite					();
	bool								verifyDecompression				(const std::vector<deUint8>&	refCompressedData,
																		 const de::MovePtr<Image>&		resCompressedImage,
																		 const deUint32					layer,
																		 const deUint32					level,
																		 const UVec3&					mipmapDims);

	typedef std::vector<deUint8>		RawDataVector;
	typedef SharedPtr<RawDataVector>	RawDataPtr;
	typedef std::vector<RawDataPtr>		LevelData;
	typedef std::vector<LevelData>		FullImageData;

	FullImageData						m_srcData;
	FullImageData						m_dstData;

	typedef SharedPtr<Image>			ImagePtr;
	typedef std::vector<ImagePtr>		LevelImages;
	typedef std::vector<LevelImages>	ImagesArray;

	ImagesArray							m_uncompressedImages;
	MovePtr<Image>						m_compressedImage;

	VkImageViewUsageCreateInfo			m_imageViewUsageKHR;
	VkImageViewUsageCreateInfo*			m_srcImageViewUsageKHR;
	VkImageViewUsageCreateInfo*			m_dstImageViewUsageKHR;
	std::vector<tcu::UVec3>				m_compressedImageResVec;
	std::vector<tcu::UVec3>				m_uncompressedImageResVec;
	VkFormat							m_srcFormat;
	VkFormat							m_dstFormat;
	VkImageUsageFlags					m_srcImageUsageFlags;
	VkImageUsageFlags					m_dstImageUsageFlags;
	std::vector<tcu::UVec3>				m_srcImageResolutions;
	std::vector<tcu::UVec3>				m_dstImageResolutions;

	MovePtr<Buffer>						m_vertexBuffer;
	deUint32							m_vertexCount;
	VkDeviceSize						m_vertexBufferOffset;
};

GraphicsAttachmentsTestInstance::GraphicsAttachmentsTestInstance (Context& context, const TestParameters& parameters)
	: BasicTranscodingTestInstance(context, parameters)
	, m_srcData()
	, m_dstData()
	, m_uncompressedImages()
	, m_compressedImage()
	, m_imageViewUsageKHR()
	, m_srcImageViewUsageKHR()
	, m_dstImageViewUsageKHR()
	, m_compressedImageResVec()
	, m_uncompressedImageResVec()
	, m_srcFormat()
	, m_dstFormat()
	, m_srcImageUsageFlags()
	, m_dstImageUsageFlags()
	, m_srcImageResolutions()
	, m_dstImageResolutions()
	, m_vertexBuffer()
	, m_vertexCount(0u)
	, m_vertexBufferOffset(0ull)
{
}

TestStatus GraphicsAttachmentsTestInstance::iterate (void)
{
	prepareData();
	prepareVertexBuffer();

	for (deUint32 levelNdx = 0; levelNdx < getLevelCount(); ++levelNdx)
		for (deUint32 layerNdx = 0; layerNdx < getLayerCount(); ++layerNdx)
			DE_ASSERT(m_srcData[levelNdx][layerNdx]->size() == m_dstData[levelNdx][layerNdx]->size());

	if (isWriteToCompressedOperation())
		transcodeWrite();
	else
		transcodeRead();

	for (deUint32 levelNdx = 0; levelNdx < getLevelCount(); ++levelNdx)
		for (deUint32 layerNdx = 0; layerNdx < getLayerCount(); ++layerNdx)
			if (isWriteToCompressedOperation())
			{
				if (!verifyDecompression(*m_srcData[levelNdx][layerNdx], m_compressedImage, levelNdx, layerNdx, m_compressedImageResVec[levelNdx]))
					return TestStatus::fail("Images difference detected");
			}
			else
			{
				if (!verifyDecompression(*m_dstData[levelNdx][layerNdx], m_compressedImage, levelNdx, layerNdx, m_compressedImageResVec[levelNdx]))
					return TestStatus::fail("Images difference detected");
			}

	if (m_bASTCErrorColourMismatch)
	{
		DE_ASSERT(m_parameters.formatIsASTC);
		return TestStatusASTCQualityWarning();
	}

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

void GraphicsAttachmentsTestInstance::prepareData ()
{
	VkImageViewUsageCreateInfo*	imageViewUsageKHRNull	= (VkImageViewUsageCreateInfo*)DE_NULL;

	m_imageViewUsageKHR			= makeImageViewUsageCreateInfo(m_parameters.compressedImageViewUsage);

	m_srcImageViewUsageKHR		= isWriteToCompressedOperation() ? imageViewUsageKHRNull : &m_imageViewUsageKHR;
	m_dstImageViewUsageKHR		= isWriteToCompressedOperation() ? &m_imageViewUsageKHR : imageViewUsageKHRNull;

	m_srcFormat					= isWriteToCompressedOperation() ? m_parameters.formatUncompressed : m_parameters.formatCompressed;
	m_dstFormat					= isWriteToCompressedOperation() ? m_parameters.formatCompressed : m_parameters.formatUncompressed;

	m_srcImageUsageFlags		= isWriteToCompressedOperation() ? m_parameters.uncompressedImageUsage : m_parameters.compressedImageUsage;
	m_dstImageUsageFlags		= isWriteToCompressedOperation() ? m_parameters.compressedImageUsage : m_parameters.uncompressedImageUsage;

	m_compressedImageResVec		= getMipLevelSizes(getLayerDims());
	m_uncompressedImageResVec	= getCompressedMipLevelSizes(m_parameters.formatCompressed, m_compressedImageResVec);

	m_srcImageResolutions		= isWriteToCompressedOperation() ? m_uncompressedImageResVec : m_compressedImageResVec;
	m_dstImageResolutions		= isWriteToCompressedOperation() ? m_compressedImageResVec : m_uncompressedImageResVec;

	m_srcData.resize(getLevelCount());
	m_dstData.resize(getLevelCount());
	m_uncompressedImages.resize(getLevelCount());

	for (deUint32 levelNdx = 0; levelNdx < getLevelCount(); ++levelNdx)
	{
		m_srcData[levelNdx].resize(getLayerCount());
		m_dstData[levelNdx].resize(getLayerCount());
		m_uncompressedImages[levelNdx].resize(getLayerCount());

		for (deUint32 layerNdx = 0; layerNdx < getLayerCount(); ++layerNdx)
		{
			m_srcData[levelNdx][layerNdx] = SharedPtr<RawDataVector>(new RawDataVector);
			m_dstData[levelNdx][layerNdx] = SharedPtr<RawDataVector>(new RawDataVector);

			if (isWriteToCompressedOperation())
			{
				getUncompressedImageData(m_srcFormat, m_srcImageResolutions[levelNdx], *m_srcData[levelNdx][layerNdx], layerNdx, levelNdx);

				m_dstData[levelNdx][layerNdx]->resize((size_t)getCompressedImageSizeInBytes(m_dstFormat, m_dstImageResolutions[levelNdx]));
			}
			else
			{
				getCompressedImageData(m_srcFormat, m_srcImageResolutions[levelNdx], *m_srcData[levelNdx][layerNdx], layerNdx, levelNdx);

				m_dstData[levelNdx][layerNdx]->resize((size_t)getUncompressedImageSizeInBytes(m_dstFormat, m_dstImageResolutions[levelNdx]));
			}

			DE_ASSERT(m_srcData[levelNdx][layerNdx]->size() == m_dstData[levelNdx][layerNdx]->size());
		}
	}
}

void GraphicsAttachmentsTestInstance::prepareVertexBuffer ()
{
	const DeviceInterface&			vk						= m_context.getDeviceInterface();
	const VkDevice					device					= m_context.getDevice();
	Allocator&						allocator				= m_context.getDefaultAllocator();

	const std::vector<tcu::Vec4>	vertexArray				= createFullscreenQuad();
	const size_t					vertexBufferSizeInBytes	= vertexArray.size() * sizeof(vertexArray[0]);

	m_vertexCount	= static_cast<deUint32>(vertexArray.size());
	m_vertexBuffer	= MovePtr<Buffer>(new Buffer(vk, device, allocator, makeBufferCreateInfo(vertexBufferSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));

	// Upload vertex data
	const Allocation&	vertexBufferAlloc	= m_vertexBuffer->getAllocation();
	deMemcpy(vertexBufferAlloc.getHostPtr(), &vertexArray[0], vertexBufferSizeInBytes);
	flushAlloc(vk, device, vertexBufferAlloc);
}

void GraphicsAttachmentsTestInstance::transcodeRead ()
{
	const DeviceInterface&				vk						= m_context.getDeviceInterface();
	const VkDevice						device					= m_context.getDevice();
	const deUint32						queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	const VkQueue						queue					= m_context.getUniversalQueue();
	Allocator&							allocator				= m_context.getDefaultAllocator();

	const VkImageCreateFlags*			imgCreateFlagsOverride	= DE_NULL;

	const VkImageCreateInfo				srcImageCreateInfo		= makeCreateImageInfo(m_srcFormat, m_parameters.imageType, m_srcImageResolutions[0], m_srcImageUsageFlags, imgCreateFlagsOverride, getLevelCount(), getLayerCount());
	MovePtr<Image>						srcImage				(new Image(vk, device, allocator, srcImageCreateInfo, MemoryRequirement::Any));

	const Unique<VkShaderModule>		vertShaderModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
	const Unique<VkShaderModule>		fragShaderModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));

	const Unique<VkRenderPass>			renderPass				(vkt::image::makeRenderPass(vk, device, m_parameters.formatUncompressed, m_parameters.formatUncompressed));

	const Move<VkDescriptorSetLayout>	descriptorSetLayout		(DescriptorSetLayoutBuilder()
																	.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
																	.build(vk, device));
	const Move<VkDescriptorPool>		descriptorPool			(DescriptorPoolBuilder()
																	.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
																	.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
	const Move<VkDescriptorSet>			descriptorSet			(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));

	const VkExtent2D					renderSizeDummy			(makeExtent2D(1u, 1u));
	const Unique<VkPipelineLayout>		pipelineLayout			(makePipelineLayout(vk, device, *descriptorSetLayout));
	const Unique<VkPipeline>			pipeline				(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule, *fragShaderModule, renderSizeDummy, 1u, true));

	const Unique<VkCommandPool>			cmdPool					(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>		cmdBuffer				(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	for (deUint32 levelNdx = 0; levelNdx < getLevelCount(); ++levelNdx)
	{
		const UVec3&				uncompressedImageRes	= m_uncompressedImageResVec[levelNdx];
		const UVec3&				srcImageResolution		= m_srcImageResolutions[levelNdx];
		const UVec3&				dstImageResolution		= m_dstImageResolutions[levelNdx];
		const size_t				srcImageSizeInBytes		= m_srcData[levelNdx][0]->size();
		const size_t				dstImageSizeInBytes		= m_dstData[levelNdx][0]->size();
		const UVec3					srcImageResBlocked		= getCompressedImageResolutionBlockCeil(m_parameters.formatCompressed, srcImageResolution);

		const VkImageCreateInfo		dstImageCreateInfo		= makeCreateImageInfo(m_dstFormat, m_parameters.imageType, dstImageResolution, m_dstImageUsageFlags, imgCreateFlagsOverride, SINGLE_LEVEL, SINGLE_LAYER);

		const VkBufferCreateInfo	srcImageBufferInfo		= makeBufferCreateInfo(srcImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
		const MovePtr<Buffer>		srcImageBuffer			= MovePtr<Buffer>(new Buffer(vk, device, allocator, srcImageBufferInfo, MemoryRequirement::HostVisible));

		const VkBufferCreateInfo	dstImageBufferInfo		= makeBufferCreateInfo(dstImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
		MovePtr<Buffer>				dstImageBuffer			= MovePtr<Buffer>(new Buffer(vk, device, allocator, dstImageBufferInfo, MemoryRequirement::HostVisible));

		const VkExtent2D			renderSize				(makeExtent2D(uncompressedImageRes.x(), uncompressedImageRes.y()));
		const VkViewport			viewport				= makeViewport(renderSize);
		const VkRect2D				scissor					= makeRect2D(renderSize);

		for (deUint32 layerNdx = 0; layerNdx < getLayerCount(); ++layerNdx)
		{
			const VkImageSubresourceRange	srcSubresourceRange		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, levelNdx, SINGLE_LEVEL, layerNdx, SINGLE_LAYER);
			const VkImageSubresourceRange	dstSubresourceRange		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER);

			Move<VkImageView>				srcImageView			(makeImageView(vk, device, srcImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, srcSubresourceRange, m_srcImageViewUsageKHR));

			de::MovePtr<Image>				dstImage				(new Image(vk, device, allocator, dstImageCreateInfo, MemoryRequirement::Any));
			Move<VkImageView>				dstImageView			(makeImageView(vk, device, dstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, dstSubresourceRange, m_dstImageViewUsageKHR));

			const VkBufferImageCopy			srcCopyRegion			= makeBufferImageCopy(srcImageResolution.x(), srcImageResolution.y(), levelNdx, layerNdx, srcImageResBlocked.x(), srcImageResBlocked.y());
			const VkBufferMemoryBarrier		srcCopyBufferBarrierPre	= makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, srcImageBuffer->get(), 0ull, srcImageSizeInBytes);
			const VkImageMemoryBarrier		srcCopyImageBarrierPre	= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, srcImage->get(), srcSubresourceRange);
			const VkImageMemoryBarrier		srcCopyImageBarrierPost	= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, srcImage->get(), srcSubresourceRange);
			const VkBufferImageCopy			dstCopyRegion			= makeBufferImageCopy(dstImageResolution.x(), dstImageResolution.y());
			const VkImageMemoryBarrier		dstInitImageBarrier		= makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, dstImage->get(), dstSubresourceRange);

			const VkImageView				attachmentBindInfos[]	= { *srcImageView, *dstImageView };
			const VkExtent2D				framebufferSize			(makeExtent2D(dstImageResolution[0], dstImageResolution[1]));
			const Move<VkFramebuffer>		framebuffer				(makeFramebuffer(vk, device, *renderPass, DE_LENGTH_OF_ARRAY(attachmentBindInfos), attachmentBindInfos, framebufferSize.width, framebufferSize.height, SINGLE_LAYER));

			// Upload source image data
			const Allocation& alloc = srcImageBuffer->getAllocation();
			deMemcpy(alloc.getHostPtr(), &m_srcData[levelNdx][layerNdx]->at(0), srcImageSizeInBytes);
			flushAlloc(vk, device, alloc);

			beginCommandBuffer(vk, *cmdBuffer);
			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

			// Copy buffer to image
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &srcCopyBufferBarrierPre, 1u, &srcCopyImageBarrierPre);
			vk.cmdCopyBufferToImage(*cmdBuffer, srcImageBuffer->get(), srcImage->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &srcCopyRegion);
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &srcCopyImageBarrierPost);

			// Define destination image layout
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &dstInitImageBarrier);

			beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize);

			const VkDescriptorImageInfo	descriptorSrcImageInfo(makeDescriptorImageInfo(DE_NULL, *srcImageView, VK_IMAGE_LAYOUT_GENERAL));
			DescriptorSetUpdateBuilder()
				.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descriptorSrcImageInfo)
				.update(vk, device);

			vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
			vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &m_vertexBuffer->get(), &m_vertexBufferOffset);

			vk.cmdSetViewport(*cmdBuffer, 0u, 1u, &viewport);
			vk.cmdSetScissor(*cmdBuffer, 0u, 1u, &scissor);

			vk.cmdDraw(*cmdBuffer, (deUint32)m_vertexCount, 1, 0, 0);

			endRenderPass(vk, *cmdBuffer);

			const VkImageMemoryBarrier prepareForTransferBarrier = makeImageMemoryBarrier(
				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
				VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
				dstImage->get(), dstSubresourceRange);

			const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier(
				VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
				dstImageBuffer->get(), 0ull, dstImageSizeInBytes);

			vk.cmdPipelineBarrier(*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, 1, &prepareForTransferBarrier);
			vk.cmdCopyImageToBuffer(*cmdBuffer, dstImage->get(), VK_IMAGE_LAYOUT_GENERAL, dstImageBuffer->get(), 1u, &dstCopyRegion);
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &copyBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);

			endCommandBuffer(vk, *cmdBuffer);

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

			const Allocation& dstImageBufferAlloc = dstImageBuffer->getAllocation();
			invalidateAlloc(vk, device, dstImageBufferAlloc);
			deMemcpy(&m_dstData[levelNdx][layerNdx]->at(0), dstImageBufferAlloc.getHostPtr(), dstImageSizeInBytes);
		}
	}

	m_compressedImage = srcImage;
}

void GraphicsAttachmentsTestInstance::transcodeWrite ()
{
	const DeviceInterface&				vk						= m_context.getDeviceInterface();
	const VkDevice						device					= m_context.getDevice();
	const deUint32						queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	const VkQueue						queue					= m_context.getUniversalQueue();
	Allocator&							allocator				= m_context.getDefaultAllocator();

	const VkImageCreateFlags*			imgCreateFlagsOverride	= DE_NULL;

	const VkImageCreateInfo				dstImageCreateInfo		= makeCreateImageInfo(m_dstFormat, m_parameters.imageType, m_dstImageResolutions[0], m_dstImageUsageFlags, imgCreateFlagsOverride, getLevelCount(), getLayerCount());
	MovePtr<Image>						dstImage				(new Image(vk, device, allocator, dstImageCreateInfo, MemoryRequirement::Any));

	const Unique<VkShaderModule>		vertShaderModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
	const Unique<VkShaderModule>		fragShaderModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));

	const Unique<VkRenderPass>			renderPass				(vkt::image::makeRenderPass(vk, device, m_parameters.formatUncompressed, m_parameters.formatUncompressed));

	const Move<VkDescriptorSetLayout>	descriptorSetLayout		(DescriptorSetLayoutBuilder()
																	.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
																	.build(vk, device));
	const Move<VkDescriptorPool>		descriptorPool			(DescriptorPoolBuilder()
																	.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
																	.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
	const Move<VkDescriptorSet>			descriptorSet			(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));

	const VkExtent2D					renderSizeDummy			(makeExtent2D(1u, 1u));
	const Unique<VkPipelineLayout>		pipelineLayout			(makePipelineLayout(vk, device, *descriptorSetLayout));
	const Unique<VkPipeline>			pipeline				(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule, *fragShaderModule, renderSizeDummy, 1u, true));

	const Unique<VkCommandPool>			cmdPool					(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>		cmdBuffer				(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	for (deUint32 levelNdx = 0; levelNdx < getLevelCount(); ++levelNdx)
	{
		const UVec3&				uncompressedImageRes	= m_uncompressedImageResVec[levelNdx];
		const UVec3&				srcImageResolution		= m_srcImageResolutions[levelNdx];
		const UVec3&				dstImageResolution		= m_dstImageResolutions[levelNdx];
		const UVec3					dstImageResBlocked		= getCompressedImageResolutionBlockCeil(m_parameters.formatCompressed, dstImageResolution);
		const size_t				srcImageSizeInBytes		= m_srcData[levelNdx][0]->size();
		const size_t				dstImageSizeInBytes		= m_dstData[levelNdx][0]->size();

		const VkImageCreateInfo		srcImageCreateInfo		= makeCreateImageInfo(m_srcFormat, m_parameters.imageType, srcImageResolution, m_srcImageUsageFlags, imgCreateFlagsOverride, SINGLE_LEVEL, SINGLE_LAYER);

		const VkExtent2D			renderSize				(makeExtent2D(uncompressedImageRes.x(), uncompressedImageRes.y()));
		const VkViewport			viewport				= makeViewport(renderSize);
		const VkRect2D				scissor					= makeRect2D(renderSize);

		for (deUint32 layerNdx = 0; layerNdx < getLayerCount(); ++layerNdx)
		{
			const VkBufferCreateInfo		srcImageBufferInfo		= makeBufferCreateInfo(srcImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
			const MovePtr<Buffer>			srcImageBuffer			= MovePtr<Buffer>(new Buffer(vk, device, allocator, srcImageBufferInfo, MemoryRequirement::HostVisible));

			const VkBufferCreateInfo		dstImageBufferInfo		= makeBufferCreateInfo(dstImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
			MovePtr<Buffer>					dstImageBuffer			= MovePtr<Buffer>(new Buffer(vk, device, allocator, dstImageBufferInfo, MemoryRequirement::HostVisible));

			const VkImageSubresourceRange	srcSubresourceRange		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER);
			const VkImageSubresourceRange	dstSubresourceRange		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, levelNdx, SINGLE_LEVEL, layerNdx, SINGLE_LAYER);

			Move<VkImageView>				dstImageView			(makeImageView(vk, device, dstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, dstSubresourceRange, m_dstImageViewUsageKHR));

			de::MovePtr<Image>				srcImage				(new Image(vk, device, allocator, srcImageCreateInfo, MemoryRequirement::Any));
			Move<VkImageView>				srcImageView			(makeImageView(vk, device, srcImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, srcSubresourceRange, m_srcImageViewUsageKHR));

			const VkBufferImageCopy			srcCopyRegion			= makeBufferImageCopy(srcImageResolution.x(), srcImageResolution.y(), 0u, 0u);
			const VkBufferMemoryBarrier		srcCopyBufferBarrierPre	= makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, srcImageBuffer->get(), 0ull, srcImageSizeInBytes);
			const VkImageMemoryBarrier		srcCopyImageBarrierPre	= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, srcImage->get(), srcSubresourceRange);
			const VkImageMemoryBarrier		srcCopyImageBarrierPost	= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, srcImage->get(), srcSubresourceRange);
			const VkBufferImageCopy			dstCopyRegion			= makeBufferImageCopy(dstImageResolution.x(), dstImageResolution.y(), levelNdx, layerNdx, dstImageResBlocked.x(), dstImageResBlocked.y());
			const VkImageMemoryBarrier		dstInitImageBarrier		= makeImageMemoryBarrier(0u, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, dstImage->get(), dstSubresourceRange);

			const VkImageView				attachmentBindInfos[]	= { *srcImageView, *dstImageView };
			const VkExtent2D				framebufferSize			(renderSize);
			const Move<VkFramebuffer>		framebuffer				(makeFramebuffer(vk, device, *renderPass, DE_LENGTH_OF_ARRAY(attachmentBindInfos), attachmentBindInfos, framebufferSize.width, framebufferSize.height, SINGLE_LAYER));

			// Upload source image data
			const Allocation& alloc = srcImageBuffer->getAllocation();
			deMemcpy(alloc.getHostPtr(), &m_srcData[levelNdx][layerNdx]->at(0), srcImageSizeInBytes);
			flushAlloc(vk, device, alloc);

			beginCommandBuffer(vk, *cmdBuffer);
			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

			// Copy buffer to image
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &srcCopyBufferBarrierPre, 1u, &srcCopyImageBarrierPre);
			vk.cmdCopyBufferToImage(*cmdBuffer, srcImageBuffer->get(), srcImage->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &srcCopyRegion);
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &srcCopyImageBarrierPost);

			// Define destination image layout
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &dstInitImageBarrier);

			beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize);

			const VkDescriptorImageInfo	descriptorSrcImageInfo(makeDescriptorImageInfo(DE_NULL, *srcImageView, VK_IMAGE_LAYOUT_GENERAL));
			DescriptorSetUpdateBuilder()
				.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descriptorSrcImageInfo)
				.update(vk, device);

			vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
			vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &m_vertexBuffer->get(), &m_vertexBufferOffset);

			vk.cmdSetViewport(*cmdBuffer, 0u, 1u, &viewport);
			vk.cmdSetScissor(*cmdBuffer, 0u, 1u, &scissor);

			vk.cmdDraw(*cmdBuffer, (deUint32)m_vertexCount, 1, 0, 0);

			endRenderPass(vk, *cmdBuffer);

			const VkImageMemoryBarrier prepareForTransferBarrier = makeImageMemoryBarrier(
				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
				VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
				dstImage->get(), dstSubresourceRange);

			const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier(
				VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
				dstImageBuffer->get(), 0ull, dstImageSizeInBytes);

			vk.cmdPipelineBarrier(*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, 1, &prepareForTransferBarrier);
			vk.cmdCopyImageToBuffer(*cmdBuffer, dstImage->get(), VK_IMAGE_LAYOUT_GENERAL, dstImageBuffer->get(), 1u, &dstCopyRegion);
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &copyBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);

			endCommandBuffer(vk, *cmdBuffer);

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

			const Allocation& dstImageBufferAlloc = dstImageBuffer->getAllocation();
			invalidateAlloc(vk, device, dstImageBufferAlloc);
			deMemcpy(&m_dstData[levelNdx][layerNdx]->at(0), dstImageBufferAlloc.getHostPtr(), dstImageSizeInBytes);
		}
	}

	m_compressedImage = dstImage;
}

bool GraphicsAttachmentsTestInstance::isWriteToCompressedOperation ()
{
	return (m_parameters.operation == OPERATION_ATTACHMENT_WRITE);
}

VkImageCreateInfo GraphicsAttachmentsTestInstance::makeCreateImageInfo (const VkFormat				format,
																	    const ImageType				type,
																	    const UVec3&				size,
																	    const VkImageUsageFlags		usageFlags,
																	    const VkImageCreateFlags*	createFlags,
																	    const deUint32				levels,
																	    const deUint32				layers)
{
	const VkImageType			imageType				= mapImageType(type);
	const VkImageCreateFlags	imageCreateFlagsBase	= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
	const VkImageCreateFlags	imageCreateFlagsAddOn	= isCompressedFormat(format) ? VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR : 0;
	const VkImageCreateFlags	imageCreateFlags		= (createFlags != DE_NULL) ? *createFlags : (imageCreateFlagsBase | imageCreateFlagsAddOn);

	VkFormatProperties properties;
	m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), format, &properties);
	if ((usageFlags & VK_IMAGE_USAGE_STORAGE_BIT) && !(properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
		TCU_THROW(NotSupportedError, "Format storage feature not supported");
	if ((usageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) && !(properties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
		TCU_THROW(NotSupportedError, "Format color attachment feature not supported");
	if ((usageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) && !(properties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) &&
		!(properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
		TCU_THROW(NotSupportedError, "Format color/depth/stencil attachment feature not supported for input attachment usage");

	const VkImageCreateInfo createImageInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
		DE_NULL,										// const void*				pNext;
		imageCreateFlags,								// VkImageCreateFlags		flags;
		imageType,										// VkImageType				imageType;
		format,											// VkFormat					format;
		makeExtent3D(getLayerSize(type, size)),			// VkExtent3D				extent;
		levels,											// deUint32					mipLevels;
		layers,											// deUint32					arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
		VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
		usageFlags,										// VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
		0u,												// deUint32					queueFamilyIndexCount;
		DE_NULL,										// const deUint32*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			initialLayout;
	};

	return createImageInfo;
}

VkDeviceSize GraphicsAttachmentsTestInstance::getCompressedImageData (const VkFormat			format,
																	  const UVec3&				size,
																	  std::vector<deUint8>&		data,
																	  const deUint32			layer,
																	  const deUint32			level)
{
	VkDeviceSize	sizeBytes	= getCompressedImageSizeInBytes(format, size);

	data.resize((size_t)sizeBytes);
	generateData(&data[0], data.size(), format, layer, level);

	return sizeBytes;
}

VkDeviceSize GraphicsAttachmentsTestInstance::getUncompressedImageData (const VkFormat			format,
																		const UVec3&			size,
																		std::vector<deUint8>&	data,
																		const deUint32			layer,
																		const deUint32			level)
{
	tcu::IVec3				sizeAsIVec3	= tcu::IVec3(static_cast<int>(size[0]), static_cast<int>(size[1]), static_cast<int>(size[2]));
	VkDeviceSize			sizeBytes	= getImageSizeBytes(sizeAsIVec3, format);

	data.resize((size_t)sizeBytes);
	generateData(&data[0], data.size(), format, layer, level);

	return sizeBytes;
}

bool GraphicsAttachmentsTestInstance::verifyDecompression (const std::vector<deUint8>&	refCompressedData,
														   const de::MovePtr<Image>&	resCompressedImage,
														   const deUint32				level,
														   const deUint32				layer,
														   const UVec3&					mipmapDims)
{
	const DeviceInterface&				vk							= m_context.getDeviceInterface();
	const VkDevice						device						= m_context.getDevice();
	const deUint32						queueFamilyIndex			= m_context.getUniversalQueueFamilyIndex();
	const VkQueue						queue						= m_context.getUniversalQueue();
	Allocator&							allocator					= m_context.getDefaultAllocator();

	const bool							layoutShaderReadOnly		= (layer % 2u) == 1;
	const UVec3							mipmapDimsBlocked			= getCompressedImageResolutionBlockCeil(m_parameters.formatCompressed, mipmapDims);

	const VkImageSubresourceRange		subresourceRange			= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER);
	const VkImageSubresourceRange		resSubresourceRange			= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, level, SINGLE_LEVEL, layer, SINGLE_LAYER);

	const VkDeviceSize					dstBufferSize				= getUncompressedImageSizeInBytes(m_parameters.formatForVerify, mipmapDims);
	const VkImageUsageFlags				refSrcImageUsageFlags		= VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;

	const VkBufferCreateInfo			refSrcImageBufferInfo		(makeBufferCreateInfo(refCompressedData.size(), VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
	const MovePtr<Buffer>				refSrcImageBuffer			= MovePtr<Buffer>(new Buffer(vk, device, allocator, refSrcImageBufferInfo, MemoryRequirement::HostVisible));

	const VkImageCreateFlags			refSrcImageCreateFlags		= 0;
	const VkImageCreateInfo				refSrcImageCreateInfo		= makeCreateImageInfo(m_parameters.formatCompressed, m_parameters.imageType, mipmapDimsBlocked, refSrcImageUsageFlags, &refSrcImageCreateFlags, SINGLE_LEVEL, SINGLE_LAYER);
	const MovePtr<Image>				refSrcImage					(new Image(vk, device, allocator, refSrcImageCreateInfo, MemoryRequirement::Any));
	Move<VkImageView>					refSrcImageView				(makeImageView(vk, device, refSrcImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatCompressed, subresourceRange));

	const VkImageUsageFlags				resSrcImageUsageFlags		= VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
	const VkImageViewUsageCreateInfo	resSrcImageViewUsageKHR		= makeImageViewUsageCreateInfo(resSrcImageUsageFlags);
	Move<VkImageView>					resSrcImageView				(makeImageView(vk, device, resCompressedImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatCompressed, resSubresourceRange, &resSrcImageViewUsageKHR));

	const VkImageCreateFlags			refDstImageCreateFlags		= 0;
	const VkImageUsageFlags				refDstImageUsageFlags		= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
	const VkImageCreateInfo				refDstImageCreateInfo		= makeCreateImageInfo(m_parameters.formatForVerify, m_parameters.imageType, mipmapDims, refDstImageUsageFlags, &refDstImageCreateFlags, SINGLE_LEVEL, SINGLE_LAYER);
	const MovePtr<Image>				refDstImage					(new Image(vk, device, allocator, refDstImageCreateInfo, MemoryRequirement::Any));
	const Move<VkImageView>				refDstImageView				(makeImageView(vk, device, refDstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatForVerify, subresourceRange));
	const VkImageMemoryBarrier			refDstInitImageBarrier		= makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, refDstImage->get(), subresourceRange);
	const VkBufferCreateInfo			refDstBufferInfo			(makeBufferCreateInfo(dstBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const MovePtr<Buffer>				refDstBuffer				= MovePtr<Buffer>(new Buffer(vk, device, allocator, refDstBufferInfo, MemoryRequirement::HostVisible));

	const VkImageCreateFlags			resDstImageCreateFlags		= 0;
	const VkImageUsageFlags				resDstImageUsageFlags		= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
	const VkImageCreateInfo				resDstImageCreateInfo		= makeCreateImageInfo(m_parameters.formatForVerify, m_parameters.imageType, mipmapDims, resDstImageUsageFlags, &resDstImageCreateFlags, SINGLE_LEVEL, SINGLE_LAYER);
	const MovePtr<Image>				resDstImage					(new Image(vk, device, allocator, resDstImageCreateInfo, MemoryRequirement::Any));
	const Move<VkImageView>				resDstImageView				(makeImageView(vk, device, resDstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatForVerify, subresourceRange));
	const VkImageMemoryBarrier			resDstInitImageBarrier		= makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, resDstImage->get(), subresourceRange);
	const VkBufferCreateInfo			resDstBufferInfo			(makeBufferCreateInfo(dstBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const MovePtr<Buffer>				resDstBuffer				= MovePtr<Buffer>(new Buffer(vk, device, allocator, resDstBufferInfo, MemoryRequirement::HostVisible));

	const Unique<VkShaderModule>		vertShaderModule			(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
	const Unique<VkShaderModule>		fragShaderModule			(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag_verify"), 0));

	const Unique<VkRenderPass>			renderPass					(vk::makeRenderPass(vk, device));

	const Move<VkDescriptorSetLayout>	descriptorSetLayout			(DescriptorSetLayoutBuilder()
																		.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT)
																		.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT)
																		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT)
																		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT)
																		.build(vk, device));
	const Move<VkDescriptorPool>		descriptorPool				(DescriptorPoolBuilder()
																		.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
																		.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
																		.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
																		.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
																		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
	const Move<VkDescriptorSet>			descriptorSet				(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
	const VkSamplerCreateInfo			refSrcSamplerInfo			(makeSamplerCreateInfo());
	const Move<VkSampler>				refSrcSampler				= vk::createSampler(vk, device, &refSrcSamplerInfo);
	const VkSamplerCreateInfo			resSrcSamplerInfo			(makeSamplerCreateInfo());
	const Move<VkSampler>				resSrcSampler				= vk::createSampler(vk, device, &resSrcSamplerInfo);
	const VkDescriptorImageInfo			descriptorRefSrcImage		(makeDescriptorImageInfo(*refSrcSampler, *refSrcImageView, layoutShaderReadOnly ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL));
	const VkDescriptorImageInfo			descriptorResSrcImage		(makeDescriptorImageInfo(*resSrcSampler, *resSrcImageView, layoutShaderReadOnly ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL));
	const VkDescriptorImageInfo			descriptorRefDstImage		(makeDescriptorImageInfo(DE_NULL, *refDstImageView, VK_IMAGE_LAYOUT_GENERAL));
	const VkDescriptorImageInfo			descriptorResDstImage		(makeDescriptorImageInfo(DE_NULL, *resDstImageView, VK_IMAGE_LAYOUT_GENERAL));

	const VkExtent2D					renderSize					(makeExtent2D(mipmapDims.x(), mipmapDims.y()));
	const Unique<VkPipelineLayout>		pipelineLayout				(makePipelineLayout(vk, device, *descriptorSetLayout));
	const Unique<VkPipeline>			pipeline					(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule, *fragShaderModule, renderSize, 0u));
	const Unique<VkCommandPool>			cmdPool						(createCommandPool(vk, device, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>		cmdBuffer					(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const VkBufferImageCopy				copyBufferToImageRegion		= makeBufferImageCopy(mipmapDimsBlocked.x(), mipmapDimsBlocked.y(), 0u, 0u, mipmapDimsBlocked.x(), mipmapDimsBlocked.y());
	const VkBufferImageCopy				copyRegion					= makeBufferImageCopy(mipmapDims.x(), mipmapDims.y(), 0u, 0u);
	const VkBufferMemoryBarrier			refSrcCopyBufferBarrierPre	= makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, refSrcImageBuffer->get(), 0ull, refCompressedData.size());
	const VkImageMemoryBarrier			refSrcCopyImageBarrierPre	= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, refSrcImage->get(), subresourceRange);
	const VkImageMemoryBarrier			refSrcCopyImageBarrierPost	= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL, layoutShaderReadOnly ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL, refSrcImage->get(), subresourceRange);
	const VkImageMemoryBarrier			resCompressedImageBarrier	= makeImageMemoryBarrier(0, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL, layoutShaderReadOnly ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL, resCompressedImage->get(), resSubresourceRange);

	const Move<VkFramebuffer>			framebuffer					(makeFramebuffer(vk, device, *renderPass, 0, DE_NULL, renderSize.width, renderSize.height, getLayerCount()));

	// Upload source image data
	{
		const Allocation& refSrcImageBufferAlloc = refSrcImageBuffer->getAllocation();
		deMemcpy(refSrcImageBufferAlloc.getHostPtr(), &refCompressedData[0], refCompressedData.size());
		flushAlloc(vk, device, refSrcImageBufferAlloc);
	}

	beginCommandBuffer(vk, *cmdBuffer);
	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

	// Copy buffer to image
	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &refSrcCopyBufferBarrierPre, 1u, &refSrcCopyImageBarrierPre);
	vk.cmdCopyBufferToImage(*cmdBuffer, refSrcImageBuffer->get(), refSrcImage->get(), VK_IMAGE_LAYOUT_GENERAL, 1u, &copyBufferToImageRegion);
	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, DE_NULL, 1u, &refSrcCopyImageBarrierPost);

	// Make reference and result images readable
	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &refDstInitImageBarrier);
	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &resDstInitImageBarrier);
	{
		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &resCompressedImageBarrier);
	}

	beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize);
	{
		DescriptorSetUpdateBuilder()
			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorRefSrcImage)
			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorResSrcImage)
			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorRefDstImage)
			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(3u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorResDstImage)
			.update(vk, device);

		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
		vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &m_vertexBuffer->get(), &m_vertexBufferOffset);
		vk.cmdDraw(*cmdBuffer, m_vertexCount, 1, 0, 0);
	}
	endRenderPass(vk, *cmdBuffer);

	// Decompress reference image
	{
		const VkImageMemoryBarrier refDstImageBarrier = makeImageMemoryBarrier(
			VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
			VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
			refDstImage->get(), subresourceRange);

		const VkBufferMemoryBarrier refDstBufferBarrier = makeBufferMemoryBarrier(
			VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
			refDstBuffer->get(), 0ull, dstBufferSize);

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &refDstImageBarrier);
		vk.cmdCopyImageToBuffer(*cmdBuffer, refDstImage->get(), VK_IMAGE_LAYOUT_GENERAL, refDstBuffer->get(), 1u, &copyRegion);
		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &refDstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
	}

	// Decompress result image
	{
		const VkImageMemoryBarrier resDstImageBarrier = makeImageMemoryBarrier(
			VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
			VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
			resDstImage->get(), subresourceRange);

		const VkBufferMemoryBarrier resDstBufferBarrier = makeBufferMemoryBarrier(
			VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
			resDstBuffer->get(), 0ull, dstBufferSize);

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &resDstImageBarrier);
		vk.cmdCopyImageToBuffer(*cmdBuffer, resDstImage->get(), VK_IMAGE_LAYOUT_GENERAL, resDstBuffer->get(), 1u, &copyRegion);
		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &resDstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
	}

	endCommandBuffer(vk, *cmdBuffer);

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

	// Compare decompressed pixel data in reference and result images
	{
		const Allocation&	refDstBufferAlloc	= refDstBuffer->getAllocation();
		invalidateAlloc(vk, device, refDstBufferAlloc);

		const Allocation&	resDstBufferAlloc	= resDstBuffer->getAllocation();
		invalidateAlloc(vk, device, resDstBufferAlloc);

		BinaryCompareMode compareMode =
			(m_parameters.formatIsASTC)
				?(COMPARE_MODE_ALLOW_ASTC_ERROR_COLOUR_WARNING)
				:(COMPARE_MODE_NORMAL);

		BinaryCompareResult res = BinaryCompare(refDstBufferAlloc.getHostPtr(),
												resDstBufferAlloc.getHostPtr(),
												dstBufferSize,
												m_parameters.formatForVerify,
												compareMode);

		if (res == COMPARE_RESULT_FAILED)
		{
			// Do fuzzy to log error mask
			invalidateAlloc(vk, device, resDstBufferAlloc);
			invalidateAlloc(vk, device, refDstBufferAlloc);

			tcu::ConstPixelBufferAccess	resPixels	(mapVkFormat(m_parameters.formatForVerify), renderSize.width, renderSize.height, 1u, resDstBufferAlloc.getHostPtr());
			tcu::ConstPixelBufferAccess	refPixels	(mapVkFormat(m_parameters.formatForVerify), renderSize.width, renderSize.height, 1u, refDstBufferAlloc.getHostPtr());

			string	comment	= string("Image Comparison (level=") + de::toString(level) + string(", layer=") + de::toString(layer) + string(")");

			if (isWriteToCompressedOperation())
				tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ImageComparison", comment.c_str(), refPixels, resPixels, 0.001f, tcu::COMPARE_LOG_EVERYTHING);
			else
				tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ImageComparison", comment.c_str(), resPixels, refPixels, 0.001f, tcu::COMPARE_LOG_EVERYTHING);

			return false;
		}
		else if (res == COMPARE_RESULT_ASTC_QUALITY_WARNING)
		{
			m_bASTCErrorColourMismatch = true;
		}
	}

	return true;
}


class GraphicsTextureTestInstance : public GraphicsAttachmentsTestInstance
{
public:
						GraphicsTextureTestInstance		(Context& context, const TestParameters& parameters);

protected:
	virtual bool		isWriteToCompressedOperation	();
	virtual void		transcodeRead					();
	virtual void		transcodeWrite					();
};

GraphicsTextureTestInstance::GraphicsTextureTestInstance (Context& context, const TestParameters& parameters)
	: GraphicsAttachmentsTestInstance(context, parameters)
{
}

bool GraphicsTextureTestInstance::isWriteToCompressedOperation ()
{
	return (m_parameters.operation == OPERATION_TEXTURE_WRITE);
}

void GraphicsTextureTestInstance::transcodeRead ()
{
	const DeviceInterface&				vk						= m_context.getDeviceInterface();
	const VkDevice						device					= m_context.getDevice();
	const deUint32						queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	const VkQueue						queue					= m_context.getUniversalQueue();
	Allocator&							allocator				= m_context.getDefaultAllocator();

	const VkImageCreateFlags*			imgCreateFlagsOverride	= DE_NULL;

	const VkImageCreateInfo				srcImageCreateInfo		= makeCreateImageInfo(m_srcFormat, m_parameters.imageType, m_srcImageResolutions[0], m_srcImageUsageFlags, imgCreateFlagsOverride, getLevelCount(), getLayerCount());
	MovePtr<Image>						srcImage				(new Image(vk, device, allocator, srcImageCreateInfo, MemoryRequirement::Any));

	const Unique<VkShaderModule>		vertShaderModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
	const Unique<VkShaderModule>		fragShaderModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));

	const Unique<VkRenderPass>			renderPass				(vk::makeRenderPass(vk, device));

	const Move<VkDescriptorSetLayout>	descriptorSetLayout		(DescriptorSetLayoutBuilder()
																	.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT)
																	.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT)
																	.build(vk, device));
	const Move<VkDescriptorPool>		descriptorPool			(DescriptorPoolBuilder()
																	.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
																	.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
																	.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
	const Move<VkDescriptorSet>			descriptorSet			(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));

	const VkExtent2D					renderSizeDummy			(makeExtent2D(1u, 1u));
	const Unique<VkPipelineLayout>		pipelineLayout			(makePipelineLayout(vk, device, *descriptorSetLayout));
	const Unique<VkPipeline>			pipeline				(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule, *fragShaderModule, renderSizeDummy, 0u, true));

	const Unique<VkCommandPool>			cmdPool					(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>		cmdBuffer				(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	for (deUint32 levelNdx = 0; levelNdx < getLevelCount(); ++levelNdx)
	{
		const UVec3&				uncompressedImageRes	= m_uncompressedImageResVec[levelNdx];
		const UVec3&				srcImageResolution		= m_srcImageResolutions[levelNdx];
		const UVec3&				dstImageResolution		= m_dstImageResolutions[levelNdx];
		const size_t				srcImageSizeInBytes		= m_srcData[levelNdx][0]->size();
		const size_t				dstImageSizeInBytes		= m_dstData[levelNdx][0]->size();
		const UVec3					srcImageResBlocked		= getCompressedImageResolutionBlockCeil(m_parameters.formatCompressed, srcImageResolution);

		const VkImageCreateInfo		dstImageCreateInfo		= makeCreateImageInfo(m_dstFormat, m_parameters.imageType, dstImageResolution, m_dstImageUsageFlags, imgCreateFlagsOverride, SINGLE_LEVEL, SINGLE_LAYER);

		const VkBufferCreateInfo	srcImageBufferInfo		= makeBufferCreateInfo(srcImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
		const MovePtr<Buffer>		srcImageBuffer			= MovePtr<Buffer>(new Buffer(vk, device, allocator, srcImageBufferInfo, MemoryRequirement::HostVisible));

		const VkBufferCreateInfo	dstImageBufferInfo		= makeBufferCreateInfo(dstImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
		MovePtr<Buffer>				dstImageBuffer			= MovePtr<Buffer>(new Buffer(vk, device, allocator, dstImageBufferInfo, MemoryRequirement::HostVisible));

		const VkExtent2D			renderSize				(makeExtent2D(uncompressedImageRes.x(), uncompressedImageRes.y()));
		const VkViewport			viewport				= makeViewport(renderSize);
		const VkRect2D				scissor					= makeRect2D(renderSize);

		for (deUint32 layerNdx = 0; layerNdx < getLayerCount(); ++layerNdx)
		{
			const VkImageSubresourceRange	srcSubresourceRange		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, levelNdx, SINGLE_LEVEL, layerNdx, SINGLE_LAYER);
			const VkImageSubresourceRange	dstSubresourceRange		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER);

			Move<VkImageView>				srcImageView			(makeImageView(vk, device, srcImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, srcSubresourceRange, m_srcImageViewUsageKHR));

			de::MovePtr<Image>				dstImage				(new Image(vk, device, allocator, dstImageCreateInfo, MemoryRequirement::Any));
			Move<VkImageView>				dstImageView			(makeImageView(vk, device, dstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, dstSubresourceRange, m_dstImageViewUsageKHR));

			const VkSamplerCreateInfo		srcSamplerInfo			(makeSamplerCreateInfo());
			const Move<VkSampler>			srcSampler				= vk::createSampler(vk, device, &srcSamplerInfo);
			const VkDescriptorImageInfo		descriptorSrcImage		(makeDescriptorImageInfo(*srcSampler, *srcImageView, VK_IMAGE_LAYOUT_GENERAL));
			const VkDescriptorImageInfo		descriptorDstImage		(makeDescriptorImageInfo(DE_NULL, *dstImageView, VK_IMAGE_LAYOUT_GENERAL));

			const VkBufferImageCopy			srcCopyRegion			= makeBufferImageCopy(srcImageResolution.x(), srcImageResolution.y(), levelNdx, layerNdx, srcImageResBlocked.x(), srcImageResBlocked.y());
			const VkBufferMemoryBarrier		srcCopyBufferBarrierPre	= makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, srcImageBuffer->get(), 0ull, srcImageSizeInBytes);
			const VkImageMemoryBarrier		srcCopyImageBarrierPre	= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, srcImage->get(), srcSubresourceRange);
			const VkImageMemoryBarrier		srcCopyImageBarrierPost	= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, srcImage->get(), srcSubresourceRange);
			const VkBufferImageCopy			dstCopyRegion			= makeBufferImageCopy(dstImageResolution.x(), dstImageResolution.y());
			const VkImageMemoryBarrier		dstInitImageBarrier		= makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, dstImage->get(), dstSubresourceRange);

			const VkExtent2D				framebufferSize			(makeExtent2D(dstImageResolution[0], dstImageResolution[1]));
			const Move<VkFramebuffer>		framebuffer				(makeFramebuffer(vk, device, *renderPass, 0, DE_NULL, framebufferSize.width, framebufferSize.height, SINGLE_LAYER));

			// Upload source image data
			const Allocation& alloc = srcImageBuffer->getAllocation();
			deMemcpy(alloc.getHostPtr(), &m_srcData[levelNdx][layerNdx]->at(0), srcImageSizeInBytes);
			flushAlloc(vk, device, alloc);

			beginCommandBuffer(vk, *cmdBuffer);
			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

			// Copy buffer to image
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &srcCopyBufferBarrierPre, 1u, &srcCopyImageBarrierPre);
			vk.cmdCopyBufferToImage(*cmdBuffer, srcImageBuffer->get(), srcImage->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &srcCopyRegion);
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &srcCopyImageBarrierPost);

			// Define destination image layout
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &dstInitImageBarrier);

			beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize);

			DescriptorSetUpdateBuilder()
				.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorSrcImage)
				.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorDstImage)
				.update(vk, device);

			vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
			vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &m_vertexBuffer->get(), &m_vertexBufferOffset);

			vk.cmdSetViewport(*cmdBuffer, 0u, 1u, &viewport);
			vk.cmdSetScissor(*cmdBuffer, 0u, 1u, &scissor);

			vk.cmdDraw(*cmdBuffer, (deUint32)m_vertexCount, 1, 0, 0);

			endRenderPass(vk, *cmdBuffer);

			const VkImageMemoryBarrier prepareForTransferBarrier = makeImageMemoryBarrier(
				VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
				VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
				dstImage->get(), dstSubresourceRange);

			const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier(
				VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
				dstImageBuffer->get(), 0ull, dstImageSizeInBytes);

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &prepareForTransferBarrier);
			vk.cmdCopyImageToBuffer(*cmdBuffer, dstImage->get(), VK_IMAGE_LAYOUT_GENERAL, dstImageBuffer->get(), 1u, &dstCopyRegion);
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &copyBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);

			endCommandBuffer(vk, *cmdBuffer);

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

			const Allocation& dstImageBufferAlloc = dstImageBuffer->getAllocation();
			invalidateAlloc(vk, device, dstImageBufferAlloc);
			deMemcpy(&m_dstData[levelNdx][layerNdx]->at(0), dstImageBufferAlloc.getHostPtr(), dstImageSizeInBytes);
		}
	}

	m_compressedImage = srcImage;
}

void GraphicsTextureTestInstance::transcodeWrite ()
{
	const DeviceInterface&				vk						= m_context.getDeviceInterface();
	const VkDevice						device					= m_context.getDevice();
	const deUint32						queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	const VkQueue						queue					= m_context.getUniversalQueue();
	Allocator&							allocator				= m_context.getDefaultAllocator();

	const VkImageCreateFlags*			imgCreateFlagsOverride	= DE_NULL;

	const VkImageCreateInfo				dstImageCreateInfo		= makeCreateImageInfo(m_dstFormat, m_parameters.imageType, m_dstImageResolutions[0], m_dstImageUsageFlags, imgCreateFlagsOverride, getLevelCount(), getLayerCount());
	MovePtr<Image>						dstImage				(new Image(vk, device, allocator, dstImageCreateInfo, MemoryRequirement::Any));

	const Unique<VkShaderModule>		vertShaderModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
	const Unique<VkShaderModule>		fragShaderModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));

	const Unique<VkRenderPass>			renderPass				(vk::makeRenderPass(vk, device));

	const Move<VkDescriptorSetLayout>	descriptorSetLayout		(DescriptorSetLayoutBuilder()
																	.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT)
																	.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT)
																	.build(vk, device));
	const Move<VkDescriptorPool>		descriptorPool			(DescriptorPoolBuilder()
																	.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
																	.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
																	.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
	const Move<VkDescriptorSet>			descriptorSet			(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));

	const VkExtent2D					renderSizeDummy			(makeExtent2D(1u, 1u));
	const Unique<VkPipelineLayout>		pipelineLayout			(makePipelineLayout(vk, device, *descriptorSetLayout));
	const Unique<VkPipeline>			pipeline				(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule, *fragShaderModule, renderSizeDummy, 0u, true));

	const Unique<VkCommandPool>			cmdPool					(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>		cmdBuffer				(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	for (deUint32 levelNdx = 0; levelNdx < getLevelCount(); ++levelNdx)
	{
		const UVec3&				uncompressedImageRes	= m_uncompressedImageResVec[levelNdx];
		const UVec3&				srcImageResolution		= m_srcImageResolutions[levelNdx];
		const UVec3&				dstImageResolution		= m_dstImageResolutions[levelNdx];
		const size_t				srcImageSizeInBytes		= m_srcData[levelNdx][0]->size();
		const size_t				dstImageSizeInBytes		= m_dstData[levelNdx][0]->size();
		const UVec3					dstImageResBlocked		= getCompressedImageResolutionBlockCeil(m_parameters.formatCompressed, dstImageResolution);

		const VkImageCreateInfo		srcImageCreateInfo		= makeCreateImageInfo(m_srcFormat, m_parameters.imageType, srcImageResolution, m_srcImageUsageFlags, imgCreateFlagsOverride, SINGLE_LEVEL, SINGLE_LAYER);

		const VkExtent2D			renderSize				(makeExtent2D(uncompressedImageRes.x(), uncompressedImageRes.y()));
		const VkViewport			viewport				= makeViewport(renderSize);
		const VkRect2D				scissor					= makeRect2D(renderSize);

		for (deUint32 layerNdx = 0; layerNdx < getLayerCount(); ++layerNdx)
		{
			const VkBufferCreateInfo		srcImageBufferInfo		= makeBufferCreateInfo(srcImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
			const MovePtr<Buffer>			srcImageBuffer			= MovePtr<Buffer>(new Buffer(vk, device, allocator, srcImageBufferInfo, MemoryRequirement::HostVisible));

			const VkBufferCreateInfo		dstImageBufferInfo		= makeBufferCreateInfo(dstImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
			MovePtr<Buffer>					dstImageBuffer			= MovePtr<Buffer>(new Buffer(vk, device, allocator, dstImageBufferInfo, MemoryRequirement::HostVisible));

			const VkImageSubresourceRange	srcSubresourceRange		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER);
			const VkImageSubresourceRange	dstSubresourceRange		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, levelNdx, SINGLE_LEVEL, layerNdx, SINGLE_LAYER);

			Move<VkImageView>				dstImageView			(makeImageView(vk, device, dstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, dstSubresourceRange, m_dstImageViewUsageKHR));

			de::MovePtr<Image>				srcImage				(new Image(vk, device, allocator, srcImageCreateInfo, MemoryRequirement::Any));
			Move<VkImageView>				srcImageView			(makeImageView(vk, device, srcImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, srcSubresourceRange, m_srcImageViewUsageKHR));

			const VkSamplerCreateInfo		srcSamplerInfo			(makeSamplerCreateInfo());
			const Move<VkSampler>			srcSampler				= vk::createSampler(vk, device, &srcSamplerInfo);
			const VkDescriptorImageInfo		descriptorSrcImage		(makeDescriptorImageInfo(*srcSampler, *srcImageView, VK_IMAGE_LAYOUT_GENERAL));
			const VkDescriptorImageInfo		descriptorDstImage		(makeDescriptorImageInfo(DE_NULL, *dstImageView, VK_IMAGE_LAYOUT_GENERAL));

			const VkBufferImageCopy			srcCopyRegion			= makeBufferImageCopy(srcImageResolution.x(), srcImageResolution.y(), 0u, 0u);
			const VkBufferMemoryBarrier		srcCopyBufferBarrierPre	= makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, srcImageBuffer->get(), 0ull, srcImageSizeInBytes);
			const VkImageMemoryBarrier		srcCopyImageBarrierPre	= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, srcImage->get(), srcSubresourceRange);
			const VkImageMemoryBarrier		srcCopyImageBarrierPost	= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, srcImage->get(), srcSubresourceRange);
			const VkBufferImageCopy			dstCopyRegion			= makeBufferImageCopy(dstImageResolution.x(), dstImageResolution.y(), levelNdx, layerNdx, dstImageResBlocked.x(), dstImageResBlocked.y());
			const VkImageMemoryBarrier		dstInitImageBarrier		= makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, dstImage->get(), dstSubresourceRange);

			const VkExtent2D				framebufferSize			(makeExtent2D(dstImageResolution[0], dstImageResolution[1]));
			const Move<VkFramebuffer>		framebuffer				(makeFramebuffer(vk, device, *renderPass, 0, DE_NULL, framebufferSize.width, framebufferSize.height, SINGLE_LAYER));

			// Upload source image data
			const Allocation& alloc = srcImageBuffer->getAllocation();
			deMemcpy(alloc.getHostPtr(), &m_srcData[levelNdx][layerNdx]->at(0), srcImageSizeInBytes);
			flushAlloc(vk, device, alloc);

			beginCommandBuffer(vk, *cmdBuffer);
			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

			// Copy buffer to image
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &srcCopyBufferBarrierPre, 1u, &srcCopyImageBarrierPre);
			vk.cmdCopyBufferToImage(*cmdBuffer, srcImageBuffer->get(), srcImage->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &srcCopyRegion);
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &srcCopyImageBarrierPost);

			// Define destination image layout
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &dstInitImageBarrier);

			beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize);

			DescriptorSetUpdateBuilder()
				.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorSrcImage)
				.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorDstImage)
				.update(vk, device);

			vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
			vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &m_vertexBuffer->get(), &m_vertexBufferOffset);

			vk.cmdSetViewport(*cmdBuffer, 0u, 1u, &viewport);
			vk.cmdSetScissor(*cmdBuffer, 0u, 1u, &scissor);

			vk.cmdDraw(*cmdBuffer, (deUint32)m_vertexCount, 1, 0, 0);

			endRenderPass(vk, *cmdBuffer);

			const VkImageMemoryBarrier prepareForTransferBarrier = makeImageMemoryBarrier(
				VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
				VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
				dstImage->get(), dstSubresourceRange);

			const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier(
				VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
				dstImageBuffer->get(), 0ull, dstImageSizeInBytes);

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &prepareForTransferBarrier);
			vk.cmdCopyImageToBuffer(*cmdBuffer, dstImage->get(), VK_IMAGE_LAYOUT_GENERAL, dstImageBuffer->get(), 1u, &dstCopyRegion);
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &copyBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);

			endCommandBuffer(vk, *cmdBuffer);

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

			const Allocation& dstImageBufferAlloc = dstImageBuffer->getAllocation();
			invalidateAlloc(vk, device, dstImageBufferAlloc);
			deMemcpy(&m_dstData[levelNdx][layerNdx]->at(0), dstImageBufferAlloc.getHostPtr(), dstImageSizeInBytes);
		}
	}

	m_compressedImage = dstImage;
}

class TexelViewCompatibleCase : public TestCase
{
public:
							TexelViewCompatibleCase		(TestContext&				testCtx,
														 const std::string&			name,
														 const std::string&			desc,
														 const TestParameters&		parameters);
	void					initPrograms				(SourceCollections&			programCollection) const;
	TestInstance*			createInstance				(Context&					context) const;
	virtual void			checkSupport				(Context&					context) const;
protected:
	const TestParameters	m_parameters;
};

TexelViewCompatibleCase::TexelViewCompatibleCase (TestContext& testCtx, const std::string& name, const std::string& desc, const TestParameters& parameters)
	: TestCase				(testCtx, name, desc)
	, m_parameters			(parameters)
{
}

void TexelViewCompatibleCase::initPrograms (vk::SourceCollections&	programCollection) const
{
	DE_ASSERT(m_parameters.size.x() > 0);
	DE_ASSERT(m_parameters.size.y() > 0);

	const unsigned int imageTypeIndex =
		(m_parameters.imageType == IMAGE_TYPE_2D) +
		(m_parameters.imageType == IMAGE_TYPE_3D) * 2;

	switch (m_parameters.shader)
	{
		case SHADER_TYPE_COMPUTE:
		{
			const std::string	imageTypeStr		= getShaderImageType(mapVkFormat(m_parameters.formatUncompressed), m_parameters.imageType);
			const std::string	formatQualifierStr	= getShaderImageFormatQualifier(mapVkFormat(m_parameters.formatUncompressed));
			std::ostringstream	src;
			std::ostringstream	src_decompress;

			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\n";
			src_decompress << src.str();

			switch(m_parameters.operation)
			{
				case OPERATION_IMAGE_LOAD:
				{
					const char* posDefinitions[3] =
					{
						// IMAGE_TYPE_1D
						"    highp int pos = int(gl_GlobalInvocationID.x);\n",
						// IMAGE_TYPE_2D
						"    ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n",
						// IMAGE_TYPE_3D
						"    ivec3 pos = ivec3(gl_GlobalInvocationID);\n",
					};

					src << "layout (binding = 0, "<<formatQualifierStr<<") readonly uniform "<<imageTypeStr<<" u_image0;\n"
						<< "layout (binding = 1, "<<formatQualifierStr<<") writeonly uniform "<<imageTypeStr<<" u_image1;\n\n"
						<< "void main (void)\n"
						<< "{\n"
						<< posDefinitions[imageTypeIndex]
						<< "    imageStore(u_image1, pos, imageLoad(u_image0, pos));\n"
						<< "}\n";

					break;
				}

				case OPERATION_TEXEL_FETCH:
				{
					const char* storeDefinitions[3] =
					{
						// IMAGE_TYPE_1D
						"    imageStore(u_image1, pos.x, texelFetch(u_image0, pos.x, pos.z));\n",
						// IMAGE_TYPE_2D
						"    imageStore(u_image1, pos.xy, texelFetch(u_image0, pos.xy, pos.z));\n",
						// IMAGE_TYPE_3D
						"    imageStore(u_image1, pos, texelFetch(u_image0, pos, pos.z));\n",
					};

					src << "layout (binding = 0) uniform "<<getGlslSamplerType(mapVkFormat(m_parameters.formatUncompressed), mapImageViewType(m_parameters.imageType))<<" u_image0;\n"
						<< "layout (binding = 1, "<<formatQualifierStr<<") writeonly uniform "<<imageTypeStr<<" u_image1;\n\n"
						<< "void main (void)\n"
						<< "{\n"
						<< "    ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n"
						<< storeDefinitions[imageTypeIndex]
						<< "}\n";

					break;
				}

				case OPERATION_TEXTURE:
				{
					const char* coordDefinitions[3] =
					{
						// IMAGE_TYPE_1D
						"    const int     pos = int(gl_GlobalInvocationID.x);\n"
						"    const float coord = (float(gl_GlobalInvocationID.x) + 0.5) / pixels_resolution.x;\n",
						// IMAGE_TYPE_2D
						"    const ivec2  pos = ivec2(gl_GlobalInvocationID.xy);\n"
						"    const vec2 coord = (vec2(gl_GlobalInvocationID.xy) + 0.5) / vec2(pixels_resolution);\n",
						// IMAGE_TYPE_3D
						"    const ivec3  pos = ivec3(gl_GlobalInvocationID.xy, 0);\n"
						"    const vec2    v2 = (vec2(gl_GlobalInvocationID.xy) + 0.5) / vec2(pixels_resolution);\n"
						"    const vec3 coord = vec3(v2, 0.0);\n",
					};

					src << "layout (binding = 0) uniform "<<getGlslSamplerType(mapVkFormat(m_parameters.formatUncompressed), mapImageViewType(m_parameters.imageType))<<" u_image0;\n"
						<< "layout (binding = 1, "<<formatQualifierStr<<") writeonly uniform "<<imageTypeStr<<" u_image1;\n\n"
						<< "void main (void)\n"
						<< "{\n"
						<< "    const vec2 pixels_resolution = vec2(gl_NumWorkGroups.x, gl_NumWorkGroups.y);\n"
						<< coordDefinitions[imageTypeIndex]
						<< "    imageStore(u_image1, pos, texture(u_image0, coord));\n"
						<< "}\n";

					break;
				}

				case OPERATION_IMAGE_STORE:
				{
					const char* posDefinitions[3] =
					{
						// IMAGE_TYPE_1D
						"    highp int pos = int(gl_GlobalInvocationID.x);\n",
						// IMAGE_TYPE_2D
						"    ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n",
						// IMAGE_TYPE_3D
						"    ivec3 pos = ivec3(gl_GlobalInvocationID);\n",
					};

					src << "layout (binding = 0, "<<formatQualifierStr<<") uniform "<<imageTypeStr<<"           u_image0;\n"
						<< "layout (binding = 1, "<<formatQualifierStr<<") readonly uniform "<<imageTypeStr<<"  u_image1;\n"
						<< "layout (binding = 2, "<<formatQualifierStr<<") writeonly uniform "<<imageTypeStr<<" u_image2;\n\n"
						<< "void main (void)\n"
						<< "{\n"
						<< posDefinitions[imageTypeIndex]
						<< "    imageStore(u_image0, pos, imageLoad(u_image1, pos));\n"
						<< "    imageStore(u_image2, pos, imageLoad(u_image0, pos));\n"
						<< "}\n";

					break;
				}

				default:
					DE_ASSERT(false);
			}

			const char* cordDefinitions[3] =
			{
				// IMAGE_TYPE_1D
				"    const highp float cord = float(gl_GlobalInvocationID.x) / pixels_resolution.x;\n"
				"    const highp int    pos = int(gl_GlobalInvocationID.x); \n",
				// IMAGE_TYPE_2D
				"    const vec2 cord = vec2(gl_GlobalInvocationID.xy) / vec2(pixels_resolution);\n"
				"    const ivec2 pos = ivec2(gl_GlobalInvocationID.xy); \n",
				// IMAGE_TYPE_3D
				"    const vec2 v2 = vec2(gl_GlobalInvocationID.xy) / vec2(pixels_resolution);\n"
				"    const vec3 cord = vec3(v2, 0.0);\n"
				"    const ivec3 pos = ivec3(gl_GlobalInvocationID); \n",
			};
			src_decompress	<< "layout (binding = 0) uniform "<<getGlslSamplerType(mapVkFormat(m_parameters.formatUncompressed), mapImageViewType(m_parameters.imageType))<<" compressed_result;\n"
							<< "layout (binding = 1) uniform "<<getGlslSamplerType(mapVkFormat(m_parameters.formatUncompressed), mapImageViewType(m_parameters.imageType))<<" compressed_reference;\n"
							<< "layout (binding = 2, "<<formatQualifierStr<<") writeonly uniform "<<imageTypeStr<<" decompressed_result;\n"
							<< "layout (binding = 3, "<<formatQualifierStr<<") writeonly uniform "<<imageTypeStr<<" decompressed_reference;\n\n"
							<< "void main (void)\n"
							<< "{\n"
							<< "    const vec2 pixels_resolution = vec2(gl_NumWorkGroups.xy);\n"
							<< cordDefinitions[imageTypeIndex]
							<< "    imageStore(decompressed_result, pos, texture(compressed_result, cord));\n"
							<< "    imageStore(decompressed_reference, pos, texture(compressed_reference, cord));\n"
							<< "}\n";
			programCollection.glslSources.add("comp") << glu::ComputeSource(src.str());
			programCollection.glslSources.add("decompress") << glu::ComputeSource(src_decompress.str());

			break;
		}

		case SHADER_TYPE_FRAGMENT:
		{
			ImageType	imageTypeForFS = (m_parameters.imageType == IMAGE_TYPE_2D_ARRAY) ? IMAGE_TYPE_2D : m_parameters.imageType;

			// Vertex shader
			{
				std::ostringstream src;
				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
					<< "layout(location = 0) in vec4 v_in_position;\n"
					<< "\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "    gl_Position = v_in_position;\n"
					<< "}\n";

				programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
			}

			// Fragment shader
			{
				switch(m_parameters.operation)
				{
					case OPERATION_ATTACHMENT_READ:
					case OPERATION_ATTACHMENT_WRITE:
					{
						std::ostringstream	src;

						const std::string	dstTypeStr	= getGlslFormatType(m_parameters.formatUncompressed);
						const std::string	srcTypeStr	= getGlslInputFormatType(m_parameters.formatUncompressed);

						src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
							<< "precision highp int;\n"
							<< "precision highp float;\n"
							<< "\n"
							<< "layout (location = 0) out highp " << dstTypeStr << " o_color;\n"
							<< "layout (input_attachment_index = 0, set = 0, binding = 0) uniform highp " << srcTypeStr << " inputImage1;\n"
							<< "\n"
							<< "void main (void)\n"
							<< "{\n"
							<< "    o_color = " << dstTypeStr << "(subpassLoad(inputImage1));\n"
							<< "}\n";

						programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());

						break;
					}

					case OPERATION_TEXTURE_READ:
					case OPERATION_TEXTURE_WRITE:
					{
						std::ostringstream	src;

						const std::string	srcSamplerTypeStr		= getGlslSamplerType(mapVkFormat(m_parameters.formatUncompressed), mapImageViewType(imageTypeForFS));
						const std::string	dstImageTypeStr			= getShaderImageType(mapVkFormat(m_parameters.formatUncompressed), imageTypeForFS);
						const std::string	dstFormatQualifierStr	= getShaderImageFormatQualifier(mapVkFormat(m_parameters.formatUncompressed));

						const char* inDefinitions[3] =
						{
							// IMAGE_TYPE_1D
							"    const highp int out_pos = int(gl_FragCoord.x);\n"
							"    const highp float pixels_resolution = textureSize(u_imageIn, 0);\n"
							"    const highp float in_pos = gl_FragCoord.x / pixels_resolution;\n",
							// IMAGE_TYPE_2D
							"    const ivec2 out_pos = ivec2(gl_FragCoord.xy);\n"
							"    const vec2 pixels_resolution = vec2(textureSize(u_imageIn, 0));\n"
							"    const vec2 in_pos = vec2(gl_FragCoord.xy) / vec2(pixels_resolution);\n",
							// IMAGE_TYPE_3D
							"    const ivec3 out_pos = ivec3(gl_FragCoord.xy, 0);\n"
							"    const vec3 pixels_resolution = vec3(textureSize(u_imageIn, 0));\n"
							"    const vec3 in_pos = vec3(gl_FragCoord.xy, 0) / vec3(pixels_resolution.xy, 1.0);\n",
						};

						src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
							<< "layout (binding = 0) uniform " << srcSamplerTypeStr << " u_imageIn;\n"
							<< "layout (binding = 1, " << dstFormatQualifierStr << ") writeonly uniform " << dstImageTypeStr << " u_imageOut;\n"
							<< "\n"
							<< "void main (void)\n"
							<< "{\n"
							<< inDefinitions[imageTypeIndex]
							<< "    imageStore(u_imageOut, out_pos, texture(u_imageIn, in_pos));\n"
							<< "}\n";

						programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());

						break;
					}

					default:
						DE_ASSERT(false);
				}
			}

			// Verification fragment shader
			{
				std::ostringstream	src;

				const std::string	samplerType			= getGlslSamplerType(mapVkFormat(m_parameters.formatForVerify), mapImageViewType(imageTypeForFS));
				const std::string	imageTypeStr		= getShaderImageType(mapVkFormat(m_parameters.formatForVerify), imageTypeForFS);
				const std::string	formatQualifierStr	= getShaderImageFormatQualifier(mapVkFormat(m_parameters.formatForVerify));

				const char* pos0Definitions[3] =
				{
					// IMAGE_TYPE_1D
					"    const highp int out_pos = int(gl_FragCoord.x);\n"
					"    const highp float pixels_resolution0 = textureSize(u_imageIn0, 0);\n"
					"    const highp float in_pos0 = gl_FragCoord.x / pixels_resolution0;\n",
					// IMAGE_TYPE_2D
					"    const ivec2 out_pos = ivec2(gl_FragCoord.xy);\n"
					"    const vec2 pixels_resolution0 = vec2(textureSize(u_imageIn0, 0));\n"
					"    const vec2 in_pos0 = vec2(gl_FragCoord.xy) / vec2(pixels_resolution0);\n",
					// IMAGE_TYPE_3D
					"    const ivec3 out_pos = ivec3(ivec2(gl_FragCoord.xy), 0);\n"
					"    const vec3 pixels_resolution0 = vec3(textureSize(u_imageIn0, 0));\n"
					"    const vec3 in_pos0 = vec3(gl_FragCoord.xy, 0) / vec3(pixels_resolution0.xy, 1.0);\n",
				};
				const char* pos1Definitions[3] =
				{
					// IMAGE_TYPE_1D
					"    const highp float pixels_resolution1 = textureSize(u_imageIn1, 0);\n"
					"    const highp float in_pos1 = gl_FragCoord.x / pixels_resolution1;\n",
					// IMAGE_TYPE_2D
					"    const vec2 pixels_resolution1 = vec2(textureSize(u_imageIn1, 0));\n"
					"    const vec2 in_pos1 = vec2(gl_FragCoord.xy) / vec2(pixels_resolution1);\n",
					// IMAGE_TYPE_3D
					"    const vec3 pixels_resolution1 = vec3(textureSize(u_imageIn1, 0));\n"
					"    const vec3 in_pos1 = vec3(gl_FragCoord.xy, 0) / vec3(pixels_resolution1.xy, 1.0);\n",
				};

				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
					<< "layout (binding = 0) uniform " << samplerType << " u_imageIn0;\n"
					<< "layout (binding = 1) uniform " << samplerType << " u_imageIn1;\n"
					<< "layout (binding = 2, " << formatQualifierStr << ") writeonly uniform " << imageTypeStr << " u_imageOut0;\n"
					<< "layout (binding = 3, " << formatQualifierStr << ") writeonly uniform " << imageTypeStr << " u_imageOut1;\n"
					<< "\n"
					<< "void main (void)\n"
					<< "{\n"
					<< pos0Definitions[imageTypeIndex]
					<< "    imageStore(u_imageOut0, out_pos, texture(u_imageIn0, in_pos0));\n"
					<< "\n"
					<< pos1Definitions[imageTypeIndex]
					<< "    imageStore(u_imageOut1, out_pos, texture(u_imageIn1, in_pos1));\n"
					<< "}\n";

				programCollection.glslSources.add("frag_verify") << glu::FragmentSource(src.str());
			}

			break;
		}

		default:
			DE_ASSERT(false);
	}
}

void TexelViewCompatibleCase::checkSupport (Context& context) const
{
	const VkPhysicalDevice			physicalDevice			= context.getPhysicalDevice();
	const InstanceInterface&		vk						= context.getInstanceInterface();

	context.requireDeviceFunctionality("VK_KHR_maintenance2");

	{
		VkImageFormatProperties imageFormatProperties;

		if (vk.getPhysicalDeviceImageFormatProperties(physicalDevice, m_parameters.formatUncompressed,
													  mapImageType(m_parameters.imageType), VK_IMAGE_TILING_OPTIMAL,
													  m_parameters.uncompressedImageUsage, 0u, &imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
			TCU_THROW(NotSupportedError, "Operation not supported with this image format");

		if (VK_ERROR_FORMAT_NOT_SUPPORTED == vk.getPhysicalDeviceImageFormatProperties(physicalDevice, m_parameters.formatCompressed,
												mapImageType(m_parameters.imageType), VK_IMAGE_TILING_OPTIMAL,
												m_parameters.compressedImageUsage,
												VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR | VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR,
												&imageFormatProperties))
			TCU_THROW(NotSupportedError, "Operation not supported with this image format");
	}

	{
		const VkPhysicalDeviceFeatures	physicalDeviceFeatures	= getPhysicalDeviceFeatures(vk, physicalDevice);

		if (deInRange32(m_parameters.formatCompressed, VK_FORMAT_BC1_RGB_UNORM_BLOCK, VK_FORMAT_BC7_SRGB_BLOCK) &&
			!physicalDeviceFeatures.textureCompressionBC)
			TCU_THROW(NotSupportedError, "textureCompressionBC not supported");

		if (deInRange32(m_parameters.formatCompressed, VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, VK_FORMAT_EAC_R11G11_SNORM_BLOCK) &&
			!physicalDeviceFeatures.textureCompressionETC2)
			TCU_THROW(NotSupportedError, "textureCompressionETC2 not supported");

		if (m_parameters.formatIsASTC &&
			!physicalDeviceFeatures.textureCompressionASTC_LDR)
			TCU_THROW(NotSupportedError, "textureCompressionASTC_LDR not supported");

		if (m_parameters.uncompressedImageUsage & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)
		{
			const VkFormatProperties p = getPhysicalDeviceFormatProperties(vk, physicalDevice, m_parameters.formatUncompressed);
			if ((p.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
				TCU_THROW(NotSupportedError, "Storage view format not supported");
		}
	}
}

TestInstance* TexelViewCompatibleCase::createInstance (Context& context) const
{
	if (!m_parameters.useMipmaps)
		DE_ASSERT(getNumLayers(m_parameters.imageType, m_parameters.size) == 1u);

	DE_ASSERT(getLayerSize(m_parameters.imageType, m_parameters.size).x() > 0u);
	DE_ASSERT(getLayerSize(m_parameters.imageType, m_parameters.size).y() > 0u);

	switch (m_parameters.shader)
	{
		case SHADER_TYPE_COMPUTE:
		{
			switch (m_parameters.operation)
			{
				case OPERATION_IMAGE_LOAD:
				case OPERATION_TEXEL_FETCH:
				case OPERATION_TEXTURE:
					return new BasicComputeTestInstance(context, m_parameters);
				case OPERATION_IMAGE_STORE:
					return new ImageStoreComputeTestInstance(context, m_parameters);
				default:
					TCU_THROW(InternalError, "Impossible");
			}
		}

		case SHADER_TYPE_FRAGMENT:
		{
			switch (m_parameters.operation)
			{
				case OPERATION_ATTACHMENT_READ:
				case OPERATION_ATTACHMENT_WRITE:
					return new GraphicsAttachmentsTestInstance(context, m_parameters);

				case OPERATION_TEXTURE_READ:
				case OPERATION_TEXTURE_WRITE:
					return new GraphicsTextureTestInstance(context, m_parameters);

				default:
					TCU_THROW(InternalError, "Impossible");
			}
		}

		default:
			TCU_THROW(InternalError, "Impossible");
	}
}

} // anonymous ns

static tcu::UVec3 getUnniceResolution (const VkFormat format, const deUint32 layers)
{
	const deUint32	unniceMipmapTextureSize[]	= { 1, 1, 1, 8, 22, 48, 117, 275, 604, 208, 611, 274, 1211 };
	const deUint32	baseTextureWidth			= unniceMipmapTextureSize[getBlockWidth(format)];
	const deUint32	baseTextureHeight			= unniceMipmapTextureSize[getBlockHeight(format)];
	const deUint32	baseTextureWidthLevels		= deLog2Floor32(baseTextureWidth);
	const deUint32	baseTextureHeightLevels		= deLog2Floor32(baseTextureHeight);
	const deUint32	widthMultiplier				= (baseTextureHeightLevels > baseTextureWidthLevels) ? 1u << (baseTextureHeightLevels - baseTextureWidthLevels) : 1u;
	const deUint32	heightMultiplier			= (baseTextureWidthLevels > baseTextureHeightLevels) ? 1u << (baseTextureWidthLevels - baseTextureHeightLevels) : 1u;
	const deUint32	width						= baseTextureWidth * widthMultiplier;
	const deUint32	height						= baseTextureHeight * heightMultiplier;

	// Number of levels should be same on both axises
	DE_ASSERT(deLog2Floor32(width) == deLog2Floor32(height));

	return tcu::UVec3(width, height, layers);
}

tcu::TestCaseGroup* createImageCompressionTranscodingTests (tcu::TestContext& testCtx)
{
	struct FormatsArray
	{
		const VkFormat*	formats;
		deUint32		count;
	};

	const bool					mipmapness[]									=
	{
		false,
		true,
	};

	const std::string			pipelineName[SHADER_TYPE_LAST]					=
	{
		"compute",
		"graphic",
	};

	const std::string			mipmanpnessName[DE_LENGTH_OF_ARRAY(mipmapness)]	=
	{
		"basic",
		"extended",
	};

	const std::string			operationName[OPERATION_LAST]					=
	{
		"image_load",
		"texel_fetch",
		"texture",
		"image_store",
		"attachment_read",
		"attachment_write",
		"texture_read",
		"texture_write",
	};

	struct ImageTypeName
	{
		ImageType		type;
		std::string		name;
	};
	ImageTypeName imageTypes[] =
	{
		{ IMAGE_TYPE_1D, "1d_image" },
		{ IMAGE_TYPE_2D, "2d_image" },
		{ IMAGE_TYPE_3D, "3d_image" },
	};

	const VkImageUsageFlags		baseImageUsageFlagSet							= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
	const VkImageUsageFlags		compressedImageUsageFlags[OPERATION_LAST]		=
	{
		baseImageUsageFlagSet | static_cast<VkImageUsageFlagBits>(VK_IMAGE_USAGE_STORAGE_BIT),											// "image_load"
		baseImageUsageFlagSet | static_cast<VkImageUsageFlagBits>(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT),				// "texel_fetch"
		baseImageUsageFlagSet | static_cast<VkImageUsageFlagBits>(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT),				// "texture"
		baseImageUsageFlagSet | static_cast<VkImageUsageFlagBits>(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT),				// "image_store"
		baseImageUsageFlagSet | static_cast<VkImageUsageFlagBits>(VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),	// "attachment_read"
		baseImageUsageFlagSet | static_cast<VkImageUsageFlagBits>(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),	// "attachment_write"
		baseImageUsageFlagSet | static_cast<VkImageUsageFlagBits>(VK_IMAGE_USAGE_SAMPLED_BIT),											// "texture_read"
		baseImageUsageFlagSet | static_cast<VkImageUsageFlagBits>(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT),				// "texture_write"
	};

	const VkImageUsageFlags		compressedImageViewUsageFlags[OPERATION_LAST]	=
	{
		compressedImageUsageFlags[0],																									//"image_load"
		compressedImageUsageFlags[1],																									//"texel_fetch"
		compressedImageUsageFlags[2],																									//"texture"
		compressedImageUsageFlags[3],																									//"image_store"
		compressedImageUsageFlags[4],																									//"attachment_read"
		compressedImageUsageFlags[5] | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,																//"attachment_write"
		compressedImageUsageFlags[6],																									//"texture_read"
		compressedImageUsageFlags[7],																									//"texture_write"
	};

	const VkImageUsageFlags		uncompressedImageUsageFlags[OPERATION_LAST]		=
	{
		baseImageUsageFlagSet | static_cast<VkImageUsageFlagBits>(VK_IMAGE_USAGE_STORAGE_BIT),											//"image_load"
		baseImageUsageFlagSet | static_cast<VkImageUsageFlagBits>(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT),				//"texel_fetch"
		baseImageUsageFlagSet | static_cast<VkImageUsageFlagBits>(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT),				//"texture"
		baseImageUsageFlagSet | static_cast<VkImageUsageFlagBits>(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT),				//"image_store"
		baseImageUsageFlagSet | static_cast<VkImageUsageFlagBits>(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),	//"attachment_read"
		baseImageUsageFlagSet | static_cast<VkImageUsageFlagBits>(VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT),									//"attachment_write"
		baseImageUsageFlagSet | static_cast<VkImageUsageFlagBits>(VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),				//"texture_read"
		baseImageUsageFlagSet | static_cast<VkImageUsageFlagBits>(VK_IMAGE_USAGE_SAMPLED_BIT),											//"texture_write"
	};

	const VkFormat				compressedFormats64bit[]						=
	{
		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,
	};

	const VkFormat				compressedFormats128bit[]						=
	{
		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,
	};

	const VkFormat				uncompressedFormats64bit[]						=
	{
		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,	removed as float views can't preserve NAN/INF/Denorm values
		VK_FORMAT_R32G32_UINT,
		VK_FORMAT_R32G32_SINT,
		//VK_FORMAT_R32G32_SFLOAT,			removed as float views can't preserve NAN/INF/Denorm values
		//VK_FORMAT_R64_UINT,				remove from the test it couldn't be used
		//VK_FORMAT_R64_SINT,				remove from the test it couldn't be used
		//VK_FORMAT_R64_SFLOAT,				remove from the test it couldn't be used
	};

	const VkFormat				uncompressedFormats128bit[]						=
	{
		VK_FORMAT_R32G32B32A32_UINT,
		VK_FORMAT_R32G32B32A32_SINT,
		//VK_FORMAT_R32G32B32A32_SFLOAT,	removed as float views can't preserve NAN/INF/Denorm values
		//VK_FORMAT_R64G64_UINT,			remove from the test it couldn't be used
		//VK_FORMAT_R64G64_SINT,			remove from the test it couldn't be used
		//VK_FORMAT_R64G64_SFLOAT,			remove from the test it couldn't be used
	};

	const FormatsArray			formatsCompressedSets[]							=
	{
		{
			compressedFormats64bit,
			DE_LENGTH_OF_ARRAY(compressedFormats64bit)
		},
		{
			compressedFormats128bit,
			DE_LENGTH_OF_ARRAY(compressedFormats128bit)
		},
	};

	// Uncompressed formats - floating point formats should not be used in these
	// tests as they cannot be relied upon to preserve all possible values in the
	// underlying texture data. Refer to the note under the 'VkImageViewCreateInfo'
	// section of the specification.
	const FormatsArray			formatsUncompressedSets[]						=
	{
		{
			uncompressedFormats64bit,
			DE_LENGTH_OF_ARRAY(uncompressedFormats64bit)
		},
		{
			uncompressedFormats128bit,
			DE_LENGTH_OF_ARRAY(uncompressedFormats128bit)
		},
	};

	DE_ASSERT(DE_LENGTH_OF_ARRAY(formatsCompressedSets) == DE_LENGTH_OF_ARRAY(formatsUncompressedSets));

	MovePtr<tcu::TestCaseGroup>	texelViewCompatibleTests							(new tcu::TestCaseGroup(testCtx, "texel_view_compatible", "Texel view compatible cases"));

	for (int shaderType = SHADER_TYPE_COMPUTE; shaderType < SHADER_TYPE_LAST; ++shaderType)
	{
		MovePtr<tcu::TestCaseGroup>	pipelineTypeGroup	(new tcu::TestCaseGroup(testCtx, pipelineName[shaderType].c_str(), ""));

		for (int mipmapTestNdx = 0; mipmapTestNdx < DE_LENGTH_OF_ARRAY(mipmapness); mipmapTestNdx++)
		{
			const bool mipmapTest = mipmapness[mipmapTestNdx];

			MovePtr<tcu::TestCaseGroup>	mipmapTypeGroup	(new tcu::TestCaseGroup(testCtx, mipmanpnessName[mipmapTestNdx].c_str(), ""));

			for (int imageTypeNdx = 0; imageTypeNdx < DE_LENGTH_OF_ARRAY(imageTypes); imageTypeNdx++)
			{
				MovePtr<tcu::TestCaseGroup> imageTypeGroup	(new tcu::TestCaseGroup(testCtx, imageTypes[imageTypeNdx].name.c_str(), ""));
				ImageType					imageType = imageTypes[imageTypeNdx].type;

				for (int operationNdx = OPERATION_IMAGE_LOAD; operationNdx < OPERATION_LAST; ++operationNdx)
				{
					if (shaderType != SHADER_TYPE_FRAGMENT && deInRange32(operationNdx, OPERATION_ATTACHMENT_READ, OPERATION_TEXTURE_WRITE))
						continue;

					if (shaderType != SHADER_TYPE_COMPUTE && deInRange32(operationNdx, OPERATION_IMAGE_LOAD, OPERATION_IMAGE_STORE))
						continue;

					if (imageType == IMAGE_TYPE_3D && (operationNdx == OPERATION_ATTACHMENT_READ || operationNdx == OPERATION_ATTACHMENT_WRITE))
						continue;

					MovePtr<tcu::TestCaseGroup>	imageOperationGroup	(new tcu::TestCaseGroup(testCtx, operationName[operationNdx].c_str(), ""));

					deUint32 depth		= 1u + 2 * (imageType == IMAGE_TYPE_3D);
					deUint32 imageCount	= 2u + (operationNdx == OPERATION_IMAGE_STORE);

					// Iterate through bitness groups (64 bit, 128 bit, etc)
					for (deUint32 formatBitnessGroup = 0; formatBitnessGroup < DE_LENGTH_OF_ARRAY(formatsCompressedSets); ++formatBitnessGroup)
					{
						for (deUint32 formatCompressedNdx = 0; formatCompressedNdx < formatsCompressedSets[formatBitnessGroup].count; ++formatCompressedNdx)
						{
							const VkFormat				formatCompressed			= formatsCompressedSets[formatBitnessGroup].formats[formatCompressedNdx];
							const std::string			compressedFormatGroupName	= getFormatShortString(formatCompressed);
							MovePtr<tcu::TestCaseGroup>	compressedFormatGroup		(new tcu::TestCaseGroup(testCtx, compressedFormatGroupName.c_str(), ""));

							for (deUint32 formatUncompressedNdx = 0; formatUncompressedNdx < formatsUncompressedSets[formatBitnessGroup].count; ++formatUncompressedNdx)
							{
								const VkFormat			formatUncompressed			= formatsUncompressedSets[formatBitnessGroup].formats[formatUncompressedNdx];
								const std::string		uncompressedFormatGroupName	= getFormatShortString(formatUncompressed);

								const TestParameters	parameters					=
								{
									static_cast<Operation>(operationNdx),
									static_cast<ShaderType>(shaderType),
									mipmapTest ? getUnniceResolution(formatCompressed, 1u) : UVec3(64u, 64u, depth),
									1u + 2u * mipmapTest * (imageType != IMAGE_TYPE_3D),		// 1 or 3 if mipmapTest is true but image is not 3d
									imageType,
									formatCompressed,
									formatUncompressed,
									imageCount,
									compressedImageUsageFlags[operationNdx],
									compressedImageViewUsageFlags[operationNdx],
									uncompressedImageUsageFlags[operationNdx],
									mipmapTest,
									VK_FORMAT_R8G8B8A8_UNORM,
									FormatIsASTC(formatCompressed)
								};

								compressedFormatGroup->addChild(new TexelViewCompatibleCase(testCtx, uncompressedFormatGroupName, "", parameters));
							}

							imageOperationGroup->addChild(compressedFormatGroup.release());
						}
					}

					imageTypeGroup->addChild(imageOperationGroup.release());
				}

				mipmapTypeGroup->addChild(imageTypeGroup.release());
			}

			pipelineTypeGroup->addChild(mipmapTypeGroup.release());
		}

		texelViewCompatibleTests->addChild(pipelineTypeGroup.release());
	}

	return texelViewCompatibleTests.release();
}

} // image
} // vkt
