/*------------------------------------------------------------------------
 * 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 "vktPipelineMultisampleMixedAttachmentSamplesTests.hpp"
#include "vktPipelineMultisampleShaderFragmentMaskTests.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									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;
	virtual void								checkSupport						(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,
																					 const bool				minSampleShadingEnabled = true);
	virtual										~MinSampleShadingTest				(void) {}

protected:
	virtual void								initPrograms						(SourceCollections& programCollection) const;
	virtual void								checkSupport						(Context& context) 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,
																					 bool					minSampleShadingEnabled);

	const float									m_pointSize;
	const ImageBackingMode						m_backingMode;
	const bool									m_minSampleShadingEnabled;
};

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 void								checkSupport					(Context& context) const;
	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;
	virtual void								checkSupport					(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 MinSampleShadingDisabledInstance : public MinSampleShadingInstance
{
public:
												MinSampleShadingDisabledInstance	(Context&										context,
																					 VkPrimitiveTopology							topology,
																					 float											pointSize,
																					 const std::vector<Vertex4RGBA>&				vertices,
																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																					 const VkPipelineColorBlendAttachmentState&		blendState,
																					 ImageBackingMode								backingMode);
	virtual										~MinSampleShadingDisabledInstance	(void) {}

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

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

void MultisampleTest::checkSupport (Context& context) const
{
	if (m_geometryType == GEOMETRY_TYPE_OPAQUE_POINT && m_pointSize > 1.0f)
		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LARGE_POINTS);
}

// 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,
											const bool				minSampleShadingEnabled)
	: MultisampleTest			(testContext, name, description, getMinSampleShadingStateParams(rasterizationSamples, minSampleShading, minSampleShadingEnabled), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode)
	, m_pointSize				(pointSize)
	, m_backingMode				(backingMode)
	, m_minSampleShadingEnabled	(minSampleShadingEnabled)
{
}

void MinSampleShadingTest::checkSupport (Context& context) const
{
	MultisampleTest::checkSupport(context);

	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING);
}

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
{
	if (m_minSampleShadingEnabled)
		return new MinSampleShadingInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode);
	else
		return new MinSampleShadingDisabledInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode);
}

VkPipelineMultisampleStateCreateInfo MinSampleShadingTest::getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples, float minSampleShading, bool minSampleShadingEnabled)
{
	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,													// const void*								pNext;
		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
		minSampleShadingEnabled ? VK_TRUE : VK_FALSE,				// 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)
{
}

void AlphaToOneTest::checkSupport (Context& context) const
{
	MultisampleTest::checkSupport(context);

	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_ALPHA_TO_ONE);
}

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::checkSupport (Context& context) const
{
	if (!context.getDeviceProperties().limits.standardSampleLocations)
		TCU_THROW(NotSupportedError, "standardSampleLocations required");

	context.requireDeviceFunctionality("VK_EXT_post_depth_coverage");
}

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

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

MinSampleShadingDisabledInstance::MinSampleShadingDisabledInstance	(Context&										context,
																	 VkPrimitiveTopology							topology,
																	 float											pointSize,
																	 const std::vector<Vertex4RGBA>&				vertices,
																	 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
																	 const VkPipelineColorBlendAttachmentState&		blendState,
																	 ImageBackingMode								backingMode)
	: MinSampleShadingInstance	(context, topology, pointSize, vertices, multisampleStateParams, blendState, backingMode)
{
}

tcu::TestStatus MinSampleShadingDisabledInstance::verifySampleShadedImage	(const std::vector<tcu::TextureLevel>&	sampleShadedImages,
																			 const tcu::ConstPixelBufferAccess&		noSampleshadingImage)
{
	const deUint32		samplesCount		= (int)sampleShadedImages.size();
	const deUint32		width				= noSampleshadingImage.getWidth();
	const deUint32		height				= noSampleshadingImage.getHeight();
	const deUint32		depth				= noSampleshadingImage.getDepth();
	const tcu::UVec4	zeroPixel			= tcu::UVec4();
	bool				anyPixelCovered		= false;

	DE_ASSERT(depth == 1);
	DE_UNREF(depth);

	for (deUint32 y = 0; y < height; ++y)
	for (deUint32 x = 0; x < width; ++x)
	{
		const tcu::UVec4	noSampleShadingValue	= noSampleshadingImage.getPixelUint(x, y);

		if (noSampleShadingValue == zeroPixel)
			continue;

		anyPixelCovered = true;
		tcu::UVec4	sampleShadingValue	= tcu::UVec4();

		// Collect histogram of occurrences or each pixel across all samples
		for (size_t i = 0; i < samplesCount; ++i)
		{
			const tcu::UVec4	sampleShadedValue	= sampleShadedImages[i].getAccess().getPixelUint(x, y);

			sampleShadingValue += sampleShadedValue;
		}

		sampleShadingValue = sampleShadingValue / samplesCount;

		if (sampleShadingValue.w() != 255)
		{
			return tcu::TestStatus::fail("Invalid Alpha channel value");
		}

		if (sampleShadingValue != noSampleShadingValue)
		{
			return tcu::TestStatus::fail("Invalid color");
		}
	}

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

	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)
{
	DE_UNREF(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)
{
}

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

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

			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, "quad",	"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_QUAD, 1.0f, IMAGE_BACKING_MODE_REGULAR, true));

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

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

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

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

			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, "quad",	"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_QUAD, 1.0f, IMAGE_BACKING_MODE_REGULAR, false));

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

	// VK_AMD_mixed_attachment samples and VK_AMD_shader_fragment_mask
	{
		multisampleTests->addChild(createMultisampleMixedAttachmentSamplesTests(testCtx));
		multisampleTests->addChild(createMultisampleShaderFragmentMaskTests(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
