/*-------------------------------------------------------------------------
 * 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 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,
									 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.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 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
