/*-------------------------------------------------------------------------
 * 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,
	COMPATIBILITY
};

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

struct TestConfig2 : TestConfig
{
	TestConfig2(const TestConfig& src, deUint32 level)
		: TestConfig	(src)
		, resolveLevel	(level)
	{
	}
	deUint32		resolveLevel;
};

// 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);
	~MultisampleRenderPassTestBase	(void);

protected:

	Move<VkImage>			createImage			(VkSampleCountFlagBits		sampleCountBit,
												 VkImageUsageFlags			usage) const;
	Move<VkImage>			createImage			(VkSampleCountFlagBits		sampleCountBit,
												 VkImageUsageFlags			usage,
												 deUint32					width,
												 deUint32					height,
												 deUint32					mipLevels) const;
	vector<VkImageSp>		createImages		(VkSampleCountFlagBits		sampleCountBit,
												 VkImageUsageFlags			usage) const;
	vector<VkImageSp>		createImages		(VkSampleCountFlagBits		sampleCountBit,
												 VkImageUsageFlags			usage,
												 deUint32					width,
												 deUint32					height,
												 deUint32					mipLevels) const;
	vector<AllocationSp>	createImageMemory	(const vector<VkImageSp>&	images) const;
	vector<VkImageViewSp>	createImageViews	(const vector<VkImageSp>&	images,
												 deUint32					mipLevel = 0) const;

	vector<VkBufferSp>		createBuffers		() const;
	vector<VkBufferSp>		createBuffers		(deUint32					width,
												 deUint32					height,
												 deUint32					mipLevels) 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 bool						m_testCompatibility;
	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)
	: TestInstance				(context)
	, m_featuresSupported		(featuresSupported(context, config))
	, m_extensionSupported		((config.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
	, m_testCompatibility		(config.testType == COMPATIBILITY)
	, m_renderPassType			(config.renderPassType)
	, m_format					(config.format)
	, m_sampleCount				(sampleCountBitFromSampleCount(config.sampleCount))
	, m_layerCount				(config.layerCount)
	, m_attachmentsCount		(config.attachmentCount)
	, m_width					(config.width)
	, m_height					(config.height)
{
}

MultisampleRenderPassTestBase::~MultisampleRenderPassTestBase ()
{
}

Move<VkImage> MultisampleRenderPassTestBase::createImage (VkSampleCountFlagBits sampleCountBit, VkImageUsageFlags usage) const
{
	return createImage(sampleCountBit, usage, m_width, m_height, 1u);
}

Move<VkImage> MultisampleRenderPassTestBase::createImage (VkSampleCountFlagBits	sampleCountBit,
														  VkImageUsageFlags		usage,
														  deUint32				width,
														  deUint32				height,
														  deUint32				mipLevels) 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 =
	{
		width,
		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,
			mipLevels,
			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<VkImageSp> MultisampleRenderPassTestBase::createImages (VkSampleCountFlagBits	sampleCountBit,
															   VkImageUsageFlags		usage,
															   deUint32					width,
															   deUint32					height,
															   deUint32					mipLevels) 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, width, height, mipLevels)));
	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, deUint32 mipLevel) 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,
		mipLevel,
		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
{
	return createBuffers(m_width, m_height, 1u);
}

vector<VkBufferSp> MultisampleRenderPassTestBase::createBuffers (deUint32 width, deUint32 height, deUint32 mipLevels) const
{
	DE_ASSERT(mipLevels);

	VkDeviceSize				size		= 0;
	for (deUint32 level = 0; level < mipLevels; ++level)
	{
		DE_ASSERT(width && height);

		size += (width * height);
		height /= 2;
		width /=2;
	}

	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,

		size * 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			(bool usedResolveAttachment);
	Move<VkRenderPass>		createRenderPassSwitch		(bool usedResolveAttachment);
	Move<VkRenderPass>		createRenderPassCompatible	(void);
	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<VkRenderPass>			m_renderPassCompatible;
	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;
	tcu::TextureLevel					m_sumSrgb;
	deUint32							m_sampleMask;
	tcu::ResultCollector				m_resultCollector;

protected:
	MultisampleRenderPassTestInstance	(Context& context, TestConfig config, deUint32 renderLevel);

	const deUint32						m_renderLevel;
};

MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config)
	: MultisampleRenderPassTestInstance (context, config, /*defaulf render level*/0u)
{
}

MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config, deUint32 renderLevel)
	: MultisampleRenderPassTestBase(context, config)

	, 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, (1u << renderLevel)*m_width, (1u << renderLevel)*m_height, renderLevel+1 ))
	, m_singlesampleImageMemory	(createImageMemory(m_singlesampleImages))
	, m_singlesampleImageViews	(createImageViews(m_singlesampleImages, renderLevel))

	// The "normal" render pass has an unused resolve attachment when testing compatibility.
	, m_renderPass				(createRenderPassSwitch(!m_testCompatibility))
	, m_renderPassCompatible	(createRenderPassCompatible())
	, m_framebuffer				(createFramebuffer(m_multisampleImageViews, m_singlesampleImageViews, *m_renderPass))

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

	, m_buffers					(createBuffers((1u << renderLevel)*m_width, (1u << renderLevel)*m_height, renderLevel+1 ))
	, 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_sumSrgb					(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), m_width, m_height, m_layerCount)
	, m_sampleMask				(0x0u)

	, m_renderLevel				(renderLevel)
{
	tcu::clear(m_sum.getAccess(), Vec4(0.0f, 0.0f, 0.0f, 0.0f));
	tcu::clear(m_sumSrgb.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_testCompatibility ? *m_renderPassCompatible : *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++)
	{
		// assume that buffer(s) have enough memory to store desired amount of mipmaps
		copyImageToBuffer(vkd, *commandBuffer, **m_singlesampleImages[dstNdx], **m_buffers[dstNdx],
						  m_format, tcu::IVec2((1u << m_renderLevel)*m_width, (1u << m_renderLevel)*m_height), m_renderLevel,
						  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));

	deUint32							offset			(0u);
	deUint32							width			((1u << m_renderLevel) * m_width);
	deUint32							height			((1u << m_renderLevel) * m_height);
	deUint32							pixelSize		(static_cast<deUint32>(getPixelSize()));
	for (deUint32 level = 0; level < m_renderLevel; ++level)
	{
		offset += (width * height * pixelSize);
		height /= 2;
		width /= 2;
	}

	std::vector<tcu::ConstPixelBufferAccess> accesses;
	for (deUint32 attachmentIdx = 0; attachmentIdx < m_attachmentsCount; ++attachmentIdx)
	{
		void* const ptr = static_cast<deUint8*>(m_bufferMemory[attachmentIdx]->getHostPtr()) + offset;
		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);

					const Vec4 oldSrgb = m_sumSrgb.getAccess().getPixel(x, y, z);
					m_sumSrgb.getAccess().setPixel(oldSrgb + 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);

				bool failThreshold;

				if (!tcu::isSRGB(format))
				{
					failThreshold = (diff[0] > threshold.x()
										|| diff[1] > threshold.y()
										|| diff[2] > threshold.z()
										|| diff[3] > threshold.w());
				}
				else
				{
					const Vec4	sumSrgb(m_sumSrgb.getAccess().getPixel(x, y, z));
					const Vec4	averageSrgb(sumSrgb / Vec4((float)(0x1u << m_sampleCount)));
					const Vec4	diffSrgb(tcu::abs(averageSrgb - expectedAverage));

					m_sumSrgb.getAccess().setPixel(averageSrgb, x, y, z);

					// Spec doesn't restrict implementation to downsample in linear color space. So, comparing both non linear and
					// linear diff's in case of srgb formats.
					failThreshold = ((diff[0] > threshold.x()
										|| diff[1] > threshold.y()
										|| diff[2] > threshold.z()
										|| diff[3] > threshold.w()) &&
									(diffSrgb[0] > threshold.x()
										|| diffSrgb[1] > threshold.y()
										|| diffSrgb[2] > threshold.z()
										|| diffSrgb[3] > threshold.w()));

				}

				if (failThreshold)
				{
					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 (bool usedResolveAttachment)
{
	// 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 auto attachmentId = (usedResolveAttachment ? static_cast<deUint32>(attachments.size()) : VK_ATTACHMENT_UNUSED);
			const AttRef attachmentRef
			(
															// sType
				DE_NULL,									// pNext
				attachmentId,								// 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 (bool usedResolveAttachment)
{
	switch (m_renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:
			return createRenderPass<RenderPass1Trait>(usedResolveAttachment);
		case RENDERPASS_TYPE_RENDERPASS2:
			return createRenderPass<RenderPass2Trait>(usedResolveAttachment);
		default:
			TCU_THROW(InternalError, "Impossible");
	}
}

Move<VkRenderPass> MultisampleRenderPassTestInstance::createRenderPassCompatible (void)
{
	if (m_testCompatibility)
	{
		// The compatible render pass is always created with a used resolve attachment.
		return createRenderPassSwitch(true);
	}
	else
	{
		return {};
	}
}

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)

	, 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
}

class MultisampleRenderPassResolveLevelTestInstance : public MultisampleRenderPassTestInstance
{
public:
	MultisampleRenderPassResolveLevelTestInstance	(Context& context, TestConfig2 config);
	~MultisampleRenderPassResolveLevelTestInstance	(void) = default;
};

MultisampleRenderPassResolveLevelTestInstance::MultisampleRenderPassResolveLevelTestInstance (Context& context, TestConfig2 config)
	: MultisampleRenderPassTestInstance(context, config, config.resolveLevel)
{
}

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 || config.testType == COMPATIBILITY)
		{
			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));
		}
	}
};

template<class TestConfigType>
void checkSupport(Context& context, TestConfigType config)
{
#ifndef CTS_USES_VULKANSC
	if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
		!context.getPortabilitySubsetFeatures().multisampleArrayImage &&
		(config.sampleCount != VK_SAMPLE_COUNT_1_BIT) && (config.layerCount != 1))
	{
		TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Implementation does not support image array with multiple samples per texel");
	}
#else
	DE_UNREF(context);
	DE_UNREF(config);
#endif // CTS_USES_VULKANSC
}

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,
		VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
	};
	const deUint32			sampleCounts[] =
	{
		2u, 4u, 8u
	};
	const deUint32			layerCounts[] =
	{
		1u, 3u, 6u
	};
	const deUint32			resolveLevels[] =
	{
		2u, 3u, 4u
	};
	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));
				const TestConfig	testConfig =
				{
					RESOLVE,
					format,
					sampleCount,
					layerCount,
					4u,
					32u,
					32u,
					renderPassType
				};

				formatGroup->addChild(new InstanceFactory1WithSupport<MultisampleRenderPassTestInstance, TestConfig, FunctionSupport1<TestConfig>, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig, typename FunctionSupport1<TestConfig>::Args(checkSupport, testConfig)));

				for (deUint32 resolveLevel : resolveLevels)
				{
					const TestConfig2 testConfig2(testConfig, resolveLevel);
					std::string resolveLevelTestNameStr(testName + "_resolve_level_" + de::toString(resolveLevel));
					const char* resolveLevelTestName = resolveLevelTestNameStr.c_str();

					formatGroup->addChild(new InstanceFactory1WithSupport<MultisampleRenderPassResolveLevelTestInstance, TestConfig2, FunctionSupport1<TestConfig2>, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, resolveLevelTestName, resolveLevelTestName, testConfig2, typename FunctionSupport1<TestConfig2>::Args(checkSupport, testConfig2)));
				}

				// 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	maxAttachmentsTestConfig		= testConfig;
						maxAttachmentsTestConfig.testType			= MAX_ATTACHMENTS;
						maxAttachmentsTestConfig.attachmentCount	= attachmentCount;

						formatGroup->addChild(new InstanceFactory1<MaxAttachmenstsRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, maxAttName.c_str(), maxAttName.c_str(), maxAttachmentsTestConfig));
					}

					{
						std::string	compatibilityTestName			= "compatibility_" + testName;

						TestConfig	compatibilityTestConfig			= testConfig;
						compatibilityTestConfig.testType			= COMPATIBILITY;
						compatibilityTestConfig.attachmentCount		= 1;

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

			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
