/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * 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 Tests for render pass multisample resolve
 *//*--------------------------------------------------------------------*/

#include "vktRenderPassMultisampleResolveTests.hpp"
#include "vktRenderPassTestsUtil.hpp"

#include "vktTestCaseUtil.hpp"
#include "vktTestGroupUtil.hpp"

#include "vkDefs.hpp"
#include "vkDeviceUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkPlatform.hpp"
#include "vkPrograms.hpp"
#include "vkQueryUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"

#include "tcuFloat.hpp"
#include "tcuImageCompare.hpp"
#include "tcuFormatUtil.hpp"
#include "tcuMaybe.hpp"
#include "tcuResultCollector.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuStringTemplate.hpp"

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

using namespace vk;

using tcu::BVec4;
using tcu::IVec2;
using tcu::IVec4;
using tcu::UVec2;
using tcu::UVec4;
using tcu::Vec2;
using tcu::Vec3;
using tcu::Vec4;

using tcu::ConstPixelBufferAccess;
using tcu::PixelBufferAccess;
using tcu::TestLog;

using std::vector;

typedef de::SharedPtr<Allocation>							AllocationSp;
typedef de::SharedPtr<vk::Unique<VkImage> >					VkImageSp;
typedef de::SharedPtr<vk::Unique<VkImageView> >				VkImageViewSp;
typedef de::SharedPtr<vk::Unique<VkBuffer> >				VkBufferSp;
typedef de::SharedPtr<vk::Unique<VkSampler> >				VkSamplerSp;
typedef de::SharedPtr<vk::Unique<VkPipeline> >				VkPipelineSp;
typedef de::SharedPtr<vk::Unique<VkDescriptorSetLayout> >	VkDescriptorSetLayoutSp;
typedef de::SharedPtr<vk::Unique<VkDescriptorPool> >		VkDescriptorPoolSp;
typedef de::SharedPtr<vk::Unique<VkDescriptorSet> >			VkDescriptorSetSp;

namespace vkt
{
namespace
{

using namespace renderpass;

template<typename T>
de::SharedPtr<T> safeSharedPtr (T* ptr)
{
	try
	{
		return de::SharedPtr<T>(ptr);
	}
	catch (...)
	{
		delete ptr;
		throw;
	}
}

enum TestType
{
	RESOLVE			= 0,
	MAX_ATTACHMENTS,
};

struct TestConfig
{
	TestType		testType;
	VkFormat		format;
	deUint32		sampleCount;
	deUint32		layerCount;
	deUint32		attachmentCount;
	deUint32		width;
	deUint32		height;
	RenderPassType	renderPassType;
};

// Render pass traits that groups render pass related types together and by that help
// to reduce number of template parrameters passed to number of functions in those tests
struct RenderPass1Trait
{
	typedef AttachmentDescription1	AttDesc;
	typedef AttachmentReference1	AttRef;
	typedef SubpassDescription1		SubpassDesc;
	typedef SubpassDependency1		SubpassDep;
	typedef RenderPassCreateInfo1	RenderPassCreateInfo;
};
struct RenderPass2Trait
{
	typedef AttachmentDescription2	AttDesc;
	typedef AttachmentReference2	AttRef;
	typedef SubpassDescription2		SubpassDesc;
	typedef SubpassDependency2		SubpassDep;
	typedef RenderPassCreateInfo2	RenderPassCreateInfo;
};

class MultisampleRenderPassTestBase : public TestInstance
{
public:
	MultisampleRenderPassTestBase	(Context& context, TestConfig config, deUint32 attachmentsCount);
	~MultisampleRenderPassTestBase	(void);

protected:

	Move<VkImage>			createImage			(VkSampleCountFlagBits		sampleCountBit,
												 VkImageUsageFlags			usage) const;
	vector<VkImageSp>		createImages		(VkSampleCountFlagBits		sampleCountBit,
												 VkImageUsageFlags			usage) const;
	vector<AllocationSp>	createImageMemory	(const vector<VkImageSp>&	images) const;
	vector<VkImageViewSp>	createImageViews	(const vector<VkImageSp>&	images) const;

	vector<VkBufferSp>		createBuffers		() const;
	vector<AllocationSp>	createBufferMemory	(const vector<VkBufferSp>& buffers) const;

	Move<VkFramebuffer>		createFramebuffer	(const std::vector<VkImageViewSp>	multisampleImageViews,
												 const std::vector<VkImageViewSp>	singlesampleImageViews,
												 VkRenderPass						renderPass) const;

	bool					featuresSupported				(Context& context, TestConfig config) const;
	void					clearAttachments				(VkCommandBuffer commandBuffer) const;
	VkDeviceSize			getPixelSize					() const;
	tcu::Vec4				getFormatThreshold				() const;
	VkSampleCountFlagBits	sampleCountBitFromSampleCount	(deUint32 count) const;
	void					logImage						(const std::string& name,
															 const tcu::ConstPixelBufferAccess& image) const;

protected:

	const bool						m_featuresSupported;
	const bool						m_extensionSupported;
	const RenderPassType			m_renderPassType;

	const VkFormat					m_format;
	const VkSampleCountFlagBits		m_sampleCount;
	const deUint32					m_layerCount;
	const deUint32					m_attachmentsCount;
	const deUint32					m_width;
	const deUint32					m_height;
};

MultisampleRenderPassTestBase::MultisampleRenderPassTestBase (Context& context, TestConfig config, deUint32 attachmentsCount)
	: TestInstance				(context)
	, m_featuresSupported		(featuresSupported(context, config))
	, m_extensionSupported		((config.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceExtension("VK_KHR_create_renderpass2"))
	, m_renderPassType			(config.renderPassType)
	, m_format					(config.format)
	, m_sampleCount				(sampleCountBitFromSampleCount(config.sampleCount))
	, m_layerCount				(config.layerCount)
	, m_attachmentsCount		(attachmentsCount)
	, m_width					(config.width)
	, m_height					(config.height)
{
}

MultisampleRenderPassTestBase::~MultisampleRenderPassTestBase ()
{
}

Move<VkImage> MultisampleRenderPassTestBase::createImage (VkSampleCountFlagBits sampleCountBit, VkImageUsageFlags usage) const
{
	const InstanceInterface&		vki						= m_context.getInstanceInterface();
	const DeviceInterface&			vkd						= m_context.getDeviceInterface();
	VkDevice						device					= m_context.getDevice();
	VkPhysicalDevice				physicalDevice			= m_context.getPhysicalDevice();
	const tcu::TextureFormat		format					(mapVkFormat(m_format));
	const VkImageType				imageType				(VK_IMAGE_TYPE_2D);
	const VkImageTiling				imageTiling				(VK_IMAGE_TILING_OPTIMAL);
	const VkFormatProperties		formatProperties		(getPhysicalDeviceFormatProperties(vki, physicalDevice, m_format));
	const VkExtent3D				imageExtent =
	{
		m_width,
		m_height,
		1u
	};

	try
	{
		const VkImageFormatProperties	imageFormatProperties(getPhysicalDeviceImageFormatProperties(vki, physicalDevice, m_format, imageType, imageTiling, usage, 0u));

		if ((tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
			&& (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)
			TCU_THROW(NotSupportedError, "Format can't be used as depth stencil attachment");

		if (!(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
			&& (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
			TCU_THROW(NotSupportedError, "Format can't be used as color attachment");

		if (imageFormatProperties.maxExtent.width < imageExtent.width
			|| imageFormatProperties.maxExtent.height < imageExtent.height
			|| ((imageFormatProperties.sampleCounts & m_sampleCount) == 0)
			|| imageFormatProperties.maxArrayLayers < m_layerCount)
		{
			TCU_THROW(NotSupportedError, "Image type not supported");
		}

		const VkImageCreateInfo pCreateInfo =
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
			DE_NULL,
			0u,
			imageType,
			m_format,
			imageExtent,
			1u,
			m_layerCount,
			sampleCountBit,
			imageTiling,
			usage,
			VK_SHARING_MODE_EXCLUSIVE,
			0u,
			DE_NULL,
			VK_IMAGE_LAYOUT_UNDEFINED
		};

		return ::createImage(vkd, device, &pCreateInfo);
	}
	catch (const vk::Error& error)
	{
		if (error.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
			TCU_THROW(NotSupportedError, "Image format not supported");

		throw;
	}
}

vector<VkImageSp> MultisampleRenderPassTestBase::createImages (VkSampleCountFlagBits sampleCountBit, VkImageUsageFlags usage) const
{
	std::vector<VkImageSp> images (m_attachmentsCount);
	for (size_t imageNdx = 0; imageNdx < m_attachmentsCount; imageNdx++)
		images[imageNdx] = safeSharedPtr(new Unique<VkImage>(createImage(sampleCountBit, usage)));
	return images;
}

vector<AllocationSp> MultisampleRenderPassTestBase::createImageMemory (const vector<VkImageSp>& images) const
{
	const DeviceInterface&		vkd			= m_context.getDeviceInterface();
	VkDevice					device		= m_context.getDevice();
	Allocator&					allocator	= m_context.getDefaultAllocator();
	std::vector<AllocationSp>	memory		(images.size());

	for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
	{
		VkImage					image			= **images[memoryNdx];
		VkMemoryRequirements	requirements	= getImageMemoryRequirements(vkd, device, image);

		de::MovePtr<Allocation>	allocation		(allocator.allocate(requirements, MemoryRequirement::Any));
		VK_CHECK(vkd.bindImageMemory(device, image, allocation->getMemory(), allocation->getOffset()));
		memory[memoryNdx] = safeSharedPtr(allocation.release());
	}
	return memory;
}

vector<VkImageViewSp> MultisampleRenderPassTestBase::createImageViews (const vector<VkImageSp>& images) const
{
	const DeviceInterface&			vkd		= m_context.getDeviceInterface();
	VkDevice						device	= m_context.getDevice();
	std::vector<VkImageViewSp>		views	(images.size());
	const VkImageSubresourceRange	range =
	{
		VK_IMAGE_ASPECT_COLOR_BIT,
		0u,
		1u,
		0u,
		m_layerCount
	};

	for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
	{
		const VkImageViewCreateInfo pCreateInfo =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
			DE_NULL,
			0u,
			**images[imageNdx],
			VK_IMAGE_VIEW_TYPE_2D_ARRAY,
			m_format,
			makeComponentMappingRGBA(),
			range,
		};
		views[imageNdx] = safeSharedPtr(new Unique<VkImageView>(createImageView(vkd, device, &pCreateInfo)));
	}

	return views;
}

vector<VkBufferSp> MultisampleRenderPassTestBase::createBuffers () const
{
	const DeviceInterface&		vkd			= m_context.getDeviceInterface();
	VkDevice					device		= m_context.getDevice();
	std::vector<VkBufferSp>		buffers		(m_attachmentsCount);
	const VkDeviceSize			pixelSize	(getPixelSize());
	const VkBufferCreateInfo	createInfo =
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
		DE_NULL,
		0u,

		m_width * m_height * m_layerCount * pixelSize,
		VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,

		VK_SHARING_MODE_EXCLUSIVE,
		0u,
		DE_NULL
	};

	for (size_t bufferNdx = 0; bufferNdx < buffers.size(); bufferNdx++)
		buffers[bufferNdx] = safeSharedPtr(new Unique<VkBuffer>(createBuffer(vkd, device, &createInfo)));

	return buffers;
}

vector<AllocationSp> MultisampleRenderPassTestBase::createBufferMemory (const vector<VkBufferSp>& buffers) const
{
	const DeviceInterface&					vkd			= m_context.getDeviceInterface();
	VkDevice								device		= m_context.getDevice();
	Allocator&								allocator	= m_context.getDefaultAllocator();
	std::vector<de::SharedPtr<Allocation> >	memory		(buffers.size());

	for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
	{
		VkBuffer				buffer			= **buffers[memoryNdx];
		VkMemoryRequirements	requirements	= getBufferMemoryRequirements(vkd, device, buffer);
		de::MovePtr<Allocation> allocation		(allocator.allocate(requirements, MemoryRequirement::HostVisible));

		VK_CHECK(vkd.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
		memory[memoryNdx] = safeSharedPtr(allocation.release());
	}
	return memory;
}

Move<VkFramebuffer> MultisampleRenderPassTestBase::createFramebuffer (const std::vector<VkImageViewSp>	multisampleImageViews,
																	  const std::vector<VkImageViewSp>	singlesampleImageViews,
																	  VkRenderPass						renderPass) const
{
	const DeviceInterface&	vkd		= m_context.getDeviceInterface();
	VkDevice				device	= m_context.getDevice();

	std::vector<VkImageView> attachments;
	attachments.reserve(multisampleImageViews.size() + singlesampleImageViews.size());

	DE_ASSERT(multisampleImageViews.size() == singlesampleImageViews.size());

	for (size_t ndx = 0; ndx < multisampleImageViews.size(); ndx++)
	{
		attachments.push_back(**multisampleImageViews[ndx]);
		attachments.push_back(**singlesampleImageViews[ndx]);
	}

	const VkFramebufferCreateInfo createInfo =
	{
		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
		DE_NULL,
		0u,

		renderPass,
		(deUint32)attachments.size(),
		&attachments[0],

		m_width,
		m_height,
		m_layerCount
	};

	return ::createFramebuffer(vkd, device, &createInfo);
}

bool MultisampleRenderPassTestBase::featuresSupported (Context& context, TestConfig config) const
{
	bool result = ((config.layerCount > 1) && context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER));

	const InstanceInterface&				vki				= context.getInstanceInterface();
	vk::VkPhysicalDevice					physicalDevice	= context.getPhysicalDevice();
	const vk::VkPhysicalDeviceProperties	properties		= vk::getPhysicalDeviceProperties(vki, physicalDevice);

	if (config.attachmentCount > properties.limits.maxColorAttachments)
		TCU_THROW(NotSupportedError, "Required number of color attachments not supported.");

	return result;
}

void MultisampleRenderPassTestBase::clearAttachments (VkCommandBuffer commandBuffer) const
{
	const DeviceInterface&			vkd				= m_context.getDeviceInterface();
	const tcu::TextureFormat		format			(mapVkFormat(m_format));
	const tcu::TextureChannelClass	channelClass	(tcu::getTextureChannelClass(format.type));
	VkClearValue					value;

	// Clear everything to black
	switch (channelClass)
	{
		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
			value = makeClearValueColorF32(-1.0f, -1.0f, -1.0f, -1.0f);
			break;

		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
			value = makeClearValueColorF32(0.0f, 0.0f, 0.0f, 0.0f);
			break;

		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
			value = makeClearValueColorF32(-1.0f, -1.0f, -1.0f, -1.0f);
			break;

		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
			value = makeClearValueColorI32(-128, -128, -128, -128);
			break;

		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
			value = makeClearValueColorU32(0u, 0u, 0u, 0u);
			break;

		default:
			DE_FATAL("Unknown channel class");
	}
	std::vector<VkClearAttachment> colors(m_attachmentsCount);
	for (deUint32 attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
	{
		colors[attachmentNdx].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
		colors[attachmentNdx].colorAttachment = attachmentNdx;
		colors[attachmentNdx].clearValue = value;
	}
	const VkClearRect rect =
	{
		{
			{ 0u, 0u },
			{ m_width, m_height }
		},
		0u,
		m_layerCount,
	};
	vkd.cmdClearAttachments(commandBuffer, deUint32(colors.size()), &colors[0], 1u, &rect);
}

VkDeviceSize MultisampleRenderPassTestBase::getPixelSize () const
{
	const tcu::TextureFormat format(mapVkFormat(m_format));
	return format.getPixelSize();
}

tcu::Vec4 MultisampleRenderPassTestBase::getFormatThreshold () const
{
	const tcu::TextureFormat	tcuFormat		(mapVkFormat(m_format));
	const deUint32				componentCount	(tcu::getNumUsedChannels(tcuFormat.order));

	if (isSnormFormat(m_format))
	{
		return Vec4((componentCount >= 1) ? 1.5f * getRepresentableDiffSnorm(m_format, 0) : 0.0f,
					(componentCount >= 2) ? 1.5f * getRepresentableDiffSnorm(m_format, 1) : 0.0f,
					(componentCount >= 3) ? 1.5f * getRepresentableDiffSnorm(m_format, 2) : 0.0f,
					(componentCount == 4) ? 1.5f * getRepresentableDiffSnorm(m_format, 3) : 0.0f);
	}
	else if (isUnormFormat(m_format))
	{
		return Vec4((componentCount >= 1) ? 1.5f * getRepresentableDiffUnorm(m_format, 0) : 0.0f,
					(componentCount >= 2) ? 1.5f * getRepresentableDiffUnorm(m_format, 1) : 0.0f,
					(componentCount >= 3) ? 1.5f * getRepresentableDiffUnorm(m_format, 2) : 0.0f,
					(componentCount == 4) ? 1.5f * getRepresentableDiffUnorm(m_format, 3) : 0.0f);
	}
	else if (isFloatFormat(m_format))
	{
		return (tcuFormat.type == tcu::TextureFormat::HALF_FLOAT) ? tcu::Vec4(0.005f) : Vec4(0.00001f);
	}
	else
		return Vec4(0.001f);
}

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

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

void MultisampleRenderPassTestBase::logImage (const std::string& name, const tcu::ConstPixelBufferAccess& image) const
{
	m_context.getTestContext().getLog() << tcu::LogImage(name.c_str(), name.c_str(), image);

	for (deUint32 layerNdx = 0; layerNdx < m_layerCount; ++layerNdx)
	{
		const std::string			layerName	(name + " Layer:" + de::toString(layerNdx));
		tcu::ConstPixelBufferAccess	layerImage	(image.getFormat(), m_width, m_height, 1, image.getPixelPtr(0, 0, layerNdx));

		m_context.getTestContext().getLog() << tcu::LogImage(layerName.c_str(), layerName.c_str(), layerImage);
	}
}

class MultisampleRenderPassTestInstance : public MultisampleRenderPassTestBase
{
public:
	MultisampleRenderPassTestInstance	(Context& context, TestConfig config);
	~MultisampleRenderPassTestInstance	(void);

	tcu::TestStatus			iterate		(void);

private:

	template<typename RenderpassSubpass>
	void					submit						(void);
	void					submitSwitch				(RenderPassType renderPassType);
	void					verify						(void);

	template<typename RenderPassTrait>
	Move<VkRenderPass>		createRenderPass			(void);
	Move<VkRenderPass>		createRenderPassSwitch		(const RenderPassType renderPassType);
	Move<VkPipelineLayout>	createRenderPipelineLayout	(void);
	Move<VkPipeline>		createRenderPipeline		(void);

private:

	const std::vector<VkImageSp>		m_multisampleImages;
	const std::vector<AllocationSp>		m_multisampleImageMemory;
	const std::vector<VkImageViewSp>	m_multisampleImageViews;

	const std::vector<VkImageSp>		m_singlesampleImages;
	const std::vector<AllocationSp>		m_singlesampleImageMemory;
	const std::vector<VkImageViewSp>	m_singlesampleImageViews;

	const Unique<VkRenderPass>			m_renderPass;
	const Unique<VkFramebuffer>			m_framebuffer;

	const Unique<VkPipelineLayout>		m_renderPipelineLayout;
	const Unique<VkPipeline>			m_renderPipeline;

	const std::vector<VkBufferSp>		m_buffers;
	const std::vector<AllocationSp>		m_bufferMemory;

	const Unique<VkCommandPool>			m_commandPool;
	tcu::TextureLevel					m_sum;
	deUint32							m_sampleMask;
	tcu::ResultCollector				m_resultCollector;
};

MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config)
	: MultisampleRenderPassTestBase(context, config, 4u)

	, m_multisampleImages		(createImages(m_sampleCount, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
	, m_multisampleImageMemory	(createImageMemory(m_multisampleImages))
	, m_multisampleImageViews	(createImageViews(m_multisampleImages))

	, m_singlesampleImages		(createImages(VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT))
	, m_singlesampleImageMemory	(createImageMemory(m_singlesampleImages))
	, m_singlesampleImageViews	(createImageViews(m_singlesampleImages))

	, m_renderPass				(createRenderPassSwitch(config.renderPassType))
	, m_framebuffer				(createFramebuffer(m_multisampleImageViews, m_singlesampleImageViews, *m_renderPass))

	, m_renderPipelineLayout	(createRenderPipelineLayout())
	, m_renderPipeline			(createRenderPipeline())

	, m_buffers					(createBuffers())
	, m_bufferMemory			(createBufferMemory(m_buffers))

	, m_commandPool				(createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
	, m_sum						(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), m_width, m_height, m_layerCount)
	, m_sampleMask				(0x0u)
{
	tcu::clear(m_sum.getAccess(), Vec4(0.0f, 0.0f, 0.0f, 0.0f));
}

MultisampleRenderPassTestInstance::~MultisampleRenderPassTestInstance (void)
{
}

template<typename RenderpassSubpass>
void MultisampleRenderPassTestInstance::submit (void)
{
	const DeviceInterface&								vkd					(m_context.getDeviceInterface());
	const VkDevice										device				(m_context.getDevice());
	const Unique<VkCommandBuffer>						commandBuffer		(allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo		(DE_NULL);

	beginCommandBuffer(vkd, *commandBuffer);

	// Memory barriers between previous copies and rendering
	{
		std::vector<VkImageMemoryBarrier> barriers;

		for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
		{
			const VkImageMemoryBarrier barrier =
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
				DE_NULL,

				VK_ACCESS_TRANSFER_READ_BIT,
				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,

				VK_IMAGE_LAYOUT_UNDEFINED,
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,

				VK_QUEUE_FAMILY_IGNORED,
				VK_QUEUE_FAMILY_IGNORED,

				**m_singlesampleImages[dstNdx],
				{
					VK_IMAGE_ASPECT_COLOR_BIT,
					0u,
					1u,
					0u,
					m_layerCount
				}
			};

			barriers.push_back(barrier);
		}

		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, (deUint32)barriers.size(), &barriers[0]);
	}

	{
		const VkRenderPassBeginInfo beginInfo =
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
			DE_NULL,

			*m_renderPass,
			*m_framebuffer,

			{
				{ 0u, 0u },
				{ m_width, m_height }
			},

			0u,
			DE_NULL
		};
		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
	}

	// Clear everything to black
	clearAttachments(*commandBuffer);

	// Render black samples
	{
		vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
		vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(m_sampleMask), &m_sampleMask);
		vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
	}

	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);

	for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
		copyImageToBuffer(vkd, *commandBuffer, **m_singlesampleImages[dstNdx], **m_buffers[dstNdx], tcu::IVec2(m_width, m_height), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_layerCount);

	endCommandBuffer(vkd, *commandBuffer);

	submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);

	for (size_t memoryBufferNdx = 0; memoryBufferNdx < m_bufferMemory.size(); memoryBufferNdx++)
		invalidateMappedMemoryRange(vkd, device, m_bufferMemory[memoryBufferNdx]->getMemory(), 0u, VK_WHOLE_SIZE);
}

void MultisampleRenderPassTestInstance::submitSwitch (RenderPassType renderPassType)
{
	switch (renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:
			submit<RenderpassSubpass1>();
			break;
		case RENDERPASS_TYPE_RENDERPASS2:
			submit<RenderpassSubpass2>();
			break;
		default:
			TCU_THROW(InternalError, "Impossible");
	}
}

void MultisampleRenderPassTestInstance::verify (void)
{
	const Vec4							errorColor		(1.0f, 0.0f, 0.0f, 1.0f);
	const Vec4							okColor			(0.0f, 1.0f, 0.0f, 1.0f);
	const tcu::TextureFormat			format			(mapVkFormat(m_format));
	const tcu::TextureChannelClass		channelClass	(tcu::getTextureChannelClass(format.type));

	std::vector<tcu::ConstPixelBufferAccess> accesses;
	for (deUint32 attachmentIdx = 0; attachmentIdx < m_attachmentsCount; ++attachmentIdx)
	{
		void* const ptr = m_bufferMemory[attachmentIdx]->getHostPtr();
		accesses.push_back(tcu::ConstPixelBufferAccess(format, m_width, m_height, m_layerCount, ptr));
	}

	tcu::TextureLevel					errorMask		(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), m_width, m_height, m_layerCount);
	tcu::TestLog&						log				(m_context.getTestContext().getLog());

	switch (channelClass)
	{
		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
		{
			const int	componentCount	(tcu::getNumUsedChannels(format.order));
			bool		isOk			= true;
			float		clearValue;
			float		renderValue;

			switch (channelClass)
			{
				case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
				case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
					clearValue	= -1.0f;
					renderValue	= 1.0f;
					break;

				case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
					clearValue	= 0.0f;
					renderValue	= 1.0f;
					break;

				default:
					clearValue	= 0.0f;
					renderValue	= 0.0f;
					DE_FATAL("Unknown channel class");
			}

			for (deUint32 z = 0; z < m_layerCount; z++)
			for (deUint32 y = 0; y < m_height; y++)
			for (deUint32 x = 0; x < m_width; x++)
			{
				// Color has to be black if no samples were covered, white if all samples were covered or same in every attachment
				const Vec4	firstColor	(accesses[0].getPixel(x, y, z));
				const Vec4	refColor	(m_sampleMask == 0x0u
										? Vec4(clearValue,
												componentCount > 1 ? clearValue : 0.0f,
												componentCount > 2 ? clearValue : 0.0f,
												componentCount > 3 ? clearValue : 1.0f)
										: m_sampleMask == ((0x1u << m_sampleCount) - 1u)
										? Vec4(renderValue,
												componentCount > 1 ? renderValue : 0.0f,
												componentCount > 2 ? renderValue : 0.0f,
												componentCount > 3 ? renderValue : 1.0f)
										: firstColor);

				errorMask.getAccess().setPixel(okColor, x, y, z);

				for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
				{
					const Vec4 color (accesses[attachmentNdx].getPixel(x, y, z));

					if (refColor != color)
					{
						isOk = false;
						errorMask.getAccess().setPixel(errorColor, x, y, z);
						break;
					}
				}

				{
					const Vec4 old = m_sum.getAccess().getPixel(x, y, z);
					m_sum.getAccess().setPixel(old + (tcu::isSRGB(format) ? tcu::sRGBToLinear(firstColor) : firstColor), x, y, z);
				}
			}

			if (!isOk)
			{
				const std::string			sectionName	("ResolveVerifyWithMask" + de::toString(m_sampleMask));
				const tcu::ScopedLogSection	section		(log, sectionName, sectionName);

				for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
					logImage(std::string("Attachment") + de::toString(attachmentNdx), accesses[attachmentNdx]);

				logImage("ErrorMask", errorMask.getAccess());

				if (m_sampleMask == 0x0u)
				{
					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
					m_resultCollector.fail("Empty sample mask didn't produce correct pixel values");
				}
				else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
				{
					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
					m_resultCollector.fail("Full sample mask didn't produce correct pixel values");
				}
				else
				{
					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve is inconsistent between attachments" << tcu::TestLog::EndMessage;
					m_resultCollector.fail("Resolve is inconsistent between attachments");
				}
			}
			break;
		}

		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
		{
			const int		componentCount			(tcu::getNumUsedChannels(format.order));
			const UVec4		bitDepth				(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
			const UVec4		renderValue				(tcu::select((UVec4(1u) << tcu::min(UVec4(8u), bitDepth)) - UVec4(1u),
																  UVec4(0u, 0u, 0u, 1u),
																  tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
			const UVec4		clearValue				(tcu::select(UVec4(0u),
																 UVec4(0u, 0u, 0u, 1u),
																 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
			bool			unexpectedValues		= false;
			bool			inconsistentComponents	= false;
			bool			inconsistentAttachments	= false;

			for (deUint32 z = 0; z < m_layerCount; z++)
			for (deUint32 y = 0; y < m_height; y++)
			for (deUint32 x = 0; x < m_width; x++)
			{
				// Color has to be all zeros if no samples were covered, all 255 if all samples were covered or consistent across all attachments
				const UVec4 refColor	(m_sampleMask == 0x0u
										? clearValue
										: m_sampleMask == ((0x1u << m_sampleCount) - 1u)
										? renderValue
										: accesses[0].getPixelUint(x, y, z));
				bool		isOk		= true;

				// If reference value was taken from first attachment, check that it is valid value i.e. clear or render value
				if (m_sampleMask != 0x0u && m_sampleMask != ((0x1u << m_sampleCount) - 1u))
				{
					// Each component must be resolved same way
					const BVec4		isRenderValue			(refColor == renderValue);
					const BVec4		isClearValue			(refColor == clearValue);
					const bool		unexpectedValue			(tcu::anyNotEqual(tcu::logicalOr(isRenderValue, isClearValue), BVec4(true)));
					const bool		inconsistentComponent	(!(tcu::allEqual(isRenderValue, BVec4(true)) || tcu::allEqual(isClearValue, BVec4(true))));

					unexpectedValues		|= unexpectedValue;
					inconsistentComponents	|= inconsistentComponent;

					if (unexpectedValue || inconsistentComponent)
						isOk = false;
				}

				for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
				{
					const UVec4 color (accesses[attachmentNdx].getPixelUint(x, y, z));

					if (refColor != color)
					{
						isOk = false;
						inconsistentAttachments = true;
						break;
					}
				}

				errorMask.getAccess().setPixel((isOk ? okColor : errorColor), x, y, z);
			}

			if (unexpectedValues || inconsistentComponents || inconsistentAttachments)
			{
				const std::string			sectionName	("ResolveVerifyWithMask" + de::toString(m_sampleMask));
				const tcu::ScopedLogSection	section		(log, sectionName, sectionName);

				for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
					logImage(std::string("Attachment") + de::toString(attachmentNdx), accesses[attachmentNdx]);

				logImage("ErrorMask", errorMask.getAccess());

				if (m_sampleMask == 0x0u)
				{
					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
					m_resultCollector.fail("Empty sample mask didn't produce correct pixels");
				}
				else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
				{
					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
					m_resultCollector.fail("Full sample mask didn't produce correct pixels");
				}
				else
				{
					if (unexpectedValues)
					{
						m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve produced unexpected values i.e. not " << clearValue << " or " << renderValue << tcu::TestLog::EndMessage;
						m_resultCollector.fail("Resolve produced unexpected values");
					}

					if (inconsistentComponents)
					{
						m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different components of attachment were resolved to different values." << tcu::TestLog::EndMessage;
						m_resultCollector.fail("Different components of attachment were resolved to different values.");
					}

					if (inconsistentAttachments)
					{
						m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different attachments were resolved to different values." << tcu::TestLog::EndMessage;
						m_resultCollector.fail("Different attachments were resolved to different values.");
					}
				}
			}
			break;
		}

		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
		{
			const int		componentCount			(tcu::getNumUsedChannels(format.order));
			const IVec4		bitDepth				(tcu::getTextureFormatBitDepth(format));
			const IVec4		renderValue				(tcu::select((IVec4(1) << (tcu::min(IVec4(8), bitDepth) - IVec4(1))) - IVec4(1),
																  IVec4(0, 0, 0, 1),
																  tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
			const IVec4		clearValue				(tcu::select(-(IVec4(1) << (tcu::min(IVec4(8), bitDepth) - IVec4(1))),
																 IVec4(0, 0, 0, 1),
																 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
			bool			unexpectedValues		= false;
			bool			inconsistentComponents	= false;
			bool			inconsistentAttachments	= false;

			for (deUint32 z = 0; z < m_layerCount; z++)
			for (deUint32 y = 0; y < m_height; y++)
			for (deUint32 x = 0; x < m_width; x++)
			{
				// Color has to be all zeros if no samples were covered, all 255 if all samples were covered or consistent across all attachments
				const IVec4 refColor	(m_sampleMask == 0x0u
										? clearValue
										: m_sampleMask == ((0x1u << m_sampleCount) - 1u)
										? renderValue
										: accesses[0].getPixelInt(x, y, z));
				bool		isOk		= true;

				// If reference value was taken from first attachment, check that it is valid value i.e. clear or render value
				if (m_sampleMask != 0x0u && m_sampleMask != ((0x1u << m_sampleCount) - 1u))
				{
					// Each component must be resolved same way
					const BVec4		isRenderValue			(refColor == renderValue);
					const BVec4		isClearValue			(refColor == clearValue);
					const bool		unexpectedValue			(tcu::anyNotEqual(tcu::logicalOr(isRenderValue, isClearValue), BVec4(true)));
					const bool		inconsistentComponent	(!(tcu::allEqual(isRenderValue, BVec4(true)) || tcu::allEqual(isClearValue, BVec4(true))));

					unexpectedValues		|= unexpectedValue;
					inconsistentComponents	|= inconsistentComponent;

					if (unexpectedValue || inconsistentComponent)
						isOk = false;
				}

				for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
				{
					const IVec4 color (accesses[attachmentNdx].getPixelInt(x, y, z));

					if (refColor != color)
					{
						isOk = false;
						inconsistentAttachments = true;
						break;
					}
				}

				errorMask.getAccess().setPixel((isOk ? okColor : errorColor), x, y, z);
			}

			if (unexpectedValues || inconsistentComponents || inconsistentAttachments)
			{
				const std::string			sectionName	("ResolveVerifyWithMask" + de::toString(m_sampleMask));
				const tcu::ScopedLogSection	section		(log, sectionName, sectionName);

				for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
					logImage(std::string("Attachment") + de::toString(attachmentNdx), accesses[attachmentNdx]);

				logImage("ErrorMask", errorMask.getAccess());

				if (m_sampleMask == 0x0u)
				{
					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
					m_resultCollector.fail("Empty sample mask didn't produce correct pixels");
				}
				else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
				{
					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
					m_resultCollector.fail("Full sample mask didn't produce correct pixels");
				}
				else
				{
					if (unexpectedValues)
					{
						m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve produced unexpected values i.e. not " << clearValue << " or " << renderValue << tcu::TestLog::EndMessage;
						m_resultCollector.fail("Resolve produced unexpected values");
					}

					if (inconsistentComponents)
					{
						m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different components of attachment were resolved to different values." << tcu::TestLog::EndMessage;
						m_resultCollector.fail("Different components of attachment were resolved to different values.");
					}

					if (inconsistentAttachments)
					{
						m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different attachments were resolved to different values." << tcu::TestLog::EndMessage;
						m_resultCollector.fail("Different attachments were resolved to different values.");
					}
				}
			}
			break;
		}

		default:
			DE_FATAL("Unknown channel class");
	}
}

tcu::TestStatus MultisampleRenderPassTestInstance::iterate (void)
{
	if (m_sampleMask == 0u)
	{
		const tcu::TextureFormat		format			(mapVkFormat(m_format));
		const tcu::TextureChannelClass	channelClass	(tcu::getTextureChannelClass(format.type));
		tcu::TestLog&					log				(m_context.getTestContext().getLog());

		switch (channelClass)
		{
			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
				log << TestLog::Message << "Clearing target to zero and rendering 255 pixels with every possible sample mask" << TestLog::EndMessage;
				break;

			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
				log << TestLog::Message << "Clearing target to -128 and rendering 127 pixels with every possible sample mask" << TestLog::EndMessage;
				break;

			case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
			case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
			case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
				log << TestLog::Message << "Clearing target to black and rendering white pixels with every possible sample mask" << TestLog::EndMessage;
				break;

			default:
				DE_FATAL("Unknown channel class");
		}
	}

	submitSwitch(m_renderPassType);
	verify();

	if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
	{
		const tcu::TextureFormat		format			(mapVkFormat(m_format));
		const tcu::TextureChannelClass	channelClass	(tcu::getTextureChannelClass(format.type));
		const Vec4						threshold		(getFormatThreshold());
		tcu::TestLog&					log				(m_context.getTestContext().getLog());

		if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT
				|| channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT
				|| channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
		{
			const int			componentCount	(tcu::getNumUsedChannels(format.order));
			const Vec4			errorColor		(1.0f, 0.0f, 0.0f, 1.0f);
			const Vec4			okColor			(0.0f, 1.0f, 0.0f, 1.0f);
			tcu::TextureLevel	errorMask		(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), m_width, m_height, m_layerCount);
			bool				isOk			= true;
			Vec4				maxDiff			(0.0f);
			Vec4				expectedAverage;

			switch (channelClass)
			{
				case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
				{
					expectedAverage = Vec4(0.5f, componentCount > 1 ? 0.5f : 0.0f, componentCount > 2 ? 0.5f : 0.0f, componentCount > 3 ? 0.5f : 1.0f);
					break;
				}

				case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
				case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
				{
					expectedAverage = Vec4(0.0f, 0.0f, 0.0f, componentCount > 3 ? 0.0f : 1.0f);
					break;
				}

				default:
					DE_FATAL("Unknown channel class");
			}

			for (deUint32 z = 0; z < m_layerCount; z++)
			for (deUint32 y = 0; y < m_height; y++)
			for (deUint32 x = 0; x < m_width; x++)
			{
				const Vec4	sum		(m_sum.getAccess().getPixel(x, y, z));
				const Vec4	average	(sum / Vec4((float)(0x1u << m_sampleCount)));
				const Vec4	diff	(tcu::abs(average - expectedAverage));

				m_sum.getAccess().setPixel(average, x, y, z);
				errorMask.getAccess().setPixel(okColor, x, y, z);

				if (diff[0] > threshold.x()
						|| diff[1] > threshold.y()
						|| diff[2] > threshold.z()
						|| diff[3] > threshold.w())
				{
					isOk	= false;
					maxDiff	= tcu::max(maxDiff, diff);
					errorMask.getAccess().setPixel(errorColor, x, y, z);
				}
			}

			log << TestLog::Image("Average resolved values in attachment 0", "Average resolved values in attachment 0", m_sum);

			if (!isOk)
			{
				std::stringstream	message;

				m_context.getTestContext().getLog() << tcu::LogImage("ErrorMask", "ErrorMask", errorMask.getAccess());

				message << "Average resolved values differ from expected average values by more than ";

				switch (componentCount)
				{
					case 1:
						message << threshold.x();
						break;
					case 2:
						message << "vec2" << Vec2(threshold.x(), threshold.y());
						break;
					case 3:
						message << "vec3" << Vec3(threshold.x(), threshold.y(), threshold.z());
						break;
					default:
						message << "vec4" << threshold;
				}

				message << ". Max diff " << maxDiff;
				log << TestLog::Message << message.str() << TestLog::EndMessage;

				m_resultCollector.fail("Average resolved values differ from expected average values");
			}
		}

		return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
	}
	else
	{
		m_sampleMask++;
		return tcu::TestStatus::incomplete();
	}
}

template<typename RenderPassTrait>
Move<VkRenderPass> MultisampleRenderPassTestInstance::createRenderPass (void)
{
	// make name for RenderPass1Trait or RenderPass2Trait shorter
	typedef RenderPassTrait RPT;
	typedef typename RPT::AttDesc				AttDesc;
	typedef typename RPT::AttRef				AttRef;
	typedef typename RPT::SubpassDesc			SubpassDesc;
	typedef typename RPT::RenderPassCreateInfo	RenderPassCreateInfo;

	const DeviceInterface&	vkd						= m_context.getDeviceInterface();
	VkDevice				device					= m_context.getDevice();
	std::vector<AttDesc>	attachments;
	std::vector<AttRef>		colorAttachmentRefs;
	std::vector<AttRef>		resolveAttachmentRefs;

	for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
	{
		{
			const AttDesc multisampleAttachment
			(
															// sType
				DE_NULL,									// pNext
				0u,											// flags
				m_format,									// format
				m_sampleCount,								// samples
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// loadOp
				VK_ATTACHMENT_STORE_OP_DONT_CARE,			// storeOp
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// stencilLoadOp
				VK_ATTACHMENT_STORE_OP_DONT_CARE,			// stencilStoreOp
				VK_IMAGE_LAYOUT_UNDEFINED,					// initialLayout
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// finalLayout
			);
			const AttRef attachmentRef
			(
															// sType
				DE_NULL,									// pNext
				(deUint32)attachments.size(),				// attachment
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// layout
				0u											// aspectMask
			);
			colorAttachmentRefs.push_back(attachmentRef);
			attachments.push_back(multisampleAttachment);
		}
		{
			const AttDesc singlesampleAttachment
			(
															// sType
				DE_NULL,									// pNext
				0u,											// flags
				m_format,									// format
				VK_SAMPLE_COUNT_1_BIT,						// samples
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// loadOp
				VK_ATTACHMENT_STORE_OP_STORE,				// storeOp
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// stencilLoadOp
				VK_ATTACHMENT_STORE_OP_DONT_CARE,			// stencilStoreOp
				VK_IMAGE_LAYOUT_UNDEFINED,					// initialLayout
				VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL		// finalLayout
			);
			const AttRef attachmentRef
			(
															// sType
				DE_NULL,									// pNext
				(deUint32)attachments.size(),				// attachment
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// layout
				0u											// aspectMask
			);
			resolveAttachmentRefs.push_back(attachmentRef);
			attachments.push_back(singlesampleAttachment);
		}
	}

	DE_ASSERT(colorAttachmentRefs.size() == resolveAttachmentRefs.size());
	DE_ASSERT(attachments.size() == colorAttachmentRefs.size() + resolveAttachmentRefs.size());

	const SubpassDesc subpass
	(
														// sType
		DE_NULL,										// pNext
		(VkSubpassDescriptionFlags)0,					// flags
		VK_PIPELINE_BIND_POINT_GRAPHICS,				// pipelineBindPoint
		0u,												// viewMask
		0u,												// inputAttachmentCount
		DE_NULL,										// pInputAttachments
		(deUint32)colorAttachmentRefs.size(),			// colorAttachmentCount
		&colorAttachmentRefs[0],						// pColorAttachments
		&resolveAttachmentRefs[0],						// pResolveAttachments
		DE_NULL,										// pDepthStencilAttachment
		0u,												// preserveAttachmentCount
		DE_NULL											// pPreserveAttachments
	);
	const RenderPassCreateInfo renderPassCreator
	(
														// sType
		DE_NULL,										// pNext
		(VkRenderPassCreateFlags)0u,					// flags
		(deUint32)attachments.size(),					// attachmentCount
		&attachments[0],								// pAttachments
		1u,												// subpassCount
		&subpass,										// pSubpasses
		0u,												// dependencyCount
		DE_NULL,										// pDependencies
		0u,												// correlatedViewMaskCount
		DE_NULL											// pCorrelatedViewMasks
	);

	return renderPassCreator.createRenderPass(vkd, device);
}

Move<VkRenderPass> MultisampleRenderPassTestInstance::createRenderPassSwitch (const RenderPassType renderPassType)
{
	switch (renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:
			return createRenderPass<RenderPass1Trait>();
		case RENDERPASS_TYPE_RENDERPASS2:
			return createRenderPass<RenderPass2Trait>();
		default:
			TCU_THROW(InternalError, "Impossible");
	}
}

Move<VkPipelineLayout> MultisampleRenderPassTestInstance::createRenderPipelineLayout (void)
{
	const DeviceInterface&	vkd		= m_context.getDeviceInterface();
	VkDevice				device	= m_context.getDevice();

	const VkPushConstantRange pushConstant =
	{
		VK_SHADER_STAGE_FRAGMENT_BIT,
		0u,
		4u
	};
	const VkPipelineLayoutCreateInfo createInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
		DE_NULL,
		(vk::VkPipelineLayoutCreateFlags)0,

		0u,
		DE_NULL,

		1u,
		&pushConstant
	};

	return createPipelineLayout(vkd, device, &createInfo);
}

Move<VkPipeline> MultisampleRenderPassTestInstance::createRenderPipeline (void)
{
	const DeviceInterface&			vkd						= m_context.getDeviceInterface();
	VkDevice						device					= m_context.getDevice();
	const vk::BinaryCollection&		binaryCollection		= m_context.getBinaryCollection();
	const Unique<VkShaderModule>	vertexShaderModule		(createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
	const Unique<VkShaderModule>	fragmentShaderModule	(createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 0u));
	const Move<VkShaderModule>		geometryShaderModule	(m_layerCount == 1 ? Move<VkShaderModule>() : createShaderModule(vkd, device, binaryCollection.get("geom"), 0u));
	// Disable blending
	const VkPipelineColorBlendAttachmentState attachmentBlendState =
	{
		VK_FALSE,
		VK_BLEND_FACTOR_SRC_ALPHA,
		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
		VK_BLEND_OP_ADD,
		VK_BLEND_FACTOR_ONE,
		VK_BLEND_FACTOR_ONE,
		VK_BLEND_OP_ADD,
		VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
	};
	std::vector<VkPipelineColorBlendAttachmentState>	attachmentBlendStates(m_attachmentsCount, attachmentBlendState);
	const VkPipelineVertexInputStateCreateInfo			vertexInputState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
		DE_NULL,
		(VkPipelineVertexInputStateCreateFlags)0u,

		0u,
		DE_NULL,

		0u,
		DE_NULL
	};
	const tcu::UVec2				renderArea	(m_width, m_height);
	const std::vector<VkViewport>	viewports	(1, makeViewport(renderArea));
	const std::vector<VkRect2D>		scissors	(1, makeRect2D(renderArea));

	const VkPipelineMultisampleStateCreateInfo multisampleState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
		DE_NULL,
		(VkPipelineMultisampleStateCreateFlags)0u,

		sampleCountBitFromSampleCount(m_sampleCount),
		VK_FALSE,
		0.0f,
		DE_NULL,
		VK_FALSE,
		VK_FALSE,
	};
	const VkPipelineDepthStencilStateCreateInfo depthStencilState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
		DE_NULL,
		(VkPipelineDepthStencilStateCreateFlags)0u,

		VK_FALSE,
		VK_TRUE,
		VK_COMPARE_OP_ALWAYS,
		VK_FALSE,
		VK_TRUE,
		{
			VK_STENCIL_OP_KEEP,
			VK_STENCIL_OP_INCREMENT_AND_WRAP,
			VK_STENCIL_OP_KEEP,
			VK_COMPARE_OP_ALWAYS,
			~0u,
			~0u,
			0xFFu / (m_sampleCount + 1)
		},
		{
			VK_STENCIL_OP_KEEP,
			VK_STENCIL_OP_INCREMENT_AND_WRAP,
			VK_STENCIL_OP_KEEP,
			VK_COMPARE_OP_ALWAYS,
			~0u,
			~0u,
			0xFFu / (m_sampleCount + 1)
		},

		0.0f,
		1.0f
	};
	const VkPipelineColorBlendStateCreateInfo blendState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
		DE_NULL,
		(VkPipelineColorBlendStateCreateFlags)0u,

		VK_FALSE,
		VK_LOGIC_OP_COPY,
		deUint32(attachmentBlendStates.size()),
		&attachmentBlendStates[0],
		{ 0.0f, 0.0f, 0.0f, 0.0f }
	};

	return makeGraphicsPipeline(vkd,												// const DeviceInterface&                        vk
								device,												// const VkDevice                                device
								*m_renderPipelineLayout,							// const VkPipelineLayout                        pipelineLayout
								*vertexShaderModule,								// const VkShaderModule                          vertexShaderModule
								DE_NULL,											// const VkShaderModule                          tessellationControlShaderModule
								DE_NULL,											// const VkShaderModule                          tessellationEvalShaderModule
								m_layerCount != 1 ? *geometryShaderModule : DE_NULL,// const VkShaderModule                          geometryShaderModule
								*fragmentShaderModule,								// const VkShaderModule                          fragmentShaderModule
								*m_renderPass,										// const VkRenderPass                            renderPass
								viewports,											// const std::vector<VkViewport>&                viewports
								scissors,											// const std::vector<VkRect2D>&                  scissors
								VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,				// const VkPrimitiveTopology                     topology
								0u,													// const deUint32                                subpass
								0u,													// const deUint32                                patchControlPoints
								&vertexInputState,									// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
								DE_NULL,											// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
								&multisampleState,									// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
								&depthStencilState,									// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
								&blendState);										// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
}

class MaxAttachmenstsRenderPassTestInstance : public MultisampleRenderPassTestBase
{
public:
	MaxAttachmenstsRenderPassTestInstance	(Context& context, TestConfig config);
	~MaxAttachmenstsRenderPassTestInstance	(void);

	tcu::TestStatus			iterate			(void);

private:

	template<typename RenderpassSubpass>
	void					submit						(void);
	void					submitSwitch				(RenderPassType renderPassType);
	void					verify						(void);

	Move<VkDescriptorSetLayout>	createDescriptorSetLayout	(void);
	Move<VkDescriptorPool>		createDescriptorPool		(void);
	Move<VkDescriptorSet>		createDescriptorSet			(void);

	template<typename RenderPassTrait>
	Move<VkRenderPass>		createRenderPass			(void);
	Move<VkRenderPass>		createRenderPassSwitch		(const RenderPassType renderPassType);
	Move<VkPipelineLayout>	createRenderPipelineLayout	(bool secondSubpass);
	Move<VkPipeline>		createRenderPipeline		(bool secondSubpass);

private:

	const std::vector<VkImageSp>			m_multisampleImages;
	const std::vector<AllocationSp>			m_multisampleImageMemory;
	const std::vector<VkImageViewSp>		m_multisampleImageViews;

	const std::vector<VkImageSp>			m_singlesampleImages;
	const std::vector<AllocationSp>			m_singlesampleImageMemory;
	const std::vector<VkImageViewSp>		m_singlesampleImageViews;

	const Unique<VkDescriptorSetLayout>		m_descriptorSetLayout;
	const Unique<VkDescriptorPool>			m_descriptorPool;
	const Unique<VkDescriptorSet>			m_descriptorSet;

	const Unique<VkRenderPass>				m_renderPass;
	const Unique<VkFramebuffer>				m_framebuffer;

	const Unique<VkPipelineLayout>			m_pipelineLayoutPass0;
	const Unique<VkPipeline>				m_pipelinePass0;
	const Unique<VkPipelineLayout>			m_pipelineLayoutPass1;
	const Unique<VkPipeline>				m_pipelinePass1;

	const std::vector<VkBufferSp>			m_buffers;
	const std::vector<AllocationSp>			m_bufferMemory;

	const Unique<VkCommandPool>				m_commandPool;
	tcu::ResultCollector					m_resultCollector;
};

MaxAttachmenstsRenderPassTestInstance::MaxAttachmenstsRenderPassTestInstance (Context& context, TestConfig config)
	: MultisampleRenderPassTestBase(context, config, config.attachmentCount)

	, m_multisampleImages		(createImages(m_sampleCount, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
	, m_multisampleImageMemory	(createImageMemory(m_multisampleImages))
	, m_multisampleImageViews	(createImageViews(m_multisampleImages))

	, m_singlesampleImages		(createImages(VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT))
	, m_singlesampleImageMemory	(createImageMemory(m_singlesampleImages))
	, m_singlesampleImageViews	(createImageViews(m_singlesampleImages))

	, m_descriptorSetLayout		(createDescriptorSetLayout())
	, m_descriptorPool			(createDescriptorPool())
	, m_descriptorSet			(createDescriptorSet())

	, m_renderPass				(createRenderPassSwitch(config.renderPassType))
	, m_framebuffer				(createFramebuffer(m_multisampleImageViews, m_singlesampleImageViews, *m_renderPass))

	, m_pipelineLayoutPass0		(createRenderPipelineLayout(0))
	, m_pipelinePass0			(createRenderPipeline(0))
	, m_pipelineLayoutPass1		(createRenderPipelineLayout(1))
	, m_pipelinePass1			(createRenderPipeline(1))

	, m_buffers					(createBuffers())
	, m_bufferMemory			(createBufferMemory(m_buffers))

	, m_commandPool				(createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
{
}

MaxAttachmenstsRenderPassTestInstance::~MaxAttachmenstsRenderPassTestInstance (void)
{
}

template<typename RenderpassSubpass>
void MaxAttachmenstsRenderPassTestInstance::submit (void)
{
	const DeviceInterface&								vkd					(m_context.getDeviceInterface());
	const VkDevice										device				(m_context.getDevice());
	const Unique<VkCommandBuffer>						commandBuffer		(allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo		(DE_NULL);

	beginCommandBuffer(vkd, *commandBuffer);

	// Memory barriers between previous copies and rendering
	{
		std::vector<VkImageMemoryBarrier> barriers;

		for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
		{
			const VkImageMemoryBarrier barrier =
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
				DE_NULL,

				VK_ACCESS_TRANSFER_READ_BIT,
				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,

				VK_IMAGE_LAYOUT_UNDEFINED,
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,

				VK_QUEUE_FAMILY_IGNORED,
				VK_QUEUE_FAMILY_IGNORED,

				**m_singlesampleImages[dstNdx],
				{
					VK_IMAGE_ASPECT_COLOR_BIT,
					0u,
					1u,
					0u,
					m_layerCount
				}
			};

			barriers.push_back(barrier);
		}

		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, (deUint32)barriers.size(), &barriers[0]);
	}

	{
		const VkRenderPassBeginInfo beginInfo =
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
			DE_NULL,

			*m_renderPass,
			*m_framebuffer,

			{
				{ 0u, 0u },
				{ m_width, m_height }
			},

			0u,
			DE_NULL
		};
		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
	}

	// Clear everything to black
	clearAttachments(*commandBuffer);

	// First subpass - render black samples
	{
		vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelinePass0);
		vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
	}

	// Second subpasss - merge attachments
	{
		RenderpassSubpass::cmdNextSubpass(vkd, *commandBuffer, &subpassBeginInfo, &subpassEndInfo);
		vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelinePass1);
		vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutPass1, 0, 1u, &*m_descriptorSet, 0, NULL);
		vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
	}

	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);

	// Memory barriers between rendering and copies
	{
		std::vector<VkImageMemoryBarrier> barriers;

		for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
		{
			const VkImageMemoryBarrier barrier =
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
				DE_NULL,

				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
				VK_ACCESS_TRANSFER_READ_BIT,

				VK_IMAGE_LAYOUT_GENERAL,
				VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,

				VK_QUEUE_FAMILY_IGNORED,
				VK_QUEUE_FAMILY_IGNORED,

				**m_singlesampleImages[dstNdx],
				{
					VK_IMAGE_ASPECT_COLOR_BIT,
					0u,
					1u,
					0u,
					m_layerCount
				}
			};

			barriers.push_back(barrier);
		}

		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, (deUint32)barriers.size(), &barriers[0]);
	}

	// Copy image memory to buffers
	for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
	{
		const VkBufferImageCopy region =
		{
			0u,
			0u,
			0u,
			{
				VK_IMAGE_ASPECT_COLOR_BIT,
				0u,
				0u,
				m_layerCount,
			},
			{ 0u, 0u, 0u },
			{ m_width, m_height, 1u }
		};

		vkd.cmdCopyImageToBuffer(*commandBuffer, **m_singlesampleImages[dstNdx], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_buffers[dstNdx], 1u, &region);
	}

	// Memory barriers between copies and host access
	{
		std::vector<VkBufferMemoryBarrier> barriers;

		for (size_t dstNdx = 0; dstNdx < m_buffers.size(); dstNdx++)
		{
			const VkBufferMemoryBarrier barrier =
			{
				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
				DE_NULL,

				VK_ACCESS_TRANSFER_WRITE_BIT,
				VK_ACCESS_HOST_READ_BIT,

				VK_QUEUE_FAMILY_IGNORED,
				VK_QUEUE_FAMILY_IGNORED,

				**m_buffers[dstNdx],
				0u,
				VK_WHOLE_SIZE
			};

			barriers.push_back(barrier);
		}

		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, (deUint32)barriers.size(), &barriers[0], 0u, DE_NULL);
	}

	endCommandBuffer(vkd, *commandBuffer);

	submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);

	for (size_t memoryBufferNdx = 0; memoryBufferNdx < m_bufferMemory.size(); memoryBufferNdx++)
		invalidateMappedMemoryRange(vkd, device, m_bufferMemory[memoryBufferNdx]->getMemory(), 0u, VK_WHOLE_SIZE);
}

void MaxAttachmenstsRenderPassTestInstance::submitSwitch (RenderPassType renderPassType)
{
	switch (renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:
			submit<RenderpassSubpass1>();
			break;
		case RENDERPASS_TYPE_RENDERPASS2:
			submit<RenderpassSubpass2>();
			break;
		default:
			TCU_THROW(InternalError, "Impossible");
	}
}

template <typename VecType>
bool isValueAboveThreshold1 (const VecType& vale, const VecType& threshold)
{
	return (vale[0] > threshold[0]);
}

template <typename VecType>
bool isValueAboveThreshold2 (const VecType& vale, const VecType& threshold)
{
	return (vale[0] > threshold[0]) || (vale[1] > threshold[1]);
}

template <typename VecType>
bool isValueAboveThreshold3 (const VecType& vale, const VecType& threshold)
{
	return (vale[0] > threshold[0]) || (vale[1] > threshold[1]) || (vale[2] > threshold[2]);
}

template <typename VecType>
bool isValueAboveThreshold4 (const VecType& vale, const VecType& threshold)
{
	return (vale[0] > threshold[0]) || (vale[1] > threshold[1]) || (vale[2] > threshold[2]) || (vale[3] > threshold[3]);
}

void MaxAttachmenstsRenderPassTestInstance::verify (void)
{
	const Vec4							errorColor		(1.0f, 0.0f, 0.0f, 1.0f);
	const Vec4							okColor			(0.0f, 1.0f, 0.0f, 1.0f);
	const tcu::TextureFormat			format			(mapVkFormat(m_format));
	const tcu::TextureChannelClass		channelClass	(tcu::getTextureChannelClass(format.type));
	const int							componentCount	(tcu::getNumUsedChannels(format.order));
	const int							outputsCount	= m_attachmentsCount / 2;

	DE_ASSERT((componentCount >= 0) && (componentCount < 5));

	std::vector<tcu::ConstPixelBufferAccess> accesses;
	for (int outputNdx = 0; outputNdx < outputsCount; ++outputNdx)
	{
		void* const ptr = m_bufferMemory[outputNdx]->getHostPtr();
		accesses.push_back(tcu::ConstPixelBufferAccess(format, m_width, m_height, 1, ptr));
	}

	tcu::TextureLevel	errorMask	(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), m_width, m_height, outputsCount);
	tcu::TestLog&		log			(m_context.getTestContext().getLog());
	bool				isOk		= true;

	switch (channelClass)
	{
		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
		{
			const Vec4 refColor(0.0f, 0.3f, 0.6f, 0.75f);
			const Vec4 threshold(getFormatThreshold());

			typedef bool(*ValueAboveThresholdFn)(const Vec4&, const Vec4&);
			ValueAboveThresholdFn componentToFnMap[4] =
			{
				isValueAboveThreshold1<Vec4>,
				isValueAboveThreshold2<Vec4>,
				isValueAboveThreshold3<Vec4>,
				isValueAboveThreshold4<Vec4>
			};
			ValueAboveThresholdFn	isValueAboveThreshold	= componentToFnMap[componentCount - 1];
			bool					isSRGBFormat			= tcu::isSRGB(format);

			for (int outputNdx = 0; outputNdx < outputsCount; outputNdx++)
			for (int y = 0; y < (int)m_height; y++)
			for (int x = 0; x < (int)m_width; x++)
			{
				Vec4 color = accesses[outputNdx].getPixel(x, y);
				if (isSRGBFormat)
					color = tcu::sRGBToLinear(color);

				const Vec4 diff(tcu::abs(color - refColor));

				if (isValueAboveThreshold(diff, threshold))
				{
					isOk = false;
					errorMask.getAccess().setPixel(errorColor, x, y, outputNdx);
					break;
				}
				else
					errorMask.getAccess().setPixel(okColor, x, y, outputNdx);
			}
			break;
		}

		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
		{
			const UVec4	refColor(0, 48, 144, 189);
			UVec4		threshold(1, 1, 1, 1);

			if (m_format == VK_FORMAT_A2B10G10R10_UINT_PACK32)
				threshold[3] = 200;

			typedef bool(*ValueAboveThresholdFn)(const UVec4&, const UVec4&);
			ValueAboveThresholdFn componentToFnMap[4] =
			{
				isValueAboveThreshold1<UVec4>,
				isValueAboveThreshold2<UVec4>,
				isValueAboveThreshold3<UVec4>,
				isValueAboveThreshold4<UVec4>
			};
			ValueAboveThresholdFn isValueAboveThreshold = componentToFnMap[componentCount - 1];

			for (int outputNdx = 0; outputNdx < outputsCount; outputNdx++)
			for (int y = 0; y < (int)m_height; y++)
			for (int x = 0; x < (int)m_width; x++)
			{
				const UVec4 color	(accesses[outputNdx].getPixelUint(x, y));
				const UVec4 diff	(std::abs(int(color.x()) - int(refColor.x())),
									 std::abs(int(color.y()) - int(refColor.y())),
									 std::abs(int(color.z()) - int(refColor.z())),
									 std::abs(int(color.w()) - int(refColor.w())));

				if (isValueAboveThreshold(diff, threshold))
				{
					isOk = false;
					errorMask.getAccess().setPixel(errorColor, x, y, outputNdx);
					break;
				}
				else
					errorMask.getAccess().setPixel(okColor, x, y, outputNdx);
			}
			break;
		}

		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
		{
			const IVec4 refColor	(0, 24, 75, 93);
			const IVec4 threshold	(1, 1, 1, 1);

			typedef bool(*ValueAboveThresholdFn)(const IVec4&, const IVec4&);
			ValueAboveThresholdFn componentToFnMap[4] =
			{
				isValueAboveThreshold1<IVec4>,
				isValueAboveThreshold2<IVec4>,
				isValueAboveThreshold3<IVec4>,
				isValueAboveThreshold4<IVec4>
			};
			ValueAboveThresholdFn isValueAboveThreshold = componentToFnMap[componentCount - 1];

			for (int outputNdx = 0; outputNdx < outputsCount; outputNdx++)
			for (int y = 0; y < (int)m_height; y++)
			for (int x = 0; x < (int)m_width; x++)
			{
				const IVec4 color	(accesses[outputNdx].getPixelInt(x, y));
				const IVec4 diff	(std::abs(color.x() - refColor.x()),
									 std::abs(color.y() - refColor.y()),
									 std::abs(color.z() - refColor.z()),
									 std::abs(color.w() - refColor.w()));

				if (isValueAboveThreshold(diff, threshold))
				{
					isOk = false;
					errorMask.getAccess().setPixel(errorColor, x, y, outputNdx);
					break;
				}
				else
					errorMask.getAccess().setPixel(okColor, x, y, outputNdx);
			}
			break;
		}

		default:
			DE_FATAL("Unknown channel class");
	}

	if (!isOk)
	{
		const std::string			sectionName	("MaxAttachmentsVerify");
		const tcu::ScopedLogSection	section		(log, sectionName, sectionName);

		logImage("ErrorMask", errorMask.getAccess());
		m_resultCollector.fail("Fail");
	}
}

tcu::TestStatus MaxAttachmenstsRenderPassTestInstance::iterate(void)
{
	submitSwitch(m_renderPassType);
	verify();

	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
}

Move<VkDescriptorSetLayout> MaxAttachmenstsRenderPassTestInstance::createDescriptorSetLayout()
{
	const VkDescriptorSetLayoutBinding bindingTemplate =
	{
		0,														// binding
		VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,					// descriptorType
		1u,														// descriptorCount
		VK_SHADER_STAGE_FRAGMENT_BIT,							// stageFlags
		DE_NULL													// pImmutableSamplers
	};

	std::vector<VkDescriptorSetLayoutBinding> bindings(m_attachmentsCount, bindingTemplate);
	for (deUint32 idx = 0; idx < m_attachmentsCount; ++idx)
		bindings[idx].binding = idx;

	const VkDescriptorSetLayoutCreateInfo createInfo =
	{
		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// sType
		DE_NULL,												// pNext
		0u,														// flags
		m_attachmentsCount,										// bindingCount
		&bindings[0]											// pBindings
	};

	return ::createDescriptorSetLayout(m_context.getDeviceInterface(), m_context.getDevice(), &createInfo);
}

Move<VkDescriptorPool> MaxAttachmenstsRenderPassTestInstance::createDescriptorPool()
{
	const VkDescriptorPoolSize size =
	{
		VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,					// type
		m_attachmentsCount										// descriptorCount
	};

	const VkDescriptorPoolCreateInfo createInfo =
	{
		VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,			// sType
		DE_NULL,												// pNext
		VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,		// flags
		1u,														// maxSets
		1u,														// poolSizeCount
		&size													// pPoolSizes
	};

	return ::createDescriptorPool(m_context.getDeviceInterface(), m_context.getDevice(), &createInfo);
}

Move<VkDescriptorSet> MaxAttachmenstsRenderPassTestInstance::createDescriptorSet()
{
	const VkDescriptorSetAllocateInfo allocateInfo =
	{
		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,			// sType
		DE_NULL,												// pNext
		*m_descriptorPool,										// descriptorPool
		1u,														// descriptorSetCount
		&*m_descriptorSetLayout									// pSetLayouts
	};

	const vk::DeviceInterface&		vkd					= m_context.getDeviceInterface();
	vk::VkDevice					device				= m_context.getDevice();
	Move<VkDescriptorSet>			descriptorSet		= allocateDescriptorSet(vkd, device, &allocateInfo);
	vector<VkDescriptorImageInfo>	descriptorImageInfo	(m_attachmentsCount);
	vector<VkWriteDescriptorSet>	descriptorWrites	(m_attachmentsCount);

	for (deUint32 idx = 0; idx < m_attachmentsCount; ++idx)
	{
		const VkDescriptorImageInfo imageInfo =
		{
			DE_NULL,									// VkSampler		sampler
			**m_singlesampleImageViews[idx],			// VkImageView		imageView
			VK_IMAGE_LAYOUT_GENERAL						// VkImageLayout	imageLayout
		};
		descriptorImageInfo[idx] = imageInfo;

		const VkWriteDescriptorSet	write =
		{
			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,		// VkStructureType					sType
			DE_NULL,									// const void*						pNext
			*descriptorSet,								// VkDescriptorSet					dstSet
			(deUint32)idx,								// uint32_t							dstBinding
			0u,											// uint32_t							dstArrayElement
			1u,											// uint32_t							descriptorCount
			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,		// VkDescriptorType					descriptorType
			&descriptorImageInfo[idx],					// const VkDescriptorImageInfo*		pImageInfo
			DE_NULL,									// const VkDescriptorBufferInfo*	pBufferInfo
			DE_NULL										// const VkBufferView*				pTexelBufferView
		};

		descriptorWrites[idx] = write;
	}

	vkd.updateDescriptorSets(device, (deUint32)descriptorWrites.size(), &descriptorWrites[0], 0u, DE_NULL);
	return descriptorSet;
}

template<typename RenderPassTrait>
Move<VkRenderPass> MaxAttachmenstsRenderPassTestInstance::createRenderPass(void)
{
	// make name for RenderPass1Trait or RenderPass2Trait shorter
	typedef RenderPassTrait RPT;

	typedef RenderPassTrait RPT;
	typedef typename RPT::AttDesc				AttDesc;
	typedef typename RPT::AttRef				AttRef;
	typedef typename RPT::SubpassDep			SubpassDep;
	typedef typename RPT::SubpassDesc			SubpassDesc;
	typedef typename RPT::RenderPassCreateInfo	RenderPassCreateInfo;

	const DeviceInterface&	vkd		= m_context.getDeviceInterface();
	VkDevice				device	= m_context.getDevice();
	std::vector<AttDesc>	attachments;
	std::vector<AttRef>		sp0colorAttachmentRefs;
	std::vector<AttRef>		sp0resolveAttachmentRefs;
	std::vector<AttRef>		sp1inAttachmentRefs;
	std::vector<AttRef>		sp1colorAttachmentRefs;

	for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
	{
		// define first subpass outputs
		{
			const AttDesc multisampleAttachment
			(
				DE_NULL,									// pNext
				0u,											// flags
				m_format,									// format
				m_sampleCount,								// samples
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// loadOp
				VK_ATTACHMENT_STORE_OP_STORE,				// storeOp
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// stencilLoadOp
				VK_ATTACHMENT_STORE_OP_DONT_CARE,			// stencilStoreOp
				VK_IMAGE_LAYOUT_UNDEFINED,					// initialLayout
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// finalLayout
			);
			const AttRef attachmentRef
			(
				DE_NULL,
				(deUint32)attachments.size(),				// attachment
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// layout
				0u											// aspectMask
			);
			sp0colorAttachmentRefs.push_back(attachmentRef);
			attachments.push_back(multisampleAttachment);
		}
		// define first subpass resolve attachments
		{
			const AttDesc singlesampleAttachment
			(
				DE_NULL,									// pNext
				0u,											// flags
				m_format,									// format
				VK_SAMPLE_COUNT_1_BIT,						// samples
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// loadOp
				VK_ATTACHMENT_STORE_OP_STORE,				// storeOp
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// stencilLoadOp
				VK_ATTACHMENT_STORE_OP_DONT_CARE,			// stencilStoreOp
				VK_IMAGE_LAYOUT_UNDEFINED,					// initialLayout
				VK_IMAGE_LAYOUT_GENERAL						// finalLayout
			);
			const AttRef attachmentRef
			(
				DE_NULL,									// pNext
				(deUint32)attachments.size(),				// attachment
				VK_IMAGE_LAYOUT_GENERAL,					// layout
				0u											// aspectMask
			);
			sp0resolveAttachmentRefs.push_back(attachmentRef);
			attachments.push_back(singlesampleAttachment);
		}
		// define second subpass inputs
		{
			const AttRef attachmentRef
			(
				DE_NULL,									// pNext
				(deUint32)attachments.size() - 1,			// attachment
				VK_IMAGE_LAYOUT_GENERAL,					// layout
				VK_IMAGE_ASPECT_COLOR_BIT					// aspectMask
			);
			sp1inAttachmentRefs.push_back(attachmentRef);
		}
		// define second subpass outputs - it merges pairs of
		// results that were produced by the first subpass
		if (attachmentNdx < (m_attachmentsCount / 2))
		{
			const AttRef colorAttachmentRef
			(
				DE_NULL,									// pNext
				(deUint32)attachments.size() - 1,			// attachment
				VK_IMAGE_LAYOUT_GENERAL,					// layout
				0u											// aspectMask
			);
			sp1colorAttachmentRefs.push_back(colorAttachmentRef);
		}
	}

	DE_ASSERT(sp0colorAttachmentRefs.size() == sp0resolveAttachmentRefs.size());
	DE_ASSERT(attachments.size() == sp0colorAttachmentRefs.size() + sp0resolveAttachmentRefs.size());

	{
		const SubpassDesc subpass0
		(
															// sType
			DE_NULL,										// pNext
			(VkSubpassDescriptionFlags)0,					// flags
			VK_PIPELINE_BIND_POINT_GRAPHICS,				// pipelineBindPoint
			0u,												// viewMask
			0u,												// inputAttachmentCount
			DE_NULL,										// pInputAttachments
			(deUint32)sp0colorAttachmentRefs.size(),		// colorAttachmentCount
			&sp0colorAttachmentRefs[0],						// pColorAttachments
			&sp0resolveAttachmentRefs[0],					// pResolveAttachments
			DE_NULL,										// pDepthStencilAttachment
			0u,												// preserveAttachmentCount
			DE_NULL											// pPreserveAttachments
		);
		const SubpassDesc subpass1
		(
															// sType
			DE_NULL,										// pNext
			(VkSubpassDescriptionFlags)0,					// flags
			VK_PIPELINE_BIND_POINT_GRAPHICS,				// pipelineBindPoint
			0u,												// viewMask
			(deUint32)sp1inAttachmentRefs.size(),			// inputAttachmentCount
			&sp1inAttachmentRefs[0],						// pInputAttachments
			(deUint32)sp1colorAttachmentRefs.size(),		// colorAttachmentCount
			&sp1colorAttachmentRefs[0],						// pColorAttachments
			DE_NULL,										// pResolveAttachments
			DE_NULL,										// pDepthStencilAttachment
			0u,												// preserveAttachmentCount
			DE_NULL											// pPreserveAttachments
		);
		SubpassDesc subpasses[] =
		{
			subpass0,
			subpass1
		};
		const SubpassDep subpassDependency
		(
			DE_NULL,										// pNext
			0u,												// srcSubpass
			1u,												// dstSubpass
			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,	// srcStageMask
			VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,			// dstStageMask
			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// srcAccessMask
			VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,			// dstAccessMask
			0u,												// dependencyFlags
			0u												// viewOffset
		);
		const RenderPassCreateInfo renderPassCreator
		(
															// sType
			DE_NULL,										// pNext
			(VkRenderPassCreateFlags)0u,					// flags
			(deUint32)attachments.size(),					// attachmentCount
			&attachments[0],								// pAttachments
			2u,												// subpassCount
			subpasses,										// pSubpasses
			1u,												// dependencyCount
			&subpassDependency,								// pDependencies
			0u,												// correlatedViewMaskCount
			DE_NULL											// pCorrelatedViewMasks
		);

		return renderPassCreator.createRenderPass(vkd, device);
	}
}

Move<VkRenderPass> MaxAttachmenstsRenderPassTestInstance::createRenderPassSwitch(const RenderPassType renderPassType)
{
	switch (renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:
			return createRenderPass<RenderPass1Trait>();
		case RENDERPASS_TYPE_RENDERPASS2:
			return createRenderPass<RenderPass2Trait>();
		default:
			TCU_THROW(InternalError, "Impossible");
	}
}

Move<VkPipelineLayout> MaxAttachmenstsRenderPassTestInstance::createRenderPipelineLayout(bool secondSubpass)
{
	const DeviceInterface&	vkd		= m_context.getDeviceInterface();
	VkDevice				device	= m_context.getDevice();

	const VkPipelineLayoutCreateInfo createInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
		DE_NULL,
		(vk::VkPipelineLayoutCreateFlags)0,

		secondSubpass ? 1u : 0u,
		secondSubpass ? &*m_descriptorSetLayout : DE_NULL,

		0u,
		DE_NULL
	};

	return createPipelineLayout(vkd, device, &createInfo);
}

Move<VkPipeline> MaxAttachmenstsRenderPassTestInstance::createRenderPipeline(bool secondSubpass)
{
	const DeviceInterface&			vkd						= m_context.getDeviceInterface();
	VkDevice						device					= m_context.getDevice();
	const vk::BinaryCollection&		binaryCollection		= m_context.getBinaryCollection();
	VkSampleCountFlagBits			sampleCount				= sampleCountBitFromSampleCount(m_sampleCount);
	deUint32						blendStatesCount		= m_attachmentsCount;
	std::string						fragShaderNameBase		= "quad-frag-sp0-";

	if (secondSubpass)
	{
		sampleCount			= VK_SAMPLE_COUNT_1_BIT;
		blendStatesCount	/= 2;
		fragShaderNameBase	= "quad-frag-sp1-";
	}

	std::string						fragShaderName			= fragShaderNameBase + de::toString(m_attachmentsCount);
	const Unique<VkShaderModule>	vertexShaderModule		(createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
	const Unique<VkShaderModule>	fragmentShaderModule	(createShaderModule(vkd, device, binaryCollection.get(fragShaderName), 0u));
	const Move<VkShaderModule>		geometryShaderModule	(m_layerCount == 1 ? Move<VkShaderModule>() : createShaderModule(vkd, device, binaryCollection.get("geom"), 0u));

	// Disable blending
	const VkPipelineColorBlendAttachmentState attachmentBlendState =
	{
		VK_FALSE,
		VK_BLEND_FACTOR_SRC_ALPHA,
		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
		VK_BLEND_OP_ADD,
		VK_BLEND_FACTOR_ONE,
		VK_BLEND_FACTOR_ONE,
		VK_BLEND_OP_ADD,
		VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
	};
	std::vector<VkPipelineColorBlendAttachmentState>	attachmentBlendStates(blendStatesCount, attachmentBlendState);
	const VkPipelineVertexInputStateCreateInfo			vertexInputState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
		DE_NULL,
		(VkPipelineVertexInputStateCreateFlags)0u,

		0u,
		DE_NULL,

		0u,
		DE_NULL
	};
	const tcu::UVec2				renderArea	(m_width, m_height);
	const std::vector<VkViewport>	viewports	(1, makeViewport(renderArea));
	const std::vector<VkRect2D>		scissors	(1, makeRect2D(renderArea));

	const VkPipelineMultisampleStateCreateInfo multisampleState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
		DE_NULL,
		(VkPipelineMultisampleStateCreateFlags)0u,

		sampleCount,
		VK_FALSE,
		0.0f,
		DE_NULL,
		VK_FALSE,
		VK_FALSE,
	};
	const VkPipelineDepthStencilStateCreateInfo depthStencilState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
		DE_NULL,
		(VkPipelineDepthStencilStateCreateFlags)0u,

		VK_FALSE,
		VK_TRUE,
		VK_COMPARE_OP_ALWAYS,
		VK_FALSE,
		VK_TRUE,
		{
			VK_STENCIL_OP_KEEP,
			VK_STENCIL_OP_INCREMENT_AND_WRAP,
			VK_STENCIL_OP_KEEP,
			VK_COMPARE_OP_ALWAYS,
			~0u,
			~0u,
			0xFFu / (m_sampleCount + 1)
		},
		{
			VK_STENCIL_OP_KEEP,
			VK_STENCIL_OP_INCREMENT_AND_WRAP,
			VK_STENCIL_OP_KEEP,
			VK_COMPARE_OP_ALWAYS,
			~0u,
			~0u,
			0xFFu / (m_sampleCount + 1)
		},

		0.0f,
		1.0f
	};
	const VkPipelineColorBlendStateCreateInfo blendState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
		DE_NULL,
		(VkPipelineColorBlendStateCreateFlags)0u,

		VK_FALSE,
		VK_LOGIC_OP_COPY,
		deUint32(attachmentBlendStates.size()),
		&attachmentBlendStates[0],
		{ 0.0f, 0.0f, 0.0f, 0.0f }
	};

	return makeGraphicsPipeline(vkd,																// vk
								device,																// device
								secondSubpass ? *m_pipelineLayoutPass1 : *m_pipelineLayoutPass0,	// pipelineLayout
								*vertexShaderModule,												// vertexShaderModule
								DE_NULL,															// tessellationControlShaderModule
								DE_NULL,															// tessellationEvalShaderModule
								m_layerCount != 1 ? *geometryShaderModule : DE_NULL,				// geometryShaderModule
								*fragmentShaderModule,												// fragmentShaderModule
								*m_renderPass,														// renderPass
								viewports,															// viewports
								scissors,															// scissors
								VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,								// topology
								secondSubpass,														// subpass
								0u,																	// patchControlPoints
								&vertexInputState,													// vertexInputStateCreateInfo
								DE_NULL,															// rasterizationStateCreateInfo
								&multisampleState,													// multisampleStateCreateInfo
								&depthStencilState,													// depthStencilStateCreateInfo
								&blendState);														// colorBlendStateCreateInfo
}

struct Programs
{
	void init(vk::SourceCollections& dst, TestConfig config) const
	{
		const tcu::TextureFormat		format			(mapVkFormat(config.format));
		const tcu::TextureChannelClass	channelClass	(tcu::getTextureChannelClass(format.type));

		dst.glslSources.add("quad-vert") << glu::VertexSource(
			"#version 450\n"
			"out gl_PerVertex {\n"
			"\tvec4 gl_Position;\n"
			"};\n"
			"highp float;\n"
			"void main (void) {\n"
			"\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
			"\t                   ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
			"}\n");

		if (config.layerCount > 1)
		{
			std::ostringstream src;

			src << "#version 450\n"
				<< "highp float;\n"
				<< "\n"
				<< "layout(triangles) in;\n"
				<< "layout(triangle_strip, max_vertices = " << 3 * 2 * config.layerCount << ") out;\n"
				<< "\n"
				<< "in gl_PerVertex {\n"
				<< "    vec4 gl_Position;\n"
				<< "} gl_in[];\n"
				<< "\n"
				<< "out gl_PerVertex {\n"
				<< "    vec4 gl_Position;\n"
				<< "};\n"
				<< "\n"
				<< "void main (void) {\n"
				<< "    for (int layerNdx = 0; layerNdx < " << config.layerCount << "; ++layerNdx) {\n"
				<< "        for(int vertexNdx = 0; vertexNdx < gl_in.length(); vertexNdx++) {\n"
				<< "            gl_Position = gl_in[vertexNdx].gl_Position;\n"
				<< "            gl_Layer    = layerNdx;\n"
				<< "            EmitVertex();\n"
				<< "        };\n"
				<< "        EndPrimitive();\n"
				<< "    };\n"
				<< "}\n";

			dst.glslSources.add("geom") << glu::GeometrySource(src.str());
		}

		const tcu::StringTemplate genericLayoutTemplate("layout(location = ${INDEX}) out ${TYPE_PREFIX}vec4 o_color${INDEX};\n");
		const tcu::StringTemplate genericBodyTemplate("\to_color${INDEX} = ${TYPE_PREFIX}vec4(${COLOR_VAL});\n");

		if (config.testType == RESOLVE)
		{
			const tcu::StringTemplate fragTemplate("#version 450\n"
												   "layout(push_constant) uniform PushConstant {\n"
												   "\thighp uint sampleMask;\n"
												   "} pushConstants;\n"
												   "${LAYOUT}"
												   "void main (void)\n"
												   "{\n"
												   "${BODY}"
												   "}\n");

			std::map<std::string, std::string> parameters;
			switch (channelClass)
			{
				case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
					parameters["TYPE_PREFIX"] = "u";
					parameters["COLOR_VAL"] = "255";
					break;

				case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
					parameters["TYPE_PREFIX"] = "i";
					parameters["COLOR_VAL"] = "127";
					break;

				case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
				case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
				case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
					parameters["TYPE_PREFIX"] = "";
					parameters["COLOR_VAL"] = "1.0";
					break;

				default:
					DE_FATAL("Unknown channel class");
			}

			std::string layoutDefinitions = "";
			std::string shaderBody = "\tgl_SampleMask[0] = int(pushConstants.sampleMask);\n";

			for (deUint32 attIdx = 0; attIdx < config.attachmentCount; ++attIdx)
			{
				parameters["INDEX"]	= de::toString(attIdx);
				layoutDefinitions	+= genericLayoutTemplate.specialize(parameters);
				shaderBody			+= genericBodyTemplate.specialize(parameters);
			}

			parameters["LAYOUT"]	= layoutDefinitions;
			parameters["BODY"]		= shaderBody;
			dst.glslSources.add("quad-frag") << glu::FragmentSource(fragTemplate.specialize(parameters));
		}
		else	// MAX_ATTACMENTS
		{
			const tcu::StringTemplate fragTemplate("#version 450\n"
												   "${LAYOUT}"
												   "void main (void)\n"
												   "{\n"
												   "${BODY}"
												   "}\n");

			std::map<std::string, std::string> parameters;
			switch (channelClass)
			{
				case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
					parameters["TYPE_PREFIX"] = "u";
					parameters["COLOR_VAL"] = "0, 64, 192, 252";
					break;

				case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
					parameters["TYPE_PREFIX"] = "i";
					parameters["COLOR_VAL"] = "0, 32, 100, 124";
					break;

				case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
				case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
				case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
					parameters["TYPE_PREFIX"] = "";
					parameters["COLOR_VAL"] = "0.0, 0.4, 0.8, 1.0";
					break;

				default:
					DE_FATAL("Unknown channel class");
			}

			// parts of fragment shader for second subpass - Vulkan introduced a new uniform type and syntax to glsl for input attachments
			const tcu::StringTemplate subpassLayoutTemplate("layout (input_attachment_index = ${INDEX}, set = 0, binding = ${INDEX}) uniform ${TYPE_PREFIX}subpassInput i_color${INDEX};\n");
			const tcu::StringTemplate subpassFBodyTemplate("\to_color${INDEX} = subpassLoad(i_color${INDEX})*0.5 + subpassLoad(i_color${MIX_INDEX})*0.25;\n");
			const tcu::StringTemplate subpassIBodyTemplate("\to_color${INDEX} = subpassLoad(i_color${INDEX}) / 2 + subpassLoad(i_color${MIX_INDEX}) / 4;\n");

			bool selectIBody = isIntFormat(config.format) || isUintFormat(config.format);
			const tcu::StringTemplate& subpassBodyTemplate = selectIBody ? subpassIBodyTemplate : subpassFBodyTemplate;

			std::string sp0layoutDefinitions	= "";
			std::string sp0shaderBody			= "";
			std::string sp1inLayoutDefinitions	= "";
			std::string sp1outLayoutDefinitions	= "";
			std::string sp1shaderBody			= "";

			deUint32 halfAttachments = config.attachmentCount / 2;
			for (deUint32 attIdx = 0; attIdx < config.attachmentCount; ++attIdx)
			{
				parameters["INDEX"] = de::toString(attIdx);

				sp0layoutDefinitions	+= genericLayoutTemplate.specialize(parameters);
				sp0shaderBody			+= genericBodyTemplate.specialize(parameters);

				sp1inLayoutDefinitions += subpassLayoutTemplate.specialize(parameters);
				if (attIdx < halfAttachments)
				{
					// we are combining pairs of input attachments to produce half the number of outputs
					parameters["MIX_INDEX"]	= de::toString(halfAttachments + attIdx);
					sp1outLayoutDefinitions	+= genericLayoutTemplate.specialize(parameters);
					sp1shaderBody			+= subpassBodyTemplate.specialize(parameters);
				}
			}

			// construct fragment shaders for subpass1 and subpass2; note that there
			// is different shader definition depending on number of attachments
			std::string nameBase	= "quad-frag-sp";
			std::string namePostfix	= de::toString(config.attachmentCount);
			parameters["LAYOUT"]	= sp0layoutDefinitions;
			parameters["BODY"]		= sp0shaderBody;
			dst.glslSources.add(nameBase + "0-" + namePostfix) << glu::FragmentSource(fragTemplate.specialize(parameters));
			parameters["LAYOUT"]	= sp1inLayoutDefinitions + sp1outLayoutDefinitions;
			parameters["BODY"]		= sp1shaderBody;
			dst.glslSources.add(nameBase + "1-" + namePostfix) << glu::FragmentSource(fragTemplate.specialize(parameters));
		}
	}
};

std::string formatToName (VkFormat format)
{
	const std::string	formatStr	= de::toString(format);
	const std::string	prefix		= "VK_FORMAT_";

	DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);

	return de::toLower(formatStr.substr(prefix.length()));
}

void initTests (tcu::TestCaseGroup* group, RenderPassType renderPassType)
{
	static const VkFormat	formats[] =
	{
		VK_FORMAT_R5G6B5_UNORM_PACK16,
		VK_FORMAT_R8_UNORM,
		VK_FORMAT_R8_SNORM,
		VK_FORMAT_R8_UINT,
		VK_FORMAT_R8_SINT,
		VK_FORMAT_R8G8_UNORM,
		VK_FORMAT_R8G8_SNORM,
		VK_FORMAT_R8G8_UINT,
		VK_FORMAT_R8G8_SINT,
		VK_FORMAT_R8G8B8A8_UNORM,
		VK_FORMAT_R8G8B8A8_SNORM,
		VK_FORMAT_R8G8B8A8_UINT,
		VK_FORMAT_R8G8B8A8_SINT,
		VK_FORMAT_R8G8B8A8_SRGB,
		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
		VK_FORMAT_A8B8G8R8_UINT_PACK32,
		VK_FORMAT_A8B8G8R8_SINT_PACK32,
		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
		VK_FORMAT_B8G8R8A8_UNORM,
		VK_FORMAT_B8G8R8A8_SRGB,
		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
		VK_FORMAT_A2B10G10R10_UINT_PACK32,
		VK_FORMAT_R16_UNORM,
		VK_FORMAT_R16_SNORM,
		VK_FORMAT_R16_UINT,
		VK_FORMAT_R16_SINT,
		VK_FORMAT_R16_SFLOAT,
		VK_FORMAT_R16G16_UNORM,
		VK_FORMAT_R16G16_SNORM,
		VK_FORMAT_R16G16_UINT,
		VK_FORMAT_R16G16_SINT,
		VK_FORMAT_R16G16_SFLOAT,
		VK_FORMAT_R16G16B16A16_UNORM,
		VK_FORMAT_R16G16B16A16_SNORM,
		VK_FORMAT_R16G16B16A16_UINT,
		VK_FORMAT_R16G16B16A16_SINT,
		VK_FORMAT_R16G16B16A16_SFLOAT,
		VK_FORMAT_R32_UINT,
		VK_FORMAT_R32_SINT,
		VK_FORMAT_R32_SFLOAT,
		VK_FORMAT_R32G32_UINT,
		VK_FORMAT_R32G32_SINT,
		VK_FORMAT_R32G32_SFLOAT,
		VK_FORMAT_R32G32B32A32_UINT,
		VK_FORMAT_R32G32B32A32_SINT,
		VK_FORMAT_R32G32B32A32_SFLOAT,
	};
	const deUint32			sampleCounts[] =
	{
		2u, 4u, 8u
	};
	const deUint32			layerCounts[] =
	{
		1u, 3u, 6u
	};
	tcu::TestContext&		testCtx	(group->getTestContext());

	for (size_t layerCountNdx = 0; layerCountNdx < DE_LENGTH_OF_ARRAY(layerCounts); layerCountNdx++)
	{
		const deUint32					layerCount		(layerCounts[layerCountNdx]);
		const std::string				layerGroupName	("layers_" + de::toString(layerCount));
		de::MovePtr<tcu::TestCaseGroup>	layerGroup		(new tcu::TestCaseGroup(testCtx, layerGroupName.c_str(), layerGroupName.c_str()));

		for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
		{
			const VkFormat					format		(formats[formatNdx]);
			const std::string				formatName	(formatToName(format));
			de::MovePtr<tcu::TestCaseGroup>	formatGroup	(new tcu::TestCaseGroup(testCtx, formatName.c_str(), formatName.c_str()));

			for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
			{
				const deUint32	sampleCount(sampleCounts[sampleCountNdx]);

				// Skip this test as it is rather slow
				if (layerCount == 6 && sampleCount == 8)
					continue;

				std::string	testName	("samples_" + de::toString(sampleCount));
				TestConfig	testConfig =
				{
					RESOLVE,
					format,
					sampleCount,
					layerCount,
					4u,
					32u,
					32u,
					renderPassType
				};

				formatGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));

				// MaxAttachmenstsRenderPassTest is ment to test extreme cases where applications might consume all available on-chip
				// memory. This is achieved by using maxColorAttachments attachments and two subpasses, but during test creation we
				// dont know what is the maximal number of attachments (spirv tools are not available on all platforms) so we cant
				// construct shaders during test execution. To be able to test this we need to execute tests for all available
				// numbers of attachments despite the fact that we are only interested in the maximal number; test construction code
				// assumes that the number of attachments is power of two
				if (layerCount == 1)
				{
					for (deUint32 power = 2; power < 5; ++power)
					{
						deUint32	attachmentCount = 1 << power;
						std::string	maxAttName		= "max_attachments_" + de::toString(attachmentCount) + "_" + testName;
						testConfig.testType			= MAX_ATTACHMENTS;
						testConfig.attachmentCount	= attachmentCount;
						formatGroup->addChild(new InstanceFactory1<MaxAttachmenstsRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, maxAttName.c_str(), maxAttName.c_str(), testConfig));
					}
				}
			}

			if (layerCount == 1)
				group->addChild(formatGroup.release());
			else
				layerGroup->addChild(formatGroup.release());
		}

		if (layerCount != 1)
			group->addChild(layerGroup.release());
	}
}

} // anonymous

tcu::TestCaseGroup* createRenderPassMultisampleResolveTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "multisample_resolve", "Multisample render pass resolve tests", initTests, RENDERPASS_TYPE_LEGACY);
}

tcu::TestCaseGroup* createRenderPass2MultisampleResolveTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "multisample_resolve", "Multisample render pass resolve tests", initTests, RENDERPASS_TYPE_RENDERPASS2);
}

} // vkt
