/*------------------------------------------------------------------------
 * 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 "vktTestCaseUtil.hpp"
#include "vktImageTexture.hpp"

#include "vkBuilderUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkImageUtil.hpp"

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

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

#include <string>
#include <vector>

using namespace vk;
using namespace tcu;

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

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

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.10f, 0.50f, 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(112,  60,	101,  41),
	IVec4( 60, 101,	 41, 112),
	IVec4( 41, 112,	 60, 101),
	IVec4(101,  41,	112,  60),
};

// 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 VkClearValue REFERENCE_CLEAR_COLOR_INT[COLOR_TABLE_SIZE]	=
{
	makeClearValueColorI32(COLOR_TABLE_INT[0].x(), COLOR_TABLE_INT[0].y(), COLOR_TABLE_INT[0].z(), COLOR_TABLE_INT[0].w()),
	makeClearValueColorI32(COLOR_TABLE_INT[1].x(), COLOR_TABLE_INT[1].y(), COLOR_TABLE_INT[1].z(), COLOR_TABLE_INT[1].w()),
	makeClearValueColorI32(COLOR_TABLE_INT[2].x(), COLOR_TABLE_INT[2].y(), COLOR_TABLE_INT[2].z(), COLOR_TABLE_INT[2].w()),
	makeClearValueColorI32(COLOR_TABLE_INT[3].x(), COLOR_TABLE_INT[3].y(), COLOR_TABLE_INT[3].z(), COLOR_TABLE_INT[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),
};

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

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)
				src << "     " << colorTypeStr << "(" << COLOR_TABLE_INT[idx].x() << ", " << COLOR_TABLE_INT[idx].y() << ", " << COLOR_TABLE_INT[idx].z() << ", " << COLOR_TABLE_INT[idx].w() << ")";
			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 Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize bufferSize, const VkBufferUsageFlags usage)
{
	const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSize, usage);
	return createBuffer(vk, device, &bufferCreateInfo);
}

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<VkPipelineLayout> makePipelineLayout (const DeviceInterface&	vk,
										   const VkDevice			device)
{
	const VkPipelineLayoutCreateInfo info =
	{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
		DE_NULL,
		(VkPipelineLayoutCreateFlags)0,
		0u,
		DE_NULL,
		0u,
		DE_NULL,
	};
	return createPipelineLayout(vk, device, &info);
}

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 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 vertexInputStateInfo =
	{
		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;
		DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),		// deUint32									vertexAttributeDescriptionCount;
		vertexInputAttributeDescriptions,							// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
	};

	const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,														// const void*								pNext;
		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags	flags;
		topology,														// VkPrimitiveTopology						topology;
		VK_FALSE,														// VkBool32									primitiveRestartEnable;
	};

	const VkViewport viewport = makeViewport(
		0.0f, 0.0f,
		static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()),
		0.0f, 1.0f);

	const VkRect2D scissor =
	{
		makeOffset2D(0, 0),
		makeExtent2D(renderSize.x(), renderSize.y()),
	};

	const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,		// VkStructureType						sType;
		DE_NULL,													// const void*							pNext;
		(VkPipelineViewportStateCreateFlags)0,						// VkPipelineViewportStateCreateFlags	flags;
		1u,															// deUint32								viewportCount;
		&viewport,													// const VkViewport*					pViewports;
		1u,															// deUint32								scissorCount;
		&scissor,													// const VkRect2D*						pScissors;
	};

	const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,													// const void*								pNext;
		(VkPipelineRasterizationStateCreateFlags)0,					// VkPipelineRasterizationStateCreateFlags	flags;
		VK_FALSE,													// VkBool32									depthClampEnable;
		VK_FALSE,													// VkBool32									rasterizerDiscardEnable;
		VK_POLYGON_MODE_FILL,										// VkPolygonMode							polygonMode;
		VK_CULL_MODE_NONE,											// VkCullModeFlags							cullMode;
		VK_FRONT_FACE_COUNTER_CLOCKWISE,							// VkFrontFace								frontFace;
		VK_FALSE,													// VkBool32									depthBiasEnable;
		0.0f,														// float									depthBiasConstantFactor;
		0.0f,														// float									depthBiasClamp;
		0.0f,														// float									depthBiasSlopeFactor;
		1.0f,														// float									lineWidth;
	};

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

	const VkStencilOpState stencilOpState = makeStencilOpState(
		VK_STENCIL_OP_KEEP,											// stencil fail
		VK_STENCIL_OP_ZERO,											// depth & stencil pass
		VK_STENCIL_OP_KEEP,											// depth only fail
		VK_COMPARE_OP_EQUAL,										// compare op
		~0u,														// compare mask
		~0u,														// write mask
		0u);														// reference

	VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,													// const void*								pNext;
		(VkPipelineDepthStencilStateCreateFlags)0,					// VkPipelineDepthStencilStateCreateFlags	flags;
		VK_FALSE,													// VkBool32									depthTestEnable;
		VK_FALSE,													// VkBool32									depthWriteEnable;
		VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
		VK_FALSE,													// VkBool32									depthBoundsTestEnable;
		VK_FALSE,													// VkBool32									stencilTestEnable;
		stencilOpState,												// VkStencilOpState							front;
		stencilOpState,												// VkStencilOpState							back;
		0.0f,														// float									minDepthBounds;
		1.0f,														// float									maxDepthBounds;
	};

	const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
	const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
	{
		VK_FALSE,													// VkBool32					blendEnable;
		VK_BLEND_FACTOR_ONE,										// VkBlendFactor			srcColorBlendFactor;
		VK_BLEND_FACTOR_ZERO,										// VkBlendFactor			dstColorBlendFactor;
		VK_BLEND_OP_ADD,											// VkBlendOp				colorBlendOp;
		VK_BLEND_FACTOR_ONE,										// VkBlendFactor			srcAlphaBlendFactor;
		VK_BLEND_FACTOR_ZERO,										// VkBlendFactor			dstAlphaBlendFactor;
		VK_BLEND_OP_ADD,											// VkBlendOp				alphaBlendOp;
		colorComponentsAll,											// VkColorComponentFlags	colorWriteMask;
	};

	const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
		DE_NULL,													// const void*									pNext;
		(VkPipelineColorBlendStateCreateFlags)0,					// VkPipelineColorBlendStateCreateFlags			flags;
		VK_FALSE,													// VkBool32										logicOpEnable;
		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
		1u,															// deUint32										attachmentCount;
		&pipelineColorBlendAttachmentState,							// const VkPipelineColorBlendAttachmentState*	pAttachments;
		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConstants[4];
	};

	const VkPipelineShaderStageCreateInfo pShaderStages[] =
	{
		{
			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
			DE_NULL,												// const void*							pNext;
			(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
			VK_SHADER_STAGE_VERTEX_BIT,								// VkShaderStageFlagBits				stage;
			vertexModule,											// VkShaderModule						module;
			"main",													// const char*							pName;
			DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
		},
		{
			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
			DE_NULL,												// const void*							pNext;
			(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
			VK_SHADER_STAGE_FRAGMENT_BIT,							// VkShaderStageFlagBits				stage;
			fragmentModule,											// VkShaderModule						module;
			"main",													// const char*							pName;
			DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
		}
	};

	const VkGraphicsPipelineCreateInfo	graphicsPipelineInfo =
	{
		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
		DE_NULL,											// const void*										pNext;
		0u,													// VkPipelineCreateFlags							flags;
		DE_LENGTH_OF_ARRAY(pShaderStages),					// deUint32											stageCount;
		pShaderStages,										// const VkPipelineShaderStageCreateInfo*			pStages;
		&vertexInputStateInfo,								// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
		&pipelineInputAssemblyStateInfo,					// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
		DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
		&pipelineViewportStateInfo,							// const VkPipelineViewportStateCreateInfo*			pViewportState;
		&pipelineRasterizationStateInfo,					// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
		&pipelineMultisampleStateInfo,						// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
		&pipelineDepthStencilStateInfo,						// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
		&pipelineColorBlendStateInfo,						// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
		DE_NULL,											// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
		pipelineLayout,										// VkPipelineLayout									layout;
		renderPass,											// VkRenderPass										renderPass;
		subpass,											// deUint32											subpass;
		DE_NULL,											// VkPipeline										basePipelineHandle;
		0,													// deInt32											basePipelineIndex;
	};

	return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
}

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<VkFramebuffer> makeFramebuffer (const DeviceInterface&	vk,
									 const VkDevice			device,
									 const VkRenderPass		renderPass,
									 const deUint32			attachmentCount,
									 const VkImageView*		pAttachments,
									 const IVec2			size)
{
	const VkFramebufferCreateInfo framebufferInfo =
	{
		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
		DE_NULL,
		(VkFramebufferCreateFlags)0,
		renderPass,
		attachmentCount,
		pAttachments,
		static_cast<deUint32>(size.x()),
		static_cast<deUint32>(size.y()),
		1u,
	};

	return createFramebuffer(vk, device, &framebufferInfo);
}

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

MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
{
        MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
        VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
        return alloc;
}

MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
{
        MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
        VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
        return alloc;
}

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;
		const Vec4		color		= isIntegerFormat ? COLOR_TABLE_INT[colorIdx].cast<float>() : 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)
				image.setPixel(COLOR_TABLE_INT[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_ASSERT("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_ASSERT("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, const CaseDef& caseSpec) :
	m_caseDef(caseSpec),
	m_haveMaintenance2(de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance2")),
	m_vk(context.getDeviceInterface()),
	m_device(context.getDevice()),
	m_queue(context.getUniversalQueue()),
	m_queueFamilyIndex(context.getUniversalQueueFamilyIndex()),
	m_allocator(context.getDefaultAllocator())
	{
	}

	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;
	Allocator&							m_allocator;

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

	bool								m_imageIsIntegerFormat;
	bool								m_viewIsIntegerFormat;

	// Target image for upload paths
	Move<VkImage>						m_image;
	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::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_image									= 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_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_ASSERT("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_ASSERT("Unsupported download method");
	}

	VK_CHECK(m_vk.endCommandBuffer(*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_HOST_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 ? REFERENCE_CLEAR_COLOR_INT[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::VkImageViewUsageCreateInfoKHR 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)
			tcu::clear(imageAccess, COLOR_TABLE_INT[colorIdx]);
		else
			tcu::clear(imageAccess, COLOR_TABLE_FLOAT[colorIdx]);
		layerOffset += layerSize;
	}

	flushMappedMemoryRange(m_vk, m_device, m_uCopy.colorBufferAlloc->getMemory(), m_uCopy.colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);

	// 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			outputMask;
		VK_ACCESS_TRANSFER_WRITE_BIT,						// VkAccessFlags			inputMask;
		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			outputMask;
		VK_ACCESS_TRANSFER_READ_BIT,						// VkAccessFlags			inputMask;
		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_HOST_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));
		flushMappedMemoryRange(m_vk, m_device, m_uDraw.vertexBufferAlloc->getMemory(), m_uDraw.vertexBufferAlloc->getOffset(), vertexBufferSize);
	}

	// 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::VkImageViewUsageCreateInfoKHR 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
	m_uDraw.framebuffer	= makeFramebuffer(m_vk, m_device, *m_uDraw.renderPass, static_cast<deUint32>(m_uDraw.attachmentHandles.size()), &m_uDraw.attachmentHandles[0], m_caseDef.size.swizzle(0, 1));

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

			const VkRect2D			renderArea	=
			{
				makeOffset2D(0, 0),
				makeExtent2D(m_caseDef.size.x(), m_caseDef.size.y()),
			};

			const VkRenderPassBeginInfo	renderPassBeginInfo	=
			{
				VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType         sType;
				DE_NULL,									// const void*             pNext;
				*m_uDraw.renderPass,							// VkRenderPass            renderPass;
				*m_uDraw.framebuffer,							// VkFramebuffer           framebuffer;
				renderArea,									// VkRect2D                renderArea;
				static_cast<deUint32>(clearValues.size()),	// deUint32                clearValueCount;
				&clearValues[0],							// const VkClearValue*     pClearValues;
			};

			m_vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
		}

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

		m_vk.cmdEndRenderPass(*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::VkImageViewUsageCreateInfoKHR 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::VkImageViewUsageCreateInfoKHR 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			outputMask;
		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			inputMask;
		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);
}

bool isStorageImageExtendedFormat (const VkFormat format)
{
	switch (format)
	{
		case VK_FORMAT_R32G32_SFLOAT:
		case VK_FORMAT_R32G32_SINT:
		case VK_FORMAT_R32G32_UINT:
		case VK_FORMAT_R16G16B16A16_UNORM:
		case VK_FORMAT_R16G16B16A16_SNORM:
		case VK_FORMAT_R16G16_SFLOAT:
		case VK_FORMAT_R16G16_UNORM:
		case VK_FORMAT_R16G16_SNORM:
		case VK_FORMAT_R16G16_SINT:
		case VK_FORMAT_R16G16_UINT:
		case VK_FORMAT_R16_SFLOAT:
		case VK_FORMAT_R16_UNORM:
		case VK_FORMAT_R16_SNORM:
		case VK_FORMAT_R16_SINT:
		case VK_FORMAT_R16_UINT:
		case VK_FORMAT_R8G8_UNORM:
		case VK_FORMAT_R8G8_SNORM:
		case VK_FORMAT_R8G8_SINT:
		case VK_FORMAT_R8G8_UINT:
		case VK_FORMAT_R8_UNORM:
		case VK_FORMAT_R8_SNORM:
		case VK_FORMAT_R8_SINT:
		case VK_FORMAT_R8_UINT:
			return true;

		default:
			return false;
	}
}

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

	// If this is a VK_KHR_image_format_list test, check that the extension is supported
	if (caseDef.isFormatListTest && !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_image_format_list"))
		TCU_THROW(NotSupportedError, "VK_KHR_image_format_list not supported");

	// 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;
	default:
		DE_ASSERT("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;
	default:
		DE_ASSERT("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");

	// 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 &&
	    !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance2"))
	{
		TCU_THROW(NotSupportedError, "Image format doesn't support upload/download method");
	}

	// 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));
	flushMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);

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

	// Verify results
	{
		invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);

		// 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* 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++)
				for (int download = 0; download < DOWNLOAD_LAST; download++)
				{
					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
					};

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

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

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

	return testGroup.release();
}

} // image
} // vkt
