/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 The Khronos Group Inc.
 * Copyright (c) 2015 Imagination Technologies Ltd.
 * Copyright (c) 2017 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 Multisample Tests
 *//*--------------------------------------------------------------------*/

#include "vktPipelineMultisampleTests.hpp"
#include "vktPipelineMultisampleImageTests.hpp"
#include "vktPipelineMultisampleSampleLocationsExtTests.hpp"
#include "vktPipelineClearUtil.hpp"
#include "vktPipelineImageUtil.hpp"
#include "vktPipelineVertexUtil.hpp"
#include "vktPipelineReferenceRenderer.hpp"
#include "vktTestCase.hpp"
#include "vktTestCaseUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkPrograms.hpp"
#include "vkQueryUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkObjUtil.hpp"
#include "tcuImageCompare.hpp"
#include "tcuTestLog.hpp"
#include "deUniquePtr.hpp"
#include "deSharedPtr.hpp"
#include "deStringUtil.hpp"
#include "deMemory.h"

#include <sstream>
#include <vector>
#include <map>

namespace vkt
{
namespace pipeline
{

using namespace vk;

namespace
{
enum GeometryType
{
	GEOMETRY_TYPE_OPAQUE_TRIANGLE,
	GEOMETRY_TYPE_OPAQUE_LINE,
	GEOMETRY_TYPE_OPAQUE_POINT,
	GEOMETRY_TYPE_OPAQUE_QUAD,
	GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH,	//!< placed at z = 0.5
	GEOMETRY_TYPE_TRANSLUCENT_QUAD,
	GEOMETRY_TYPE_INVISIBLE_TRIANGLE,
	GEOMETRY_TYPE_INVISIBLE_QUAD,
	GEOMETRY_TYPE_GRADIENT_QUAD
};

enum TestModeBits
{
	TEST_MODE_DEPTH_BIT		= 1u,
	TEST_MODE_STENCIL_BIT	= 2u,
};
typedef deUint32 TestModeFlags;

enum RenderType
{
	// resolve multisample rendering to single sampled image
	RENDER_TYPE_RESOLVE				= 0u,

	// copy samples to an array of single sampled images
	RENDER_TYPE_COPY_SAMPLES		= 1u,

	// render first with only depth/stencil and then with color + depth/stencil
	RENDER_TYPE_DEPTHSTENCIL_ONLY	= 2u,

	// render using color attachment at location 1 and location 0 set as unused
	RENDER_TYPE_UNUSED_ATTACHMENT	= 3u
};

enum ImageBackingMode
{
	IMAGE_BACKING_MODE_REGULAR	= 0u,
	IMAGE_BACKING_MODE_SPARSE
};

struct MultisampleTestParams
{
	GeometryType		geometryType;
	float				pointSize;
	ImageBackingMode	backingMode;
};

void checkLargePointsSupport (Context& context, VkPrimitiveTopology topology, float pointSize)
{
	if (topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST && pointSize > 1.0f && !context.getDeviceFeatures().largePoints)
		TCU_THROW(NotSupportedError, "Large points feature not supported.");
}

void									initMultisamplePrograms				(SourceCollections& sources, MultisampleTestParams params);
bool									isSupportedSampleCount				(const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples);
bool									isSupportedDepthStencilFormat		(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format);
VkPipelineColorBlendAttachmentState		getDefaultColorBlendAttachmentState	(void);
deUint32								getUniqueColorsCount				(const tcu::ConstPixelBufferAccess& image);
VkImageAspectFlags						getImageAspectFlags					(const VkFormat format);
VkPrimitiveTopology						getPrimitiveTopology				(const GeometryType geometryType);
std::vector<Vertex4RGBA>				generateVertices					(const GeometryType geometryType);
VkFormat								findSupportedDepthStencilFormat		(Context& context, const bool useDepth, const bool useStencil);

class MultisampleTest : public vkt::TestCase
{
public:

												MultisampleTest						(tcu::TestContext&								testContext,
																					 const std::string&								name,
																					 const std::string&								description,
																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																					 const VkPipelineColorBlendAttachmentState&		blendState,
																					 GeometryType									geometryType,
																					 float											pointSize,
																					 ImageBackingMode								backingMode);
	virtual										~MultisampleTest					(void) {}

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

protected:
	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
																					 VkPrimitiveTopology							topology,
																					 float											pointSize,
																					 const std::vector<Vertex4RGBA>&				vertices,
																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const = 0;
	VkPipelineMultisampleStateCreateInfo		m_multisampleStateParams;
	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
	const GeometryType							m_geometryType;
	const float									m_pointSize;
	const ImageBackingMode						m_backingMode;
	std::vector<VkSampleMask>					m_sampleMask;
};

class RasterizationSamplesTest : public MultisampleTest
{
public:
												RasterizationSamplesTest			(tcu::TestContext&		testContext,
																					 const std::string&		name,
																					 const std::string&		description,
																					 VkSampleCountFlagBits	rasterizationSamples,
																					 GeometryType			geometryType,
																					 float					pointSize,
																					 ImageBackingMode		backingMode,
																					 TestModeFlags			modeFlags				= 0u);
	virtual										~RasterizationSamplesTest			(void) {}

protected:
	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
																					 VkPrimitiveTopology							topology,
																					 float											pointSize,
																					 const std::vector<Vertex4RGBA>&				vertices,
																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;

	static VkPipelineMultisampleStateCreateInfo	getRasterizationSamplesStateParams	(VkSampleCountFlagBits rasterizationSamples);

	const ImageBackingMode						m_backingMode;
	const TestModeFlags							m_modeFlags;
};

class MinSampleShadingTest : public MultisampleTest
{
public:
												MinSampleShadingTest				(tcu::TestContext&		testContext,
																					 const std::string&		name,
																					 const std::string&		description,
																					 VkSampleCountFlagBits	rasterizationSamples,
																					 float					minSampleShading,
																					 GeometryType			geometryType,
																					 float					pointSize,
																					 ImageBackingMode		backingMode);
	virtual										~MinSampleShadingTest				(void) {}

protected:
	virtual void								initPrograms						(SourceCollections& programCollection) const;
	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
																					 VkPrimitiveTopology							topology,
																					 float											pointSize,
																					 const std::vector<Vertex4RGBA>&				vertices,
																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;

	static VkPipelineMultisampleStateCreateInfo	getMinSampleShadingStateParams		(VkSampleCountFlagBits rasterizationSamples, float minSampleShading);

	const float									m_pointSize;
	const ImageBackingMode						m_backingMode;
};

class SampleMaskTest : public MultisampleTest
{
public:
												SampleMaskTest						(tcu::TestContext&					testContext,
																					 const std::string&					name,
																					 const std::string&					description,
																					 VkSampleCountFlagBits				rasterizationSamples,
																					 const std::vector<VkSampleMask>&	sampleMask,
																					 GeometryType						geometryType,
																					 float								pointSize,
																					 ImageBackingMode					backingMode);

	virtual										~SampleMaskTest						(void) {}

protected:
	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
																					 VkPrimitiveTopology							topology,
																					 float											pointSize,
																					 const std::vector<Vertex4RGBA>&				vertices,
																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;

	static VkPipelineMultisampleStateCreateInfo	getSampleMaskStateParams			(VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask);

	const ImageBackingMode						m_backingMode;
};

class AlphaToOneTest : public MultisampleTest
{
public:
												AlphaToOneTest					(tcu::TestContext&					testContext,
																				 const std::string&					name,
																				 const std::string&					description,
																				 VkSampleCountFlagBits				rasterizationSamples,
																				 ImageBackingMode					backingMode);

	virtual										~AlphaToOneTest					(void) {}

protected:
	virtual TestInstance*						createMultisampleTestInstance	(Context&										context,
																				 VkPrimitiveTopology							topology,
																				 float											pointSize,
																				 const std::vector<Vertex4RGBA>&				vertices,
																				 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																				 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;

	static VkPipelineMultisampleStateCreateInfo	getAlphaToOneStateParams		(VkSampleCountFlagBits rasterizationSamples);
	static VkPipelineColorBlendAttachmentState	getAlphaToOneBlendState			(void);

	const ImageBackingMode						m_backingMode;
};

class AlphaToCoverageTest : public MultisampleTest
{
public:
												AlphaToCoverageTest				(tcu::TestContext&		testContext,
																				 const std::string&		name,
																				 const std::string&		description,
																				 VkSampleCountFlagBits	rasterizationSamples,
																				 GeometryType			geometryType,
																				 ImageBackingMode		backingMode);

	virtual										~AlphaToCoverageTest			(void) {}

protected:
	virtual TestInstance*						createMultisampleTestInstance	(Context&										context,
																				 VkPrimitiveTopology							topology,
																				 float											pointSize,
																				 const std::vector<Vertex4RGBA>&				vertices,
																				 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																				 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;

	static VkPipelineMultisampleStateCreateInfo	getAlphaToCoverageStateParams	(VkSampleCountFlagBits rasterizationSamples);

	GeometryType								m_geometryType;
	const ImageBackingMode						m_backingMode;
};

class AlphaToCoverageNoColorAttachmentTest : public MultisampleTest
{
public:
												AlphaToCoverageNoColorAttachmentTest	(tcu::TestContext&		testContext,
																						 const std::string&		name,
																						 const std::string&		description,
																						 VkSampleCountFlagBits	rasterizationSamples,
																						 GeometryType			geometryType,
																						 ImageBackingMode		backingMode);

	virtual										~AlphaToCoverageNoColorAttachmentTest	(void) {}

protected:
	virtual TestInstance*						createMultisampleTestInstance			(Context&										context,
																						 VkPrimitiveTopology							topology,
																						 float											pointSize,
																						 const std::vector<Vertex4RGBA>&				vertices,
																						 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																						 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;

	static VkPipelineMultisampleStateCreateInfo	getStateParams							(VkSampleCountFlagBits rasterizationSamples);

	GeometryType								m_geometryType;
	const ImageBackingMode						m_backingMode;
};

class AlphaToCoverageColorUnusedAttachmentTest : public MultisampleTest
{
public:
												AlphaToCoverageColorUnusedAttachmentTest	(tcu::TestContext&		testContext,
																							 const std::string&		name,
																							 const std::string&		description,
																							 VkSampleCountFlagBits	rasterizationSamples,
																							 GeometryType			geometryType,
																							 ImageBackingMode		backingMode);

	virtual										~AlphaToCoverageColorUnusedAttachmentTest	(void) {}

protected:
	virtual void								initPrograms								(SourceCollections& programCollection) const;

	virtual TestInstance*						createMultisampleTestInstance				(Context&										context,
																							 VkPrimitiveTopology							topology,
																							 float											pointSize,
																							 const std::vector<Vertex4RGBA>&				vertices,
																							 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																							 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;

	static VkPipelineMultisampleStateCreateInfo	getStateParams								(VkSampleCountFlagBits rasterizationSamples);

	GeometryType								m_geometryType;
	const ImageBackingMode						m_backingMode;
};

class SampleMaskWithDepthTestTest : public vkt::TestCase
{
public:
												SampleMaskWithDepthTestTest		(tcu::TestContext&				testContext,
																				 const std::string&				name,
																				 const std::string&				description,
																				 const VkSampleCountFlagBits	rasterizationSamples,
																				 const bool						enablePostDepthCoverage		= false);

												~SampleMaskWithDepthTestTest	(void) {}

	void										initPrograms					(SourceCollections&		programCollection)	const;
	TestInstance*								createInstance					(Context&				context)			const;
private:
	const VkSampleCountFlagBits					m_rasterizationSamples;
	const bool									m_enablePostDepthCoverage;
};

typedef de::SharedPtr<Unique<VkPipeline> > VkPipelineSp;

class MultisampleRenderer
{
public:
												MultisampleRenderer			(Context&										context,
																			 const VkFormat									colorFormat,
																			 const tcu::IVec2&								renderSize,
																			 const VkPrimitiveTopology						topology,
																			 const std::vector<Vertex4RGBA>&				vertices,
																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																			 const VkPipelineColorBlendAttachmentState&		blendState,
																			 const RenderType								renderType,
																			 const ImageBackingMode							backingMode);

												MultisampleRenderer			(Context&										context,
																			 const VkFormat									colorFormat,
																			 const VkFormat									depthStencilFormat,
																			 const tcu::IVec2&								renderSize,
																			 const bool										useDepth,
																			 const bool										useStencil,
																			 const deUint32									numTopologies,
																			 const VkPrimitiveTopology*						pTopology,
																			 const std::vector<Vertex4RGBA>*				pVertices,
																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																			 const VkPipelineColorBlendAttachmentState&		blendState,
																			 const RenderType								renderType,
																			 const ImageBackingMode							backingMode,
																			 const float									depthClearValue			= 1.0f);

	virtual										~MultisampleRenderer		(void);

	de::MovePtr<tcu::TextureLevel>				render						(void);
	de::MovePtr<tcu::TextureLevel>				getSingleSampledImage		(deUint32 sampleId);

protected:
	void										initialize					(Context&										context,
																			 const deUint32									numTopologies,
																			 const VkPrimitiveTopology*						pTopology,
																			 const std::vector<Vertex4RGBA>*				pVertices);

	Context&									m_context;

	const Unique<VkSemaphore>					m_bindSemaphore;

	const VkFormat								m_colorFormat;
	const VkFormat								m_depthStencilFormat;
	tcu::IVec2									m_renderSize;
	const bool									m_useDepth;
	const bool									m_useStencil;

	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
	const VkPipelineColorBlendAttachmentState	m_colorBlendState;

	const RenderType							m_renderType;

	Move<VkImage>								m_colorImage;
	de::MovePtr<Allocation>						m_colorImageAlloc;
	Move<VkImageView>							m_colorAttachmentView;

	Move<VkImage>								m_resolveImage;
	de::MovePtr<Allocation>						m_resolveImageAlloc;
	Move<VkImageView>							m_resolveAttachmentView;

	struct PerSampleImage
	{
		Move<VkImage>								m_image;
		de::MovePtr<Allocation>						m_imageAlloc;
		Move<VkImageView>							m_attachmentView;
	};
	std::vector<de::SharedPtr<PerSampleImage> >	m_perSampleImages;

	Move<VkImage>								m_depthStencilImage;
	de::MovePtr<Allocation>						m_depthStencilImageAlloc;
	Move<VkImageView>							m_depthStencilAttachmentView;

	Move<VkRenderPass>							m_renderPass;
	Move<VkFramebuffer>							m_framebuffer;

	Move<VkShaderModule>						m_vertexShaderModule;
	Move<VkShaderModule>						m_fragmentShaderModule;

	Move<VkShaderModule>						m_copySampleVertexShaderModule;
	Move<VkShaderModule>						m_copySampleFragmentShaderModule;

	Move<VkBuffer>								m_vertexBuffer;
	de::MovePtr<Allocation>						m_vertexBufferAlloc;

	Move<VkPipelineLayout>						m_pipelineLayout;
	std::vector<VkPipelineSp>					m_graphicsPipelines;

	Move<VkDescriptorSetLayout>					m_copySampleDesciptorLayout;
	Move<VkDescriptorPool>						m_copySampleDesciptorPool;
	Move<VkDescriptorSet>						m_copySampleDesciptorSet;

	Move<VkPipelineLayout>						m_copySamplePipelineLayout;
	std::vector<VkPipelineSp>					m_copySamplePipelines;

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

	std::vector<de::SharedPtr<Allocation> >		m_allocations;

	ImageBackingMode							m_backingMode;
	const float									m_depthClearValue;
};

class RasterizationSamplesInstance : public vkt::TestInstance
{
public:
										RasterizationSamplesInstance	(Context&										context,
																		 VkPrimitiveTopology							topology,
																		 float											pointSize,
																		 const std::vector<Vertex4RGBA>&				vertices,
																		 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																		 const VkPipelineColorBlendAttachmentState&		blendState,
																		 const TestModeFlags							modeFlags,
																		 ImageBackingMode								backingMode);
	virtual								~RasterizationSamplesInstance	(void) {}

	virtual tcu::TestStatus				iterate							(void);

protected:
	virtual tcu::TestStatus				verifyImage						(const tcu::ConstPixelBufferAccess& result);

	const VkFormat						m_colorFormat;
	const tcu::IVec2					m_renderSize;
	const VkPrimitiveTopology			m_primitiveTopology;
	const float							m_pointSize;
	const std::vector<Vertex4RGBA>		m_vertices;
	const std::vector<Vertex4RGBA>		m_fullQuadVertices;			//!< used by depth/stencil case
	const TestModeFlags					m_modeFlags;
	de::MovePtr<MultisampleRenderer>	m_multisampleRenderer;
};

class MinSampleShadingInstance : public vkt::TestInstance
{
public:
												MinSampleShadingInstance	(Context&										context,
																			 VkPrimitiveTopology							topology,
																			 float											pointSize,
																			 const std::vector<Vertex4RGBA>&				vertices,
																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																			 const VkPipelineColorBlendAttachmentState&		blendState,
																			 ImageBackingMode								backingMode);
	virtual										~MinSampleShadingInstance	(void) {}

	virtual tcu::TestStatus						iterate						(void);

protected:
	virtual tcu::TestStatus						verifySampleShadedImage		(const std::vector<tcu::TextureLevel>& testShadingImages,
																			 const tcu::ConstPixelBufferAccess& noSampleshadingImage);

	const VkFormat								m_colorFormat;
	const tcu::IVec2							m_renderSize;
	const VkPrimitiveTopology					m_primitiveTopology;
	const std::vector<Vertex4RGBA>				m_vertices;
	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
	const ImageBackingMode						m_backingMode;
};

class SampleMaskInstance : public vkt::TestInstance
{
public:
												SampleMaskInstance			(Context&										context,
																			 VkPrimitiveTopology							topology,
																			 float											pointSize,
																			 const std::vector<Vertex4RGBA>&				vertices,
																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																			 const VkPipelineColorBlendAttachmentState&		blendState,
																			 ImageBackingMode								backingMode);
	virtual										~SampleMaskInstance			(void) {}

	virtual tcu::TestStatus						iterate						(void);

protected:
	virtual tcu::TestStatus						verifyImage					(const tcu::ConstPixelBufferAccess& testShadingImage,
																			 const tcu::ConstPixelBufferAccess& minShadingImage,
																			 const tcu::ConstPixelBufferAccess& maxShadingImage);
	const VkFormat								m_colorFormat;
	const tcu::IVec2							m_renderSize;
	const VkPrimitiveTopology					m_primitiveTopology;
	const std::vector<Vertex4RGBA>				m_vertices;
	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
	const ImageBackingMode						m_backingMode;
};

class AlphaToOneInstance : public vkt::TestInstance
{
public:
												AlphaToOneInstance			(Context&										context,
																			 VkPrimitiveTopology							topology,
																			 const std::vector<Vertex4RGBA>&				vertices,
																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																			 const VkPipelineColorBlendAttachmentState&		blendState,
																			 ImageBackingMode								backingMode);
	virtual										~AlphaToOneInstance			(void) {}

	virtual tcu::TestStatus						iterate						(void);

protected:
	virtual tcu::TestStatus						verifyImage					(const tcu::ConstPixelBufferAccess& alphaOneImage,
																			 const tcu::ConstPixelBufferAccess& noAlphaOneImage);
	const VkFormat								m_colorFormat;
	const tcu::IVec2							m_renderSize;
	const VkPrimitiveTopology					m_primitiveTopology;
	const std::vector<Vertex4RGBA>				m_vertices;
	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
	const ImageBackingMode						m_backingMode;
};

class AlphaToCoverageInstance : public vkt::TestInstance
{
public:
												AlphaToCoverageInstance		(Context&										context,
																			 VkPrimitiveTopology							topology,
																			 const std::vector<Vertex4RGBA>&				vertices,
																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																			 const VkPipelineColorBlendAttachmentState&		blendState,
																			 GeometryType									geometryType,
																			 ImageBackingMode								backingMode);
	virtual										~AlphaToCoverageInstance	(void) {}

	virtual tcu::TestStatus						iterate						(void);

protected:
	virtual tcu::TestStatus						verifyImage					(const tcu::ConstPixelBufferAccess& result);
	const VkFormat								m_colorFormat;
	const tcu::IVec2							m_renderSize;
	const VkPrimitiveTopology					m_primitiveTopology;
	const std::vector<Vertex4RGBA>				m_vertices;
	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
	const GeometryType							m_geometryType;
	const ImageBackingMode						m_backingMode;
};

class AlphaToCoverageNoColorAttachmentInstance : public vkt::TestInstance
{
public:
												AlphaToCoverageNoColorAttachmentInstance	(Context&										context,
																							 VkPrimitiveTopology							topology,
																							 const std::vector<Vertex4RGBA>&				vertices,
																							 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																							 const VkPipelineColorBlendAttachmentState&		blendState,
																							 GeometryType									geometryType,
																							 ImageBackingMode								backingMode);
	virtual										~AlphaToCoverageNoColorAttachmentInstance	(void) {}

	virtual tcu::TestStatus						iterate										(void);

protected:
	virtual tcu::TestStatus						verifyImage									(const tcu::ConstPixelBufferAccess& result);
	const VkFormat								m_colorFormat;
	const VkFormat								m_depthStencilFormat;
	const tcu::IVec2							m_renderSize;
	const VkPrimitiveTopology					m_primitiveTopology;
	const std::vector<Vertex4RGBA>				m_vertices;
	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
	const GeometryType							m_geometryType;
	const ImageBackingMode						m_backingMode;
};

class AlphaToCoverageColorUnusedAttachmentInstance : public vkt::TestInstance
{
public:
												AlphaToCoverageColorUnusedAttachmentInstance	(Context&										context,
																								 VkPrimitiveTopology							topology,
																								 const std::vector<Vertex4RGBA>&				vertices,
																								 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																								 const VkPipelineColorBlendAttachmentState&		blendState,
																								 GeometryType									geometryType,
																								 ImageBackingMode								backingMode);
	virtual										~AlphaToCoverageColorUnusedAttachmentInstance	(void) {}

	virtual tcu::TestStatus						iterate											(void);

protected:
	virtual tcu::TestStatus						verifyImage										(const tcu::ConstPixelBufferAccess& result);
	const VkFormat								m_colorFormat;
	const tcu::IVec2							m_renderSize;
	const VkPrimitiveTopology					m_primitiveTopology;
	const std::vector<Vertex4RGBA>				m_vertices;
	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
	const GeometryType							m_geometryType;
	const ImageBackingMode						m_backingMode;
};

class SampleMaskWithDepthTestInstance : public vkt::TestInstance
{
public:
													SampleMaskWithDepthTestInstance		(Context&							context,
																						 const VkSampleCountFlagBits		rasterizationSamples,
																						 const bool							enablePostDepthCoverage);
													~SampleMaskWithDepthTestInstance	(void) {}

	tcu::TestStatus									iterate								(void);

protected:
	VkPipelineMultisampleStateCreateInfo			getMultisampleState					(const VkSampleCountFlagBits		rasterizationSamples);
	std::vector<Vertex4RGBA>						generateVertices					(void);
	tcu::TestStatus									verifyImage							(const tcu::ConstPixelBufferAccess&	result);

	struct SampleCoverage
	{
		SampleCoverage() {};
		SampleCoverage(deUint32 min_, deUint32 max_)
			: min(min_), max(max_) {};

		deUint32	min;
		deUint32	max;
	};

	const VkSampleCountFlagBits						m_rasterizationSamples;
	const bool										m_enablePostDepthCoverage;
	const VkFormat									m_colorFormat;
	const VkFormat									m_depthStencilFormat;
	const tcu::IVec2								m_renderSize;
	const bool										m_useDepth;
	const bool										m_useStencil;
	const VkPrimitiveTopology						m_topology;
	const tcu::Vec4									m_renderColor;
	const std::vector<Vertex4RGBA>					m_vertices;
	const VkPipelineMultisampleStateCreateInfo		m_multisampleStateParams;
	const VkPipelineColorBlendAttachmentState		m_blendState;
	const RenderType								m_renderType;
	const ImageBackingMode							m_imageBackingMode;
	const float										m_depthClearValue;
	std::map<VkSampleCountFlagBits, SampleCoverage>	m_refCoverageAfterDepthTest;
};


// Helper functions

void initMultisamplePrograms (SourceCollections& sources, MultisampleTestParams params)
{
	const std::string	pointSize		= params.geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? (std::string("	gl_PointSize = ") + de::toString(params.pointSize) + ".0f;\n") : std::string("");
	std::ostringstream	vertexSource;

	vertexSource <<
		"#version 310 es\n"
		"layout(location = 0) in vec4 position;\n"
		"layout(location = 1) in vec4 color;\n"
		"layout(location = 0) out highp vec4 vtxColor;\n"
		"void main (void)\n"
		"{\n"
		"	gl_Position = position;\n"
		"	vtxColor = color;\n"
		<< pointSize
		<< "}\n";

	static const char* fragmentSource =
		"#version 310 es\n"
		"layout(location = 0) in highp vec4 vtxColor;\n"
		"layout(location = 0) out highp vec4 fragColor;\n"
		"void main (void)\n"
		"{\n"
		"	fragColor = vtxColor;\n"
		"}\n";

	sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
	sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
}

void initSampleShadingPrograms (SourceCollections& sources, MultisampleTestParams params)
{
	{
		const std::string	pointSize		= params.geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? (std::string("	gl_PointSize = ") + de::toString(params.pointSize) + ".0f;\n") : std::string("");
		std::ostringstream	vertexSource;

		vertexSource <<
			"#version 440\n"
			"layout(location = 0) in vec4 position;\n"
			"layout(location = 1) in vec4 color;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = position;\n"
			<< pointSize
			<< "}\n";

		static const char* fragmentSource =
			"#version 440\n"
			"layout(location = 0) out highp vec4 fragColor;\n"
			"void main (void)\n"
			"{\n"
			"	fragColor = vec4(fract(gl_FragCoord.xy), 0.0, 1.0);\n"
			"}\n";

		sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
		sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
	}

	{
		static const char*  vertexSource =
			"#version 440\n"
			"void main (void)\n"
			"{\n"
			"	const vec4 positions[4] = vec4[4](\n"
			"		vec4(-1.0, -1.0, 0.0, 1.0),\n"
			"		vec4(-1.0,  1.0, 0.0, 1.0),\n"
			"		vec4( 1.0, -1.0, 0.0, 1.0),\n"
			"		vec4( 1.0,  1.0, 0.0, 1.0)\n"
			"	);\n"
			"	gl_Position = positions[gl_VertexIndex];\n"
			"}\n";

		static const char* fragmentSource =
			"#version 440\n"
			"precision highp float;\n"
			"layout(location = 0) out highp vec4 fragColor;\n"
			"layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInputMS imageMS;\n"
			"layout(push_constant) uniform PushConstantsBlock\n"
			"{\n"
			"	int sampleId;\n"
			"} pushConstants;\n"
			"void main (void)\n"
			"{\n"
			"	fragColor = subpassLoad(imageMS, pushConstants.sampleId);\n"
			"}\n";

		sources.glslSources.add("quad_vert") << glu::VertexSource(vertexSource);
		sources.glslSources.add("copy_sample_frag") << glu::FragmentSource(fragmentSource);
	}
}

void initAlphaToCoverageColorUnusedAttachmentPrograms (SourceCollections& sources)
{
	std::ostringstream vertexSource;

	vertexSource <<
		"#version 310 es\n"
		"layout(location = 0) in vec4 position;\n"
		"layout(location = 1) in vec4 color;\n"
		"layout(location = 0) out highp vec4 vtxColor;\n"
		"void main (void)\n"
		"{\n"
		"	gl_Position = position;\n"
		"	vtxColor = color;\n"
		"}\n";

	// Location 0 is unused, but the alpha for coverage is written there. Location 1 has no alpha channel.
	static const char* fragmentSource =
		"#version 310 es\n"
		"layout(location = 0) in highp vec4 vtxColor;\n"
		"layout(location = 0) out highp vec4 fragColor0;\n"
		"layout(location = 1) out highp vec3 fragColor1;\n"
		"void main (void)\n"
		"{\n"
		"	fragColor0 = vtxColor;\n"
		"	fragColor1 = vtxColor.rgb;\n"
		"}\n";

	sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
	sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
}

bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples)
{
	VkPhysicalDeviceProperties deviceProperties;

	instanceInterface.getPhysicalDeviceProperties(physicalDevice, &deviceProperties);

	return !!(deviceProperties.limits.framebufferColorSampleCounts & rasterizationSamples);
}

VkPipelineColorBlendAttachmentState getDefaultColorBlendAttachmentState (void)
{
	const VkPipelineColorBlendAttachmentState colorBlendState =
	{
		false,														// VkBool32					blendEnable;
		VK_BLEND_FACTOR_ONE,										// VkBlendFactor			srcColorBlendFactor;
		VK_BLEND_FACTOR_ZERO,										// VkBlendFactor			dstColorBlendFactor;
		VK_BLEND_OP_ADD,											// VkBlendOp				colorBlendOp;
		VK_BLEND_FACTOR_ONE,										// VkBlendFactor			srcAlphaBlendFactor;
		VK_BLEND_FACTOR_ZERO,										// VkBlendFactor			dstAlphaBlendFactor;
		VK_BLEND_OP_ADD,											// VkBlendOp				alphaBlendOp;
		VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |		// VkColorComponentFlags	colorWriteMask;
			VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
	};

	return colorBlendState;
}

deUint32 getUniqueColorsCount (const tcu::ConstPixelBufferAccess& image)
{
	DE_ASSERT(image.getFormat().getPixelSize() == 4);

	std::map<deUint32, deUint32>	histogram; // map<pixel value, number of occurrences>
	const deUint32					pixelCount	= image.getWidth() * image.getHeight() * image.getDepth();

	for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++)
	{
		const deUint32 pixelValue = *((const deUint32*)image.getDataPtr() + pixelNdx);

		if (histogram.find(pixelValue) != histogram.end())
			histogram[pixelValue]++;
		else
			histogram[pixelValue] = 1;
	}

	return (deUint32)histogram.size();
}

VkImageAspectFlags getImageAspectFlags (const VkFormat format)
{
	const tcu::TextureFormat tcuFormat = mapVkFormat(format);

	if      (tcuFormat.order == tcu::TextureFormat::DS)		return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
	else if (tcuFormat.order == tcu::TextureFormat::D)		return VK_IMAGE_ASPECT_DEPTH_BIT;
	else if (tcuFormat.order == tcu::TextureFormat::S)		return VK_IMAGE_ASPECT_STENCIL_BIT;

	DE_ASSERT(false);
	return 0u;
}

std::vector<Vertex4RGBA> generateVertices (const GeometryType geometryType)
{
	std::vector<Vertex4RGBA> vertices;

	switch (geometryType)
	{
		case GEOMETRY_TYPE_OPAQUE_TRIANGLE:
		case GEOMETRY_TYPE_INVISIBLE_TRIANGLE:
		{
			Vertex4RGBA vertexData[3] =
			{
				{
					tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f),
					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
				},
				{
					tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f),
					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
				},
				{
					tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f),
					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
				}
			};

			if (geometryType == GEOMETRY_TYPE_INVISIBLE_TRIANGLE)
			{
				for (int i = 0; i < 3; i++)
					vertexData[i].color = tcu::Vec4();
			}

			vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 3);
			break;
		}

		case GEOMETRY_TYPE_OPAQUE_LINE:
		{
			const Vertex4RGBA vertexData[2] =
			{
				{
					tcu::Vec4(-0.75f, 0.25f, 0.0f, 1.0f),
					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
				},
				{
					tcu::Vec4(0.75f, -0.25f, 0.0f, 1.0f),
					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
				}
			};

			vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 2);
			break;
		}

		case GEOMETRY_TYPE_OPAQUE_POINT:
		{
			const Vertex4RGBA vertex =
			{
				tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
				tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
			};

			vertices = std::vector<Vertex4RGBA>(1, vertex);
			break;
		}

		case GEOMETRY_TYPE_OPAQUE_QUAD:
		case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH:
		case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
		case GEOMETRY_TYPE_INVISIBLE_QUAD:
		case GEOMETRY_TYPE_GRADIENT_QUAD:
		{
			Vertex4RGBA vertexData[4] =
			{
				{
					tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
				},
				{
					tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f),
					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
				},
				{
					tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f),
					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
				},
				{
					tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
				}
			};

			if (geometryType == GEOMETRY_TYPE_TRANSLUCENT_QUAD)
			{
				for (int i = 0; i < 4; i++)
					vertexData[i].color.w() = 0.25f;
			}
			else if (geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD)
			{
				for (int i = 0; i < 4; i++)
					vertexData[i].color.w() = 0.0f;
			}
			else if (geometryType == GEOMETRY_TYPE_GRADIENT_QUAD)
			{
				vertexData[0].color.w() = 0.0f;
				vertexData[2].color.w() = 0.0f;
			}
			else if (geometryType == GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH)
			{
				for (int i = 0; i < 4; i++)
					vertexData[i].position.z() = 0.5f;
			}

			vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 4);
			break;
		}

		default:
			DE_ASSERT(false);
	}
	return vertices;
}

VkPrimitiveTopology getPrimitiveTopology (const GeometryType geometryType)
{
	switch (geometryType)
	{
		case GEOMETRY_TYPE_OPAQUE_TRIANGLE:
		case GEOMETRY_TYPE_INVISIBLE_TRIANGLE:			return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;

		case GEOMETRY_TYPE_OPAQUE_LINE:					return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
		case GEOMETRY_TYPE_OPAQUE_POINT:				return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;

		case GEOMETRY_TYPE_OPAQUE_QUAD:
		case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH:
		case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
		case GEOMETRY_TYPE_INVISIBLE_QUAD:
		case GEOMETRY_TYPE_GRADIENT_QUAD:				return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;

		default:
			DE_ASSERT(false);
			return VK_PRIMITIVE_TOPOLOGY_LAST;
	}
}

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

VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil)
{
	if (useDepth && !useStencil)
		return VK_FORMAT_D16_UNORM;		// must be supported

	const InstanceInterface&	vki			= context.getInstanceInterface();
	const VkPhysicalDevice		physDevice	= context.getPhysicalDevice();

	// One of these formats must be supported.

	if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
		return VK_FORMAT_D24_UNORM_S8_UINT;

	if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D32_SFLOAT_S8_UINT))
		return VK_FORMAT_D32_SFLOAT_S8_UINT;

	return VK_FORMAT_UNDEFINED;
}


// MultisampleTest

MultisampleTest::MultisampleTest (tcu::TestContext&								testContext,
								  const std::string&							name,
								  const std::string&							description,
								  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
								  const VkPipelineColorBlendAttachmentState&	blendState,
								  GeometryType									geometryType,
								  float											pointSize,
								  ImageBackingMode								backingMode)
	: vkt::TestCase				(testContext, name, description)
	, m_multisampleStateParams	(multisampleStateParams)
	, m_colorBlendState			(blendState)
	, m_geometryType			(geometryType)
	, m_pointSize				(pointSize)
	, m_backingMode				(backingMode)
{
	if (m_multisampleStateParams.pSampleMask)
	{
		// Copy pSampleMask to avoid dependencies with other classes

		const deUint32 maskCount = deCeilFloatToInt32(float(m_multisampleStateParams.rasterizationSamples) / 32);

		for (deUint32 maskNdx = 0; maskNdx < maskCount; maskNdx++)
			m_sampleMask.push_back(m_multisampleStateParams.pSampleMask[maskNdx]);

		m_multisampleStateParams.pSampleMask = m_sampleMask.data();
	}
}

void MultisampleTest::initPrograms (SourceCollections& programCollection) const
{
	MultisampleTestParams params = {m_geometryType, m_pointSize, m_backingMode};
	initMultisamplePrograms(programCollection, params);
}

TestInstance* MultisampleTest::createInstance (Context& context) const
{
	return createMultisampleTestInstance(context, getPrimitiveTopology(m_geometryType), m_pointSize, generateVertices(m_geometryType), m_multisampleStateParams, m_colorBlendState);
}


// RasterizationSamplesTest

RasterizationSamplesTest::RasterizationSamplesTest (tcu::TestContext&		testContext,
													const std::string&		name,
													const std::string&		description,
													VkSampleCountFlagBits	rasterizationSamples,
													GeometryType			geometryType,
													float					pointSize,
													ImageBackingMode		backingMode,
													TestModeFlags			modeFlags)
	: MultisampleTest	(testContext, name, description, getRasterizationSamplesStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode)
	, m_backingMode		(backingMode)
	, m_modeFlags		(modeFlags)
{
}

VkPipelineMultisampleStateCreateInfo RasterizationSamplesTest::getRasterizationSamplesStateParams (VkSampleCountFlagBits rasterizationSamples)
{
	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,													// const void*								pNext;
		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
		false,														// VkBool32									sampleShadingEnable;
		0.0f,														// float									minSampleShading;
		DE_NULL,													// const VkSampleMask*						pSampleMask;
		false,														// VkBool32									alphaToCoverageEnable;
		false														// VkBool32									alphaToOneEnable;
	};

	return multisampleStateParams;
}

TestInstance* RasterizationSamplesTest::createMultisampleTestInstance (Context&										context,
																	   VkPrimitiveTopology							topology,
																	   float										pointSize,
																	   const std::vector<Vertex4RGBA>&				vertices,
																	   const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																	   const VkPipelineColorBlendAttachmentState&	colorBlendState) const
{
	return new RasterizationSamplesInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_modeFlags, m_backingMode);
}


// MinSampleShadingTest

MinSampleShadingTest::MinSampleShadingTest (tcu::TestContext&		testContext,
											const std::string&		name,
											const std::string&		description,
											VkSampleCountFlagBits	rasterizationSamples,
											float					minSampleShading,
											GeometryType			geometryType,
											float					pointSize,
											ImageBackingMode		backingMode)
	: MultisampleTest	(testContext, name, description, getMinSampleShadingStateParams(rasterizationSamples, minSampleShading), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode)
	, m_pointSize		(pointSize)
	, m_backingMode		(backingMode)
{
}

void MinSampleShadingTest::initPrograms (SourceCollections& programCollection) const
{
	MultisampleTestParams params = {m_geometryType, m_pointSize, m_backingMode};
	initSampleShadingPrograms(programCollection, params);
}

TestInstance* MinSampleShadingTest::createMultisampleTestInstance (Context&										context,
																   VkPrimitiveTopology							topology,
																   float										pointSize,
																   const std::vector<Vertex4RGBA>&				vertices,
																   const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																   const VkPipelineColorBlendAttachmentState&	colorBlendState) const
{
	return new MinSampleShadingInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode);
}

VkPipelineMultisampleStateCreateInfo MinSampleShadingTest::getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples, float minSampleShading)
{
	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,													// const void*								pNext;
		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
		true,														// VkBool32									sampleShadingEnable;
		minSampleShading,											// float									minSampleShading;
		DE_NULL,													// const VkSampleMask*						pSampleMask;
		false,														//  VkBool32								alphaToCoverageEnable;
		false														//  VkBool32								alphaToOneEnable;
	};

	return multisampleStateParams;
}


// SampleMaskTest

SampleMaskTest::SampleMaskTest (tcu::TestContext&					testContext,
								const std::string&					name,
								const std::string&					description,
								VkSampleCountFlagBits				rasterizationSamples,
								const std::vector<VkSampleMask>&	sampleMask,
								GeometryType						geometryType,
								float								pointSize,
								ImageBackingMode					backingMode)
	: MultisampleTest	(testContext, name, description, getSampleMaskStateParams(rasterizationSamples, sampleMask), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode)
	, m_backingMode		(backingMode)
{
}

TestInstance* SampleMaskTest::createMultisampleTestInstance (Context&										context,
															 VkPrimitiveTopology							topology,
															 float											pointSize,
															 const std::vector<Vertex4RGBA>&				vertices,
															 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
															 const VkPipelineColorBlendAttachmentState&		colorBlendState) const
{
	DE_UNREF(pointSize);
	return new SampleMaskInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode);
}

VkPipelineMultisampleStateCreateInfo SampleMaskTest::getSampleMaskStateParams (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask)
{
	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,													// const void*								pNext;
		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
		false,														// VkBool32									sampleShadingEnable;
		0.0f,														// float									minSampleShading;
		sampleMask.data(),											// const VkSampleMask*						pSampleMask;
		false,														// VkBool32									alphaToCoverageEnable;
		false														// VkBool32									alphaToOneEnable;
	};

	return multisampleStateParams;
}


// AlphaToOneTest

AlphaToOneTest::AlphaToOneTest (tcu::TestContext&		testContext,
								const std::string&		name,
								const std::string&		description,
								VkSampleCountFlagBits	rasterizationSamples,
								ImageBackingMode		backingMode)
	: MultisampleTest	(testContext, name, description, getAlphaToOneStateParams(rasterizationSamples), getAlphaToOneBlendState(), GEOMETRY_TYPE_GRADIENT_QUAD, 1.0f, backingMode)
	, m_backingMode(backingMode)
{
}

TestInstance* AlphaToOneTest::createMultisampleTestInstance (Context&										context,
															 VkPrimitiveTopology							topology,
															 float											pointSize,
															 const std::vector<Vertex4RGBA>&				vertices,
															 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
															 const VkPipelineColorBlendAttachmentState&		colorBlendState) const
{
	DE_UNREF(pointSize);
	return new AlphaToOneInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_backingMode);
}

VkPipelineMultisampleStateCreateInfo AlphaToOneTest::getAlphaToOneStateParams (VkSampleCountFlagBits rasterizationSamples)
{
	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,													// const void*								pNext;
		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
		false,														// VkBool32									sampleShadingEnable;
		0.0f,														// float									minSampleShading;
		DE_NULL,													// const VkSampleMask*						pSampleMask;
		false,														// VkBool32									alphaToCoverageEnable;
		true														// VkBool32									alphaToOneEnable;
	};

	return multisampleStateParams;
}

VkPipelineColorBlendAttachmentState AlphaToOneTest::getAlphaToOneBlendState (void)
{
	const VkPipelineColorBlendAttachmentState colorBlendState =
	{
		true,														// VkBool32					blendEnable;
		VK_BLEND_FACTOR_SRC_ALPHA,									// VkBlendFactor			srcColorBlendFactor;
		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,						// VkBlendFactor			dstColorBlendFactor;
		VK_BLEND_OP_ADD,											// VkBlendOp				colorBlendOp;
		VK_BLEND_FACTOR_SRC_ALPHA,									// VkBlendFactor			srcAlphaBlendFactor;
		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,						// VkBlendFactor			dstAlphaBlendFactor;
		VK_BLEND_OP_ADD,											// VkBlendOp				alphaBlendOp;
		VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |		// VkColorComponentFlags	colorWriteMask;
			VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
	};

	return colorBlendState;
}


// AlphaToCoverageTest

AlphaToCoverageTest::AlphaToCoverageTest (tcu::TestContext&			testContext,
										  const std::string&		name,
										  const std::string&		description,
										  VkSampleCountFlagBits		rasterizationSamples,
										  GeometryType				geometryType,
										  ImageBackingMode			backingMode)
	: MultisampleTest	(testContext, name, description, getAlphaToCoverageStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode)
	, m_geometryType	(geometryType)
	, m_backingMode		(backingMode)
{
}

TestInstance* AlphaToCoverageTest::createMultisampleTestInstance (Context&										context,
																  VkPrimitiveTopology							topology,
																  float											pointSize,
																  const std::vector<Vertex4RGBA>&				vertices,
																  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																  const VkPipelineColorBlendAttachmentState&	colorBlendState) const
{
	DE_UNREF(pointSize);
	return new AlphaToCoverageInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode);
}

VkPipelineMultisampleStateCreateInfo AlphaToCoverageTest::getAlphaToCoverageStateParams (VkSampleCountFlagBits rasterizationSamples)
{
	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,													// const void*								pNext;
		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
		false,														// VkBool32									sampleShadingEnable;
		0.0f,														// float									minSampleShading;
		DE_NULL,													// const VkSampleMask*						pSampleMask;
		true,														// VkBool32									alphaToCoverageEnable;
		false														// VkBool32									alphaToOneEnable;
	};

	return multisampleStateParams;
}

// AlphaToCoverageNoColorAttachmentTest

AlphaToCoverageNoColorAttachmentTest::AlphaToCoverageNoColorAttachmentTest (tcu::TestContext&		testContext,
																			const std::string&		name,
																			const std::string&		description,
																			VkSampleCountFlagBits	rasterizationSamples,
																			GeometryType			geometryType,
																			ImageBackingMode		backingMode)
	: MultisampleTest	(testContext, name, description, getStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode)
	, m_geometryType	(geometryType)
	, m_backingMode		(backingMode)
{
}

TestInstance* AlphaToCoverageNoColorAttachmentTest::createMultisampleTestInstance (Context&										context,
																				   VkPrimitiveTopology							topology,
																				   float										pointSize,
																				   const std::vector<Vertex4RGBA>&				vertices,
																				   const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																				   const VkPipelineColorBlendAttachmentState&	colorBlendState) const
{
	DE_UNREF(pointSize);
	return new AlphaToCoverageNoColorAttachmentInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode);
}

VkPipelineMultisampleStateCreateInfo AlphaToCoverageNoColorAttachmentTest::getStateParams (VkSampleCountFlagBits rasterizationSamples)
{
	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,													// const void*								pNext;
		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
		false,														// VkBool32									sampleShadingEnable;
		0.0f,														// float									minSampleShading;
		DE_NULL,													// const VkSampleMask*						pSampleMask;
		true,														// VkBool32									alphaToCoverageEnable;
		false														// VkBool32									alphaToOneEnable;
	};

	return multisampleStateParams;
}

// AlphaToCoverageColorUnusedAttachmentTest

AlphaToCoverageColorUnusedAttachmentTest::AlphaToCoverageColorUnusedAttachmentTest (tcu::TestContext&		testContext,
																					const std::string&		name,
																					const std::string&		description,
																					VkSampleCountFlagBits	rasterizationSamples,
																					GeometryType			geometryType,
																					ImageBackingMode		backingMode)
	: MultisampleTest	(testContext, name, description, getStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode)
	, m_geometryType	(geometryType)
	, m_backingMode		(backingMode)
{
}

void AlphaToCoverageColorUnusedAttachmentTest::initPrograms (SourceCollections& programCollection) const
{
	initAlphaToCoverageColorUnusedAttachmentPrograms(programCollection);
}

TestInstance* AlphaToCoverageColorUnusedAttachmentTest::createMultisampleTestInstance (Context&										context,
																					   VkPrimitiveTopology							topology,
																					   float										pointSize,
																					   const std::vector<Vertex4RGBA>&				vertices,
																					   const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																					   const VkPipelineColorBlendAttachmentState&	colorBlendState) const
{
	DE_UNREF(pointSize);
	return new AlphaToCoverageColorUnusedAttachmentInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode);
}

VkPipelineMultisampleStateCreateInfo AlphaToCoverageColorUnusedAttachmentTest::getStateParams (VkSampleCountFlagBits rasterizationSamples)
{
	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,													// const void*								pNext;
		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
		false,														// VkBool32									sampleShadingEnable;
		0.0f,														// float									minSampleShading;
		DE_NULL,													// const VkSampleMask*						pSampleMask;
		true,														// VkBool32									alphaToCoverageEnable;
		false														// VkBool32									alphaToOneEnable;
	};

	return multisampleStateParams;
}

// SampleMaskWithDepthTestTest

SampleMaskWithDepthTestTest::SampleMaskWithDepthTestTest (tcu::TestContext&					testContext,
														  const std::string&				name,
														  const std::string&				description,
														  const VkSampleCountFlagBits		rasterizationSamples,
														  const bool						enablePostDepthCoverage)
	: vkt::TestCase				(testContext, name, description)
	, m_rasterizationSamples	(rasterizationSamples)
	, m_enablePostDepthCoverage	(enablePostDepthCoverage)
{
}

void SampleMaskWithDepthTestTest::initPrograms (SourceCollections& programCollection) const
{
	DE_ASSERT((int)m_rasterizationSamples <= 32);

	static const char* vertexSource =
		"#version 440\n"
		"layout(location = 0) in vec4 position;\n"
		"layout(location = 1) in vec4 color;\n"
		"layout(location = 0) out vec4 vtxColor;\n"
		"out gl_PerVertex\n"
		"{\n"
		"    vec4 gl_Position;\n"
		"};\n"
		"\n"
		"void main (void)\n"
		"{\n"
		"    gl_Position = position;\n"
		"    vtxColor = color;\n"
		"}\n";

	std::ostringstream fragmentSource;
	fragmentSource <<
		"#version 440\n"
		<< (m_enablePostDepthCoverage ? "#extension GL_ARB_post_depth_coverage : require\n" : "") <<
		"layout(early_fragment_tests) in;\n"
		<< (m_enablePostDepthCoverage ? "layout(post_depth_coverage) in;\n" : "") <<
		"layout(location = 0) in vec4 vtxColor;\n"
		"layout(location = 0) out vec4 fragColor;\n"
		"void main (void)\n"
		"{\n"
		"    const int coveredSamples = bitCount(gl_SampleMaskIn[0]);\n"
		"    fragColor = vtxColor * (1.0 / " << (int)m_rasterizationSamples << " * coveredSamples);\n"
		"}\n";

	programCollection.glslSources.add("color_vert") << glu::VertexSource(vertexSource);
	programCollection.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str());
}

TestInstance* SampleMaskWithDepthTestTest::createInstance (Context& context) const
{
	return new SampleMaskWithDepthTestInstance(context, m_rasterizationSamples, m_enablePostDepthCoverage);
}

// RasterizationSamplesInstance

RasterizationSamplesInstance::RasterizationSamplesInstance (Context&										context,
															VkPrimitiveTopology								topology,
															float											pointSize,
															const std::vector<Vertex4RGBA>&					vertices,
															const VkPipelineMultisampleStateCreateInfo&		multisampleStateParams,
															const VkPipelineColorBlendAttachmentState&		blendState,
															const TestModeFlags								modeFlags,
															ImageBackingMode								backingMode)
	: vkt::TestInstance		(context)
	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
	, m_renderSize			(32, 32)
	, m_primitiveTopology	(topology)
	, m_pointSize			(pointSize)
	, m_vertices			(vertices)
	, m_fullQuadVertices	(generateVertices(GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH))
	, m_modeFlags			(modeFlags)
{
	checkLargePointsSupport(context, topology, pointSize);

	if (m_modeFlags != 0)
	{
		const bool		useDepth			= (m_modeFlags & TEST_MODE_DEPTH_BIT) != 0;
		const bool		useStencil			= (m_modeFlags & TEST_MODE_STENCIL_BIT) != 0;
		const VkFormat	depthStencilFormat	= findSupportedDepthStencilFormat(context, useDepth, useStencil);

		if (depthStencilFormat == VK_FORMAT_UNDEFINED)
			TCU_THROW(NotSupportedError, "Required depth/stencil format is not supported");

		const VkPrimitiveTopology		pTopology[2] = { m_primitiveTopology, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP };
		const std::vector<Vertex4RGBA>	pVertices[2] = { m_vertices, m_fullQuadVertices };

		m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
			new MultisampleRenderer(
				context, m_colorFormat, depthStencilFormat, m_renderSize, useDepth, useStencil, 2u, pTopology, pVertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE, backingMode));
	}
	else
	{
		m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
			new MultisampleRenderer(context, m_colorFormat, m_renderSize, topology, vertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE, backingMode));
	}
}

tcu::TestStatus RasterizationSamplesInstance::iterate (void)
{
	de::MovePtr<tcu::TextureLevel> level(m_multisampleRenderer->render());
	return verifyImage(level->getAccess());
}

tcu::TestStatus RasterizationSamplesInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
{
	// Verify range of unique pixels
	{
		const deUint32	numUniqueColors = getUniqueColorsCount(result);
		const deUint32	minUniqueColors	= (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST && m_pointSize == 1.0f) ? 2 : 3;

		tcu::TestLog& log = m_context.getTestContext().getLog();

		log << tcu::TestLog::Message
			<< "\nMin. unique colors expected: " << minUniqueColors << "\n"
			<< "Unique colors found: " << numUniqueColors << "\n"
			<< tcu::TestLog::EndMessage;

		if (numUniqueColors < minUniqueColors)
			return tcu::TestStatus::fail("Unique colors out of expected bounds");
	}

	// Verify shape of the rendered primitive (fuzzy-compare)
	{
		const tcu::TextureFormat	tcuColorFormat	= mapVkFormat(m_colorFormat);
		const tcu::TextureFormat	tcuDepthFormat	= tcu::TextureFormat();
		const ColorVertexShader		vertexShader;
		const ColorFragmentShader	fragmentShader	(tcuColorFormat, tcuDepthFormat);
		const rr::Program			program			(&vertexShader, &fragmentShader);
		ReferenceRenderer			refRenderer		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
		rr::RenderState				renderState		(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits);

		if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
		{
			VkPhysicalDeviceProperties deviceProperties;

			m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties);

			// gl_PointSize is clamped to pointSizeRange
			renderState.point.pointSize = deFloatMin(m_pointSize, deviceProperties.limits.pointSizeRange[1]);
		}

		if (m_modeFlags == 0)
		{
			refRenderer.colorClear(tcu::Vec4(0.0f));
			refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
		}
		else
		{
			// For depth/stencil case the primitive is invisible and the surroundings are filled red.
			refRenderer.colorClear(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
			refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
		}

		if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "FuzzyImageCompare", "Image comparison", refRenderer.getAccess(), result, 0.05f, tcu::COMPARE_LOG_RESULT))
			return tcu::TestStatus::fail("Primitive has unexpected shape");
	}

	return tcu::TestStatus::pass("Primitive rendered, unique colors within expected bounds");
}


// MinSampleShadingInstance

MinSampleShadingInstance::MinSampleShadingInstance (Context&									context,
													VkPrimitiveTopology							topology,
													float										pointSize,
													const std::vector<Vertex4RGBA>&				vertices,
													const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
													const VkPipelineColorBlendAttachmentState&	colorBlendState,
													ImageBackingMode							backingMode)
	: vkt::TestInstance			(context)
	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
	, m_renderSize				(32, 32)
	, m_primitiveTopology		(topology)
	, m_vertices				(vertices)
	, m_multisampleStateParams	(multisampleStateParams)
	, m_colorBlendState			(colorBlendState)
	, m_backingMode				(backingMode)
{
	checkLargePointsSupport(context, topology, pointSize);

	VkPhysicalDeviceFeatures deviceFeatures;

	m_context.getInstanceInterface().getPhysicalDeviceFeatures(m_context.getPhysicalDevice(), &deviceFeatures);

	if (!deviceFeatures.sampleRateShading)
		throw tcu::NotSupportedError("Sample shading is not supported");
}

tcu::TestStatus MinSampleShadingInstance::iterate (void)
{
	de::MovePtr<tcu::TextureLevel>	noSampleshadingImage;
	std::vector<tcu::TextureLevel>	sampleShadedImages;

	// Render and resolve without sample shading
	{
		VkPipelineMultisampleStateCreateInfo multisampleStateParms = m_multisampleStateParams;
		multisampleStateParms.sampleShadingEnable	= VK_FALSE;
		multisampleStateParms.minSampleShading		= 0.0;

		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleStateParms, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
		noSampleshadingImage  = renderer.render();
	}

	// Render with test minSampleShading and collect per-sample images
	{
		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_COPY_SAMPLES, m_backingMode);
		renderer.render();

		sampleShadedImages.resize(m_multisampleStateParams.rasterizationSamples);
		for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
		{
			sampleShadedImages[sampleId] = *renderer.getSingleSampledImage(sampleId);
		}
	}

	// Log images
	{
		tcu::TestLog& testLog	= m_context.getTestContext().getLog();

		testLog << tcu::TestLog::ImageSet("Images", "Images")
				<< tcu::TestLog::Image("noSampleshadingImage", "Image rendered without sample shading", noSampleshadingImage->getAccess());

		for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
		{
			testLog << tcu::TestLog::Image("sampleShadedImage", "One sample of sample shaded image", sampleShadedImages[sampleId].getAccess());
		}
		testLog << tcu::TestLog::EndImageSet;
	}

	return verifySampleShadedImage(sampleShadedImages, noSampleshadingImage->getAccess());
}

tcu::TestStatus MinSampleShadingInstance::verifySampleShadedImage (const std::vector<tcu::TextureLevel>& sampleShadedImages, const tcu::ConstPixelBufferAccess& noSampleshadingImage)
{
	const deUint32	pixelCount	= noSampleshadingImage.getWidth() * noSampleshadingImage.getHeight() * noSampleshadingImage.getDepth();

	bool anyPixelCovered		= false;

	for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++)
	{
		const deUint32 noSampleShadingValue = *((const deUint32*)noSampleshadingImage.getDataPtr() + pixelNdx);

		if (noSampleShadingValue == 0)
		{
			// non-covered pixel, continue
			continue;
		}
		else
		{
			anyPixelCovered = true;
		}

		int numNotCoveredSamples = 0;

		std::map<deUint32, deUint32>	histogram; // map<pixel value, number of occurrences>

		// Collect histogram of occurrences or each pixel across all samples
		for (size_t i = 0; i < sampleShadedImages.size(); ++i)
		{
			const deUint32 sampleShadedValue = *((const deUint32*)sampleShadedImages[i].getAccess().getDataPtr() + pixelNdx);

			if (sampleShadedValue == 0)
			{
				numNotCoveredSamples++;
				continue;
			}

			if (histogram.find(sampleShadedValue) != histogram.end())
				histogram[sampleShadedValue]++;
			else
				histogram[sampleShadedValue] = 1;
		}

		if (numNotCoveredSamples == static_cast<int>(sampleShadedImages.size()))
		{
			return tcu::TestStatus::fail("Got uncovered pixel, where covered samples were expected");
		}

		const int uniqueColorsCount				= (int)histogram.size();
		const int expectedUniqueSamplesCount	= static_cast<int>(m_multisampleStateParams.minSampleShading * static_cast<float>(sampleShadedImages.size()) + 0.5f);

		if (uniqueColorsCount + numNotCoveredSamples < expectedUniqueSamplesCount)
		{
			return tcu::TestStatus::fail("Got less unique colors than requested through minSampleShading");
		}
	}

	if (!anyPixelCovered)
	{
		return tcu::TestStatus::fail("Did not get any covered pixel, cannot test minSampleShading");
	}

	return tcu::TestStatus::pass("Got proper count of unique colors");
}

SampleMaskInstance::SampleMaskInstance (Context&										context,
										VkPrimitiveTopology								topology,
										float											pointSize,
										const std::vector<Vertex4RGBA>&					vertices,
										const VkPipelineMultisampleStateCreateInfo&		multisampleStateParams,
										const VkPipelineColorBlendAttachmentState&		blendState,
										ImageBackingMode								backingMode)
	: vkt::TestInstance			(context)
	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
	, m_renderSize				(32, 32)
	, m_primitiveTopology		(topology)
	, m_vertices				(vertices)
	, m_multisampleStateParams	(multisampleStateParams)
	, m_colorBlendState			(blendState)
	, m_backingMode				(backingMode)
{
	checkLargePointsSupport(context, topology, pointSize);
}

tcu::TestStatus SampleMaskInstance::iterate (void)
{
	de::MovePtr<tcu::TextureLevel>				testSampleMaskImage;
	de::MovePtr<tcu::TextureLevel>				minSampleMaskImage;
	de::MovePtr<tcu::TextureLevel>				maxSampleMaskImage;

	// Render with test flags
	{
		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
		testSampleMaskImage = renderer.render();
	}

	// Render with all flags off
	{
		VkPipelineMultisampleStateCreateInfo	multisampleParams	= m_multisampleStateParams;
		const std::vector<VkSampleMask>			sampleMask			(multisampleParams.rasterizationSamples / 32, (VkSampleMask)0);

		multisampleParams.pSampleMask = sampleMask.data();

		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
		minSampleMaskImage = renderer.render();
	}

	// Render with all flags on
	{
		VkPipelineMultisampleStateCreateInfo	multisampleParams	= m_multisampleStateParams;
		const std::vector<VkSampleMask>			sampleMask			(multisampleParams.rasterizationSamples / 32, ~((VkSampleMask)0));

		multisampleParams.pSampleMask = sampleMask.data();

		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
		maxSampleMaskImage = renderer.render();
	}

	return verifyImage(testSampleMaskImage->getAccess(), minSampleMaskImage->getAccess(), maxSampleMaskImage->getAccess());
}

tcu::TestStatus SampleMaskInstance::verifyImage (const tcu::ConstPixelBufferAccess& testSampleMaskImage,
												 const tcu::ConstPixelBufferAccess& minSampleMaskImage,
												 const tcu::ConstPixelBufferAccess& maxSampleMaskImage)
{
	const deUint32	testColorCount	= getUniqueColorsCount(testSampleMaskImage);
	const deUint32	minColorCount	= getUniqueColorsCount(minSampleMaskImage);
	const deUint32	maxColorCount	= getUniqueColorsCount(maxSampleMaskImage);

	tcu::TestLog& log = m_context.getTestContext().getLog();

	log << tcu::TestLog::Message
		<< "\nColors found: " << testColorCount << "\n"
		<< "Min. colors expected: " << minColorCount << "\n"
		<< "Max. colors expected: " << maxColorCount << "\n"
		<< tcu::TestLog::EndMessage;

	if (minColorCount > testColorCount || testColorCount > maxColorCount)
		return tcu::TestStatus::fail("Unique colors out of expected bounds");
	else
		return tcu::TestStatus::pass("Unique colors within expected bounds");
}

tcu::TestStatus testRasterSamplesConsistency (Context& context, MultisampleTestParams params)
{
	const VkSampleCountFlagBits samples[] =
	{
		VK_SAMPLE_COUNT_1_BIT,
		VK_SAMPLE_COUNT_2_BIT,
		VK_SAMPLE_COUNT_4_BIT,
		VK_SAMPLE_COUNT_8_BIT,
		VK_SAMPLE_COUNT_16_BIT,
		VK_SAMPLE_COUNT_32_BIT,
		VK_SAMPLE_COUNT_64_BIT
	};

	const Vertex4RGBA vertexData[3] =
	{
		{
			tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f),
			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
		},
		{
			tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f),
			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
		},
		{
			tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f),
			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
		}
	};

	const std::vector<Vertex4RGBA>	vertices			(vertexData, vertexData + 3);
	deUint32						prevUniqueColors	= 2;
	int								renderCount			= 0;

	// Do not render with 1 sample (start with samplesNdx = 1).
	for (int samplesNdx = 1; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
	{
		if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), samples[samplesNdx]))
			continue;

		const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
			DE_NULL,													// const void*								pNext;
			0u,															// VkPipelineMultisampleStateCreateFlags	flags;
			samples[samplesNdx],										// VkSampleCountFlagBits					rasterizationSamples;
			false,														// VkBool32									sampleShadingEnable;
			0.0f,														// float									minSampleShading;
			DE_NULL,													// const VkSampleMask*						pSampleMask;
			false,														// VkBool32									alphaToCoverageEnable;
			false														// VkBool32									alphaToOneEnable;
		};

		MultisampleRenderer				renderer		(context, VK_FORMAT_R8G8B8A8_UNORM, tcu::IVec2(32, 32), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, vertices, multisampleStateParams, getDefaultColorBlendAttachmentState(), RENDER_TYPE_RESOLVE, params.backingMode);
		de::MovePtr<tcu::TextureLevel>	result			= renderer.render();
		const deUint32					uniqueColors	= getUniqueColorsCount(result->getAccess());

		renderCount++;

		if (prevUniqueColors > uniqueColors)
		{
			std::ostringstream message;

			message << "More unique colors generated with " << samples[samplesNdx - 1] << " than with " << samples[samplesNdx];
			return tcu::TestStatus::fail(message.str());
		}

		prevUniqueColors = uniqueColors;
	}

	if (renderCount == 0)
		throw tcu::NotSupportedError("Multisampling is unsupported");

	return tcu::TestStatus::pass("Number of unique colors increases as the sample count increases");
}


// AlphaToOneInstance

AlphaToOneInstance::AlphaToOneInstance (Context&									context,
										VkPrimitiveTopology							topology,
										const std::vector<Vertex4RGBA>&				vertices,
										const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
										const VkPipelineColorBlendAttachmentState&	blendState,
										ImageBackingMode							backingMode)
	: vkt::TestInstance			(context)
	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
	, m_renderSize				(32, 32)
	, m_primitiveTopology		(topology)
	, m_vertices				(vertices)
	, m_multisampleStateParams	(multisampleStateParams)
	, m_colorBlendState			(blendState)
	, m_backingMode				(backingMode)
{
	VkPhysicalDeviceFeatures deviceFeatures;

	context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &deviceFeatures);

	if (!deviceFeatures.alphaToOne)
		throw tcu::NotSupportedError("Alpha-to-one is not supported");
}

tcu::TestStatus AlphaToOneInstance::iterate	(void)
{
	DE_ASSERT(m_multisampleStateParams.alphaToOneEnable);
	DE_ASSERT(m_colorBlendState.blendEnable);

	de::MovePtr<tcu::TextureLevel>	alphaOneImage;
	de::MovePtr<tcu::TextureLevel>	noAlphaOneImage;

	// Render with blend enabled and alpha to one on
	{
		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
		alphaOneImage = renderer.render();
	}

	// Render with blend enabled and alpha to one off
	{
		VkPipelineMultisampleStateCreateInfo	multisampleParams	= m_multisampleStateParams;
		multisampleParams.alphaToOneEnable = false;

		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
		noAlphaOneImage = renderer.render();
	}

	return verifyImage(alphaOneImage->getAccess(), noAlphaOneImage->getAccess());
}

tcu::TestStatus AlphaToOneInstance::verifyImage (const tcu::ConstPixelBufferAccess&	alphaOneImage,
												 const tcu::ConstPixelBufferAccess&	noAlphaOneImage)
{
	for (int y = 0; y < m_renderSize.y(); y++)
	{
		for (int x = 0; x < m_renderSize.x(); x++)
		{
			if (!tcu::boolAll(tcu::greaterThanEqual(alphaOneImage.getPixel(x, y), noAlphaOneImage.getPixel(x, y))))
			{
				std::ostringstream message;
				message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " >= " << noAlphaOneImage.getPixel(x, y);
				return tcu::TestStatus::fail(message.str());
			}
		}
	}

	return tcu::TestStatus::pass("Image rendered with alpha-to-one contains pixels of image rendered with no alpha-to-one");
}


// AlphaToCoverageInstance

AlphaToCoverageInstance::AlphaToCoverageInstance (Context&										context,
												  VkPrimitiveTopology							topology,
												  const std::vector<Vertex4RGBA>&				vertices,
												  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
												  const VkPipelineColorBlendAttachmentState&	blendState,
												  GeometryType									geometryType,
												  ImageBackingMode								backingMode)
	: vkt::TestInstance			(context)
	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
	, m_renderSize				(32, 32)
	, m_primitiveTopology		(topology)
	, m_vertices				(vertices)
	, m_multisampleStateParams	(multisampleStateParams)
	, m_colorBlendState			(blendState)
	, m_geometryType			(geometryType)
	, m_backingMode				(backingMode)
{
}

tcu::TestStatus AlphaToCoverageInstance::iterate (void)
{
	DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);

	de::MovePtr<tcu::TextureLevel>	result;
	MultisampleRenderer				renderer	(m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);

	result = renderer.render();

	return verifyImage(result->getAccess());
}

tcu::TestStatus AlphaToCoverageInstance::verifyImage (const tcu::ConstPixelBufferAccess&	result)
{
	float maxColorValue;

	switch (m_geometryType)
	{
		case GEOMETRY_TYPE_OPAQUE_QUAD:
			maxColorValue = 1.01f;
			break;

		case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
			maxColorValue = 0.52f;
			break;

		case GEOMETRY_TYPE_INVISIBLE_QUAD:
			maxColorValue = 0.01f;
			break;

		default:
			maxColorValue = 0.0f;
			DE_ASSERT(false);
	}

	for (int y = 0; y < m_renderSize.y(); y++)
	{
		for (int x = 0; x < m_renderSize.x(); x++)
		{
			if (result.getPixel(x, y).x() > maxColorValue)
			{
				std::ostringstream message;
				message << "Pixel is not below the threshold value (" << result.getPixel(x, y).x() << " > " << maxColorValue << ")";
				return tcu::TestStatus::fail(message.str());
			}
		}
	}

	return tcu::TestStatus::pass("Image matches reference value");
}

// AlphaToCoverageNoColorAttachmentInstance

AlphaToCoverageNoColorAttachmentInstance::AlphaToCoverageNoColorAttachmentInstance (Context&									context,
																					VkPrimitiveTopology							topology,
																					const std::vector<Vertex4RGBA>&				vertices,
																					const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																					const VkPipelineColorBlendAttachmentState&	blendState,
																					GeometryType								geometryType,
																					ImageBackingMode							backingMode)
	: vkt::TestInstance			(context)
	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
	, m_depthStencilFormat		(VK_FORMAT_D16_UNORM)
	, m_renderSize				(32, 32)
	, m_primitiveTopology		(topology)
	, m_vertices				(vertices)
	, m_multisampleStateParams	(multisampleStateParams)
	, m_colorBlendState			(blendState)
	, m_geometryType			(geometryType)
	, m_backingMode				(backingMode)
{
}

tcu::TestStatus AlphaToCoverageNoColorAttachmentInstance::iterate (void)
{
	DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);

	de::MovePtr<tcu::TextureLevel>	result;
	MultisampleRenderer				renderer	(m_context, m_colorFormat, m_depthStencilFormat, m_renderSize, true, false, 1u, &m_primitiveTopology, &m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_DEPTHSTENCIL_ONLY, m_backingMode, 1.0f);

	result = renderer.render();

	return verifyImage(result->getAccess());
}

tcu::TestStatus AlphaToCoverageNoColorAttachmentInstance::verifyImage (const tcu::ConstPixelBufferAccess&	result)
{
	for (int y = 0; y < m_renderSize.y(); y++)
	{
		for (int x = 0; x < m_renderSize.x(); x++)
		{
			// Expect full red for each pixel. Fail if clear color is showing.
			if (result.getPixel(x, y).x() < 1.0f)
			{
				// Log result image when failing.
				m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result image") << tcu::TestLog::Image("Rendered", "Rendered image", result) << tcu::TestLog::EndImageSet;

				return tcu::TestStatus::fail("Fail");
			}
		}
	}

	return tcu::TestStatus::pass("Pass");
}

// AlphaToCoverageColorUnusedAttachmentInstance

AlphaToCoverageColorUnusedAttachmentInstance::AlphaToCoverageColorUnusedAttachmentInstance (Context&									context,
																							VkPrimitiveTopology							topology,
																							const std::vector<Vertex4RGBA>&				vertices,
																							const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																							const VkPipelineColorBlendAttachmentState&	blendState,
																							GeometryType								geometryType,
																							ImageBackingMode							backingMode)
	: vkt::TestInstance			(context)
	, m_colorFormat				(VK_FORMAT_R5G6B5_UNORM_PACK16)
	, m_renderSize				(32, 32)
	, m_primitiveTopology		(topology)
	, m_vertices				(vertices)
	, m_multisampleStateParams	(multisampleStateParams)
	, m_colorBlendState			(blendState)
	, m_geometryType			(geometryType)
	, m_backingMode				(backingMode)
{
}

tcu::TestStatus AlphaToCoverageColorUnusedAttachmentInstance::iterate (void)
{
	DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);

	de::MovePtr<tcu::TextureLevel>	result;
	MultisampleRenderer				renderer	(m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_UNUSED_ATTACHMENT, m_backingMode);

	result = renderer.render();

	return verifyImage(result->getAccess());
}

tcu::TestStatus AlphaToCoverageColorUnusedAttachmentInstance::verifyImage (const tcu::ConstPixelBufferAccess&	result)
{
	for (int y = 0; y < m_renderSize.y(); y++)
	{
		for (int x = 0; x < m_renderSize.x(); x++)
		{
			// Quad color gets written to color buffer at location 1, and the alpha value to location 0 which is unused.
			// The coverage should still be affected by the alpha written to location 0.
			if ((m_geometryType == GEOMETRY_TYPE_OPAQUE_QUAD && result.getPixel(x, y).x() < 1.0f)
				|| (m_geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD && result.getPixel(x, y).x() > 0.0f))
			{
				// Log result image when failing.
				m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result image") << tcu::TestLog::Image("Rendered", "Rendered image", result) << tcu::TestLog::EndImageSet;

				return tcu::TestStatus::fail("Fail");
			}
		}
	}

	return tcu::TestStatus::pass("Pass");
}

// SampleMaskWithDepthTestInstance

SampleMaskWithDepthTestInstance::SampleMaskWithDepthTestInstance (Context&						context,
																  const VkSampleCountFlagBits	rasterizationSamples,
																  const bool					enablePostDepthCoverage)
	: vkt::TestInstance			(context)
	, m_rasterizationSamples	(rasterizationSamples)
	, m_enablePostDepthCoverage	(enablePostDepthCoverage)
	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
	, m_depthStencilFormat		(VK_FORMAT_D16_UNORM)
	, m_renderSize				(tcu::IVec2(3, 3))
	, m_useDepth				(true)
	, m_useStencil				(false)
	, m_topology				(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
	, m_renderColor				(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f))
	, m_vertices				(generateVertices())
	, m_multisampleStateParams	(getMultisampleState(rasterizationSamples))
	, m_blendState				(getDefaultColorBlendAttachmentState())
	, m_renderType				(RENDER_TYPE_RESOLVE)
	, m_imageBackingMode		(IMAGE_BACKING_MODE_REGULAR)
	, m_depthClearValue			(0.667f)
{
	if (!m_context.getDeviceProperties().limits.standardSampleLocations)
		TCU_THROW(NotSupportedError, "standardSampleLocations required");

	std::vector<VkExtensionProperties> supportedExtensions = enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL);

	if (!isExtensionSupported(supportedExtensions, RequiredExtension("VK_EXT_post_depth_coverage")))
		TCU_THROW(NotSupportedError, "VK_EXT_post_depth_coverage not supported");

	m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_2_BIT]	= SampleCoverage(1u, 1u);	// !< Sample coverage of the diagonally halved pixel,
	m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_4_BIT]	= SampleCoverage(2u, 2u);	// !< with max possible subPixelPrecisionBits threshold
	m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_8_BIT]	= SampleCoverage(2u, 6u);	// !<
	m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_16_BIT]	= SampleCoverage(6u, 11u);	// !<
}

tcu::TestStatus SampleMaskWithDepthTestInstance::iterate (void)
{
	de::MovePtr<tcu::TextureLevel>	result;

	MultisampleRenderer renderer (m_context, m_colorFormat, m_depthStencilFormat, m_renderSize, m_useDepth, m_useStencil, 1u, &m_topology,
								  &m_vertices, m_multisampleStateParams, m_blendState, m_renderType, m_imageBackingMode, m_depthClearValue);
	result = renderer.render();

	return verifyImage(result->getAccess());
}

VkPipelineMultisampleStateCreateInfo SampleMaskWithDepthTestInstance::getMultisampleState (const VkSampleCountFlagBits rasterizationSamples)
{
	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,													// const void*								pNext;
		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
		false,														// VkBool32									sampleShadingEnable;
		0.0f,														// float									minSampleShading;
		DE_NULL,													// const VkSampleMask*						pSampleMask;
		false,														// VkBool32									alphaToCoverageEnable;
		false														// VkBool32									alphaToOneEnable;
	};

	return multisampleStateParams;
}

std::vector<Vertex4RGBA> SampleMaskWithDepthTestInstance::generateVertices (void)
{
	std::vector<Vertex4RGBA> vertices;

	{
		const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), m_renderColor };
		vertices.push_back(vertexInput);
	}
	{
		const Vertex4RGBA vertexInput = { tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), m_renderColor };
		vertices.push_back(vertexInput);
	}
	{
		const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f,  1.0f, 1.0f, 1.0f), m_renderColor };
		vertices.push_back(vertexInput);
	}

	return vertices;
}

tcu::TestStatus SampleMaskWithDepthTestInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
{
	bool			pass	= true;
	const int		width	= result.getWidth();
	const int		height	= result.getHeight();
	tcu::TestLog&	log		= m_context.getTestContext().getLog();

	DE_ASSERT(width == 3);
	DE_ASSERT(height == 3);

	const tcu::Vec4 clearColor = tcu::Vec4(0.0f);

	for (int x = 0; x < width; ++x)
	for (int y = 0; y < height; ++y)
	{
		const tcu::Vec4 resultPixel = result.getPixel(x, y);

		if (x + y == 0)
		{
			if (resultPixel != m_renderColor)
			{
				log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
					<< " Reference: " << m_renderColor << tcu::TestLog::EndMessage;
				pass = false;
			}
		}
		else if (x + y == 1)
		{
			// default: m_rasterizationSamples bits set in FS's gl_SampleMaskIn[0] (before depth test)
			// post_depth_coverage: m_refCoverageAfterDepthTest[m_rasterizationSamples] bits set in FS's gl_SampleMaskIn[0] (after depth test)
			const float		threshold	= 0.02f;
			const float		minCoverage	= (m_enablePostDepthCoverage ? (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].min / (float)m_rasterizationSamples : 1.0f)
										* ((float)m_refCoverageAfterDepthTest[m_rasterizationSamples].min / (float)m_rasterizationSamples);
			const float		maxCoverage	= (m_enablePostDepthCoverage ? (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].max / (float)m_rasterizationSamples : 1.0f)
										* ((float)m_refCoverageAfterDepthTest[m_rasterizationSamples].max / (float)m_rasterizationSamples);

			bool			localPass	= true;
			for (deUint32 componentNdx = 0u; componentNdx < m_renderColor.SIZE; ++componentNdx)
			{
				if (m_renderColor[componentNdx] != 0.0f && (resultPixel[componentNdx] <= m_renderColor[componentNdx] * (minCoverage - threshold)
															|| resultPixel[componentNdx] >= m_renderColor[componentNdx] * (maxCoverage + threshold)))
					localPass = false;
			}

			if (!localPass)
			{
				log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
					<< " Reference range ( " << m_renderColor * (minCoverage - threshold) << " ; " << m_renderColor * (maxCoverage + threshold) << " )" << tcu::TestLog::EndMessage;
				pass = false;
			}
		}
		else
		{
			if (resultPixel != clearColor)
			{
				log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
					<< " Reference: " << clearColor << tcu::TestLog::EndMessage;
				pass = false;
			}
		}
	}

	if (pass)
		return tcu::TestStatus::pass("Passed");
	else
		return tcu::TestStatus::fail("Failed");
}

// MultisampleRenderer

MultisampleRenderer::MultisampleRenderer (Context&										context,
										  const VkFormat								colorFormat,
										  const tcu::IVec2&								renderSize,
										  const VkPrimitiveTopology						topology,
										  const std::vector<Vertex4RGBA>&				vertices,
										  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
										  const VkPipelineColorBlendAttachmentState&	blendState,
										  const RenderType								renderType,
										  const ImageBackingMode						backingMode)
	: m_context					(context)
	, m_bindSemaphore			(createSemaphore(context.getDeviceInterface(), context.getDevice()))
	, m_colorFormat				(colorFormat)
	, m_depthStencilFormat		(VK_FORMAT_UNDEFINED)
	, m_renderSize				(renderSize)
	, m_useDepth				(false)
	, m_useStencil				(false)
	, m_multisampleStateParams	(multisampleStateParams)
	, m_colorBlendState			(blendState)
	, m_renderType				(renderType)
	, m_backingMode				(backingMode)
	, m_depthClearValue			(1.0f)
{
	initialize(context, 1u, &topology, &vertices);
}

MultisampleRenderer::MultisampleRenderer (Context&										context,
										  const VkFormat								colorFormat,
										  const VkFormat								depthStencilFormat,
										  const tcu::IVec2&								renderSize,
										  const bool									useDepth,
										  const bool									useStencil,
										  const deUint32								numTopologies,
										  const VkPrimitiveTopology*					pTopology,
										  const std::vector<Vertex4RGBA>*				pVertices,
										  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
										  const VkPipelineColorBlendAttachmentState&	blendState,
										  const RenderType								renderType,
										  const ImageBackingMode						backingMode,
										  const float									depthClearValue)
	: m_context					(context)
	, m_bindSemaphore			(createSemaphore(context.getDeviceInterface(), context.getDevice()))
	, m_colorFormat				(colorFormat)
	, m_depthStencilFormat		(depthStencilFormat)
	, m_renderSize				(renderSize)
	, m_useDepth				(useDepth)
	, m_useStencil				(useStencil)
	, m_multisampleStateParams	(multisampleStateParams)
	, m_colorBlendState			(blendState)
	, m_renderType				(renderType)
	, m_backingMode				(backingMode)
	, m_depthClearValue			(depthClearValue)
{
	initialize(context, numTopologies, pTopology, pVertices);
}

void MultisampleRenderer::initialize (Context&									context,
									  const deUint32							numTopologies,
									  const VkPrimitiveTopology*				pTopology,
									  const std::vector<Vertex4RGBA>*			pVertices)
{
	if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), m_multisampleStateParams.rasterizationSamples))
		throw tcu::NotSupportedError("Unsupported number of rasterization samples");

	const DeviceInterface&			vk						= context.getDeviceInterface();
	const VkDevice					vkDevice				= context.getDevice();
	const VkPhysicalDeviceFeatures	features				= context.getDeviceFeatures();
	const deUint32					queueFamilyIndices[]	= { context.getUniversalQueueFamilyIndex(), context.getSparseQueueFamilyIndex() };
	const bool						sparse					= m_backingMode == IMAGE_BACKING_MODE_SPARSE;
	const VkComponentMapping		componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
	const VkImageCreateFlags		imageCreateFlags		= sparse ? (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) : 0u;
	const VkSharingMode				sharingMode				= (sparse && context.getUniversalQueueFamilyIndex() != context.getSparseQueueFamilyIndex()) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE;
	Allocator&						memAlloc				= m_context.getDefaultAllocator();
	const bool						usesResolveImage		= m_renderType == RENDER_TYPE_RESOLVE || m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY || m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT;

	if (sparse)
	{
		bool sparseSamplesSupported = false;
		switch(m_multisampleStateParams.rasterizationSamples)
		{
			case VK_SAMPLE_COUNT_2_BIT:
				sparseSamplesSupported = features.sparseResidency2Samples;
				break;
			case VK_SAMPLE_COUNT_4_BIT:
				sparseSamplesSupported = features.sparseResidency4Samples;
				break;
			case VK_SAMPLE_COUNT_8_BIT:
				sparseSamplesSupported = features.sparseResidency8Samples;
				break;
			case VK_SAMPLE_COUNT_16_BIT:
				sparseSamplesSupported = features.sparseResidency16Samples;
				break;
			default:
				break;
		}

		if (!sparseSamplesSupported)
			throw tcu::NotSupportedError("Unsupported number of rasterization samples for sparse residency");
	}

	if (sparse && !context.getDeviceFeatures().sparseBinding)
		throw tcu::NotSupportedError("No sparseBinding support");

	// Create color image
	{
		const VkImageUsageFlags	imageUsageFlags		= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
			(m_renderType == RENDER_TYPE_COPY_SAMPLES ? VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0u);

		const VkImageCreateInfo colorImageParams	=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
			DE_NULL,																	// const void*				pNext;
			imageCreateFlags,															// VkImageCreateFlags		flags;
			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
			m_colorFormat,																// VkFormat					format;
			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },				// VkExtent3D				extent;
			1u,																			// deUint32					mipLevels;
			1u,																			// deUint32					arrayLayers;
			m_multisampleStateParams.rasterizationSamples,								// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
			imageUsageFlags,															// VkImageUsageFlags		usage;
			sharingMode,																// VkSharingMode			sharingMode;
			sharingMode == VK_SHARING_MODE_CONCURRENT ? 2u : 1u,						// deUint32					queueFamilyIndexCount;
			queueFamilyIndices,															// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout			initialLayout;
		};

		if (sparse && !checkSparseImageFormatSupport(context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams))
			TCU_THROW(NotSupportedError, "The image format does not support sparse operations.");

		m_colorImage = createImage(vk, vkDevice, &colorImageParams);

		// Allocate and bind color image memory
		if (sparse)
		{
			allocateAndBindSparseImage(vk, vkDevice, context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams, *m_bindSemaphore, context.getSparseQueue(), memAlloc, m_allocations, mapVkFormat(m_colorFormat), *m_colorImage);
		}
		else
		{
			m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
			VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
		}
	}

	// Create resolve image
	if (usesResolveImage)
	{
		const VkImageCreateInfo resolveImageParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
			DE_NULL,																		// const void*				pNext;
			0u,																				// VkImageCreateFlags		flags;
			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
			m_colorFormat,																	// VkFormat					format;
			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },					// VkExtent3D				extent;
			1u,																				// deUint32					mipLevels;
			1u,																				// deUint32					arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,															// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |			// VkImageUsageFlags		usage;
				VK_IMAGE_USAGE_TRANSFER_DST_BIT,
			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
			1u,																				// deUint32					queueFamilyIndexCount;
			queueFamilyIndices,																// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
		};

		m_resolveImage = createImage(vk, vkDevice, &resolveImageParams);

		// Allocate and bind resolve image memory
		m_resolveImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_resolveImage), MemoryRequirement::Any);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_resolveImage, m_resolveImageAlloc->getMemory(), m_resolveImageAlloc->getOffset()));

		// Create resolve attachment view
		{
			const VkImageViewCreateInfo resolveAttachmentViewParams =
			{
				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
				DE_NULL,										// const void*				pNext;
				0u,												// VkImageViewCreateFlags	flags;
				*m_resolveImage,								// VkImage					image;
				VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
				m_colorFormat,									// VkFormat					format;
				componentMappingRGBA,							// VkComponentMapping		components;
				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
			};

			m_resolveAttachmentView = createImageView(vk, vkDevice, &resolveAttachmentViewParams);
		}
	}

	// Create per-sample output images
	if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
	{
		const VkImageCreateInfo perSampleImageParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
			DE_NULL,																		// const void*				pNext;
			0u,																				// VkImageCreateFlags		flags;
			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
			m_colorFormat,																	// VkFormat					format;
			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },					// VkExtent3D				extent;
			1u,																				// deUint32					mipLevels;
			1u,																				// deUint32					arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,															// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |			// VkImageUsageFlags		usage;
			VK_IMAGE_USAGE_TRANSFER_DST_BIT,
			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
			1u,																				// deUint32					queueFamilyIndexCount;
			queueFamilyIndices,																// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
		};

		m_perSampleImages.resize(static_cast<size_t>(m_multisampleStateParams.rasterizationSamples));

		for (size_t i = 0; i < m_perSampleImages.size(); ++i)
		{
			m_perSampleImages[i]	= de::SharedPtr<PerSampleImage>(new PerSampleImage);
			PerSampleImage& image	= *m_perSampleImages[i];

			image.m_image			= createImage(vk, vkDevice, &perSampleImageParams);

			// Allocate and bind image memory
			image.m_imageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image.m_image), MemoryRequirement::Any);
			VK_CHECK(vk.bindImageMemory(vkDevice, *image.m_image, image.m_imageAlloc->getMemory(), image.m_imageAlloc->getOffset()));

			// Create per-sample attachment view
			{
				const VkImageViewCreateInfo perSampleAttachmentViewParams =
				{
					VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
					DE_NULL,										// const void*				pNext;
					0u,												// VkImageViewCreateFlags	flags;
					*image.m_image,									// VkImage					image;
					VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
					m_colorFormat,									// VkFormat					format;
					componentMappingRGBA,							// VkComponentMapping		components;
					{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
				};

				image.m_attachmentView = createImageView(vk, vkDevice, &perSampleAttachmentViewParams);
			}
		}
	}

	// Create a depth/stencil image
	if (m_useDepth || m_useStencil)
	{
		const VkImageCreateInfo depthStencilImageParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
			DE_NULL,																		// const void*				pNext;
			0u,																				// VkImageCreateFlags		flags;
			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
			m_depthStencilFormat,															// VkFormat					format;
			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },					// VkExtent3D				extent;
			1u,																				// deUint32					mipLevels;
			1u,																				// deUint32					arrayLayers;
			m_multisampleStateParams.rasterizationSamples,									// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
			VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,									// VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
			1u,																				// deUint32					queueFamilyIndexCount;
			queueFamilyIndices,																// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
		};

		m_depthStencilImage = createImage(vk, vkDevice, &depthStencilImageParams);

		// Allocate and bind depth/stencil image memory
		m_depthStencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthStencilImage), MemoryRequirement::Any);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthStencilImage, m_depthStencilImageAlloc->getMemory(), m_depthStencilImageAlloc->getOffset()));
	}

	// Create color attachment view
	{
		const VkImageViewCreateInfo colorAttachmentViewParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
			DE_NULL,										// const void*				pNext;
			0u,												// VkImageViewCreateFlags	flags;
			*m_colorImage,									// VkImage					image;
			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
			m_colorFormat,									// VkFormat					format;
			componentMappingRGBA,							// VkComponentMapping		components;
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
		};

		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
	}

	VkImageAspectFlags	depthStencilAttachmentAspect	= (VkImageAspectFlagBits)0;

	// Create depth/stencil attachment view
	if (m_useDepth || m_useStencil)
	{
		depthStencilAttachmentAspect = getImageAspectFlags(m_depthStencilFormat);

		const VkImageViewCreateInfo depthStencilAttachmentViewParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
			DE_NULL,											// const void*				pNext;
			0u,													// VkImageViewCreateFlags	flags;
			*m_depthStencilImage,								// VkImage					image;
			VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
			m_depthStencilFormat,								// VkFormat					format;
			componentMappingRGBA,								// VkComponentMapping		components;
			{ depthStencilAttachmentAspect, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
		};

		m_depthStencilAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams);
	}

	// Create render pass
	{
		std::vector<VkAttachmentDescription> attachmentDescriptions;
		{
			const VkAttachmentDescription colorAttachmentDescription =
			{
				0u,													// VkAttachmentDescriptionFlags		flags;
				m_colorFormat,										// VkFormat							format;
				m_multisampleStateParams.rasterizationSamples,		// 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_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
			};
			attachmentDescriptions.push_back(colorAttachmentDescription);
		}

		deUint32 resolveAttachmentIndex = VK_ATTACHMENT_UNUSED;

		if (usesResolveImage)
		{
			resolveAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());

			const VkAttachmentDescription resolveAttachmentDescription =
			{
				0u,													// VkAttachmentDescriptionFlags		flags;
				m_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_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
			};
			attachmentDescriptions.push_back(resolveAttachmentDescription);
		}

		deUint32 perSampleAttachmentIndex = VK_ATTACHMENT_UNUSED;

		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
		{
			perSampleAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());

			const VkAttachmentDescription perSampleAttachmentDescription =
			{
				0u,													// VkAttachmentDescriptionFlags		flags;
				m_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_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
			};

			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
			{
				attachmentDescriptions.push_back(perSampleAttachmentDescription);
			}
		}

		deUint32 depthStencilAttachmentIndex = VK_ATTACHMENT_UNUSED;

		if (m_useDepth || m_useStencil)
		{
			depthStencilAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());

			const VkAttachmentDescription depthStencilAttachmentDescription =
			{
				0u,																					// VkAttachmentDescriptionFlags		flags;
				m_depthStencilFormat,																// VkFormat							format;
				m_multisampleStateParams.rasterizationSamples,										// VkSampleCountFlagBits			samples;
				(m_useDepth ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE),		// VkAttachmentLoadOp				loadOp;
				(m_useDepth ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE),		// VkAttachmentStoreOp				storeOp;
				(m_useStencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE),		// VkAttachmentStoreOp				stencilLoadOp;
				(m_useStencil ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE),	// VkAttachmentStoreOp				stencilStoreOp;
				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,									// VkImageLayout					initialLayout;
				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL									// VkImageLayout					finalLayout;
			};
			attachmentDescriptions.push_back(depthStencilAttachmentDescription);
		};

		const VkAttachmentReference colorAttachmentReference =
		{
			0u,													// deUint32			attachment;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
		};

		const VkAttachmentReference inputAttachmentReference =
		{
			0u,													// deUint32			attachment;
			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL			// VkImageLayout	layout;
		};

		const VkAttachmentReference resolveAttachmentReference =
		{
			resolveAttachmentIndex,								// deUint32			attachment;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
		};

		const VkAttachmentReference colorAttachmentReferencesUnusedAttachment[] =
		{
			{
				VK_ATTACHMENT_UNUSED,		// deUint32			attachment
				VK_IMAGE_LAYOUT_UNDEFINED	// VkImageLayout	layout
			},
			{
				0u,											// deUint32			attachment
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout	layout
			}
		};

		const VkAttachmentReference resolveAttachmentReferencesUnusedAttachment[] =
		{
			{
				VK_ATTACHMENT_UNUSED,		// deUint32			attachment
				VK_IMAGE_LAYOUT_UNDEFINED	// VkImageLayout	layout
			},
			{
				resolveAttachmentIndex,						// deUint32			attachment
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout	layout
			}
		};

		std::vector<VkAttachmentReference> perSampleAttachmentReferences(m_perSampleImages.size());
		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
		{
			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
			{
				const VkAttachmentReference perSampleAttachmentReference =
				{
					perSampleAttachmentIndex + static_cast<deUint32>(i),	// deUint32			attachment;
					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL				// VkImageLayout	layout;
				};
				perSampleAttachmentReferences[i] = perSampleAttachmentReference;
			}
		}

		const VkAttachmentReference depthStencilAttachmentReference =
		{
			depthStencilAttachmentIndex,						// deUint32			attachment;
			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout	layout;
		};

		std::vector<VkSubpassDescription>	subpassDescriptions;
		std::vector<VkSubpassDependency>	subpassDependencies;

		if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
		{
				const VkSubpassDescription	subpassDescription0	=
				{
					0u,										// VkSubpassDescriptionFlags	flags
					VK_PIPELINE_BIND_POINT_GRAPHICS,		// VkPipelineBindPoint			pipelineBindPoint
					0u,										// deUint32						inputAttachmentCount
					DE_NULL,								// const VkAttachmentReference*	pInputAttachments
					0u,										// deUint32						colorAttachmentCount
					DE_NULL,								// const VkAttachmentReference*	pColorAttachments
					DE_NULL,								// const VkAttachmentReference*	pResolveAttachments
					&depthStencilAttachmentReference,		// const VkAttachmentReference*	pDepthStencilAttachment
					0u,										// deUint32						preserveAttachmentCount
					DE_NULL									// const VkAttachmentReference*	pPreserveAttachments
				};

				const VkSubpassDescription	subpassDescription1	=
				{
					0u,									// VkSubpassDescriptionFlags	flags
					VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint			pipelineBindPoint
					0u,									// deUint32						inputAttachmentCount
					DE_NULL,							// const VkAttachmentReference*	pInputAttachments
					1u,									// deUint32						colorAttachmentCount
					&colorAttachmentReference,			// const VkAttachmentReference*	pColorAttachments
					&resolveAttachmentReference,		// const VkAttachmentReference*	pResolveAttachments
					&depthStencilAttachmentReference,	// const VkAttachmentReference*	pDepthStencilAttachment
					0u,									// deUint32						preserveAttachmentCount
					DE_NULL								// const VkAttachmentReference*	pPreserveAttachments
				};

				const VkSubpassDependency	subpassDependency	=
				{
					0u,												// deUint32				srcSubpass
					1u,												// deUint32				dstSubpass
					VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,		// VkPipelineStageFlags	srcStageMask
					VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,		// VkPipelineStageFlags	dstStageMask
					VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,	// VkAccessFlags		srcAccessMask
					VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,	// VkAccessFlags		dstAccessMask
					0u												// VkDependencyFlags	dependencyFlags
				};

				subpassDescriptions.push_back(subpassDescription0);
				subpassDescriptions.push_back(subpassDescription1);
				subpassDependencies.push_back(subpassDependency);
		}
		else if (m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT)
		{
			const VkSubpassDescription renderSubpassDescription =
			{
				0u,												// VkSubpassDescriptionFlags	flags
				VK_PIPELINE_BIND_POINT_GRAPHICS,				// VkPipelineBindPoint			pipelineBindPoint
				0u,												// deUint32						inputAttachmentCount
				DE_NULL,										// const VkAttachmentReference*	pInputAttachments
				2u,												// deUint32						colorAttachmentCount
				colorAttachmentReferencesUnusedAttachment,		// const VkAttachmentReference*	pColorAttachments
				resolveAttachmentReferencesUnusedAttachment,	// const VkAttachmentReference*	pResolveAttachments
				DE_NULL,										// const VkAttachmentReference*	pDepthStencilAttachment
				0u,												// deUint32						preserveAttachmentCount
				DE_NULL											// const VkAttachmentReference*	pPreserveAttachments
			};

			subpassDescriptions.push_back(renderSubpassDescription);
		}
		else
		{
			{
				const VkSubpassDescription renderSubpassDescription =
				{
					0u,																				// VkSubpassDescriptionFlags	flags;
					VK_PIPELINE_BIND_POINT_GRAPHICS,												// VkPipelineBindPoint			pipelineBindPoint;
					0u,																				// deUint32						inputAttachmentCount;
					DE_NULL,																		// const VkAttachmentReference*	pInputAttachments;
					1u,																				// deUint32						colorAttachmentCount;
					&colorAttachmentReference,														// const VkAttachmentReference*	pColorAttachments;
					usesResolveImage ? &resolveAttachmentReference : DE_NULL,						// const VkAttachmentReference*	pResolveAttachments;
					(m_useDepth || m_useStencil ? &depthStencilAttachmentReference : DE_NULL),		// const VkAttachmentReference*	pDepthStencilAttachment;
					0u,																				// deUint32						preserveAttachmentCount;
					DE_NULL																			// const VkAttachmentReference*	pPreserveAttachments;
				};
				subpassDescriptions.push_back(renderSubpassDescription);
			}

			if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
			{

				for (size_t i = 0; i < m_perSampleImages.size(); ++i)
				{
					const VkSubpassDescription copySampleSubpassDescription =
					{
						0u,													// VkSubpassDescriptionFlags		flags;
						VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
						1u,													// deUint32							inputAttachmentCount;
						&inputAttachmentReference,							// const VkAttachmentReference*		pInputAttachments;
						1u,													// deUint32							colorAttachmentCount;
						&perSampleAttachmentReferences[i],					// const VkAttachmentReference*		pColorAttachments;
						DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
						DE_NULL,											// const VkAttachmentReference*		pDepthStencilAttachment;
						0u,													// deUint32							preserveAttachmentCount;
						DE_NULL												// const VkAttachmentReference*		pPreserveAttachments;
					};
					subpassDescriptions.push_back(copySampleSubpassDescription);

					const VkSubpassDependency copySampleSubpassDependency =
					{
						0u,													// deUint32							srcSubpass
						1u + static_cast<deUint32>(i),						// 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
						0u,													// VkDependencyFlags				dependencyFlags
					};
					subpassDependencies.push_back(copySampleSubpassDependency);
				}
			}
		}

		const VkRenderPassCreateInfo renderPassParams =
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,					// VkStructureType					sType;
			DE_NULL,													// const void*						pNext;
			0u,															// VkRenderPassCreateFlags			flags;
			(deUint32)attachmentDescriptions.size(),					// deUint32							attachmentCount;
			&attachmentDescriptions[0],									// const VkAttachmentDescription*	pAttachments;
			(deUint32)subpassDescriptions.size(),						// deUint32							subpassCount;
			&subpassDescriptions[0],									// const VkSubpassDescription*		pSubpasses;
			(deUint32)subpassDependencies.size(),						// deUint32							dependencyCount;
			subpassDependencies.size() != 0 ? &subpassDependencies[0] : DE_NULL
		};

		m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
	}

	// Create framebuffer
	{
		std::vector<VkImageView> attachments;
		attachments.push_back(*m_colorAttachmentView);
		if (usesResolveImage)
		{
			attachments.push_back(*m_resolveAttachmentView);
		}
		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
		{
			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
			{
				attachments.push_back(*m_perSampleImages[i]->m_attachmentView);
			}
		}

		if (m_useDepth || m_useStencil)
		{
			attachments.push_back(*m_depthStencilAttachmentView);
		}

		const VkFramebufferCreateInfo framebufferParams =
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType					sType;
			DE_NULL,											// const void*						pNext;
			0u,													// VkFramebufferCreateFlags			flags;
			*m_renderPass,										// VkRenderPass						renderPass;
			(deUint32)attachments.size(),						// deUint32							attachmentCount;
			&attachments[0],									// const VkImageView*				pAttachments;
			(deUint32)m_renderSize.x(),							// deUint32							width;
			(deUint32)m_renderSize.y(),							// deUint32							height;
			1u													// deUint32							layers;
		};

		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
	}

	// Create pipeline layout
	{
		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
			DE_NULL,											// const void*						pNext;
			0u,													// VkPipelineLayoutCreateFlags		flags;
			0u,													// deUint32							setLayoutCount;
			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
			0u,													// deUint32							pushConstantRangeCount;
			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
		};

		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);

		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
		{

			// Create descriptor set layout
			const VkDescriptorSetLayoutBinding		layoutBinding					=
			{
				0u,															// deUint32								binding;
				VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,						// VkDescriptorType						descriptorType;
				1u,															// deUint32								descriptorCount;
				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlags					stageFlags;
				DE_NULL,													// const VkSampler*						pImmutableSamplers;
			};

			const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutParams		=
			{
				VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType						sType
				DE_NULL,													// const void*							pNext
				0u,															// VkDescriptorSetLayoutCreateFlags		flags
				1u,															// deUint32								bindingCount
				&layoutBinding												// const VkDescriptorSetLayoutBinding*	pBindings
			};
			m_copySampleDesciptorLayout	= createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);

			// Create pipeline layout

			const VkPushConstantRange				pushConstantRange				=
			{
				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlags					stageFlags;
				0u,															// deUint32								offset;
				sizeof(deInt32)												// deUint32								size;
			};
			const VkPipelineLayoutCreateInfo		copySamplePipelineLayoutParams	=
			{
				VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,				// VkStructureType						sType;
				DE_NULL,													// const void*							pNext;
				0u,															// VkPipelineLayoutCreateFlags			flags;
				1u,															// deUint32								setLayoutCount;
				&m_copySampleDesciptorLayout.get(),							// const VkDescriptorSetLayout*			pSetLayouts;
				1u,															// deUint32								pushConstantRangeCount;
				&pushConstantRange											// const VkPushConstantRange*			pPushConstantRanges;
			};
			m_copySamplePipelineLayout		= createPipelineLayout(vk, vkDevice, &copySamplePipelineLayoutParams);
		}
	}

	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);

	if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
	{
		m_copySampleVertexShaderModule		= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("quad_vert"), 0);
		m_copySampleFragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("copy_sample_frag"), 0);
	}

	// Create pipeline
	{
		const VkVertexInputBindingDescription	vertexInputBindingDescription =
		{
			0u,									// deUint32				binding;
			sizeof(Vertex4RGBA),				// deUint32				stride;
			VK_VERTEX_INPUT_RATE_VERTEX			// VkVertexInputRate	inputRate;
		};

		const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
		{
			{
				0u,									// deUint32	location;
				0u,									// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
				0u									// deUint32	offset;
			},
			{
				1u,									// deUint32	location;
				0u,									// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
				DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32	offset;
			}
		};

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

		const std::vector<VkViewport>	viewports		(1, makeViewport(m_renderSize));
		const std::vector<VkRect2D>		scissors		(1, makeRect2D(m_renderSize));

		const deUint32					attachmentCount	= m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT ? 2u : 1u;

		std::vector<VkPipelineColorBlendAttachmentState> attachments;

		for (deUint32 attachmentIdx = 0; attachmentIdx < attachmentCount; attachmentIdx++)
			attachments.push_back(m_colorBlendState);

		const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
			DE_NULL,													// const void*									pNext;
			0u,															// VkPipelineColorBlendStateCreateFlags			flags;
			false,														// VkBool32										logicOpEnable;
			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
			attachmentCount,											// deUint32										attachmentCount;
			attachments.data(),											// const VkPipelineColorBlendAttachmentState*	pAttachments;
			{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4];
		};

		const VkStencilOpState stencilOpState =
		{
			VK_STENCIL_OP_KEEP,						// VkStencilOp	failOp;
			VK_STENCIL_OP_REPLACE,					// VkStencilOp	passOp;
			VK_STENCIL_OP_KEEP,						// VkStencilOp	depthFailOp;
			VK_COMPARE_OP_GREATER,					// VkCompareOp	compareOp;
			1u,										// deUint32		compareMask;
			1u,										// deUint32		writeMask;
			1u,										// deUint32		reference;
		};

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

		const deUint32 numSubpasses = m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY ? 2u : 1u;

		for (deUint32 subpassIdx = 0; subpassIdx < numSubpasses; subpassIdx++)
			for (deUint32 i = 0u; i < numTopologies; ++i)
			{
				m_graphicsPipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(vk,							// const DeviceInterface&                        vk
																									   vkDevice,					// const VkDevice                                device
																									   *m_pipelineLayout,			// const VkPipelineLayout                        pipelineLayout
																									   *m_vertexShaderModule,		// const VkShaderModule                          vertexShaderModule
																									   DE_NULL,						// const VkShaderModule                          tessellationControlModule
																									   DE_NULL,						// const VkShaderModule                          tessellationEvalModule
																									   DE_NULL,						// const VkShaderModule                          geometryShaderModule
																									   *m_fragmentShaderModule,		// const VkShaderModule                          fragmentShaderModule
																									   *m_renderPass,				// const VkRenderPass                            renderPass
																									   viewports,					// const std::vector<VkViewport>&                viewports
																									   scissors,					// const std::vector<VkRect2D>&                  scissors
																									   pTopology[i],				// const VkPrimitiveTopology                     topology
																									   subpassIdx,					// const deUint32                                subpass
																									   0u,							// const deUint32                                patchControlPoints
																									   &vertexInputStateParams,		// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
																									   DE_NULL,						// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
																									   &m_multisampleStateParams,	// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
																									   &depthStencilStateParams,	// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
																									   &colorBlendStateParams))));	// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
			}
	}

	if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
	{
		// Create pipelines for copying samples to single sampled images
		{
			const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
			{
				VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
				DE_NULL,														// const void*								pNext;
				0u,																// VkPipelineVertexInputStateCreateFlags	flags;
				0u,																// deUint32									vertexBindingDescriptionCount;
				DE_NULL,														// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
				0u,																// deUint32									vertexAttributeDescriptionCount;
				DE_NULL															// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
			};

			const std::vector<VkViewport>	viewports	(1, makeViewport(m_renderSize));
			const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_renderSize));

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

			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
			{
				// Pipeline is to be used in subpasses subsequent to sample-shading subpass
				m_copySamplePipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(vk,									// const DeviceInterface&                        vk
																										 vkDevice,								// const VkDevice                                device
																										 *m_copySamplePipelineLayout,			// const VkPipelineLayout                        pipelineLayout
																										 *m_copySampleVertexShaderModule,		// const VkShaderModule                          vertexShaderModule
																										 DE_NULL,								// const VkShaderModule                          tessellationControlModule
																										 DE_NULL,								// const VkShaderModule                          tessellationEvalModule
																										 DE_NULL,								// const VkShaderModule                          geometryShaderModule
																										 *m_copySampleFragmentShaderModule,		// const VkShaderModule                          fragmentShaderModule
																										 *m_renderPass,							// const VkRenderPass                            renderPass
																										 viewports,								// const std::vector<VkViewport>&                viewports
																										 scissors,								// const std::vector<VkRect2D>&                  scissors
																										 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	// const VkPrimitiveTopology                     topology
																										 1u + (deUint32)i,						// const deUint32                                subpass
																										 0u,									// const deUint32                                patchControlPoints
																										 &vertexInputStateParams,				// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
																										 DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
																										 DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
																										 DE_NULL,								// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
																										 &colorBlendStateParams))));			// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
			}
		}


		const VkDescriptorPoolSize			descriptorPoolSize			=
		{
			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,					// VkDescriptorType					type;
			1u														// deUint32							descriptorCount;
		};

		const VkDescriptorPoolCreateInfo	descriptorPoolCreateInfo	=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,			// VkStructureType					sType
			DE_NULL,												// const void*						pNext
			VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,		// VkDescriptorPoolCreateFlags		flags
			1u,													// deUint32							maxSets
			1u,														// deUint32							poolSizeCount
			&descriptorPoolSize										// const VkDescriptorPoolSize*		pPoolSizes
		};

		m_copySampleDesciptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo);

		const VkDescriptorSetAllocateInfo	descriptorSetAllocateInfo	=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,			// VkStructureType					sType
			DE_NULL,												// const void*						pNext
			*m_copySampleDesciptorPool,								// VkDescriptorPool					descriptorPool
			1u,														// deUint32							descriptorSetCount
			&m_copySampleDesciptorLayout.get(),						// const VkDescriptorSetLayout*		pSetLayouts
		};

		m_copySampleDesciptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);

		const VkDescriptorImageInfo			imageInfo					=
		{
			DE_NULL,
			*m_colorAttachmentView,
			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
		};
		const VkWriteDescriptorSet			descriptorWrite				=
		{
			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,			// VkStructureType					sType;
			DE_NULL,										// const void*						pNext;
			*m_copySampleDesciptorSet,						// VkDescriptorSet					dstSet;
			0u,												// deUint32							dstBinding;
			0u,												// deUint32							dstArrayElement;
			1u,												// deUint32							descriptorCount;
			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,			// VkDescriptorType					descriptorType;
			&imageInfo,										// const VkDescriptorImageInfo*		pImageInfo;
			DE_NULL,										// const VkDescriptorBufferInfo*	pBufferInfo;
			DE_NULL,										// const VkBufferView*				pTexelBufferView;
		};
		vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL);
	}

	// Create vertex buffer
	{
		const VkBufferCreateInfo vertexBufferParams =
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			1024u,										// VkDeviceSize			size;
			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyIndexCount;
			&queueFamilyIndices[0]						// const deUint32*		pQueueFamilyIndices;
		};

		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));

		// Load vertices into vertex buffer
		{
			Vertex4RGBA* pDst = static_cast<Vertex4RGBA*>(m_vertexBufferAlloc->getHostPtr());

			if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
			{
				DE_ASSERT(numTopologies == 1);

				std::vector<Vertex4RGBA> vertices = pVertices[0];

				// Set alpha to zero for the first draw. This should prevent depth writes because of zero coverage.
				for (size_t i = 0; i < vertices.size(); i++)
					vertices[i].color.w() = 0.0f;

				deMemcpy(pDst, &vertices[0], vertices.size() * sizeof(Vertex4RGBA));

				pDst += vertices.size();

				// The second draw uses original vertices which are pure red.
				deMemcpy(pDst, &pVertices[0][0], pVertices[0].size() * sizeof(Vertex4RGBA));
			}
			else
			{
				for (deUint32 i = 0u; i < numTopologies; ++i)
				{
					deMemcpy(pDst, &pVertices[i][0], pVertices[i].size() * sizeof(Vertex4RGBA));
					pDst += pVertices[i].size();
				}
			}
		}
		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
	}

	// Create command pool
	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndices[0]);

	// Create command buffer
	{
		VkClearValue colorClearValue;
		if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
		{
			colorClearValue.color.float32[0] = 0.25;
			colorClearValue.color.float32[1] = 0.25;
			colorClearValue.color.float32[2] = 0.25;
			colorClearValue.color.float32[3] = 1.0f;
		}
		else
		{
			colorClearValue.color.float32[0] = 0.0f;
			colorClearValue.color.float32[1] = 0.0f;
			colorClearValue.color.float32[2] = 0.0f;
			colorClearValue.color.float32[3] = 0.0f;
		}

		VkClearValue depthStencilClearValue;
		depthStencilClearValue.depthStencil.depth = m_depthClearValue;
		depthStencilClearValue.depthStencil.stencil = 0u;

		std::vector<VkClearValue> clearValues;
		clearValues.push_back(colorClearValue);
		if (usesResolveImage)
		{
			clearValues.push_back(colorClearValue);
		}
		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
		{
			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
			{
				clearValues.push_back(colorClearValue);
			}
		}
		if (m_useDepth || m_useStencil)
		{
			clearValues.push_back(depthStencilClearValue);
		}

		vk::VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
		std::vector<VkImageMemoryBarrier> imageLayoutBarriers;

		{
			const VkImageMemoryBarrier colorImageBarrier =
			// color attachment image
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
				DE_NULL,										// const void*				pNext;
				0u,												// VkAccessFlags			srcAccessMask;
				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
				VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
				VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
				VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
				*m_colorImage,									// VkImage					image;
				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
			};
			imageLayoutBarriers.push_back(colorImageBarrier);
		}
		if (usesResolveImage)
		{
			const VkImageMemoryBarrier resolveImageBarrier =
			// resolve attachment image
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
				DE_NULL,										// const void*				pNext;
				0u,												// VkAccessFlags			srcAccessMask;
				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
				VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
				VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
				VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
				*m_resolveImage,								// VkImage					image;
				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
			};
			imageLayoutBarriers.push_back(resolveImageBarrier);
		}
		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
		{
			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
			{
				const VkImageMemoryBarrier perSampleImageBarrier =
				// resolve attachment image
				{
					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
					DE_NULL,										// const void*				pNext;
					0u,												// VkAccessFlags			srcAccessMask;
					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
					VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
					VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
					VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
					*m_perSampleImages[i]->m_image,					// VkImage					image;
					{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
				};
				imageLayoutBarriers.push_back(perSampleImageBarrier);
			}
		}
		if (m_useDepth || m_useStencil)
		{
			const VkImageMemoryBarrier depthStencilImageBarrier =
			// depth/stencil attachment image
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
				DE_NULL,											// const void*				pNext;
				0u,													// VkAccessFlags			srcAccessMask;
				VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
				VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
				VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
				VK_QUEUE_FAMILY_IGNORED,							// deUint32					dstQueueFamilyIndex;
				*m_depthStencilImage,								// VkImage					image;
				{ depthStencilAttachmentAspect, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
			};
			imageLayoutBarriers.push_back(depthStencilImageBarrier);
			dstStageMask |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
		};

		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

		beginCommandBuffer(vk, *m_cmdBuffer, 0u);

		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, dstStageMask, (VkDependencyFlags)0,
			0u, DE_NULL, 0u, DE_NULL, (deUint32)imageLayoutBarriers.size(), &imageLayoutBarriers[0]);

		beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), (deUint32)clearValues.size(), &clearValues[0]);

		VkDeviceSize vertexBufferOffset = 0u;

		for (deUint32 i = 0u; i < numTopologies; ++i)
		{
			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_graphicsPipelines[i]);
			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
			vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[i].size(), 1, 0, 0);

			vertexBufferOffset += static_cast<VkDeviceSize>(pVertices[i].size() * sizeof(Vertex4RGBA));
		}

		if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
		{
			// The first draw was without color buffer and zero coverage. The depth buffer is expected to still have the clear value.
			vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_graphicsPipelines[1]);
			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
			// The depth test should pass as the first draw didn't touch the depth buffer.
			vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[0].size(), 1, 0, 0);
		}
		else if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
		{
			// Copy each sample id to single sampled image
			for (deInt32 sampleId = 0; sampleId < (deInt32)m_perSampleImages.size(); ++sampleId)
			{
				vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
				vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_copySamplePipelines[sampleId]);
				vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_copySamplePipelineLayout, 0u, 1u, &m_copySampleDesciptorSet.get(), 0u, DE_NULL);
				vk.cmdPushConstants(*m_cmdBuffer, *m_copySamplePipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(deInt32), &sampleId);
				vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
			}
		}

		endRenderPass(vk, *m_cmdBuffer);

		endCommandBuffer(vk, *m_cmdBuffer);
	}
}

MultisampleRenderer::~MultisampleRenderer (void)
{
}

de::MovePtr<tcu::TextureLevel> MultisampleRenderer::render (void)
{
	const DeviceInterface&		vk					= m_context.getDeviceInterface();
	const VkDevice				vkDevice			= m_context.getDevice();
	const VkQueue				queue				= m_context.getUniversalQueue();
	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();

	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());

	if (m_renderType == RENDER_TYPE_RESOLVE || m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY || m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT)
	{
		return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *m_resolveImage, m_colorFormat, m_renderSize.cast<deUint32>());
	}
	else
	{
		return de::MovePtr<tcu::TextureLevel>();
	}
}

de::MovePtr<tcu::TextureLevel> MultisampleRenderer::getSingleSampledImage (deUint32 sampleId)
{
	return readColorAttachment(m_context.getDeviceInterface(), m_context.getDevice(), m_context.getUniversalQueue(), m_context.getUniversalQueueFamilyIndex(), m_context.getDefaultAllocator(), *m_perSampleImages[sampleId]->m_image, m_colorFormat, m_renderSize.cast<deUint32>());
}

} // anonymous

tcu::TestCaseGroup* createMultisampleTests (tcu::TestContext& testCtx)
{
	const VkSampleCountFlagBits samples[] =
	{
		VK_SAMPLE_COUNT_2_BIT,
		VK_SAMPLE_COUNT_4_BIT,
		VK_SAMPLE_COUNT_8_BIT,
		VK_SAMPLE_COUNT_16_BIT,
		VK_SAMPLE_COUNT_32_BIT,
		VK_SAMPLE_COUNT_64_BIT
	};

	de::MovePtr<tcu::TestCaseGroup> multisampleTests (new tcu::TestCaseGroup(testCtx, "multisample", ""));

	// Rasterization samples tests
	{
		de::MovePtr<tcu::TestCaseGroup> rasterizationSamplesTests(new tcu::TestCaseGroup(testCtx, "raster_samples", ""));

		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
		{
			std::ostringstream caseName;
			caseName << "samples_" << samples[samplesNdx];

			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));

			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_1px", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR));
			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR));

			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_DEPTH_BIT));
			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_STENCIL_BIT));
			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_stencil", "",	samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_DEPTH_BIT | TEST_MODE_STENCIL_BIT));

			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle_sparse", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line_sparse", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_1px_sparse", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE));
			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_sparse", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE));

			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_sparse", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_DEPTH_BIT));
			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil_sparse", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_STENCIL_BIT));
			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_stencil_sparse", "",	samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_DEPTH_BIT | TEST_MODE_STENCIL_BIT));

			rasterizationSamplesTests->addChild(samplesTests.release());
		}

		multisampleTests->addChild(rasterizationSamplesTests.release());
	}

	// Raster samples consistency check
	{
		de::MovePtr<tcu::TestCaseGroup> rasterSamplesConsistencyTests	(new tcu::TestCaseGroup(testCtx, "raster_samples_consistency", ""));
		MultisampleTestParams			paramsRegular					= {GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR};
		MultisampleTestParams			paramsSparse					= {GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE};

		addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(),
									"unique_colors_check",
									"",
									initMultisamplePrograms,
									testRasterSamplesConsistency,
									paramsRegular);

		addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(),
									"unique_colors_check_sparse",
									"",
									initMultisamplePrograms,
									testRasterSamplesConsistency,
									paramsSparse);

		multisampleTests->addChild(rasterSamplesConsistencyTests.release());
	}

	// minSampleShading tests
	{
		struct TestConfig
		{
			const char*	name;
			float		minSampleShading;
		};

		const TestConfig testConfigs[] =
		{
			{ "min_0_0",	0.0f },
			{ "min_0_25",	0.25f },
			{ "min_0_5",	0.5f },
			{ "min_0_75",	0.75f },
			{ "min_1_0",	1.0f }
		};

		de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading", ""));

		for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
		{
			const TestConfig&				testConfig				= testConfigs[configNdx];
			de::MovePtr<tcu::TestCaseGroup>	minShadingValueTests	(new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));

			for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
			{
				std::ostringstream caseName;
				caseName << "samples_" << samples[samplesNdx];

				de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));

				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_1px", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR));
				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR));

				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle_sparse", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line_sparse", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_1px_sparse", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE));
				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_sparse", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE));

				minShadingValueTests->addChild(samplesTests.release());
			}

			minSampleShadingTests->addChild(minShadingValueTests.release());
		}

		multisampleTests->addChild(minSampleShadingTests.release());
	}

	// SampleMask tests
	{
		struct TestConfig
		{
			const char*		name;
			const char*		description;
			VkSampleMask	sampleMask;
		};

		const TestConfig testConfigs[] =
		{
			{ "mask_all_on",	"All mask bits are off",			0x0 },
			{ "mask_all_off",	"All mask bits are on",				0xFFFFFFFF },
			{ "mask_one",		"All mask elements are 0x1",		0x1},
			{ "mask_random",	"All mask elements are 0xAAAAAAAA",	0xAAAAAAAA },
		};

		de::MovePtr<tcu::TestCaseGroup> sampleMaskTests(new tcu::TestCaseGroup(testCtx, "sample_mask", ""));

		for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
		{
			const TestConfig&				testConfig				= testConfigs[configNdx];
			de::MovePtr<tcu::TestCaseGroup>	sampleMaskValueTests	(new tcu::TestCaseGroup(testCtx, testConfig.name, testConfig.description));

			for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
			{
				std::ostringstream caseName;
				caseName << "samples_" << samples[samplesNdx];

				const deUint32					sampleMaskCount	= samples[samplesNdx] / 32;
				de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));

				std::vector<VkSampleMask> mask;
				for (deUint32 maskNdx = 0; maskNdx < sampleMaskCount; maskNdx++)
					mask.push_back(testConfig.sampleMask);

				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_1px", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR));
				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR));

				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_1px_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE));
				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE));

				sampleMaskValueTests->addChild(samplesTests.release());
			}

			sampleMaskTests->addChild(sampleMaskValueTests.release());
		}

		multisampleTests->addChild(sampleMaskTests.release());

	}

	// AlphaToOne tests
	{
		de::MovePtr<tcu::TestCaseGroup> alphaToOneTests(new tcu::TestCaseGroup(testCtx, "alpha_to_one", ""));

		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
		{
			std::ostringstream caseName;
			caseName << "samples_" << samples[samplesNdx];

			alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", samples[samplesNdx], IMAGE_BACKING_MODE_REGULAR));

			caseName << "_sparse";
			alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", samples[samplesNdx], IMAGE_BACKING_MODE_SPARSE));
		}

		multisampleTests->addChild(alphaToOneTests.release());
	}

	// AlphaToCoverageEnable tests
	{
		de::MovePtr<tcu::TestCaseGroup> alphaToCoverageTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage", ""));

		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
		{
			std::ostringstream caseName;
			caseName << "samples_" << samples[samplesNdx];

			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));

			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR));
			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent", "", samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD, IMAGE_BACKING_MODE_REGULAR));
			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_REGULAR));

			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE));
			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD, IMAGE_BACKING_MODE_SPARSE));
			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_SPARSE));

			alphaToCoverageTests->addChild(samplesTests.release());
		}
		multisampleTests->addChild(alphaToCoverageTests.release());
	}

	// AlphaToCoverageEnable without color buffer tests
	{
		de::MovePtr<tcu::TestCaseGroup> alphaToCoverageNoColorAttachmentTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage_no_color_attachment", ""));

		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
		{
			std::ostringstream caseName;
			caseName << "samples_" << samples[samplesNdx];

			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));

			samplesTests->addChild(new AlphaToCoverageNoColorAttachmentTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR));
			samplesTests->addChild(new AlphaToCoverageNoColorAttachmentTest(testCtx, "alpha_opaque_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE));

			alphaToCoverageNoColorAttachmentTests->addChild(samplesTests.release());
		}
		multisampleTests->addChild(alphaToCoverageNoColorAttachmentTests.release());
	}

	// AlphaToCoverageEnable with unused color attachment:
	// Set color output at location 0 as unused, but use the alpha write to control coverage for rendering to color buffer at location 1.
	{
		de::MovePtr<tcu::TestCaseGroup> alphaToCoverageColorUnusedAttachmentTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage_unused_attachment", ""));

		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
		{
			std::ostringstream caseName;
			caseName << "samples_" << samples[samplesNdx];

			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));

			samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR));
			samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_opaque_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE));
			samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_invisible", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_REGULAR));
			samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_invisible_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_SPARSE));

			alphaToCoverageColorUnusedAttachmentTests->addChild(samplesTests.release());
		}
		multisampleTests->addChild(alphaToCoverageColorUnusedAttachmentTests.release());
	}

	// Sampling from a multisampled image texture (texelFetch)
	{
		multisampleTests->addChild(createMultisampleSampledImageTests(testCtx));
	}

	// Load/store on a multisampled rendered image (different kinds of access: color attachment write, storage image, etc.)
	{
		multisampleTests->addChild(createMultisampleStorageImageTests(testCtx));
	}

	// VK_EXT_sample_locations
	{
		multisampleTests->addChild(createMultisampleSampleLocationsExtTests(testCtx));
	}

	// Sample mask with and without vk_ext_post_depth_coverage
	{
		const vk::VkSampleCountFlagBits standardSamplesSet[] =
		{
			vk::VK_SAMPLE_COUNT_2_BIT,
			vk::VK_SAMPLE_COUNT_4_BIT,
			vk::VK_SAMPLE_COUNT_8_BIT,
			vk::VK_SAMPLE_COUNT_16_BIT
		};

		de::MovePtr<tcu::TestCaseGroup> sampleMaskWithDepthTestGroup(new tcu::TestCaseGroup(testCtx, "sample_mask_with_depth_test", ""));

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(standardSamplesSet); ++ndx)
		{
			std::ostringstream caseName;
			caseName << "samples_" << standardSamplesSet[ndx];

			sampleMaskWithDepthTestGroup->addChild(new SampleMaskWithDepthTestTest(testCtx, caseName.str(), "", standardSamplesSet[ndx]));

			caseName << "_post_depth_coverage";
			sampleMaskWithDepthTestGroup->addChild(new SampleMaskWithDepthTestTest(testCtx, caseName.str(), "", standardSamplesSet[ndx], true));

		}
		multisampleTests->addChild(sampleMaskWithDepthTestGroup.release());
	}

	return multisampleTests.release();
}

} // pipeline
} // vkt
