/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2019 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 Vulkan Imageless Framebuffer Tests
 *//*--------------------------------------------------------------------*/

#include "vktImagelessFramebufferTests.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktTestCase.hpp"

#include "deUniquePtr.hpp"
#include "deRandom.hpp"

#include "tcuTextureUtil.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRGBA.hpp"

#include "vkCmdUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkBuilderUtil.hpp"

#include <iostream>

namespace vkt
{
namespace imageless
{

namespace
{
using namespace vk;
using de::MovePtr;
using de::UniquePtr;
using de::SharedPtr;

typedef SharedPtr<Unique<VkPipeline> >	SharedPtrVkPipeline;

enum TestType
{
	TEST_TYPE_COLOR = 0,
	TEST_TYPE_DEPTH_STENCIL,
	TEST_TYPE_COLOR_RESOLVE,
	TEST_TYPE_DEPTH_STENCIL_RESOLVE,
	TEST_TYPE_MULTISUBPASS,
	TEST_TYPE_LAST
};

enum AspectFlagBits
{
	ASPECT_NONE				= 0,
	ASPECT_COLOR			= (1<<0),
	ASPECT_DEPTH			= (1<<1),
	ASPECT_STENCIL			= (1<<2),
	ASPECT_DEPTH_STENCIL	= ASPECT_DEPTH | ASPECT_STENCIL,
};
typedef deUint32 AspectFlags;

const deUint32	NO_SAMPLE	= static_cast<deUint32>(-1);
const deUint32	NO_SUBPASS	= static_cast<deUint32>(-1);

struct TestParameters
{
	TestType	testType;
	VkFormat	colorFormat;
	VkFormat	dsFormat;
};

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

VkSampleCountFlagBits sampleCountBitFromSampleCount (deUint32 count)
{
	switch (count)
	{
		case 1:  return VK_SAMPLE_COUNT_1_BIT;
		case 2:  return VK_SAMPLE_COUNT_2_BIT;
		case 4:  return VK_SAMPLE_COUNT_4_BIT;
		case 8:  return VK_SAMPLE_COUNT_8_BIT;
		case 16: return VK_SAMPLE_COUNT_16_BIT;
		case 32: return VK_SAMPLE_COUNT_32_BIT;
		case 64: return VK_SAMPLE_COUNT_64_BIT;

		default:
			DE_FATAL("Invalid sample count");
			return (VkSampleCountFlagBits)0x0;
	}
}

VkAttachmentReference2KHR convertAttachmentReference (const VkAttachmentReference& attachmentReference, const VkImageAspectFlags aspectMask)
{
	const VkAttachmentReference2KHR	attachmentReference2	=
	{
		VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR,	//  VkStructureType		sType;
		DE_NULL,										//  const void*			pNext;
		attachmentReference.attachment,					//  deUint32			attachment;
		attachmentReference.layout,						//  VkImageLayout		layout;
		aspectMask										//  VkImageAspectFlags	aspectMask;
	};

	return attachmentReference2;
}

std::vector<VkAttachmentDescription2KHR> convertAttachmentDescriptions (const std::vector<VkAttachmentDescription>& attachmentDescriptions)
{
	std::vector<VkAttachmentDescription2KHR>	attachmentDescriptions2;

	attachmentDescriptions2.reserve(attachmentDescriptions.size());

	for (size_t adNdx = 0; adNdx < attachmentDescriptions.size(); ++adNdx)
	{
		const VkAttachmentDescription&		attachmentDescription	= attachmentDescriptions[adNdx];
		const VkAttachmentDescription2KHR	attachmentDescription2	=
		{
			VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR,	//  VkStructureType					sType;
			DE_NULL,										//  const void*						pNext;
			attachmentDescription.flags,					//  VkAttachmentDescriptionFlags	flags;
			attachmentDescription.format,					//  VkFormat						format;
			attachmentDescription.samples,					//  VkSampleCountFlagBits			samples;
			attachmentDescription.loadOp,					//  VkAttachmentLoadOp				loadOp;
			attachmentDescription.storeOp,					//  VkAttachmentStoreOp				storeOp;
			attachmentDescription.stencilLoadOp,			//  VkAttachmentLoadOp				stencilLoadOp;
			attachmentDescription.stencilStoreOp,			//  VkAttachmentStoreOp				stencilStoreOp;
			attachmentDescription.initialLayout,			//  VkImageLayout					initialLayout;
			attachmentDescription.finalLayout,				//  VkImageLayout					finalLayout;
		};

		attachmentDescriptions2.push_back(attachmentDescription2);
	}

	return attachmentDescriptions2;
}

Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&		vk,
									   const VkDevice				device,
									   const VkPipelineLayout		pipelineLayout,
									   const VkRenderPass			renderPass,
									   const VkShaderModule			vertexModule,
									   const VkShaderModule			fragmendModule,
									   const VkExtent2D				renderSize,
									   const AspectFlags			depthStencilAspects	= ASPECT_NONE,
									   const VkSampleCountFlagBits	sampleCountBits		= VK_SAMPLE_COUNT_1_BIT,
									   const deUint32				subpass				= 0)
{
	const bool									useDepth						= (depthStencilAspects & ASPECT_DEPTH) != 0;
	const bool									useStencil						= (depthStencilAspects & ASPECT_STENCIL) != 0;
	const std::vector<VkViewport>				viewports						(1, makeViewport(renderSize));
	const std::vector<VkRect2D>					scissors						(1, makeRect2D(renderSize));
	const VkStencilOpState						stencilOpState					=
	{
		VK_STENCIL_OP_KEEP,					//  VkStencilOp	failOp;
		VK_STENCIL_OP_INCREMENT_AND_CLAMP,	//  VkStencilOp	passOp;
		VK_STENCIL_OP_KEEP,					//  VkStencilOp	depthFailOp;
		VK_COMPARE_OP_ALWAYS,				//  VkCompareOp	compareOp;
		~0u,								//  deUint32	compareMask;
		~0u,								//  deUint32	writeMask;
		0u									//  deUint32	reference;
	};
	const VkPipelineDepthStencilStateCreateInfo	pipelineDepthStencilStateInfo	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	//  VkStructureType							sType;
		DE_NULL,													//  const void*								pNext;
		(VkPipelineDepthStencilStateCreateFlags)0,					//  VkPipelineDepthStencilStateCreateFlags	flags;
		useDepth ? VK_TRUE : VK_FALSE,								//  VkBool32								depthTestEnable;
		useDepth ? VK_TRUE : VK_FALSE,								//  VkBool32								depthWriteEnable;
		VK_COMPARE_OP_LESS,											//  VkCompareOp								depthCompareOp;
		VK_FALSE,													//  VkBool32								depthBoundsTestEnable;
		useStencil ? VK_TRUE : VK_FALSE,							//  VkBool32								stencilTestEnable;
		stencilOpState,												//  VkStencilOpState						front;
		stencilOpState,												//  VkStencilOpState						back;
		0.0f,														//  float									minDepthBounds;
		1.0f														//  float									maxDepthBounds;
	};
	const VkPipelineMultisampleStateCreateInfo	multisampleState				=
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	//  VkStructureType							sType;
		DE_NULL,													//  const void*								pNext;
		(VkPipelineMultisampleStateCreateFlags)0u,					//  VkPipelineMultisampleStateCreateFlags	flags;
		sampleCountBits,											//  VkSampleCountFlagBits					rasterizationSamples;
		VK_FALSE,													//  VkBool32								sampleShadingEnable;
		0.0f,														//  float									minSampleShading;
		DE_NULL,													//  const VkSampleMask*						pSampleMask;
		VK_FALSE,													//  VkBool32								alphaToCoverageEnable;
		VK_FALSE,													//  VkBool32								alphaToOneEnable;
	};

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

Move<VkRenderPass> makeRenderPass (const DeviceInterface&				vk,
								   const VkDevice						device,
								   const VkFormat						colorFormat,
								   const VkFormat						depthStencilFormat,
								   const VkSampleCountFlagBits			colorSamples,
								   const VkSampleCountFlagBits			depthStencilSamples			= VK_SAMPLE_COUNT_1_BIT,
								   const VkAttachmentLoadOp				loadOperation				= VK_ATTACHMENT_LOAD_OP_CLEAR,
								   const VkImageLayout					finalLayoutColor			= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
								   const VkImageLayout					finalLayoutDepthStencil		= VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
								   const VkImageLayout					subpassLayoutColor			= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
								   const VkImageLayout					subpassLayoutDepthStencil	= VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
								   const VkAllocationCallbacks* const	allocationCallbacks			= DE_NULL)
{
	const bool								hasColor									= colorFormat != VK_FORMAT_UNDEFINED;
	const bool								hasDepthStencil								= depthStencilFormat != VK_FORMAT_UNDEFINED;
	const bool								hasColorResolve								= hasColor && (colorSamples != VK_SAMPLE_COUNT_1_BIT);
	const bool								hasDepthStencilResolve						= hasDepthStencil && (depthStencilSamples != VK_SAMPLE_COUNT_1_BIT);
	const VkImageLayout						initialLayoutColor							= loadOperation == VK_ATTACHMENT_LOAD_OP_LOAD ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
	const VkImageLayout						initialLayoutDepthStencil					= loadOperation == VK_ATTACHMENT_LOAD_OP_LOAD ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
	const VkAttachmentDescription			colorAttachmentDescription					=
	{
		(VkAttachmentDescriptionFlags)0,		//  VkAttachmentDescriptionFlags	flags;
		colorFormat,							//  VkFormat						format;
		colorSamples,							//  VkSampleCountFlagBits			samples;
		loadOperation,							//  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;
		initialLayoutColor,						//  VkImageLayout					initialLayout;
		finalLayoutColor						//  VkImageLayout					finalLayout;
	};
	const VkAttachmentDescription			depthStencilAttachmentDescription			=
	{
		(VkAttachmentDescriptionFlags)0,		//  VkAttachmentDescriptionFlags	flags;
		depthStencilFormat,						//  VkFormat						format;
		depthStencilSamples,					//  VkSampleCountFlagBits			samples;
		loadOperation,							//  VkAttachmentLoadOp				loadOp;
		VK_ATTACHMENT_STORE_OP_STORE,			//  VkAttachmentStoreOp				storeOp;
		loadOperation,							//  VkAttachmentLoadOp				stencilLoadOp;
		VK_ATTACHMENT_STORE_OP_STORE,			//  VkAttachmentStoreOp				stencilStoreOp;
		initialLayoutDepthStencil,				//  VkImageLayout					initialLayout;
		finalLayoutDepthStencil					//  VkImageLayout					finalLayout;
	};
	const VkAttachmentDescription			colorResolveAttachmentDescription			=
	{
		(VkAttachmentDescriptionFlags)0,		//  VkAttachmentDescriptionFlags	flags;
		colorFormat,							//  VkFormat						format;
		VK_SAMPLE_COUNT_1_BIT,					//  VkSampleCountFlagBits			samples;
		VK_ATTACHMENT_LOAD_OP_LOAD,				//  VkAttachmentLoadOp				loadOp;
		VK_ATTACHMENT_STORE_OP_STORE,			//  VkAttachmentStoreOp				storeOp;
		VK_ATTACHMENT_LOAD_OP_DONT_CARE,		//  VkAttachmentLoadOp				stencilLoadOp;
		VK_ATTACHMENT_STORE_OP_DONT_CARE,		//  VkAttachmentStoreOp				stencilStoreOp;
		initialLayoutColor,						//  VkImageLayout					initialLayout;
		finalLayoutColor						//  VkImageLayout					finalLayout;
	};
	const VkAttachmentDescription			depthStencilResolveAttachmentDescription	=
	{
		(VkAttachmentDescriptionFlags)0,		//  VkAttachmentDescriptionFlags	flags;
		depthStencilFormat,						//  VkFormat						format;
		VK_SAMPLE_COUNT_1_BIT,					//  VkSampleCountFlagBits			samples;
		VK_ATTACHMENT_LOAD_OP_LOAD,				//  VkAttachmentLoadOp				loadOp;
		VK_ATTACHMENT_STORE_OP_STORE,			//  VkAttachmentStoreOp				storeOp;
		VK_ATTACHMENT_LOAD_OP_LOAD,				//  VkAttachmentLoadOp				stencilLoadOp;
		VK_ATTACHMENT_STORE_OP_STORE,			//  VkAttachmentStoreOp				stencilStoreOp;
		initialLayoutDepthStencil,				//  VkImageLayout					initialLayout;
		finalLayoutDepthStencil					//  VkImageLayout					finalLayout;
	};
	std::vector<VkAttachmentDescription>	attachmentDescriptions;

	if (hasColor)
		attachmentDescriptions.push_back(colorAttachmentDescription);
	if (hasDepthStencil)
		attachmentDescriptions.push_back(depthStencilAttachmentDescription);
	if (hasColorResolve)
		attachmentDescriptions.push_back(colorResolveAttachmentDescription);
	if (hasDepthStencilResolve)
		attachmentDescriptions.push_back(depthStencilResolveAttachmentDescription);

	deUint32								attachmentCounter								= 0;
	const VkAttachmentReference				colorAttachmentRef								=
	{
		hasColor ? attachmentCounter++ : 0u,				//  deUint32		attachment;
		subpassLayoutColor									//  VkImageLayout	layout;
	};
	const VkAttachmentReference				depthStencilAttachmentRef						=
	{
		hasDepthStencil ? attachmentCounter++ : 0u,			//  deUint32		attachment;
		subpassLayoutDepthStencil							//  VkImageLayout	layout;
	};
	const VkAttachmentReference				colorResolveAttachmentRef						=
	{
		hasColorResolve ? attachmentCounter++ : 0u,			//  deUint32		attachment;
		subpassLayoutColor									//  VkImageLayout	layout;
	};

	if (hasDepthStencilResolve)
	{
		const VkImageAspectFlags							colorAspectMask							= VK_IMAGE_ASPECT_COLOR_BIT;
		const VkImageAspectFlags							depthStencilAspectMask					= VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
		const VkAttachmentReference2KHR						colorAttachmentRef2						= convertAttachmentReference(colorAttachmentRef, colorAspectMask);
		const VkAttachmentReference2KHR						depthStencilAttachmentRef2				= convertAttachmentReference(depthStencilAttachmentRef, depthStencilAspectMask);
		const VkAttachmentReference2KHR						colorResolveAttachmentRef2				= convertAttachmentReference(colorResolveAttachmentRef, colorAspectMask);
		const VkAttachmentReference2KHR						depthStencilResolveAttachmentRef2		=
		{
			VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR,			//  VkStructureType		sType;
			DE_NULL,												//  const void*			pNext;
			hasDepthStencilResolve ? attachmentCounter++ : 0u,		//  deUint32			attachment;
			subpassLayoutDepthStencil,								//  VkImageLayout		layout;
			depthStencilAspectMask									//  VkImageAspectFlags	aspectMask;
		};
		const VkSubpassDescriptionDepthStencilResolveKHR	subpassDescriptionDepthStencilResolve	=
		{
			VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR,	//  VkStructureType						sType;
			DE_NULL,															//  const void*							pNext;
			VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,								//  VkResolveModeFlagBitsKHR			depthResolveMode;
			VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,								//  VkResolveModeFlagBitsKHR			stencilResolveMode;
			&depthStencilResolveAttachmentRef2									//  const VkAttachmentReference2KHR*	pDepthStencilResolveAttachment;
		};
		const VkSubpassDescription2KHR						subpassDescription2						=
		{
			VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR,				//  VkStructureType						sType;
			&subpassDescriptionDepthStencilResolve,						//  const void*							pNext;
			(VkSubpassDescriptionFlags)0,								//  VkSubpassDescriptionFlags			flags;
			VK_PIPELINE_BIND_POINT_GRAPHICS,							//  VkPipelineBindPoint					pipelineBindPoint;
			0u,															//  deUint32							viewMask;
			0u,															//  deUint32							inputAttachmentCount;
			DE_NULL,													//  const VkAttachmentReference2KHR*	pInputAttachments;
			hasColor ? 1u : 0u,											//  deUint32							colorAttachmentCount;
			hasColor ? &colorAttachmentRef2 : DE_NULL,					//  const VkAttachmentReference2KHR*	pColorAttachments;
			hasColorResolve ? &colorResolveAttachmentRef2 : DE_NULL,	//  const VkAttachmentReference2KHR*	pResolveAttachments;
			hasDepthStencil ? &depthStencilAttachmentRef2 : DE_NULL,	//  const VkAttachmentReference2KHR*	pDepthStencilAttachment;
			0u,															//  deUint32							preserveAttachmentCount;
			DE_NULL														//  const deUint32*						pPreserveAttachments;
		};
		const std::vector<VkAttachmentDescription2KHR>		attachmentDescriptions2					= convertAttachmentDescriptions(attachmentDescriptions);
		const VkRenderPassCreateInfo2KHR					renderPassInfo							=
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR,	//  VkStructureType						sType;
			DE_NULL,											//  const void*							pNext;
			(VkRenderPassCreateFlags)0,							//  VkRenderPassCreateFlags				flags;
			(deUint32)attachmentDescriptions2.size(),			//  deUint32							attachmentCount;
			&attachmentDescriptions2[0],						//  const VkAttachmentDescription2KHR*	pAttachments;
			1u,													//  deUint32							subpassCount;
			&subpassDescription2,								//  const VkSubpassDescription2KHR*		pSubpasses;
			0u,													//  deUint32							dependencyCount;
			DE_NULL,											//  const VkSubpassDependency2KHR*		pDependencies;
			0u,													//  deUint32							correlatedViewMaskCount;
			DE_NULL												//  const deUint32*						pCorrelatedViewMasks;
		};

		return createRenderPass2KHR(vk, device, &renderPassInfo, allocationCallbacks);
	}
	else
	{
		const VkSubpassDescription				subpassDescription							=
		{
			(VkSubpassDescriptionFlags)0,							//  VkSubpassDescriptionFlags		flags;
			VK_PIPELINE_BIND_POINT_GRAPHICS,						//  VkPipelineBindPoint				pipelineBindPoint;
			0u,														//  deUint32						inputAttachmentCount;
			DE_NULL,												//  const VkAttachmentReference*	pInputAttachments;
			hasColor ? 1u : 0u,										//  deUint32						colorAttachmentCount;
			hasColor ? &colorAttachmentRef : DE_NULL,				//  const VkAttachmentReference*	pColorAttachments;
			hasColorResolve ? &colorResolveAttachmentRef : DE_NULL,	//  const VkAttachmentReference*	pResolveAttachments;
			hasDepthStencil ? &depthStencilAttachmentRef : DE_NULL,	//  const VkAttachmentReference*	pDepthStencilAttachment;
			0u,														//  deUint32						preserveAttachmentCount;
			DE_NULL													//  const deUint32*					pPreserveAttachments;
		};
		const VkRenderPassCreateInfo			renderPassInfo								=
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	//  VkStructureType					sType;
			DE_NULL,									//  const void*						pNext;
			(VkRenderPassCreateFlags)0,					//  VkRenderPassCreateFlags			flags;
			(deUint32)attachmentDescriptions.size(),	//  deUint32						attachmentCount;
			&attachmentDescriptions[0],					//  const VkAttachmentDescription*	pAttachments;
			1u,											//  deUint32						subpassCount;
			&subpassDescription,						//  const VkSubpassDescription*		pSubpasses;
			0u,											//  deUint32						dependencyCount;
			DE_NULL										//  const VkSubpassDependency*		pDependencies;
		};

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

Move<VkRenderPass> makeRenderPass (const DeviceInterface&				vk,
								   const VkDevice						device,
								   const VkFormat						colorFormat,
								   const VkAllocationCallbacks* const	allocationCallbacks)
{
	const VkAttachmentDescription	attachmentDescriptions[]	=
	{
		{
			(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_GENERAL						//  VkImageLayout					finalLayout;
		},
		{
			(VkAttachmentDescriptionFlags)0,			//  VkAttachmentDescriptionFlags	flags;
			colorFormat,								//  VkFormat						format;
			VK_SAMPLE_COUNT_1_BIT,						//  VkSampleCountFlagBits			samples;
			VK_ATTACHMENT_LOAD_OP_LOAD,					//  VkAttachmentLoadOp				loadOp;
			VK_ATTACHMENT_STORE_OP_STORE,				//  VkAttachmentStoreOp				storeOp;
			VK_ATTACHMENT_LOAD_OP_DONT_CARE,			//  VkAttachmentLoadOp				stencilLoadOp;
			VK_ATTACHMENT_STORE_OP_DONT_CARE,			//  VkAttachmentStoreOp				stencilStoreOp;
			VK_IMAGE_LAYOUT_UNDEFINED,					//  VkImageLayout					initialLayout;
			VK_IMAGE_LAYOUT_GENERAL						//  VkImageLayout					finalLayout;
		},
	};
	const VkAttachmentReference		colorAttachmentRef0			=
	{
		0u,							//  deUint32		attachment;
		VK_IMAGE_LAYOUT_GENERAL		//  VkImageLayout	layout;
	};
	const deUint32					preserveAttachment			= 1u;
	const VkAttachmentReference		inputAttachmentRef1			=
	{
		0u,							//  deUint32		attachment;
		VK_IMAGE_LAYOUT_GENERAL		//  VkImageLayout	layout;
	};
	const VkAttachmentReference		colorAttachmentRef1			=
	{
		1u,							//  deUint32		attachment;
		VK_IMAGE_LAYOUT_GENERAL		//  VkImageLayout	layout;
	};
	const VkSubpassDescription		subpassDescriptions[]		=
	{
		{
			(VkSubpassDescriptionFlags)0,				//  VkSubpassDescriptionFlags		flags;
			VK_PIPELINE_BIND_POINT_GRAPHICS,			//  VkPipelineBindPoint				pipelineBindPoint;
			0u,											//  deUint32						inputAttachmentCount;
			DE_NULL,									//  const VkAttachmentReference*	pInputAttachments;
			1u,											//  deUint32						colorAttachmentCount;
			&colorAttachmentRef0,						//  const VkAttachmentReference*	pColorAttachments;
			DE_NULL,									//  const VkAttachmentReference*	pResolveAttachments;
			DE_NULL,									//  const VkAttachmentReference*	pDepthStencilAttachment;
			1u,											//  deUint32						preserveAttachmentCount;
			&preserveAttachment							//  const deUint32*					pPreserveAttachments;
		},
		{
			(VkSubpassDescriptionFlags)0,				//  VkSubpassDescriptionFlags		flags;
			VK_PIPELINE_BIND_POINT_GRAPHICS,			//  VkPipelineBindPoint				pipelineBindPoint;
			1u,											//  deUint32						inputAttachmentCount;
			&inputAttachmentRef1,						//  const VkAttachmentReference*	pInputAttachments;
			1u,											//  deUint32						colorAttachmentCount;
			&colorAttachmentRef1,						//  const VkAttachmentReference*	pColorAttachments;
			DE_NULL,									//  const VkAttachmentReference*	pResolveAttachments;
			DE_NULL,									//  const VkAttachmentReference*	pDepthStencilAttachment;
			0u,											//  deUint32						preserveAttachmentCount;
			DE_NULL										//  const deUint32*					pPreserveAttachments;
		},
	};
	const VkSubpassDependency		subpassDependency			=
	{
		0,												//  deUint32						srcSubpass;
		1u,												//  deUint32						dstSubpass;
		VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,	//  VkPipelineStageFlags			srcStageMask;
		VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,			//  VkPipelineStageFlags			dstStageMask;
		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			//  VkAccessFlags					srcAccessMask;
		VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,			//  VkAccessFlags					dstAccessMask;
		VK_DEPENDENCY_VIEW_LOCAL_BIT_KHR,				//  VkDependencyFlags				dependencyFlags;
	};
	const VkRenderPassCreateInfo	renderPassInfo				=
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,		//  VkStructureType					sType;
		DE_NULL,										//  const void*						pNext;
		(VkRenderPassCreateFlags)0,						//  VkRenderPassCreateFlags			flags;
		DE_LENGTH_OF_ARRAY(attachmentDescriptions),		//  deUint32						attachmentCount;
		&attachmentDescriptions[0],						//  const VkAttachmentDescription*	pAttachments;
		DE_LENGTH_OF_ARRAY(subpassDescriptions),		//  deUint32						subpassCount;
		&subpassDescriptions[0],						//  const VkSubpassDescription*		pSubpasses;
		1u,												//  deUint32						dependencyCount;
		&subpassDependency								//  const VkSubpassDependency*		pDependencies;
	};

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

VkImageCreateInfo makeImageCreateInfo (const VkFormat format, const VkExtent2D size, const VkImageUsageFlags usage, VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT)
{
	const VkExtent3D		extent		= { size.width, size.height, 1u };
	const VkImageCreateInfo imageParams =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
		DE_NULL,										// const void*				pNext;
		0u,												// VkImageCreateFlags		flags;
		VK_IMAGE_TYPE_2D,								// VkImageType				imageType;
		format,											// VkFormat					format;
		extent,											// VkExtent3D				extent;
		1u,												// deUint32					mipLevels;
		1u,												// deUint32					arrayLayers;
		samples,										// 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 imageParams;
}

std::vector<VkFramebufferAttachmentImageInfoKHR> makeFramebufferAttachmentImageInfos (const VkExtent2D&			renderSize,
																					  const VkFormat*			colorFormat,
																					  const VkImageUsageFlags	colorUsage,
																					  const VkFormat*			dsFormat,
																					  const VkImageUsageFlags	dsUsage,
																					  const AspectFlags			resolveAspects,
																					  const deUint32			inputAttachmentCount)
{
	const bool											colorResolve					= (resolveAspects & ASPECT_COLOR) != 0;
	const bool											depthStencilResolve				= (resolveAspects & ASPECT_DEPTH_STENCIL) != 0;
	std::vector<VkFramebufferAttachmentImageInfoKHR>	framebufferAttachmentImageInfos;

	DE_ASSERT(colorFormat != DE_NULL);
	DE_ASSERT(dsFormat != DE_NULL);

	if (*colorFormat != VK_FORMAT_UNDEFINED)
	{
		const VkFramebufferAttachmentImageInfoKHR	framebufferAttachmentImageInfo		=
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR,	//  VkStructureType		sType;
			DE_NULL,													//  const void*			pNext;
			(VkImageCreateFlags)0u,										//  VkImageCreateFlags	flags;
			colorUsage,													//  VkImageUsageFlags	usage;
			renderSize.width,											//  deUint32			width;
			renderSize.height,											//  deUint32			height;
			1u,															//  deUint32			layerCount;
			1u,															//  deUint32			viewFormatCount;
			colorFormat													//  const VkFormat*		pViewFormats;
		};

		framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
	}

	if (*dsFormat != VK_FORMAT_UNDEFINED)
	{
		const VkFramebufferAttachmentImageInfoKHR	framebufferAttachmentImageInfo		=
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR,	//  VkStructureType		sType;
			DE_NULL,													//  const void*			pNext;
			(VkImageCreateFlags)0u,										//  VkImageCreateFlags	flags;
			dsUsage,													//  VkImageUsageFlags	usage;
			renderSize.width,											//  deUint32			width;
			renderSize.height,											//  deUint32			height;
			1u,															//  deUint32			layerCount;
			1u,															//  deUint32			viewFormatCount;
			dsFormat													//  const VkFormat*		pViewFormats;
		};

		framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
	}

	if (colorResolve)
	{
		const VkFramebufferAttachmentImageInfoKHR	framebufferAttachmentImageInfo		=
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR,	//  VkStructureType		sType;
			DE_NULL,													//  const void*			pNext;
			(VkImageCreateFlags)0u,										//  VkImageCreateFlags	flags;
			colorUsage,													//  VkImageUsageFlags	usage;
			renderSize.width,											//  deUint32			width;
			renderSize.height,											//  deUint32			height;
			1u,															//  deUint32			layerCount;
			1u,															//  deUint32			viewFormatCount;
			colorFormat													//  const VkFormat*		pViewFormats;
		};

		DE_ASSERT(*colorFormat != VK_FORMAT_UNDEFINED);

		framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
	}

	if (depthStencilResolve)
	{
		const VkFramebufferAttachmentImageInfoKHR	framebufferAttachmentImageInfo		=
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR,	//  VkStructureType		sType;
			DE_NULL,													//  const void*			pNext;
			(VkImageCreateFlags)0u,										//  VkImageCreateFlags	flags;
			dsUsage,													//  VkImageUsageFlags	usage;
			renderSize.width,											//  deUint32			width;
			renderSize.height,											//  deUint32			height;
			1u,															//  deUint32			layerCount;
			1u,															//  deUint32			viewFormatCount;
			dsFormat													//  const VkFormat*		pViewFormats;
		};

		DE_ASSERT(*dsFormat != VK_FORMAT_UNDEFINED);

		framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
	}

	for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < inputAttachmentCount; ++inputAttachmentNdx)
	{
		const VkFramebufferAttachmentImageInfoKHR	framebufferAttachmentImageInfo		=
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR,	//  VkStructureType		sType;
			DE_NULL,													//  const void*			pNext;
			(VkImageCreateFlags)0u,										//  VkImageCreateFlags	flags;
			colorUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,			//  VkImageUsageFlags	usage;
			renderSize.width,											//  deUint32			width;
			renderSize.height,											//  deUint32			height;
			1u,															//  deUint32			layerCount;
			1u,															//  deUint32			viewFormatCount;
			colorFormat													//  const VkFormat*		pViewFormats;
		};

		framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
	}

	return framebufferAttachmentImageInfos;
}

Move<VkFramebuffer> makeFramebuffer (const DeviceInterface&			vk,
									 const VkDevice					device,
									 const VkRenderPass				renderPass,
									 const VkExtent2D&				renderSize,
									 const VkFormat*				colorFormat,
									 const VkImageUsageFlags		colorUsage,
									 const VkFormat*				dsFormat,
									 const VkImageUsageFlags		dsUsage					= static_cast<VkImageUsageFlags>(0),
									 const AspectFlags				resolveAspects			= ASPECT_NONE,
									 const deUint32					inputAttachmentCount	= 0)
{
	const std::vector<VkFramebufferAttachmentImageInfoKHR>	framebufferAttachmentImageInfos		= makeFramebufferAttachmentImageInfos(renderSize, colorFormat, colorUsage, dsFormat, dsUsage, resolveAspects, inputAttachmentCount);
	const deUint32											attachmentCount						= static_cast<deUint32>(framebufferAttachmentImageInfos.size());
	const VkFramebufferAttachmentsCreateInfoKHR				framebufferAttachmentsCreateInfo	=
	{
		VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR,	//  VkStructureType								sType;
		DE_NULL,													//  const void*									pNext;
		attachmentCount,											//  deUint32									attachmentImageInfoCount;
		&framebufferAttachmentImageInfos[0]							//  const VkFramebufferAttachmentImageInfoKHR*	pAttachmentImageInfos;
	};
	const VkFramebufferCreateInfo							framebufferInfo	=
	{
		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,					//  VkStructureType				sType;
		&framebufferAttachmentsCreateInfo,							//  const void*					pNext;
		VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR,					//  VkFramebufferCreateFlags	flags;
		renderPass,													//  VkRenderPass				renderPass;
		attachmentCount,											//  deUint32					attachmentCount;
		DE_NULL,													//  const VkImageView*			pAttachments;
		renderSize.width,											//  deUint32					width;
		renderSize.height,											//  deUint32					height;
		1u,															//  deUint32					layers;
	};

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

Move<VkFramebuffer> makeVerifyFramebuffer (const DeviceInterface&	vk,
										   const VkDevice			device,
										   const VkRenderPass		renderPass,
										   const VkImageView		colorAttachment,
										   const VkExtent2D&		renderSize,
										   const deUint32			layers = 1u)
{
	const VkFramebufferCreateInfo framebufferInfo = {
		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		//  VkStructureType				sType;
		DE_NULL,										//  const void*					pNext;
		(VkFramebufferCreateFlags)0,					//  VkFramebufferCreateFlags	flags;
		renderPass,										//  VkRenderPass				renderPass;
		1u,												//  deUint32					attachmentCount;
		&colorAttachment,								//  const VkImageView*			pAttachments;
		renderSize.width,								//  deUint32					width;
		renderSize.height,								//  deUint32					height;
		layers,											//  deUint32					layers;
	};

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

Move<VkPipelineLayout> makeVerifyPipelineLayout (const DeviceInterface&			vk,
												 const VkDevice					device,
												 const VkDescriptorSetLayout	descriptorSetLayout)
{
	const VkPushConstantRange			pushConstantRanges			=
	{
		VK_SHADER_STAGE_FRAGMENT_BIT,					//  VkShaderStageFlags				stageFlags;
		0u,												//  deUint32						offset;
		sizeof(deUint32)								//  deUint32						size;
	};
	const VkPipelineLayoutCreateInfo	pipelineLayoutCreateInfo	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	//  VkStructureType					sType;
		DE_NULL,										//  const void*						pNext;
		(VkPipelineLayoutCreateFlags)0,					//  VkPipelineLayoutCreateFlags		flags;
		1u,												//  deUint32						setLayoutCount;
		&descriptorSetLayout,							//  const VkDescriptorSetLayout*	pSetLayouts;
		1u,												//  deUint32						pushConstantRangeCount;
		&pushConstantRanges,							//  const VkPushConstantRange*		pPushConstantRanges;
	};
	return createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
}

Move<VkRenderPass> makeVerifyRenderPass (const DeviceInterface&	vk,
										 const VkDevice			device,
										 const VkFormat			colorFormat)
{
	return makeRenderPass(vk, device, colorFormat);
}

VkImageMemoryBarrier makeImageMemoryBarrier	(const VkAccessFlags			srcAccessMask,
											 const VkAccessFlags			dstAccessMask,
											 const VkImageLayout			oldLayout,
											 const VkImageLayout			newLayout,
											 const VkImage					image,
											 const VkImageSubresourceRange	subresourceRange)
{
	const VkImageMemoryBarrier barrier =
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
		DE_NULL,										// const void*				pNext;
		srcAccessMask,									// VkAccessFlags			outputMask;
		dstAccessMask,									// VkAccessFlags			inputMask;
		oldLayout,										// VkImageLayout			oldLayout;
		newLayout,										// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32					destQueueFamilyIndex;
		image,											// VkImage					image;
		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
	};
	return barrier;
}

VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags	srcAccessMask,
											   const VkAccessFlags	dstAccessMask,
											   const VkBuffer		buffer,
											   const VkDeviceSize	offset,
											   const VkDeviceSize	bufferSizeBytes)
{
	const VkBufferMemoryBarrier barrier =
	{
		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//  VkStructureType	sType;
		DE_NULL,									//  const void*		pNext;
		srcAccessMask,								//  VkAccessFlags	srcAccessMask;
		dstAccessMask,								//  VkAccessFlags	dstAccessMask;
		VK_QUEUE_FAMILY_IGNORED,					//  deUint32		srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					//  deUint32		destQueueFamilyIndex;
		buffer,										//  VkBuffer		buffer;
		offset,										//  VkDeviceSize	offset;
		bufferSizeBytes,							//  VkDeviceSize	size;
	};
	return barrier;
}

Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice& device)
{
	const VkSamplerCreateInfo createInfo =
	{
		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		//  VkStructureType			sType;
		DE_NULL,									//  const void*				pNext;
		0u,											//  VkSamplerCreateFlags	flags;
		VK_FILTER_NEAREST,							//  VkFilter				magFilter;
		VK_FILTER_NEAREST,							//  VkFilter				minFilter;
		VK_SAMPLER_MIPMAP_MODE_LINEAR,				//  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, &createInfo);
}

void fillBuffer (const DeviceInterface& vk, const VkDevice device, Allocation& bufferAlloc, const void* data, const VkDeviceSize dataSize)
{
	const VkMappedMemoryRange	memRange		=
	{
		VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,	//  VkStructureType	sType;
		DE_NULL,								//  const void*		pNext;
		bufferAlloc.getMemory(),				//  VkDeviceMemory	memory;
		bufferAlloc.getOffset(),				//  VkDeviceSize	offset;
		VK_WHOLE_SIZE							//  VkDeviceSize	size;
	};
	const deUint32				dataSize32		= static_cast<deUint32>(dataSize);

	deMemcpy(bufferAlloc.getHostPtr(), data, dataSize32);
	VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &memRange));
}

std::vector<float> getFullQuadVertices (void)
{
	const float					verticesData[]	=
	{
		-1.0f, -1.0f, 0.0f, 1.0f,
		-1.0f, +1.0f, 0.0f, 1.0f,
		+1.0f, -1.0f, 0.0f, 1.0f,
		-1.0f, +1.0f, 0.0f, 1.0f,
		+1.0f, -1.0f, 0.0f, 1.0f,
		+1.0f, +1.0f, 0.0f, 1.0f,
	};
	const std::vector<float>	vertices		(verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));

	return vertices;
}

void checkImageFormatProperties (const InstanceInterface&	vki,
								 const VkPhysicalDevice&	physDevice,
								 const VkFormat				format,
								 const VkImageUsageFlags	imageUsageFlags,
								 const VkExtent2D&			requiredSize2D)
{
	const VkImageType			imageType			= VK_IMAGE_TYPE_2D;
	const VkImageTiling			imageTiling			= VK_IMAGE_TILING_OPTIMAL;
	const VkImageCreateFlags	imageCreateFlags	= static_cast<VkImageCreateFlags>(0u);
	const deUint32				requiredLayers		= 1u;
	const VkExtent3D			requiredSize		= makeExtent3D(requiredSize2D.height, requiredSize2D.width, 1u);

	VkImageFormatProperties	imageFormatProperties;
	VkResult				result;

	deMemset(&imageFormatProperties, 0, sizeof(imageFormatProperties));

	result = vki.getPhysicalDeviceImageFormatProperties(physDevice, format, imageType, imageTiling, imageUsageFlags, imageCreateFlags, &imageFormatProperties);

	if (result									!= VK_SUCCESS			||
		imageFormatProperties.maxArrayLayers	<  requiredLayers		||
		imageFormatProperties.maxExtent.height	<  requiredSize.height	||
		imageFormatProperties.maxExtent.width	<  requiredSize.width	||
		imageFormatProperties.maxExtent.depth	<  requiredSize.depth)
	{
		TCU_THROW(NotSupportedError, "Depth/stencil format is not supported");
	}
}

VkFormat getStencilBufferFormat(VkFormat depthStencilImageFormat)
{
	const tcu::TextureFormat	tcuFormat	= mapVkFormat(depthStencilImageFormat);
	const VkFormat				result		= (tcuFormat.order == tcu::TextureFormat::S || tcuFormat.order == tcu::TextureFormat::DS) ? VK_FORMAT_S8_UINT : VK_FORMAT_UNDEFINED;

	DE_ASSERT(result != VK_FORMAT_UNDEFINED);

	return result;
}

static MovePtr<tcu::TextureLevel> convertDepthToColor (const tcu::TextureFormat& dataFormat, const int width, const int height, const void* data, const tcu::TextureFormat& targetFormat)
{
	const tcu::ConstPixelBufferAccess	srcImage	(dataFormat, width, height, 1u, data);
	MovePtr<tcu::TextureLevel>			dstImage	(new tcu::TextureLevel(targetFormat, width, height, 1u));
	tcu::PixelBufferAccess				dstAccess	(dstImage->getAccess());

	for (int y = 0; y < height; y++)
	for (int x = 0; x < width; x++)
	{
		const float		depth	= srcImage.getPixDepth(x, y);
		const tcu::Vec4	color	= tcu::Vec4(depth, depth, depth, 1.0f);

		dstAccess.setPixel(color, x, y);
	}

	return dstImage;
}

static MovePtr<tcu::TextureLevel> convertStencilToColor (const tcu::TextureFormat& dataFormat, const int width, const int height, const void* data, const tcu::TextureFormat& targetFormat)
{
	const int							maxValue	(4);
	const tcu::ConstPixelBufferAccess	srcImage	(dataFormat, width, height, 1u, data);
	MovePtr<tcu::TextureLevel>			dstImage	(new tcu::TextureLevel(targetFormat, width, height, 1u));
	tcu::PixelBufferAccess				dstAccess	(dstImage->getAccess());

	for (int y = 0; y < height; y++)
	for (int x = 0; x < width; x++)
	{
		const int		stencilInt	= srcImage.getPixStencil(x, y);
		const float		stencil		= (stencilInt < maxValue) ? float(stencilInt) / float(maxValue) : 1.0f;
		const tcu::Vec4	color		= tcu::Vec4(stencil, stencil, stencil, 1.0f);

		dstAccess.setPixel(color, x, y);
	}

	return dstImage;
}

class ColorImagelessTestInstance : public TestInstance
{
public:
										ColorImagelessTestInstance			(Context& context, const TestParameters& parameters);
protected:
	virtual tcu::TestStatus				iterate								(void);

	virtual std::vector<float>			getVertices							(void);
	void								readOneSampleFromMultisampleImage	(const VkFormat					srcFormat,
																			 const Unique<VkImage>&			srcImage,
																			 const deUint32					sampleID,
																			 const VkFormat					dstFormat,
																			 const Unique<VkImage>&			dstImage,
																			 const Unique<VkBuffer>&		dstBuffer,
																			 const AspectFlags				aspect);
	virtual MovePtr<tcu::TextureLevel>	generateReferenceImage				(const tcu::TextureFormat&		textureFormat,
																			 const AspectFlags				aspectFlags,
																			 const deUint32					sample,
																			 const deUint32					subpass);
	virtual bool						verifyBuffer						(const UniquePtr<Allocation>&	bufAlloc,
																			 const VkFormat					bufferFormat,
																			 const std::string&				name,
																			 const AspectFlags				aspectFlags,
																			 const deUint32					sample		= NO_SAMPLE,
																			 const deUint32					subpass		= NO_SUBPASS);
	virtual bool						verifyBufferInternal				(const void*					resultData,
																			 const tcu::TextureFormat&		textureFormat,
																			 const tcu::TextureLevel&		referenceImage,
																			 const std::string&				name);

	const bool							m_extensions;
	const VkExtent2D					m_imageExtent2D;
	const TestParameters				m_parameters;
	VkImageUsageFlags					m_colorImageUsage;
};

ColorImagelessTestInstance::ColorImagelessTestInstance (Context& context, const TestParameters& parameters)
	: TestInstance				(context)
	, m_extensions				(context.requireDeviceExtension("VK_KHR_imageless_framebuffer"))
	, m_imageExtent2D			(makeExtent2D(32u, 32u))
	, m_parameters				(parameters)
	, m_colorImageUsage			(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)
{
	const InstanceInterface&								vki								= m_context.getInstanceInterface();
	const VkPhysicalDevice									physDevice						= m_context.getPhysicalDevice();
	const VkPhysicalDeviceImagelessFramebufferFeaturesKHR&	imagelessFramebufferFeatures	(context.getImagelessFramebufferFeatures());

	if (imagelessFramebufferFeatures.imagelessFramebuffer == DE_FALSE)
		TCU_THROW(NotSupportedError, "Imageless framebuffer is not supported");

	checkImageFormatProperties(vki, physDevice, m_parameters.colorFormat, m_colorImageUsage, m_imageExtent2D);
}

void ColorImagelessTestInstance::readOneSampleFromMultisampleImage (const VkFormat			srcFormat,
																	const Unique<VkImage>&	srcImage,
																	const deUint32			sampleID,
																	const VkFormat			dstFormat,
																	const Unique<VkImage>&	dstImage,
																	const Unique<VkBuffer>&	dstBuffer,
																	const AspectFlags		aspect)
{
	const DeviceInterface&				vk					= m_context.getDeviceInterface();
	const VkDevice						device				= m_context.getDevice();
	const deUint32						queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	const VkQueue						queue				= m_context.getUniversalQueue();
	Allocator&							allocator			= m_context.getDefaultAllocator();

	const tcu::Vec4						clearColor			= tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
	const bool							color				= ((aspect & ASPECT_COLOR) != 0);
	const bool							depth				= ((aspect & ASPECT_DEPTH) != 0);
	const bool							stencil				= ((aspect & ASPECT_STENCIL) != 0);
	const VkImageAspectFlags			srcAspect			= color   ? VK_IMAGE_ASPECT_COLOR_BIT
															: depth   ? VK_IMAGE_ASPECT_DEPTH_BIT
															: VK_IMAGE_ASPECT_STENCIL_BIT;
	const VkImageSubresourceRange		srcSubresRange		= makeImageSubresourceRange(srcAspect, 0u, 1u, 0u, 1u);
	const Unique<VkImageView>			srcImageView		(makeImageView			(vk, device, *srcImage, VK_IMAGE_VIEW_TYPE_2D, srcFormat, srcSubresRange));

	const VkImageAspectFlags			dstAspect			= VK_IMAGE_ASPECT_COLOR_BIT;
	const VkImageSubresourceRange		dstSubresRange		= makeImageSubresourceRange(dstAspect, 0u, 1u, 0u, 1u);
	const Unique<VkImageView>			dstAttachment		(makeImageView			(vk, device, *dstImage, VK_IMAGE_VIEW_TYPE_2D, dstFormat, dstSubresRange));

	const std::string					fragModuleInfix		= color   ? "-color"
															: depth   ? "-depth"
															: stencil ? "-stencil"
															: "";
	const Unique<VkShaderModule>		vertModule			(createShaderModule		(vk, device, m_context.getBinaryCollection().get("demultisample-vert"), 0u));
	const Unique<VkShaderModule>		fragModule			(createShaderModule		(vk, device, m_context.getBinaryCollection().get("demultisample" + fragModuleInfix + "-frag"), 0u));
	const Unique<VkRenderPass>			renderPass			(makeVerifyRenderPass	(vk, device, dstFormat));
	const Unique<VkFramebuffer>			framebuffer			(makeVerifyFramebuffer	(vk, device, *renderPass, *dstAttachment, m_imageExtent2D));

	const VkDescriptorType				samplerDescType		(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
	const Unique<VkSampler>				sampler				(makeSampler(vk, device));
	const Unique<VkDescriptorSetLayout>	descriptorSetLayout	(DescriptorSetLayoutBuilder()
		.addSingleSamplerBinding(samplerDescType, VK_SHADER_STAGE_FRAGMENT_BIT, &sampler.get())
		.build(vk, device));
	const Unique<VkDescriptorPool>		descriptorPool		(DescriptorPoolBuilder()
		.addType(samplerDescType)
		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
	const Unique<VkDescriptorSet>		descriptorSet		(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
	const VkDescriptorImageInfo			imageDescriptorInfo	(makeDescriptorImageInfo(DE_NULL, *srcImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));

	DescriptorSetUpdateBuilder()
		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), samplerDescType, &imageDescriptorInfo)
		.update(vk, device);

	const Unique<VkPipelineLayout>		pipelineLayout		(makeVerifyPipelineLayout	(vk, device, *descriptorSetLayout));
	const Unique<VkPipeline>			pipeline			(makeGraphicsPipeline		(vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D));
	const Unique<VkCommandPool>			cmdPool				(createCommandPool			(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>		cmdBuffer			(allocateCommandBuffer		(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const std::vector<float>			vertexArray			(getFullQuadVertices());
	const deUint32						vertexCount			(static_cast<deUint32>(vertexArray.size() / 4u));
	const VkDeviceSize					vertexArraySize		(vertexArray.size() * sizeof(vertexArray[0]));
	const Unique<VkBuffer>				vertexBuffer		(makeBuffer				(vk, device, vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
	const UniquePtr<Allocation>			vertexBufferAlloc	(bindBuffer				(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
	const VkDeviceSize					vertexBufferOffset	(0u);

	fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);

	beginCommandBuffer(vk, *cmdBuffer);
	{
		if (sampleID == 0)
		{
			if (color)
			{
				const VkImageMemoryBarrier	preCopyBarrier	= makeImageMemoryBarrier	(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
																						 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
																						 *srcImage, srcSubresRange);

				vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
			}
			else if (depth)
			{
				const VkImageSubresourceRange	preCopySubresRange	= makeImageSubresourceRange	(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, 1u);
				const VkImageMemoryBarrier		preCopyBarrier		= makeImageMemoryBarrier	(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
																								 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
																								 *srcImage, preCopySubresRange);

				vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
			}
		}

		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor);
		{
			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

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

			vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);

			vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(sampleID), &sampleID);

			vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
		}
		endRenderPass(vk, *cmdBuffer);

		// Image copy
		{
			const VkImageMemoryBarrier	preCopyBarrier	= makeImageMemoryBarrier	(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
																					 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
																					 *dstImage, dstSubresRange);
			const VkBufferImageCopy		region			= makeBufferImageCopy		(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
																					 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
			const VkBufferMemoryBarrier	postCopyBarrier	= makeBufferMemoryBarrier	(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *dstBuffer, 0ull, VK_WHOLE_SIZE);

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
			vk.cmdCopyImageToBuffer(*cmdBuffer, *dstImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dstBuffer, 1u, &region);
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
		}
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
}

bool ColorImagelessTestInstance::verifyBufferInternal (const void* resultData, const tcu::TextureFormat& textureFormat, const tcu::TextureLevel& referenceImage, const std::string& name)
{
	const int							dataSize		(m_imageExtent2D.width * m_imageExtent2D.height * textureFormat.getPixelSize());
	const tcu::ConstPixelBufferAccess	referenceAccess	(referenceImage.getAccess());

	if (deMemCmp(resultData, referenceAccess.getDataPtr(), dataSize) != 0)
	{
		const tcu::ConstPixelBufferAccess	resultImage	(textureFormat, m_imageExtent2D.width, m_imageExtent2D.height, 1u, resultData);
		bool								ok;

		ok = tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), "", referenceAccess, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);

		return ok;
	}

	return true;
}

bool ColorImagelessTestInstance::verifyBuffer (const UniquePtr<Allocation>& bufAlloc, const VkFormat bufferFormat, const std::string& name, const AspectFlags aspectFlags, const deUint32 sample, const deUint32 subpass)
{
	invalidateMappedMemoryRange(m_context.getDeviceInterface(), m_context.getDevice(), bufAlloc->getMemory(), bufAlloc->getOffset(), VK_WHOLE_SIZE);

	const tcu::TextureFormat			bufferTextureFormat		(mapVkFormat(bufferFormat));
	const bool							multisampled			(sample != NO_SAMPLE);
	const bool							depth					((aspectFlags & ASPECT_DEPTH) != 0);
	const bool							stencil					((aspectFlags & ASPECT_STENCIL) != 0);
	const bool							convertRequired			((depth || stencil) && !multisampled);
	const tcu::TextureFormat			convertTextureFormat	(tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::UNORM_INT8));
	const tcu::TextureFormat			referenceTextureFormat	(convertRequired ? convertTextureFormat : bufferTextureFormat);
	const MovePtr<tcu::TextureLevel>	referenceImage			(generateReferenceImage(referenceTextureFormat, aspectFlags, sample, subpass));

	if (!multisampled && depth)
	{
		MovePtr<tcu::TextureLevel>	convertedImage	(convertDepthToColor(bufferTextureFormat, m_imageExtent2D.width, m_imageExtent2D.height, bufAlloc->getHostPtr(), convertTextureFormat));
		tcu::ConstPixelBufferAccess	convertedAccess	(convertedImage->getAccess());

		return verifyBufferInternal(convertedAccess.getDataPtr(), convertTextureFormat, *referenceImage, name);
	}
	else if (!multisampled && stencil)
	{
		MovePtr<tcu::TextureLevel>	convertedImage	(convertStencilToColor(bufferTextureFormat, m_imageExtent2D.width, m_imageExtent2D.height, bufAlloc->getHostPtr(), convertTextureFormat));
		tcu::ConstPixelBufferAccess	convertedAccess	(convertedImage->getAccess());

		return verifyBufferInternal(convertedAccess.getDataPtr(), convertTextureFormat, *referenceImage, name);
	}
	else
	{
		const void*	resultData	(bufAlloc->getHostPtr());

		return verifyBufferInternal(resultData, bufferTextureFormat, *referenceImage, name);
	}
}

MovePtr<tcu::TextureLevel> ColorImagelessTestInstance::generateReferenceImage (const tcu::TextureFormat&	textureFormat,
																			   const AspectFlags			aspectFlags,
																			   const deUint32				sample,
																			   const deUint32				subpass)
{
	const int					width			= m_imageExtent2D.width;
	const int					height			= m_imageExtent2D.height;
	const int					componentValue	(static_cast<int>(0.75f * 0x100));
	const tcu::RGBA				colorDrawRGBA	(tcu::RGBA(componentValue, componentValue, componentValue, 0xFF));
	const tcu::Vec4				colorDraw		(colorDrawRGBA.toVec());
	const tcu::Vec4				colorFill		(tcu::RGBA::black().toVec());
	MovePtr<tcu::TextureLevel>	image			(new tcu::TextureLevel(textureFormat, width, height));
	tcu::PixelBufferAccess		access			(image->getAccess());

	DE_UNREF(aspectFlags);
	DE_ASSERT(aspectFlags == ASPECT_COLOR);
	DE_UNREF(sample);
	DE_ASSERT(sample == NO_SAMPLE);
	DE_UNREF(subpass);
	DE_ASSERT(subpass == NO_SUBPASS);

	for (int y = 0; y < height; ++y)
	{
		const tcu::Vec4&	validColor	= (y < height / 2) ? colorFill : colorDraw;

		for (int x = 0; x < width; ++x)
			access.setPixel(validColor, x, y);
	}

	return image;
}

std::vector<float> ColorImagelessTestInstance::getVertices (void)
{
	const float					verticesData[]	=
	{
		-1.0f,  0.0f, 0.0f, 1.0f,
		-1.0f, +1.0f, 0.0f, 1.0f,
		+1.0f,  0.0f, 0.0f, 1.0f,
		-1.0f, +1.0f, 0.0f, 1.0f,
		+1.0f,  0.0f, 0.0f, 1.0f,
		+1.0f, +1.0f, 0.0f, 1.0f,
	};
	const std::vector<float>	vertices		(verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));

	return vertices;
}

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

	const tcu::Vec4					clearColor			= tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
	const VkFormat					colorFormat			= m_parameters.colorFormat;
	const VkDeviceSize				colorBufferSize		= m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
	const VkImageSubresourceRange	colorSubresRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);

	const Unique<VkImage>			colorImage			(makeImage				(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
	const UniquePtr<Allocation>		colorImageAlloc		(bindImage				(vk, device, allocator, *colorImage, MemoryRequirement::Any));
	const Unique<VkImageView>		colorAttachment		(makeImageView			(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
	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));

	const Unique<VkShaderModule>	vertModule			(createShaderModule		(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
	const Unique<VkShaderModule>	fragModule			(createShaderModule		(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
	const Unique<VkRenderPass>		renderPass			(makeRenderPass			(vk, device, colorFormat, m_parameters.dsFormat));
	const Unique<VkFramebuffer>		framebuffer			(makeFramebuffer		(vk, device, *renderPass, m_imageExtent2D, &colorFormat, m_colorImageUsage, &m_parameters.dsFormat));
	const Unique<VkPipelineLayout>	pipelineLayout		(makePipelineLayout		(vk, device));
	const Unique<VkPipeline>		pipeline			(makeGraphicsPipeline	(vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D));
	const Unique<VkCommandPool>		cmdPool				(createCommandPool		(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>	cmdBuffer			(allocateCommandBuffer	(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const std::vector<float>		vertexArray			(getVertices());
	const deUint32					vertexCount			(static_cast<deUint32>(vertexArray.size() / 4u));
	const VkDeviceSize				vertexArraySize		(vertexArray.size() * sizeof(vertexArray[0]));
	const Unique<VkBuffer>			vertexBuffer		(makeBuffer				(vk, device, vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
	const UniquePtr<Allocation>		vertexBufferAlloc	(bindBuffer				(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
	const VkDeviceSize				vertexBufferOffset	(0u);

	fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);

	beginCommandBuffer(vk, *cmdBuffer);
	{
		const VkRenderPassAttachmentBeginInfoKHR	renderPassAttachmentBeginInfo	=
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR,	//  VkStructureType		sType;
			DE_NULL,													//  const void*			pNext;
			1u,															//  deUint32			attachmentCount;
			&*colorAttachment											//  const VkImageView*	pAttachments;
		};

		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, &renderPassAttachmentBeginInfo);
		{
			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

			vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);

			vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
		}
		endRenderPass(vk, *cmdBuffer);

		// Color image copy
		{
			const VkImageMemoryBarrier	preCopyBarrier	= makeImageMemoryBarrier	(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
																					 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
																					 *colorImage, colorSubresRange);
			const VkBufferImageCopy		region			= makeBufferImageCopy		(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
																					 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
			const VkBufferMemoryBarrier	postCopyBarrier	= makeBufferMemoryBarrier	(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE);

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
			vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &region);
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
		}
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	if (verifyBuffer(colorBufferAlloc, colorFormat, "Color", ASPECT_COLOR))
		return tcu::TestStatus::pass("Pass");
	else
		return tcu::TestStatus::fail("Fail");
}

class DepthImagelessTestInstance : public ColorImagelessTestInstance
{
public:
										DepthImagelessTestInstance	(Context& context, const TestParameters& parameters);

protected:
	virtual tcu::TestStatus				iterate						(void);

	virtual std::vector<float>			getVertices					(void);

	virtual MovePtr<tcu::TextureLevel>	generateReferenceImage		(const tcu::TextureFormat&	textureFormat,
																	 const AspectFlags			aspectFlags,
																	 const deUint32				sample,
																	 const deUint32				subpass);

	VkImageUsageFlags					m_dsImageUsage;
};

DepthImagelessTestInstance::DepthImagelessTestInstance (Context& context, const TestParameters& parameters)
	: ColorImagelessTestInstance	(context, parameters)
	, m_dsImageUsage				(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)
{
	const InstanceInterface&	vki			= m_context.getInstanceInterface();
	const VkPhysicalDevice		physDevice	= m_context.getPhysicalDevice();

	checkImageFormatProperties(vki, physDevice, m_parameters.dsFormat, m_dsImageUsage, m_imageExtent2D);
}

MovePtr<tcu::TextureLevel> DepthImagelessTestInstance::generateReferenceImage (const tcu::TextureFormat&	textureFormat,
																			   const AspectFlags			aspectFlags,
																			   const deUint32				sample,
																			   const deUint32				subpass)
{
	const bool					color	= ((aspectFlags & ASPECT_COLOR) != 0);
	const bool					depth	= ((aspectFlags & ASPECT_DEPTH) != 0);
	const bool					stencil	= ((aspectFlags & ASPECT_STENCIL) != 0);
	const int					width	= m_imageExtent2D.width;
	const int					height	= m_imageExtent2D.height;
	MovePtr<tcu::TextureLevel>	image	(new tcu::TextureLevel(textureFormat, width, height));
	tcu::PixelBufferAccess		access	(image->getAccess());

	DE_ASSERT(dePop32(aspectFlags) == 1);
	DE_UNREF(sample);
	DE_ASSERT(sample == NO_SAMPLE);
	DE_UNREF(subpass);
	DE_ASSERT(subpass == NO_SUBPASS);

	if (color)
	{
		const int		componentValue	(static_cast<int>(0.75f * 0x100));
		const tcu::RGBA	colorDrawRGBA	(tcu::RGBA(componentValue, componentValue, componentValue, 0xFF));
		const tcu::Vec4	colorDraw		(colorDrawRGBA.toVec());
		const tcu::Vec4	colorDrawTop	(tcu::RGBA::white().toVec());
		const tcu::Vec4	colorFill		(tcu::RGBA::black().toVec());

		for (int y = 0; y < height; ++y)
		for (int x = 0; x < width; ++x)
		{
			const tcu::Vec4&	validColor	= (y < height / 2) ? colorFill
											: (x < width  / 2) ? colorDraw
											: colorDrawTop;

			access.setPixel(validColor, x, y);
		}
	}

	if (depth)
	{
		const int			colorFillValue	(static_cast<int>(1.00f * 0x100));
		const int			colorDrawValue	(static_cast<int>(0.50f * 0x100));
		const int			colorTopValue	(static_cast<int>(0.25f * 0x100));
		const tcu::IVec4	colorFill		(colorFillValue, 0, 0, 0xFF);
		const tcu::IVec4	colorDraw		(colorDrawValue, 0, 0, 0xFF);
		const tcu::IVec4	colorTop		(colorTopValue,  0, 0, 0xFF);

		for (int y = 0; y < height; ++y)
		for (int x = 0; x < width; ++x)
		{
			const tcu::IVec4&	validColor	= (y < height / 2) ? colorFill
											: (x < width  / 2) ? colorDraw
											: colorTop;

			access.setPixel(validColor, x, y);
		}
	}

	if (stencil)
	{
		const int			colorFillValue	(static_cast<int>(0.00f * 0x100));
		const int			colorDrawValue	(static_cast<int>(0.25f * 0x100));
		const int			colorTopValue	(static_cast<int>(0.50f * 0x100));
		const tcu::IVec4	colorFill		(colorFillValue, 0, 0, 0xFF);
		const tcu::IVec4	colorDraw		(colorDrawValue, 0, 0, 0xFF);
		const tcu::IVec4	colorTop		(colorTopValue,  0, 0, 0xFF);

		for (int y = 0; y < height; ++y)
		for (int x = 0; x < width; ++x)
		{
			const tcu::IVec4&	validColor	= (y < height / 2) ? colorFill
											: (x < width  / 2) ? colorDraw
											: colorTop;

			access.setPixel(validColor, x, y);
		}
	}

	return image;
}

std::vector<float> DepthImagelessTestInstance::getVertices (void)
{
	const float					verticesData[]	=
	{
		-1.0f,  0.0f, 0.50f, 1.0f,
		-1.0f, +1.0f, 0.50f, 1.0f,
		+1.0f,  0.0f, 0.50f, 1.0f,
		-1.0f, +1.0f, 0.50f, 1.0f,
		+1.0f,  0.0f, 0.50f, 1.0f,
		+1.0f, +1.0f, 0.50f, 1.0f,

		 0.0f,  0.0f, 0.25f, 1.0f,
		 0.0f, +1.0f, 0.25f, 1.0f,
		+1.0f,  0.0f, 0.25f, 1.0f,
		 0.0f, +1.0f, 0.25f, 1.0f,
		+1.0f,  0.0f, 0.25f, 1.0f,
		+1.0f, +1.0f, 0.25f, 1.0f,
	};
	const std::vector<float>	vertices		(verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));

	return vertices;
}

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

	const tcu::Vec4					clearColor			= tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
	const VkFormat					colorFormat			= m_parameters.colorFormat;
	const VkDeviceSize				colorBufferSize		= m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
	const VkImageSubresourceRange	colorSubresRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);

	const Unique<VkImage>			colorImage			(makeImage				(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
	const UniquePtr<Allocation>		colorImageAlloc		(bindImage				(vk, device, allocator, *colorImage, MemoryRequirement::Any));
	const Unique<VkImageView>		colorAttachment		(makeImageView			(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
	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));

	const float						clearDepth			= 1.0f;
	const deUint32					clearStencil		= 0u;
	const VkFormat					dsFormat			= m_parameters.dsFormat;
	const deUint32					dsImagePixelSize	= static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(dsFormat)));
	const VkImageAspectFlags		dsAspectFlags		= VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
	const VkImageSubresourceRange	dsSubresRange		= makeImageSubresourceRange(dsAspectFlags, 0u, 1u, 0u, 1u);

	const VkDeviceSize				depthBufferSize		= m_imageExtent2D.width * m_imageExtent2D.height * dsImagePixelSize;
	const VkFormat					stencilBufferFormat	= getStencilBufferFormat(dsFormat);
	const deUint32					stencilPixelSize	= static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(stencilBufferFormat)));
	const VkDeviceSize				stencilBufferSize	= m_imageExtent2D.width * m_imageExtent2D.height * stencilPixelSize;

	const Unique<VkImage>			dsImage				(makeImage				(vk, device, makeImageCreateInfo(dsFormat, m_imageExtent2D, m_dsImageUsage)));
	const UniquePtr<Allocation>		dsImageAlloc		(bindImage				(vk, device, allocator, *dsImage, MemoryRequirement::Any));
	const Unique<VkImageView>		dsAttachment		(makeImageView			(vk, device, *dsImage, VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsSubresRange));
	const Unique<VkBuffer>			depthBuffer			(makeBuffer				(vk, device, depthBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const UniquePtr<Allocation>		depthBufferAlloc	(bindBuffer				(vk, device, allocator, *depthBuffer, MemoryRequirement::HostVisible));
	const Unique<VkBuffer>			stencilBuffer		(makeBuffer				(vk, device, stencilBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const UniquePtr<Allocation>		stencilBufferAlloc	(bindBuffer				(vk, device, allocator, *stencilBuffer, MemoryRequirement::HostVisible));

	const Unique<VkShaderModule>	vertModule			(createShaderModule		(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
	const Unique<VkShaderModule>	fragModule			(createShaderModule		(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
	const Unique<VkRenderPass>		renderPass			(makeRenderPass			(vk, device, colorFormat, dsFormat));
	const Unique<VkFramebuffer>		framebuffer			(makeFramebuffer		(vk, device, *renderPass, m_imageExtent2D, &colorFormat, m_colorImageUsage, &dsFormat, m_dsImageUsage));
	const Unique<VkPipelineLayout>	pipelineLayout		(makePipelineLayout		(vk, device));
	const Unique<VkPipeline>		pipeline			(makeGraphicsPipeline	(vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D, ASPECT_DEPTH_STENCIL));
	const Unique<VkCommandPool>		cmdPool				(createCommandPool		(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>	cmdBuffer			(allocateCommandBuffer	(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const std::vector<float>		vertexArray			(getVertices());
	const deUint32					vertexCount			(static_cast<deUint32>(vertexArray.size() / 4u));
	const VkDeviceSize				vertexArraySize		(vertexArray.size() * sizeof(vertexArray[0]));
	const Unique<VkBuffer>			vertexBuffer		(makeBuffer				(vk, device, vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
	const UniquePtr<Allocation>		vertexBufferAlloc	(bindBuffer				(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
	const VkDeviceSize				vertexBufferOffset	(0u);

	fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);

	beginCommandBuffer(vk, *cmdBuffer);
	{
		const VkImageView							attachments[]					= { *colorAttachment, *dsAttachment };
		const VkRenderPassAttachmentBeginInfoKHR	renderPassAttachmentBeginInfo	=
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR,	//  VkStructureType		sType;
			DE_NULL,													//  const void*			pNext;
			DE_LENGTH_OF_ARRAY(attachments),							//  deUint32			attachmentCount;
			attachments													//  const VkImageView*	pAttachments;
		};

		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, clearDepth, clearStencil, &renderPassAttachmentBeginInfo);
		{
			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

			vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);

			vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
		}
		endRenderPass(vk, *cmdBuffer);

		// Color image copy
		{
			const VkImageMemoryBarrier	preCopyBarrier	= makeImageMemoryBarrier	(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
																					 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
																					 *colorImage, colorSubresRange);
			const VkBufferImageCopy		region			= makeBufferImageCopy		(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
																					 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
			const VkBufferMemoryBarrier	postCopyBarrier	= makeBufferMemoryBarrier	(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE);

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
			vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &region);
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
		}

		// Depth/Stencil image copy
		{
			const VkImageMemoryBarrier	preCopyBarrier		= makeImageMemoryBarrier(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
																VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dsImage, dsSubresRange);
			const VkBufferImageCopy		depthCopyRegion		= makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
																				  makeImageSubresourceLayers(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u));
			const VkBufferImageCopy		stencilCopyRegion	= makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
																				  makeImageSubresourceLayers(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u));
			const VkBufferMemoryBarrier	postCopyBarriers[]	=
			{
				makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *depthBuffer, 0ull, VK_WHOLE_SIZE),
				makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *stencilBuffer, 0ull, VK_WHOLE_SIZE),
			};

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
			vk.cmdCopyImageToBuffer(*cmdBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *depthBuffer, 1u, &depthCopyRegion);
			vk.cmdCopyImageToBuffer(*cmdBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *stencilBuffer, 1u, &stencilCopyRegion);
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(postCopyBarriers), postCopyBarriers, DE_NULL, 0u);
		}
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	{
		std::string result;

		if (!verifyBuffer(colorBufferAlloc, colorFormat, "Color", ASPECT_COLOR))
			result += " Color";

		if (!verifyBuffer(depthBufferAlloc, dsFormat, "Depth", ASPECT_DEPTH))
			result += " Depth";

		if (!verifyBuffer(stencilBufferAlloc, stencilBufferFormat, "Stencil", ASPECT_STENCIL))
			result += " Stencil";

		if (result.empty())
			return tcu::TestStatus::pass("Pass");
		else
			return tcu::TestStatus::fail("Following parts of image are incorrect:" + result);
	}
}

class ColorResolveImagelessTestInstance : public ColorImagelessTestInstance
{
public:
										ColorResolveImagelessTestInstance	(Context& context, const TestParameters& parameters);
protected:
	virtual tcu::TestStatus				iterate								(void);

	virtual MovePtr<tcu::TextureLevel>	generateReferenceImage				(const tcu::TextureFormat&	textureFormat,
																			 const AspectFlags			aspectFlags,
																			 const deUint32				sample,
																			 const deUint32				subpass);

	virtual std::vector<float>			getVertices							(void);
};

ColorResolveImagelessTestInstance::ColorResolveImagelessTestInstance (Context& context, const TestParameters& parameters)
	: ColorImagelessTestInstance	(context, parameters)
{
	const InstanceInterface&	vki			= m_context.getInstanceInterface();
	const VkPhysicalDevice		physDevice	= m_context.getPhysicalDevice();

	// To validate per-sample image image must also be sampled
	m_colorImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT;

	checkImageFormatProperties(vki, physDevice, m_parameters.colorFormat, m_colorImageUsage, m_imageExtent2D);
}

MovePtr<tcu::TextureLevel> ColorResolveImagelessTestInstance::generateReferenceImage (const tcu::TextureFormat&	textureFormat,
																					  const AspectFlags			aspectFlags,
																					  const deUint32			sample,
																					  const deUint32			subpass)
{
	const int					width			= m_imageExtent2D.width;
	const int					height			= m_imageExtent2D.height;
	MovePtr<tcu::TextureLevel>	image			(new tcu::TextureLevel(textureFormat, width, height));
	tcu::PixelBufferAccess		access			(image->getAccess());
	const int					componentValue	(static_cast<int>(0.75f * 0x100));
	const tcu::RGBA				colorDrawRGBA	(tcu::RGBA(componentValue, componentValue, componentValue, 0xFF));
	const tcu::Vec4				colorDraw		(colorDrawRGBA.toVec());
	const tcu::Vec4				colorFill		(tcu::RGBA::black().toVec());
	const tcu::Vec4				colorEdge0		(colorDraw);
	const tcu::Vec4				colorEdge1		(colorFill);
	const tcu::Vec4				colorEdge2		(colorDraw);
	const tcu::Vec4				colorEdge3		(colorFill);
	const tcu::Vec4				colorEdgeR		((colorDraw.x() + colorFill.x()) / 2, (colorDraw.y() + colorFill.y()) / 2, (colorDraw.z() + colorFill.z()) / 2, colorDraw.w()); // AVERAGE
	const tcu::Vec4&			colorEdge		= sample == 0 ? colorEdge0
												: sample == 1 ? colorEdge1
												: sample == 2 ? colorEdge2
												: sample == 3 ? colorEdge3
												: colorEdgeR;

	DE_UNREF(aspectFlags);
	DE_ASSERT(dePop32(aspectFlags) == 1);
	DE_ASSERT(aspectFlags == ASPECT_COLOR);
	DE_UNREF(subpass);
	DE_ASSERT(subpass == NO_SUBPASS);

	for (int y = 0; y < height; ++y)
	for (int x = 0; x < width; ++x)
	{
		const int			mx			= width - 1 - x;
		const tcu::Vec4&	validColor	= (y == mx) ? colorEdge
										: (y >  mx) ? colorFill
										: colorDraw;

		access.setPixel(validColor, x, y);
	}

	return image;
}

std::vector<float> ColorResolveImagelessTestInstance::getVertices (void)
{
	const float					verticesData[]	=
	{
		-1.0f, -1.0f, 0.0f, 1.0f,
		-1.0f, +1.0f, 0.0f, 1.0f,
		+1.0f, -1.0f, 0.0f, 1.0f,
	};
	const std::vector<float>	vertices		(verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));

	return vertices;
}

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

	const VkSampleCountFlagBits		sampleCount				= VK_SAMPLE_COUNT_4_BIT;
	const tcu::Vec4					clearColor				= tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
	const VkFormat					colorFormat				= m_parameters.colorFormat;
	const VkDeviceSize				colorBufferSize			= m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
	const VkImageSubresourceRange	colorSubresRange		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);

	const Unique<VkImage>			colorImage				(makeImage				(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage, sampleCount)));
	const UniquePtr<Allocation>		colorImageAlloc			(bindImage				(vk, device, allocator, *colorImage, MemoryRequirement::Any));
	const Unique<VkImageView>		colorAttachment			(makeImageView			(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));

	const Unique<VkImage>			colorResolveImage		(makeImage				(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
	const UniquePtr<Allocation>		colorResolveImageAlloc	(bindImage				(vk, device, allocator, *colorResolveImage, MemoryRequirement::Any));
	const Unique<VkImageView>		colorResolveAttachment	(makeImageView			(vk, device, *colorResolveImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
	const Unique<VkBuffer>			colorResolveBuffer		(makeBuffer				(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const UniquePtr<Allocation>		colorResolveBufferAlloc	(bindBuffer				(vk, device, allocator, *colorResolveBuffer, MemoryRequirement::HostVisible));

	const Unique<VkShaderModule>	vertModule				(createShaderModule		(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
	const Unique<VkShaderModule>	fragModule				(createShaderModule		(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
	const Unique<VkRenderPass>		renderPass				(makeRenderPass			(vk, device, colorFormat, m_parameters.dsFormat, sampleCount));
	const Unique<VkFramebuffer>		framebuffer				(makeFramebuffer		(vk, device, *renderPass, m_imageExtent2D, &colorFormat, m_colorImageUsage, &m_parameters.dsFormat, 0u, ASPECT_COLOR));
	const Unique<VkPipelineLayout>	pipelineLayout			(makePipelineLayout		(vk, device));
	const Unique<VkPipeline>		pipeline				(makeGraphicsPipeline	(vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D, ASPECT_NONE, sampleCount));
	const Unique<VkCommandPool>		cmdPool					(createCommandPool		(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>	cmdBuffer				(allocateCommandBuffer	(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const std::vector<float>		vertexArray				(getVertices());
	const deUint32					vertexCount				(static_cast<deUint32>(vertexArray.size() / 4u));
	const VkDeviceSize				vertexArraySize			(vertexArray.size() * sizeof(vertexArray[0]));
	const Unique<VkBuffer>			vertexBuffer			(makeBuffer				(vk, device, vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
	const UniquePtr<Allocation>		vertexBufferAlloc		(bindBuffer				(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
	const VkDeviceSize				vertexBufferOffset		(0u);

	fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);

	beginCommandBuffer(vk, *cmdBuffer);
	{
		const VkImageView							attachments[]					= { *colorAttachment, *colorResolveAttachment };
		const VkRenderPassAttachmentBeginInfoKHR	renderPassAttachmentBeginInfo	=
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR,	//  VkStructureType		sType;
			DE_NULL,													//  const void*			pNext;
			DE_LENGTH_OF_ARRAY(attachments),							//  deUint32			attachmentCount;
			attachments													//  const VkImageView*	pAttachments;
		};

		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, &renderPassAttachmentBeginInfo);
		{
			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

			vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);

			vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
		}
		endRenderPass(vk, *cmdBuffer);

		// Color image copy
		{
			const VkImageMemoryBarrier	preCopyBarrier	= makeImageMemoryBarrier	(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
																					 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
																					 *colorResolveImage, colorSubresRange);
			const VkBufferImageCopy		region			= makeBufferImageCopy		(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
																					 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
			const VkBufferMemoryBarrier	postCopyBarrier	= makeBufferMemoryBarrier	(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorResolveBuffer, 0ull, VK_WHOLE_SIZE);

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
			vk.cmdCopyImageToBuffer(*cmdBuffer, *colorResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorResolveBuffer, 1u, &region);
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
		}
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	{
		std::string result;

		if (!verifyBuffer(colorResolveBufferAlloc, colorFormat, "ResolveColor", ASPECT_COLOR))
			result += " ResolveColor";

		// Parse color aspect of separate samples of multisample image
		for (deUint32 sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx)
		{
			const std::string				name				("Color" + de::toString(sampleNdx));
			const Unique<VkImage>			imageSample			(makeImage	(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
			const UniquePtr<Allocation>		imageSampleAlloc	(bindImage	(vk, device, allocator, *imageSample, MemoryRequirement::Any));
			const Unique<VkBuffer>			imageBuffer			(makeBuffer	(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
			const UniquePtr<Allocation>		imageBufferAlloc	(bindBuffer	(vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible));

			readOneSampleFromMultisampleImage(colorFormat, colorImage, sampleNdx, colorFormat, imageSample, imageBuffer, ASPECT_COLOR);

			if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_COLOR, sampleNdx))
				result += " " + name;
		}


		if (result.empty())
			return tcu::TestStatus::pass("Pass");
		else
			return tcu::TestStatus::fail("Fail");
	}
}

class DepthResolveImagelessTestInstance : public DepthImagelessTestInstance
{
public:
										DepthResolveImagelessTestInstance	(Context& context, const TestParameters& parameters);

protected:
	virtual tcu::TestStatus				iterate								(void);

	virtual MovePtr<tcu::TextureLevel>	generateReferenceImage				(const tcu::TextureFormat&	textureFormat,
																			 const AspectFlags			aspectFlags,
																			 const deUint32				sample,
																			 const deUint32				subpass);

	virtual std::vector<float>			getVertices							(void);
};

DepthResolveImagelessTestInstance::DepthResolveImagelessTestInstance (Context& context, const TestParameters& parameters)
	: DepthImagelessTestInstance	(context, parameters)
{
	context.requireDeviceExtension("VK_KHR_depth_stencil_resolve");

	const InstanceInterface&							vki					= m_context.getInstanceInterface();
	const VkPhysicalDevice								physDevice			= m_context.getPhysicalDevice();
	VkPhysicalDeviceProperties2							deviceProperties;
	VkPhysicalDeviceDepthStencilResolvePropertiesKHR	dsResolveProperties;

	deMemset(&deviceProperties, 0, sizeof(deviceProperties));
	deMemset(&dsResolveProperties, 0, sizeof(dsResolveProperties));

	deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
	deviceProperties.pNext = &dsResolveProperties;

	dsResolveProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
	dsResolveProperties.pNext = DE_NULL;

	vki.getPhysicalDeviceProperties2(physDevice, &deviceProperties);

	m_colorImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT;

	checkImageFormatProperties(vki, physDevice, m_parameters.colorFormat, m_colorImageUsage, m_imageExtent2D);

	m_dsImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT;

	checkImageFormatProperties(vki, physDevice, m_parameters.dsFormat, m_dsImageUsage, m_imageExtent2D);
}

MovePtr<tcu::TextureLevel> DepthResolveImagelessTestInstance::generateReferenceImage (const tcu::TextureFormat&	textureFormat,
																					  const AspectFlags			aspectFlags,
																					  const deUint32			sample,
																					  const deUint32			subpass)
{
	const bool					color	= ((aspectFlags & ASPECT_COLOR) != 0);
	const bool					depth	= ((aspectFlags & ASPECT_DEPTH) != 0);
	const bool					stencil	= ((aspectFlags & ASPECT_STENCIL) != 0);
	const int					width	= m_imageExtent2D.width;
	const int					height	= m_imageExtent2D.height;
	MovePtr<tcu::TextureLevel>	image	(new tcu::TextureLevel(textureFormat, width, height));
	tcu::PixelBufferAccess		access	(image->getAccess());

	DE_ASSERT(dePop32(aspectFlags) == 1);
	DE_UNREF(subpass);

	if (color)
	{
		const tcu::Vec4		colorDraw	(tcu::RGBA::blue().toVec());
		const tcu::Vec4		colorFill	(tcu::RGBA::black().toVec());
		const tcu::Vec4		colorEdge0	(colorDraw);
		const tcu::Vec4		colorEdge1	(colorFill);
		const tcu::Vec4		colorEdge2	(colorDraw);
		const tcu::Vec4		colorEdge3	(colorFill);
		const tcu::Vec4		colorEdgeR	((colorDraw.x() + colorFill.x()) / 2, (colorDraw.y() + colorFill.y()) / 2, (colorDraw.z() + colorFill.z()) / 2, colorDraw.w()); // AVERAGE
		const tcu::Vec4&	colorEdge	= sample == 0 ? colorEdge0
										: sample == 1 ? colorEdge1
										: sample == 2 ? colorEdge2
										: sample == 3 ? colorEdge3
										: colorEdgeR;

		for (int y = 0; y < height; ++y)
		for (int x = 0; x < width; ++x)
		{
			const int			mx			= width - 1 - x;
			const tcu::Vec4&	validColor	= (y == mx) ? colorEdge
											: (y >  mx) ? colorFill
											: colorDraw;

			access.setPixel(validColor, x, y);
		}
	}

	if (depth)
	{
		const int			colorFillValue	(static_cast<int>(1.00f * 0x100));
		const int			colorDrawValue	(static_cast<int>(0.00f * 0x100));
		const tcu::IVec4	colorFill		(colorFillValue, colorFillValue, colorFillValue, 0xFF);
		const tcu::IVec4	colorDraw		(colorDrawValue, colorDrawValue, colorDrawValue, 0xFF);
		const tcu::IVec4	colorEdge0		(colorDraw);
		const tcu::IVec4	colorEdge1		(colorFill);
		const tcu::IVec4	colorEdge2		(colorDraw);
		const tcu::IVec4	colorEdge3		(colorFill);
		const tcu::IVec4	colorEdgeR		(colorEdge0); // SAMPLE_ZERO
		const tcu::IVec4&	colorEdge		= sample == 0 ? colorEdge0
											: sample == 1 ? colorEdge1
											: sample == 2 ? colorEdge2
											: sample == 3 ? colorEdge3
											: colorEdgeR;

		for (int y = 0; y < height; ++y)
		for (int x = 0; x < width; ++x)
		{
			const int			mx			= width - 1 - x;
			const tcu::IVec4&	validColor	= (y == mx) ? colorEdge
											: (y >  mx) ? colorFill
											: colorDraw;

			access.setPixel(validColor, x, y);
		}
	}

	if (stencil)
	{
		const int			colorFillValue	((0 * 0x100) / 4);
		const int			colorDrawValue	((1 * 0x100) / 4);
		const tcu::IVec4	colorFill		(colorFillValue, colorFillValue, colorFillValue, 0xFF);
		const tcu::IVec4	colorDraw		(colorDrawValue, colorDrawValue, colorDrawValue, 0xFF);
		const tcu::IVec4	colorEdge0		(colorDraw);
		const tcu::IVec4	colorEdge1		(colorFill);
		const tcu::IVec4	colorEdge2		(colorDraw);
		const tcu::IVec4	colorEdge3		(colorFill);
		const tcu::IVec4	colorEdgeR		(colorEdge0); // SAMPLE_ZERO
		const tcu::IVec4&	colorEdge		= sample == 0 ? colorEdge0
											: sample == 1 ? colorEdge1
											: sample == 2 ? colorEdge2
											: sample == 3 ? colorEdge3
											: colorEdgeR;

		for (int y = 0; y < height; ++y)
		for (int x = 0; x < width; ++x)
		{
			const int			mx			= width - 1 - x;
			const tcu::IVec4&	validColor	= (y == mx) ? colorEdge
											: (y >  mx) ? colorFill
											: colorDraw;

			access.setPixel(validColor, x, y);
		}
	}

	return image;
}

std::vector<float> DepthResolveImagelessTestInstance::getVertices (void)
{
	const float					verticesData[]	=
	{
		-1.0f, -1.0f, 0.0f, 1.0f,
		-1.0f, +1.0f, 0.0f, 1.0f,
		+1.0f, -1.0f, 0.0f, 1.0f,
		-1.0f, -1.0f, 0.5f, 1.0f,
		-1.0f, +1.0f, 0.5f, 1.0f,
		+1.0f, -1.0f, 0.5f, 1.0f,
	};
	const std::vector<float>	vertices		(verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));

	return vertices;
}

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

	const deUint32					sampleCount					= 4u;
	const VkSampleCountFlagBits		sampleCountFlag				= sampleCountBitFromSampleCount(sampleCount);
	const tcu::Vec4					clearColor					= tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
	const VkFormat					colorFormat					= m_parameters.colorFormat;
	const VkDeviceSize				colorBufferSize				= m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
	const VkImageSubresourceRange	colorSubresRange			= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);

	const Unique<VkImage>			colorImage					(makeImage				(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage, sampleCountFlag)));
	const UniquePtr<Allocation>		colorImageAlloc				(bindImage				(vk, device, allocator, *colorImage, MemoryRequirement::Any));
	const Unique<VkImageView>		colorAttachment				(makeImageView			(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));

	const Unique<VkImage>			colorResolveImage			(makeImage				(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
	const UniquePtr<Allocation>		colorResolveImageAlloc		(bindImage				(vk, device, allocator, *colorResolveImage, MemoryRequirement::Any));
	const Unique<VkImageView>		colorResolveAttachment		(makeImageView			(vk, device, *colorResolveImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
	const Unique<VkBuffer>			colorResolveBuffer			(makeBuffer				(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const UniquePtr<Allocation>		colorResolveBufferAlloc		(bindBuffer				(vk, device, allocator, *colorResolveBuffer, MemoryRequirement::HostVisible));

	const float						clearDepth					= 1.0f;
	const deUint32					clearStencil				= 0u;
	const VkFormat					dsFormat					= m_parameters.dsFormat;
	const deUint32					dsImagePixelSize			= static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(dsFormat)));
	const VkImageAspectFlags		dsAspectFlags				= VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
	const VkImageSubresourceRange	dsSubresRange				= makeImageSubresourceRange(dsAspectFlags, 0u, 1u, 0u, 1u);

	const VkDeviceSize				depthBufferSize				= m_imageExtent2D.width * m_imageExtent2D.height * dsImagePixelSize;
	const VkFormat					stencilBufferFormat			= getStencilBufferFormat(dsFormat);
	const deUint32					stencilPixelSize			= static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(stencilBufferFormat)));
	const VkDeviceSize				stencilBufferSize			= m_imageExtent2D.width * m_imageExtent2D.height * stencilPixelSize;

	const Unique<VkImage>			dsImage						(makeImage				(vk, device, makeImageCreateInfo(dsFormat, m_imageExtent2D, m_dsImageUsage, sampleCountFlag)));
	const UniquePtr<Allocation>		dsImageAlloc				(bindImage				(vk, device, allocator, *dsImage, MemoryRequirement::Any));
	const Unique<VkImageView>		dsAttachment				(makeImageView			(vk, device, *dsImage, VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsSubresRange));

	const Unique<VkImage>			dsResolveImage				(makeImage				(vk, device, makeImageCreateInfo(dsFormat, m_imageExtent2D, m_dsImageUsage)));
	const UniquePtr<Allocation>		dsResolveImageAlloc			(bindImage				(vk, device, allocator, *dsResolveImage, MemoryRequirement::Any));
	const Unique<VkImageView>		dsResolveAttachment			(makeImageView			(vk, device, *dsResolveImage, VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsSubresRange));
	const Unique<VkBuffer>			depthResolveBuffer			(makeBuffer				(vk, device, depthBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const UniquePtr<Allocation>		depthResolveBufferAlloc		(bindBuffer				(vk, device, allocator, *depthResolveBuffer, MemoryRequirement::HostVisible));
	const Unique<VkBuffer>			stencilResolveBuffer		(makeBuffer				(vk, device, stencilBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const UniquePtr<Allocation>		stencilResolveBufferAlloc	(bindBuffer				(vk, device, allocator, *stencilResolveBuffer, MemoryRequirement::HostVisible));

	const Unique<VkShaderModule>	vertModule					(createShaderModule		(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
	const Unique<VkShaderModule>	fragModule					(createShaderModule		(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
	const Unique<VkRenderPass>		renderPass					(makeRenderPass			(vk, device, colorFormat, m_parameters.dsFormat, sampleCountFlag, sampleCountFlag));
	const Unique<VkFramebuffer>		framebuffer					(makeFramebuffer		(vk, device, *renderPass, m_imageExtent2D, &colorFormat, m_colorImageUsage, &m_parameters.dsFormat, m_dsImageUsage, ASPECT_COLOR|ASPECT_DEPTH_STENCIL));
	const Unique<VkPipelineLayout>	pipelineLayout				(makePipelineLayout		(vk, device));
	const Unique<VkPipeline>		pipeline					(makeGraphicsPipeline	(vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D, ASPECT_DEPTH_STENCIL, sampleCountFlag));
	const Unique<VkCommandPool>		cmdPool						(createCommandPool		(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>	cmdBuffer					(allocateCommandBuffer	(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const std::vector<float>		vertexArray					(getVertices());
	const deUint32					vertexCount					(static_cast<deUint32>(vertexArray.size() / 4u));
	const VkDeviceSize				vertexArraySize				(vertexArray.size() * sizeof(vertexArray[0]));
	const Unique<VkBuffer>			vertexBuffer				(makeBuffer				(vk, device, vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
	const UniquePtr<Allocation>		vertexBufferAlloc			(bindBuffer				(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
	const VkDeviceSize				vertexBufferOffset			(0u);

	fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);

	beginCommandBuffer(vk, *cmdBuffer);
	{
		const VkImageView							attachments[]					= { *colorAttachment, *dsAttachment, *colorResolveAttachment, *dsResolveAttachment };
		const VkRenderPassAttachmentBeginInfoKHR	renderPassAttachmentBeginInfo	=
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR,	//  VkStructureType		sType;
			DE_NULL,													//  const void*			pNext;
			DE_LENGTH_OF_ARRAY(attachments),							//  deUint32			attachmentCount;
			attachments													//  const VkImageView*	pAttachments;
		};

		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, clearDepth, clearStencil, &renderPassAttachmentBeginInfo);
		{
			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

			vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);

			vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
		}
		endRenderPass(vk, *cmdBuffer);

		// Color resolve image copy
		{
			const VkImageMemoryBarrier	preCopyBarrier	= makeImageMemoryBarrier	(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
																					 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
																					 *colorResolveImage, colorSubresRange);
			const VkBufferImageCopy		region			= makeBufferImageCopy		(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
																					 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
			const VkBufferMemoryBarrier	postCopyBarrier	= makeBufferMemoryBarrier	(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorResolveBuffer, 0ull, VK_WHOLE_SIZE);

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
			vk.cmdCopyImageToBuffer(*cmdBuffer, *colorResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorResolveBuffer, 1u, &region);
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
		}

		// Depth/Stencil resolve image copy
		{
			const VkImageMemoryBarrier	preCopyBarrier		= makeImageMemoryBarrier(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
																					 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
																					 *dsResolveImage, dsSubresRange);
			const VkBufferImageCopy		depthCopyRegion		= makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
																				  makeImageSubresourceLayers(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u));
			const VkBufferImageCopy		stencilCopyRegion	= makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
																				  makeImageSubresourceLayers(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u));
			const VkBufferMemoryBarrier	postCopyBarriers[]	=
			{
				makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *depthResolveBuffer, 0ull, VK_WHOLE_SIZE),
				makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *stencilResolveBuffer, 0ull, VK_WHOLE_SIZE),
			};

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
			vk.cmdCopyImageToBuffer(*cmdBuffer, *dsResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *depthResolveBuffer, 1u, &depthCopyRegion);
			vk.cmdCopyImageToBuffer(*cmdBuffer, *dsResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *stencilResolveBuffer, 1u, &stencilCopyRegion);
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(postCopyBarriers), postCopyBarriers, DE_NULL, 0u);
		}
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	{
		std::string result;

		if (!verifyBuffer(colorResolveBufferAlloc, colorFormat, "ResolveColor", ASPECT_COLOR))
			result += " ResolveColor";

		if (!verifyBuffer(depthResolveBufferAlloc, dsFormat, "ResolveDepth", ASPECT_DEPTH))
			result += " ResolveDepth";

		if (!verifyBuffer(stencilResolveBufferAlloc, stencilBufferFormat, "ResolveStencil", ASPECT_STENCIL))
			result += " ResolveStencil";

		// Parse color aspect of separate samples of multisample image
		for (deUint32 sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx)
		{
			const std::string				name				("Color" + de::toString(sampleNdx));
			const Unique<VkImage>			imageSample			(makeImage	(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
			const UniquePtr<Allocation>		imageSampleAlloc	(bindImage	(vk, device, allocator, *imageSample, MemoryRequirement::Any));
			const Unique<VkBuffer>			imageBuffer			(makeBuffer	(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
			const UniquePtr<Allocation>		imageBufferAlloc	(bindBuffer	(vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible));

			readOneSampleFromMultisampleImage(colorFormat, colorImage, sampleNdx, colorFormat, imageSample, imageBuffer, ASPECT_COLOR);

			if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_COLOR, sampleNdx))
				result += " " + name;
		}

		// Parse depth aspect of separate samples of multisample image
		for (deUint32 sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx)
		{
			const std::string				name				("Depth" + de::toString(sampleNdx));
			const Unique<VkImage>			imageSample			(makeImage	(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
			const UniquePtr<Allocation>		imageSampleAlloc	(bindImage	(vk, device, allocator, *imageSample, MemoryRequirement::Any));
			const Unique<VkBuffer>			imageBuffer			(makeBuffer	(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
			const UniquePtr<Allocation>		imageBufferAlloc	(bindBuffer	(vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible));

			readOneSampleFromMultisampleImage(dsFormat, dsImage, sampleNdx, colorFormat, imageSample, imageBuffer, ASPECT_DEPTH);

			if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_DEPTH, sampleNdx))
				result += " " + name;
		}

		// Parse stencil aspect of separate samples of multisample image
		for (deUint32 sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx)
		{
			const std::string				name				("Stencil" + de::toString(sampleNdx));
			const Unique<VkImage>			imageSample			(makeImage	(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
			const UniquePtr<Allocation>		imageSampleAlloc	(bindImage	(vk, device, allocator, *imageSample, MemoryRequirement::Any));
			const Unique<VkBuffer>			imageBuffer			(makeBuffer	(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
			const UniquePtr<Allocation>		imageBufferAlloc	(bindBuffer	(vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible));

			readOneSampleFromMultisampleImage(dsFormat, dsImage, sampleNdx, colorFormat, imageSample, imageBuffer, ASPECT_STENCIL);

			if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_STENCIL, sampleNdx))
				result += " " + name;
		}

		if (result.empty())
			return tcu::TestStatus::pass("Pass");
		else
			return tcu::TestStatus::fail("Following parts of image are incorrect:" + result);
	}
}

class MultisubpassTestInstance : public ColorImagelessTestInstance
{
public:
										MultisubpassTestInstance	(Context& context, const TestParameters& parameters);

protected:
	virtual tcu::TestStatus				iterate						(void);

	virtual std::vector<float>			getVertices					(void);

	virtual MovePtr<tcu::TextureLevel>	generateReferenceImage		(const tcu::TextureFormat&	textureFormat,
																	 const AspectFlags			aspectFlags,
																	 const deUint32				sample,
																	 const deUint32				subpass);
};

MultisubpassTestInstance::MultisubpassTestInstance (Context& context, const TestParameters& parameters)
	: ColorImagelessTestInstance	(context, parameters)
{
}

std::vector<float> MultisubpassTestInstance::getVertices (void)
{
	const float					verticesData[]	=
	{
		-1.0f,  0.0f, 0.0f, 1.0f,
		-1.0f, +1.0f, 0.0f, 1.0f,
		+1.0f,  0.0f, 0.0f, 1.0f,
		-1.0f, +1.0f, 0.0f, 1.0f,
		+1.0f,  0.0f, 0.0f, 1.0f,
		+1.0f, +1.0f, 0.0f, 1.0f,
	};
	const std::vector<float>	vertices		(verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));

	return vertices;
}

MovePtr<tcu::TextureLevel> MultisubpassTestInstance::generateReferenceImage (const tcu::TextureFormat&	textureFormat,
																			 const AspectFlags			aspectFlags,
																			 const deUint32				sample,
																			 const deUint32				subpass)
{
	const int					width			= m_imageExtent2D.width;
	const int					height			= m_imageExtent2D.height;
	const tcu::Vec4				colorDraw0		(0.0f, 0.0f, 1.0f, 1.0f);
	const tcu::Vec4				colorFill0		(tcu::RGBA::black().toVec());
	const tcu::Vec4				colorDraw1		(colorDraw0.x(), 1.0f, colorDraw0.z(), 1.0f);
	const tcu::Vec4				colorFill1		(colorFill0.x(), 1.0f, colorFill0.z(), 1.0f);
	const tcu::Vec4&			colorDraw		((subpass == 0) ? colorDraw0 : colorDraw1);
	const tcu::Vec4&			colorFill		((subpass == 0) ? colorFill0 : colorFill1);
	MovePtr<tcu::TextureLevel>	image			(new tcu::TextureLevel(textureFormat, width, height));
	tcu::PixelBufferAccess		access			(image->getAccess());

	DE_UNREF(aspectFlags);
	DE_ASSERT(aspectFlags == ASPECT_COLOR);
	DE_UNREF(sample);
	DE_ASSERT(sample == NO_SAMPLE);
	DE_ASSERT(subpass != NO_SUBPASS);

	for (int y = 0; y < height; ++y)
	{
		const tcu::Vec4&	validColor	= (y < height / 2) ? colorFill : colorDraw;

		for (int x = 0; x < width; ++x)
			access.setPixel(validColor, x, y);
	}

	return image;
}

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

	const tcu::Vec4						clearColor			= tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
	const VkFormat						colorFormat			= m_parameters.colorFormat;
	const VkDeviceSize					colorBufferSize		= m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
	const VkImageSubresourceRange		colorSubresRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);

	const Unique<VkImage>				color0Image			(makeImage				(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)));
	const UniquePtr<Allocation>			color0ImageAlloc	(bindImage				(vk, device, allocator, *color0Image, MemoryRequirement::Any));
	const Unique<VkImageView>			color0Attachment	(makeImageView			(vk, device, *color0Image, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
	const Unique<VkBuffer>				color0Buffer		(makeBuffer				(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const UniquePtr<Allocation>			color0BufferAlloc	(bindBuffer				(vk, device, allocator, *color0Buffer, MemoryRequirement::HostVisible));

	const Unique<VkImage>				color1Image			(makeImage				(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)));
	const UniquePtr<Allocation>			color1ImageAlloc	(bindImage				(vk, device, allocator, *color1Image, MemoryRequirement::Any));
	const Unique<VkImageView>			color1Attachment	(makeImageView			(vk, device, *color1Image, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
	const Unique<VkBuffer>				color1Buffer		(makeBuffer				(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const UniquePtr<Allocation>			color1BufferAlloc	(bindBuffer				(vk, device, allocator, *color1Buffer, MemoryRequirement::HostVisible));

	const VkDescriptorType				descriptorType		(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
	const Unique<VkDescriptorSetLayout>	descriptorSetLayout	(DescriptorSetLayoutBuilder()
		.addSingleBinding(descriptorType, VK_SHADER_STAGE_FRAGMENT_BIT)
		.build(vk, device));
	const Unique<VkDescriptorPool>		descriptorPool		(DescriptorPoolBuilder()
		.addType(descriptorType)
		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
	const Unique<VkDescriptorSet>		descriptorSet		(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
	const VkDescriptorImageInfo			imageDescriptorInfo	(makeDescriptorImageInfo(DE_NULL, *color0Attachment, VK_IMAGE_LAYOUT_GENERAL));

	DescriptorSetUpdateBuilder()
		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageDescriptorInfo)
		.update(vk, device);

	const Unique<VkRenderPass>			renderPass			(makeRenderPass			(vk, device, colorFormat, DE_NULL));
	const Unique<VkFramebuffer>			framebuffer			(makeFramebuffer		(vk, device, *renderPass, m_imageExtent2D, &colorFormat, m_colorImageUsage, &m_parameters.dsFormat, 0u, ASPECT_NONE, 1u));
	const Unique<VkCommandPool>			cmdPool				(createCommandPool		(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>		cmdBuffer			(allocateCommandBuffer	(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const Unique<VkShaderModule>		vertModule0			(createShaderModule		(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
	const Unique<VkShaderModule>		fragModule0			(createShaderModule		(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
	const Unique<VkPipelineLayout>		pipelineLayout0		(makePipelineLayout		(vk, device));
	const Unique<VkPipeline>			pipeline0			(makeGraphicsPipeline	(vk, device, *pipelineLayout0, *renderPass, *vertModule0, *fragModule0, m_imageExtent2D));

	const Unique<VkShaderModule>		vertModule1			(createShaderModule		(vk, device, m_context.getBinaryCollection().get("vert1"), 0u));
	const Unique<VkShaderModule>		fragModule1			(createShaderModule		(vk, device, m_context.getBinaryCollection().get("frag1"), 0u));
	const Unique<VkPipelineLayout>		pipelineLayout1		(makePipelineLayout		(vk, device, 1u, &*descriptorSetLayout));
	const Unique<VkPipeline>			pipeline1			(makeGraphicsPipeline	(vk, device, *pipelineLayout1, *renderPass, *vertModule1, *fragModule1, m_imageExtent2D, 0u, VK_SAMPLE_COUNT_1_BIT, 1u));

	const std::vector<float>			vertex0Array		(getVertices());
	const deUint32						vertex0Count		(static_cast<deUint32>(vertex0Array.size() / 4u));
	const VkDeviceSize					vertex0ArraySize	(vertex0Array.size() * sizeof(vertex0Array[0]));
	const Unique<VkBuffer>				vertex0Buffer		(makeBuffer				(vk, device, vertex0ArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
	const UniquePtr<Allocation>			vertex0BufferAlloc	(bindBuffer				(vk, device, allocator, *vertex0Buffer, MemoryRequirement::HostVisible));
	const VkDeviceSize					vertex0BufferOffset	(0u);

	const std::vector<float>			vertex1Array		(getFullQuadVertices());
	const deUint32						vertex1Count		(static_cast<deUint32>(vertex1Array.size() / 4u));
	const VkDeviceSize					vertex1ArraySize	(vertex1Array.size() * sizeof(vertex1Array[0]));
	const Unique<VkBuffer>				vertex1Buffer		(makeBuffer				(vk, device, vertex1ArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
	const UniquePtr<Allocation>			vertex1BufferAlloc	(bindBuffer				(vk, device, allocator, *vertex1Buffer, MemoryRequirement::HostVisible));
	const VkDeviceSize					vertex1BufferOffset	(0u);

	fillBuffer(vk, device, *vertex0BufferAlloc, &vertex0Array[0], vertex0ArraySize);
	fillBuffer(vk, device, *vertex1BufferAlloc, &vertex1Array[0], vertex1ArraySize);

	beginCommandBuffer(vk, *cmdBuffer);
	{
		const VkImageView							attachments[]					= { *color0Attachment, *color1Attachment };
		const VkRenderPassAttachmentBeginInfoKHR	renderPassAttachmentBeginInfo	=
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR,	//  VkStructureType		sType;
			DE_NULL,													//  const void*			pNext;
			DE_LENGTH_OF_ARRAY(attachments),							//  deUint32			attachmentCount;
			&attachments[0]												//  const VkImageView*	pAttachments;
		};

		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, &renderPassAttachmentBeginInfo);
		{
			{
				vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline0);

				vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertex0Buffer, &vertex0BufferOffset);

				vk.cmdDraw(*cmdBuffer, vertex0Count, 1u, 0u, 0u);
			}

			vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);

			{
				vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);

				vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertex1Buffer, &vertex1BufferOffset);

				vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout1, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);

				vk.cmdDraw(*cmdBuffer, vertex1Count, 1u, 0u, 0u);
			}
		}
		endRenderPass(vk, *cmdBuffer);

		// Subpass0 color image copy
		{
			const VkImageMemoryBarrier	preCopyBarrier	= makeImageMemoryBarrier	(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
																					 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
																					 *color0Image, colorSubresRange);
			const VkBufferImageCopy		region			= makeBufferImageCopy		(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
																					 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
			const VkBufferMemoryBarrier	postCopyBarrier	= makeBufferMemoryBarrier	(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *color0Buffer, 0ull, VK_WHOLE_SIZE);

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
			vk.cmdCopyImageToBuffer(*cmdBuffer, *color0Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *color0Buffer, 1u, &region);
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
		}

		// Subpass1 color image copy
		{
			const VkImageMemoryBarrier	preCopyBarrier	= makeImageMemoryBarrier	(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
																					 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
																					 *color1Image, colorSubresRange);
			const VkBufferImageCopy		region			= makeBufferImageCopy		(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
																					 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
			const VkBufferMemoryBarrier	postCopyBarrier	= makeBufferMemoryBarrier	(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *color1Buffer, 0ull, VK_WHOLE_SIZE);

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
			vk.cmdCopyImageToBuffer(*cmdBuffer, *color1Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *color1Buffer, 1u, &region);
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
		}
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	{
		std::string result;

		if (!verifyBuffer(color0BufferAlloc, colorFormat, "ColorSubpass0", ASPECT_COLOR, NO_SAMPLE, 0u))
			result += " ColorSubpass0";

		if (!verifyBuffer(color1BufferAlloc, colorFormat, "ColorSubpass1", ASPECT_COLOR, NO_SAMPLE, 1u))
			result += " ColorSubpass1";

		if (result.empty())
			return tcu::TestStatus::pass("Pass");
		else
			return tcu::TestStatus::fail("Following parts of image are incorrect:" + result);
	}
}

class BaseTestCase : public TestCase
{
public:
							BaseTestCase	(tcu::TestContext& context, const std::string& name, const std::string& description, const TestParameters& parameters);
	virtual					~BaseTestCase	(void);

protected:
	virtual void			checkSupport	(Context& context) const;
	virtual void			initPrograms	(SourceCollections& programCollection) const;
	virtual TestInstance*	createInstance	(Context& context) const;

	const TestParameters	m_parameters;
};

BaseTestCase::BaseTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, const TestParameters& parameters)
	: TestCase		(context, name, description)
	, m_parameters	(parameters)
{
}

BaseTestCase::~BaseTestCase ()
{
}

void BaseTestCase::checkSupport (Context& context) const
{
	if (m_parameters.testType == TEST_TYPE_COLOR_RESOLVE || m_parameters.testType == TEST_TYPE_DEPTH_STENCIL_RESOLVE)
	{
		if (!context.getDeviceProperties().limits.standardSampleLocations)
			TCU_THROW(NotSupportedError, "Non-standard sample locations are not supported");
	}
}

void BaseTestCase::initPrograms (SourceCollections& programCollection) const
{
	// Vertex shader
	{
		std::ostringstream src;

		if (m_parameters.testType == TEST_TYPE_COLOR || m_parameters.testType == TEST_TYPE_COLOR_RESOLVE || m_parameters.testType == TEST_TYPE_DEPTH_STENCIL)
		{
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
				<< "\n"
				<< "layout(location = 0) in highp vec4 a_position;\n"
				<< "layout(location = 0) out highp vec4 a_color;\n"
				<< "\n"
				<< "void main (void)\n"
				<< "{\n"
				<< "    gl_Position = a_position;\n"
				<< "    if (gl_VertexIndex < 6)\n"
				<< "        a_color = vec4(0.75f, 0.75f, 0.75f, 1.0f);\n"
				<< "    else\n"
				<< "        a_color = vec4(1.00f, 1.00f, 1.00f, 1.0f);\n"
				<< "}\n";
		}

		if (m_parameters.testType == TEST_TYPE_DEPTH_STENCIL_RESOLVE)
		{
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
				<< "\n"
				<< "layout(location = 0) in highp vec4 a_position;\n"
				<< "layout(location = 0) out highp vec4 a_color;\n"
				<< "\n"
				<< "void main (void)\n"
				<< "{\n"
				<< "    gl_Position = a_position;\n"
				<< "    if (gl_VertexIndex < 3)\n"
				<< "        a_color = vec4(0.00f, 0.00f, 1.00f, 1.0f);\n"
				<< "    else\n"
				<< "        a_color = vec4(0.00f, 1.00f, 0.00f, 1.0f);\n"
				<< "}\n";
		}

		if (m_parameters.testType == TEST_TYPE_MULTISUBPASS)
		{
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
				<< "\n"
				<< "layout(location = 0) in highp vec4 a_position;\n"
				<< "layout(location = 0) out highp vec4 a_color;\n"
				<< "\n"
				<< "void main (void)\n"
				<< "{\n"
				<< "    gl_Position = a_position;\n"
				<< "    a_color = vec4(0.0f, 0.0f, 1.0f, 1.0f);\n"
				<< "}\n";
		}

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

	// Fragment shader
	{
		std::ostringstream src;

		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
			<< "\n"
			<< "layout(location = 0) in highp vec4 a_color;\n"
			<< "layout(location = 0) out highp vec4 o_color;\n"
			<< "\n"
			<< "void main (void)\n"
			<< "{\n"
			<< "    o_color = a_color;\n"
			<< "}\n";

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

	// Additional shaders
	if (m_parameters.testType == TEST_TYPE_COLOR_RESOLVE || m_parameters.testType == TEST_TYPE_DEPTH_STENCIL_RESOLVE)
	{
		// Vertex shader
		{
			std::ostringstream src;

			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
				<< "\n"
				<< "layout(location = 0) in highp vec4 a_position;\n"
				<< "\n"
				<< "void main (void)\n"
				<< "{\n"
				<< "    gl_Position = a_position;\n"
				<< "}\n";

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

		// Fragment shader
		{
			// Color
			{
				std::ostringstream src;

				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
					<< "\n"
					<< "layout(set = 0, binding = 0) uniform sampler2DMS u_ms_image_sampler;\n"
					<< "layout(push_constant) uniform PushConstantsBlock {\n"
					<< "    highp int sampleID;\n"
					<< "} pushConstants;\n"
					<< "layout(location = 0) out highp vec4 o_color;\n"
					<< "\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "    o_color = texelFetch(u_ms_image_sampler, ivec2(gl_FragCoord.xy), pushConstants.sampleID);\n"
					<< "}\n";

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

			// Depth
			{
				std::ostringstream src;

				// Depth-component textures are treated as one-component floating-point textures.
				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
					<< "\n"
					<< "layout(binding = 0) uniform sampler2DMS u_ms_image_sampler;\n"
					<< "layout(push_constant) uniform PushConstantsBlock {\n"
					<< "    highp int sampleID;\n"
					<< "} pushConstants;\n"
					<< "layout(location = 0) out highp vec4 o_color;\n"
					<< "\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "    vec4 val = texelFetch(u_ms_image_sampler, ivec2(gl_FragCoord.xy), pushConstants.sampleID);\n"
					<< "    o_color = vec4(val.x, val.x, val.x, 1.0);\n"
					<< "}\n";

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

			// Stencil
			{
				std::ostringstream src;

				// Stencil-component textures are treated as one-component unsigned integer textures.
				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
					<< "\n"
					<< "layout(binding = 0) uniform usampler2DMS u_ms_image_sampler;\n"
					<< "layout(push_constant) uniform PushConstantsBlock {\n"
					<< "    highp int sampleID;\n"
					<< "} pushConstants;\n"
					<< "layout(location = 0) out highp vec4 o_color;\n"
					<< "\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "    uvec4 uVal = texelFetch(u_ms_image_sampler, ivec2(gl_FragCoord.xy), pushConstants.sampleID);\n"
					<< "    float val = float(uVal.x) / 4.0f;\n"
					<< "    o_color = vec4(val, val, val, 1.0);\n"
					<< "}\n";

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

	if (m_parameters.testType == TEST_TYPE_MULTISUBPASS)
	{
		// Vertex shader
		{
			std::ostringstream src;

			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
				<< "\n"
				<< "layout(location = 0) in highp vec4 a_position;\n"
				<< "\n"
				<< "void main (void)\n"
				<< "{\n"
				<< "    gl_Position = a_position;\n"
				<< "}\n";

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

		// Fragment shader
		{
			std::ostringstream src;

			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
				<< "\n"
				<< "layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput u_colors;\n"
				<< "layout(location = 0) out highp vec4 o_color;\n"
				<< "\n"
				<< "void main (void)\n"
				<< "{\n"
				<< "    o_color = subpassLoad(u_colors);\n"
				<< "    o_color.g = 1.0f;\n"
				<< "    o_color.a = 1.0f;\n"
				<< "}\n";

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


	return;
}

TestInstance*	BaseTestCase::createInstance (Context& context) const
{
	if (m_parameters.testType == TEST_TYPE_COLOR)
		return new ColorImagelessTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_DEPTH_STENCIL)
		return new DepthImagelessTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_COLOR_RESOLVE)
		return new ColorResolveImagelessTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_DEPTH_STENCIL_RESOLVE)
		return new DepthResolveImagelessTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_MULTISUBPASS)
		return new MultisubpassTestInstance(context, m_parameters);

	TCU_THROW(InternalError, "Unknown test type specified");
}

tcu::TestNode*	imagelessColorTests (tcu::TestContext& testCtx)
{
	TestParameters	parameters	=
	{
		TEST_TYPE_COLOR,					//  TestType	testType;
		VK_FORMAT_R8G8B8A8_UNORM,			//  VkFormat	colorFormat;
		VK_FORMAT_UNDEFINED,				//  VkFormat	dsFormat;
	};

	return new BaseTestCase(testCtx, "color", "Imageless color attachment test", parameters);
}

tcu::TestNode*	imagelessDepthStencilTests (tcu::TestContext& testCtx)
{
	TestParameters	parameters	=
	{
		TEST_TYPE_DEPTH_STENCIL,			//  TestType	testType;
		VK_FORMAT_R8G8B8A8_UNORM,			//  VkFormat	colorFormat;
		VK_FORMAT_D24_UNORM_S8_UINT,		//  VkFormat	dsFormat;
	};

	return new BaseTestCase(testCtx, "depth_stencil", "Imageless depth/stencil attachment test", parameters);
}

tcu::TestNode*	imagelessColorResolveTests (tcu::TestContext& testCtx)
{
	TestParameters	parameters	=
	{
		TEST_TYPE_COLOR_RESOLVE,			//  TestType	testType;
		VK_FORMAT_R8G8B8A8_UNORM,			//  VkFormat	colorFormat;
		VK_FORMAT_UNDEFINED,				//  VkFormat	dsFormat;
	};

	return new BaseTestCase(testCtx, "color_resolve", "Imageless color attachment resolve test", parameters);
}

tcu::TestNode*	imagelessDepthStencilResolveTests (tcu::TestContext& testCtx)
{
	TestParameters	parameters	=
	{
		TEST_TYPE_DEPTH_STENCIL_RESOLVE,	//  TestType	testType;
		VK_FORMAT_R8G8B8A8_UNORM,			//  VkFormat	colorFormat;
		VK_FORMAT_D24_UNORM_S8_UINT,		//  VkFormat	dsFormat;
	};

	return new BaseTestCase(testCtx, "depth_stencil_resolve", "Imageless color and depth/stencil attachment resolve test", parameters);
}

tcu::TestNode*	imagelessMultisubpass (tcu::TestContext& testCtx)
{
	TestParameters	parameters	=
	{
		TEST_TYPE_MULTISUBPASS,			//  TestType	testType;
		VK_FORMAT_R8G8B8A8_UNORM,		//  VkFormat	colorFormat;
		VK_FORMAT_UNDEFINED,			//  VkFormat	dsFormat;
	};

	return new BaseTestCase(testCtx, "multisubpass", "Multi-subpass test", parameters);
}

}	// anonymous

tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> imagelessFramebufferGroup (new tcu::TestCaseGroup(testCtx, "imageless_framebuffer", "Imageless Framebuffer tests"));

	imagelessFramebufferGroup->addChild(imagelessColorTests(testCtx));						// Color only test
	imagelessFramebufferGroup->addChild(imagelessDepthStencilTests(testCtx));				// Color and depth/stencil test
	imagelessFramebufferGroup->addChild(imagelessColorResolveTests(testCtx));				// Color and color resolve test
	imagelessFramebufferGroup->addChild(imagelessDepthStencilResolveTests(testCtx));		// Color, depth and depth resolve test (interaction with VK_KHR_depth_stencil_resolve)
	imagelessFramebufferGroup->addChild(imagelessMultisubpass(testCtx));					// Multi-subpass test

	return imagelessFramebufferGroup.release();
}

} // imageless
} // vkt
