/*-------------------------------------------------------------------------
 * 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::nothing;

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 VkImageStencilUsageCreateInfoEXT stencilUsageInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT,
		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 VkImageStencilUsageCreateInfoEXT	stencilUsageInfo =
			{
				VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT,			//	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,
									 RenderPassType			renderPassType,
									 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;
		(renderPassType == RENDERPASS_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);
			}
		};
		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 RenderPassType		renderPassType,
									 const TestSeparateUsage	separateStencilUsage)
{
	switch (renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:
			return createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vkd, device, srcFormat, dstFormat, sampleCount, renderPassType, separateStencilUsage);
		case RENDERPASS_TYPE_RENDERPASS2:
			return createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vkd, device, srcFormat, dstFormat, sampleCount, renderPassType, 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_,
								 RenderPassType		renderPassType_,
								 TestSeparateUsage	separateStencilUsage_ = (TestSeparateUsage)0u)
		: format			(format_)
		, sampleCount		(sampleCount_)
		, renderPassType	(renderPassType_)
		, separateStencilUsage(separateStencilUsage_)
	{
	}

	VkFormat			format;
	deUint32			sampleCount;
	RenderPassType		renderPassType;
	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, RenderPassType renderPassType, TestSeparateUsage separateStencilUsage)
{

	if (renderPassType == RENDERPASS_TYPE_RENDERPASS2)
		context.requireDeviceExtension("VK_KHR_create_renderpass2");

	if (separateStencilUsage)
	{
		context.requireDeviceExtension	("VK_EXT_separate_stencil_usage");
		context.requireInstanceExtension("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 RenderPassType							m_renderPassType;
	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.renderPassType, config.separateStencilUsage))
	, m_renderPassType				(config.renderPassType)
	, 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.renderPassType, 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_renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:
			return iterateInternal<RenderpassSubpass1>();
		case RENDERPASS_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, 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_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, renderPassType);
			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, renderPassType, 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, renderPassType, 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, RENDERPASS_TYPE_LEGACY);
}

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

} // vkt
