/*------------------------------------------------------------------------
 * 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
 * \brief Tests for mutable images
 *//*--------------------------------------------------------------------*/

#include "vktImageMutableTests.hpp"
#include "vktImageLoadStoreUtil.hpp"
#include "vktTestCaseUtil.hpp"
#include "vktImageTexture.hpp"
#include "vktCustomInstancesDevices.hpp"

#include "vkBuilderUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkRef.hpp"
#include "vkDefs.hpp"
#include "vkPlatform.hpp"
#include "vkWsiUtil.hpp"
#include "vkDeviceUtil.hpp"

#include "deUniquePtr.hpp"
#include "deSharedPtr.hpp"

#include "tcuImageCompare.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuPlatform.hpp"
#include "tcuCommandLine.hpp"

#include <string>
#include <vector>

using namespace vk;
using namespace tcu;
using namespace vk::wsi;

using de::UniquePtr;
using de::MovePtr;
using de::SharedPtr;
using std::vector;
using std::string;

namespace vkt
{
namespace image
{

typedef SharedPtr<Unique<VkPipeline> >	SharedPtrVkPipeline;
typedef SharedPtr<Unique<VkImageView> >	SharedPtrVkImageView;

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

enum Upload {
	UPLOAD_CLEAR = 0,
	UPLOAD_COPY,
	UPLOAD_STORE,
	UPLOAD_DRAW,
	UPLOAD_LAST
};

enum Download {
	DOWNLOAD_COPY = 0,
	DOWNLOAD_LOAD,
	DOWNLOAD_TEXTURE,
	DOWNLOAD_LAST
};

std::string getUploadString (const int upload)
{
	const char* strs[] = { "clear", "copy", "store", "draw" };
	return strs[upload];
}

std::string getDownloadString (const int download)
{
	const char* strs[] = { "copy", "load", "texture" };
	return strs[download];
}

struct CaseDef
{
	ImageType		imageType;
	IVec3			size;
	deUint32		numLayers;
	VkFormat		imageFormat;
	VkFormat		viewFormat;
	enum Upload		upload;
	enum Download	download;
	bool			isFormatListTest;
	bool			isSwapchainImageTest;
	Type			wsiType;
};

static const deUint32 COLOR_TABLE_SIZE = 4;

// Reference color values for float color rendering. Values have been chosen
// so that when the bit patterns are reinterpreted as a 16-bit float, we do not
// run into NaN / inf / denorm values.
static const Vec4	COLOR_TABLE_FLOAT[COLOR_TABLE_SIZE]	=
{
	Vec4(0.00f, 0.40f, 0.80f, 0.10f),
	Vec4(0.50f, 0.10f, 0.90f, 0.20f),
	Vec4(0.20f, 0.60f, 1.00f, 0.30f),
	Vec4(0.30f, 0.70f, 0.00f, 0.40f),
};

// Reference color values for integer color rendering. We avoid negative
// values (even for SINT formats) to avoid the situation where sign extension
// leads to NaN / inf values when they are reinterpreted with a float
// format.
static const IVec4	COLOR_TABLE_INT[COLOR_TABLE_SIZE]	=
{
	IVec4(0x70707070, 0x3C3C3C3C, 0x65656565, 0x29292929),
	IVec4(0x3C3C3C3C, 0x65656565, 0x29292929, 0x70707070),
	IVec4(0x29292929, 0x70707070, 0x3C3C3C3C, 0x65656565),
	IVec4(0x65656565, 0x29292929, 0x70707070, 0x3C3C3C3C),
};

// Reference clear colors created from the color table values
static const VkClearValue REFERENCE_CLEAR_COLOR_FLOAT[COLOR_TABLE_SIZE]	=
{
	makeClearValueColorF32(COLOR_TABLE_FLOAT[0].x(), COLOR_TABLE_FLOAT[0].y(), COLOR_TABLE_FLOAT[0].z(), COLOR_TABLE_FLOAT[0].w()),
	makeClearValueColorF32(COLOR_TABLE_FLOAT[1].x(), COLOR_TABLE_FLOAT[1].y(), COLOR_TABLE_FLOAT[1].z(), COLOR_TABLE_FLOAT[1].w()),
	makeClearValueColorF32(COLOR_TABLE_FLOAT[2].x(), COLOR_TABLE_FLOAT[2].y(), COLOR_TABLE_FLOAT[2].z(), COLOR_TABLE_FLOAT[2].w()),
	makeClearValueColorF32(COLOR_TABLE_FLOAT[3].x(), COLOR_TABLE_FLOAT[3].y(), COLOR_TABLE_FLOAT[3].z(), COLOR_TABLE_FLOAT[3].w()),
};

static const Texture s_textures[] =
{
	Texture(IMAGE_TYPE_2D,			tcu::IVec3(32, 32, 1),	1),
	Texture(IMAGE_TYPE_2D_ARRAY,	tcu::IVec3(32, 32, 1),	4),
};

static VkClearValue getClearValueInt(const CaseDef& caseDef, deUint32 colorTableIndex)
{
	VkClearValue		clearValue;
	deUint32			channelMask	= 0;

	if (caseDef.upload == UPLOAD_DRAW)
	{
		// We use this mask to get small color values in the vertex buffer and
		// avoid possible round off errors from int-to-float conversions.
		channelMask = 0xFFu;
	}
	else
	{
		VkFormat			format;
		tcu::TextureFormat	tcuFormat;

		// Select a mask such that no integer-based color values end up
		// reinterpreted as NaN/Inf/denorm values.
		if (caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY)
			format = caseDef.imageFormat;
		else
			format = caseDef.viewFormat;

		tcuFormat = mapVkFormat(format);

		switch (getChannelSize(tcuFormat.type))
		{
			case 1: // 8-bit
				channelMask = 0xFFu;
				break;
			case 2: // 16-bit
				channelMask = 0xFFFFu;
				break;
			case 4: // 32-bit
				channelMask = 0xFFFFFFFFu;
				break;
			default:
				DE_ASSERT(0);
		}
	}

	clearValue.color.int32[0] = COLOR_TABLE_INT[colorTableIndex].x() & channelMask;
	clearValue.color.int32[1] = COLOR_TABLE_INT[colorTableIndex].y() & channelMask;
	clearValue.color.int32[2] = COLOR_TABLE_INT[colorTableIndex].z() & channelMask;
	clearValue.color.int32[3] = COLOR_TABLE_INT[colorTableIndex].w() & channelMask;

	return clearValue;
}

VkImageType getImageType (const ImageType textureImageType)
{
	switch (textureImageType)
	{
		case IMAGE_TYPE_2D:
		case IMAGE_TYPE_2D_ARRAY:
			return VK_IMAGE_TYPE_2D;

		default:
			DE_ASSERT(0);
			return VK_IMAGE_TYPE_LAST;
	}
}

VkImageViewType getImageViewType (const ImageType textureImageType)
{
	switch (textureImageType)
	{
		case IMAGE_TYPE_2D:
			return VK_IMAGE_VIEW_TYPE_2D;
		case IMAGE_TYPE_2D_ARRAY:
			return VK_IMAGE_VIEW_TYPE_2D_ARRAY;

		default:
			DE_ASSERT(0);
			return VK_IMAGE_VIEW_TYPE_LAST;
	}
}

static const VkFormat s_formats[] =
{
	VK_FORMAT_R32G32B32A32_SFLOAT,
	VK_FORMAT_R16G16B16A16_SFLOAT,
	VK_FORMAT_R32G32_SFLOAT,
	VK_FORMAT_R16G16_SFLOAT,
	VK_FORMAT_R32_SFLOAT,

	VK_FORMAT_R32G32B32A32_UINT,
	VK_FORMAT_R16G16B16A16_UINT,
	VK_FORMAT_R8G8B8A8_UINT,
	VK_FORMAT_R32G32_UINT,
	VK_FORMAT_R16G16_UINT,
	VK_FORMAT_R32_UINT,

	VK_FORMAT_R32G32B32A32_SINT,
	VK_FORMAT_R16G16B16A16_SINT,
	VK_FORMAT_R8G8B8A8_SINT,
	VK_FORMAT_R32G32_SINT,
	VK_FORMAT_R16G16_SINT,
	VK_FORMAT_R32_SINT,

	VK_FORMAT_R8G8B8A8_UNORM,
	VK_FORMAT_R8G8B8A8_SNORM,
	VK_FORMAT_R8G8B8A8_SRGB,
	VK_FORMAT_B8G8R8A8_UNORM,
	VK_FORMAT_B8G8R8A8_SNORM,
	VK_FORMAT_B8G8R8A8_SRGB,
};

static const VkFormat s_swapchainFormats[] =
{
	VK_FORMAT_R8G8B8A8_UNORM,
	VK_FORMAT_R8G8B8A8_SNORM,
	VK_FORMAT_R8G8B8A8_SRGB,
	VK_FORMAT_B8G8R8A8_UNORM,
	VK_FORMAT_B8G8R8A8_SNORM,
	VK_FORMAT_B8G8R8A8_SRGB,
};

bool isSRGBConversionRequired(const CaseDef& caseDef)
{
	bool required = false;

	if (isSRGB(mapVkFormat(caseDef.imageFormat)))
	{
		if (caseDef.upload == UPLOAD_CLEAR)
		{
			required = true;
		}
	}

	if (isSRGB(mapVkFormat(caseDef.viewFormat)))
	{
		if (caseDef.upload == UPLOAD_DRAW || caseDef.upload == UPLOAD_STORE)
		{
			required = true;
		}
	}

	return required;
}


inline bool formatsAreCompatible (const VkFormat format0, const VkFormat format1)
{
	return format0 == format1 || mapVkFormat(format0).getPixelSize() == mapVkFormat(format1).getPixelSize();
}

std::string getColorFormatStr (const int numComponents, const bool isUint, const bool isSint)
{
	std::ostringstream str;
	if (numComponents == 1)
		str << (isUint ? "uint" : isSint ? "int" : "float");
	else
		str << (isUint ? "u" : isSint ? "i" : "") << "vec" << numComponents;

	return str.str();
}

std::string getShaderSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
{
	std::ostringstream samplerType;

	if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
		samplerType << "u";
	else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
		samplerType << "i";

	switch (type)
	{
		case VK_IMAGE_VIEW_TYPE_2D:
			samplerType << "sampler2D";
			break;

		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
			samplerType << "sampler2DArray";
			break;

		default:
			DE_FATAL("Ivalid image view type");
			break;
	}

	return samplerType.str();
}

void initPrograms (SourceCollections& programCollection, const CaseDef caseDef)
{
	if (caseDef.upload == UPLOAD_DRAW)
	{
		{
			std::ostringstream src;
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "\n"
				<< "layout(location = 0) in  vec4 in_position;\n"
				<< "layout(location = 1) in  vec4 in_color;\n"
				<< "layout(location = 0) out vec4 out_color;\n"
				<< "\n"
				<< "out gl_PerVertex {\n"
				<< "	vec4 gl_Position;\n"
				<< "};\n"
				<< "\n"
				<< "void main(void)\n"
				<< "{\n"
				<< "	gl_Position	= in_position;\n"
				<< "	out_color	= in_color;\n"
				<< "}\n";

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

		{
			const int	numComponents		= getNumUsedChannels(mapVkFormat(caseDef.viewFormat).order);
			const bool	isUint				= isUintFormat(caseDef.viewFormat);
			const bool	isSint				= isIntFormat(caseDef.viewFormat);
			const std::string colorFormat	= getColorFormatStr(numComponents, isUint, isSint);

			std::ostringstream src;
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "\n"
				<< "layout(location = 0) in  vec4 in_color;\n"
				<< "layout(location = 0) out " << colorFormat << " out_color;\n"
				<< "\n"
				<< "void main(void)\n"
				<< "{\n"
				<< "    out_color = " << colorFormat << "("
				<< (numComponents == 1 ? "in_color.r"   :
					numComponents == 2 ? "in_color.rg"  :
					numComponents == 3 ? "in_color.rgb" : "in_color")
				<< ");\n"
				<< "}\n";

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

	if (caseDef.upload == UPLOAD_STORE)
	{
		const TextureFormat	tcuFormat		= mapVkFormat(caseDef.viewFormat);
		const std::string	imageFormatStr	= getShaderImageFormatQualifier(tcuFormat);
		const std::string	imageTypeStr	= getShaderImageType(tcuFormat, caseDef.imageType);
		const std::string	colorTypeStr	= isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
		const bool			isIntegerFormat	= isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat);

		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
			<< "\n"
			<< "layout (local_size_x = 1) in;\n"
			<< "\n"
			<< "layout(binding=0, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " u_image;\n"
			<< "\n"
			<< "const " << colorTypeStr << " colorTable[] = " << colorTypeStr << "[](\n";
		for (deUint32 idx = 0; idx < COLOR_TABLE_SIZE; idx++)
		{
			if (isIntegerFormat)
			{
				const VkClearValue	clearValue	= getClearValueInt(caseDef, idx);

				src << "     " << colorTypeStr << "(" << clearValue.color.int32[0] << ", " << clearValue.color.int32[1] << ", " << clearValue.color.int32[2] << ", " << clearValue.color.int32[3] << ")";
			}
			else
				src << "     " << colorTypeStr << "(" << COLOR_TABLE_FLOAT[idx].x() << ", " << COLOR_TABLE_FLOAT[idx].y() << ", " << COLOR_TABLE_FLOAT[idx].z() << ", " << COLOR_TABLE_FLOAT[idx].w() << ")";
			if (idx < COLOR_TABLE_SIZE - 1)
				src << ",";
			src << "\n";
		}
		src << ");\n"
			<< "\n"
			<< "void main(void)\n"
			<< "{\n";
		if (caseDef.imageType == IMAGE_TYPE_2D)
		{
			src	<< "    ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
		}
		else
		{
			DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
			src	<< "    ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
		}
		src << "    " << colorTypeStr << " color = colorTable[gl_GlobalInvocationID.z];\n"
			<< "    imageStore(u_image, pos, color);\n"
			<< "}\n";

		programCollection.glslSources.add("uploadStoreComp") << glu::ComputeSource(src.str());
	}

	if (caseDef.download == DOWNLOAD_LOAD)
	{
		const TextureFormat	tcuFormat		= mapVkFormat(caseDef.viewFormat);
		const std::string	imageFormatStr	= getShaderImageFormatQualifier(tcuFormat);
		const std::string	imageTypeStr	= getShaderImageType(tcuFormat, caseDef.imageType);
		const std::string	colorTypeStr	= isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";

		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
			<< "\n"
			<< "layout (local_size_x = 1) in;\n"
			<< "\n"
			<< "layout(binding=0, " << imageFormatStr << ") readonly uniform " << imageTypeStr << " in_image;\n"
			<< "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n"
			<< "\n"
			<< "void main(void)\n"
			<< "{\n";
		if (caseDef.imageType == IMAGE_TYPE_2D)
		{
			src	<< "    ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
		}
		else
		{
			DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
			src	<< "    ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
		}
		src	<< "    imageStore(out_image, pos, imageLoad(in_image, pos));\n"
			<< "}\n";

		programCollection.glslSources.add("downloadLoadComp") << glu::ComputeSource(src.str());
	}

	if (caseDef.download == DOWNLOAD_TEXTURE)
	{
		const TextureFormat		tcuFormat		= mapVkFormat(caseDef.viewFormat);
		const VkImageViewType	viewType		= getImageViewType(caseDef.imageType);
		const std::string		samplerTypeStr	= getShaderSamplerType(tcuFormat, viewType);
		const std::string		imageFormatStr	= getShaderImageFormatQualifier(tcuFormat);
		const std::string		imageTypeStr	= getShaderImageType(tcuFormat, caseDef.imageType);
		const std::string		colorTypeStr	= isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";

		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
			<< "\n"
			<< "layout (local_size_x = 1) in;\n"
			<< "\n"
			<< "layout(binding=0) uniform " << samplerTypeStr << " u_tex;\n"
			<< "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n"
			<< "\n"
			<< "void main(void)\n"
			<< "{\n";
		if (caseDef.imageType == IMAGE_TYPE_2D)
		{
			src	<< "    ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
		}
		else
		{
			DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
			src	<< "    ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
		}
		src	<< "    imageStore(out_image, pos, texelFetch(u_tex, pos, 0));\n"
			<< "}\n";

		programCollection.glslSources.add("downloadTextureComp") << glu::ComputeSource(src.str());
	}
}

Move<VkImage> makeImage (const DeviceInterface&		vk,
						 const VkDevice				device,
						 VkImageCreateFlags			flags,
						 VkImageType				imageType,
						 const VkFormat				format,
						 const VkFormat				viewFormat,
						 const bool					useImageFormatList,
						 const IVec3&				size,
						 const deUint32				numMipLevels,
						 const deUint32				numLayers,
						 const VkImageUsageFlags	usage)
{
	const VkFormat formatList[2] =
	{
		format,
		viewFormat
	};

	const VkImageFormatListCreateInfoKHR formatListInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR,	// VkStructureType			sType;
		DE_NULL,												// const void*				pNext;
		2u,														// deUint32					viewFormatCount
		formatList												// const VkFormat*			pViewFormats
	};

	const VkImageCreateInfo imageParams =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,					// VkStructureType			sType;
		useImageFormatList ? &formatListInfo : DE_NULL,			// const void*				pNext;
		flags,													// VkImageCreateFlags		flags;
		imageType,												// VkImageType				imageType;
		format,													// VkFormat					format;
		makeExtent3D(size),										// VkExtent3D				extent;
		numMipLevels,											// deUint32					mipLevels;
		numLayers,												// deUint32					arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits	samples;
		VK_IMAGE_TILING_OPTIMAL,								// VkImageTiling			tiling;
		usage,													// VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,								// VkSharingMode			sharingMode;
		0u,														// deUint32					queueFamilyIndexCount;
		DE_NULL,												// const deUint32*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout			initialLayout;
	};
	return createImage(vk, device, &imageParams);
}

inline VkImageSubresourceRange makeColorSubresourceRange (const int baseArrayLayer, const int layerCount)
{
	return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, static_cast<deUint32>(baseArrayLayer), static_cast<deUint32>(layerCount));
}

Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice device)
{
	const VkSamplerCreateInfo samplerParams =
	{
		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		(VkSamplerCreateFlags)0,					// 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_ALWAYS,						// VkCompareOp				compareOp;
		0.0f,										// float					minLod;
		0.0f,										// float					maxLod;
		VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,	// VkBorderColor			borderColor;
		VK_FALSE,									// VkBool32					unnormalizedCoordinates;
	};

	return createSampler(vk, device, &samplerParams);
}

Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&		vk,
									   const VkDevice				device,
									   const VkPipelineLayout		pipelineLayout,
									   const VkRenderPass			renderPass,
									   const VkShaderModule			vertexModule,
									   const VkShaderModule			fragmentModule,
									   const IVec2&					renderSize,
									   const VkPrimitiveTopology	topology,
									   const deUint32				subpass)
{
	const std::vector<VkViewport>			viewports							(1, makeViewport(renderSize));
	const std::vector<VkRect2D>				scissors							(1, makeRect2D(renderSize));

	const VkVertexInputBindingDescription	vertexInputBindingDescription		=
	{
		0u,									// deUint32				binding;
		(deUint32)(2 * sizeof(Vec4)),		// deUint32				stride;
		VK_VERTEX_INPUT_RATE_VERTEX,		// VkVertexInputRate	inputRate;
	};

	const VkVertexInputAttributeDescription	vertexInputAttributeDescriptions[]	=
	{
		{
			0u,								// deUint32			location;
			0u,								// deUint32			binding;
			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat			format;
			0u,								// deUint32			offset;
		},
		{
			1u,								// deUint32			location;
			0u,								// deUint32			binding;
			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat			format;
			(deUint32)sizeof(Vec4),			// deUint32			offset;
		}
	};

	const VkPipelineVertexInputStateCreateInfo	vertexInputStateCreateInfo	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType                             sType;
		DE_NULL,													// const void*                                 pNext;
		(VkPipelineVertexInputStateCreateFlags)0,					// VkPipelineVertexInputStateCreateFlags       flags;
		1u,															// deUint32                                    vertexBindingDescriptionCount;
		&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
		2u,															// deUint32                                    vertexAttributeDescriptionCount;
		vertexInputAttributeDescriptions							// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
	};

	return vk::makeGraphicsPipeline(vk,									// const DeviceInterface&                        vk
									device,								// const VkDevice                                device
									pipelineLayout,						// const VkPipelineLayout                        pipelineLayout
									vertexModule,						// const VkShaderModule                          vertexShaderModule
									DE_NULL,							// const VkShaderModule                          tessellationControlModule
									DE_NULL,							// const VkShaderModule                          tessellationEvalModule
									DE_NULL,							// const VkShaderModule                          geometryShaderModule
									fragmentModule,						// const VkShaderModule                          fragmentShaderModule
									renderPass,							// const VkRenderPass                            renderPass
									viewports,							// const std::vector<VkViewport>&                viewports
									scissors,							// const std::vector<VkRect2D>&                  scissors
									topology,							// const VkPrimitiveTopology                     topology
									subpass,							// const deUint32                                subpass
									0u,									// const deUint32                                patchControlPoints
									&vertexInputStateCreateInfo);		// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
}

Move<VkPipeline> makeComputePipeline (const DeviceInterface&		vk,
									  const VkDevice				device,
									  const VkPipelineLayout		pipelineLayout,
									  const VkShaderModule			shaderModule,
									  const VkSpecializationInfo*	specInfo)
{
	const VkPipelineShaderStageCreateInfo shaderStageInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType					sType;
		DE_NULL,												// const void*						pNext;
		(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags	flags;
		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits			stage;
		shaderModule,											// VkShaderModule					module;
		"main",													// const char*						pName;
		specInfo,												// const VkSpecializationInfo*		pSpecializationInfo;
	};
	const VkComputePipelineCreateInfo pipelineInfo =
	{
		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,			// VkStructureType					sType;
		DE_NULL,												// const void*						pNext;
		(VkPipelineCreateFlags)0,								// VkPipelineCreateFlags			flags;
		shaderStageInfo,										// VkPipelineShaderStageCreateInfo	stage;
		pipelineLayout,											// VkPipelineLayout					layout;
		DE_NULL,												// VkPipeline						basePipelineHandle;
		0,														// deInt32							basePipelineIndex;
	};
	return createComputePipeline(vk, device, DE_NULL , &pipelineInfo);
}

Move<VkRenderPass> makeRenderPass (const DeviceInterface&	vk,
								   const VkDevice			device,
								   const VkFormat			colorFormat,
								   const deUint32			numLayers)
{
	const VkAttachmentDescription colorAttachmentDescription =
	{
		(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
		colorFormat,										// VkFormat							format;
		VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
		VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
		VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
		VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					initialLayout;
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					finalLayout;
	};
	vector<VkAttachmentDescription> attachmentDescriptions(numLayers, colorAttachmentDescription);

	// Create a subpass for each attachment (each attachement is a layer of an arrayed image).
	vector<VkAttachmentReference>	colorAttachmentReferences	(numLayers);
	vector<VkSubpassDescription>	subpasses;

	// Ordering here must match the framebuffer attachments
	for (deUint32 i = 0; i < numLayers; ++i)
	{
		const VkAttachmentReference attachmentRef =
		{
			i,													// deUint32			attachment;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
		};

		colorAttachmentReferences[i]	= attachmentRef;

		const VkSubpassDescription		subpassDescription	=
		{
			(VkSubpassDescriptionFlags)0,					// VkSubpassDescriptionFlags		flags;
			VK_PIPELINE_BIND_POINT_GRAPHICS,				// VkPipelineBindPoint				pipelineBindPoint;
			0u,												// deUint32							inputAttachmentCount;
			DE_NULL,										// const VkAttachmentReference*		pInputAttachments;
			1u,												// deUint32							colorAttachmentCount;
			&colorAttachmentReferences[i],					// const VkAttachmentReference*		pColorAttachments;
			DE_NULL,										// const VkAttachmentReference*		pResolveAttachments;
			DE_NULL,										// const VkAttachmentReference*		pDepthStencilAttachment;
			0u,												// deUint32							preserveAttachmentCount;
			DE_NULL											// const deUint32*					pPreserveAttachments;
		};
		subpasses.push_back(subpassDescription);
	}

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

	return createRenderPass(vk, device, &renderPassInfo);
}

Move<VkCommandBuffer> makeCommandBuffer	(const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
{
	return allocateCommandBuffer(vk, device, commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
}

vector<Vec4> genVertexData (const CaseDef& caseDef)
{
	vector<Vec4>	vectorData;
	const bool		isIntegerFormat	= isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat);

	for (deUint32 z = 0; z < caseDef.numLayers; z++)
	{
		const deUint32	colorIdx	= z % COLOR_TABLE_SIZE;
		Vec4			color;

		if (isIntegerFormat)
		{
			const VkClearValue	clearValue	= getClearValueInt(caseDef, colorIdx);
			const IVec4			colorInt	(clearValue.color.int32[0], clearValue.color.int32[1], clearValue.color.int32[2], clearValue.color.int32[3]);

			color = colorInt.cast<float>();
		}
		else
		{
			color = COLOR_TABLE_FLOAT[colorIdx];
		}

		vectorData.push_back(Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
		vectorData.push_back(color);
		vectorData.push_back(Vec4(-1.0f,  1.0f, 0.0f, 1.0f));
		vectorData.push_back(color);
		vectorData.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
		vectorData.push_back(color);
		vectorData.push_back(Vec4( 1.0f,  1.0f, 0.0f, 1.0f));
		vectorData.push_back(color);
	}

	return vectorData;
}

void generateExpectedImage(const tcu::PixelBufferAccess& image, const CaseDef& caseDef)
{
	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(image.getFormat().type);
	const bool						isIntegerFormat	= channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
	const IVec2						size			= caseDef.size.swizzle(0, 1);

	for (int z = 0; z < static_cast<int>(caseDef.numLayers); z++)
	{
		const deUint32	colorIdx	= z % COLOR_TABLE_SIZE;
		for (int y = 0; y < size.y(); y++)
		for (int x = 0; x < size.x(); x++)
		{
			if (isIntegerFormat)
			{
				const VkClearValue	clearValue	= getClearValueInt(caseDef, colorIdx);
				const IVec4			colorInt	(clearValue.color.int32[0], clearValue.color.int32[1], clearValue.color.int32[2], clearValue.color.int32[3]);

				image.setPixel(colorInt, x, y, z);
			}
			else
				if(isSRGBConversionRequired(caseDef))
					image.setPixel(tcu::linearToSRGB(COLOR_TABLE_FLOAT[colorIdx]), x, y, z);
				else
					image.setPixel(COLOR_TABLE_FLOAT[colorIdx], x, y, z);
		}
	}
}

VkImageUsageFlags getImageUsageForTestCase (const CaseDef& caseDef)
{
	VkImageUsageFlags flags = 0u;

	switch (caseDef.upload)
	{
	case UPLOAD_CLEAR:
		flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
		break;
	case UPLOAD_DRAW:
		flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
		break;
	case UPLOAD_STORE:
		flags |= VK_IMAGE_USAGE_STORAGE_BIT;
		break;
	case UPLOAD_COPY:
		flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
		break;
	default:
		DE_FATAL("Invalid upload method");
		break;
	}

	switch (caseDef.download)
	{
	case DOWNLOAD_TEXTURE:
		flags |= VK_IMAGE_USAGE_SAMPLED_BIT;
		break;
	case DOWNLOAD_LOAD:
		flags |= VK_IMAGE_USAGE_STORAGE_BIT;
		break;
	case DOWNLOAD_COPY:
		flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
		break;
	default:
		DE_FATAL("Invalid download method");
		break;
	}

	// We can only create a view for the image if it is going to be used for any of these usages,
	// so let's make sure that we have at least one of them.
	VkImageUsageFlags viewRequiredFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
	if (!(flags & viewRequiredFlags))
		flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;

	return flags;
}

// Executes a combination of upload/download methods
class UploadDownloadExecutor
{
public:
	UploadDownloadExecutor(Context& context, VkDevice device, VkQueue queue, deUint32 queueFamilyIndex, const CaseDef& caseSpec) :
	m_caseDef(caseSpec),
	m_haveMaintenance2(context.isDeviceFunctionalitySupported("VK_KHR_maintenance2")),
	m_vk(context.getDeviceInterface()),
	m_device(device),
	m_queue(queue),
	m_queueFamilyIndex(queueFamilyIndex),
	m_allocator(context.getDeviceInterface(), device,
		    getPhysicalDeviceMemoryProperties(context.getInstanceInterface(),
						      context.getPhysicalDevice()))
	{
	}

	void runSwapchain(Context& context, VkBuffer buffer, VkImage image);

	void run(Context& context, VkBuffer buffer);

private:
	void uploadClear(Context& context);
	void uploadStore(Context& context);
	void uploadCopy(Context& context);
	void uploadDraw(Context& context);
	void downloadCopy(Context& context, VkBuffer buffer);
	void downloadTexture(Context& context, VkBuffer buffer);
	void downloadLoad(Context& context, VkBuffer buffer);

	void copyImageToBuffer(VkImage				image,
						   VkBuffer				buffer,
						   const IVec3			size,
						   const VkAccessFlags	srcAccessMask,
						   const VkImageLayout	oldLayout,
						   const deUint32		numLayers);

	const CaseDef&						m_caseDef;

	bool								m_haveMaintenance2;

	const DeviceInterface&				m_vk;
	const VkDevice						m_device;
	const VkQueue						m_queue;
	const deUint32						m_queueFamilyIndex;
	SimpleAllocator						m_allocator;

	Move<VkCommandPool>					m_cmdPool;
	Move<VkCommandBuffer>				m_cmdBuffer;

	bool								m_imageIsIntegerFormat;
	bool								m_viewIsIntegerFormat;

	// Target image for upload paths
	VkImage								m_image;
	Move<VkImage>						m_imageHolder;
	MovePtr<Allocation>					m_imageAlloc;

	// Upload copy
	struct
	{
		Move<VkBuffer>					colorBuffer;
		VkDeviceSize					colorBufferSize;
		MovePtr<Allocation>				colorBufferAlloc;
	} m_uCopy;

	// Upload draw
	struct
	{
		Move<VkBuffer>					vertexBuffer;
		MovePtr<Allocation>				vertexBufferAlloc;
		Move<VkPipelineLayout>			pipelineLayout;
		Move<VkRenderPass>				renderPass;
		Move<VkShaderModule>			vertexModule;
		Move<VkShaderModule>			fragmentModule;
		vector<SharedPtrVkImageView>	attachments;
		vector<VkImageView>				attachmentHandles;
		vector<SharedPtrVkPipeline>		pipelines;
		Move<VkFramebuffer>				framebuffer;
	} m_uDraw;

	// Upload store
	struct
	{
		Move<VkDescriptorPool>			descriptorPool;
		Move<VkPipelineLayout>			pipelineLayout;
		Move<VkDescriptorSetLayout>		descriptorSetLayout;
		Move<VkDescriptorSet>			descriptorSet;
		VkDescriptorImageInfo			imageDescriptorInfo;
		Move<VkShaderModule>			computeModule;
		Move<VkPipeline>				computePipeline;
		Move<VkImageView>				imageView;
	} m_uStore;

	// Download load
	struct
	{
		Move<VkDescriptorPool>			descriptorPool;
		Move<VkPipelineLayout>			pipelineLayout;
		Move<VkDescriptorSetLayout>		descriptorSetLayout;
		Move<VkDescriptorSet>			descriptorSet;
		Move<VkShaderModule>			computeModule;
		Move<VkPipeline>				computePipeline;
		Move<VkImageView>				inImageView;
		VkDescriptorImageInfo			inImageDescriptorInfo;
		Move<VkImage>					outImage;
		Move<VkImageView>				outImageView;
		MovePtr<Allocation>				outImageAlloc;
		VkDescriptorImageInfo			outImageDescriptorInfo;
	} m_dLoad;

	// Download texture
	struct
	{
		Move<VkDescriptorPool>			descriptorPool;
		Move<VkPipelineLayout>			pipelineLayout;
		Move<VkDescriptorSetLayout>		descriptorSetLayout;
		Move<VkDescriptorSet>			descriptorSet;
		Move<VkShaderModule>			computeModule;
		Move<VkPipeline>				computePipeline;
		Move<VkImageView>				inImageView;
		VkDescriptorImageInfo			inImageDescriptorInfo;
		Move<VkSampler>					sampler;
		Move<VkImage>					outImage;
		Move<VkImageView>				outImageView;
		MovePtr<Allocation>				outImageAlloc;
		VkDescriptorImageInfo			outImageDescriptorInfo;
	} m_dTex;

	VkImageLayout						m_imageLayoutAfterUpload;
	VkAccessFlagBits					m_imageUploadAccessMask;
};


void UploadDownloadExecutor::runSwapchain(Context& context, VkBuffer buffer, VkImage image)
{
	m_imageIsIntegerFormat = isUintFormat(m_caseDef.imageFormat) || isIntFormat(m_caseDef.imageFormat);
	m_viewIsIntegerFormat = isUintFormat(m_caseDef.viewFormat) || isIntFormat(m_caseDef.viewFormat);

	m_cmdPool = createCommandPool(m_vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_queueFamilyIndex);
	m_cmdBuffer = makeCommandBuffer(m_vk, m_device, *m_cmdPool);
	beginCommandBuffer(m_vk, *m_cmdBuffer);

	m_image = image;

	switch (m_caseDef.upload)
	{
	case UPLOAD_DRAW:
		uploadDraw(context);
		break;
	case UPLOAD_STORE:
		uploadStore(context);
		break;
	case UPLOAD_CLEAR:
		uploadClear(context);
		break;
	case UPLOAD_COPY:
		uploadCopy(context);
		break;
	default:
		DE_FATAL("Unsupported upload method");
	}

	switch (m_caseDef.download)
	{
	case DOWNLOAD_COPY:
		downloadCopy(context, buffer);
		break;
	case DOWNLOAD_LOAD:
		downloadLoad(context, buffer);
		break;
	case DOWNLOAD_TEXTURE:
		downloadTexture(context, buffer);
		break;
	default:
		DE_FATAL("Unsupported download method");
	}

	endCommandBuffer(m_vk, *m_cmdBuffer);
	submitCommandsAndWait(m_vk, m_device, m_queue, *m_cmdBuffer);

}

void UploadDownloadExecutor::run(Context& context, VkBuffer buffer)
{
	m_imageIsIntegerFormat	= isUintFormat(m_caseDef.imageFormat) || isIntFormat(m_caseDef.imageFormat);
	m_viewIsIntegerFormat	= isUintFormat(m_caseDef.viewFormat) || isIntFormat(m_caseDef.viewFormat);

	m_cmdPool				= createCommandPool(m_vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_queueFamilyIndex);
	m_cmdBuffer				= makeCommandBuffer(m_vk, m_device, *m_cmdPool);
	beginCommandBuffer(m_vk, *m_cmdBuffer);

	const VkImageUsageFlags		imageUsage	= getImageUsageForTestCase(m_caseDef);
	const VkImageCreateFlags	imageFlags	= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | (m_haveMaintenance2 ? VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR : 0);

	m_imageHolder							= makeImage(m_vk, m_device, imageFlags, getImageType(m_caseDef.imageType), m_caseDef.imageFormat, m_caseDef.viewFormat,
														m_caseDef.isFormatListTest, m_caseDef.size, 1u, m_caseDef.numLayers, imageUsage);
	m_image									= *m_imageHolder;
	m_imageAlloc							= bindImage(m_vk, m_device, m_allocator, m_image, MemoryRequirement::Any);

	switch (m_caseDef.upload)
	{
	case UPLOAD_DRAW:
		uploadDraw(context);
		break;
	case UPLOAD_STORE:
		uploadStore(context);
		break;
	case UPLOAD_CLEAR:
		uploadClear(context);
		break;
	case UPLOAD_COPY:
		uploadCopy(context);
		break;
	default:
		DE_FATAL("Unsupported upload method");
	}

	switch (m_caseDef.download)
	{
	case DOWNLOAD_COPY:
		downloadCopy(context, buffer);
		break;
	case DOWNLOAD_LOAD:
		downloadLoad(context, buffer);
		break;
	case DOWNLOAD_TEXTURE:
		downloadTexture(context, buffer);
		break;
	default:
		DE_FATAL("Unsupported download method");
	}

	endCommandBuffer(m_vk, *m_cmdBuffer);
	submitCommandsAndWait(m_vk, m_device, m_queue, *m_cmdBuffer);
}

void UploadDownloadExecutor::uploadClear(Context& context)
{
	(void) context;

	VkImageLayout					requiredImageLayout	= VK_IMAGE_LAYOUT_GENERAL;

	const VkImageSubresourceRange	subresourceRange	= makeColorSubresourceRange(0, m_caseDef.numLayers);
	const VkImageMemoryBarrier		imageInitBarrier	=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
		DE_NULL,										// const void*				pNext;
		0u,												// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAcessMask;
		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
		requiredImageLayout,							// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32					destQueueFamilyIndex;
		m_image,										// VkImage					image;
		subresourceRange								// VkImageSubresourceRange	subresourceRange;
	};

	m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
		0u, DE_NULL, 0u, DE_NULL, 1u, &imageInitBarrier);

	for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++)
	{
		const VkImageSubresourceRange	layerSubresourceRange	= makeColorSubresourceRange(layer, 1u);
		const deUint32					colorIdx				= layer % COLOR_TABLE_SIZE;
		const VkClearColorValue			clearColor				= m_imageIsIntegerFormat ? getClearValueInt(m_caseDef, colorIdx).color : REFERENCE_CLEAR_COLOR_FLOAT[colorIdx].color;
		m_vk.cmdClearColorImage(*m_cmdBuffer, m_image, requiredImageLayout, &clearColor, 1u, &layerSubresourceRange);
	}

	m_imageLayoutAfterUpload	= requiredImageLayout;
	m_imageUploadAccessMask		= VK_ACCESS_TRANSFER_WRITE_BIT;
}

void UploadDownloadExecutor::uploadStore(Context& context)
{
	const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR,	// VkStructureType		sType
		DE_NULL,											// const void*			pNext
		VK_IMAGE_USAGE_STORAGE_BIT,							// VkImageUsageFlags	usage;
	};
	m_uStore.imageView				= makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
													makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);

	// Setup compute pipeline
	m_uStore.descriptorPool			= DescriptorPoolBuilder()
		.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
		.build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);

	m_uStore.descriptorSetLayout	= DescriptorSetLayoutBuilder()
		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
		.build(m_vk, m_device);

	m_uStore.pipelineLayout			= makePipelineLayout(m_vk, m_device, *m_uStore.descriptorSetLayout);
	m_uStore.descriptorSet			= makeDescriptorSet(m_vk, m_device, *m_uStore.descriptorPool, *m_uStore.descriptorSetLayout);
	m_uStore.imageDescriptorInfo	= makeDescriptorImageInfo(DE_NULL, *m_uStore.imageView, VK_IMAGE_LAYOUT_GENERAL);
	m_uStore.computeModule			= createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadStoreComp"), 0);
	m_uStore.computePipeline		= makeComputePipeline(m_vk, m_device, *m_uStore.pipelineLayout, *m_uStore.computeModule, DE_NULL);

	DescriptorSetUpdateBuilder()
		.writeSingle(*m_uStore.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_uStore.imageDescriptorInfo)
		.update(m_vk, m_device);

	// Transition storage image for shader access (imageStore)
	VkImageLayout requiredImageLayout	= VK_IMAGE_LAYOUT_GENERAL;
	const VkImageMemoryBarrier imageBarrier	=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
		DE_NULL,											// const void*				pNext;
		(VkAccessFlags)0,									// VkAccessFlags			srcAccessMask;
		(VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
		requiredImageLayout,								// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,							// deUint32					destQueueFamilyIndex;
		m_image,											// VkImage					image;
		makeColorSubresourceRange(0, m_caseDef.numLayers),	// VkImageSubresourceRange	subresourceRange;
	};

	m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
		0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);

	// Dispatch
	m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.computePipeline);
	m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.pipelineLayout, 0u, 1u, &m_uStore.descriptorSet.get(), 0u, DE_NULL);
	m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);

	m_imageLayoutAfterUpload	= requiredImageLayout;
	m_imageUploadAccessMask		= VK_ACCESS_SHADER_WRITE_BIT;
}

void UploadDownloadExecutor::uploadCopy(Context& context)
{
	(void) context;

	// Create a host-mappable buffer with the color data to upload
	const VkDeviceSize	pixelSize			= tcu::getPixelSize(mapVkFormat(m_caseDef.imageFormat));
	const VkDeviceSize	layerSize			= m_caseDef.size.x() * m_caseDef.size.y() * m_caseDef.size.z() * pixelSize;

	m_uCopy.colorBufferSize					= layerSize * m_caseDef.numLayers;
	m_uCopy.colorBuffer						= makeBuffer(m_vk, m_device, m_uCopy.colorBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
	m_uCopy.colorBufferAlloc				= bindBuffer(m_vk, m_device, m_allocator, *m_uCopy.colorBuffer, MemoryRequirement::HostVisible);

	// Fill color buffer
	const tcu::TextureFormat	tcuFormat	= mapVkFormat(m_caseDef.imageFormat);
	VkDeviceSize				layerOffset = 0ull;
	for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++)
	{
		tcu::PixelBufferAccess	imageAccess	= tcu::PixelBufferAccess(tcuFormat, m_caseDef.size.x(), m_caseDef.size.y(), 1u, (deUint8*) m_uCopy.colorBufferAlloc->getHostPtr() + layerOffset);
		const deUint32			colorIdx	= layer % COLOR_TABLE_SIZE;
		if (m_imageIsIntegerFormat)
		{
			const VkClearValue	clearValue	= getClearValueInt(m_caseDef, colorIdx);
			const IVec4			colorInt	(clearValue.color.int32[0], clearValue.color.int32[1], clearValue.color.int32[2], clearValue.color.int32[3]);

			tcu::clear(imageAccess, colorInt);
		}
		else
			tcu::clear(imageAccess, COLOR_TABLE_FLOAT[colorIdx]);
		layerOffset += layerSize;
	}

	flushAlloc(m_vk, m_device, *(m_uCopy.colorBufferAlloc));

	// Prepare buffer and image for copy
	const VkBufferMemoryBarrier	bufferInitBarrier	=
	{
		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,			// VkStructureType    sType;
		DE_NULL,											// const void*        pNext;
		VK_ACCESS_HOST_WRITE_BIT,							// VkAccessFlags      srcAccessMask;
		VK_ACCESS_TRANSFER_READ_BIT,						// VkAccessFlags      dstAccessMask;
		VK_QUEUE_FAMILY_IGNORED,							// deUint32           srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,							// deUint32           dstQueueFamilyIndex;
		*m_uCopy.colorBuffer,								// VkBuffer           buffer;
		0ull,												// VkDeviceSize       offset;
		VK_WHOLE_SIZE,										// VkDeviceSize       size;
	};

	const VkImageMemoryBarrier	imageInitBarrier	=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
		DE_NULL,											// const void*				pNext;
		0u,													// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_WRITE_BIT,						// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,							// deUint32					destQueueFamilyIndex;
		m_image,											// VkImage					image;
		makeColorSubresourceRange(0, m_caseDef.numLayers)	// VkImageSubresourceRange	subresourceRange;
	};

	m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
		0u, DE_NULL, 1u, &bufferInitBarrier, 1u, &imageInitBarrier);

	// Copy buffer to image
	const VkImageSubresourceLayers	subresource	=
	{
		VK_IMAGE_ASPECT_COLOR_BIT,							// VkImageAspectFlags    aspectMask;
		0u,													// deUint32              mipLevel;
		0u,													// deUint32              baseArrayLayer;
		m_caseDef.numLayers,								// deUint32              layerCount;
	};

	const VkBufferImageCopy			region		=
	{
		0ull,												// VkDeviceSize                bufferOffset;
		0u,													// deUint32                    bufferRowLength;
		0u,													// deUint32                    bufferImageHeight;
		subresource,										// VkImageSubresourceLayers    imageSubresource;
		makeOffset3D(0, 0, 0),								// VkOffset3D                  imageOffset;
		makeExtent3D(m_caseDef.size),						// VkExtent3D                  imageExtent;
	};

	m_vk.cmdCopyBufferToImage(*m_cmdBuffer, *m_uCopy.colorBuffer, m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &region);

	const VkImageMemoryBarrier	imagePostInitBarrier	=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
		DE_NULL,											// const void*				pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,						// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_READ_BIT,						// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,							// deUint32					destQueueFamilyIndex;
		m_image,											// VkImage					image;
		makeColorSubresourceRange(0, m_caseDef.numLayers)	// VkImageSubresourceRange	subresourceRange;
	};

	m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
		0u, DE_NULL, 0u, DE_NULL, 1u, &imagePostInitBarrier);

	m_imageLayoutAfterUpload	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
	m_imageUploadAccessMask		= VK_ACCESS_TRANSFER_WRITE_BIT;
}

void UploadDownloadExecutor::uploadDraw(Context& context)
{
	// Create vertex buffer
	{
		const vector<Vec4>	vertices				= genVertexData(m_caseDef);
		const VkDeviceSize	vertexBufferSize		= vertices.size() * sizeof(Vec4);

		m_uDraw.vertexBuffer						= makeBuffer(m_vk, m_device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
		m_uDraw.vertexBufferAlloc					= bindBuffer(m_vk, m_device, m_allocator, *m_uDraw.vertexBuffer, MemoryRequirement::HostVisible);
		deMemcpy(m_uDraw.vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast<std::size_t>(vertexBufferSize));
		flushAlloc(m_vk, m_device, *(m_uDraw.vertexBufferAlloc));
	}

	// Create attachments and pipelines for each image layer
	m_uDraw.pipelineLayout							= makePipelineLayout(m_vk, m_device);
	m_uDraw.renderPass								= makeRenderPass(m_vk, m_device, m_caseDef.viewFormat, m_caseDef.numLayers);
	m_uDraw.vertexModule							= createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawVert"), 0u);
	m_uDraw.fragmentModule							= createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawFrag"), 0u);

	for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx)
	{
		const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR,	// VkStructureType		sType
			DE_NULL,											// const void*			pNext
			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,				// VkImageUsageFlags	usage;
		};
		Move<VkImageView>	imageView	= makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
														makeColorSubresourceRange(subpassNdx, 1), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
		m_uDraw.attachmentHandles.push_back(*imageView);
		m_uDraw.attachments.push_back(makeSharedPtr(imageView));
		m_uDraw.pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(m_vk, m_device, *m_uDraw.pipelineLayout, *m_uDraw.renderPass, *m_uDraw.vertexModule, *m_uDraw.fragmentModule,
			m_caseDef.size.swizzle(0, 1), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, subpassNdx)));
	}

	// Create framebuffer
	{
		const IVec2 size = m_caseDef.size.swizzle(0, 1);

		m_uDraw.framebuffer = makeFramebuffer(m_vk, m_device, *m_uDraw.renderPass, static_cast<deUint32>(m_uDraw.attachmentHandles.size()), &m_uDraw.attachmentHandles[0], static_cast<deUint32>(size.x()), static_cast<deUint32>(size.y()));
	}

	// Create command buffer
	{
		{
			vector<VkClearValue>	clearValues		(m_caseDef.numLayers, m_viewIsIntegerFormat ? getClearValueInt(m_caseDef, 0) : REFERENCE_CLEAR_COLOR_FLOAT[0]);

			beginRenderPass(m_vk, *m_cmdBuffer, *m_uDraw.renderPass, *m_uDraw.framebuffer, makeRect2D(0, 0, m_caseDef.size.x(), m_caseDef.size.y()), (deUint32)clearValues.size(), &clearValues[0]);
		}

		// Render
		const VkDeviceSize	vertexDataPerDraw	= 4 * 2 * sizeof(Vec4);
		VkDeviceSize		vertexBufferOffset	= 0ull;
		for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx)
		{
			if (subpassNdx != 0)
				m_vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);

			m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_uDraw.pipelines[subpassNdx]);

			m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_uDraw.vertexBuffer.get(), &vertexBufferOffset);
			m_vk.cmdDraw(*m_cmdBuffer, 4u, 1u, 0u, 0u);
			vertexBufferOffset	+= vertexDataPerDraw;
		}

		endRenderPass(m_vk, *m_cmdBuffer);
	}

	m_imageLayoutAfterUpload	= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
	m_imageUploadAccessMask		= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
}

void UploadDownloadExecutor::downloadCopy(Context& context, VkBuffer buffer)
{
	(void) context;

	copyImageToBuffer(m_image, buffer, m_caseDef.size, m_imageUploadAccessMask, m_imageLayoutAfterUpload, m_caseDef.numLayers);
}

void UploadDownloadExecutor::downloadTexture(Context& context, VkBuffer buffer)
{
	// Create output image with download result
	const VkImageUsageFlags	usageFlags	= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
	m_dTex.outImage						= makeImage(m_vk, m_device, 0u, VK_IMAGE_TYPE_2D, m_caseDef.viewFormat, m_caseDef.viewFormat, false, m_caseDef.size, 1u, m_caseDef.numLayers, usageFlags);
	m_dTex.outImageAlloc				= bindImage(m_vk, m_device, m_allocator, *m_dTex.outImage, MemoryRequirement::Any);
	m_dTex.outImageView					= makeImageView(m_vk, m_device, *m_dTex.outImage, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, makeColorSubresourceRange(0, m_caseDef.numLayers));

	const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR,	// VkStructureType		sType
		DE_NULL,											// const void*			pNext
		VK_IMAGE_USAGE_SAMPLED_BIT,							// VkImageUsageFlags	usage;
	};
	m_dTex.inImageView					= makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
														makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
	m_dTex.sampler						= makeSampler(m_vk, m_device);

	// Setup compute pipeline
	m_dTex.descriptorPool				= DescriptorPoolBuilder()
		.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
		.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
		.build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);

	m_dTex.descriptorSetLayout			= DescriptorSetLayoutBuilder()
		.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT, &m_dTex.sampler.get())
		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
		.build(m_vk, m_device);

	m_dTex.pipelineLayout				= makePipelineLayout(m_vk, m_device, *m_dTex.descriptorSetLayout);
	m_dTex.descriptorSet				= makeDescriptorSet(m_vk, m_device, *m_dTex.descriptorPool, *m_dTex.descriptorSetLayout);
	m_dTex.inImageDescriptorInfo		= makeDescriptorImageInfo(DE_NULL, *m_dTex.inImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
	m_dTex.outImageDescriptorInfo		= makeDescriptorImageInfo(DE_NULL, *m_dTex.outImageView, VK_IMAGE_LAYOUT_GENERAL);
	m_dTex.computeModule				= createShaderModule(m_vk, m_device, context.getBinaryCollection().get("downloadTextureComp"), 0);
	m_dTex.computePipeline				= makeComputePipeline(m_vk, m_device, *m_dTex.pipelineLayout, *m_dTex.computeModule, DE_NULL);

	DescriptorSetUpdateBuilder()
		.writeSingle(*m_dTex.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &m_dTex.inImageDescriptorInfo)
		.writeSingle(*m_dTex.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dTex.outImageDescriptorInfo)
		.update(m_vk, m_device);

	// Transition images for shader access (texture / imageStore)
	const VkImageMemoryBarrier imageBarriers[]	=
	{
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
			DE_NULL,											// const void*				pNext;
			(VkAccessFlags)m_imageUploadAccessMask,				// VkAccessFlags			srcAccessMask;
			(VkAccessFlags)VK_ACCESS_SHADER_READ_BIT,			// VkAccessFlags			dstAccessMask;
			m_imageLayoutAfterUpload,							// VkImageLayout			oldLayout;
			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,			// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,							// deUint32					destQueueFamilyIndex;
			m_image,											// VkImage					image;
			makeColorSubresourceRange(0, m_caseDef.numLayers),	// VkImageSubresourceRange	subresourceRange;
		},
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
			DE_NULL,											// const void*				pNext;
			(VkAccessFlags)0,									// VkAccessFlags			srcAccessMask;
			(VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
			VK_IMAGE_LAYOUT_GENERAL,							// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,							// deUint32					destQueueFamilyIndex;
			*m_dTex.outImage,									// VkImage					image;
			makeColorSubresourceRange(0, m_caseDef.numLayers),	// VkImageSubresourceRange	subresourceRange;
		}
	};

	m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
		0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);

	// Dispatch
	m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dTex.computePipeline);
	m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dTex.pipelineLayout, 0u, 1u, &m_dTex.descriptorSet.get(), 0u, DE_NULL);
	m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);

	// Copy output image to color buffer
	copyImageToBuffer(*m_dTex.outImage, buffer, m_caseDef.size, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL, m_caseDef.numLayers);
}

void UploadDownloadExecutor::downloadLoad(Context& context, VkBuffer buffer)
{
	// Create output image with download result
	const VkImageUsageFlags usageFlags	= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
	m_dLoad.outImage					= makeImage(m_vk, m_device, 0u, VK_IMAGE_TYPE_2D, m_caseDef.viewFormat, m_caseDef.viewFormat, false, m_caseDef.size, 1u, m_caseDef.numLayers, usageFlags);
	m_dLoad.outImageAlloc				= bindImage(m_vk, m_device, m_allocator, *m_dLoad.outImage, MemoryRequirement::Any);
	m_dLoad.outImageView				= makeImageView(m_vk, m_device, *m_dLoad.outImage, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, makeColorSubresourceRange(0, m_caseDef.numLayers));

	const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR,	// VkStructureType		sType
		DE_NULL,											// const void*			pNext
		VK_IMAGE_USAGE_STORAGE_BIT,							// VkImageUsageFlags	usage;
	};
	m_dLoad.inImageView					= makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
														makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);

	// Setup compute pipeline
	m_dLoad.descriptorPool				= DescriptorPoolBuilder()
		.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2u)
		.build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);

	m_dLoad.descriptorSetLayout			= DescriptorSetLayoutBuilder()
		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
		.build(m_vk, m_device);

	m_dLoad.pipelineLayout				= makePipelineLayout(m_vk, m_device, *m_dLoad.descriptorSetLayout);
	m_dLoad.descriptorSet				= makeDescriptorSet(m_vk, m_device, *m_dLoad.descriptorPool, *m_dLoad.descriptorSetLayout);
	m_dLoad.inImageDescriptorInfo		= makeDescriptorImageInfo(DE_NULL, *m_dLoad.inImageView, VK_IMAGE_LAYOUT_GENERAL);
	m_dLoad.outImageDescriptorInfo		= makeDescriptorImageInfo(DE_NULL, *m_dLoad.outImageView, VK_IMAGE_LAYOUT_GENERAL);
	m_dLoad.computeModule				= createShaderModule(m_vk, m_device, context.getBinaryCollection().get("downloadLoadComp"), 0);
	m_dLoad.computePipeline				= makeComputePipeline(m_vk, m_device, *m_dLoad.pipelineLayout, *m_dLoad.computeModule, DE_NULL);

	DescriptorSetUpdateBuilder()
		.writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.inImageDescriptorInfo)
		.writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.outImageDescriptorInfo)
		.update(m_vk, m_device);

	// Transition storage images for shader access (imageLoad/Store)
	VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
	const VkImageMemoryBarrier imageBarriers[]	=
	{
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
			DE_NULL,											// const void*				pNext;
			(VkAccessFlags)m_imageUploadAccessMask,				// VkAccessFlags			srcAccessMask;
			(VkAccessFlags)VK_ACCESS_SHADER_READ_BIT,			// VkAccessFlags			dstAccessMask;
			m_imageLayoutAfterUpload,							// VkImageLayout			oldLayout;
			requiredImageLayout,								// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,							// deUint32					destQueueFamilyIndex;
			m_image,											// VkImage					image;
			makeColorSubresourceRange(0, m_caseDef.numLayers),	// VkImageSubresourceRange	subresourceRange;
		},
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
			DE_NULL,											// const void*				pNext;
			(VkAccessFlags)0,									// VkAccessFlags			srcAccessMask;
			(VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
			requiredImageLayout,								// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,							// deUint32					destQueueFamilyIndex;
			*m_dLoad.outImage,									// VkImage					image;
			makeColorSubresourceRange(0, m_caseDef.numLayers),	// VkImageSubresourceRange	subresourceRange;
		}
	};

	m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
		0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);

	// Dispatch
	m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.computePipeline);
	m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.pipelineLayout, 0u, 1u, &m_dLoad.descriptorSet.get(), 0u, DE_NULL);
	m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);

	// Copy output image to color buffer
	copyImageToBuffer(*m_dLoad.outImage, buffer, m_caseDef.size, VK_ACCESS_SHADER_WRITE_BIT, requiredImageLayout, m_caseDef.numLayers);
}

void UploadDownloadExecutor::copyImageToBuffer(VkImage				sourceImage,
											   VkBuffer				buffer,
											   const IVec3			size,
											   const VkAccessFlags	srcAccessMask,
											   const VkImageLayout	oldLayout,
											   const deUint32		numLayers)
{
	// Copy result to host visible buffer for inspection
	const VkImageMemoryBarrier	imageBarrier	=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		srcAccessMask,								// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
		oldLayout,									// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					destQueueFamilyIndex;
		sourceImage,								// VkImage					image;
		makeColorSubresourceRange(0, numLayers)		// VkImageSubresourceRange	subresourceRange;
	};

	m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
		0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);

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

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

	m_vk.cmdCopyImageToBuffer(*m_cmdBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, 1u, &region);

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

	m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
		0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
}

tcu::TestStatus testMutable (Context& context, const CaseDef caseDef)
{
	const DeviceInterface&		vk					= context.getDeviceInterface();
	const VkDevice				device				= context.getDevice();
	Allocator&					allocator			= context.getDefaultAllocator();

	// Create a color buffer for host-inspection of results
	// For the Copy download method, this is the target of the download, for other
	// download methods, pixel data will be copied to this buffer from the download
	// target
	const VkDeviceSize			colorBufferSize		= caseDef.size.x() * caseDef.size.y() * caseDef.size.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.imageFormat));
	const Unique<VkBuffer>		colorBuffer			(makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const UniquePtr<Allocation>	colorBufferAlloc	(bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
	deMemset(colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
	flushAlloc(vk, device, *colorBufferAlloc);

	// Execute the test
	UploadDownloadExecutor executor(context, device, context.getUniversalQueue(), context.getUniversalQueueFamilyIndex(), caseDef);
	executor.run(context, *colorBuffer);

	// Verify results
	{
		invalidateAlloc(vk, device, *colorBufferAlloc);

		// For verification purposes, we use the format of the upload to generate the expected image
		const VkFormat						format			= caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY ? caseDef.imageFormat : caseDef.viewFormat;
		const tcu::TextureFormat			tcuFormat		= mapVkFormat(format);
		const bool							isIntegerFormat	= isUintFormat(format) || isIntFormat(format);
		const tcu::ConstPixelBufferAccess	resultImage		(tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers, colorBufferAlloc->getHostPtr());
		tcu::TextureLevel					textureLevel	(tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers);
		const tcu::PixelBufferAccess		expectedImage	= textureLevel.getAccess();
		generateExpectedImage(expectedImage, caseDef);

		bool ok;
		if (isIntegerFormat)
			ok = tcu::intThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
		else
			ok = tcu::floatThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
		return ok ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
	}
}

void checkSupport (Context& context, const CaseDef caseDef)
{
	const InstanceInterface&		vki			= context.getInstanceInterface();
	const VkPhysicalDevice			physDevice	= context.getPhysicalDevice();

	// If this is a VK_KHR_image_format_list test, check that the extension is supported
	if (caseDef.isFormatListTest)
		context.requireDeviceFunctionality("VK_KHR_image_format_list");

	// Check required features on the format for the required upload/download methods
	VkFormatProperties	imageFormatProps, viewFormatProps;
	vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.imageFormat, &imageFormatProps);
	vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.viewFormat, &viewFormatProps);

	VkFormatFeatureFlags	viewFormatFeatureFlags = 0u;
	switch (caseDef.upload)
	{
	case UPLOAD_DRAW:
		viewFormatFeatureFlags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
		break;
	case UPLOAD_STORE:
		viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
		break;
	case UPLOAD_CLEAR:
		viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
		break;
	case UPLOAD_COPY:
		viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
		break;
	default:
		DE_FATAL("Invalid upload method");
		break;
	}
	switch (caseDef.download)
	{
	case DOWNLOAD_TEXTURE:
		viewFormatFeatureFlags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
		// For the texture case we write the samples read to a separate output image with the same view format
		// so we need to check that we can also use the view format for storage
		viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
		break;
	case DOWNLOAD_LOAD:
		viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
		break;
	case DOWNLOAD_COPY:
		viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
		break;
	default:
		DE_FATAL("Invalid download method");
		break;
	}

	if ((viewFormatFeatureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) &&
		isStorageImageExtendedFormat(caseDef.viewFormat) &&
		!getPhysicalDeviceFeatures(vki, physDevice).shaderStorageImageExtendedFormats)
	{
		TCU_THROW(NotSupportedError, "View format requires shaderStorageImageExtended");
	}

	if ((viewFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags)
		TCU_THROW(NotSupportedError, "View format doesn't support upload/download method");

	const bool haveMaintenance2 = context.isDeviceFunctionalitySupported("VK_KHR_maintenance2");

	// We don't use the base image for anything other than transfer
	// operations so there are no features to check.  However, The Vulkan
	// 1.0 spec does not allow us to create an image view with usage that
	// is not supported by the main format.  With VK_KHR_maintenance2, we
	// can do this via VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR.
	if ((imageFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags &&
		!haveMaintenance2)
	{
		TCU_THROW(NotSupportedError, "Image format doesn't support upload/download method");
	}

	// If no format feature flags are supported, the format itself is not supported,
	// and images of that format cannot be created.
	if (imageFormatProps.optimalTilingFeatures == 0)
	{
		TCU_THROW(NotSupportedError, "Base image format is not supported");
	}
}

tcu::TestCaseGroup* createImageMutableTests (TestContext& testCtx)
{
	de::MovePtr<TestCaseGroup> testGroup	(new TestCaseGroup(testCtx, "mutable", "Cases with mutable images"));
	for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx)
	{
		const Texture&					texture					= s_textures[textureNdx];
		de::MovePtr<tcu::TestCaseGroup> groupByImageViewType	(new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str(), ""));

		for (int imageFormatNdx = 0; imageFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++imageFormatNdx)
		for (int viewFormatNdx = 0; viewFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++viewFormatNdx)
		{
			if (imageFormatNdx != viewFormatNdx && formatsAreCompatible(s_formats[imageFormatNdx], s_formats[viewFormatNdx]))
			{
				for (int upload = 0; upload < UPLOAD_LAST; upload++)
				{
					if (upload == UPLOAD_STORE && !isFormatImageLoadStoreCapable(s_formats[viewFormatNdx]))
						continue;

					for (int download = 0; download < DOWNLOAD_LAST; download++)
					{
						if ((download == DOWNLOAD_LOAD || download == DOWNLOAD_TEXTURE) &&
							!isFormatImageLoadStoreCapable(s_formats[viewFormatNdx]))
							continue;

						CaseDef caseDef =
						{
							texture.type(),
							texture.layerSize(),
							static_cast<deUint32>(texture.numLayers()),
							s_formats[imageFormatNdx],
							s_formats[viewFormatNdx],
							static_cast<enum Upload>(upload),
							static_cast<enum Download>(download),
							false,				// isFormatListTest;
							false,				// isSwapchainImageTest
							vk::wsi::TYPE_LAST	// wsiType
						};

						std::string caseName = getFormatShortString(s_formats[imageFormatNdx]) + "_" + getFormatShortString(s_formats[viewFormatNdx]) +
							"_" + getUploadString(upload) + "_" + getDownloadString(download);
						addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", checkSupport, initPrograms, testMutable, caseDef);

						caseDef.isFormatListTest = true;
						caseName += "_format_list";
						addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", checkSupport, initPrograms, testMutable, caseDef);
					}
				}
			}
		}

		testGroup->addChild(groupByImageViewType.release());
	}

	return testGroup.release();
}

typedef vector<VkExtensionProperties> Extensions;

void checkAllSupported(const Extensions& supportedExtensions, const vector<string>& requiredExtensions)
{
	for (vector<string>::const_iterator requiredExtName = requiredExtensions.begin();
		requiredExtName != requiredExtensions.end();
		++requiredExtName)
	{
		if (!isExtensionSupported(supportedExtensions, RequiredExtension(*requiredExtName)))
			TCU_THROW(NotSupportedError, (*requiredExtName + " is not supported").c_str());
	}
}

CustomInstance createInstanceWithWsi(Context&						context,
									 const Extensions&				supportedExtensions,
									 Type							wsiType,
									 const VkAllocationCallbacks*	pAllocator = DE_NULL)
{
	vector<string>	extensions;

	extensions.push_back("VK_KHR_surface");
	extensions.push_back(getExtensionName(wsiType));

	// VK_EXT_swapchain_colorspace adds new surface formats. Driver can enumerate
	// the formats regardless of whether VK_EXT_swapchain_colorspace was enabled,
	// but using them without enabling the extension is not allowed. Thus we have
	// two options:
	//
	// 1) Filter out non-core formats to stay within valid usage.
	//
	// 2) Enable VK_EXT_swapchain colorspace if advertised by the driver.
	//
	// We opt for (2) as it provides basic coverage for the extension as a bonus.
	if (isExtensionSupported(supportedExtensions, RequiredExtension("VK_EXT_swapchain_colorspace")))
		extensions.push_back("VK_EXT_swapchain_colorspace");

	checkAllSupported(supportedExtensions, extensions);

	return createCustomInstanceWithExtensions(context, extensions, pAllocator);
}


Move<VkDevice> createDeviceWithWsi(const PlatformInterface&		vkp,
								   VkInstance					instance,
								   const InstanceInterface&		vki,
								   VkPhysicalDevice				physicalDevice,
								   const Extensions&			supportedExtensions,
								   const deUint32				queueFamilyIndex,
								   const VkAllocationCallbacks*	pAllocator,
								   bool							enableValidation)
{
	const float						queuePriorities[] = { 1.0f };
	const VkDeviceQueueCreateInfo	queueInfos[] =
	{
		{
			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
			DE_NULL,
			(VkDeviceQueueCreateFlags)0,
			queueFamilyIndex,
			DE_LENGTH_OF_ARRAY(queuePriorities),
			&queuePriorities[0]
		}
	};
	VkPhysicalDeviceFeatures		features;
	deMemset(&features, 0x0, sizeof(features));

	const char* const				extensions[] = { "VK_KHR_swapchain", "VK_KHR_swapchain_mutable_format" };

	const VkDeviceCreateInfo		deviceParams =
	{
		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
		DE_NULL,
		(VkDeviceCreateFlags)0,
		DE_LENGTH_OF_ARRAY(queueInfos),
		&queueInfos[0],
		0u,									// enabledLayerCount
		DE_NULL,							// ppEnabledLayerNames
		DE_LENGTH_OF_ARRAY(extensions),		// enabledExtensionCount
		DE_ARRAY_BEGIN(extensions),			// ppEnabledExtensionNames
		&features
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(extensions); ++ndx)
	{
		if (!isExtensionSupported(supportedExtensions, RequiredExtension(extensions[ndx])))
			TCU_THROW(NotSupportedError, (string(extensions[ndx]) + " is not supported").c_str());
	}

	return createCustomDevice(enableValidation, vkp, instance, vki, physicalDevice, &deviceParams, pAllocator);
}

deUint32 getNumQueueFamilyIndices(const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
{
	deUint32	numFamilies = 0;

	vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);

	return numFamilies;
}

vector<deUint32> getSupportedQueueFamilyIndices(const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
{
	const deUint32		numTotalFamilyIndices = getNumQueueFamilyIndices(vki, physicalDevice);
	vector<deUint32>	supportedFamilyIndices;

	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numTotalFamilyIndices; ++queueFamilyNdx)
	{
		if (getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) != VK_FALSE)
			supportedFamilyIndices.push_back(queueFamilyNdx);
	}

	return supportedFamilyIndices;
}

deUint32 chooseQueueFamilyIndex(const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
{
	const vector<deUint32>	supportedFamilyIndices = getSupportedQueueFamilyIndices(vki, physicalDevice, surface);

	if (supportedFamilyIndices.empty())
		TCU_THROW(NotSupportedError, "Device doesn't support presentation");

	return supportedFamilyIndices[0];
}

struct InstanceHelper
{
	const vector<VkExtensionProperties>	supportedExtensions;
	const CustomInstance				instance;
	const InstanceDriver&				vki;

	InstanceHelper(Context& context, Type wsiType, const VkAllocationCallbacks* pAllocator = DE_NULL)
		: supportedExtensions(enumerateInstanceExtensionProperties(context.getPlatformInterface(),
			DE_NULL))
		, instance(createInstanceWithWsi(context,
			supportedExtensions,
			wsiType,
			pAllocator))
		, vki(instance.getDriver())
	{}
};


struct DeviceHelper
{
	const VkPhysicalDevice	physicalDevice;
	const deUint32			queueFamilyIndex;
	const Unique<VkDevice>	device;
	const DeviceDriver		vkd;
	const VkQueue			queue;

	DeviceHelper(Context&						context,
		const InstanceInterface&		vki,
		VkInstance					instance,
		VkSurfaceKHR					surface,
		const VkAllocationCallbacks*	pAllocator = DE_NULL)
		: physicalDevice(chooseDevice(vki, instance, context.getTestContext().getCommandLine()))
		, queueFamilyIndex(chooseQueueFamilyIndex(vki, physicalDevice, surface))
		, device(createDeviceWithWsi(context.getPlatformInterface(),
			context.getInstance(),
			vki,
			physicalDevice,
			enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL),
			queueFamilyIndex,
			pAllocator,
			context.getTestContext().getCommandLine().isValidationEnabled()))
		, vkd(context.getPlatformInterface(), context.getInstance(), *device)
		, queue(getDeviceQueue(vkd, *device, queueFamilyIndex, 0))
	{
	}
};

MovePtr<Display> createDisplay(const vk::Platform&	platform,
	const Extensions&	supportedExtensions,
	Type				wsiType)
{
	try
	{
		return MovePtr<Display>(platform.createWsiDisplay(wsiType));
	}
	catch (const tcu::NotSupportedError& e)
	{
		if (isExtensionSupported(supportedExtensions, RequiredExtension(getExtensionName(wsiType))) &&
		    platform.hasDisplay(wsiType))
		{
			// If VK_KHR_{platform}_surface was supported, vk::Platform implementation
			// must support creating native display & window for that WSI type.
			throw tcu::TestError(e.getMessage());
		}
		else
			throw;
	}
}

MovePtr<Window> createWindow(const Display& display, const Maybe<UVec2>& initialSize)
{
	try
	{
		return MovePtr<Window>(display.createWindow(initialSize));
	}
	catch (const tcu::NotSupportedError& e)
	{
		// See createDisplay - assuming that wsi::Display was supported platform port
		// should also support creating a window.
		throw tcu::TestError(e.getMessage());
	}
}

struct NativeObjects
{
	const UniquePtr<Display>	display;
	const UniquePtr<Window>		window;

	NativeObjects(Context&				context,
		const Extensions&	supportedExtensions,
		Type					wsiType,
		const Maybe<UVec2>&	initialWindowSize = tcu::nothing<UVec2>())
		: display(createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
		, window(createWindow(*display, initialWindowSize))
	{}
};

Move<VkSwapchainKHR> makeSwapchain(const DeviceInterface&		vk,
									const VkDevice				device,
									const vk::wsi::Type			wsiType,
									const VkSurfaceKHR			surface,
									const VkSurfaceCapabilitiesKHR		capabilities,
									const VkSurfaceFormatKHR	surfaceFormat,
									const VkFormat				viewFormat,
									const deUint32				numLayers,
									const VkImageUsageFlags		usage,
									const tcu::UVec2&			desiredSize,
									deUint32					desiredImageCount
)
{
	const VkFormat formatList[2] =
	{
		surfaceFormat.format,
		viewFormat
	};

	const VkImageFormatListCreateInfoKHR formatListInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR,	// VkStructureType			sType;
		DE_NULL,												// const void*				pNext;
		2u,														// deUint32					viewFormatCount
		formatList												// const VkFormat*			pViewFormats
	};

	const VkSurfaceTransformFlagBitsKHR transform = (capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : capabilities.currentTransform;
	const PlatformProperties&			platformProperties = getPlatformProperties(wsiType);

	const VkSwapchainCreateInfoKHR		swapchainInfo =
	{
		VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,		// VkStructureType					sType;
		&formatListInfo,									// const void*						pNext;
		VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR,			// VkSwapchainCreateFlagsKHR		flags;
		surface,											// VkSurfaceKHR						surface;
		de::clamp(desiredImageCount, capabilities.minImageCount, capabilities.maxImageCount > 0 ? capabilities.maxImageCount : capabilities.minImageCount + desiredImageCount), // deUint32						minImageCount;
		surfaceFormat.format,								// VkFormat							imageFormat;
		surfaceFormat.colorSpace,							// VkColorSpaceKHR					imageColorSpace;
		(platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE
		? capabilities.currentExtent : vk::makeExtent2D(desiredSize.x(), desiredSize.y())),	// VkExtent2D						imageExtent;
		numLayers,											// deUint32							imageArrayLayers;
		usage,												// VkImageUsageFlags				imageUsage;
		VK_SHARING_MODE_EXCLUSIVE,							// VkSharingMode					imageSharingMode;
		0u,													// deUint32							queueFamilyIndexCount;
		(const deUint32*)DE_NULL,							// const deUint32*					pQueueFamilyIndices;
		transform,											// VkSurfaceTransformFlagBitsKHR	preTransform;
		VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,					// VkCompositeAlphaFlagBitsKHR		compositeAlpha;
		VK_PRESENT_MODE_FIFO_KHR,							// VkPresentModeKHR					presentMode;
		VK_FALSE,											// VkBool32							clipped;
		(VkSwapchainKHR)0									// VkSwapchainKHR					oldSwapchain;
	};

	return createSwapchainKHR(vk, device, &swapchainInfo);
}

tcu::TestStatus testSwapchainMutable(Context& context, CaseDef caseDef)
{
	const Type						wsiType(caseDef.wsiType);
	const tcu::UVec2				desiredSize(256, 256);
	const InstanceHelper			instHelper(context, wsiType);
	const NativeObjects				native(context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
	const Unique<VkSurfaceKHR>		surface(createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
	const DeviceHelper				devHelper(context, instHelper.vki, instHelper.instance, *surface);
	const DeviceInterface&			vk = devHelper.vkd;
	const InstanceDriver&			vki = instHelper.vki;
	const VkDevice					device = *devHelper.device;
	const VkPhysicalDevice			physDevice = devHelper.physicalDevice;
	SimpleAllocator					allocator(vk, device, getPhysicalDeviceMemoryProperties(vki, context.getPhysicalDevice()));

	const VkImageUsageFlags			imageUsage = getImageUsageForTestCase(caseDef);

	{
		VkImageFormatProperties properties;
		VkResult				result;

		result = vki.getPhysicalDeviceImageFormatProperties(physDevice, caseDef.imageFormat, getImageType(caseDef.imageType), VK_IMAGE_TILING_OPTIMAL, imageUsage, 0, &properties);

		if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
		{
			TCU_THROW(NotSupportedError, "Image format is not supported for required usage");
		}

		result = vki.getPhysicalDeviceImageFormatProperties(physDevice, caseDef.viewFormat, getImageType(caseDef.imageType), VK_IMAGE_TILING_OPTIMAL, imageUsage, 0, &properties);

		if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
		{
			TCU_THROW(NotSupportedError, "Image view format is not supported for required usage");
		}
	}

	const VkSurfaceCapabilitiesKHR		capabilities = getPhysicalDeviceSurfaceCapabilities(vki,
																							physDevice,
																							*surface);

	if (caseDef.numLayers > capabilities.maxImageArrayLayers)
		caseDef.numLayers = capabilities.maxImageArrayLayers;

	// Check support for requested formats by swapchain surface
	const vector<VkSurfaceFormatKHR>surfaceFormats = getPhysicalDeviceSurfaceFormats(vki,
																						 physDevice,
																						 *surface);

	const VkSurfaceFormatKHR*		surfaceFormat = DE_NULL;
	const VkFormat*					viewFormat = DE_NULL;

	for (vector<VkSurfaceFormatKHR>::size_type i = 0; i < surfaceFormats.size(); i++)
	{
		if (surfaceFormats[i].format == caseDef.imageFormat)
			surfaceFormat = &surfaceFormats[i];

		if (surfaceFormats[i].format == caseDef.viewFormat)
			viewFormat = &surfaceFormats[i].format;
	}

	if (surfaceFormat == DE_NULL)
		TCU_THROW(NotSupportedError, "Image format is not supported by swapchain.");

	if (viewFormat == DE_NULL)
		TCU_THROW(NotSupportedError, "Image view format is not supported by swapchain.");

	if ((capabilities.supportedUsageFlags & imageUsage) != imageUsage)
		TCU_THROW(NotSupportedError, "Image usage request not supported by swapchain.");

	const Unique<VkSwapchainKHR>	swapchain(
		makeSwapchain(
			vk,
			device,
			caseDef.wsiType,
			*surface,
			capabilities,
			*surfaceFormat,
			caseDef.viewFormat,
			caseDef.numLayers,
			imageUsage,
			desiredSize,
			2)
		);
	const vector<VkImage>			swapchainImages = getSwapchainImages(vk, device, *swapchain);

	// Create a color buffer for host-inspection of results
	// For the Copy download method, this is the target of the download, for other
	// download methods, pixel data will be copied to this buffer from the download
	// target
	const VkDeviceSize			colorBufferSize = caseDef.size.x() * caseDef.size.y() * caseDef.size.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.imageFormat));
	const Unique<VkBuffer>		colorBuffer(makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const UniquePtr<Allocation>	colorBufferAlloc(bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
	deMemset(colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
	flushAlloc(vk, device, *colorBufferAlloc);


	// Execute the test
	UploadDownloadExecutor executor(context, device, devHelper.queue, devHelper.queueFamilyIndex, caseDef);

	executor.runSwapchain(context, *colorBuffer, swapchainImages[0]);

	// Verify results
	{
		invalidateAlloc(vk, device, *colorBufferAlloc);

		// For verification purposes, we use the format of the upload to generate the expected image
		const VkFormat						format = caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY ? caseDef.imageFormat : caseDef.viewFormat;
		const tcu::TextureFormat			tcuFormat = mapVkFormat(format);
		const bool							isIntegerFormat = isUintFormat(format) || isIntFormat(format);
		const tcu::ConstPixelBufferAccess	resultImage(tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers, colorBufferAlloc->getHostPtr());
		tcu::TextureLevel					textureLevel(tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers);
		const tcu::PixelBufferAccess		expectedImage = textureLevel.getAccess();
		generateExpectedImage(expectedImage, caseDef);

		bool ok;
		if (isIntegerFormat)
			ok = tcu::intThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
		else
			ok = tcu::floatThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
		return ok ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
	}
}

tcu::TestCaseGroup* createSwapchainImageMutableTests(TestContext& testCtx)
{
	de::MovePtr<TestCaseGroup> testGroup(new TestCaseGroup(testCtx, "swapchain_mutable", "Cases with swapchain mutable images"));

	for (int typeNdx = 0; typeNdx < vk::wsi::TYPE_LAST; ++typeNdx)
	{
		const vk::wsi::Type	wsiType = (vk::wsi::Type)typeNdx;

		de::MovePtr<TestCaseGroup> testGroupWsi(new TestCaseGroup(testCtx, getName(wsiType), ""));

		for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx)
		{
			const Texture&					texture = s_textures[textureNdx];
			de::MovePtr<tcu::TestCaseGroup> groupByImageViewType(new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str(), ""));

			for (int imageFormatNdx = 0; imageFormatNdx < DE_LENGTH_OF_ARRAY(s_swapchainFormats); ++imageFormatNdx)
				for (int viewFormatNdx = 0; viewFormatNdx < DE_LENGTH_OF_ARRAY(s_swapchainFormats); ++viewFormatNdx)
				{
					if (imageFormatNdx != viewFormatNdx && formatsAreCompatible(s_swapchainFormats[imageFormatNdx], s_swapchainFormats[viewFormatNdx]))
					{
						for (int upload = 0; upload < UPLOAD_LAST; upload++)
						{
							if (upload == UPLOAD_STORE && !isFormatImageLoadStoreCapable(s_swapchainFormats[viewFormatNdx]))
								continue;

							for (int download = 0; download < DOWNLOAD_LAST; download++)
							{
								if ((download == DOWNLOAD_LOAD || download == DOWNLOAD_TEXTURE) &&
									!isFormatImageLoadStoreCapable(s_swapchainFormats[viewFormatNdx]))
									continue;

								CaseDef caseDef =
								{
									texture.type(),
									texture.layerSize(),
									static_cast<deUint32>(texture.numLayers()),
									s_swapchainFormats[imageFormatNdx],
									s_swapchainFormats[viewFormatNdx],
									static_cast<enum Upload>(upload),
									static_cast<enum Download>(download),
									true,		// isFormatListTest;
									true,		// isSwapchainImageTest
									wsiType
								};

								std::string caseName = getFormatShortString(s_swapchainFormats[imageFormatNdx]) + "_" + getFormatShortString(s_swapchainFormats[viewFormatNdx]) +
									"_" + getUploadString(upload) + "_" + getDownloadString(download) + "_format_list";

								addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", checkSupport, initPrograms, testSwapchainMutable, caseDef);
							}
						}
					}
				}

			testGroupWsi->addChild(groupByImageViewType.release());
		}

		testGroup->addChild(testGroupWsi.release());
	}
	return testGroup.release();
}

} // image
} // vkt
