/*------------------------------------------------------------------------
 * 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 vktPipelineRenderToImageTests.cpp
 * \brief Render to image tests
 *//*--------------------------------------------------------------------*/

#include "vktPipelineRenderToImageTests.hpp"
#include "vktPipelineMakeUtil.hpp"
#include "vktTestCase.hpp"
#include "vktTestCaseUtil.hpp"
#include "vktPipelineVertexUtil.hpp"
#include "vktTestGroupUtil.hpp"
#include "vkObjUtil.hpp"

#include "vkMemUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkPrograms.hpp"
#include "vkImageUtil.hpp"
#include "vkCmdUtil.hpp"

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

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

#include <string>
#include <vector>
#include <set>

namespace vkt
{
namespace pipeline
{
namespace
{
using namespace vk;
using de::UniquePtr;
using de::MovePtr;
using de::SharedPtr;
using tcu::IVec3;
using tcu::Vec4;
using tcu::UVec4;
using tcu::IVec2;
using tcu::IVec4;
using tcu::BVec4;
using std::vector;

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

enum Constants
{
	NUM_CUBE_FACES					= 6,
	REFERENCE_COLOR_VALUE			= 125,
	REFERENCE_STENCIL_VALUE			= 42,
	MAX_SIZE						= -1,	//!< Should be queried at runtime and replaced with max possible value
	MAX_VERIFICATION_REGION_SIZE	= 32,	//!<  Limit the checked area to a small size, especially for huge images
	MAX_VERIFICATION_REGION_DEPTH	= 8,

	MASK_W					= (1 | 0 | 0 | 0),
	MASK_W_LAYERS			= (1 | 0 | 0 | 8),
	MASK_WH					= (1 | 2 | 0 | 0),
	MASK_WH_LAYERS			= (1 | 2 | 0 | 8),
	MASK_WHD				= (1 | 2 | 4 | 0),
};

enum AllocationKind
{
	ALLOCATION_KIND_SUBALLOCATED = 0,
	ALLOCATION_KIND_DEDICATED,
};

static const float	REFERENCE_DEPTH_VALUE	= 1.0f;
static const Vec4	COLOR_TABLE[]			=
{
	Vec4(0.9f, 0.0f, 0.0f, 1.0f),
	Vec4(0.6f, 1.0f, 0.0f, 1.0f),
	Vec4(0.3f, 0.0f, 1.0f, 1.0f),
	Vec4(0.1f, 1.0f, 1.0f, 1.0f),
	Vec4(0.8f, 1.0f, 0.0f, 1.0f),
	Vec4(0.5f, 0.0f, 1.0f, 1.0f),
	Vec4(0.2f, 0.0f, 0.0f, 1.0f),
	Vec4(1.0f, 1.0f, 0.0f, 1.0f),
};

struct CaseDef
{
	VkImageViewType	viewType;
	IVec4			imageSizeHint;			//!< (w, h, d, layers), a component may have a symbolic value MAX_SIZE
	VkFormat		colorFormat;
	VkFormat		depthStencilFormat;		//! A depth/stencil format, or UNDEFINED if not used
	AllocationKind	allocationKind;
};

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

template<typename T>
inline VkDeviceSize sizeInBytes (const vector<T>& vec)
{
	return vec.size() * sizeof(vec[0]);
}

inline bool isCube (const VkImageViewType viewType)
{
	return (viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY);
}

inline VkDeviceSize product (const IVec4& v)
{
	return ((static_cast<VkDeviceSize>(v.x()) * v.y()) * v.z()) * v.w();
}

template<typename T>
inline T sum (const vector<T>& v)
{
	T total = static_cast<T>(0);
	for (typename vector<T>::const_iterator it = v.begin(); it != v.end(); ++it)
		total += *it;
	return total;
}

template <typename T, int Size>
int findIndexOfMaxComponent (const tcu::Vector<T, Size>& vec)
{
	int index	= 0;
	T	value	= vec[0];

	for (int i = 1; i < Size; ++i)
	{
		if (vec[i] > value)
		{
			index	= i;
			value	= vec[i];
		}
	}

	return index;
}

inline int maxLayersOrDepth (const IVec4& size)
{
	// This is safe because 3D images must have layers (w) = 1
	return deMax32(size.z(), size.w());
}

de::MovePtr<Allocation> bindBuffer (const InstanceInterface&	vki,
									const DeviceInterface&		vkd,
									const VkPhysicalDevice&		physDevice,
									const VkDevice				device,
									const VkBuffer&				buffer,
									const MemoryRequirement		requirement,
									Allocator&					allocator,
									AllocationKind				allocationKind)
{
	switch (allocationKind)
	{
		case ALLOCATION_KIND_SUBALLOCATED:
		{
			return vk::bindBuffer(vkd, device, allocator, buffer, requirement);
		}

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

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

de::MovePtr<Allocation> bindImage (const InstanceInterface&		vki,
								   const DeviceInterface&		vkd,
								   const VkPhysicalDevice&		physDevice,
								   const VkDevice				device,
								   const VkImage&				image,
								   const MemoryRequirement		requirement,
								   Allocator&					allocator,
								   AllocationKind				allocationKind)
{
	switch (allocationKind)
	{
		case ALLOCATION_KIND_SUBALLOCATED:
		{
			return vk::bindImage(vkd, device, allocator, image, requirement);
		}

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

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

// This is very test specific, so be careful if you want to reuse this code.
Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&		vk,
									   const VkDevice				device,
									   const VkPipeline				basePipeline,		// for derivatives
									   const VkPipelineLayout		pipelineLayout,
									   const VkRenderPass			renderPass,
									   const VkShaderModule			vertexModule,
									   const VkShaderModule			fragmentModule,
									   const IVec2&					renderSize,
									   const VkPrimitiveTopology	topology,
									   const deUint32				subpass,
									   const bool					useDepth,
									   const bool					useStencil)
{
	const VkVertexInputBindingDescription vertexInputBindingDescription =
	{
		0u,								// uint32_t				binding;
		sizeof(Vertex4RGBA),			// uint32_t				stride;
		VK_VERTEX_INPUT_RATE_VERTEX,	// VkVertexInputRate	inputRate;
	};

	const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
	{
		{
			0u,								// uint32_t			location;
			0u,								// uint32_t			binding;
			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat			format;
			0u,								// uint32_t			offset;
		},
		{
			1u,								// uint32_t			location;
			0u,								// uint32_t			binding;
			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat			format;
			sizeof(Vec4),					// uint32_t			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,															// uint32_t									vertexBindingDescriptionCount;
		&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
		DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),		// uint32_t									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(renderSize);
	const VkRect2D		scissor		= makeRect2D(renderSize);

	const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType						sType;
		DE_NULL,												// const void*							pNext;
		(VkPipelineViewportStateCreateFlags)0,					// VkPipelineViewportStateCreateFlags	flags;
		1u,														// uint32_t								viewportCount;
		&viewport,												// const VkViewport*					pViewports;
		1u,														// uint32_t								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_KEEP,									// depth & stencil pass
		VK_STENCIL_OP_KEEP,									// depth only fail
		VK_COMPARE_OP_EQUAL,								// compare op
		~0u,												// compare mask
		~0u,												// write mask
		static_cast<deUint32>(REFERENCE_STENCIL_VALUE));	// reference

	VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,													// const void*								pNext;
		(VkPipelineDepthStencilStateCreateFlags)0,					// VkPipelineDepthStencilStateCreateFlags	flags;
		useDepth,													// VkBool32									depthTestEnable;
		VK_FALSE,													// VkBool32									depthWriteEnable;
		VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
		VK_FALSE,													// VkBool32									depthBoundsTestEnable;
		useStencil,													// 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;
	// Number of blend attachments must equal the number of color attachments during any subpass.
	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 VkPipelineCreateFlags			flags = (basePipeline == DE_NULL ? VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT
																		 : VK_PIPELINE_CREATE_DERIVATIVE_BIT);

	const VkGraphicsPipelineCreateInfo	graphicsPipelineInfo =
	{
		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
		DE_NULL,											// const void*										pNext;
		flags,												// 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;
		basePipeline,										// VkPipeline										basePipelineHandle;
		-1,													// deInt32											basePipelineIndex;
	};

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

//! Make a render pass with one subpass per color attachment and depth/stencil attachment (if used).
Move<VkRenderPass> makeRenderPass (const DeviceInterface&		vk,
								   const VkDevice				device,
								   const VkFormat				colorFormat,
								   const VkFormat				depthStencilFormat,
								   const deUint32				numLayers,
								   const VkImageLayout			initialColorImageLayout			= VK_IMAGE_LAYOUT_UNDEFINED,
								   const VkImageLayout			initialDepthStencilImageLayout	= VK_IMAGE_LAYOUT_UNDEFINED)
{
	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;
		initialColorImageLayout,							// VkImageLayout					initialLayout;
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					finalLayout;
	};
	vector<VkAttachmentDescription> attachmentDescriptions(numLayers, colorAttachmentDescription);

	const VkAttachmentDescription depthStencilAttachmentDescription =
	{
		(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
		depthStencilFormat,									// VkFormat							format;
		VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
		VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				storeOp;
		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				stencilLoadOp;
		VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
		initialDepthStencilImageLayout,						// VkImageLayout					initialLayout;
		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout					finalLayout;
	};

	if (depthStencilFormat != VK_FORMAT_UNDEFINED)
		attachmentDescriptions.insert(attachmentDescriptions.end(), numLayers, depthStencilAttachmentDescription);

	// Create a subpass for each attachment (each attachement is a layer of an arrayed image).
	vector<VkAttachmentReference>	colorAttachmentReferences		(numLayers);
	vector<VkAttachmentReference>	depthStencilAttachmentReferences(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;
		};
		const VkAttachmentReference depthStencilAttachmentRef =
		{
			i + numLayers,										// deUint32			attachment;
			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout	layout;
		};

		colorAttachmentReferences[i]		= attachmentRef;
		depthStencilAttachmentReferences[i]	= depthStencilAttachmentRef;

		const VkAttachmentReference*	pDepthStencilAttachment	= (depthStencilFormat != VK_FORMAT_UNDEFINED ? &depthStencilAttachmentReferences[i] : DE_NULL);
		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;
			pDepthStencilAttachment,						// 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<VkImage> makeImage (const DeviceInterface&		vk,
						 const VkDevice				device,
						 VkImageCreateFlags			flags,
						 VkImageType				imageType,
						 const VkFormat				format,
						 const IVec3&				size,
						 const deUint32				numMipLevels,
						 const deUint32				numLayers,
						 const VkImageUsageFlags	usage)
{
	const VkImageCreateInfo imageParams =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType;
		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));
}

//! Get a reference clear value based on color format.
VkClearValue getClearValue (const VkFormat format)
{
	if (isUintFormat(format) || isIntFormat(format))
		return makeClearValueColorU32(REFERENCE_COLOR_VALUE, REFERENCE_COLOR_VALUE, REFERENCE_COLOR_VALUE, REFERENCE_COLOR_VALUE);
	else
		return makeClearValueColorF32(1.0f, 1.0f, 1.0f, 1.0f);
}

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

//! A half-viewport quad. Use with TRIANGLE_STRIP topology.
vector<Vertex4RGBA> genFullQuadVertices (const int subpassCount)
{
	vector<Vertex4RGBA>	vectorData;
	for (int subpassNdx = 0; subpassNdx < subpassCount; ++subpassNdx)
	{
		Vertex4RGBA data =
		{
			Vec4(0.0f, -1.0f, 0.0f, 1.0f),
			COLOR_TABLE[subpassNdx % DE_LENGTH_OF_ARRAY(COLOR_TABLE)],
		};
		vectorData.push_back(data);
		data.position	= Vec4(0.0f,  1.0f, 0.0f, 1.0f);
		vectorData.push_back(data);
		data.position	= Vec4(1.0f, -1.0f, 0.0f, 1.0f);
		vectorData.push_back(data);
		data.position	= Vec4(1.0f,  1.0f, 0.0f, 1.0f);
		vectorData.push_back(data);
	}
	return vectorData;
}

VkImageType getImageType (const VkImageViewType viewType)
{
	switch (viewType)
	{
		case VK_IMAGE_VIEW_TYPE_1D:
		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
			return VK_IMAGE_TYPE_1D;

		case VK_IMAGE_VIEW_TYPE_2D:
		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
		case VK_IMAGE_VIEW_TYPE_CUBE:
		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
			return VK_IMAGE_TYPE_2D;

		case VK_IMAGE_VIEW_TYPE_3D:
			return VK_IMAGE_TYPE_3D;

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

//! ImageViewType for accessing a single layer/slice of an image
VkImageViewType getImageViewSliceType (const VkImageViewType viewType)
{
	switch (viewType)
	{
		case VK_IMAGE_VIEW_TYPE_1D:
		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
			return VK_IMAGE_VIEW_TYPE_1D;

		case VK_IMAGE_VIEW_TYPE_2D:
		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
		case VK_IMAGE_VIEW_TYPE_CUBE:
		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
		case VK_IMAGE_VIEW_TYPE_3D:
			return VK_IMAGE_VIEW_TYPE_2D;

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

VkImageCreateFlags getImageCreateFlags (const VkImageViewType viewType)
{
	VkImageCreateFlags	flags	= (VkImageCreateFlags)0;

	if (viewType == VK_IMAGE_VIEW_TYPE_3D)	flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR;
	if (isCube(viewType))					flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;

	return flags;
}

void generateExpectedImage (const tcu::PixelBufferAccess& outputImage, const IVec2& renderSize, const int colorDepthOffset)
{
	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(outputImage.getFormat().type);
	const bool						isInt			= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
	const VkClearValue				clearValue		= getClearValue(mapTextureFormat(outputImage.getFormat()));

	if (isInt)
		tcu::clear(outputImage, IVec4(clearValue.color.int32));
	else
		tcu::clear(outputImage, Vec4(clearValue.color.float32));

	for (int z = 0; z < outputImage.getDepth(); ++z)
	{
		const Vec4& setColor	= COLOR_TABLE[(z + colorDepthOffset) % DE_LENGTH_OF_ARRAY(COLOR_TABLE)];
		const IVec4 setColorInt	= (static_cast<float>(REFERENCE_COLOR_VALUE) * setColor).cast<deInt32>();

		for (int y = 0;					y < renderSize.y(); ++y)
		for (int x = renderSize.x()/2;	x < renderSize.x(); ++x)
		{
			if (isInt)
				outputImage.setPixel(setColorInt, x, y, z);
			else
				outputImage.setPixel(setColor, x, y, z);
		}
	}
}

deUint32 selectMatchingMemoryType (const VkPhysicalDeviceMemoryProperties& deviceMemProps, deUint32 allowedMemTypeBits, MemoryRequirement requirement)
{
	const deUint32	compatibleTypes	= getCompatibleMemoryTypes(deviceMemProps, requirement);
	const deUint32	candidates		= allowedMemTypeBits & compatibleTypes;

	if (candidates == 0)
		TCU_THROW(NotSupportedError, "No compatible memory type found");

	return (deUint32)deCtz32(candidates);
}

IVec4 getMaxImageSize (const VkImageViewType viewType, const IVec4& sizeHint)
{
	//Limits have been taken from the vulkan specification
	IVec4 size = IVec4(
		sizeHint.x() != MAX_SIZE ? sizeHint.x() : 4096,
		sizeHint.y() != MAX_SIZE ? sizeHint.y() : 4096,
		sizeHint.z() != MAX_SIZE ? sizeHint.z() : 256,
		sizeHint.w() != MAX_SIZE ? sizeHint.w() : 256);

	switch (viewType)
	{
		case VK_IMAGE_VIEW_TYPE_1D:
		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
			size.x() = deMin32(4096, size.x());
			break;

		case VK_IMAGE_VIEW_TYPE_2D:
		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
			size.x() = deMin32(4096, size.x());
			size.y() = deMin32(4096, size.y());
			break;

		case VK_IMAGE_VIEW_TYPE_3D:
			size.x() = deMin32(256, size.x());
			size.y() = deMin32(256, size.y());
			break;

		case VK_IMAGE_VIEW_TYPE_CUBE:
		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
			size.x() = deMin32(4096, size.x());
			size.y() = deMin32(4096, size.y());
			size.w() = deMin32(252, size.w());
			size.w() = NUM_CUBE_FACES * (size.w() / NUM_CUBE_FACES);	// round down to 6 faces
			break;

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

	return size;
}

deUint32 getMemoryTypeNdx (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();

	const VkPhysicalDeviceMemoryProperties	memoryProperties	= getPhysicalDeviceMemoryProperties(vki, physDevice);
	Move<VkImage>							colorImage;
	VkMemoryRequirements					memReqs;

	const VkImageUsageFlags					imageUsage	= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
	const IVec4								imageSize	= getMaxImageSize(caseDef.viewType, caseDef.imageSizeHint);

	//create image, don't bind any memory to it
	colorImage	= makeImage(vk, device, getImageCreateFlags(caseDef.viewType), getImageType(caseDef.viewType), caseDef.colorFormat,
								imageSize.swizzle(0, 1, 2), 1u, imageSize.w(), imageUsage);

	vk.getImageMemoryRequirements(device, *colorImage, &memReqs);
	return selectMatchingMemoryType(memoryProperties, memReqs.memoryTypeBits, MemoryRequirement::Any);
}

VkDeviceSize getMaxDeviceHeapSize (Context& context, const CaseDef& caseDef)
{
	const InstanceInterface&				vki					= context.getInstanceInterface();
	const VkPhysicalDevice					physDevice			= context.getPhysicalDevice();
	const VkPhysicalDeviceMemoryProperties	memoryProperties	= getPhysicalDeviceMemoryProperties(vki, physDevice);
	const deUint32							memoryTypeNdx		= getMemoryTypeNdx (context, caseDef);

	return memoryProperties.memoryHeaps[memoryProperties.memoryTypes[memoryTypeNdx].heapIndex].size;
}

//! Get a smaller image size. Returns a vector of zeroes, if it can't reduce more.
IVec4 getReducedImageSize (const CaseDef& caseDef, IVec4 size)
{
	const int maxIndex		= findIndexOfMaxComponent(size);
	const int reducedSize	= size[maxIndex] >> 1;

	switch (caseDef.viewType)
	{
		case VK_IMAGE_VIEW_TYPE_CUBE:
		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
			if (maxIndex < 2)
				size.x() = size.y() = reducedSize;
			else if (maxIndex == 3 && reducedSize >= NUM_CUBE_FACES)
				size.w() = NUM_CUBE_FACES * (reducedSize / NUM_CUBE_FACES); // round down to a multiple of 6
			else
				size = IVec4(0);
			break;

		default:
			size[maxIndex] = reducedSize;
			break;
	}

	if (reducedSize == 0)
		size = IVec4(0);

	return size;
}

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

VkImageAspectFlags getFormatAspectFlags (const VkFormat format)
{
	if (format == VK_FORMAT_UNDEFINED)
		return 0;

	const tcu::TextureFormat::ChannelOrder	order	= mapVkFormat(format).order;

	switch (order)
	{
		case tcu::TextureFormat::DS:	return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
		case tcu::TextureFormat::D:		return VK_IMAGE_ASPECT_DEPTH_BIT;
		case tcu::TextureFormat::S:		return VK_IMAGE_ASPECT_STENCIL_BIT;
		default:						return VK_IMAGE_ASPECT_COLOR_BIT;
	}
}

void initPrograms (SourceCollections& programCollection, const CaseDef caseDef)
{
	const int	numComponents	= getNumUsedChannels(mapVkFormat(caseDef.colorFormat).order);
	const bool	isUint			= isUintFormat(caseDef.colorFormat);
	const bool	isSint			= isIntFormat(caseDef.colorFormat);

	// Vertex shader
	{
		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("vert") << glu::VertexSource(src.str());
	}

	// Fragment shader
	{
		std::ostringstream colorValue;
		colorValue << REFERENCE_COLOR_VALUE;
		const std::string colorFormat	= getColorFormatStr(numComponents, isUint, isSint);
		const std::string colorInteger	= (isUint || isSint ? " * "+colorFormat+"("+colorValue.str()+")" :"");

		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 << " o_color;\n"
			<< "\n"
			<< "void main(void)\n"
			<< "{\n"
			<< "    o_color = " << colorFormat << "("
			<< (numComponents == 1 ? "in_color.r"   :
				numComponents == 2 ? "in_color.rg"  :
				numComponents == 3 ? "in_color.rgb" : "in_color")
			<< colorInteger
			<< ");\n"
			<< "}\n";

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

//! See testAttachmentSize() description
tcu::TestStatus testWithSizeReduction (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();
	const VkQueue					queue				= context.getUniversalQueue();
	const deUint32					queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	Allocator&						allocator			= context.getDefaultAllocator();

	// The memory might be too small to allocate a largest possible attachment, so try to account for that.
	const bool						useDepthStencil		= (caseDef.depthStencilFormat != VK_FORMAT_UNDEFINED);

	IVec4							imageSize			= getMaxImageSize(caseDef.viewType, caseDef.imageSizeHint);
	VkDeviceSize					colorSize			= product(imageSize) * tcu::getPixelSize(mapVkFormat(caseDef.colorFormat));
	VkDeviceSize					depthStencilSize	= (useDepthStencil ? product(imageSize) * tcu::getPixelSize(mapVkFormat(caseDef.depthStencilFormat)) : 0ull);

	const VkDeviceSize				reserveForChecking	= 500ull * 1024ull;	//left 512KB
	const float						additionalMemory	= 1.15f;			//left some free memory on device (15%)
	VkDeviceSize					neededMemory		= static_cast<VkDeviceSize>(static_cast<float>(colorSize + depthStencilSize) * additionalMemory) + reserveForChecking;
	VkDeviceSize					maxMemory			= getMaxDeviceHeapSize(context, caseDef) >> 2;

	vk::PlatformMemoryLimits		memoryLimits;
	context.getTestContext().getPlatform().getVulkanPlatform().getMemoryLimits(memoryLimits);
	maxMemory = std::min(maxMemory, VkDeviceSize(memoryLimits.totalSystemMemory));

	const VkDeviceSize				deviceMemoryBudget	= std::min(neededMemory, maxMemory);
	bool							allocationPossible	= false;

	// Keep reducing the size, if image size is too big
	while (neededMemory > deviceMemoryBudget)
	{
		imageSize = getReducedImageSize(caseDef, imageSize);

		if (imageSize == IVec4())
			return tcu::TestStatus::fail("Couldn't create an image with required size");

		colorSize			= product(imageSize) * tcu::getPixelSize(mapVkFormat(caseDef.colorFormat));
		depthStencilSize	= (useDepthStencil ? product(imageSize) * tcu::getPixelSize(mapVkFormat(caseDef.depthStencilFormat)) : 0ull);
		neededMemory		= static_cast<VkDeviceSize>(static_cast<double>(colorSize + depthStencilSize) * additionalMemory);
	}

	// Keep reducing the size, if allocation return out of any memory
	while (!allocationPossible)
	{
		VkDeviceMemory				object			= 0;
		const VkMemoryAllocateInfo	allocateInfo	=
		{
			VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//VkStructureType	sType;
			DE_NULL,								//const void*		pNext;
			neededMemory,							//VkDeviceSize		allocationSize;
			getMemoryTypeNdx(context, caseDef)		//deUint32			memoryTypeIndex;
		};

		const VkResult				result			= vk.allocateMemory(device, &allocateInfo, DE_NULL, &object);

		if (VK_ERROR_OUT_OF_DEVICE_MEMORY == result || VK_ERROR_OUT_OF_HOST_MEMORY == result)
		{
			imageSize = getReducedImageSize(caseDef, imageSize);

			if (imageSize == IVec4())
				return tcu::TestStatus::fail("Couldn't create an image with required size");

			colorSize			= product(imageSize) * tcu::getPixelSize(mapVkFormat(caseDef.colorFormat));
			depthStencilSize	= (useDepthStencil ? product(imageSize) * tcu::getPixelSize(mapVkFormat(caseDef.depthStencilFormat)) : 0ull);
			neededMemory		= static_cast<VkDeviceSize>(static_cast<double>(colorSize + depthStencilSize) * additionalMemory) + reserveForChecking;
		}
		else if (VK_SUCCESS != result)
		{
			return tcu::TestStatus::fail("Couldn't allocate memory");
		}
		else
		{
			//free memory using Move pointer
			Move<VkDeviceMemory> memoryAllocated (check<VkDeviceMemory>(object), Deleter<VkDeviceMemory>(vk, device, DE_NULL));
			allocationPossible = true;
		}
	}

	context.getTestContext().getLog()
		<< tcu::TestLog::Message << "Using an image with size (width, height, depth, layers) = " << imageSize << tcu::TestLog::EndMessage;

	// "Slices" is either the depth of a 3D image, or the number of layers of an arrayed image
	const deInt32					numSlices			= maxLayersOrDepth(imageSize);

	// Determine the verification bounds. The checked region will be in the center of the rendered image
	const IVec4	checkSize	= tcu::min(imageSize, IVec4(MAX_VERIFICATION_REGION_SIZE,
														MAX_VERIFICATION_REGION_SIZE,
														MAX_VERIFICATION_REGION_DEPTH,
														MAX_VERIFICATION_REGION_DEPTH));
	const IVec4	checkOffset	= (imageSize - checkSize) / 2;

	// Only make enough space for the check region
	const VkDeviceSize				colorBufferSize		= product(checkSize) * tcu::getPixelSize(mapVkFormat(caseDef.colorFormat));
	const Unique<VkBuffer>			colorBuffer			(makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const UniquePtr<Allocation>		colorBufferAlloc	(bindBuffer(vki, vk, physDevice, device, *colorBuffer, MemoryRequirement::HostVisible, allocator, caseDef.allocationKind));

	{
		deMemset(colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
		flushAlloc(vk, device, *colorBufferAlloc);
	}

	const Unique<VkShaderModule>	vertexModule	(createShaderModule			(vk, device, context.getBinaryCollection().get("vert"), 0u));
	const Unique<VkShaderModule>	fragmentModule	(createShaderModule			(vk, device, context.getBinaryCollection().get("frag"), 0u));
	const Unique<VkRenderPass>		renderPass		(makeRenderPass				(vk, device, caseDef.colorFormat, caseDef.depthStencilFormat, static_cast<deUint32>(numSlices),
																				 (caseDef.viewType == VK_IMAGE_VIEW_TYPE_3D) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
																															 : VK_IMAGE_LAYOUT_UNDEFINED));
	const Unique<VkPipelineLayout>	pipelineLayout	(makePipelineLayout			(vk, device));
	vector<SharedPtrVkPipeline>		pipelines;

	Move<VkImage>					colorImage;
	MovePtr<Allocation>				colorImageAlloc;
	vector<SharedPtrVkImageView>	colorAttachments;
	Move<VkImage>					depthStencilImage;
	MovePtr<Allocation>				depthStencilImageAlloc;
	vector<SharedPtrVkImageView>	depthStencilAttachments;
	vector<VkImageView>				attachmentHandles;			// all attachments (color and d/s)
	Move<VkBuffer>					vertexBuffer;
	MovePtr<Allocation>				vertexBufferAlloc;
	Move<VkFramebuffer>				framebuffer;

	// Create a color image
	{
		const VkImageUsageFlags	imageUsage	= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;

		colorImage		= makeImage(vk, device, getImageCreateFlags(caseDef.viewType), getImageType(caseDef.viewType), caseDef.colorFormat,
									imageSize.swizzle(0, 1, 2), 1u, imageSize.w(), imageUsage);
		colorImageAlloc	= bindImage(vki, vk, physDevice, device, *colorImage, MemoryRequirement::Any, allocator, caseDef.allocationKind);
	}

	// Create a depth/stencil image (always a 2D image, optionally layered)
	if (useDepthStencil)
	{
		const VkImageUsageFlags	imageUsage	= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;

		depthStencilImage		= makeImage(vk, device, (VkImageCreateFlags)0, VK_IMAGE_TYPE_2D, caseDef.depthStencilFormat,
											IVec3(imageSize.x(), imageSize.y(), 1), 1u, numSlices, imageUsage);
		depthStencilImageAlloc	= bindImage(vki, vk, physDevice, device, *depthStencilImage, MemoryRequirement::Any, allocator, caseDef.allocationKind);
	}

	// Create a vertex buffer
	{
		const vector<Vertex4RGBA>	vertices			= genFullQuadVertices(numSlices);
		const VkDeviceSize			vertexBufferSize	= sizeInBytes(vertices);

		vertexBuffer		= makeBuffer(vk, device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
		vertexBufferAlloc	= bindBuffer(vki, vk, physDevice, device, *vertexBuffer, MemoryRequirement::HostVisible, allocator, caseDef.allocationKind);

		deMemcpy(vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast<std::size_t>(vertexBufferSize));
		flushAlloc(vk, device, *vertexBufferAlloc);
	}

	// Prepare color image upfront for rendering to individual slices.  3D slices aren't separate subresources, so they shouldn't be transitioned
	// during each subpass like array layers.
	if (caseDef.viewType == VK_IMAGE_VIEW_TYPE_3D)
	{
		const Unique<VkCommandPool>		cmdPool		(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
		const Unique<VkCommandBuffer>	cmdBuffer	(makeCommandBuffer(vk, device, *cmdPool));

		beginCommandBuffer(vk, *cmdBuffer);

		const VkImageMemoryBarrier	imageBarrier	=
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType            sType;
			DE_NULL,											// const void*                pNext;
			(VkAccessFlags)0,									// VkAccessFlags              srcAccessMask;
			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,				// VkAccessFlags              dstAccessMask;
			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout              oldLayout;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout              newLayout;
			VK_QUEUE_FAMILY_IGNORED,							// uint32_t                   srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,							// uint32_t                   dstQueueFamilyIndex;
			*colorImage,										// VkImage                    image;
			{													// VkImageSubresourceRange    subresourceRange;
				VK_IMAGE_ASPECT_COLOR_BIT,							// VkImageAspectFlags    aspectMask;
				0u,													// uint32_t              baseMipLevel;
				1u,													// uint32_t              levelCount;
				0u,													// uint32_t              baseArrayLayer;
				static_cast<deUint32>(imageSize.w()),				// uint32_t              layerCount;
			}
		};

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u,
								0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);

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

	// For each image layer or slice (3D), create an attachment and a pipeline
	{
		const VkImageAspectFlags	depthStencilAspect		= getFormatAspectFlags(caseDef.depthStencilFormat);
		const bool					useDepth				= (depthStencilAspect & VK_IMAGE_ASPECT_DEPTH_BIT)   != 0;
		const bool					useStencil				= (depthStencilAspect & VK_IMAGE_ASPECT_STENCIL_BIT) != 0;
		VkPipeline					basePipeline			= DE_NULL;

		// Color attachments are first in the framebuffer
		for (int subpassNdx = 0; subpassNdx < numSlices; ++subpassNdx)
		{
			colorAttachments.push_back(makeSharedPtr(
				makeImageView(vk, device, *colorImage, getImageViewSliceType(caseDef.viewType), caseDef.colorFormat, makeColorSubresourceRange(subpassNdx, 1))));
			attachmentHandles.push_back(**colorAttachments.back());

			// We also have to create pipelines for each subpass
			pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(
				vk, device, basePipeline, *pipelineLayout, *renderPass, *vertexModule, *fragmentModule, imageSize.swizzle(0, 1), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
				static_cast<deUint32>(subpassNdx), useDepth, useStencil)));

			basePipeline = **pipelines.front();
		}

		// Then D/S attachments, if any
		if (useDepthStencil)
		for (int subpassNdx = 0; subpassNdx < numSlices; ++subpassNdx)
		{
			depthStencilAttachments.push_back(makeSharedPtr(
				makeImageView(vk, device, *depthStencilImage, VK_IMAGE_VIEW_TYPE_2D, caseDef.depthStencilFormat, makeImageSubresourceRange(depthStencilAspect, 0u, 1u, subpassNdx, 1u))));
			attachmentHandles.push_back(**depthStencilAttachments.back());
		}
	}

	framebuffer = makeFramebuffer(vk, device, *renderPass, static_cast<deUint32>(attachmentHandles.size()), &attachmentHandles[0], static_cast<deUint32>(imageSize.x()), static_cast<deUint32>(imageSize.y()));

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

		beginCommandBuffer(vk, *cmdBuffer);
		{
			vector<VkClearValue>	clearValues	(numSlices, getClearValue(caseDef.colorFormat));

			if (useDepthStencil)
				clearValues.insert(clearValues.end(), numSlices, makeClearValueDepthStencil(REFERENCE_DEPTH_VALUE, REFERENCE_STENCIL_VALUE));

			const VkDeviceSize		vertexBufferOffset	= 0ull;

			beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, imageSize.x(), imageSize.y()), (deUint32)clearValues.size(), &clearValues[0]);
			vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
		}

		// Draw
		for (deUint32 subpassNdx = 0; subpassNdx < static_cast<deUint32>(numSlices); ++subpassNdx)
		{
			if (subpassNdx != 0)
				vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);

			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
			vk.cmdDraw(*cmdBuffer, 4u, 1u, subpassNdx*4u, 0u);
		}

		endRenderPass(vk, *cmdBuffer);

		// Copy colorImage -> host visible colorBuffer
		{
			const VkImageMemoryBarrier	imageBarriers[]	=
			{
				{
					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
					DE_NULL,										// const void*				pNext;
					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			outputMask;
					VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags			inputMask;
					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			oldLayout;
					VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,			// VkImageLayout			newLayout;
					VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
					VK_QUEUE_FAMILY_IGNORED,						// deUint32					destQueueFamilyIndex;
					*colorImage,									// VkImage					image;
					makeColorSubresourceRange(0, imageSize.w())		// VkImageSubresourceRange	subresourceRange;
				}
			};

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
								  0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);

			// Copy the checked region rather than the whole image
			const VkImageSubresourceLayers	subresource	=
			{
				VK_IMAGE_ASPECT_COLOR_BIT,							// VkImageAspectFlags    aspectMask;
				0u,													// uint32_t              mipLevel;
				static_cast<deUint32>(checkOffset.w()),				// uint32_t              baseArrayLayer;
				static_cast<deUint32>(checkSize.w()),				// uint32_t              layerCount;
			};

			const VkBufferImageCopy			region		=
			{
				0ull,																// VkDeviceSize                bufferOffset;
				0u,																	// uint32_t                    bufferRowLength;
				0u,																	// uint32_t                    bufferImageHeight;
				subresource,														// VkImageSubresourceLayers    imageSubresource;
				makeOffset3D(checkOffset.x(), checkOffset.y(), checkOffset.z()),	// VkOffset3D                  imageOffset;
				makeExtent3D(checkSize.swizzle(0, 1, 2)),							// VkExtent3D                  imageExtent;
			};

			vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &region);

			const VkBufferMemoryBarrier	bufferBarriers[] =
			{
				{
					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,					// uint32_t           srcQueueFamilyIndex;
					VK_QUEUE_FAMILY_IGNORED,					// uint32_t           dstQueueFamilyIndex;
					*colorBuffer,								// VkBuffer           buffer;
					0ull,										// VkDeviceSize       offset;
					VK_WHOLE_SIZE,								// VkDeviceSize       size;
				},
			};

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
								  0u, DE_NULL, DE_LENGTH_OF_ARRAY(bufferBarriers), bufferBarriers, 0u, DE_NULL);
		}

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

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

		const tcu::TextureFormat			format			= mapVkFormat(caseDef.colorFormat);
		const int							checkDepth		= maxLayersOrDepth(checkSize);
		const int							depthOffset		= maxLayersOrDepth(checkOffset);
		const tcu::ConstPixelBufferAccess	resultImage		(format, checkSize.x(), checkSize.y(), checkDepth, colorBufferAlloc->getHostPtr());
		tcu::TextureLevel					textureLevel	(format, checkSize.x(), checkSize.y(), checkDepth);
		const tcu::PixelBufferAccess		expectedImage	= textureLevel.getAccess();
		bool								ok				= false;

		generateExpectedImage(expectedImage, checkSize.swizzle(0, 1), depthOffset);

		if (isFloatFormat(caseDef.colorFormat))
			ok = tcu::floatThresholdCompare(context.getTestContext().getLog(), "Image Comparison", "", expectedImage, resultImage, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
		else
			ok = tcu::intThresholdCompare(context.getTestContext().getLog(), "Image Comparison", "", expectedImage, resultImage, tcu::UVec4(2), tcu::COMPARE_LOG_RESULT);

		return ok ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
	}
}

void checkImageViewTypeRequirements (Context& context, const VkImageViewType viewType)
{
	if (viewType == VK_IMAGE_VIEW_TYPE_3D)
	{
		if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
		   !context.getPortabilitySubsetFeatures().imageView2DOn3DImage)
		{
			TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Implementation does not support 2D or 2D array image view to be created on a 3D VkImage");
		}

		context.requireDeviceFunctionality("VK_KHR_maintenance1");
	}

	if (viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY);
}

void checkSupportAttachmentSize (Context& context, const CaseDef caseDef)
{
	checkImageViewTypeRequirements(context, caseDef.viewType);

	if (caseDef.allocationKind == ALLOCATION_KIND_DEDICATED)
		context.requireDeviceFunctionality("VK_KHR_dedicated_allocation");

	if (caseDef.depthStencilFormat != VK_FORMAT_UNDEFINED  && !isDepthStencilFormatSupported(context.getInstanceInterface(), context.getPhysicalDevice(), caseDef.depthStencilFormat))
		TCU_THROW(NotSupportedError, "Unsupported depth/stencil format");
}

//! A test that can exercise very big color and depth/stencil attachment sizes.
//! If the total memory consumed by images is too large, or if the implementation returns OUT_OF_MEMORY error somewhere,
//! the test can be retried with a next increment of size reduction index, making the attachments smaller.
tcu::TestStatus testAttachmentSize (Context& context, const CaseDef caseDef)
{
	return testWithSizeReduction(context, caseDef);
	// Never reached
}

vector<IVec4> getMipLevelSizes (IVec4 baseSize)
{
	vector<IVec4> levels;
	levels.push_back(baseSize);

	while (baseSize.x() != 1 || baseSize.y() != 1 || baseSize.z() != 1)
	{
		baseSize.x() = deMax32(baseSize.x() >> 1, 1);
		baseSize.y() = deMax32(baseSize.y() >> 1, 1);
		baseSize.z() = deMax32(baseSize.z() >> 1, 1);
		levels.push_back(baseSize);
	}

	return levels;
}

//! Compute memory consumed by each mip level, including all layers. Sizes include a padding for alignment.
vector<VkDeviceSize> getPerMipLevelStorageSize (const vector<IVec4>& mipLevelSizes, const VkDeviceSize pixelSize)
{
	const deInt64			levelAlignment	= 16;
	vector<VkDeviceSize>	storageSizes;

	for (vector<IVec4>::const_iterator it = mipLevelSizes.begin(); it != mipLevelSizes.end(); ++it)
		storageSizes.push_back(deAlign64(pixelSize * product(*it), levelAlignment));

	return storageSizes;
}

void drawToMipLevel (const Context&				context,
					 const CaseDef&				caseDef,
					 const int					mipLevel,
					 const IVec4&				mipSize,
					 const int					numSlices,
					 const VkImage				colorImage,
					 const VkImage				depthStencilImage,
					 const VkBuffer				vertexBuffer,
					 const VkPipelineLayout		pipelineLayout,
					 const VkShaderModule		vertexModule,
					 const VkShaderModule		fragmentModule)
{
	const DeviceInterface&			vk					= context.getDeviceInterface();
	const VkDevice					device				= context.getDevice();
	const VkQueue					queue				= context.getUniversalQueue();
	const deUint32					queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	const VkImageAspectFlags		depthStencilAspect	= getFormatAspectFlags(caseDef.depthStencilFormat);
	const bool						useDepth			= (depthStencilAspect & VK_IMAGE_ASPECT_DEPTH_BIT)   != 0;
	const bool						useStencil			= (depthStencilAspect & VK_IMAGE_ASPECT_STENCIL_BIT) != 0;
	const Unique<VkRenderPass>		renderPass			(makeRenderPass(vk, device, caseDef.colorFormat, caseDef.depthStencilFormat, static_cast<deUint32>(numSlices),
																		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
																		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
	vector<SharedPtrVkPipeline>		pipelines;
	vector<SharedPtrVkImageView>	colorAttachments;
	vector<SharedPtrVkImageView>	depthStencilAttachments;
	vector<VkImageView>				attachmentHandles;			// all attachments (color and d/s)

	// For each image layer or slice (3D), create an attachment and a pipeline
	{
		VkPipeline					basePipeline			= DE_NULL;

		// Color attachments are first in the framebuffer
		for (int subpassNdx = 0; subpassNdx < numSlices; ++subpassNdx)
		{
			colorAttachments.push_back(makeSharedPtr(makeImageView(
				vk, device, colorImage, getImageViewSliceType(caseDef.viewType), caseDef.colorFormat,
				makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 1u, subpassNdx, 1u))));
			attachmentHandles.push_back(**colorAttachments.back());

			// We also have to create pipelines for each subpass
			pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(
				vk, device, basePipeline, pipelineLayout, *renderPass, vertexModule, fragmentModule, mipSize.swizzle(0, 1), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
				static_cast<deUint32>(subpassNdx), useDepth, useStencil)));

			basePipeline = **pipelines.front();
		}

		// Then D/S attachments, if any
		if (useDepth || useStencil)
		for (int subpassNdx = 0; subpassNdx < numSlices; ++subpassNdx)
		{
			depthStencilAttachments.push_back(makeSharedPtr(makeImageView(
				vk, device, depthStencilImage, VK_IMAGE_VIEW_TYPE_2D, caseDef.depthStencilFormat,
				makeImageSubresourceRange(depthStencilAspect, mipLevel, 1u, subpassNdx, 1u))));
			attachmentHandles.push_back(**depthStencilAttachments.back());
		}
	}

	const Unique<VkFramebuffer>			framebuffer (makeFramebuffer(vk, device, *renderPass, static_cast<deUint32>(attachmentHandles.size()), &attachmentHandles[0],
																	 static_cast<deUint32>(mipSize.x()), static_cast<deUint32>(mipSize.y())));

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

		beginCommandBuffer(vk, *cmdBuffer);
		{
			vector<VkClearValue>	clearValues	(numSlices, getClearValue(caseDef.colorFormat));

			if (useDepth || useStencil)
				clearValues.insert(clearValues.end(), numSlices, makeClearValueDepthStencil(REFERENCE_DEPTH_VALUE, REFERENCE_STENCIL_VALUE));

			const VkDeviceSize		vertexBufferOffset	= 0ull;

			beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, mipSize.x(), mipSize.y()), (deUint32)clearValues.size(), &clearValues[0]);
			vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
		}

		// Draw
		for (deUint32 subpassNdx = 0; subpassNdx < static_cast<deUint32>(numSlices); ++subpassNdx)
		{
			if (subpassNdx != 0)
				vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);

			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
			vk.cmdDraw(*cmdBuffer, 4u, 1u, subpassNdx*4u, 0u);
		}

		endRenderPass(vk, *cmdBuffer);

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

void checkSupportRenderToMipMaps (Context& context, const CaseDef caseDef)
{
	checkImageViewTypeRequirements(context, caseDef.viewType);

	if (caseDef.allocationKind == ALLOCATION_KIND_DEDICATED)
		context.requireDeviceFunctionality("VK_KHR_dedicated_allocation");

	if (caseDef.depthStencilFormat != VK_FORMAT_UNDEFINED  && !isDepthStencilFormatSupported(context.getInstanceInterface(), context.getPhysicalDevice(), caseDef.depthStencilFormat))
		TCU_THROW(NotSupportedError, "Unsupported depth/stencil format");
}

//! Use image mip levels as attachments
tcu::TestStatus testRenderToMipMaps (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();
	const VkQueue					queue				= context.getUniversalQueue();
	const deUint32					queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	Allocator&						allocator			= context.getDefaultAllocator();

	const IVec4						imageSize				= caseDef.imageSizeHint;	// MAX_SIZE is not used in this test
	const deInt32					numSlices				= maxLayersOrDepth(imageSize);
	const vector<IVec4>				mipLevelSizes			= getMipLevelSizes(imageSize);
	const vector<VkDeviceSize>		mipLevelStorageSizes	= getPerMipLevelStorageSize(mipLevelSizes, tcu::getPixelSize(mapVkFormat(caseDef.colorFormat)));
	const int						numMipLevels			= static_cast<int>(mipLevelSizes.size());
	const bool						useDepthStencil			= (caseDef.depthStencilFormat != VK_FORMAT_UNDEFINED);

	// Create a color buffer big enough to hold all layers and mip levels
	const VkDeviceSize				colorBufferSize		= sum(mipLevelStorageSizes);
	const Unique<VkBuffer>			colorBuffer			(makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const UniquePtr<Allocation>		colorBufferAlloc	(bindBuffer(vki, vk, physDevice, device, *colorBuffer, MemoryRequirement::HostVisible, allocator, caseDef.allocationKind));

	{
		deMemset(colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
		flushAlloc(vk, device, *colorBufferAlloc);
	}

	const Unique<VkShaderModule>	vertexModule		(createShaderModule	(vk, device, context.getBinaryCollection().get("vert"), 0u));
	const Unique<VkShaderModule>	fragmentModule		(createShaderModule	(vk, device, context.getBinaryCollection().get("frag"), 0u));
	const Unique<VkPipelineLayout>	pipelineLayout		(makePipelineLayout	(vk, device));

	Move<VkImage>					colorImage;
	MovePtr<Allocation>				colorImageAlloc;
	Move<VkImage>					depthStencilImage;
	MovePtr<Allocation>				depthStencilImageAlloc;
	Move<VkBuffer>					vertexBuffer;
	MovePtr<Allocation>				vertexBufferAlloc;

	// Create a color image
	{
		const VkImageUsageFlags	imageUsage	= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;

		colorImage		= makeImage(vk, device, getImageCreateFlags(caseDef.viewType), getImageType(caseDef.viewType), caseDef.colorFormat,
									imageSize.swizzle(0, 1, 2), numMipLevels, imageSize.w(), imageUsage);
		colorImageAlloc	= bindImage(vki, vk, physDevice, device, *colorImage, MemoryRequirement::Any, allocator, caseDef.allocationKind);
	}

	// Create a depth/stencil image (always a 2D image, optionally layered)
	if (useDepthStencil)
	{
		const VkImageUsageFlags	imageUsage	= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;

		depthStencilImage		= makeImage(vk, device, (VkImageCreateFlags)0, VK_IMAGE_TYPE_2D, caseDef.depthStencilFormat,
											IVec3(imageSize.x(), imageSize.y(), 1), numMipLevels, numSlices, imageUsage);
		depthStencilImageAlloc	= bindImage(vki, vk, physDevice, device, *depthStencilImage, MemoryRequirement::Any, allocator, caseDef.allocationKind);
	}

	// Create a vertex buffer
	{
		const vector<Vertex4RGBA>	vertices			= genFullQuadVertices(numSlices);
		const VkDeviceSize			vertexBufferSize	= sizeInBytes(vertices);

		vertexBuffer		= makeBuffer(vk, device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
		vertexBufferAlloc	= bindBuffer(vki, vk, physDevice, device, *vertexBuffer, MemoryRequirement::HostVisible, allocator, caseDef.allocationKind);

		deMemcpy(vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast<std::size_t>(vertexBufferSize));
		flushAlloc(vk, device, *vertexBufferAlloc);
	}

	// Prepare images
	{
		const Unique<VkCommandPool>		cmdPool		(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
		const Unique<VkCommandBuffer>	cmdBuffer	(makeCommandBuffer(vk, device, *cmdPool));

		beginCommandBuffer(vk, *cmdBuffer);

		const VkImageMemoryBarrier	imageBarriers[]	=
		{
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType            sType;
				DE_NULL,											// const void*                pNext;
				(VkAccessFlags)0,									// VkAccessFlags              srcAccessMask;
				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,				// VkAccessFlags              dstAccessMask;
				VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout              oldLayout;
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout              newLayout;
				VK_QUEUE_FAMILY_IGNORED,							// uint32_t                   srcQueueFamilyIndex;
				VK_QUEUE_FAMILY_IGNORED,							// uint32_t                   dstQueueFamilyIndex;
				*colorImage,										// VkImage                    image;
				{													// VkImageSubresourceRange    subresourceRange;
					VK_IMAGE_ASPECT_COLOR_BIT,							// VkImageAspectFlags    aspectMask;
					0u,													// uint32_t              baseMipLevel;
					static_cast<deUint32>(numMipLevels),				// uint32_t              levelCount;
					0u,													// uint32_t              baseArrayLayer;
					static_cast<deUint32>(imageSize.w()),				// uint32_t              layerCount;
				},
			},
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType            sType;
				DE_NULL,											// const void*                pNext;
				(VkAccessFlags)0,									// VkAccessFlags              srcAccessMask;
				VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags              dstAccessMask;
				VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout              oldLayout;
				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout              newLayout;
				VK_QUEUE_FAMILY_IGNORED,							// uint32_t                   srcQueueFamilyIndex;
				VK_QUEUE_FAMILY_IGNORED,							// uint32_t                   dstQueueFamilyIndex;
				*depthStencilImage,									// VkImage                    image;
				{													// VkImageSubresourceRange    subresourceRange;
					getFormatAspectFlags(caseDef.depthStencilFormat),	// VkImageAspectFlags    aspectMask;
					0u,													// uint32_t              baseMipLevel;
					static_cast<deUint32>(numMipLevels),				// uint32_t              levelCount;
					0u,													// uint32_t              baseArrayLayer;
					static_cast<deUint32>(numSlices),					// uint32_t              layerCount;
				},
			}
		};

		const deUint32	numImageBarriers = static_cast<deUint32>(DE_LENGTH_OF_ARRAY(imageBarriers) - (useDepthStencil ? 0 : 1));

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, 0u,
								0u, DE_NULL, 0u, DE_NULL, numImageBarriers, imageBarriers);

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

	// Draw
	for (int mipLevel = 0; mipLevel < numMipLevels; ++mipLevel)
	{
		const IVec4&	mipSize		= mipLevelSizes[mipLevel];
		const int		levelSlices	= maxLayersOrDepth(mipSize);

		drawToMipLevel (context, caseDef, mipLevel, mipSize, levelSlices, *colorImage, *depthStencilImage, *vertexBuffer, *pipelineLayout,
						*vertexModule, *fragmentModule);
	}

	// Copy results: colorImage -> host visible colorBuffer
	{
		const Unique<VkCommandPool>		cmdPool		(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
		const Unique<VkCommandBuffer>	cmdBuffer	(makeCommandBuffer(vk, device, *cmdPool));

		beginCommandBuffer(vk, *cmdBuffer);

		{
			const VkImageMemoryBarrier	imageBarriers[]	=
			{
				{
					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType            sType;
					DE_NULL,										// const void*                pNext;
					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags              srcAccessMask;
					VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags              dstAccessMask;
					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout              oldLayout;
					VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,			// VkImageLayout              newLayout;
					VK_QUEUE_FAMILY_IGNORED,						// uint32_t                   srcQueueFamilyIndex;
					VK_QUEUE_FAMILY_IGNORED,						// uint32_t                   dstQueueFamilyIndex;
					*colorImage,									// VkImage                    image;
					{												// VkImageSubresourceRange    subresourceRange;
						VK_IMAGE_ASPECT_COLOR_BIT,							// VkImageAspectFlags    aspectMask;
						0u,													// uint32_t              baseMipLevel;
						static_cast<deUint32>(numMipLevels),				// uint32_t              levelCount;
						0u,													// uint32_t              baseArrayLayer;
						static_cast<deUint32>(imageSize.w()),				// uint32_t              layerCount;
					},
				}
			};

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
									0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
		}
		{
			vector<VkBufferImageCopy>	regions;
			VkDeviceSize				levelOffset = 0ull;
			VkBufferImageCopy			workRegion	=
			{
				0ull,																				// VkDeviceSize                bufferOffset;
				0u,																					// uint32_t                    bufferRowLength;
				0u,																					// uint32_t                    bufferImageHeight;
				makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, imageSize.w()),		// VkImageSubresourceLayers    imageSubresource;
				makeOffset3D(0, 0, 0),																// VkOffset3D                  imageOffset;
				makeExtent3D(0, 0, 0),																// VkExtent3D                  imageExtent;
			};

			for (int mipLevel = 0; mipLevel < numMipLevels; ++mipLevel)
			{
				workRegion.bufferOffset					= levelOffset;
				workRegion.imageSubresource.mipLevel	= static_cast<deUint32>(mipLevel);
				workRegion.imageExtent					= makeExtent3D(mipLevelSizes[mipLevel].swizzle(0, 1, 2));

				regions.push_back(workRegion);

				levelOffset += mipLevelStorageSizes[mipLevel];
			}

			vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, static_cast<deUint32>(regions.size()), &regions[0]);
		}
		{
			const VkBufferMemoryBarrier	bufferBarriers[] =
			{
				{
					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,					// uint32_t           srcQueueFamilyIndex;
					VK_QUEUE_FAMILY_IGNORED,					// uint32_t           dstQueueFamilyIndex;
					*colorBuffer,								// VkBuffer           buffer;
					0ull,										// VkDeviceSize       offset;
					VK_WHOLE_SIZE,								// VkDeviceSize       size;
				},
			};

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
									0u, DE_NULL, DE_LENGTH_OF_ARRAY(bufferBarriers), bufferBarriers, 0u, DE_NULL);
		}

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

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

		const tcu::TextureFormat			format			= mapVkFormat(caseDef.colorFormat);

		VkDeviceSize						levelOffset		= 0ull;
		bool								allOk			= true;

		for (int mipLevel = 0; mipLevel < numMipLevels; ++mipLevel)
		{
			const IVec4&						mipSize			= mipLevelSizes[mipLevel];
			const void*	const					pLevelData		= static_cast<const deUint8*>(colorBufferAlloc->getHostPtr()) + levelOffset;
			const int							levelDepth		= maxLayersOrDepth(mipSize);
			const tcu::ConstPixelBufferAccess	resultImage		(format, mipSize.x(), mipSize.y(), levelDepth, pLevelData);
			tcu::TextureLevel					textureLevel	(format, mipSize.x(), mipSize.y(), levelDepth);
			const tcu::PixelBufferAccess		expectedImage	= textureLevel.getAccess();
			const std::string					comparisonName	= "Mip level " + de::toString(mipLevel);
			bool								ok				= false;

			generateExpectedImage(expectedImage, mipSize.swizzle(0, 1), 0);

			if (isFloatFormat(caseDef.colorFormat))
				ok = tcu::floatThresholdCompare(context.getTestContext().getLog(), "Image Comparison", comparisonName.c_str(), expectedImage, resultImage, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
			else
				ok = tcu::intThresholdCompare(context.getTestContext().getLog(), "Image Comparison", comparisonName.c_str(), expectedImage, resultImage, tcu::UVec4(2), tcu::COMPARE_LOG_RESULT);

			allOk		=  allOk && ok;	// keep testing all levels, even if we know it's a fail overall
			levelOffset += mipLevelStorageSizes[mipLevel];
		}

		return allOk ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
	}
}

std::string getSizeDescription (const IVec4& size)
{
	std::ostringstream str;

	const char* const description[4] =
	{
		"width", "height", "depth", "layers"
	};

	int numMaxComponents = 0;

	for (int i = 0; i < 4; ++i)
	{
		if (size[i] == MAX_SIZE)
		{
			if (numMaxComponents > 0)
				str << "_";

			str << description[i];
			++numMaxComponents;
		}
	}

	if (numMaxComponents == 0)
		str << "small";

	return str.str();
}

inline std::string getFormatString (const VkFormat format)
{
	std::string name(getFormatName(format));
	return de::toLower(name.substr(10));
}

std::string getFormatString (const VkFormat colorFormat, const VkFormat depthStencilFormat)
{
	std::ostringstream str;
	str << getFormatString(colorFormat);
	if (depthStencilFormat != VK_FORMAT_UNDEFINED)
		str << "_" << getFormatString(depthStencilFormat);
	return str.str();
}

std::string getShortImageViewTypeName (const VkImageViewType imageViewType)
{
	std::string s(getImageViewTypeName(imageViewType));
	return de::toLower(s.substr(19));
}

inline BVec4 bvecFromMask (deUint32 mask)
{
	return BVec4((mask >> 0) & 1,
				 (mask >> 1) & 1,
				 (mask >> 2) & 1,
				 (mask >> 3) & 1);
}

vector<IVec4> genSizeCombinations (const IVec4& baselineSize, const deUint32 sizeMask, const VkImageViewType imageViewType)
{
	vector<IVec4>		sizes;
	std::set<deUint32>	masks;

	for (deUint32 i = 0; i < (1u << 4); ++i)
	{
		// Cube images have square faces
		if (isCube(imageViewType) && ((i & MASK_WH) != 0))
			i |= MASK_WH;

		masks.insert(i & sizeMask);
	}

	for (std::set<deUint32>::const_iterator it = masks.begin(); it != masks.end(); ++it)
		sizes.push_back(tcu::select(IVec4(MAX_SIZE), baselineSize, bvecFromMask(*it)));

	return sizes;
}

void addTestCasesWithFunctions (tcu::TestCaseGroup* group, AllocationKind allocationKind)
{
	const struct
	{
		VkImageViewType		viewType;
		IVec4				baselineSize;	//!< image size: (dimX, dimY, dimZ, arraySize)
		deUint32			sizeMask;		//!< if a dimension is masked, generate a huge size case for it
	} testCase[] =
	{
		{ VK_IMAGE_VIEW_TYPE_1D,			IVec4(54,  1, 1,   1),	MASK_W			},
		{ VK_IMAGE_VIEW_TYPE_1D_ARRAY,		IVec4(54,  1, 1,   4),	MASK_W_LAYERS	},
		{ VK_IMAGE_VIEW_TYPE_2D,			IVec4(44, 23, 1,   1),	MASK_WH			},
		{ VK_IMAGE_VIEW_TYPE_2D_ARRAY,		IVec4(44, 23, 1,   4),	MASK_WH_LAYERS	},
		{ VK_IMAGE_VIEW_TYPE_3D,			IVec4(22, 31, 7,   1),	MASK_WHD		},
		{ VK_IMAGE_VIEW_TYPE_CUBE,			IVec4(35, 35, 1,   6),	MASK_WH			},
		{ VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,	IVec4(35, 35, 1, 2*6),	MASK_WH_LAYERS	},
	};

	const VkFormat format[]	=
	{
		VK_FORMAT_R8G8B8A8_UNORM,
		VK_FORMAT_R32_UINT,
		VK_FORMAT_R16G16_SINT,
		VK_FORMAT_R32G32B32A32_SFLOAT,
		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
		VK_FORMAT_R5G6B5_UNORM_PACK16,
		VK_FORMAT_A2B10G10R10_UINT_PACK32,
		VK_FORMAT_A2B10G10R10_UNORM_PACK32
	};

	const VkFormat depthStencilFormat[] =
	{
		VK_FORMAT_UNDEFINED,			// don't use a depth/stencil attachment
		VK_FORMAT_D16_UNORM,
		VK_FORMAT_S8_UINT,
		VK_FORMAT_D24_UNORM_S8_UINT,	// one of the following mixed formats must be supported
		VK_FORMAT_D32_SFLOAT_S8_UINT,
	};

	for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(testCase); ++caseNdx)
	{
		MovePtr<tcu::TestCaseGroup>	imageGroup(new tcu::TestCaseGroup(group->getTestContext(), getShortImageViewTypeName(testCase[caseNdx].viewType).c_str(), ""));

		// Generate attachment size cases
		{
			const vector<IVec4> sizes = genSizeCombinations(testCase[caseNdx].baselineSize, testCase[caseNdx].sizeMask, testCase[caseNdx].viewType);

			MovePtr<tcu::TestCaseGroup>	smallGroup(new tcu::TestCaseGroup(group->getTestContext(), "small", ""));
			MovePtr<tcu::TestCaseGroup>	hugeGroup (new tcu::TestCaseGroup(group->getTestContext(), "huge",  ""));

			imageGroup->addChild(smallGroup.get());
			imageGroup->addChild(hugeGroup.get());

			for (vector<IVec4>::const_iterator sizeIter = sizes.begin(); sizeIter != sizes.end(); ++sizeIter)
			{
				// The first size is the baseline size, put it in a dedicated group
				if (sizeIter == sizes.begin())
				{
					for (int dsFormatNdx = 0; dsFormatNdx < DE_LENGTH_OF_ARRAY(depthStencilFormat); ++dsFormatNdx)
					for (int formatNdx   = 0; formatNdx   < DE_LENGTH_OF_ARRAY(format);             ++formatNdx)
					{
						const CaseDef caseDef =
						{
							testCase[caseNdx].viewType,			// VkImageViewType	imageType;
							*sizeIter,							// IVec4			imageSizeHint;
							format[formatNdx],					// VkFormat			colorFormat;
							depthStencilFormat[dsFormatNdx],	// VkFormat			depthStencilFormat;
							allocationKind						// AllocationKind	allocationKind;
						};
						addFunctionCaseWithPrograms(smallGroup.get(), getFormatString(format[formatNdx], depthStencilFormat[dsFormatNdx]), "", checkSupportAttachmentSize, initPrograms, testAttachmentSize, caseDef);
					}
				}
				else // All huge cases go into a separate group
				{
					if (allocationKind != ALLOCATION_KIND_DEDICATED)
					{
						MovePtr<tcu::TestCaseGroup>	sizeGroup	(new tcu::TestCaseGroup(group->getTestContext(), getSizeDescription(*sizeIter).c_str(), ""));
						const VkFormat				colorFormat	= VK_FORMAT_R8G8B8A8_UNORM;

						// Use the same color format for all cases, to reduce the number of permutations
						for (int dsFormatNdx = 0; dsFormatNdx < DE_LENGTH_OF_ARRAY(depthStencilFormat); ++dsFormatNdx)
						{
							const CaseDef caseDef =
							{
								testCase[caseNdx].viewType,			// VkImageViewType	viewType;
								*sizeIter,							// IVec4			imageSizeHint;
								colorFormat,						// VkFormat			colorFormat;
								depthStencilFormat[dsFormatNdx],	// VkFormat			depthStencilFormat;
								allocationKind						// AllocationKind	allocationKind;
							};
							addFunctionCaseWithPrograms(sizeGroup.get(), getFormatString(colorFormat, depthStencilFormat[dsFormatNdx]), "", checkSupportAttachmentSize, initPrograms, testAttachmentSize, caseDef);
						}
						hugeGroup->addChild(sizeGroup.release());
					}
				}
			}
			smallGroup.release();
			hugeGroup.release();
		}

		// Generate mip map cases
		{
			MovePtr<tcu::TestCaseGroup>	mipmapGroup(new tcu::TestCaseGroup(group->getTestContext(), "mipmap", ""));

			for (int dsFormatNdx = 0; dsFormatNdx < DE_LENGTH_OF_ARRAY(depthStencilFormat); ++dsFormatNdx)
			for (int formatNdx   = 0; formatNdx   < DE_LENGTH_OF_ARRAY(format);             ++formatNdx)
			{
				const CaseDef caseDef =
				{
					testCase[caseNdx].viewType,			// VkImageViewType	imageType;
					testCase[caseNdx].baselineSize,		// IVec4			imageSizeHint;
					format[formatNdx],					// VkFormat			colorFormat;
					depthStencilFormat[dsFormatNdx],	// VkFormat			depthStencilFormat;
					allocationKind						// AllocationKind	allocationKind;
				};
				addFunctionCaseWithPrograms(mipmapGroup.get(), getFormatString(format[formatNdx], depthStencilFormat[dsFormatNdx]), "", checkSupportRenderToMipMaps, initPrograms, testRenderToMipMaps, caseDef);
			}
			imageGroup->addChild(mipmapGroup.release());
		}

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

void addCoreRenderToImageTests (tcu::TestCaseGroup* group)
{
	addTestCasesWithFunctions(group, ALLOCATION_KIND_SUBALLOCATED);
}

void addDedicatedAllocationRenderToImageTests (tcu::TestCaseGroup* group)
{
	addTestCasesWithFunctions(group, ALLOCATION_KIND_DEDICATED);
}

} // anonymous ns

tcu::TestCaseGroup* createRenderToImageTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup>	renderToImageTests	(new tcu::TestCaseGroup(testCtx, "render_to_image", "Render to image tests"));

	renderToImageTests->addChild(createTestGroup(testCtx, "core",					"Core render to image tests",								addCoreRenderToImageTests));
	renderToImageTests->addChild(createTestGroup(testCtx, "dedicated_allocation",	"Render to image tests for dedicated memory allocation",	addDedicatedAllocationRenderToImageTests));

	return renderToImageTests.release();
}

} // pipeline
} // vkt
