/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2019 The Khronos Group Inc.
 * Copyright (c) 2019 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Tests for multiple interpolation decorations in a shader stage
 *//*--------------------------------------------------------------------*/

#include "vktDrawMultipleInterpolationTests.hpp"

#include "tcuStringTemplate.hpp"
#include "vkCmdUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vktDrawBaseClass.hpp"
#include "vktTestGroupUtil.hpp"

namespace vkt
{
namespace Draw
{
namespace
{

enum Interpolation
{
	SMOOTH			= 0,
	FLAT			= 1,
	NOPERSPECTIVE	= 2,
	CENTROID		= 3
};

struct DrawParams
{
	vk::VkFormat				format;
	tcu::UVec2					size;
	vk::VkSampleCountFlagBits	samples;
	// From the SPIR-V point of view, structured test variants will allow us to test interpolation decorations on struct members
	// instead of plain ids.
	bool						useStructure;
};

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

const char* interpolationToString (Interpolation interpolation)
{
	switch (interpolation)
	{
		case SMOOTH:
			return "smooth";
		case FLAT:
			return "flat";
		case NOPERSPECTIVE:
			return "noperspective";
		case CENTROID:
			return "centroid";
		default:
			DE_FATAL("Invalid interpolation enum");
	}

	return "";
}

class DrawTestInstance : public TestInstance
{
public:
					DrawTestInstance	(Context& context, DrawParams params);
	void			render				(std::vector<de::SharedPtr<Image> >& colorTargetImages,
										 tcu::ConstPixelBufferAccess* frames,
										 const char* vsName,
										 const char* fsName);
	bool			compare				(const tcu::ConstPixelBufferAccess& result,
										 const tcu::ConstPixelBufferAccess& reference);
	tcu::TestStatus	iterate				(void);
private:
	DrawParams		m_params;
};

DrawTestInstance::DrawTestInstance (Context& context, DrawParams params)
	: TestInstance	(context)
	, m_params		(params)
{
}

class DrawTestCase : public TestCase
{
public:
							DrawTestCase	(tcu::TestContext&	testCtx,
											 const std::string&	name,
											 const std::string&	description,
											 const DrawParams	params);
							~DrawTestCase	(void);
	virtual void			initPrograms	(vk::SourceCollections& programCollection) const;
	virtual void			checkSupport	(Context& context) const;
	virtual TestInstance*	createInstance	(Context& context) const;
private:
	const DrawParams		m_params;
};

DrawTestCase::DrawTestCase (tcu::TestContext& testCtx,
							const std::string& name,
							const std::string& description,
							const DrawParams params)
	: TestCase	(testCtx, name, description)
	, m_params	(params)
{
}

DrawTestCase::~DrawTestCase (void)
{
}

void DrawTestCase::initPrograms (vk::SourceCollections& programCollection) const
{
	const std::string							blockName		= "ifb";
	const std::map<std::string, std::string>	replacements	=
	{
		std::pair<std::string, std::string>{"blockOpeningOut"	, (m_params.useStructure ? "layout(location = 0) out InterfaceBlock {\n" : "")},
		std::pair<std::string, std::string>{"blockOpeningIn"	, (m_params.useStructure ? "layout(location = 0) in InterfaceBlock {\n" : "")},
		std::pair<std::string, std::string>{"blockClosure"		, (m_params.useStructure ? "} " + blockName + ";\n" : "")},
		std::pair<std::string, std::string>{"extensions"		, (m_params.useStructure ? "#extension GL_ARB_enhanced_layouts : require\n" : "")},
		std::pair<std::string, std::string>{"accessPrefix"		, (m_params.useStructure ? blockName + "." : "")},
		std::pair<std::string, std::string>{"outQual"			, (m_params.useStructure ? "" : "out ")},
		std::pair<std::string, std::string>{"inQual"			, (m_params.useStructure ? "" : "in ")},
		std::pair<std::string, std::string>{"indent"			, (m_params.useStructure ? "    " : "")},
	};

	const tcu::StringTemplate vertShaderMulti
	{
		"#version 430\n"
		"${extensions}"
		"\n"
		"layout(location = 0) in vec4 in_position;\n"
		"layout(location = 1) in vec4 in_color;\n"
		"\n"
		"${blockOpeningOut}"
		"${indent}layout(location = 0) ${outQual}vec4 out_color_smooth;\n"
		"${indent}layout(location = 1) ${outQual}flat vec4 out_color_flat;\n"
		"${indent}layout(location = 2) ${outQual}noperspective vec4 out_color_noperspective;\n"
		"${indent}layout(location = 3) ${outQual}centroid vec4 out_color_centroid;\n"
		"${blockClosure}"
		"\n"
		"void main()\n"
		"{\n"
		"    ${accessPrefix}out_color_smooth = in_color;\n"
		"    ${accessPrefix}out_color_flat = in_color;\n"
		"    ${accessPrefix}out_color_noperspective = in_color;\n"
		"    ${accessPrefix}out_color_centroid = in_color;\n"
		"    gl_Position = in_position;\n"
		"}\n"
	};

	const tcu::StringTemplate fragShaderMulti
	{
		"#version 430\n"
		"${extensions}"
		"\n"
		"${blockOpeningIn}"
		"${indent}layout(location = 0) ${inQual}vec4 in_color_smooth;\n"
		"${indent}layout(location = 1) ${inQual}flat vec4 in_color_flat;\n"
		"${indent}layout(location = 2) ${inQual}noperspective vec4 in_color_noperspective;\n"
		"${indent}layout(location = 3) ${inQual}centroid vec4 in_color_centroid;\n"
		"${blockClosure}"
		"\n"
		"layout(location = " + de::toString(SMOOTH) + ") out vec4 out_color_smooth;\n"
		"layout(location = " + de::toString(FLAT) + ") out vec4 out_color_flat;\n"
		"layout(location = " + de::toString(NOPERSPECTIVE) + ") out vec4 out_color_noperspective;\n"
		"layout(location = " + de::toString(CENTROID) + ") out vec4 out_color_centroid;\n"
		"\n"
		"void main()\n"
		"{\n"
		"    out_color_smooth = ${accessPrefix}in_color_smooth;\n"
		"    out_color_flat = ${accessPrefix}in_color_flat;\n"
		"    out_color_noperspective = ${accessPrefix}in_color_noperspective;\n"
		"    out_color_centroid = ${accessPrefix}in_color_centroid;\n"
		"}\n"
	};

	const tcu::StringTemplate vertShaderSingle
	{
		"#version 430\n"
		"${extensions}"
		"\n"
		"layout(location = 0) in vec4 in_position;\n"
		"layout(location = 1) in vec4 in_color;\n"
		"\n"
		"${blockOpeningOut}"
		"${indent}layout(location = 0) ${outQual}${qualifier:opt}vec4 out_color;\n"
		"${blockClosure}"
		"\n"
		"void main()\n"
		"{\n"
		"    ${accessPrefix}out_color = in_color;\n"
		"    gl_Position = in_position;\n"
		"}\n"
	};

	const tcu::StringTemplate fragShaderSingle
	{
		"#version 430\n"
		"${extensions}"
		"\n"
		"${blockOpeningIn}"
		"${indent}layout(location = 0) ${inQual}${qualifier:opt}vec4 in_color;\n"
		"${blockClosure}"
		"\n"
		"layout(location = 0) out vec4 out_color;\n"
		"\n"
		"void main()\n"
		"{\n"
		"    out_color = ${accessPrefix}in_color;\n"
		"}\n"
	};

	std::map<std::string, std::string>	smooth			= replacements;
	std::map<std::string, std::string>	flat			= replacements;
	std::map<std::string, std::string>	noperspective	= replacements;
	std::map<std::string, std::string>	centroid		= replacements;

	flat["qualifier"]			= "flat ";
	noperspective["qualifier"]	= "noperspective ";
	centroid["qualifier"]		= "centroid ";

	programCollection.glslSources.add("vert_multi")			<< glu::VertexSource(vertShaderMulti.specialize(replacements));
	programCollection.glslSources.add("frag_multi")			<< glu::FragmentSource(fragShaderMulti.specialize(replacements));
	programCollection.glslSources.add("vert_smooth")		<< glu::VertexSource(vertShaderSingle.specialize(smooth));
	programCollection.glslSources.add("frag_smooth")		<< glu::FragmentSource(fragShaderSingle.specialize(smooth));
	programCollection.glslSources.add("vert_flat")			<< glu::VertexSource(vertShaderSingle.specialize(flat));
	programCollection.glslSources.add("frag_flat")			<< glu::FragmentSource(fragShaderSingle.specialize(flat));
	programCollection.glslSources.add("vert_noperspective")	<< glu::VertexSource(vertShaderSingle.specialize(noperspective));
	programCollection.glslSources.add("frag_noperspective")	<< glu::FragmentSource(fragShaderSingle.specialize(noperspective));
	programCollection.glslSources.add("vert_centroid")		<< glu::VertexSource(vertShaderSingle.specialize(centroid));
	programCollection.glslSources.add("frag_centroid")		<< glu::FragmentSource(fragShaderSingle.specialize(centroid));
}

void DrawTestCase::checkSupport (Context& context) const
{
	if (!(m_params.samples & context.getDeviceProperties().limits.framebufferColorSampleCounts))
		throw tcu::NotSupportedError("Multisampling with " + de::toString(m_params.samples) + " samples not supported");
}

TestInstance* DrawTestCase::createInstance (Context& context) const
{
	return new DrawTestInstance(context, m_params);
}

void DrawTestInstance::render (std::vector<de::SharedPtr<Image> >& colorTargetImages,
							   tcu::ConstPixelBufferAccess* frames,
							   const char* vsName,
							   const char* fsName)
{
	const bool												useMultisampling	= (m_params.samples != vk::VK_SAMPLE_COUNT_1_BIT);
	const vk::DeviceInterface&								vk					= m_context.getDeviceInterface();
	const vk::VkDevice										device				= m_context.getDevice();
	const vk::Unique<vk::VkShaderModule>					vs					(createShaderModule(vk, device, m_context.getBinaryCollection().get(vsName), 0));
	const vk::Unique<vk::VkShaderModule>					fs					(createShaderModule(vk, device, m_context.getBinaryCollection().get(fsName), 0));
	const CmdPoolCreateInfo									cmdPoolCreateInfo	= m_context.getUniversalQueueFamilyIndex();
	vk::Move<vk::VkCommandPool>								cmdPool				= createCommandPool(vk, device, &cmdPoolCreateInfo);
	vk::Move<vk::VkCommandBuffer>							cmdBuffer			= vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
	std::vector<de::SharedPtr<Image> >						multisampleImages;
	std::vector<de::SharedPtr<vk::Move<vk::VkImageView> > >	colorTargetViews;
	std::vector<de::SharedPtr<vk::Move<vk::VkImageView> > >	multisampleViews;
	de::SharedPtr<Buffer>									vertexBuffer;
	vk::Move<vk::VkRenderPass>								renderPass;
	vk::Move<vk::VkFramebuffer>								framebuffer;
	vk::Move<vk::VkPipeline>								pipeline;

	// Create color buffer images
	for (deUint32 frameNdx = 0; frameNdx < colorTargetImages.size(); frameNdx++)
	{
		const vk::VkExtent3D		targetImageExtent		= { m_params.size.x(), m_params.size.y(), 1 };
		const vk::VkImageUsageFlags	usage					= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT;
		const ImageCreateInfo		targetImageCreateInfo	(vk::VK_IMAGE_TYPE_2D,
															 m_params.format,
															 targetImageExtent,
															 1,
															 1,
															 vk::VK_SAMPLE_COUNT_1_BIT,
															 vk::VK_IMAGE_TILING_OPTIMAL,
															 usage);

		colorTargetImages[frameNdx] = Image::createAndAlloc(vk, device, targetImageCreateInfo,
															m_context.getDefaultAllocator(),
															m_context.getUniversalQueueFamilyIndex());

		if (useMultisampling)
		{
			const ImageCreateInfo multisampleImageCreateInfo (vk::VK_IMAGE_TYPE_2D,
															  m_params.format,
															  targetImageExtent,
															  1,
															  1,
															  m_params.samples,
															  vk::VK_IMAGE_TILING_OPTIMAL,
															  usage);

			multisampleImages.push_back(Image::createAndAlloc(vk, device, multisampleImageCreateInfo,
															  m_context.getDefaultAllocator(),
															  m_context.getUniversalQueueFamilyIndex()));
		}
	}

	// Create render pass and framebuffer
	{
		RenderPassCreateInfo					renderPassCreateInfo;
		std::vector<vk::VkImageView>			attachments;
		std::vector<vk::VkAttachmentReference>	colorAttachmentRefs;
		std::vector<vk::VkAttachmentReference>	multisampleAttachmentRefs;
		deUint32								attachmentNdx				= 0;

		for (deUint32 frameNdx = 0; frameNdx < colorTargetImages.size(); frameNdx++)
		{
			const ImageViewCreateInfo		colorTargetViewInfo			(colorTargetImages[frameNdx]->object(),
																		 vk::VK_IMAGE_VIEW_TYPE_2D,
																		 m_params.format);

			const vk::VkAttachmentReference	colorAttachmentReference	=
			{
				attachmentNdx++,
				vk::VK_IMAGE_LAYOUT_GENERAL
			};

			colorTargetViews.push_back(makeSharedPtr(createImageView(vk, device, &colorTargetViewInfo)));
			colorAttachmentRefs.push_back(colorAttachmentReference);

			renderPassCreateInfo.addAttachment(AttachmentDescription(m_params.format,
																	 vk::VK_SAMPLE_COUNT_1_BIT,
																	 vk::VK_ATTACHMENT_LOAD_OP_CLEAR,
																	 vk::VK_ATTACHMENT_STORE_OP_STORE,
																	 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
																	 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,
																	 vk::VK_IMAGE_LAYOUT_UNDEFINED,
																	 vk::VK_IMAGE_LAYOUT_GENERAL));

			if (useMultisampling)
			{
				const ImageViewCreateInfo		multisamplingTargetViewInfo		(multisampleImages[frameNdx]->object(),
																				 vk::VK_IMAGE_VIEW_TYPE_2D,
																				 m_params.format);

				const vk::VkAttachmentReference	multiSampleAttachmentReference	=
				{
					attachmentNdx++,
					vk::VK_IMAGE_LAYOUT_GENERAL
				};

				multisampleViews.push_back(makeSharedPtr(createImageView(vk, device, &multisamplingTargetViewInfo)));
				multisampleAttachmentRefs.push_back(multiSampleAttachmentReference);

				renderPassCreateInfo.addAttachment(AttachmentDescription(m_params.format,
																		 m_params.samples,
																		 vk::VK_ATTACHMENT_LOAD_OP_CLEAR,
																		 vk::VK_ATTACHMENT_STORE_OP_STORE,
																		 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
																		 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,
																		 vk::VK_IMAGE_LAYOUT_UNDEFINED,
																		 vk::VK_IMAGE_LAYOUT_GENERAL));
			}
		}

		renderPassCreateInfo.addSubpass(SubpassDescription(vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
														   0,
														   0,
														   DE_NULL,
														   (deUint32)colorAttachmentRefs.size(),
														   useMultisampling ? &multisampleAttachmentRefs[0] : &colorAttachmentRefs[0],
														   useMultisampling ? &colorAttachmentRefs[0] : DE_NULL,
														   AttachmentReference(),
														   0,
														   DE_NULL));

		renderPass = createRenderPass(vk, device, &renderPassCreateInfo);

		for (deUint32 frameNdx = 0; frameNdx < colorTargetViews.size(); frameNdx++)
		{
			attachments.push_back(**colorTargetViews[frameNdx]);

			if (useMultisampling)
				attachments.push_back(**multisampleViews[frameNdx]);
		}

		const vk::VkFramebufferCreateInfo framebufferCreateInfo =
		{
			vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
			DE_NULL,
			0u,
			*renderPass,
			(deUint32)attachments.size(),
			&attachments[0],
			m_params.size.x(),
			m_params.size.y(),
			1
		};

		framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
	}

	// Create vertex buffer.
	{
		const PositionColorVertex	vertices[]		=
		{
			PositionColorVertex(
				tcu::Vec4(-1.5f, -0.4f, 1.0f, 2.0f),	// Coord
				tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)),		// Color

			PositionColorVertex(
				tcu::Vec4(0.4f, -0.4f, 0.5f, 0.5f),		// Coord
				tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)),		// Color

			PositionColorVertex(
				tcu::Vec4(0.3f, 0.8f, 0.0f, 1.0f),		// Coord
				tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f))		// Color
		};

		const vk::VkDeviceSize		dataSize		= DE_LENGTH_OF_ARRAY(vertices) * sizeof(PositionColorVertex);
									vertexBuffer	= Buffer::createAndAlloc(vk,
																			 device,
																			 BufferCreateInfo(dataSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
																			 m_context.getDefaultAllocator(),
																			 vk::MemoryRequirement::HostVisible);
		deUint8*					ptr				= reinterpret_cast<deUint8*>(vertexBuffer->getBoundMemory().getHostPtr());

		deMemcpy(ptr, vertices, static_cast<size_t>(dataSize));
		flushMappedMemoryRange(vk,
							   device,
							   vertexBuffer->getBoundMemory().getMemory(),
							   vertexBuffer->getBoundMemory().getOffset(),
							   VK_WHOLE_SIZE);
	}

	// Create pipeline
	{
		const vk::VkViewport											viewport							= vk::makeViewport(m_params.size.x(), m_params.size.y());
		const vk::VkRect2D												scissor								= vk::makeRect2D(m_params.size.x(), m_params.size.y());
		const PipelineLayoutCreateInfo									pipelineLayoutCreateInfo;
		const vk::Move<vk::VkPipelineLayout>							pipelineLayout						= createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
		PipelineCreateInfo												pipelineCreateInfo					(*pipelineLayout, *renderPass, 0, 0);

		const vk::VkVertexInputBindingDescription						vertexInputBindingDescription		=
		{
			0,
			(deUint32)sizeof(tcu::Vec4) * 2,
			vk::VK_VERTEX_INPUT_RATE_VERTEX
		};

		const vk::VkVertexInputAttributeDescription						vertexInputAttributeDescriptions[2]	=
		{
			{ 0u, 0u, vk::VK_FORMAT_R32G32B32A32_SFLOAT, 0u },
			{ 1u, 0u, vk::VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)(sizeof(float) * 4) }
		};

		std::vector<PipelineCreateInfo::ColorBlendState::Attachment>	vkCbAttachmentStates				(colorTargetImages.size());
		PipelineCreateInfo::VertexInputState							vertexInputState					= PipelineCreateInfo::VertexInputState(1,
																																				   &vertexInputBindingDescription,
																																				   2,
																																				   vertexInputAttributeDescriptions);

		pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
		pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
		pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(vertexInputState));
		pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
		pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState((deUint32)vkCbAttachmentStates.size(), &vkCbAttachmentStates[0]));
		pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1, std::vector<vk::VkViewport>(1, viewport), std::vector<vk::VkRect2D>(1, scissor)));
		pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
		pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
		pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState(m_params.samples));

		pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
	}

	// Queue draw and read results.
	{
		const vk::VkQueue				queue				= m_context.getUniversalQueue();
		const vk::VkRect2D				renderArea			= vk::makeRect2D(m_params.size.x(), m_params.size.y());
		const vk::VkDeviceSize			vertexBufferOffset	= 0;
		const vk::VkBuffer				buffer				= vertexBuffer->object();
		const vk::VkOffset3D			zeroOffset			= { 0, 0, 0 };
		std::vector<vk::VkClearValue>	clearValues;

		for (deUint32 i = 0; i < colorTargetImages.size() + multisampleImages.size(); i++)
			clearValues.push_back(vk::makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));

		beginCommandBuffer(vk, *cmdBuffer, 0u);
		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea, (deUint32)clearValues.size(), &clearValues[0]);
		vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &buffer, &vertexBufferOffset);
		vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
		vk.cmdDraw(*cmdBuffer, 3u, 1u, 0u, 0u);
		endRenderPass(vk, *cmdBuffer);

		endCommandBuffer(vk, *cmdBuffer);
		submitCommandsAndWait(vk, device, queue, cmdBuffer.get());

		for (deUint32 frameNdx = 0; frameNdx < colorTargetImages.size(); frameNdx++)
		{
			frames[frameNdx] = colorTargetImages[frameNdx]->readSurface(queue,
																		m_context.getDefaultAllocator(),
																		vk::VK_IMAGE_LAYOUT_GENERAL,
																		zeroOffset,
																		(int)m_params.size.x(),
																		(int)m_params.size.y(),
																		vk::VK_IMAGE_ASPECT_COLOR_BIT);
		}
	}
}

bool DrawTestInstance::compare (const tcu::ConstPixelBufferAccess& result, const tcu::ConstPixelBufferAccess& reference)
{
	DE_ASSERT(result.getSize() == reference.getSize());

	const size_t	size	= result.getWidth() * result.getHeight() * vk::mapVkFormat(m_params.format).getPixelSize();
	const int		res		= deMemCmp(result.getDataPtr(), reference.getDataPtr(), size);

	return (res == 0);
}

tcu::TestStatus DrawTestInstance::iterate (void)
{
	tcu::TestLog&						log						= m_context.getTestContext().getLog();
	const bool							useMultisampling		= (m_params.samples != vk::VK_SAMPLE_COUNT_1_BIT);
	const deUint32						frameCount				= 4;
	std::vector<de::SharedPtr<Image> >	resImages				(frameCount);
	std::vector<de::SharedPtr<Image> >	smoothImage				(1);
	std::vector<de::SharedPtr<Image> >	flatImage				(1);
	std::vector<de::SharedPtr<Image> >	noperspectiveImage		(1);
	std::vector<de::SharedPtr<Image> >	centroidImage			(1);
	tcu::ConstPixelBufferAccess			resFrames[frameCount];
	tcu::ConstPixelBufferAccess			refFrames[frameCount];

	render(resImages,			resFrames,					"vert_multi",			"frag_multi");
	render(smoothImage,			&refFrames[SMOOTH],			"vert_smooth",			"frag_smooth");
	render(flatImage,			&refFrames[FLAT],			"vert_flat",			"frag_flat");
	render(noperspectiveImage,	&refFrames[NOPERSPECTIVE],	"vert_noperspective",	"frag_noperspective");
	render(centroidImage,		&refFrames[CENTROID],		"vert_centroid",		"frag_centroid");

	for (deUint32 resNdx = 0; resNdx < frameCount; resNdx++)
	{
		const std::string resName = interpolationToString((Interpolation)resNdx);

		log	<< tcu::TestLog::ImageSet(resName, resName)
			<< tcu::TestLog::Image("Result", "Result", resFrames[resNdx])
			<< tcu::TestLog::Image("Reference", "Reference", refFrames[resNdx])
			<< tcu::TestLog::EndImageSet;

		for (deUint32 refNdx = 0; refNdx < frameCount; refNdx++)
		{
			const std::string refName = interpolationToString((Interpolation)refNdx);

			if (resNdx == refNdx)
			{
				if (!compare(resFrames[resNdx], refFrames[refNdx]))
					return tcu::TestStatus::fail(resName + " produced different results");
			}
			else if (!useMultisampling && ((resNdx == SMOOTH && refNdx == CENTROID) || (resNdx == CENTROID && refNdx == SMOOTH)))
			{
				if (!compare(resFrames[resNdx], refFrames[refNdx]))
					return tcu::TestStatus::fail(resName + " and " + refName + " produced different results without multisampling");
			}
			else
			{
				if (compare(resFrames[resNdx], refFrames[refNdx]))
					return tcu::TestStatus::fail(resName + " and " + refName + " produced same result");
			}
		}
	}

	return tcu::TestStatus::pass("Results differ and references match");
}

void createTests (tcu::TestCaseGroup* testGroup)
{
	tcu::TestContext&	testCtx	= testGroup->getTestContext();
	const vk::VkFormat	format	= vk::VK_FORMAT_R8G8B8A8_UNORM;
	const tcu::UVec2	size	(128, 128);

	struct TestVariant
	{
		const std::string				name;
		const std::string				desc;
		const vk::VkSampleCountFlagBits	samples;
	};

	static const std::vector<TestVariant> testVariants =
	{
		{ "1_sample",	"Without multisampling",	vk::VK_SAMPLE_COUNT_1_BIT	},
		{ "2_samples",	"2 samples",				vk::VK_SAMPLE_COUNT_2_BIT	},
		{ "4_samples",	"4 samples",				vk::VK_SAMPLE_COUNT_4_BIT	},
		{ "8_samples",	"8 samples",				vk::VK_SAMPLE_COUNT_8_BIT	},
		{ "16_samples",	"16 samples",				vk::VK_SAMPLE_COUNT_16_BIT	},
		{ "32_samples",	"32 samples",				vk::VK_SAMPLE_COUNT_32_BIT	},
		{ "64_samples",	"64 samples",				vk::VK_SAMPLE_COUNT_64_BIT	},
	};

	struct GroupVariant
	{
		const bool			useStructure;
		const std::string	groupName;
	};

	static const std::vector<GroupVariant> groupVariants =
	{
		{ false,	"separate"		},
		{ true,		"structured"	},
	};

	for (const auto& grpVariant : groupVariants)
	{
		de::MovePtr<tcu::TestCaseGroup> group {new tcu::TestCaseGroup{testCtx, grpVariant.groupName.c_str(), ""}};

		for (const auto& testVariant : testVariants)
		{
			const DrawParams params {format, size, testVariant.samples, grpVariant.useStructure};
			group->addChild(new DrawTestCase(testCtx, testVariant.name, testVariant.desc, params));
		}

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

}	// anonymous

tcu::TestCaseGroup* createMultipleInterpolationTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx,
						   "multiple_interpolation",
						   "Tests for multiple interpolation decorations in a shader stage.",
						   createTests);
}

}	// Draw
}	// vkt
