/*-------------------------------------------------------------------------
 * 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 passses with multisample attachments
 *//*--------------------------------------------------------------------*/

#include "vktRenderPassMultisampleTests.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 "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::Vec4;

using tcu::Maybe;
using tcu::just;

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

using tcu::TestLog;

using std::pair;
using std::string;
using std::vector;

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<VkPipeline> > VkPipelineSp;

namespace vkt
{
namespace
{
using namespace renderpass;

enum
{
	MAX_COLOR_ATTACHMENT_COUNT = 4u
};

enum TestSeparateUsage
{
	TEST_DEPTH	 = (1 << 0),
	TEST_STENCIL = (1 << 1)
};

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

VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat)
{
	const tcu::TextureFormat	format		(mapVkFormat(vkFormat));
	const bool					hasDepth	(tcu::hasDepthComponent(format.order));
	const bool					hasStencil	(tcu::hasStencilComponent(format.order));

	if (hasDepth || hasStencil)
	{
		return (hasDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : (VkImageAspectFlagBits)0u)
				| (hasStencil ? VK_IMAGE_ASPECT_STENCIL_BIT : (VkImageAspectFlagBits)0u);
	}
	else
		return VK_IMAGE_ASPECT_COLOR_BIT;
}

void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
{
	VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
}

void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
{
	VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
}

de::MovePtr<Allocation> createBufferMemory (const DeviceInterface&	vk,
											VkDevice				device,
											Allocator&				allocator,
											VkBuffer				buffer)
{
	de::MovePtr<Allocation> allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
	bindBufferMemory(vk, device, buffer, allocation->getMemory(), allocation->getOffset());
	return allocation;
}

de::MovePtr<Allocation> createImageMemory (const DeviceInterface&	vk,
										   VkDevice					device,
										   Allocator&				allocator,
										   VkImage					image)
{
	de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(vk, device, image), MemoryRequirement::Any));
	bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
	return allocation;
}

Move<VkImage> createImage (const DeviceInterface&	vk,
						   VkDevice					device,
						   VkImageCreateFlags		flags,
						   VkImageType				imageType,
						   VkFormat					format,
						   VkExtent3D				extent,
						   deUint32					mipLevels,
						   deUint32					arrayLayers,
						   VkSampleCountFlagBits	samples,
						   VkImageTiling			tiling,
						   VkImageUsageFlags		usage,
						   VkSharingMode			sharingMode,
						   deUint32					queueFamilyCount,
						   const deUint32*			pQueueFamilyIndices,
						   VkImageLayout			initialLayout,
						   TestSeparateUsage		separateStencilUsage)
{
	VkImageUsageFlags depthUsage	= (separateStencilUsage == TEST_DEPTH)	 ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
	VkImageUsageFlags stencilUsage	= (separateStencilUsage == TEST_STENCIL) ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;

	const VkImageStencilUsageCreateInfo stencilUsageInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,
		DE_NULL,
		stencilUsage
	};

	const VkImageCreateInfo pCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
		separateStencilUsage ? &stencilUsageInfo : DE_NULL,
		flags,
		imageType,
		format,
		extent,
		mipLevels,
		arrayLayers,
		samples,
		tiling,
		separateStencilUsage ? depthUsage : usage,
		sharingMode,
		queueFamilyCount,
		pQueueFamilyIndices,
		initialLayout
	};

	return createImage(vk, device, &pCreateInfo);
}

Move<VkImageView> createImageView (const DeviceInterface&	vk,
								   VkDevice					device,
								   VkImageViewCreateFlags	flags,
								   VkImage					image,
								   VkImageViewType			viewType,
								   VkFormat					format,
								   VkComponentMapping		components,
								   VkImageSubresourceRange	subresourceRange)
{
	const VkImageViewCreateInfo pCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
		DE_NULL,
		flags,
		image,
		viewType,
		format,
		components,
		subresourceRange,
	};
	return createImageView(vk, device, &pCreateInfo);
}

Move<VkImage> createImage (const InstanceInterface&	vki,
						   VkPhysicalDevice			physicalDevice,
						   const DeviceInterface&	vkd,
						   VkDevice					device,
						   VkFormat					vkFormat,
						   VkSampleCountFlagBits	sampleCountBit,
						   VkImageUsageFlags		usage,
						   deUint32					width,
						   deUint32					height,
						   TestSeparateUsage		separateStencilUsage = (TestSeparateUsage)0u)
{
	try
	{
		const tcu::TextureFormat		format					(mapVkFormat(vkFormat));
		const VkImageType				imageType				(VK_IMAGE_TYPE_2D);
		const VkImageTiling				imageTiling				(VK_IMAGE_TILING_OPTIMAL);
		const VkFormatProperties		formatProperties		(getPhysicalDeviceFormatProperties(vki, physicalDevice, vkFormat));
		const VkImageFormatProperties	imageFormatProperties	(getPhysicalDeviceImageFormatProperties(vki, physicalDevice, vkFormat, imageType, imageTiling, usage, 0u));
		const VkImageUsageFlags			depthUsage				= (separateStencilUsage == TEST_DEPTH)	 ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
		const VkImageUsageFlags			stencilUsage			= (separateStencilUsage == TEST_STENCIL) ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
		const VkExtent3D				imageExtent				=
		{
			width,
			height,
			1u
		};

		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 & sampleCountBit) == 0))
		{
			TCU_THROW(NotSupportedError, "Image type not supported");
		}

		if (separateStencilUsage)
		{
			const VkImageStencilUsageCreateInfo	stencilUsageInfo =
			{
				VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,				//	VkStructureType			sType
				DE_NULL,														//	const void*				pNext
				stencilUsage													//	VkImageUsageFlags		stencilUsage
			};

			const VkPhysicalDeviceImageFormatInfo2 formatInfo2 =
			{
				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,			//	VkStructureType			sType
				&stencilUsageInfo,												//	const void*				pNext
				vkFormat,														//	VkFormat				format
				imageType,														//	VkImageType				type
				imageTiling,													//	VkImageTiling			tiling
				depthUsage,														//	VkImageUsageFlags		usage
				(VkImageCreateFlags)0u											//	VkImageCreateFlags		flags
			};

			VkImageFormatProperties2				extProperties =
			{
				VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
				DE_NULL,
			{
				{
					0,	// width
					0,	// height
					0,	// depth
				},
				0u,		// maxMipLevels
				0u,		// maxArrayLayers
				0,		// sampleCounts
				0u,		// maxResourceSize
			},
			};

			if ((vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &formatInfo2, &extProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
				|| extProperties.imageFormatProperties.maxExtent.width < imageExtent.width
				|| extProperties.imageFormatProperties.maxExtent.height < imageExtent.height
				|| ((extProperties.imageFormatProperties.sampleCounts & sampleCountBit) == 0))
			{
				TCU_THROW(NotSupportedError, "Image format not supported");
			}

		}

		return createImage(vkd, device, 0u, imageType, vkFormat, imageExtent, 1u, 1u, sampleCountBit, imageTiling, usage, VK_SHARING_MODE_EXCLUSIVE, 0u, DE_NULL, VK_IMAGE_LAYOUT_UNDEFINED, separateStencilUsage);
	}
	catch (const vk::Error& error)
	{
		if (error.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
			TCU_THROW(NotSupportedError, "Image format not supported");

		throw;
	}
}

Move<VkImageView> createImageAttachmentView (const DeviceInterface&	vkd,
											 VkDevice				device,
											 VkImage				image,
											 VkFormat				format,
											 VkImageAspectFlags		aspect)
{
	const VkImageSubresourceRange	range =
	{
		aspect,
		0u,
		1u,
		0u,
		1u
	};

	return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
}

Move<VkImageView> createSrcPrimaryInputImageView (const DeviceInterface&	vkd,
												  VkDevice					device,
												  VkImage					image,
												  VkFormat					format,
												  VkImageAspectFlags		aspect,
												  TestSeparateUsage			testSeparateUsage)
{
	VkImageAspectFlags primaryDepthStencilAspect = (testSeparateUsage == TEST_STENCIL) ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;

	const VkImageSubresourceRange	range =
	{
		aspect == (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT)
			? primaryDepthStencilAspect
			: aspect,
		0u,
		1u,
		0u,
		1u
	};

	return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
}

Move<VkImageView> createSrcSecondaryInputImageView (const DeviceInterface&	vkd,
													VkDevice				device,
													VkImage					image,
													VkFormat				format,
													VkImageAspectFlags		aspect,
													TestSeparateUsage		separateStencilUsage)
{
	if ((aspect == (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT)) && !separateStencilUsage)
	{
		const VkImageSubresourceRange	range =
		{
			VK_IMAGE_ASPECT_STENCIL_BIT,
			0u,
			1u,
			0u,
			1u
		};

		return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
	}
	else
		return Move<VkImageView>();
}

VkDeviceSize getPixelSize (VkFormat vkFormat)
{
	const tcu::TextureFormat	format	(mapVkFormat(vkFormat));

	return format.getPixelSize();
}

Move<VkBuffer> createBuffer (const DeviceInterface&		vkd,
							 VkDevice					device,
							 VkFormat					format,
							 deUint32					width,
							 deUint32					height)
{
	const VkBufferUsageFlags	bufferUsage			(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
	const VkDeviceSize			pixelSize			(getPixelSize(format));
	const VkBufferCreateInfo	createInfo			=
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
		DE_NULL,
		0u,

		width * height * pixelSize,
		bufferUsage,

		VK_SHARING_MODE_EXCLUSIVE,
		0u,
		DE_NULL
	};
	return createBuffer(vkd, device, &createInfo);
}

VkSampleCountFlagBits sampleCountBitFromomSampleCount (deUint32 count)
{
	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)(0x1u << count);
	}
}

std::vector<VkImageSp> createMultisampleImages (const InstanceInterface&	vki,
												VkPhysicalDevice			physicalDevice,
												const DeviceInterface&		vkd,
												VkDevice					device,
												VkFormat					format,
												deUint32					sampleCount,
												deUint32					width,
												deUint32					height)
{
	std::vector<VkImageSp> images (sampleCount);

	for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
		images[imageNdx] = safeSharedPtr(new vk::Unique<VkImage>(createImage(vki, physicalDevice, vkd, device, format, sampleCountBitFromomSampleCount(sampleCount), VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, width, height)));

	return images;
}

std::vector<VkImageSp> createSingleSampleImages (const InstanceInterface&	vki,
												 VkPhysicalDevice			physicalDevice,
												 const DeviceInterface&		vkd,
												 VkDevice					device,
												 VkFormat					format,
												 deUint32					sampleCount,
												 deUint32					width,
												 deUint32					height)
{
	std::vector<VkImageSp> images (sampleCount);

	for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
		images[imageNdx] = safeSharedPtr(new vk::Unique<VkImage>(createImage(vki, physicalDevice, vkd, device, format, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, width, height)));

	return images;
}

std::vector<de::SharedPtr<Allocation> > createImageMemory (const DeviceInterface&		vkd,
														   VkDevice						device,
														   Allocator&					allocator,
														   const std::vector<VkImageSp>	images)
{
	std::vector<de::SharedPtr<Allocation> > memory (images.size());

	for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
		memory[memoryNdx] = safeSharedPtr(createImageMemory(vkd, device, allocator, **images[memoryNdx]).release());

	return memory;
}

std::vector<VkImageViewSp> createImageAttachmentViews (const DeviceInterface&			vkd,
													   VkDevice							device,
													   const std::vector<VkImageSp>&	images,
													   VkFormat							format,
													   VkImageAspectFlagBits			aspect)
{
	std::vector<VkImageViewSp> views (images.size());

	for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
		views[imageNdx] = safeSharedPtr(new vk::Unique<VkImageView>(createImageAttachmentView(vkd, device, **images[imageNdx], format, aspect)));

	return views;
}

std::vector<VkBufferSp> createBuffers (const DeviceInterface&	vkd,
									   VkDevice					device,
									   VkFormat					format,
									   deUint32					sampleCount,
									   deUint32					width,
									   deUint32					height)
{
	std::vector<VkBufferSp> buffers (sampleCount);

	for (size_t bufferNdx = 0; bufferNdx < buffers.size(); bufferNdx++)
		buffers[bufferNdx] = safeSharedPtr(new vk::Unique<VkBuffer>(createBuffer(vkd, device, format, width, height)));

	return buffers;
}

std::vector<de::SharedPtr<Allocation> > createBufferMemory (const DeviceInterface&			vkd,
															VkDevice						device,
															Allocator&						allocator,
															const std::vector<VkBufferSp>	buffers)
{
	std::vector<de::SharedPtr<Allocation> > memory (buffers.size());

	for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
		memory[memoryNdx] = safeSharedPtr(createBufferMemory(vkd, device, allocator, **buffers[memoryNdx]).release());

	return memory;
}

template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
Move<VkRenderPass> createRenderPass (const DeviceInterface&	vkd,
									 VkDevice				device,
									 VkFormat				srcFormat,
									 VkFormat				dstFormat,
									 deUint32				sampleCount,
									 RenderingType			renderingType,
									 TestSeparateUsage		separateStencilUsage)
{
	const VkSampleCountFlagBits		samples						(sampleCountBitFromomSampleCount(sampleCount));
	const deUint32					splitSubpassCount			(deDivRoundUp32(sampleCount, MAX_COLOR_ATTACHMENT_COUNT));
	const tcu::TextureFormat		format						(mapVkFormat(srcFormat));
	const bool						isDepthStencilFormat		(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order));
	const VkImageAspectFlags		inputAspect					(separateStencilUsage == TEST_DEPTH ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT
																: separateStencilUsage == TEST_STENCIL ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT
																									   : getImageAspectFlags(srcFormat));
	vector<SubpassDesc>				subpasses;
	vector<vector<AttachmentRef> >	dstAttachmentRefs			(splitSubpassCount);
	vector<vector<AttachmentRef> >	dstResolveAttachmentRefs	(splitSubpassCount);
	vector<AttachmentDesc>			attachments;
	vector<SubpassDep>				dependencies;
	const AttachmentRef				srcAttachmentRef				//  VkAttachmentReference										||  VkAttachmentReference2KHR
	(
																	//																||  VkStructureType						sType;
		DE_NULL,													//																||  const void*							pNext;
		0u,															//  deUint32						attachment;					||  deUint32							attachment;
		isDepthStencilFormat										//  VkImageLayout					layout;						||  VkImageLayout						layout;
			? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
			: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
		0u															//																||  VkImageAspectFlags					aspectMask;
	);
	const AttachmentRef				srcAttachmentInputRef			//  VkAttachmentReference										||  VkAttachmentReference2KHR
	(
																	//																||  VkStructureType						sType;
		DE_NULL,													//																||  const void*							pNext;
		0u,															//  deUint32						attachment;					||  deUint32							attachment;
		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,					//  VkImageLayout					layout;						||  VkImageLayout						layout;
		(renderingType == RENDERING_TYPE_RENDERPASS2)				//																||  VkImageAspectFlags					aspectMask;
			? inputAspect
			: 0u
	);

	{
		const AttachmentDesc srcAttachment							//  VkAttachmentDescription										||  VkAttachmentDescription2KHR
		(
																	//																||  VkStructureType						sType;
			DE_NULL,												//																||  const void*							pNext;
			0u,														//  VkAttachmentDescriptionFlags	flags;						||  VkAttachmentDescriptionFlags		flags;
			srcFormat,												//  VkFormat						format;						||  VkFormat							format;
			samples,												//  VkSampleCountFlagBits			samples;					||  VkSampleCountFlagBits				samples;
			VK_ATTACHMENT_LOAD_OP_DONT_CARE,						//  VkAttachmentLoadOp				loadOp;						||  VkAttachmentLoadOp					loadOp;
			VK_ATTACHMENT_STORE_OP_DONT_CARE,						//  VkAttachmentStoreOp				storeOp;					||  VkAttachmentStoreOp					storeOp;
			VK_ATTACHMENT_LOAD_OP_DONT_CARE,						//  VkAttachmentLoadOp				stencilLoadOp;				||  VkAttachmentLoadOp					stencilLoadOp;
			VK_ATTACHMENT_STORE_OP_DONT_CARE,						//  VkAttachmentStoreOp				stencilStoreOp;				||  VkAttachmentStoreOp					stencilStoreOp;
			VK_IMAGE_LAYOUT_UNDEFINED,								//  VkImageLayout					initialLayout;				||  VkImageLayout						initialLayout;
			VK_IMAGE_LAYOUT_GENERAL									//  VkImageLayout					finalLayout;				||  VkImageLayout						finalLayout;
		);

		attachments.push_back(srcAttachment);
	}

	for (deUint32 splitSubpassIndex = 0; splitSubpassIndex < splitSubpassCount; splitSubpassIndex++)
	{
		for (deUint32 sampleNdx = 0; sampleNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, sampleCount  - splitSubpassIndex * MAX_COLOR_ATTACHMENT_COUNT); sampleNdx++)
		{
			// Multisample color attachment
			{
				const AttachmentDesc dstAttachment					//  VkAttachmentDescription										||  VkAttachmentDescription2KHR
				(
																	//																||  VkStructureType						sType;
					DE_NULL,										//																||  const void*							pNext;
					0u,												//  VkAttachmentDescriptionFlags	flags;						||  VkAttachmentDescriptionFlags		flags;
					dstFormat,										//  VkFormat						format;						||  VkFormat							format;
					samples,										//  VkSampleCountFlagBits			samples;					||  VkSampleCountFlagBits				samples;
					VK_ATTACHMENT_LOAD_OP_DONT_CARE,				//  VkAttachmentLoadOp				loadOp;						||  VkAttachmentLoadOp					loadOp;
					VK_ATTACHMENT_STORE_OP_DONT_CARE,				//  VkAttachmentStoreOp				storeOp;					||  VkAttachmentStoreOp					storeOp;
					VK_ATTACHMENT_LOAD_OP_DONT_CARE,				//  VkAttachmentLoadOp				stencilLoadOp;				||  VkAttachmentLoadOp					stencilLoadOp;
					VK_ATTACHMENT_STORE_OP_DONT_CARE,				//  VkAttachmentStoreOp				stencilStoreOp;				||  VkAttachmentStoreOp					stencilStoreOp;
					VK_IMAGE_LAYOUT_UNDEFINED,						//  VkImageLayout					initialLayout;				||  VkImageLayout						initialLayout;
					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL		//  VkImageLayout					finalLayout;				||  VkImageLayout						finalLayout;
				);
				const AttachmentRef dstAttachmentRef				//  VkAttachmentReference										||  VkAttachmentReference2KHR
				(
																	//																||  VkStructureType						sType;
					DE_NULL,										//																||  const void*							pNext;
					(deUint32)attachments.size(),					//  deUint32						attachment;					||  deUint32							attachment;
					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		//  VkImageLayout					layout;						||  VkImageLayout						layout;
					0u												//																||  VkImageAspectFlags					aspectMask;
				);

				attachments.push_back(dstAttachment);
				dstAttachmentRefs[splitSubpassIndex].push_back(dstAttachmentRef);
			}
			// Resolve attachment
			{
				const AttachmentDesc dstAttachment					//  VkAttachmentDescription										||  VkAttachmentDescription2KHR
				(
																	//																||  VkStructureType						sType;
					DE_NULL,										//																||  const void*							pNext;
					0u,												//  VkAttachmentDescriptionFlags	flags;						||  VkAttachmentDescriptionFlags		flags;
					dstFormat,										//  VkFormat						format;						||  VkFormat							format;
					VK_SAMPLE_COUNT_1_BIT,							//  VkSampleCountFlagBits			samples;					||  VkSampleCountFlagBits				samples;
					VK_ATTACHMENT_LOAD_OP_DONT_CARE,				//  VkAttachmentLoadOp				loadOp;						||  VkAttachmentLoadOp					loadOp;
					VK_ATTACHMENT_STORE_OP_STORE,					//  VkAttachmentStoreOp				storeOp;					||  VkAttachmentStoreOp					storeOp;
					VK_ATTACHMENT_LOAD_OP_DONT_CARE,				//  VkAttachmentLoadOp				stencilLoadOp;				||  VkAttachmentLoadOp					stencilLoadOp;
					VK_ATTACHMENT_STORE_OP_STORE,					//  VkAttachmentStoreOp				stencilStoreOp;				||  VkAttachmentStoreOp					stencilStoreOp;
					VK_IMAGE_LAYOUT_UNDEFINED,						//  VkImageLayout					initialLayout;				||  VkImageLayout						initialLayout;
					VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL			//  VkImageLayout					finalLayout;				||  VkImageLayout						finalLayout;
				);
				const AttachmentRef dstAttachmentRef				//  VkAttachmentReference										||  VkAttachmentReference2KHR
				(
																	//																||  VkStructureType						sType;
					DE_NULL,										//																||  const void*							pNext;
					(deUint32)attachments.size(),					//  deUint32						attachment;					||  deUint32							attachment;
					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		//  VkImageLayout					layout;						||  VkImageLayout						layout;
					0u												//																||  VkImageAspectFlags					aspectMask;
				);

				attachments.push_back(dstAttachment);
				dstResolveAttachmentRefs[splitSubpassIndex].push_back(dstAttachmentRef);
			}
		}
	}

	{
		{
			const SubpassDesc	subpass								//  VkSubpassDescription										||  VkSubpassDescription2KHR
			(
																	//																||  VkStructureType						sType;
				DE_NULL,											//																||  const void*							pNext;
				(VkSubpassDescriptionFlags)0,						//  VkSubpassDescriptionFlags		flags;						||  VkSubpassDescriptionFlags			flags;
				VK_PIPELINE_BIND_POINT_GRAPHICS,					//  VkPipelineBindPoint				pipelineBindPoint;			||  VkPipelineBindPoint					pipelineBindPoint;
				0u,													//																||  deUint32							viewMask;
				0u,													//  deUint32						inputAttachmentCount;		||  deUint32							inputAttachmentCount;
				DE_NULL,											//  const VkAttachmentReference*	pInputAttachments;			||  const VkAttachmentReference2KHR*	pInputAttachments;
				isDepthStencilFormat ? 0u : 1u,						//  deUint32						colorAttachmentCount;		||  deUint32							colorAttachmentCount;
				isDepthStencilFormat ? DE_NULL : &srcAttachmentRef,	//  const VkAttachmentReference*	pColorAttachments;			||  const VkAttachmentReference2KHR*	pColorAttachments;
				DE_NULL,											//  const VkAttachmentReference*	pResolveAttachments;		||  const VkAttachmentReference2KHR*	pResolveAttachments;
				isDepthStencilFormat ? &srcAttachmentRef : DE_NULL,	//  const VkAttachmentReference*	pDepthStencilAttachment;	||  const VkAttachmentReference2KHR*	pDepthStencilAttachment;
				0u,													//  deUint32						preserveAttachmentCount;	||  deUint32							preserveAttachmentCount;
				DE_NULL												//  const deUint32*					pPreserveAttachments;		||  const deUint32*						pPreserveAttachments;
			);

			subpasses.push_back(subpass);
		}

		for (deUint32 splitSubpassIndex = 0; splitSubpassIndex < splitSubpassCount; splitSubpassIndex++)
		{
			{
				const SubpassDesc	subpass									//  VkSubpassDescription										||  VkSubpassDescription2KHR
				(
																			//																||  VkStructureType						sType;
					DE_NULL,												//																||  const void*							pNext;
					(VkSubpassDescriptionFlags)0,							//  VkSubpassDescriptionFlags		flags;						||  VkSubpassDescriptionFlags			flags;
					VK_PIPELINE_BIND_POINT_GRAPHICS,						//  VkPipelineBindPoint				pipelineBindPoint;			||  VkPipelineBindPoint					pipelineBindPoint;
					0u,														//																||  deUint32							viewMask;
					1u,														//  deUint32						inputAttachmentCount;		||  deUint32							inputAttachmentCount;
					&srcAttachmentInputRef,									//  const VkAttachmentReference*	pInputAttachments;			||  const VkAttachmentReference2KHR*	pInputAttachments;
					(deUint32)dstAttachmentRefs[splitSubpassIndex].size(),	//  deUint32						colorAttachmentCount;		||  deUint32							colorAttachmentCount;
					&dstAttachmentRefs[splitSubpassIndex][0],				//  const VkAttachmentReference*	pColorAttachments;			||  const VkAttachmentReference2KHR*	pColorAttachments;
					&dstResolveAttachmentRefs[splitSubpassIndex][0],		//  const VkAttachmentReference*	pResolveAttachments;		||  const VkAttachmentReference2KHR*	pResolveAttachments;
					DE_NULL,												//  const VkAttachmentReference*	pDepthStencilAttachment;	||  const VkAttachmentReference2KHR*	pDepthStencilAttachment;
					0u,														//  deUint32						preserveAttachmentCount;	||  deUint32							preserveAttachmentCount;
					DE_NULL													//  const deUint32*					pPreserveAttachments;		||  const deUint32*						pPreserveAttachments;
				);
				subpasses.push_back(subpass);
			}
			{
				const SubpassDep	dependency																//  VkSubpassDependency							||  VkSubpassDependency2KHR
				(
																											//												||	VkStructureType			sType;
					DE_NULL,																				//												||	const void*				pNext;
					0u,																						//  deUint32				srcSubpass;			||	deUint32				srcSubpass;
					splitSubpassIndex + 1,																	//  deUint32				dstSubpass;			||	deUint32				dstSubpass;
					VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,											//  VkPipelineStageFlags	srcStageMask;		||	VkPipelineStageFlags	srcStageMask;
					VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,													//  VkPipelineStageFlags	dstStageMask;		||	VkPipelineStageFlags	dstStageMask;
					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,	//  VkAccessFlags			srcAccessMask;		||	VkAccessFlags			srcAccessMask;
					VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,													//  VkAccessFlags			dstAccessMask;		||	VkAccessFlags			dstAccessMask;
					VK_DEPENDENCY_BY_REGION_BIT,															//  VkDependencyFlags		dependencyFlags;	||	VkDependencyFlags		dependencyFlags;
					0u																						//												||	deInt32					viewOffset;
				);

				dependencies.push_back(dependency);
			}
		}
		// the last subpass must synchronize with all prior subpasses
		for (deUint32 splitSubpassIndex = 0; splitSubpassIndex < (splitSubpassCount - 1); splitSubpassIndex++)
		{
				const SubpassDep	dependency																//  VkSubpassDependency							||  VkSubpassDependency2KHR
				(
																											//												||	VkStructureType			sType;
					DE_NULL,																				//												||	const void*				pNext;
					splitSubpassIndex + 1,																	//  deUint32				srcSubpass;			||	deUint32				srcSubpass;
					splitSubpassCount,																		//  deUint32				dstSubpass;			||	deUint32				dstSubpass;
					VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
					| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,											//  VkPipelineStageFlags	srcStageMask;		||	VkPipelineStageFlags	srcStageMask;
					VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,													//  VkPipelineStageFlags	dstStageMask;		||	VkPipelineStageFlags	dstStageMask;
					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,	//  VkAccessFlags			srcAccessMask;		||	VkAccessFlags			srcAccessMask;
					VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,													//  VkAccessFlags			dstAccessMask;		||	VkAccessFlags			dstAccessMask;
					VK_DEPENDENCY_BY_REGION_BIT,															//  VkDependencyFlags		dependencyFlags;	||	VkDependencyFlags		dependencyFlags;
					0u																						//												||	deInt32					viewOffset;
				);
				dependencies.push_back(dependency);
		}
		const RenderPassCreateInfo	renderPassCreator						//  VkRenderPassCreateInfo										||  VkRenderPassCreateInfo2KHR
		(
																			//  VkStructureType					sType;						||  VkStructureType						sType;
			DE_NULL,														//  const void*						pNext;						||  const void*							pNext;
			(VkRenderPassCreateFlags)0u,									//  VkRenderPassCreateFlags			flags;						||  VkRenderPassCreateFlags				flags;
			(deUint32)attachments.size(),									//  deUint32						attachmentCount;			||  deUint32							attachmentCount;
			&attachments[0],												//  const VkAttachmentDescription*	pAttachments;				||  const VkAttachmentDescription2KHR*	pAttachments;
			(deUint32)subpasses.size(),										//  deUint32						subpassCount;				||  deUint32							subpassCount;
			&subpasses[0],													//  const VkSubpassDescription*		pSubpasses;					||  const VkSubpassDescription2KHR*		pSubpasses;
			(deUint32)dependencies.size(),									//  deUint32						dependencyCount;			||  deUint32							dependencyCount;
			&dependencies[0],												//  const VkSubpassDependency*		pDependencies;				||  const VkSubpassDependency2KHR*		pDependencies;
			0u,																//																||  deUint32							correlatedViewMaskCount;
			DE_NULL															//																||  const deUint32*						pCorrelatedViewMasks;
		);

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

Move<VkRenderPass> createRenderPass (const DeviceInterface&		vkd,
									 VkDevice					device,
									 VkFormat					srcFormat,
									 VkFormat					dstFormat,
									 deUint32					sampleCount,
									 const RenderingType		renderingType,
									 const TestSeparateUsage	separateStencilUsage)
{
	switch (renderingType)
	{
		case RENDERING_TYPE_RENDERPASS_LEGACY:
			return createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vkd, device, srcFormat, dstFormat, sampleCount, renderingType, separateStencilUsage);
		case RENDERING_TYPE_RENDERPASS2:
			return createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vkd, device, srcFormat, dstFormat, sampleCount, renderingType, separateStencilUsage);
		default:
			TCU_THROW(InternalError, "Impossible");
	}
}

Move<VkFramebuffer> createFramebuffer (const DeviceInterface&				vkd,
									   VkDevice								device,
									   VkRenderPass							renderPass,
									   VkImageView							srcImageView,
									   const std::vector<VkImageViewSp>&	dstMultisampleImageViews,
									   const std::vector<VkImageViewSp>&	dstSinglesampleImageViews,
									   deUint32								width,
									   deUint32								height)
{
	std::vector<VkImageView> attachments;

	attachments.reserve(dstMultisampleImageViews.size() + dstSinglesampleImageViews.size() + 1u);

	attachments.push_back(srcImageView);

	DE_ASSERT(dstMultisampleImageViews.size() == dstSinglesampleImageViews.size());

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

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

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

		width,
		height,
		1u
	};

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

Move<VkPipelineLayout> createRenderPipelineLayout (const DeviceInterface&	vkd,
												   VkDevice					device)
{
	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> createRenderPipeline (const DeviceInterface&		vkd,
									   VkDevice						device,
									   VkFormat						srcFormat,
									   VkRenderPass					renderPass,
									   VkPipelineLayout				pipelineLayout,
									   const vk::BinaryCollection&	binaryCollection,
									   deUint32						width,
									   deUint32						height,
									   deUint32						sampleCount)
{
	const tcu::TextureFormat		format						(mapVkFormat(srcFormat));
	const bool						isDepthStencilFormat		(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order));

	const Unique<VkShaderModule>	vertexShaderModule			(createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
	const Unique<VkShaderModule>	fragmentShaderModule		(createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 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
	};
	const VkPipelineVertexInputStateCreateInfo vertexInputState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
		DE_NULL,
		(VkPipelineVertexInputStateCreateFlags)0u,

		0u,
		DE_NULL,

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

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

		sampleCountBitFromomSampleCount(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_TRUE,
		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 / (sampleCount + 1)
		},
		{
			VK_STENCIL_OP_KEEP,
			VK_STENCIL_OP_INCREMENT_AND_WRAP,
			VK_STENCIL_OP_KEEP,
			VK_COMPARE_OP_ALWAYS,
			~0u,
			~0u,
			0xFFu / (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,
		(isDepthStencilFormat ? 0u : 1u),
		(isDepthStencilFormat ? DE_NULL : &attachmentBlendState),
		{ 0.0f, 0.0f, 0.0f, 0.0f }
	};

	return makeGraphicsPipeline(vkd,									// const DeviceInterface&                        vk
								device,									// const VkDevice                                device
								pipelineLayout,							// const VkPipelineLayout                        pipelineLayout
								*vertexShaderModule,					// const VkShaderModule                          vertexShaderModule
								DE_NULL,								// const VkShaderModule                          tessellationControlShaderModule
								DE_NULL,								// const VkShaderModule                          tessellationEvalShaderModule
								DE_NULL,								// const VkShaderModule                          geometryShaderModule
								*fragmentShaderModule,					// const VkShaderModule                          fragmentShaderModule
								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
}

Move<VkDescriptorSetLayout> createSplitDescriptorSetLayout (const DeviceInterface&	vkd,
															VkDevice				device,
															VkFormat				vkFormat)
{
	const tcu::TextureFormat				format		(mapVkFormat(vkFormat));
	const bool								hasDepth	(tcu::hasDepthComponent(format.order));
	const bool								hasStencil	(tcu::hasStencilComponent(format.order));
	const VkDescriptorSetLayoutBinding		bindings[]	=
	{
		{
			0u,
			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
			1u,
			VK_SHADER_STAGE_FRAGMENT_BIT,
			DE_NULL
		},
		{
			1u,
			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
			1u,
			VK_SHADER_STAGE_FRAGMENT_BIT,
			DE_NULL
		}
	};
	const VkDescriptorSetLayoutCreateInfo	createInfo	=
	{
		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
		DE_NULL,
		0u,

		hasDepth && hasStencil ? 2u : 1u,
		bindings
	};

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

Move<VkPipelineLayout> createSplitPipelineLayout (const DeviceInterface&	vkd,
												  VkDevice					device,
												  VkDescriptorSetLayout		descriptorSetLayout)
{
	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,

		1u,
		&descriptorSetLayout,

		1u,
		&pushConstant
	};

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

Move<VkPipeline> createSplitPipeline (const DeviceInterface&		vkd,
									  VkDevice						device,
									  VkRenderPass					renderPass,
									  deUint32						subpassIndex,
									  VkPipelineLayout				pipelineLayout,
									  const vk::BinaryCollection&	binaryCollection,
									  deUint32						width,
									  deUint32						height,
									  deUint32						sampleCount)
{
	const Unique<VkShaderModule>	vertexShaderModule			(createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
	const Unique<VkShaderModule>	fragmentShaderModule		(createShaderModule(vkd, device, binaryCollection.get("quad-split-frag"), 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
	};
	const std::vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates (de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, sampleCount), attachmentBlendState);
	const VkPipelineVertexInputStateCreateInfo vertexInputState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
		DE_NULL,
		(VkPipelineVertexInputStateCreateFlags)0u,

		0u,
		DE_NULL,

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

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

		sampleCountBitFromomSampleCount(sampleCount),
		VK_FALSE,
		0.0f,
		DE_NULL,
		VK_FALSE,
		VK_FALSE,
	};
	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
								pipelineLayout,							// const VkPipelineLayout                        pipelineLayout
								*vertexShaderModule,					// const VkShaderModule                          vertexShaderModule
								DE_NULL,								// const VkShaderModule                          tessellationControlShaderModule
								DE_NULL,								// const VkShaderModule                          tessellationEvalShaderModule
								DE_NULL,								// const VkShaderModule                          geometryShaderModule
								*fragmentShaderModule,					// const VkShaderModule                          fragmentShaderModule
								renderPass,								// const VkRenderPass                            renderPass
								viewports,								// const std::vector<VkViewport>&                viewports
								scissors,								// const std::vector<VkRect2D>&                  scissors
								VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
								subpassIndex,							// const deUint32                                subpass
								0u,										// const deUint32                                patchControlPoints
								&vertexInputState,						// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
								DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
								&multisampleState,						// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
								DE_NULL,								// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
								&blendState);							// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
}

vector<VkPipelineSp> createSplitPipelines (const DeviceInterface&		vkd,
										 VkDevice						device,
										 VkRenderPass					renderPass,
										 VkPipelineLayout				pipelineLayout,
										 const vk::BinaryCollection&	binaryCollection,
										 deUint32						width,
										 deUint32						height,
										 deUint32						sampleCount)
{
	std::vector<VkPipelineSp> pipelines (deDivRoundUp32(sampleCount, MAX_COLOR_ATTACHMENT_COUNT), (VkPipelineSp)0u);

	for (size_t ndx = 0; ndx < pipelines.size(); ndx++)
		pipelines[ndx] = safeSharedPtr(new Unique<VkPipeline>(createSplitPipeline(vkd, device, renderPass, (deUint32)(ndx + 1), pipelineLayout, binaryCollection, width, height, sampleCount)));

	return pipelines;
}

Move<VkDescriptorPool> createSplitDescriptorPool (const DeviceInterface&	vkd,
												  VkDevice					device)
{
	const VkDescriptorPoolSize			size		=
	{
		VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2u
	};
	const VkDescriptorPoolCreateInfo	createInfo	=
	{
		VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
		DE_NULL,
		VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,


		2u,
		1u,
		&size
	};

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

Move<VkDescriptorSet> createSplitDescriptorSet (const DeviceInterface&	vkd,
												VkDevice				device,
												VkDescriptorPool		pool,
												VkDescriptorSetLayout	layout,
												VkImageView				primaryImageView,
												VkImageView				secondaryImageView)
{
	const VkDescriptorSetAllocateInfo	allocateInfo	=
	{
		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
		DE_NULL,

		pool,
		1u,
		&layout
	};
	Move<VkDescriptorSet> set (allocateDescriptorSet(vkd, device, &allocateInfo));

	{
		const VkDescriptorImageInfo	imageInfos[]	=
		{
			{
				(VkSampler)0u,
				primaryImageView,
				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
			},
			{
				(VkSampler)0u,
				secondaryImageView,
				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
			}
		};
		const VkWriteDescriptorSet	writes[]	=
		{
			{
				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
				DE_NULL,

				*set,
				0u,
				0u,
				1u,
				VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
				&imageInfos[0],
				DE_NULL,
				DE_NULL
			},
			{
				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
				DE_NULL,

				*set,
				1u,
				0u,
				1u,
				VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
				&imageInfos[1],
				DE_NULL,
				DE_NULL
			}
		};
		const deUint32	count	= secondaryImageView != (VkImageView)0
								? 2u
								: 1u;

		vkd.updateDescriptorSets(device, count, writes, 0u, DE_NULL);
	}
	return set;
}

struct TestConfig
{
				TestConfig		(VkFormat			format_,
								 deUint32			sampleCount_,
								 RenderingType		renderingType_,
								 TestSeparateUsage	separateStencilUsage_ = (TestSeparateUsage)0u)
		: format			(format_)
		, sampleCount		(sampleCount_)
		, renderingType		(renderingType_)
		, separateStencilUsage(separateStencilUsage_)
	{
	}

	VkFormat			format;
	deUint32			sampleCount;
	RenderingType		renderingType;
	TestSeparateUsage	separateStencilUsage;
};

VkImageUsageFlags getSrcImageUsage (VkFormat vkFormat)
{
	const tcu::TextureFormat	format		(mapVkFormat(vkFormat));
	const bool					hasDepth	(tcu::hasDepthComponent(format.order));
	const bool					hasStencil	(tcu::hasStencilComponent(format.order));

	if (hasDepth || hasStencil)
		return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
	else
		return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
}

VkFormat getDstFormat (VkFormat vkFormat, TestSeparateUsage separateStencilUsage)
{
	const tcu::TextureFormat	format		(mapVkFormat(vkFormat));
	const bool					hasDepth	(tcu::hasDepthComponent(format.order));
	const bool					hasStencil	(tcu::hasStencilComponent(format.order));

	if (hasDepth && hasStencil && !separateStencilUsage)
		return VK_FORMAT_R32G32_SFLOAT;
	else if (hasDepth || hasStencil)
		return VK_FORMAT_R32_SFLOAT;
	else
		return vkFormat;
}

bool isExtensionSupported(Context& context, RenderingType renderingType, TestSeparateUsage separateStencilUsage)
{
	if (renderingType == RENDERING_TYPE_RENDERPASS2)
		context.requireDeviceFunctionality("VK_KHR_create_renderpass2");

	if (separateStencilUsage)
	{
		context.requireDeviceFunctionality	("VK_EXT_separate_stencil_usage");
		context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
	}

	return true;
}


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

	tcu::TestStatus	iterate								(void);

	template<typename RenderpassSubpass>
	tcu::TestStatus	iterateInternal						(void);

private:
	const bool										m_extensionSupported;
	const RenderingType								m_renderingType;
	const TestSeparateUsage							m_separateStencilUsage;

	const VkFormat									m_srcFormat;
	const VkFormat									m_dstFormat;
	const deUint32									m_sampleCount;
	const deUint32									m_width;
	const deUint32									m_height;

	const VkImageAspectFlags						m_srcImageAspect;
	const VkImageUsageFlags							m_srcImageUsage;
	const Unique<VkImage>							m_srcImage;
	const de::UniquePtr<Allocation>					m_srcImageMemory;
	const Unique<VkImageView>						m_srcImageView;
	const Unique<VkImageView>						m_srcPrimaryInputImageView;
	const Unique<VkImageView>						m_srcSecondaryInputImageView;

	const std::vector<VkImageSp>					m_dstMultisampleImages;
	const std::vector<de::SharedPtr<Allocation> >	m_dstMultisampleImageMemory;
	const std::vector<VkImageViewSp>				m_dstMultisampleImageViews;

	const std::vector<VkImageSp>					m_dstSinglesampleImages;
	const std::vector<de::SharedPtr<Allocation> >	m_dstSinglesampleImageMemory;
	const std::vector<VkImageViewSp>				m_dstSinglesampleImageViews;

	const std::vector<VkBufferSp>					m_dstBuffers;
	const std::vector<de::SharedPtr<Allocation> >	m_dstBufferMemory;

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

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

	const Unique<VkDescriptorSetLayout>				m_splitDescriptorSetLayout;
	const Unique<VkPipelineLayout>					m_splitPipelineLayout;
	const std::vector<VkPipelineSp>					m_splitPipelines;
	const Unique<VkDescriptorPool>					m_splitDescriptorPool;
	const Unique<VkDescriptorSet>					m_splitDescriptorSet;

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

MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config)
	: TestInstance					(context)
	, m_extensionSupported			(isExtensionSupported(context, config.renderingType, config.separateStencilUsage))
	, m_renderingType				(config.renderingType)
	, m_separateStencilUsage		(config.separateStencilUsage)
	, m_srcFormat					(config.format)
	, m_dstFormat					(getDstFormat(config.format, config.separateStencilUsage))
	, m_sampleCount					(config.sampleCount)
	, m_width						(32u)
	, m_height						(32u)

	, m_srcImageAspect				(getImageAspectFlags(m_srcFormat))
	, m_srcImageUsage				(getSrcImageUsage(m_srcFormat))
	, m_srcImage					(createImage(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_srcFormat, sampleCountBitFromomSampleCount(m_sampleCount), m_srcImageUsage, m_width, m_height, m_separateStencilUsage))
	, m_srcImageMemory				(createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_srcImage))
	, m_srcImageView				(createImageAttachmentView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect))
	, m_srcPrimaryInputImageView	(createSrcPrimaryInputImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect, m_separateStencilUsage))
	, m_srcSecondaryInputImageView	(createSrcSecondaryInputImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect, m_separateStencilUsage))

	, m_dstMultisampleImages		(createMultisampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
	, m_dstMultisampleImageMemory	(createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstMultisampleImages))
	, m_dstMultisampleImageViews	(createImageAttachmentViews(context.getDeviceInterface(), context.getDevice(), m_dstMultisampleImages, m_dstFormat, VK_IMAGE_ASPECT_COLOR_BIT))

	, m_dstSinglesampleImages		(createSingleSampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
	, m_dstSinglesampleImageMemory	(createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstSinglesampleImages))
	, m_dstSinglesampleImageViews	(createImageAttachmentViews(context.getDeviceInterface(), context.getDevice(), m_dstSinglesampleImages, m_dstFormat, VK_IMAGE_ASPECT_COLOR_BIT))

	, m_dstBuffers					(createBuffers(context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
	, m_dstBufferMemory				(createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstBuffers))

	, m_renderPass					(createRenderPass(context.getDeviceInterface(), context.getDevice(), m_srcFormat, m_dstFormat, m_sampleCount, config.renderingType, m_separateStencilUsage))
	, m_framebuffer					(createFramebuffer(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_srcImageView, m_dstMultisampleImageViews, m_dstSinglesampleImageViews, m_width, m_height))

	, m_renderPipelineLayout		(createRenderPipelineLayout(context.getDeviceInterface(), context.getDevice()))
	, m_renderPipeline				(createRenderPipeline(context.getDeviceInterface(), context.getDevice(), m_srcFormat, *m_renderPass, *m_renderPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))

	, m_splitDescriptorSetLayout	(createSplitDescriptorSetLayout(context.getDeviceInterface(), context.getDevice(), m_srcFormat))
	, m_splitPipelineLayout			(createSplitPipelineLayout(context.getDeviceInterface(), context.getDevice(), *m_splitDescriptorSetLayout))
	, m_splitPipelines				(createSplitPipelines(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_splitPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))
	, m_splitDescriptorPool			(createSplitDescriptorPool(context.getDeviceInterface(), context.getDevice()))
	, m_splitDescriptorSet			(createSplitDescriptorSet(context.getDeviceInterface(), context.getDevice(), *m_splitDescriptorPool, *m_splitDescriptorSetLayout, *m_srcPrimaryInputImageView, *m_srcSecondaryInputImageView))
	, m_commandPool					(createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
{
}

MultisampleRenderPassTestInstance::~MultisampleRenderPassTestInstance (void)
{
}

tcu::TestStatus MultisampleRenderPassTestInstance::iterate (void)
{
	switch (m_renderingType)
	{
		case RENDERING_TYPE_RENDERPASS_LEGACY:
			return iterateInternal<RenderpassSubpass1>();
		case RENDERING_TYPE_RENDERPASS2:
			return iterateInternal<RenderpassSubpass2>();
		default:
			TCU_THROW(InternalError, "Impossible");
	}
}

template<typename RenderpassSubpass>
tcu::TestStatus MultisampleRenderPassTestInstance::iterateInternal (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);

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

		// Stencil needs to be cleared if it exists.
		if (tcu::hasStencilComponent(mapVkFormat(m_srcFormat).order))
		{
			const VkClearAttachment clearAttachment =
			{
				VK_IMAGE_ASPECT_STENCIL_BIT,						// VkImageAspectFlags	aspectMask;
				0,													// deUint32				colorAttachment;
				makeClearValueDepthStencil(0, 0)					// VkClearValue			clearValue;
			};

			const VkClearRect clearRect =
			{
				{
					{ 0u, 0u },
					{ m_width, m_height }
				},
				0,													// deUint32	baseArrayLayer;
				1													// deUint32	layerCount;
			};

			vkd.cmdClearAttachments(*commandBuffer, 1, &clearAttachment, 1, &clearRect);
		}
	}

	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);

	for (deUint32 sampleNdx = 0; sampleNdx < m_sampleCount; sampleNdx++)
	{
		vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(sampleNdx), &sampleNdx);
		vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
	}

	for (deUint32 splitPipelineNdx = 0; splitPipelineNdx < m_splitPipelines.size(); splitPipelineNdx++)
	{
		RenderpassSubpass::cmdNextSubpass(vkd, *commandBuffer, &subpassBeginInfo, &subpassEndInfo);

		vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_splitPipelines[splitPipelineNdx]);
		vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_splitPipelineLayout, 0u, 1u,  &*m_splitDescriptorSet, 0u, DE_NULL);
		vkd.cmdPushConstants(*commandBuffer, *m_splitPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(splitPipelineNdx), &splitPipelineNdx);
		vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
	}

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

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

	endCommandBuffer(vkd, *commandBuffer);

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

	{
		const tcu::TextureFormat		format			(mapVkFormat(m_dstFormat));
		const tcu::TextureFormat		srcFormat		(mapVkFormat(m_srcFormat));
		const bool						verifyDepth		(m_separateStencilUsage ? (m_separateStencilUsage == TEST_DEPTH)   : tcu::hasDepthComponent(srcFormat.order));
		const bool						verifyStencil	(m_separateStencilUsage ? (m_separateStencilUsage == TEST_STENCIL) : tcu::hasStencilComponent(srcFormat.order));

		for (deUint32 sampleNdx = 0; sampleNdx < m_sampleCount; sampleNdx++)
		{
			Allocation *dstBufMem = m_dstBufferMemory[sampleNdx].get();
			invalidateAlloc(vkd, device, *dstBufMem);

			const std::string					name		("Sample" + de::toString(sampleNdx));
			const void* const					ptr			(dstBufMem->getHostPtr());
			const tcu::ConstPixelBufferAccess	access		(format, m_width, m_height, 1, ptr);
			tcu::TextureLevel					reference	(format, m_width, m_height);

			if (verifyDepth || verifyStencil)
			{
				if (verifyDepth)
				{
					for (deUint32 y = 0; y < m_height; y++)
					for (deUint32 x = 0; x < m_width; x++)
					{
						const deUint32	x1				= x ^ sampleNdx;
						const deUint32	y1				= y ^ sampleNdx;
						const float		range			= 1.0f;
						float			depth			= 0.0f;
						deUint32		divider			= 2;

						// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
						for (size_t bitNdx = 0; bitNdx < 10; bitNdx++)
						{
							depth += (range / (float)divider)
									* (((bitNdx % 2 == 0 ? x1 : y1) & (0x1u << (bitNdx / 2u))) == 0u ? 0u : 1u);
							divider *= 2;
						}

						reference.getAccess().setPixel(Vec4(depth, 0.0f, 0.0f, 0.0f), x, y);
					}
				}
				if (verifyStencil)
				{
					for (deUint32 y = 0; y < m_height; y++)
					for (deUint32 x = 0; x < m_width; x++)
					{
						const deUint32	stencil	= sampleNdx + 1u;

						if (verifyDepth)
						{
							const Vec4 src (reference.getAccess().getPixel(x, y));

							reference.getAccess().setPixel(Vec4(src.x(), (float)stencil, 0.0f, 0.0f), x, y);
						}
						else
							reference.getAccess().setPixel(Vec4((float)stencil, 0.0f, 0.0f, 0.0f), x, y);
					}
				}
				{
					const Vec4 threshold (verifyDepth ? (1.0f / 1024.0f) : 0.0f, 0.0f, 0.0f, 0.0f);

					if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
						m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
				}
			}
			else
			{
				const tcu::TextureChannelClass	channelClass	(tcu::getTextureChannelClass(format.type));

				switch (channelClass)
				{
					case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
					{
						const UVec4		bits			(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
						const UVec4		minValue		(0);
						const UVec4		range			(UVec4(1u) << tcu::min(bits, UVec4(31)));
						const int		componentCount	(tcu::getNumUsedChannels(format.order));
						const deUint32	bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);

						for (deUint32 y = 0; y < m_height; y++)
						for (deUint32 x = 0; x < m_width; x++)
						{
							const deUint32	x1				= x ^ sampleNdx;
							const deUint32	y1				= y ^ sampleNdx;
							UVec4			color			(minValue);
							deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
							deUint32		nextSrcBit		= 0;
							deUint32		divider			= 2;

							// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
							while (nextSrcBit < de::min(bitSize, 10u))
							{
								for (int compNdx = 0; compNdx < componentCount; compNdx++)
								{
									if (dstBitsUsed[compNdx] > bits[compNdx])
										continue;

									color[compNdx] += (range[compNdx] / divider)
													* (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);

									nextSrcBit++;
									dstBitsUsed[compNdx]++;
								}

								divider *= 2;
							}

							reference.getAccess().setPixel(color, x, y);
						}

						if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
							m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));

						break;
					}

					case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
					{
						const UVec4		bits			(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
						const IVec4		minValue		(0);
						const IVec4		range			((UVec4(1u) << tcu::min(bits, UVec4(30))).cast<deInt32>());
						const int		componentCount	(tcu::getNumUsedChannels(format.order));
						const deUint32	bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);

						for (deUint32 y = 0; y < m_height; y++)
						for (deUint32 x = 0; x < m_width; x++)
						{
							const deUint32	x1				= x ^ sampleNdx;
							const deUint32	y1				= y ^ sampleNdx;
							IVec4			color			(minValue);
							deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
							deUint32		nextSrcBit		= 0;
							deUint32		divider			= 2;

							// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
							while (nextSrcBit < de::min(bitSize, 10u))
							{
								for (int compNdx = 0; compNdx < componentCount; compNdx++)
								{
									if (dstBitsUsed[compNdx] > bits[compNdx])
										continue;

									color[compNdx] += (range[compNdx] / divider)
													* (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);

									nextSrcBit++;
									dstBitsUsed[compNdx]++;
								}

								divider *= 2;
							}

							reference.getAccess().setPixel(color, x, y);
						}

						if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
							m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));

						break;
					}

					case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
					case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
					case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
					{
						const tcu::TextureFormatInfo	info			(tcu::getTextureFormatInfo(format));
						const UVec4						bits			(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
						const Vec4						minLimit		(-65536.0);
						const Vec4						maxLimit		(65536.0);
						const Vec4						minValue		(tcu::max(info.valueMin, minLimit));
						const Vec4						range			(tcu::min(info.valueMax, maxLimit) - minValue);
						const int						componentCount	(tcu::getNumUsedChannels(format.order));
						const deUint32					bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);

						for (deUint32 y = 0; y < m_height; y++)
						for (deUint32 x = 0; x < m_width; x++)
						{
							const deUint32	x1				= x ^ sampleNdx;
							const deUint32	y1				= y ^ sampleNdx;
							Vec4			color			(minValue);
							deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
							deUint32		nextSrcBit		= 0;
							deUint32		divider			= 2;

							// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
							while (nextSrcBit < de::min(bitSize, 10u))
							{
								for (int compNdx = 0; compNdx < componentCount; compNdx++)
								{
									if (dstBitsUsed[compNdx] > bits[compNdx])
										continue;

									color[compNdx] += (range[compNdx] / (float)divider)
													* (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);

									nextSrcBit++;
									dstBitsUsed[compNdx]++;
								}

								divider *= 2;
							}

							if (tcu::isSRGB(format))
								reference.getAccess().setPixel(tcu::linearToSRGB(color), x, y);
							else
								reference.getAccess().setPixel(color, x, y);
						}

						if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
						{
							// Convert target format ulps to float ulps and allow 64ulp differences
							const UVec4 threshold (64u * (UVec4(1u) << (UVec4(23) - tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>())));

							if (!tcu::floatUlpThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
								m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
						}
						else
						{
							// Allow error of 4 times the minimum presentable difference
							const Vec4 threshold (4.0f * 1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>()) - 1u).cast<float>());

							if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
								m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
						}

						break;
					}

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

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

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));
		const bool						testDepth		(config.separateStencilUsage ? (config.separateStencilUsage == TEST_DEPTH) : tcu::hasDepthComponent(format.order));
		const bool						testStencil		(config.separateStencilUsage ? (config.separateStencilUsage == TEST_STENCIL) : tcu::hasStencilComponent(format.order));

		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 (testDepth)
		{
			const Vec4			minValue		(0.0f);
			const Vec4			range			(1.0f);
			std::ostringstream	fragmentShader;

			fragmentShader <<
				"#version 450\n"
				"layout(push_constant) uniform PushConstant {\n"
				"\thighp uint sampleIndex;\n"
				"} pushConstants;\n"
				"void main (void)\n"
				"{\n"
				"\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
				"\tgl_SampleMask[0] = int((~0x0u) << sampleIndex);\n"
				"\thighp float depth;\n"
				"\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
				"\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";

			fragmentShader << "\tdepth = "  << minValue[0] << ";\n";

			{
				deUint32 divider = 2;

				// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
				for (size_t bitNdx = 0; bitNdx < 10; bitNdx++)
				{
					fragmentShader <<
							"\tdepth += " << (range[0] / (float)divider)
							<< " * float(bitfieldExtract(" << (bitNdx % 2 == 0 ? "x" : "y") << ", " << (bitNdx / 2) << ", 1));\n";

					divider *= 2;
				}
			}

			fragmentShader <<
				"\tgl_FragDepth = depth;\n"
				"}\n";

			dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
		}
		else if (testStencil)
		{
			dst.glslSources.add("quad-frag") << glu::FragmentSource(
				"#version 450\n"
				"layout(push_constant) uniform PushConstant {\n"
				"\thighp uint sampleIndex;\n"
				"} pushConstants;\n"
				"void main (void)\n"
				"{\n"
				"\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
				"\tgl_SampleMask[0] = int((~0x0u) << sampleIndex);\n"
				"}\n");
		}
		else
		{
			switch (channelClass)
			{
				case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
				{
					const UVec4	bits		(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
					const UVec4 minValue	(0);
					const UVec4 range		(UVec4(1u) << tcu::min(bits, UVec4(31)));
					std::ostringstream		fragmentShader;

					fragmentShader <<
						"#version 450\n"
						"layout(location = 0) out highp uvec4 o_color;\n"
						"layout(push_constant) uniform PushConstant {\n"
						"\thighp uint sampleIndex;\n"
						"} pushConstants;\n"
						"void main (void)\n"
						"{\n"
						"\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
						"\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
						"\thighp uint color[4];\n"
						"\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
						"\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";

					for (int ndx = 0; ndx < 4; ndx++)
						fragmentShader << "\tcolor[" << ndx << "] = "  << minValue[ndx] << ";\n";

					{
						const int		componentCount	= tcu::getNumUsedChannels(format.order);
						const deUint32	bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);
						deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
						deUint32		nextSrcBit		= 0;
						deUint32		divider			= 2;

						// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
						while (nextSrcBit < de::min(bitSize, 10u))
						{
							for (int compNdx = 0; compNdx < componentCount; compNdx++)
							{
								if (dstBitsUsed[compNdx] > bits[compNdx])
									continue;

								fragmentShader <<
										"\tcolor[" << compNdx << "] += " << (range[compNdx] / divider)
										<< " * bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1);\n";

								nextSrcBit++;
								dstBitsUsed[compNdx]++;
							}

							divider *= 2;
						}
					}

					fragmentShader <<
						"\to_color = uvec4(color[0], color[1], color[2], color[3]);\n"
						"}\n";

					dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
					break;
				}

				case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
				{
					const UVec4	bits		(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
					const IVec4 minValue	(0);
					const IVec4 range		((UVec4(1u) << tcu::min(bits, UVec4(30))).cast<deInt32>());
					const IVec4 maxV		((UVec4(1u) << (bits - UVec4(1u))).cast<deInt32>());
					const IVec4 clampMax	(maxV - 1);
					const IVec4 clampMin	(-maxV);
					std::ostringstream		fragmentShader;

					fragmentShader <<
						"#version 450\n"
						"layout(location = 0) out highp ivec4 o_color;\n"
						"layout(push_constant) uniform PushConstant {\n"
						"\thighp uint sampleIndex;\n"
						"} pushConstants;\n"
						"void main (void)\n"
						"{\n"
						"\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
						"\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
						"\thighp int color[4];\n"
						"\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
						"\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";

					for (int ndx = 0; ndx < 4; ndx++)
						fragmentShader << "\tcolor[" << ndx << "] = "  << minValue[ndx] << ";\n";

					{
						const int		componentCount	= tcu::getNumUsedChannels(format.order);
						const deUint32	bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);
						deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
						deUint32		nextSrcBit		= 0;
						deUint32		divider			= 2;

						// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
						while (nextSrcBit < de::min(bitSize, 10u))
						{
							for (int compNdx = 0; compNdx < componentCount; compNdx++)
							{
								if (dstBitsUsed[compNdx] > bits[compNdx])
									continue;

								fragmentShader <<
										"\tcolor[" << compNdx << "] += " << (range[compNdx] / divider)
										<< " * int(bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1));\n";

								nextSrcBit++;
								dstBitsUsed[compNdx]++;
							}

							divider *= 2;
						}
					}

					// The spec doesn't define whether signed-integers are clamped on output,
					// so we'll clamp them explicitly to have well-defined outputs.
					fragmentShader <<
						"\to_color = clamp(ivec4(color[0], color[1], color[2], color[3]), " <<
						"ivec4" << clampMin << ", ivec4" << clampMax << ");\n" <<
						"}\n";

					dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
					break;
				}

				case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
				case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
				case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
				{
					const tcu::TextureFormatInfo	info			(tcu::getTextureFormatInfo(format));
					const UVec4						bits			(tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>());
					const Vec4						minLimit		(-65536.0);
					const Vec4						maxLimit		(65536.0);
					const Vec4						minValue		(tcu::max(info.valueMin, minLimit));
					const Vec4						range			(tcu::min(info.valueMax, maxLimit) - minValue);
					std::ostringstream				fragmentShader;

					fragmentShader <<
						"#version 450\n"
						"layout(location = 0) out highp vec4 o_color;\n"
						"layout(push_constant) uniform PushConstant {\n"
						"\thighp uint sampleIndex;\n"
						"} pushConstants;\n"
						"void main (void)\n"
						"{\n"
						"\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
						"\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
						"\thighp float color[4];\n"
						"\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
						"\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";

					for (int ndx = 0; ndx < 4; ndx++)
						fragmentShader << "\tcolor[" << ndx << "] = "  << minValue[ndx] << ";\n";

					{
						const int		componentCount	= tcu::getNumUsedChannels(format.order);
						const deUint32	bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);
						deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
						deUint32		nextSrcBit		= 0;
						deUint32		divider			= 2;

						// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
						while (nextSrcBit < de::min(bitSize, 10u))
						{
							for (int compNdx = 0; compNdx < componentCount; compNdx++)
							{
								if (dstBitsUsed[compNdx] > bits[compNdx])
									continue;

								fragmentShader <<
										"\tcolor[" << compNdx << "] += " << (range[compNdx] / (float)divider)
										<< " * float(bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1));\n";

								nextSrcBit++;
								dstBitsUsed[compNdx]++;
							}

							divider *= 2;
						}
					}

					fragmentShader <<
						"\to_color = vec4(color[0], color[1], color[2], color[3]);\n"
						"}\n";

					dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
					break;
				}

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

		if (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
		{
			std::ostringstream splitShader;

			splitShader <<
				"#version 450\n";

			if (testDepth && testStencil)
			{
				splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInputMS i_depth;\n"
							<< "layout(input_attachment_index = 0, set = 0, binding = 1) uniform highp usubpassInputMS i_stencil;\n";
			}
			else if (testDepth)
				splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInputMS i_depth;\n";
			else if (testStencil)
				splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp usubpassInputMS i_stencil;\n";

			splitShader <<
				"layout(push_constant) uniform PushConstant {\n"
				"\thighp uint splitSubpassIndex;\n"
				"} pushConstants;\n";

			for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
			{
				if (testDepth && testStencil)
					splitShader << "layout(location = " << attachmentNdx << ") out highp vec2 o_color" << attachmentNdx << ";\n";
				else
					splitShader << "layout(location = " << attachmentNdx << ") out highp float o_color" << attachmentNdx << ";\n";
			}

			splitShader <<
				"void main (void)\n"
				"{\n";

			for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
			{
				if (testDepth)
					splitShader << "\thighp float depth" << attachmentNdx << " = subpassLoad(i_depth, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u)).x;\n";

				if (testStencil)
					splitShader << "\thighp uint stencil" << attachmentNdx << " = subpassLoad(i_stencil, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u)).x;\n";

				if (testDepth && testStencil)
					splitShader << "\to_color" << attachmentNdx << " = vec2(depth" << attachmentNdx << ", float(stencil" << attachmentNdx << "));\n";
				else if (testDepth)
					splitShader << "\to_color" << attachmentNdx << " = float(depth" << attachmentNdx << ");\n";
				else if (testStencil)
					splitShader << "\to_color" << attachmentNdx << " = float(stencil" << attachmentNdx << ");\n";
			}

			splitShader <<
				"}\n";

			dst.glslSources.add("quad-split-frag") << glu::FragmentSource(splitShader.str());
		}
		else
		{
			std::string subpassType;
			std::string outputType;

			switch (channelClass)
			{
				case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
					subpassType	= "usubpassInputMS";
					outputType	= "uvec4";
					break;

				case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
					subpassType	= "isubpassInputMS";
					outputType	= "ivec4";
					break;

				case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
				case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
				case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
					subpassType	= "subpassInputMS";
					outputType	= "vec4";
					break;

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

			std::ostringstream splitShader;
			splitShader <<
				"#version 450\n"
				"layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp " << subpassType << " i_color;\n"
				"layout(push_constant) uniform PushConstant {\n"
				"\thighp uint splitSubpassIndex;\n"
				"} pushConstants;\n";

			for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
				splitShader << "layout(location = " << attachmentNdx << ") out highp " << outputType << " o_color" << attachmentNdx << ";\n";

			splitShader <<
				"void main (void)\n"
				"{\n";

			for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
				splitShader << "\to_color" << attachmentNdx << " = subpassLoad(i_color, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u));\n";

			splitShader <<
				"}\n";

			dst.glslSources.add("quad-split-frag") << glu::FragmentSource(splitShader.str());
		}
	}
};

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, RenderingType renderingType)
{
	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,

		VK_FORMAT_D16_UNORM,
		VK_FORMAT_X8_D24_UNORM_PACK32,
		VK_FORMAT_D32_SFLOAT,
		VK_FORMAT_S8_UINT,
		VK_FORMAT_D16_UNORM_S8_UINT,
		VK_FORMAT_D24_UNORM_S8_UINT,
		VK_FORMAT_D32_SFLOAT_S8_UINT
	};
	const deUint32			sampleCounts[] =
	{
		2u, 4u, 8u, 16u, 32u
	};
	tcu::TestContext&				testCtx		(group->getTestContext());
	de::MovePtr<tcu::TestCaseGroup>	extGroup	(new tcu::TestCaseGroup(testCtx, "separate_stencil_usage", "test VK_EXT_separate_stencil_usage"));


	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()));
		de::MovePtr<tcu::TestCaseGroup>	extFormatGroup	(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]);
			const TestConfig	testConfig	(format, sampleCount, renderingType);
			const std::string	testName	("samples_" + de::toString(sampleCount));

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

			// create tests for VK_EXT_separate_stencil_usage
			if (tcu::hasDepthComponent(mapVkFormat(format).order) && tcu::hasStencilComponent(mapVkFormat(format).order))
			{
				de::MovePtr<tcu::TestCaseGroup>	sampleGroup	(new tcu::TestCaseGroup(testCtx, testName.c_str(), testName.c_str()));
				{
					const TestConfig	separateUsageDepthTestConfig	(format, sampleCount, renderingType, TEST_DEPTH);
					sampleGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "test_depth", "depth with input attachment bit", separateUsageDepthTestConfig));

					const TestConfig	separateUsageStencilTestConfig	(format, sampleCount, renderingType, TEST_STENCIL);
					sampleGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "test_stencil", "stencil with input attachment bit", separateUsageStencilTestConfig));
				}

				extFormatGroup->addChild(sampleGroup.release());
			}
		}

		group->addChild(formatGroup.release());
		extGroup->addChild(extFormatGroup.release());
	}

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

} // anonymous

tcu::TestCaseGroup* createRenderPassMultisampleTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "multisample", "Multisample render pass tests", initTests, RENDERING_TYPE_RENDERPASS_LEGACY);
}

tcu::TestCaseGroup* createRenderPass2MultisampleTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "multisample", "Multisample render pass tests", initTests, RENDERING_TYPE_RENDERPASS2);
}

} // vkt
