/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 * Copyright (c) 2017 The Khronos Group 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 VK_EXT_sample_locations
 *//*--------------------------------------------------------------------*/

#include "vktPipelineMultisampleSampleLocationsExtTests.hpp"
#include "vktPipelineMakeUtil.hpp"
#include "vktTestCase.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktTestCaseUtil.hpp"

#include "vkPlatform.hpp"
#include "vkMemUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkPrograms.hpp"
#include "vkImageUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"

#include "deUniquePtr.hpp"
#include "deRandom.hpp"
#include "deMath.h"

#include "tcuTestLog.hpp"
#include "tcuImageCompare.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuRGBA.hpp"
#include "tcuVectorUtil.hpp"

#include <string>
#include <vector>
#include <set>
#include <algorithm>

namespace vkt
{
namespace pipeline
{
namespace
{
using namespace vk;
using de::UniquePtr;
using de::MovePtr;
using tcu::Vec4;
using tcu::Vec2;
using tcu::UVec2;
using tcu::UVec4;
using tcu::RGBA;

static const deUint32		STENCIL_REFERENCE	= 1u;
static const float			DEPTH_CLEAR			= 1.0f;
static const float			DEPTH_REFERENCE     = 0.5f;
static const Vec4			CLEAR_COLOR_0		= Vec4(0.0f, 0.0f,  0.0f,  1.0f);
static const Vec4			CLEAR_COLOR_1		= Vec4(0.5f, 0.25f, 0.75f, 1.0f);
static const VkDeviceSize	ZERO				= 0u;

template<typename T>
inline const T* dataOrNullPtr (const std::vector<T>& v)
{
	return (v.empty() ? DE_NULL : &v[0]);
}

template<typename T>
inline T* dataOrNullPtr (std::vector<T>& v)
{
	return (v.empty() ? DE_NULL : &v[0]);
}

template<typename T>
inline void append (std::vector<T>& first, const std::vector<T>& second)
{
	first.insert(first.end(), second.begin(), second.end());
}

//! Order a Vector by X, Y, Z, and W
template<typename VectorT>
struct LessThan
{
	bool operator()(const VectorT& v1, const VectorT& v2) const
	{
		for (int i = 0; i < VectorT::SIZE; ++i)
		{
			if (v1[i] == v2[i])
				continue;
			else
				return v1[i] < v2[i];
		}

		return false;
	}
};

//! Similar to the class in vktTestCaseUtil.hpp, but uses Arg0 directly rather than through a InstanceFunction1
template<typename Arg0>
class FunctionProgramsSimple1
{
public:
	typedef void	(*Function)				(vk::SourceCollections& dst, Arg0 arg0);
					FunctionProgramsSimple1	(Function func) : m_func(func)							{}
	void			init					(vk::SourceCollections& dst, const Arg0& arg0) const	{ m_func(dst, arg0); }

private:
	const Function	m_func;
};

//! Convenience function to create a TestCase based on a freestanding initPrograms and a TestInstance implementation
template<typename Instance, typename Arg0>
void addInstanceTestCaseWithPrograms (tcu::TestCaseGroup*								group,
									  const std::string&								name,
									  const std::string&								desc,
									  typename FunctionProgramsSimple1<Arg0>::Function	initPrograms,
									  Arg0												arg0)
{
	group->addChild(new InstanceFactory1<Instance, Arg0, FunctionProgramsSimple1<Arg0> >(
		group->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, FunctionProgramsSimple1<Arg0>(initPrograms), arg0));
}

std::string getString (const VkSampleCountFlagBits sampleCount)
{
	std::ostringstream str;
	str << "samples_" << static_cast<deUint32>(sampleCount);
	return str.str();
}

bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
{
	VkFormatProperties formatProps;
	vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
}

VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil)
{
	const InstanceInterface&	vki			= context.getInstanceInterface();
	const VkPhysicalDevice		physDevice	= context.getPhysicalDevice();

	if (useDepth && !useStencil)
		return VK_FORMAT_D16_UNORM;		// must be supported

	// One of these formats must be supported.

	if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
		return VK_FORMAT_D24_UNORM_S8_UINT;

	if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D32_SFLOAT_S8_UINT))
		return VK_FORMAT_D32_SFLOAT_S8_UINT;

	return VK_FORMAT_UNDEFINED;
}

VkImageAspectFlags getImageAspectFlags (const VkFormat format)
{
	const tcu::TextureFormat tcuFormat = mapVkFormat(format);

	if      (tcuFormat.order == tcu::TextureFormat::DS)		return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
	else if (tcuFormat.order == tcu::TextureFormat::D)		return VK_IMAGE_ASPECT_DEPTH_BIT;
	else if (tcuFormat.order == tcu::TextureFormat::S)		return VK_IMAGE_ASPECT_STENCIL_BIT;

	DE_FATAL("Format not handled");
	return 0u;
}

//! Return NotSupported if required extensions are missing
void requireExtensions (Context& context)
{
	const InstanceInterface&					vki					= context.getInstanceInterface();
	const VkPhysicalDevice						physicalDevice		= context.getPhysicalDevice();
	const std::vector<VkExtensionProperties>	supportedExtensions = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);

	if (!isExtensionSupported(supportedExtensions, RequiredExtension("VK_EXT_sample_locations")))
		TCU_THROW(NotSupportedError, "Missing extension: VK_EXT_sample_locations");
}

VkPhysicalDeviceSampleLocationsPropertiesEXT getSampleLocationsPropertiesEXT (Context& context)
{
	const InstanceInterface&	vki				= context.getInstanceInterface();
	const VkPhysicalDevice		physicalDevice	= context.getPhysicalDevice();

	VkPhysicalDeviceSampleLocationsPropertiesEXT sampleLocationsProperties;
	deMemset(&sampleLocationsProperties, 0, sizeof(sampleLocationsProperties));

	sampleLocationsProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT;
	sampleLocationsProperties.pNext = DE_NULL;

	VkPhysicalDeviceProperties2 properties =
	{
		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,	    // VkStructureType               sType;
		&sampleLocationsProperties,								// void*                         pNext;
		VkPhysicalDeviceProperties(),							// VkPhysicalDeviceProperties    properties;
	};

	vki.getPhysicalDeviceProperties2(physicalDevice, &properties);

	return sampleLocationsProperties;
}

//! Specify sample locations in a pixel grid
class MultisamplePixelGrid
{
public:
	MultisamplePixelGrid (const tcu::UVec2& gridSize, const VkSampleCountFlagBits numSamples)
		: m_gridSize		(gridSize)
		, m_numSamples		(numSamples)
		, m_sampleLocations	(gridSize.x() * gridSize.y() * numSamples)
	{
		DE_ASSERT(gridSize.x() > 0 && gridSize.y() > 0);
		DE_ASSERT(numSamples   > 1);
	}

	//! If grid x,y is larger than gridSize, then each coordinate is wrapped, x' = x % size_x
	const VkSampleLocationEXT& getSample (deUint32 gridX, deUint32 gridY, const deUint32 sampleNdx) const
	{
		return m_sampleLocations[getSampleIndex(gridX, gridY, sampleNdx)];
	}

	void setSample (const deUint32 gridX, const deUint32 gridY, const deUint32 sampleNdx, const VkSampleLocationEXT& location)
	{
		DE_ASSERT(gridX < m_gridSize.x());
		DE_ASSERT(gridY < m_gridSize.y());

		m_sampleLocations[getSampleIndex(gridX, gridY, sampleNdx)] = location;
	}

	const tcu::UVec2&			size				(void) const	{ return m_gridSize; }
	VkSampleCountFlagBits		samplesPerPixel		(void) const	{ return m_numSamples; }
	const VkSampleLocationEXT*	sampleLocations		(void) const	{ return dataOrNullPtr(m_sampleLocations); }
	VkSampleLocationEXT*		sampleLocations		(void)			{ return dataOrNullPtr(m_sampleLocations); }
	deUint32					sampleLocationCount	(void) const	{ return static_cast<deUint32>(m_sampleLocations.size()); }

private:
	deUint32 getSampleIndex (deUint32 gridX, deUint32 gridY, const deUint32 sampleNdx) const
	{
		gridX %= m_gridSize.x();
		gridY %= m_gridSize.y();
		return (gridY * m_gridSize.x() + gridX) * static_cast<deUint32>(m_numSamples) + sampleNdx;
	}

	tcu::UVec2							m_gridSize;
	VkSampleCountFlagBits				m_numSamples;
	std::vector<VkSampleLocationEXT>	m_sampleLocations;
};

inline deUint32 numSamplesPerPixel (const MultisamplePixelGrid& pixelGrid)
{
	return static_cast<deUint32>(pixelGrid.samplesPerPixel());
}

//! References the data inside MultisamplePixelGrid
inline VkSampleLocationsInfoEXT makeSampleLocationsInfo (const MultisamplePixelGrid& pixelGrid)
{
	const VkSampleLocationsInfoEXT info =
	{
		VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT,				// VkStructureType               sType;
		DE_NULL,													// const void*                   pNext;
		pixelGrid.samplesPerPixel(),								// VkSampleCountFlagBits         sampleLocationsPerPixel;
		makeExtent2D(pixelGrid.size().x(), pixelGrid.size().y()),	// VkExtent2D                    sampleLocationGridSize;
		pixelGrid.sampleLocationCount(),							// uint32_t                      sampleLocationsCount;
		pixelGrid.sampleLocations(),								// const VkSampleLocationEXT*    pSampleLocations;
	};
	return info;
}

inline VkSampleLocationsInfoEXT makeEmptySampleLocationsInfo ()
{
	const VkSampleLocationsInfoEXT info =
	{
		VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT,				// VkStructureType               sType;
		DE_NULL,													// const void*                   pNext;
		(VkSampleCountFlagBits)0,									// VkSampleCountFlagBits         sampleLocationsPerPixel;
		makeExtent2D(0,0),											// VkExtent2D                    sampleLocationGridSize;
		0,															// uint32_t                      sampleLocationsCount;
		DE_NULL,													// const VkSampleLocationEXT*    pSampleLocations;
	};
	return info;
}

void logPixelGrid (tcu::TestLog& log, const VkPhysicalDeviceSampleLocationsPropertiesEXT& sampleLocationsProperties, const MultisamplePixelGrid& pixelGrid)
{
	log << tcu::TestLog::Section("pixelGrid", "Multisample pixel grid configuration:")
		<< tcu::TestLog::Message << sampleLocationsProperties << tcu::TestLog::EndMessage
		<< tcu::TestLog::Message << "Specified grid size = " << pixelGrid.size() << tcu::TestLog::EndMessage;

	for (deUint32 gridY = 0; gridY < pixelGrid.size().y(); ++gridY)
	for (deUint32 gridX = 0; gridX < pixelGrid.size().x(); ++gridX)
	{
		log << tcu::TestLog::Message << "Pixel(" << gridX << ", " << gridY <<")" << tcu::TestLog::EndMessage;

		for (deUint32 sampleNdx = 0; sampleNdx < numSamplesPerPixel(pixelGrid); ++sampleNdx)
		{
			const VkSampleLocationEXT& loc = pixelGrid.getSample(gridX, gridY, sampleNdx);
			log << tcu::TestLog::Message << "* Sample(" << sampleNdx <<") = " << Vec2(loc.x, loc.y) << tcu::TestLog::EndMessage;
		}
	}

	log << tcu::TestLog::Message << "Sample locations visualization" << tcu::TestLog::EndMessage;

	{
		const deUint32		height	= deMinu32(1u << sampleLocationsProperties.sampleLocationSubPixelBits, 16u);	// increase if you want more precision
		const deUint32		width	= 2 * height;	// works well with a fixed-size font
		std::vector<char>	buffer	(width * height);

		for (deUint32 gridY = 0; gridY < pixelGrid.size().y(); ++gridY)
		for (deUint32 gridX = 0; gridX < pixelGrid.size().x(); ++gridX)
		{
			std::fill(buffer.begin(), buffer.end(), '.');

			for (deUint32 sampleNdx = 0; sampleNdx < numSamplesPerPixel(pixelGrid); ++sampleNdx)
			{
				const VkSampleLocationEXT&	loc		= pixelGrid.getSample(gridX, gridY, sampleNdx);
				const deUint32				ndx		= deMinu32(width  - 1, static_cast<deUint32>(static_cast<float>(width)  * loc.x)) +
													  deMinu32(height - 1, static_cast<deUint32>(static_cast<float>(height) * loc.y)) * width;
				const deUint32				evenNdx = ndx - ndx % 2;

				buffer[evenNdx    ] = '[';
				buffer[evenNdx + 1] = ']';
			}

			std::ostringstream str;
			str << "Pixel(" << gridX << ", " << gridY <<")\n";

			for (deUint32 lineNdx = 0; lineNdx < height; ++lineNdx)
			{
				str.write(&buffer[width * lineNdx], width);
				str << "\n";
			}

			log << tcu::TestLog::Message << str.str() << tcu::TestLog::EndMessage;
		}
	}

	log << tcu::TestLog::EndSection;
}

//! Fill each grid pixel with a distinct samples pattern, rounding locations based on subPixelBits
void fillSampleLocationsRandom (MultisamplePixelGrid& grid, const deUint32 subPixelBits, const deUint32 seed = 142u)
{
	const deUint32	numLocations	= 1u << subPixelBits;
	de::Random		rng				(seed);

	for (deUint32 gridY = 0; gridY < grid.size().y(); ++gridY)
	for (deUint32 gridX = 0; gridX < grid.size().x(); ++gridX)
	{
		std::set<UVec2, LessThan<UVec2> >	takenLocationIndices;
		for (deUint32 sampleNdx = 0; sampleNdx < numSamplesPerPixel(grid); /* no increment */)
		{
			const UVec2 locationNdx (rng.getUint32() % numLocations,
									 rng.getUint32() % numLocations);

			if (takenLocationIndices.find(locationNdx) == takenLocationIndices.end())
			{
				const VkSampleLocationEXT location =
				{
					static_cast<float>(locationNdx.x()) / static_cast<float>(numLocations),	// float x;
					static_cast<float>(locationNdx.y()) / static_cast<float>(numLocations),	// float y;
				};

				grid.setSample(gridX, gridY, sampleNdx, location);
				takenLocationIndices.insert(locationNdx);

				++sampleNdx;	// next sample
			}
		}
	}
}

//! Place samples very close to each other
void fillSampleLocationsPacked (MultisamplePixelGrid& grid, const deUint32 subPixelBits)
{
	const deUint32	numLocations	= 1u << subPixelBits;
	const int		offset[3]		= { -1, 0, 1 };
	de::Random		rng				(214);

	for (deUint32 gridY = 0; gridY < grid.size().y(); ++gridY)
	for (deUint32 gridX = 0; gridX < grid.size().x(); ++gridX)
	{
		// Will start placing from this location
		const UVec2 baseLocationNdx (rng.getUint32() % numLocations,
									 rng.getUint32() % numLocations);
		UVec2		locationNdx		= baseLocationNdx;

		std::set<UVec2, LessThan<UVec2> >	takenLocationIndices;
		for (deUint32 sampleNdx = 0; sampleNdx < numSamplesPerPixel(grid); /* no increment */)
		{
			if (takenLocationIndices.find(locationNdx) == takenLocationIndices.end())
			{
				const VkSampleLocationEXT location =
				{
					static_cast<float>(locationNdx.x()) / static_cast<float>(numLocations),	// float x;
					static_cast<float>(locationNdx.y()) / static_cast<float>(numLocations),	// float y;
				};

				grid.setSample(gridX, gridY, sampleNdx, location);
				takenLocationIndices.insert(locationNdx);

				++sampleNdx;	// next sample
			}

			// Find next location by applying a small offset. Just keep iterating if a redundant location is chosen
			locationNdx.x() = static_cast<deUint32>(deClamp32(locationNdx.x() + offset[rng.getUint32() % DE_LENGTH_OF_ARRAY(offset)], 0u, numLocations - 1));
			locationNdx.y() = static_cast<deUint32>(deClamp32(locationNdx.y() + offset[rng.getUint32() % DE_LENGTH_OF_ARRAY(offset)], 0u, numLocations - 1));
		}
	}
}

//! Unorm/int compare, very low threshold as we are expecting near-exact values
bool compareGreenImage (tcu::TestLog& log, const char* name, const char* description, const tcu::ConstPixelBufferAccess& image)
{
	tcu::TextureLevel greenImage(image.getFormat(), image.getWidth(), image.getHeight());
	tcu::clear(greenImage.getAccess(), tcu::RGBA::green().toIVec());
	return tcu::intThresholdCompare(log, name, description, greenImage.getAccess(), image, tcu::UVec4(2u), tcu::COMPARE_LOG_RESULT);
}

//! Silent compare - no logging
bool intThresholdCompare (const tcu::ConstPixelBufferAccess& reference, const tcu::ConstPixelBufferAccess& result, const UVec4& threshold)
{
	using namespace tcu;

	int						width				= reference.getWidth();
	int						height				= reference.getHeight();
	int						depth				= reference.getDepth();
	UVec4					maxDiff				(0, 0, 0, 0);

	TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);

	for (int z = 0; z < depth; z++)
	{
		for (int y = 0; y < height; y++)
		{
			for (int x = 0; x < width; x++)
			{
				IVec4	refPix	= reference.getPixelInt(x, y, z);
				IVec4	cmpPix	= result.getPixelInt(x, y, z);
				UVec4	diff	= abs(refPix - cmpPix).cast<deUint32>();

				maxDiff = max(maxDiff, diff);
			}
		}
	}

	return boolAll(lessThanEqual(maxDiff, threshold));
}

int countUniqueColors (const tcu::ConstPixelBufferAccess& image)
{
	std::set<Vec4, LessThan<Vec4> > colors;

	for (int y = 0; y < image.getHeight(); ++y)
	for (int x = 0; x < image.getWidth();  ++x)
	{
		colors.insert(image.getPixel(x, y));
	}

	return static_cast<int>(colors.size());
}

Move<VkImage> makeImage (const DeviceInterface&			vk,
						 const VkDevice					device,
						 const VkImageCreateFlags		flags,
						 const VkFormat					format,
						 const UVec2&					size,
						 const VkSampleCountFlagBits	samples,
						 const VkImageUsageFlags		usage)
{
	const VkImageCreateInfo imageParams =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
		DE_NULL,										// const void*				pNext;
		flags,											// VkImageCreateFlags		flags;
		VK_IMAGE_TYPE_2D,								// VkImageType				imageType;
		format,											// VkFormat					format;
		makeExtent3D(size.x(), size.y(), 1),			// VkExtent3D				extent;
		1u,												// deUint32					mipLevels;
		1u,												// deUint32					arrayLayers;
		samples,										// VkSampleCountFlagBits	samples;
		VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
		usage,											// VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
		0u,												// deUint32					queueFamilyIndexCount;
		DE_NULL,										// const deUint32*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			initialLayout;
	};
	return createImage(vk, device, &imageParams);
}

inline Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize bufferSize, const VkBufferUsageFlags usage)
{
	const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSize, usage);
	return createBuffer(vk, device, &bufferCreateInfo);
}

Move<VkEvent> makeEvent (const DeviceInterface& vk, const VkDevice device)
{
	const VkEventCreateInfo createInfo =
	{
		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,		// VkStructureType       sType;
		DE_NULL,									// const void*           pNext;
		(VkEventCreateFlags)0,						// VkEventCreateFlags    flags;
	};
	return createEvent(vk, device, &createInfo);
}

//! Generate NDC space sample locations at each framebuffer pixel
//! Data is filled starting at pixel (0,0) and for each pixel there are numSamples locations
std::vector<Vec2> genFramebufferSampleLocations (const MultisamplePixelGrid& pixelGrid, const UVec2& gridSize, const UVec2& framebufferSize)
{
	std::vector<Vec2>	locations;

	for (deUint32 y			= 0; y			< framebufferSize.y();				++y)
	for (deUint32 x			= 0; x			< framebufferSize.x();				++x)
	for (deUint32 sampleNdx	= 0; sampleNdx	< numSamplesPerPixel(pixelGrid);	++sampleNdx)
	{
		const VkSampleLocationEXT&	location = pixelGrid.getSample(x % gridSize.x(), y % gridSize.y(), sampleNdx);
		const float					globalX  = location.x + static_cast<float>(x);
		const float					globalY  = location.y + static_cast<float>(y);

		// Transform to [-1, 1] space
		locations.push_back(Vec2(-1.0f + 2.0f * (globalX / static_cast<float>(framebufferSize.x())),
								 -1.0f + 2.0f * (globalY / static_cast<float>(framebufferSize.y()))));
	}

	return locations;
}

struct PositionColor
{
	tcu::Vec4	position;
	tcu::Vec4	color;

	PositionColor (const tcu::Vec4& pos, const tcu::Vec4& col) : position(pos), color(col) {}
};

std::vector<PositionColor> genVerticesFullQuad (const Vec4& color = Vec4(1.0f), const float z = 0.0f)
{
	const PositionColor vertices[] =
	{
		PositionColor(Vec4( 1.0f, -1.0f, z, 1.0f), color),
		PositionColor(Vec4(-1.0f, -1.0f, z, 1.0f), color),
		PositionColor(Vec4(-1.0f,  1.0f, z, 1.0f), color),

		PositionColor(Vec4(-1.0f,  1.0f, z, 1.0f), color),
		PositionColor(Vec4( 1.0f,  1.0f, z, 1.0f), color),
		PositionColor(Vec4( 1.0f, -1.0f, z, 1.0f), color),
	};

	return std::vector<PositionColor>(vertices, vertices + DE_LENGTH_OF_ARRAY(vertices));
}

//! Some abstract geometry with angled edges, to make multisampling visible.
std::vector<PositionColor> genVerticesShapes (const Vec4& color = Vec4(1.0f), const float z = 0.0f)
{
	std::vector<PositionColor> vertices;

	const float numSteps  = 16.0f;
	const float angleStep = (2.0f * DE_PI) / numSteps;

	for (float a = 0.0f; a <= 2.0f * DE_PI; a += angleStep)
	{
		vertices.push_back(PositionColor(Vec4(1.0f * deFloatCos(a),				1.0f * deFloatSin(a),				z, 1.0f), color));
		vertices.push_back(PositionColor(Vec4(0.1f * deFloatCos(a - angleStep), 0.1f * deFloatSin(a - angleStep),	z, 1.0f), color));
		vertices.push_back(PositionColor(Vec4(0.1f * deFloatCos(a + angleStep), 0.1f * deFloatSin(a + angleStep),	z, 1.0f), color));
	}

	return vertices;
}

//! Stencil op that only allows drawing over the cleared area of an attachment.
inline VkStencilOpState stencilOpStateDrawOnce (void)
{
	return makeStencilOpState(
		VK_STENCIL_OP_KEEP,		// stencil fail
		VK_STENCIL_OP_ZERO,		// depth & stencil pass
		VK_STENCIL_OP_KEEP,		// depth only fail
		VK_COMPARE_OP_EQUAL,	// compare op
		~0u,					// compare mask
		~0u,					// write mask
		STENCIL_REFERENCE);		// reference
}

//! Stencil op that simply increments the buffer with each passing test.
inline VkStencilOpState stencilOpStateIncrement(void)
{
	return makeStencilOpState(
		VK_STENCIL_OP_KEEP,						// stencil fail
		VK_STENCIL_OP_INCREMENT_AND_CLAMP,		// depth & stencil pass
		VK_STENCIL_OP_KEEP,						// depth only fail
		VK_COMPARE_OP_ALWAYS,					// compare op
		~0u,									// compare mask
		~0u,									// write mask
		STENCIL_REFERENCE);						// reference
}

//! A few preconfigured vertex attribute configurations
enum VertexInputConfig
{
	VERTEX_INPUT_NONE = 0u,
	VERTEX_INPUT_VEC4,
	VERTEX_INPUT_VEC4_VEC4,
};

//! Create a MSAA pipeline, with max per-sample shading
Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&				vk,
									   const VkDevice						device,
									   const std::vector<VkDynamicState>&	dynamicState,
									   const VkPipelineLayout				pipelineLayout,
									   const VkRenderPass					renderPass,
									   const VkShaderModule					vertexModule,
									   const VkShaderModule					fragmentModule,
									   const deUint32						subpassIndex,
									   const VkViewport&					viewport,
									   const VkRect2D						scissor,
									   const VkSampleCountFlagBits			numSamples,
									   const bool							useSampleLocations,
									   const VkSampleLocationsInfoEXT&		sampleLocationsInfo,
									   const bool							useDepth,
									   const bool							useStencil,
									   const VertexInputConfig				vertexInputConfig,
									   const VkPrimitiveTopology			topology,
									   const VkStencilOpState&				stencilOpState)
{
	std::vector<VkVertexInputBindingDescription>	vertexInputBindingDescriptions;
	std::vector<VkVertexInputAttributeDescription>	vertexInputAttributeDescriptions;

	const deUint32 sizeofVec4 = static_cast<deUint32>(sizeof(Vec4));

	switch (vertexInputConfig)
	{
		case VERTEX_INPUT_NONE:
			break;

		case VERTEX_INPUT_VEC4:
			vertexInputBindingDescriptions.push_back  (makeVertexInputBindingDescription  (0u, sizeofVec4, VK_VERTEX_INPUT_RATE_VERTEX));
			vertexInputAttributeDescriptions.push_back(makeVertexInputAttributeDescription(0u, 0u,		   VK_FORMAT_R32G32B32A32_SFLOAT, 0u));
			break;

		case VERTEX_INPUT_VEC4_VEC4:
			vertexInputBindingDescriptions.push_back  (makeVertexInputBindingDescription  (0u, 2u * sizeofVec4, VK_VERTEX_INPUT_RATE_VERTEX));
			vertexInputAttributeDescriptions.push_back(makeVertexInputAttributeDescription(0u, 0u,				VK_FORMAT_R32G32B32A32_SFLOAT, 0u));
			vertexInputAttributeDescriptions.push_back(makeVertexInputAttributeDescription(1u, 0u,				VK_FORMAT_R32G32B32A32_SFLOAT, sizeofVec4));
			break;

		default:
			DE_FATAL("Vertex input config not supported");
			break;
	}

	const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
		DE_NULL,														// const void*								pNext;
		(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags	flags;
		static_cast<deUint32>(vertexInputBindingDescriptions.size()),	// uint32_t									vertexBindingDescriptionCount;
		dataOrNullPtr(vertexInputBindingDescriptions),					// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
		static_cast<deUint32>(vertexInputAttributeDescriptions.size()),	// uint32_t									vertexAttributeDescriptionCount;
		dataOrNullPtr(vertexInputAttributeDescriptions),				// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
	};

	const std::vector<VkViewport>	viewports	(1, viewport);
	const std::vector<VkRect2D>		scissors	(1, scissor);

	const VkPipelineSampleLocationsStateCreateInfoEXT pipelineSampleLocationsCreateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT,	// VkStructureType             sType;
		DE_NULL,															// const void*                 pNext;
		useSampleLocations,													// VkBool32                    sampleLocationsEnable;
		sampleLocationsInfo,												// VkSampleLocationsInfoEXT    sampleLocationsInfo;
	};

	const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
		&pipelineSampleLocationsCreateInfo,							// const void*								pNext;
		(VkPipelineMultisampleStateCreateFlags)0,					// VkPipelineMultisampleStateCreateFlags	flags;
		numSamples,													// VkSampleCountFlagBits					rasterizationSamples;
		VK_TRUE,													// VkBool32									sampleShadingEnable;
		1.0f,														// float									minSampleShading;
		DE_NULL,													// const VkSampleMask*						pSampleMask;
		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
		VK_FALSE													// VkBool32									alphaToOneEnable;
	};

	VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,													// const void*								pNext;
		(VkPipelineDepthStencilStateCreateFlags)0,					// VkPipelineDepthStencilStateCreateFlags	flags;
		useDepth,													// VkBool32									depthTestEnable;
		true,														// VkBool32									depthWriteEnable;
		VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
		VK_FALSE,													// VkBool32									depthBoundsTestEnable;
		useStencil,													// VkBool32									stencilTestEnable;
		stencilOpState,												// VkStencilOpState							front;
		stencilOpState,												// VkStencilOpState							back;
		0.0f,														// float									minDepthBounds;
		1.0f,														// float									maxDepthBounds;
	};

	const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,		// VkStructureType                      sType;
		DE_NULL,													// const void*                          pNext;
		(VkPipelineDynamicStateCreateFlags)0,						// VkPipelineDynamicStateCreateFlags    flags;
		static_cast<deUint32>(dynamicState.size()),					// uint32_t                             dynamicStateCount;
		dataOrNullPtr(dynamicState),								// const VkDynamicState*                pDynamicStates;
	};

	return makeGraphicsPipeline(vk,								// const DeviceInterface&                        vk
								device,							// const VkDevice                                device
								pipelineLayout,					// const VkPipelineLayout                        pipelineLayout
								vertexModule,					// const VkShaderModule                          vertexShaderModule
								DE_NULL,						// const VkShaderModule                          tessellationControlShaderModule
								DE_NULL,						// const VkShaderModule                          tessellationEvalShaderModule
								DE_NULL,						// const VkShaderModule                          geometryShaderModule
								fragmentModule,					// const VkShaderModule                          fragmentShaderModule
								renderPass,						// const VkRenderPass                            renderPass
								viewports,						// const std::vector<VkViewport>&                viewports
								scissors,						// const std::vector<VkRect2D>&                  scissors
								topology,						// const VkPrimitiveTopology                     topology
								subpassIndex,					// const deUint32                                subpass
								0u,								// const deUint32                                patchControlPoints
								&vertexInputStateInfo,			// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
								DE_NULL,						// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
								&pipelineMultisampleStateInfo,	// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
								&pipelineDepthStencilStateInfo,	// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
								DE_NULL,						// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
								&dynamicStateCreateInfo);		// const VkPipelineDynamicStateCreateInfo*       dynamicStateCreateInfo
}

inline Move<VkPipeline> makeGraphicsPipelineSinglePassColor (const DeviceInterface&				vk,
															 const VkDevice						device,
															 const std::vector<VkDynamicState>&	dynamicState,
															 const VkPipelineLayout				pipelineLayout,
															 const VkRenderPass					renderPass,
															 const VkShaderModule				vertexModule,
															 const VkShaderModule				fragmentModule,
															 const VkViewport&					viewport,
															 const VkRect2D						scissor,
															 const VkSampleCountFlagBits		numSamples,
															 const bool							useSampleLocations,
															 const VkSampleLocationsInfoEXT&	sampleLocationsInfo,
															 const VertexInputConfig			vertexInputConfig,
															 const VkPrimitiveTopology			topology)
{
	return makeGraphicsPipeline(vk, device, dynamicState, pipelineLayout, renderPass, vertexModule, fragmentModule,
								/*subpass*/ 0u, viewport, scissor, numSamples, useSampleLocations, sampleLocationsInfo,
								/*depth test*/ false, /*stencil test*/ false, vertexInputConfig, topology, stencilOpStateIncrement());
}

//! Utility to build and maintain render pass, framebuffer and related resources.
//! Use bake() before using the render pass.
class RenderTarget
{
public:
	RenderTarget (void)
	{
		nextSubpass();
	}

	//! Returns an attachment index that is used to reference this attachment later
	deUint32 addAttachment (const VkImageView					imageView,
							const VkAttachmentDescriptionFlags	flags,
							const VkFormat						format,
							const VkSampleCountFlagBits			numSamples,
							const VkAttachmentLoadOp			loadOp,
							const VkAttachmentStoreOp			storeOp,
							const VkAttachmentLoadOp			stencilLoadOp,
							const VkAttachmentStoreOp			stencilStoreOp,
							const VkImageLayout					initialLayout,
							const VkImageLayout					finalLayout,
							const VkClearValue					clearValue,
							const VkSampleLocationsInfoEXT*		pInitialSampleLocations = DE_NULL)
	{
		const deUint32 index = static_cast<deUint32>(m_attachments.size());

		m_attachments.push_back(imageView);
		m_attachmentDescriptions.push_back(makeAttachmentDescription(
			flags,										// VkAttachmentDescriptionFlags		flags;
			format,										// VkFormat							format;
			numSamples,									// VkSampleCountFlagBits			samples;
			loadOp,										// VkAttachmentLoadOp				loadOp;
			storeOp,									// VkAttachmentStoreOp				storeOp;
			stencilLoadOp,								// VkAttachmentLoadOp				stencilLoadOp;
			stencilStoreOp,								// VkAttachmentStoreOp				stencilStoreOp;
			initialLayout,								// VkImageLayout					initialLayout;
			finalLayout									// VkImageLayout					finalLayout;
		));
		m_clearValues.push_back(clearValue);			// always add, even if unused

		if (pInitialSampleLocations)
		{
			const VkAttachmentSampleLocationsEXT attachmentSampleLocations =
			{
				index,						// uint32_t                    attachmentIndex;
				*pInitialSampleLocations,	// VkSampleLocationsInfoEXT    sampleLocationsInfo;
			};
			m_attachmentSampleLocations.push_back(attachmentSampleLocations);
		}

		return index;
	}

	void addSubpassColorAttachment (const deUint32 attachmentIndex, const VkImageLayout subpassLayout)
	{
		m_subpasses.back().colorAttachmentReferences.push_back(
			makeAttachmentReference(attachmentIndex, subpassLayout));
		m_subpasses.back().resolveAttachmentReferences.push_back(
			makeAttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_UNDEFINED));
	}

	void addSubpassColorAttachmentWithResolve (const deUint32 colorAttachmentIndex, const VkImageLayout colorSubpassLayout, const deUint32 resolveAttachmentIndex, const VkImageLayout resolveSubpassLayout)
	{
		m_subpasses.back().colorAttachmentReferences.push_back(
			makeAttachmentReference(colorAttachmentIndex, colorSubpassLayout));
		m_subpasses.back().resolveAttachmentReferences.push_back(
			makeAttachmentReference(resolveAttachmentIndex, resolveSubpassLayout));
	}

	void addSubpassDepthStencilAttachment (const deUint32 attachmentIndex, const VkImageLayout subpassLayout, const VkSampleLocationsInfoEXT* pSampleLocations = DE_NULL)
	{
		m_subpasses.back().depthStencilAttachmentReferences.push_back(
			makeAttachmentReference(attachmentIndex, subpassLayout));

		if (pSampleLocations)
		{
			const VkSubpassSampleLocationsEXT subpassSampleLocations =
			{
				static_cast<deUint32>(m_subpasses.size() - 1),		// uint32_t                    subpassIndex;
				*pSampleLocations,									// VkSampleLocationsInfoEXT    sampleLocationsInfo;
			};
			m_subpassSampleLocations.push_back(subpassSampleLocations);
		}
	}

	void addSubpassInputAttachment (const deUint32 attachmentIndex, const VkImageLayout subpassLayout)
	{
		m_subpasses.back().inputAttachmentReferences.push_back(
			makeAttachmentReference(attachmentIndex, subpassLayout));
	}

	void addSubpassPreserveAttachment (const deUint32 attachmentIndex)
	{
		m_subpasses.back().preserveAttachmentReferences.push_back(attachmentIndex);
	}

	void nextSubpass (void)
	{
		m_subpasses.push_back(SubpassDescription());
	}

	//! Create a RenderPass and Framebuffer based on provided attachments
	void bake (const DeviceInterface&							vk,
			   const VkDevice									device,
			   const UVec2&										framebufferSize)
	{
		DE_ASSERT(!m_renderPass);
		const deUint32 numSubpasses = static_cast<deUint32>(m_subpasses.size());

		std::vector<VkSubpassDescription>	subpassDescriptions;
		std::vector<VkSubpassDependency>	subpassDependencies;
		for (deUint32 subpassNdx = 0; subpassNdx < numSubpasses; ++subpassNdx)
		{
			const SubpassDescription&	sd			= m_subpasses[subpassNdx];
			const VkSubpassDescription	description	=
			{
				(VkSubpassDescriptionFlags)0,									// VkSubpassDescriptionFlags		flags;
				VK_PIPELINE_BIND_POINT_GRAPHICS,								// VkPipelineBindPoint				pipelineBindPoint;
				static_cast<deUint32>(sd.inputAttachmentReferences.size()),		// deUint32							inputAttachmentCount;
				dataOrNullPtr(sd.inputAttachmentReferences),					// const VkAttachmentReference*		pInputAttachments;
				static_cast<deUint32>(sd.colorAttachmentReferences.size()),		// deUint32							colorAttachmentCount;
				dataOrNullPtr(sd.colorAttachmentReferences),					// const VkAttachmentReference*		pColorAttachments;
				dataOrNullPtr(sd.resolveAttachmentReferences),					// const VkAttachmentReference*		pResolveAttachments;
				dataOrNullPtr(sd.depthStencilAttachmentReferences),				// const VkAttachmentReference*		pDepthStencilAttachment;
				static_cast<deUint32>(sd.preserveAttachmentReferences.size()),	// deUint32							preserveAttachmentCount;
				dataOrNullPtr(sd.preserveAttachmentReferences)					// const deUint32*					pPreserveAttachments;
			};
			subpassDescriptions.push_back(description);

			// Add a very coarse dependency enforcing sequential ordering of subpasses
			if (subpassNdx > 0)
			{
				static const VkAccessFlags	accessAny	= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
														| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
														| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
														| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
														| VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
				const VkSubpassDependency	dependency	=
				{
					subpassNdx - 1,								// uint32_t                srcSubpass;
					subpassNdx,									// uint32_t                dstSubpass;
					VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,			// VkPipelineStageFlags    srcStageMask;
					VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,			// VkPipelineStageFlags    dstStageMask;
					accessAny,									// VkAccessFlags           srcAccessMask;
					accessAny,									// VkAccessFlags           dstAccessMask;
					(VkDependencyFlags)0,						// VkDependencyFlags       dependencyFlags;
				};
				subpassDependencies.push_back(dependency);
			}
		}

		const VkRenderPassCreateInfo renderPassInfo =
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,						// VkStructureType					sType;
			DE_NULL,														// const void*						pNext;
			(VkRenderPassCreateFlags)0,										// VkRenderPassCreateFlags			flags;
			static_cast<deUint32>(m_attachmentDescriptions.size()),			// deUint32							attachmentCount;
			dataOrNullPtr(m_attachmentDescriptions),						// const VkAttachmentDescription*	pAttachments;
			static_cast<deUint32>(subpassDescriptions.size()),				// deUint32							subpassCount;
			dataOrNullPtr(subpassDescriptions),								// const VkSubpassDescription*		pSubpasses;
			static_cast<deUint32>(subpassDependencies.size()),				// deUint32							dependencyCount;
			dataOrNullPtr(subpassDependencies)								// const VkSubpassDependency*		pDependencies;
		};

		m_renderPass  = createRenderPass(vk, device, &renderPassInfo);
		m_framebuffer = makeFramebuffer (vk, device, *m_renderPass, static_cast<deUint32>(m_attachments.size()), dataOrNullPtr(m_attachments), framebufferSize.x(), framebufferSize.y());
	}

	VkRenderPass getRenderPass (void) const
	{
		DE_ASSERT(m_renderPass);
		return *m_renderPass;
	}

	VkFramebuffer getFramebuffer (void) const
	{
		DE_ASSERT(m_framebuffer);
		return *m_framebuffer;
	}

	void recordBeginRenderPass (const DeviceInterface&	vk,
								const VkCommandBuffer	cmdBuffer,
								const VkRect2D&			renderArea,
								const VkSubpassContents	subpassContents) const
	{
		DE_ASSERT(m_renderPass);
		DE_ASSERT(m_framebuffer);

		const VkRenderPassSampleLocationsBeginInfoEXT renderPassSampleLocationsBeginInfo =
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT,	// VkStructureType                          sType;
			DE_NULL,														// const void*                              pNext;
			static_cast<deUint32>(m_attachmentSampleLocations.size()),		// uint32_t                                 attachmentInitialSampleLocationsCount;
			dataOrNullPtr(m_attachmentSampleLocations),						// const VkAttachmentSampleLocationsEXT*    pAttachmentInitialSampleLocations;
			static_cast<deUint32>(m_subpassSampleLocations.size()),			// uint32_t                                 postSubpassSampleLocationsCount;
			dataOrNullPtr(m_subpassSampleLocations),						// const VkSubpassSampleLocationsEXT*       pPostSubpassSampleLocations;
		};

		const VkRenderPassBeginInfo renderPassBeginInfo =
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,						// VkStructureType         sType;
			&renderPassSampleLocationsBeginInfo,							// const void*             pNext;
			*m_renderPass,													// VkRenderPass            renderPass;
			*m_framebuffer,													// VkFramebuffer           framebuffer;
			renderArea,														// VkRect2D                renderArea;
			static_cast<deUint32>(m_clearValues.size()),					// uint32_t                clearValueCount;
			dataOrNullPtr(m_clearValues),									// const VkClearValue*     pClearValues;
		};
		vk.cmdBeginRenderPass(cmdBuffer, &renderPassBeginInfo, subpassContents);
	}

private:
	struct SubpassDescription
	{
		std::vector<VkAttachmentReference>	inputAttachmentReferences;
		std::vector<VkAttachmentReference>	colorAttachmentReferences;
		std::vector<VkAttachmentReference>	resolveAttachmentReferences;
		std::vector<VkAttachmentReference>	depthStencilAttachmentReferences;
		std::vector<deUint32>				preserveAttachmentReferences;
	};

	std::vector<SubpassDescription>				m_subpasses;
	std::vector<VkImageView>					m_attachments;
	std::vector<VkAttachmentDescription>		m_attachmentDescriptions;
	std::vector<VkClearValue>					m_clearValues;
	std::vector<VkAttachmentSampleLocationsEXT>	m_attachmentSampleLocations;
	std::vector<VkSubpassSampleLocationsEXT>	m_subpassSampleLocations;
	Move<VkRenderPass>							m_renderPass;
	Move<VkFramebuffer>							m_framebuffer;

	// No copying allowed
	RenderTarget (const RenderTarget&);
	RenderTarget& operator=(const RenderTarget&);
};

void recordImageBarrier (const DeviceInterface&				vk,
						 const VkCommandBuffer				cmdBuffer,
						 const VkImage						image,
						 const VkImageAspectFlags			aspect,
						 const VkPipelineStageFlags			srcStageMask,
						 const VkPipelineStageFlags			dstStageMask,
						 const VkAccessFlags				srcAccessMask,
						 const VkAccessFlags				dstAccessMask,
						 const VkImageLayout				oldLayout,
						 const VkImageLayout				newLayout,
						 const VkSampleLocationsInfoEXT*	pSampleLocationsInfo = DE_NULL)
{
	const VkImageMemoryBarrier barrier =
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,						// VkStructureType            sType;
		pSampleLocationsInfo,										// const void*                pNext;
		srcAccessMask,												// VkAccessFlags              srcAccessMask;
		dstAccessMask,												// VkAccessFlags              dstAccessMask;
		oldLayout,													// VkImageLayout              oldLayout;
		newLayout,													// VkImageLayout              newLayout;
		VK_QUEUE_FAMILY_IGNORED,									// uint32_t                   srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,									// uint32_t                   dstQueueFamilyIndex;
		image,														// VkImage                    image;
		makeImageSubresourceRange(aspect, 0u, 1u, 0u, 1u),			// VkImageSubresourceRange    subresourceRange;
	};

	vk.cmdPipelineBarrier(cmdBuffer, srcStageMask, dstStageMask, (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
}

void recordWaitEventWithImage (const DeviceInterface&			vk,
							   const VkCommandBuffer			cmdBuffer,
							   const VkEvent					event,
							   const VkImage					image,
							   const VkImageAspectFlags			aspect,
							   const VkPipelineStageFlags		srcStageMask,
							   const VkPipelineStageFlags		dstStageMask,
							   const VkAccessFlags				srcAccessMask,
							   const VkAccessFlags				dstAccessMask,
							   const VkImageLayout				oldLayout,
							   const VkImageLayout				newLayout,
							   const VkSampleLocationsInfoEXT*	pSampleLocationsInfo = DE_NULL)
{
	const VkImageMemoryBarrier barrier =
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,						// VkStructureType            sType;
		pSampleLocationsInfo,										// const void*                pNext;
		srcAccessMask,												// VkAccessFlags              srcAccessMask;
		dstAccessMask,												// VkAccessFlags              dstAccessMask;
		oldLayout,													// VkImageLayout              oldLayout;
		newLayout,													// VkImageLayout              newLayout;
		VK_QUEUE_FAMILY_IGNORED,									// uint32_t                   srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,									// uint32_t                   dstQueueFamilyIndex;
		image,														// VkImage                    image;
		makeImageSubresourceRange(aspect, 0u, 1u, 0u, 1u),			// VkImageSubresourceRange    subresourceRange;
	};

	vk.cmdWaitEvents(
		cmdBuffer,													// VkCommandBuffer                             commandBuffer,
		1u,															// uint32_t                                    eventCount,
		&event,														// const VkEvent*                              pEvents,
		srcStageMask,												// VkPipelineStageFlags                        srcStageMask,
		dstStageMask,												// VkPipelineStageFlags                        dstStageMask,
		0u,															// uint32_t                                    memoryBarrierCount,
		DE_NULL,													// const VkMemoryBarrier*                      pMemoryBarriers,
		0u,															// uint32_t                                    bufferMemoryBarrierCount,
		DE_NULL,													// const VkBufferMemoryBarrier*                pBufferMemoryBarriers,
		1u,															// uint32_t                                    imageMemoryBarrierCount,
		&barrier);													// const VkImageMemoryBarrier*                 pImageMemoryBarriers);
}

void recordCopyImageToBuffer (const DeviceInterface&	vk,
							  const VkCommandBuffer		cmdBuffer,
							  const UVec2&				imageSize,
							  const VkImage				srcImage,
							  const VkBuffer			dstBuffer)
{
	// Resolve image -> host buffer
	{
		const VkBufferImageCopy region =
		{
			0ull,																// VkDeviceSize                bufferOffset;
			0u,																	// uint32_t                    bufferRowLength;
			0u,																	// uint32_t                    bufferImageHeight;
			makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),	// VkImageSubresourceLayers    imageSubresource;
			makeOffset3D(0, 0, 0),												// VkOffset3D                  imageOffset;
			makeExtent3D(imageSize.x(), imageSize.y(), 1u),						// VkExtent3D                  imageExtent;
		};

		vk.cmdCopyImageToBuffer(cmdBuffer, srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstBuffer, 1u, &region);
	}
	// Buffer write barrier
	{
		const VkBufferMemoryBarrier barrier =
		{
			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType    sType;
			DE_NULL,										// const void*        pNext;
			VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags      srcAccessMask;
			VK_ACCESS_HOST_READ_BIT,						// VkAccessFlags      dstAccessMask;
			VK_QUEUE_FAMILY_IGNORED,						// uint32_t           srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,						// uint32_t           dstQueueFamilyIndex;
			dstBuffer,										// VkBuffer           buffer;
			0ull,											// VkDeviceSize       offset;
			VK_WHOLE_SIZE,									// VkDeviceSize       size;
		};

		vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
							  0u, DE_NULL, 1u, &barrier, DE_NULL, 0u);
	}
}

void recordClearAttachments (const DeviceInterface&		vk,
							 const VkCommandBuffer		cmdBuffer,
							 const deUint32				colorAttachment,
							 const VkClearValue&		colorClearValue,
							 const VkImageAspectFlags	depthStencilAspect,
							 const VkClearValue&		depthStencilClearValue,
							 const VkRect2D&			clearRect)
{
	std::vector<VkClearAttachment> attachments;

	const VkClearRect rect =
	{
		clearRect,					// VkRect2D    rect;
		0u,							// uint32_t    baseArrayLayer;
		1u,							// uint32_t    layerCount;
	};

	// Clear color
	{
		const VkClearAttachment attachment =
		{
			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags    aspectMask;
			colorAttachment,			// uint32_t              colorAttachment;
			colorClearValue,			// VkClearValue          clearValue;
		};
		attachments.push_back(attachment);
	}

	if ((depthStencilAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0u)
	{
		const VkClearAttachment attachment =
		{
			depthStencilAspect,			// VkImageAspectFlags    aspectMask;
			VK_ATTACHMENT_UNUSED,		// uint32_t              colorAttachment;
			depthStencilClearValue,		// VkClearValue          clearValue;
		};
		attachments.push_back(attachment);
	}

	vk.cmdClearAttachments(cmdBuffer, static_cast<deUint32>(attachments.size()), dataOrNullPtr(attachments), 1u, &rect);
}

//! Suitable for executing in a render pass, no queries
void beginSecondaryCommandBuffer (const DeviceInterface&	vk,
								  const VkCommandBuffer		commandBuffer,
								  const VkRenderPass		renderPass,
								  const deUint32			subpass,
								  const VkFramebuffer		framebuffer)
{
	const VkCommandBufferInheritanceInfo inheritanceInfo =
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,		// VkStructureType                  sType;
		DE_NULL,												// const void*                      pNext;
		renderPass,												// VkRenderPass                     renderPass;
		subpass,												// uint32_t                         subpass;
		framebuffer,											// VkFramebuffer                    framebuffer;
		VK_FALSE,												// VkBool32                         occlusionQueryEnable;
		(VkQueryControlFlags)0,									// VkQueryControlFlags              queryFlags;
		(VkQueryPipelineStatisticFlags)0,						// VkQueryPipelineStatisticFlags    pipelineStatistics;
	};
	const VkCommandBufferBeginInfo beginInfo =
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,		// VkStructureType                          sType;
		DE_NULL,											// const void*                              pNext;
		(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
		|VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT),	// VkCommandBufferUsageFlags                flags;
		&inheritanceInfo,									// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
	};
	VK_CHECK(vk.beginCommandBuffer(commandBuffer, &beginInfo));
}

//! Verify results of a VkPhysicalDeviceSampleLocationsPropertiesEXT query with VkPhysicalDeviceProperties2KHR
tcu::TestStatus testQuerySampleLocationProperties (Context& context)
{
	requireExtensions(context);

	const VkPhysicalDeviceSampleLocationsPropertiesEXT sampleLocationsProperties = getSampleLocationsPropertiesEXT(context);

	context.getTestContext().getLog()
		<< tcu::TestLog::Section("VkPhysicalDeviceSampleLocationsPropertiesEXT", "Query results")
		<< tcu::TestLog::Message << sampleLocationsProperties << tcu::TestLog::EndMessage
		<< tcu::TestLog::EndSection;

	const VkSampleCountFlags allowedSampleCounts = (VK_SAMPLE_COUNT_2_BIT  |
													VK_SAMPLE_COUNT_4_BIT  |
													VK_SAMPLE_COUNT_8_BIT  |
													VK_SAMPLE_COUNT_16_BIT |
													VK_SAMPLE_COUNT_32_BIT |
													VK_SAMPLE_COUNT_64_BIT);

	if ((sampleLocationsProperties.sampleLocationSampleCounts & allowedSampleCounts) == 0)
	{
		return tcu::TestStatus::fail("VkPhysicalDeviceSampleLocationsPropertiesEXT: sampleLocationSampleCounts should specify at least one MSAA sample count");
	}

	if (sampleLocationsProperties.maxSampleLocationGridSize.width  == 0u     ||
		sampleLocationsProperties.maxSampleLocationGridSize.height == 0u     ||
		sampleLocationsProperties.maxSampleLocationGridSize.width  >  16384u || // max not specified, but try to catch nonsense values like -1
		sampleLocationsProperties.maxSampleLocationGridSize.height >  16384u)
	{
		return tcu::TestStatus::fail("VkPhysicalDeviceSampleLocationsPropertiesEXT: maxSampleLocationGridSize must be at least (1,1) size");
	}

	for (int i = 0; i < 2; ++i)
	{
		if (sampleLocationsProperties.sampleLocationCoordinateRange[i] < 0.0f ||
			sampleLocationsProperties.sampleLocationCoordinateRange[i] > 1.0f)
		{
			return tcu::TestStatus::fail("VkPhysicalDeviceSampleLocationsPropertiesEXT: sampleLocationCoordinateRange[] values must be in [0, 1] range");
		}
	}

	if (sampleLocationsProperties.sampleLocationSubPixelBits == 0u  ||
		sampleLocationsProperties.sampleLocationSubPixelBits >  64u)	// max not specified, but try to catch nonsense values
	{
		return tcu::TestStatus::fail("VkPhysicalDeviceSampleLocationsPropertiesEXT: sampleLocationSubPixelBits should be greater than 0");
	}

	return tcu::TestStatus::pass("Pass");
}

//! Verify results of vkGetPhysicalDeviceMultisamplePropertiesEXT queries
tcu::TestStatus testQueryMultisampleProperties (Context& context)
{
	requireExtensions(context);

	const InstanceInterface&	vki				= context.getInstanceInterface();
	const VkPhysicalDevice		physicalDevice	= context.getPhysicalDevice();
	tcu::TestLog&				log				= context.getTestContext().getLog();

	const VkPhysicalDeviceSampleLocationsPropertiesEXT sampleLocationsProperties = getSampleLocationsPropertiesEXT(context);

	const VkSampleCountFlagBits	sampleCountRange[] =
	{
		VK_SAMPLE_COUNT_1_BIT,
		VK_SAMPLE_COUNT_2_BIT,
		VK_SAMPLE_COUNT_4_BIT,
		VK_SAMPLE_COUNT_8_BIT,
		VK_SAMPLE_COUNT_16_BIT,
		VK_SAMPLE_COUNT_32_BIT,
		VK_SAMPLE_COUNT_64_BIT,
	};

	bool allOk = true;

	for (const VkSampleCountFlagBits* pLoopNumSamples = sampleCountRange; pLoopNumSamples < DE_ARRAY_END(sampleCountRange); ++pLoopNumSamples)
	{
		VkMultisamplePropertiesEXT multisampleProperties =
		{
			VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT,		// VkStructureType    sType;
			DE_NULL,											// void*              pNext;
			VkExtent2D(),										// VkExtent2D         maxSampleLocationGridSize;
		};

		vki.getPhysicalDeviceMultisamplePropertiesEXT(physicalDevice, *pLoopNumSamples, &multisampleProperties);

		log << tcu::TestLog::Section("getPhysicalDeviceMultisamplePropertiesEXT", "Query results")
			<< tcu::TestLog::Message << "Sample count: " << *pLoopNumSamples << tcu::TestLog::EndMessage
			<< tcu::TestLog::Message << multisampleProperties << tcu::TestLog::EndMessage;

		const bool isSupportedSampleCount = (*pLoopNumSamples & sampleLocationsProperties.sampleLocationSampleCounts) != 0;

		if (isSupportedSampleCount)
		{
			if (!(multisampleProperties.maxSampleLocationGridSize.width  >= sampleLocationsProperties.maxSampleLocationGridSize.width &&
				  multisampleProperties.maxSampleLocationGridSize.height >= sampleLocationsProperties.maxSampleLocationGridSize.height))
			{
				allOk = false;
				log << tcu::TestLog::Message
					<< "FAIL: Grid size should be the same or larger than VkPhysicalDeviceSampleLocationsPropertiesEXT::maxSampleLocationGridSize"
					<< tcu::TestLog::EndMessage;
			}
		}
		else
		{
			if (!(multisampleProperties.maxSampleLocationGridSize.width  == 0u &&
				  multisampleProperties.maxSampleLocationGridSize.height == 0u))
			{
				allOk = false;
				log << tcu::TestLog::Message << "FAIL: Expected (0, 0) grid size" << tcu::TestLog::EndMessage;
			}
		}

		log << tcu::TestLog::EndSection;
	}

	return allOk ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some values were incorrect");
}

// These tests only use a color attachment and focus on per-sample data
namespace VerifySamples
{

//! Data layout used in verify sample locations and interpolation cases
namespace SampleDataSSBO
{

static VkDeviceSize	STATIC_SIZE		= 6 * sizeof(deUint32);

static UVec2&		renderSize		(void* const basePtr) { return *reinterpret_cast<UVec2*>	(static_cast<deUint8*>(basePtr) + 0 * sizeof(deUint32)); }
static UVec2&		gridSize		(void* const basePtr) { return *reinterpret_cast<UVec2*>	(static_cast<deUint8*>(basePtr) + 2 * sizeof(deUint32)); }
static deUint32&	samplesPerPixel	(void* const basePtr) { return *reinterpret_cast<deUint32*>	(static_cast<deUint8*>(basePtr) + 4 * sizeof(deUint32)); }

template<typename T>
static T*			sampleData		(void* const basePtr) { DE_STATIC_ASSERT(sizeof(T) == sizeof(Vec2));
															return  reinterpret_cast<T*>		(static_cast<deUint8*>(basePtr) + STATIC_SIZE); }

} // SampleDataSSBO

enum TestOptionFlagBits
{
	TEST_OPTION_DYNAMIC_STATE_BIT	= 0x1,	//!< Use dynamic pipeline state to pass in sample locations
	TEST_OPTION_CLOSELY_PACKED_BIT	= 0x2,	//!< Place samples as close as possible to each other
};
typedef deUint32 TestOptionFlags;

struct TestParams
{
	VkSampleCountFlagBits	numSamples;
	TestOptionFlags			options;
};

std::string declareSampleDataSSBO (void)
{
	std::ostringstream str;
	str << "layout(set = 0, binding = 0, std430) readonly buffer SampleData {\n"	// make sure this matches SampleDataSSBO definition
		<< "    uvec2 renderSize;\n"
		<< "    uvec2 gridSize;\n"
		<< "    uint  samplesPerPixel;\n"
		<< "          // padding 1-uint size;\n"
		<< "    vec2  data[];\n"
		<< "} sb_data;\n";
	return str.str();
};

void addProgramsVerifyLocationGeometry (SourceCollections& programCollection, const TestParams)
{
	// Vertex shader
	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
			<< "\n"
			<< "layout(location = 0) in vec4 in_position;\n"
			<< "\n"
			<< "out gl_PerVertex {\n"
			<< "    vec4 gl_Position;\n"
			<< "};\n"
			<< "\n"
			<< "void main(void)\n"
			<< "{\n"
			<< "    gl_Position = in_position;\n"
			<< "}\n";

		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
	}

	// Fragment shader
	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
			<< "\n"
			<< "layout(location = 0) out vec4 o_color;\n"
			<< "\n"
			<< declareSampleDataSSBO()
			<< "\n"
			<< "void main(void)\n"
			<< "{\n"
			<< "    uvec2 fragCoord = uvec2(gl_FragCoord.xy);\n"
			<< "    uint  index     = (fragCoord.y * sb_data.renderSize.x + fragCoord.x) * sb_data.samplesPerPixel + gl_SampleID;\n"
			<< "\n"
			<< "    if (gl_PrimitiveID == index)\n"
			<< "        o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
			<< "    else\n"
			<< "        o_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
			<< "}\n";

		programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
	}
}

void addProgramsVerifyInterpolation (SourceCollections& programCollection, const TestParams)
{
	// Vertex shader
	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
			<< "\n"
			<< "layout(location = 0) in  vec4 in_position;\n"
			<< "layout(location = 0) out vec2 o_position;\n"
			<< "\n"
			<< "out gl_PerVertex {\n"
			<< "    vec4 gl_Position;\n"
			<< "};\n"
			<< "\n"
			<< "void main(void)\n"
			<< "{\n"
			<< "    gl_Position = in_position;\n"
			<< "    o_position  = in_position.xy;\n"	// user-data that will be interpolated
			<< "}\n";

		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
	}

	// Fragment shader
	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
			<< "\n"
			<< "layout(location = 0) sample in  vec2 in_value;\n"
			<< "layout(location = 0)        out vec4 o_color;\n"
			<< "\n"
			<< declareSampleDataSSBO()
			<< "\n"
			<< "void main(void)\n"
			<< "{\n"
			<< "    uvec2 fragCoord         = uvec2(gl_FragCoord.xy);\n"
			<< "    uint  index             = (fragCoord.y * sb_data.renderSize.x + fragCoord.x) * sb_data.samplesPerPixel + gl_SampleID;\n"
			<< "    vec2  diff              = abs(sb_data.data[index] - in_value);\n"
			<< "    vec2  threshold         = vec2(0.002);\n"
			<< "\n"
			<< "    if (all(lessThan(diff, threshold)))\n"
			<< "        o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
			<< "    else\n"
			<< "        o_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
			<< "}\n";

		programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
	}
}

class TestBase : public TestInstance
{
public:
	TestBase (Context& context, const TestParams params)
		: TestInstance					(context)
		, m_params						(params)
		, m_sampleLocationsProperties	(getSampleLocationsPropertiesEXT(context))
		, m_colorFormat					(VK_FORMAT_R8G8B8A8_UNORM)
		, m_numVertices					(0)
		, m_currentGridNdx				(0)
	{
		requireExtensions(context);

		VkMultisamplePropertiesEXT multisampleProperties =
		{
			VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT,		// VkStructureType    sType;
			DE_NULL,											// void*              pNext;
			VkExtent2D(),										// VkExtent2D         maxSampleLocationGridSize;
		};

		m_context.getInstanceInterface().getPhysicalDeviceMultisamplePropertiesEXT(m_context.getPhysicalDevice(), m_params.numSamples, &multisampleProperties);

		// Generate grid size combinations
		for (deUint32 y = multisampleProperties.maxSampleLocationGridSize.height; y >= 1u; y >>= 1)
		for (deUint32 x = multisampleProperties.maxSampleLocationGridSize.width;  x >= 1u; x >>= 1)
		{
			DE_ASSERT(multisampleProperties.maxSampleLocationGridSize.width  % x == 0u);
			DE_ASSERT(multisampleProperties.maxSampleLocationGridSize.height % y == 0u);
			m_gridSizes.push_back(UVec2(x, y));
		}
	}

	tcu::TestStatus iterate (void)
	{
		// Will be executed several times, for all possible pixel grid sizes

		const VkPhysicalDeviceLimits&	limits	= m_context.getDeviceProperties().limits;

		if (!m_context.getDeviceFeatures().sampleRateShading)
			TCU_THROW(NotSupportedError, "Missing feature: sampleRateShading");

		if ((limits.framebufferColorSampleCounts & m_params.numSamples) == 0u)
			TCU_THROW(NotSupportedError, "framebufferColorSampleCounts: sample count not supported");

		if ((m_sampleLocationsProperties.sampleLocationSampleCounts & m_params.numSamples) == 0u)
			TCU_THROW(NotSupportedError, "VkPhysicalDeviceSampleLocationsPropertiesEXT: sample count not supported");

		if (!(currentGridSize().x() >= 1 && currentGridSize().y() >= 1))
			return tcu::TestStatus::fail("maxSampleLocationGridSize is invalid");

		// Prepare the pixel grid
		{
			const deUint32	pixelGridRepetitions = 2;	// just to make sure the pattern is consistently applied across the framebuffer
			m_renderSize = UVec2(pixelGridRepetitions * currentGridSize().x(),
								 pixelGridRepetitions * currentGridSize().y());
			m_pixelGrid = MovePtr<MultisamplePixelGrid>(new MultisamplePixelGrid(currentGridSize(), m_params.numSamples));

			if ((m_params.options & TEST_OPTION_CLOSELY_PACKED_BIT) != 0u)
				fillSampleLocationsPacked(*m_pixelGrid, m_sampleLocationsProperties.sampleLocationSubPixelBits);
			else
				fillSampleLocationsRandom(*m_pixelGrid, m_sampleLocationsProperties.sampleLocationSubPixelBits);

			logPixelGrid (m_context.getTestContext().getLog(), m_sampleLocationsProperties, *m_pixelGrid);
		}

		// Create images
		{
			const DeviceInterface&	vk			= m_context.getDeviceInterface();
			const VkDevice			device		= m_context.getDevice();
			Allocator&				allocator	= m_context.getDefaultAllocator();

			// Images and staging buffers

			m_colorImage		= makeImage(vk, device, (VkImageCreateFlags)0, m_colorFormat, m_renderSize, m_params.numSamples, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
			m_colorImageAlloc	= bindImage(vk, device, allocator, *m_colorImage, MemoryRequirement::Any);
			m_colorImageView	= makeImageView(vk, device, *m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));

			m_resolveImage		= makeImage(vk, device, (VkImageCreateFlags)0, m_colorFormat, m_renderSize, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
			m_resolveImageAlloc	= bindImage(vk, device, allocator, *m_resolveImage, MemoryRequirement::Any);
			m_resolveImageView	= makeImageView(vk, device, *m_resolveImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));

			const VkDeviceSize	colorBufferSize = m_renderSize.x() * m_renderSize.y() * tcu::getPixelSize(mapVkFormat(m_colorFormat));
			m_colorBuffer		= makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
			m_colorBufferAlloc	= bindBuffer(vk, device, allocator, *m_colorBuffer, MemoryRequirement::HostVisible);
		}

		if (!testPixelGrid())
			return tcu::TestStatus::fail("Fail");

		if (shrinkCurrentGrid())
			return tcu::TestStatus::incomplete();
		else
			return tcu::TestStatus::pass("Pass");
	}

protected:
	//! Return true if the test passed the current grid size
	virtual bool testPixelGrid (void) = 0;

	const UVec2& currentGridSize (void)
	{
		return m_gridSizes[m_currentGridNdx];
	}

	//! Return false if the grid is already at (1, 1) size
	bool shrinkCurrentGrid (void)
	{
		if (m_gridSizes.size() <= m_currentGridNdx + 1)
			return false;

		++m_currentGridNdx;
		return true;
	}

	void drawSinglePass (const VertexInputConfig vertexInputConfig)
	{
		DE_ASSERT(m_descriptorSetLayout);

		const DeviceInterface&			vk				= m_context.getDeviceInterface();
		const VkDevice					device			= m_context.getDevice();
		const VkViewport				viewport		= makeViewport(m_renderSize);
		const VkRect2D					renderArea		= makeRect2D(m_renderSize);
		const VkRect2D					scissor			= makeRect2D(m_renderSize);
		const Unique<VkShaderModule>	vertexModule	(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
		const Unique<VkShaderModule>	fragmentModule	(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
		const Unique<VkPipelineLayout>	pipelineLayout	(makePipelineLayout(vk, device, *m_descriptorSetLayout));

		const bool						useDynamicStateSampleLocations	= ((m_params.options & TEST_OPTION_DYNAMIC_STATE_BIT) != 0u);
		const VkSampleLocationsInfoEXT	sampleLocationsInfo				= makeSampleLocationsInfo(*m_pixelGrid);

		RenderTarget rt;

		rt.addAttachment(
			*m_colorImageView,											// VkImageView					imageView,
			(VkAttachmentDescriptionFlags)0,							// VkAttachmentDescriptionFlags	flags,
			m_colorFormat,												// VkFormat						format,
			m_params.numSamples,										// VkSampleCountFlagBits		numSamples,
			VK_ATTACHMENT_LOAD_OP_CLEAR,								// VkAttachmentLoadOp			loadOp,
			VK_ATTACHMENT_STORE_OP_STORE,								// VkAttachmentStoreOp			storeOp,
			VK_ATTACHMENT_LOAD_OP_DONT_CARE,							// VkAttachmentLoadOp			stencilLoadOp,
			VK_ATTACHMENT_STORE_OP_DONT_CARE,							// VkAttachmentStoreOp			stencilStoreOp,
			VK_IMAGE_LAYOUT_UNDEFINED,									// VkImageLayout				initialLayout,
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,					// VkImageLayout				finalLayout,
			makeClearValueColor(CLEAR_COLOR_0));						// VkClearValue					clearValue,

		rt.addAttachment(
			*m_resolveImageView,										// VkImageView					imageView,
			(VkAttachmentDescriptionFlags)0,							// VkAttachmentDescriptionFlags	flags,
			m_colorFormat,												// VkFormat						format,
			VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits		numSamples,
			VK_ATTACHMENT_LOAD_OP_DONT_CARE,							// VkAttachmentLoadOp			loadOp,
			VK_ATTACHMENT_STORE_OP_STORE,								// VkAttachmentStoreOp			storeOp,
			VK_ATTACHMENT_LOAD_OP_DONT_CARE,							// VkAttachmentLoadOp			stencilLoadOp,
			VK_ATTACHMENT_STORE_OP_DONT_CARE,							// VkAttachmentStoreOp			stencilStoreOp,
			VK_IMAGE_LAYOUT_UNDEFINED,									// VkImageLayout				initialLayout,
			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,						// VkImageLayout				finalLayout,
			VkClearValue());											// VkClearValue					clearValue,

		rt.addSubpassColorAttachmentWithResolve(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
												1u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);

		rt.bake(vk, device, m_renderSize);

		Move<VkPipeline> pipeline;

		if (useDynamicStateSampleLocations)
		{
			std::vector<VkDynamicState>	dynamicState;
			dynamicState.push_back(VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT);

			pipeline = makeGraphicsPipelineSinglePassColor(
				vk, device, dynamicState, *pipelineLayout, rt.getRenderPass(), *vertexModule, *fragmentModule, viewport, scissor,
				m_params.numSamples, /*use sample locations*/ true, makeEmptySampleLocationsInfo(), vertexInputConfig, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
		}
		else
		{
			pipeline = makeGraphicsPipelineSinglePassColor(
				vk, device, std::vector<VkDynamicState>(), *pipelineLayout, rt.getRenderPass(), *vertexModule, *fragmentModule, viewport, scissor,
				m_params.numSamples, /*use sample locations*/ true, sampleLocationsInfo, vertexInputConfig, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
		}

		const Unique<VkCommandPool>		cmdPool		(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_context.getUniversalQueueFamilyIndex()));
		const Unique<VkCommandBuffer>	cmdBuffer	(makeCommandBuffer(vk, device, *cmdPool));

		beginCommandBuffer(vk, *cmdBuffer);

		rt.recordBeginRenderPass(vk, *cmdBuffer, renderArea, VK_SUBPASS_CONTENTS_INLINE);

		vk.cmdBindVertexBuffers(*cmdBuffer, /*first binding*/ 0u, /*num bindings*/ 1u, &m_vertexBuffer.get(), /*offsets*/ &ZERO);
		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

		if (useDynamicStateSampleLocations)
			vk.cmdSetSampleLocationsEXT(*cmdBuffer, &sampleLocationsInfo);

		if (m_descriptorSet)
			vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);

		vk.cmdDraw(*cmdBuffer, m_numVertices, 1u, 0u, 0u);
		endRenderPass(vk, *cmdBuffer);

		// Resolve image -> host buffer
		recordImageBarrier(vk, *cmdBuffer, *m_resolveImage,
						VK_IMAGE_ASPECT_COLOR_BIT,								// VkImageAspectFlags	aspect,
						VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,			// VkPipelineStageFlags srcStageMask,
						VK_PIPELINE_STAGE_TRANSFER_BIT,							// VkPipelineStageFlags dstStageMask,
						VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,					// VkAccessFlags		srcAccessMask,
						VK_ACCESS_TRANSFER_READ_BIT,							// VkAccessFlags		dstAccessMask,
						VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,					// VkImageLayout		oldLayout,
						VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);					// VkImageLayout		newLayout)

		recordCopyImageToBuffer(vk, *cmdBuffer, m_renderSize, *m_resolveImage, *m_colorBuffer);

		endCommandBuffer(vk, *cmdBuffer);
		submitCommandsAndWait(vk, device, m_context.getUniversalQueue(), *cmdBuffer);

		invalidateAlloc(vk, device, *m_colorBufferAlloc);
	}

	void createSampleDataBufferAndDescriptors (const VkDeviceSize bufferSize)
	{
		// Make sure the old descriptor set is destroyed before we destroy its pool
		m_descriptorSet	= Move<VkDescriptorSet>();

		const DeviceInterface&	vk			= m_context.getDeviceInterface();
		const VkDevice			device		= m_context.getDevice();
		Allocator&				allocator	= m_context.getDefaultAllocator();

		m_sampleDataBuffer		= makeBuffer(vk, device, bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
		m_sampleDataBufferAlloc	= bindBuffer(vk, device, allocator, *m_sampleDataBuffer, MemoryRequirement::HostVisible);

		m_descriptorSetLayout = DescriptorSetLayoutBuilder()
			.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT)
			.build(vk, device);

		m_descriptorPool = DescriptorPoolBuilder()
			.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
			.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);

		m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);

		const VkDescriptorBufferInfo bufferDescriptorInfo = makeDescriptorBufferInfo(*m_sampleDataBuffer, 0ull, bufferSize);
		DescriptorSetUpdateBuilder()
			.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferDescriptorInfo)
			.update(vk, device);

		SampleDataSSBO::renderSize		(m_sampleDataBufferAlloc->getHostPtr()) = m_renderSize;
		SampleDataSSBO::gridSize		(m_sampleDataBufferAlloc->getHostPtr()) = m_pixelGrid->size();
		SampleDataSSBO::samplesPerPixel	(m_sampleDataBufferAlloc->getHostPtr()) = m_pixelGrid->samplesPerPixel();

		flushAlloc(vk, device, *m_sampleDataBufferAlloc);
	}

	template<typename Vertex>
	void createVertexBuffer (const std::vector<Vertex>& vertices)
	{
		const DeviceInterface&  vk                  = m_context.getDeviceInterface();
		const VkDevice			device				= m_context.getDevice();
		Allocator&				allocator			= m_context.getDefaultAllocator();
		const VkDeviceSize      vertexBufferSize    = static_cast<VkDeviceSize>(vertices.size() * sizeof(vertices[0]));

		m_numVertices       = static_cast<deUint32>(vertices.size());
		m_vertexBuffer      = makeBuffer(vk, device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
		m_vertexBufferAlloc = bindBuffer(vk, device, allocator, *m_vertexBuffer, MemoryRequirement::HostVisible);

		deMemcpy(m_vertexBufferAlloc->getHostPtr(), dataOrNullPtr(vertices), static_cast<std::size_t>(vertexBufferSize));
		flushAlloc(vk, device, *m_vertexBufferAlloc);
	}

	const TestParams									m_params;
	const VkPhysicalDeviceSampleLocationsPropertiesEXT	m_sampleLocationsProperties;
	const VkFormat										m_colorFormat;
	UVec2												m_renderSize;
	MovePtr<MultisamplePixelGrid>						m_pixelGrid;
	deUint32											m_numVertices;
	Move<VkBuffer>										m_vertexBuffer;
	MovePtr<Allocation>									m_vertexBufferAlloc;
	Move<VkImage>										m_colorImage;
	Move<VkImageView>									m_colorImageView;
	MovePtr<Allocation>									m_colorImageAlloc;
	Move<VkImage>										m_resolveImage;
	Move<VkImageView>									m_resolveImageView;
	MovePtr<Allocation>									m_resolveImageAlloc;
	Move<VkBuffer>										m_colorBuffer;
	MovePtr<Allocation>									m_colorBufferAlloc;
	Move<VkBuffer>										m_sampleDataBuffer;
	MovePtr<Allocation>									m_sampleDataBufferAlloc;
	Move<VkDescriptorSetLayout>							m_descriptorSetLayout;
	Move<VkDescriptorPool>								m_descriptorPool;
	Move<VkDescriptorSet>								m_descriptorSet;

private:
	deUint32											m_currentGridNdx;
	std::vector<UVec2>									m_gridSizes;
};

//! Check that each custom sample has the expected position
class VerifyLocationTest : public TestBase
{
public:
	VerifyLocationTest (Context& context, const TestParams params) : TestBase(context, params) {}

	bool testPixelGrid (void)
	{
		// Create vertices
		{
			// For each sample location (in the whole framebuffer), create a sub-pixel triangle that contains it.
			// NDC viewport size is 2.0 in X and Y and NDC pixel width/height depends on the framebuffer resolution.
			const Vec2			pixelSize	= Vec2(2.0f) / m_renderSize.cast<float>();
			const Vec2			offset		= pixelSize / UVec2(1u << m_sampleLocationsProperties.sampleLocationSubPixelBits).cast<float>();
			std::vector<Vec4>	vertices;

			// Surround with a roughly centered triangle
			const float y1 = 0.5f  * offset.y();
			const float y2 = 0.35f * offset.y();
			const float x1 = 0.5f  * offset.x();

			const std::vector<Vec2>	locations = genFramebufferSampleLocations(*m_pixelGrid, m_pixelGrid->size(), m_renderSize);
			for (std::vector<Vec2>::const_iterator iter = locations.begin(); iter != locations.end(); ++iter)
			{
				vertices.push_back(Vec4(iter->x(),      iter->y() - y1, 0.0f, 1.0f));
				vertices.push_back(Vec4(iter->x() - x1, iter->y() + y2, 0.0f, 1.0f));
				vertices.push_back(Vec4(iter->x() + x1, iter->y() + y2, 0.0f, 1.0f));
			}

			createVertexBuffer(vertices);
		}

		createSampleDataBufferAndDescriptors(SampleDataSSBO::STATIC_SIZE);	// no per-sample data used

		drawSinglePass(VERTEX_INPUT_VEC4);	// sample locations are taken from the pixel grid

		// Verify

		const tcu::ConstPixelBufferAccess image (tcu::ConstPixelBufferAccess(mapVkFormat(m_colorFormat), tcu::IVec3(m_renderSize.x(), m_renderSize.y(), 1), m_colorBufferAlloc->getHostPtr()));

		return compareGreenImage(m_context.getTestContext().getLog(), "resolve0", "Resolved test image", image);
	}
};

//! Verify that vertex attributes are correctly interpolated at each custom sample location
class VerifyInterpolationTest : public TestBase
{
public:
	VerifyInterpolationTest (Context& context, const TestParams params) : TestBase(context, params)	{}

	bool testPixelGrid (void)
	{
		createVertexBuffer(genVerticesFullQuad());

		// Create sample data SSBO
		{
			const deUint32		numSamples		= m_pixelGrid->samplesPerPixel();
			const deUint32		numDataEntries	= numSamples * m_renderSize.x() * m_renderSize.y();
			const VkDeviceSize  bufferSize		= SampleDataSSBO::STATIC_SIZE + sizeof(Vec2) * numDataEntries;

			createSampleDataBufferAndDescriptors(bufferSize);

			Vec2* const				pSampleData	= SampleDataSSBO::sampleData<Vec2>(m_sampleDataBufferAlloc->getHostPtr());
			const std::vector<Vec2>	locations	= genFramebufferSampleLocations(*m_pixelGrid, m_pixelGrid->size(), m_renderSize);

			// Fill SSBO with interpolated values (here: from -1.0 to 1.0 across the render area in both x and y)
			DE_ASSERT(locations.size() == numDataEntries);
			std::copy(locations.begin(), locations.end(), pSampleData);

			flushAlloc(m_context.getDeviceInterface(), m_context.getDevice(), *m_sampleDataBufferAlloc);
		}

		drawSinglePass(VERTEX_INPUT_VEC4_VEC4);	// sample locations are taken from the pixel grid

		// Verify

		const tcu::ConstPixelBufferAccess image (tcu::ConstPixelBufferAccess(mapVkFormat(m_colorFormat), tcu::IVec3(m_renderSize.x(), m_renderSize.y(), 1), m_colorBufferAlloc->getHostPtr()));

		return compareGreenImage(m_context.getTestContext().getLog(), "resolve0", "Resolved test image", image);
	}
};

template<typename Test, typename ProgramsFunc>
void addCases (tcu::TestCaseGroup* group, const VkSampleCountFlagBits numSamples, const ProgramsFunc initPrograms)
{
	TestParams params;
	deMemset(&params, 0, sizeof(params));

	params.numSamples	= numSamples;
	params.options		= (TestOptionFlags)0;

	addInstanceTestCaseWithPrograms<Test>(group, getString(numSamples).c_str(), "", initPrograms, params);

	params.options = (TestOptionFlags)TEST_OPTION_DYNAMIC_STATE_BIT;
	addInstanceTestCaseWithPrograms<Test>(group, (getString(numSamples) + "_dynamic").c_str(), "", initPrograms, params);

	params.options = (TestOptionFlags)TEST_OPTION_CLOSELY_PACKED_BIT;
	addInstanceTestCaseWithPrograms<Test>(group, (getString(numSamples) + "_packed").c_str(), "", initPrograms, params);
}

} // VerifySamples

// Draw tests with at least two "passes" where sample locations may change.
// Test case is based on a combination of parameters defined below. Not all combinations are compatible.
namespace Draw
{

//! Options common to all test cases
enum TestOptionFlagBits
{
	TEST_OPTION_SAME_PATTERN_BIT				= 1u << 0,	//!< Use the same sample pattern for all operations
	TEST_OPTION_DYNAMIC_STATE_BIT				= 1u << 1,	//!< Use dynamic pipeline state to pass in sample locations
	TEST_OPTION_SECONDARY_COMMAND_BUFFER_BIT	= 1u << 2,	//!< Put drawing commands in a secondary buffer, including sample locations change (if dynamic)
	TEST_OPTION_GENERAL_LAYOUT_BIT				= 1u << 3,	//!< Transition the image to general layout at some point in rendering
	TEST_OPTION_WAIT_EVENTS_BIT					= 1u << 4,	//!< Use image memory barriers with vkCmdWaitEvents rather than vkCmdPipelineBarrier
};
typedef deUint32 TestOptionFlags;

//! Determines where draws/clears with custom samples occur in the test
enum TestDrawIn
{
	TEST_DRAW_IN_RENDER_PASSES = 0u,	//!< Each operation in a separate render pass
	TEST_DRAW_IN_SUBPASSES,				//!< Each operation in a separate subpass of the same render pass
	TEST_DRAW_IN_SAME_SUBPASS,			//!< Each operation in the same subpass
};

//! How a clear before the second pass will be done
enum TestClears
{
	TEST_CLEARS_NO_CLEAR = 0u,				//!< Don't clear
	TEST_CLEARS_LOAD_OP_CLEAR,				//!< Render pass attachment load clear
	TEST_CLEARS_CMD_CLEAR_ATTACHMENTS,		//!< vkCmdClearAttachments within a subpass
	TEST_CLEARS_CMD_CLEAR_IMAGE,			//!< vkCmdClear{Color|DepthStencil}Image outside a render pass
};

//! What type of image will be verified with custom samples
enum TestImageAspect
{
	TEST_IMAGE_ASPECT_COLOR = 0u,			//!< Color image
	TEST_IMAGE_ASPECT_DEPTH,				//!< Depth aspect of an image (can be mixed format)
	TEST_IMAGE_ASPECT_STENCIL,				//!< Stencil aspect of an image (can be mixed format)
};

struct TestParams
{
	VkSampleCountFlagBits	numSamples;
	TestOptionFlags			options;
	TestDrawIn				drawIn;
	TestClears				clears;
	TestImageAspect			imageAspect;
};

const char* getString (const TestImageAspect aspect)
{
	switch (aspect)
	{
		case TEST_IMAGE_ASPECT_COLOR:	return "color";
		case TEST_IMAGE_ASPECT_DEPTH:	return "depth";
		case TEST_IMAGE_ASPECT_STENCIL:	return "stencil";
	}
	DE_ASSERT(0);
	return DE_NULL;
}

const char* getString (const TestDrawIn drawIn)
{
	switch (drawIn)
	{
		case TEST_DRAW_IN_RENDER_PASSES:	return "separate_renderpass";
		case TEST_DRAW_IN_SUBPASSES:		return "separate_subpass";
		case TEST_DRAW_IN_SAME_SUBPASS:		return "same_subpass";
	}
	DE_ASSERT(0);
	return DE_NULL;
}

const char* getString (const TestClears clears)
{
	switch (clears)
	{
		case TEST_CLEARS_NO_CLEAR:				return "no_clear";
		case TEST_CLEARS_LOAD_OP_CLEAR:			return "load_op_clear";
		case TEST_CLEARS_CMD_CLEAR_ATTACHMENTS:	return "clear_attachments";
		case TEST_CLEARS_CMD_CLEAR_IMAGE:		return "clear_image";
	}
	DE_ASSERT(0);
	return DE_NULL;
}

std::string getTestOptionFlagsString (const deUint32 flags)
{
	std::ostringstream str;

	if ((flags & TEST_OPTION_SAME_PATTERN_BIT) != 0)				str << (str.tellp() > 0 ? "_" : "") << "same_pattern";
	if ((flags & TEST_OPTION_DYNAMIC_STATE_BIT) != 0)				str << (str.tellp() > 0 ? "_" : "") << "dynamic";
	if ((flags & TEST_OPTION_SECONDARY_COMMAND_BUFFER_BIT) != 0)	str << (str.tellp() > 0 ? "_" : "") << "secondary_cmd_buf";
	if ((flags & TEST_OPTION_GENERAL_LAYOUT_BIT) != 0)				str << (str.tellp() > 0 ? "_" : "") << "general_layout";
	if ((flags & TEST_OPTION_WAIT_EVENTS_BIT) != 0)					str << (str.tellp() > 0 ? "_" : "") << "event";

	return str.str();
}

void initPrograms (SourceCollections& programCollection, const TestParams)
{
	// Vertex shader
	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
			<< "\n"
			<< "layout(location = 0) in  vec4 in_position;\n"
			<< "layout(location = 1) in  vec4 in_color;\n"
			<< "layout(location = 0) out vec4 o_color;\n"
			<< "\n"
			<< "out gl_PerVertex {\n"
			<< "    vec4 gl_Position;\n"
			<< "};\n"
			<< "\n"
			<< "void main(void)\n"
			<< "{\n"
			<< "    gl_Position = in_position;\n"
			<< "    o_color     = in_color;\n"
			<< "\n"
			// We use instance index to draw the left shape (index = 0) or the right shape (index = 1).
			// Vertices are squished and moved to either half of the viewport.
			<< "    if (gl_InstanceIndex == 0)\n"
			<< "        gl_Position.x = 0.5 * (gl_Position.x - 1.0);\n"
			<< "    else if (gl_InstanceIndex == 1)\n"
			<< "        gl_Position.x = 0.5 * (gl_Position.x + 1.0);\n"
			<< "}\n";

		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
	}

	// Fragment shader
	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
			<< "\n"
			<< "layout(location = 0) in  vec4 in_color;\n"
			<< "layout(location = 0) out vec4 o_color;\n"
			<< "\n"
			<< "void main(void)\n"
			<< "{\n"
			<< "    o_color = in_color;\n"
			<< "}\n";

		programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
	}
}

//! Draw shapes using changing sample patterns. Add clears and other operations as necessary
class DrawTest : public TestInstance
{
	static const deUint32 NUM_PASSES = 2u;

public:
	DrawTest (Context& context, const TestParams params)
		: TestInstance					(context)
		, m_params						(params)
		, m_sampleLocationsProperties	(getSampleLocationsPropertiesEXT(context))
		, m_renderSize					(64, 32)
		, m_numVertices					(0)
		, m_colorFormat					(VK_FORMAT_R8G8B8A8_UNORM)
		, m_depthStencilFormat			(VK_FORMAT_UNDEFINED)
		, m_depthStencilAspect			(0)
	{
		requireExtensions(context);

		VkMultisamplePropertiesEXT multisampleProperties =
		{
			VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT,		// VkStructureType    sType;
			DE_NULL,											// void*              pNext;
			VkExtent2D(),										// VkExtent2D         maxSampleLocationGridSize;
		};

		// For this test always use the full pixel grid

		m_context.getInstanceInterface().getPhysicalDeviceMultisamplePropertiesEXT(m_context.getPhysicalDevice(), m_params.numSamples, &multisampleProperties);
		m_gridSize.x() = multisampleProperties.maxSampleLocationGridSize.width;
		m_gridSize.y() = multisampleProperties.maxSampleLocationGridSize.height;
	}

	tcu::TestStatus iterate (void)
	{
		// Requirements
		{
			const VkPhysicalDeviceLimits&	limits	= m_context.getDeviceProperties().limits;

			if ((limits.framebufferColorSampleCounts & m_params.numSamples) == 0u)
				TCU_THROW(NotSupportedError, "framebufferColorSampleCounts: sample count not supported");

			if ((m_sampleLocationsProperties.sampleLocationSampleCounts & m_params.numSamples) == 0u)
				TCU_THROW(NotSupportedError, "VkPhysicalDeviceSampleLocationsPropertiesEXT: sample count not supported");

			if (!(m_gridSize.x() >= 1 && m_gridSize.y() >= 1))
				return tcu::TestStatus::fail("maxSampleLocationGridSize is invalid");

			// Are we allowed to modify the sample pattern within the same subpass?
			if (m_params.drawIn == TEST_DRAW_IN_SAME_SUBPASS && !useSameSamplePattern() && !m_sampleLocationsProperties.variableSampleLocations)
				TCU_THROW(NotSupportedError, "VkPhysicalDeviceSampleLocationsPropertiesEXT: variableSampleLocations not supported");
		}

		// Images
		{
			const DeviceInterface&	vk					 = m_context.getDeviceInterface();
			const VkDevice			device				 = m_context.getDevice();
			Allocator&				allocator			 = m_context.getDefaultAllocator();
			const VkImageUsageFlags	colorImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;

			m_colorImage		= makeImage(vk, device, (VkImageCreateFlags)0, m_colorFormat, m_renderSize, m_params.numSamples, colorImageUsageFlags);
			m_colorImageAlloc	= bindImage(vk, device, allocator, *m_colorImage, MemoryRequirement::Any);
			m_colorImageView	= makeImageView(vk, device, *m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat,
												makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));

			m_resolveImage		= makeImage(vk, device, (VkImageCreateFlags)0, m_colorFormat, m_renderSize, VK_SAMPLE_COUNT_1_BIT, colorImageUsageFlags);
			m_resolveImageAlloc	= bindImage(vk, device, allocator, *m_resolveImage, MemoryRequirement::Any);
			m_resolveImageView	= makeImageView(vk, device, *m_resolveImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat,
												makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));

			const VkDeviceSize	colorBufferSize = m_renderSize.x() * m_renderSize.y() * tcu::getPixelSize(mapVkFormat(m_colorFormat));
			m_colorBuffer		= makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
			m_colorBufferAlloc	= bindBuffer(vk, device, allocator, *m_colorBuffer, MemoryRequirement::HostVisible);

			if (m_params.imageAspect != TEST_IMAGE_ASPECT_COLOR)
			{
				const VkImageUsageFlags depthStencilImageUsageFlags = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;

				m_depthStencilFormat	 = findSupportedDepthStencilFormat(m_context, useDepth(), useStencil());
				m_depthStencilAspect	 = (useDepth()   ? VK_IMAGE_ASPECT_DEPTH_BIT   : (VkImageAspectFlagBits)0) |
										   (useStencil() ? VK_IMAGE_ASPECT_STENCIL_BIT : (VkImageAspectFlagBits)0);
				m_depthStencilImage		 = makeImage(vk, device, VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT,
													 m_depthStencilFormat, m_renderSize, m_params.numSamples, depthStencilImageUsageFlags);
				m_depthStencilImageAlloc = bindImage(vk, device, allocator, *m_depthStencilImage, MemoryRequirement::Any);
				m_depthStencilImageView	 = makeImageView(vk, device, *m_depthStencilImage, VK_IMAGE_VIEW_TYPE_2D, m_depthStencilFormat,
														 makeImageSubresourceRange(m_depthStencilAspect, 0u, 1u, 0u, 1u));
			}
		}

		// Vertices
		{
			const DeviceInterface&	vk			= m_context.getDeviceInterface();
			const VkDevice			device		= m_context.getDevice();
			Allocator&				allocator	= m_context.getDefaultAllocator();

			std::vector<PositionColor> vertices;

			if (useDepth())
			{
				append(vertices, genVerticesShapes  (RGBA::black().toVec(), DEPTH_REFERENCE / 2.0f));	// mask above (z = 0.0 is nearest)
				append(vertices, genVerticesFullQuad(RGBA::white().toVec(), DEPTH_REFERENCE));			// fill below the mask, using the depth test
			}
			else if (useStencil())
			{
				append(vertices, genVerticesShapes  (RGBA::black().toVec(), DEPTH_REFERENCE));			// first mask
				append(vertices, genVerticesFullQuad(RGBA::white().toVec(), DEPTH_REFERENCE / 2.0f));	// then fill the whole area, using the stencil test
			}
			else
				vertices = genVerticesShapes();

			const VkDeviceSize vertexBufferSize = static_cast<VkDeviceSize>(vertices.size() * sizeof(vertices[0]));

			m_numVertices       = static_cast<deUint32>(vertices.size());
			m_vertexBuffer      = makeBuffer(vk, device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
			m_vertexBufferAlloc = bindBuffer(vk, device, allocator, *m_vertexBuffer, MemoryRequirement::HostVisible);

			deMemcpy(m_vertexBufferAlloc->getHostPtr(), dataOrNullPtr(vertices), static_cast<std::size_t>(vertexBufferSize));
			flushAlloc(vk, device, *m_vertexBufferAlloc);
		}

		// Multisample pixel grids - set up two sample patterns for two draw passes
		{
			const deUint32 numGrids = (useSameSamplePattern() ? 1u : NUM_PASSES);
			m_pixelGrids.reserve(numGrids);

			for (deUint32 passNdx = 0u; passNdx < numGrids; ++passNdx)
			{
				const deUint32 seed = 142u + 75u * passNdx;
				m_pixelGrids.push_back(MultisamplePixelGrid(m_gridSize, m_params.numSamples));
				fillSampleLocationsRandom(m_pixelGrids.back(), m_sampleLocationsProperties.sampleLocationSubPixelBits, seed);
				logPixelGrid (m_context.getTestContext().getLog(), m_sampleLocationsProperties, m_pixelGrids.back());
			}
		}

		// Some test cases will not clear the left hand image, so we can use it directly
		const bool isClearCase		= (m_params.clears != TEST_CLEARS_NO_CLEAR);
		const bool hasLeftSideImage = (!isClearCase ||
										(m_params.drawIn != TEST_DRAW_IN_RENDER_PASSES && m_params.clears != TEST_CLEARS_CMD_CLEAR_ATTACHMENTS));

		// Render second pass reference image with the first pattern
		tcu::TextureLevel refImagePattern0;
		if (!useSameSamplePattern() && !hasLeftSideImage)
		{
			const tcu::TextureFormat colorFormat = mapVkFormat(m_colorFormat);

			drawPatternChangeReference();

			refImagePattern0.setStorage(colorFormat, m_renderSize.x(), m_renderSize.y());
			tcu::copy(refImagePattern0.getAccess(), tcu::ConstPixelBufferAccess(colorFormat, tcu::IVec3(m_renderSize.x(), m_renderSize.y(), 1), m_colorBufferAlloc->getHostPtr()));
		}

		// Two-pass rendering

		switch (m_params.drawIn)
		{
			case TEST_DRAW_IN_RENDER_PASSES:	drawRenderPasses();	break;
			case TEST_DRAW_IN_SUBPASSES:		drawSubpasses();	break;
			case TEST_DRAW_IN_SAME_SUBPASS:		drawSameSubpass();	break;

			default:
				DE_ASSERT(0);
				break;
		}

		// Log the result

		const tcu::ConstPixelBufferAccess image (tcu::ConstPixelBufferAccess(mapVkFormat(m_colorFormat), tcu::IVec3(m_renderSize.x(), m_renderSize.y(), 1), m_colorBufferAlloc->getHostPtr()));

		m_context.getTestContext().getLog()
			<< tcu::TestLog::ImageSet("Result", "Final result")
			<< tcu::TestLog::Image("resolve0", "resolve0", image)
			<< tcu::TestLog::EndImageSet;

		// Verify result
		{
			DE_ASSERT((m_renderSize.x() % 2) == 0);
			DE_ASSERT((m_renderSize.y() % 2) == 0);

			// Count colors in each image half separately, each half may have its own background color
			const int  numBackgroundColors		= 1;
			const int  numExpectedColorsRight	= numBackgroundColors + static_cast<int>(m_params.numSamples);
			const int  numExpectedColorsLeft	= (isClearCase ? numBackgroundColors : numExpectedColorsRight);
			const int  numActualColorsLeft		= countUniqueColors(tcu::getSubregion(image, 0,					 0, m_renderSize.x()/2, m_renderSize.y()));
			const int  numActualColorsRight		= countUniqueColors(tcu::getSubregion(image, m_renderSize.x()/2, 0, m_renderSize.x()/2, m_renderSize.y()));

			if (numActualColorsLeft != numExpectedColorsLeft || numActualColorsRight != numExpectedColorsRight)
			{
				std::ostringstream msg;
				msg << "Expected " << numExpectedColorsLeft << " unique colors, but got " << numActualColorsLeft;

				if (numActualColorsLeft != numActualColorsRight)
					msg << " and " << numActualColorsRight;

				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << msg.str() << tcu::TestLog::EndMessage;

				return tcu::TestStatus::fail("Resolved image has incorrect pixels");
			}

			if (hasLeftSideImage)
			{
				// Compare the left and the right half
				const bool match = intThresholdCompare(tcu::getSubregion(image,	0,					0, m_renderSize.x()/2,	m_renderSize.y()),
													   tcu::getSubregion(image,	m_renderSize.x()/2, 0, m_renderSize.x()/2,	m_renderSize.y()),
													   UVec4(2u));
				if (useSameSamplePattern() && !match)
					return tcu::TestStatus::fail("Multisample pattern should be identical in both image halves");
				else if (!useSameSamplePattern() && match)
					return tcu::TestStatus::fail("Multisample pattern doesn't seem to change between left and right image halves");
			}
			else if (!useSameSamplePattern())
			{
				// Compare the right half with the previously rendered reference image -- patterns should be different
				bool match = intThresholdCompare(tcu::getSubregion(refImagePattern0.getAccess(),	m_renderSize.x()/2, 0, m_renderSize.x()/2,	m_renderSize.y()),
												 tcu::getSubregion(image,							m_renderSize.x()/2, 0, m_renderSize.x()/2,	m_renderSize.y()),
												 UVec4(2u));

				if (match)
					return tcu::TestStatus::fail("Multisample pattern doesn't seem to change between passes");
			}
		}

		return tcu::TestStatus::pass("Pass");
	}

protected:
	bool useDepth				(void) const { return m_params.imageAspect == TEST_IMAGE_ASPECT_DEPTH; }
	bool useStencil				(void) const { return m_params.imageAspect == TEST_IMAGE_ASPECT_STENCIL; }
	bool useSameSamplePattern	(void) const { return (m_params.options & TEST_OPTION_SAME_PATTERN_BIT) != 0u; }
	bool useDynamicState		(void) const { return (m_params.options & TEST_OPTION_DYNAMIC_STATE_BIT) != 0u; }
	bool useSecondaryCmdBuffer	(void) const { return (m_params.options & TEST_OPTION_SECONDARY_COMMAND_BUFFER_BIT) != 0u; }
	bool useGeneralLayout		(void) const { return (m_params.options & TEST_OPTION_GENERAL_LAYOUT_BIT) != 0u; }
	bool useWaitEvents			(void) const { return (m_params.options & TEST_OPTION_WAIT_EVENTS_BIT) != 0u; }

	//! Draw the second pass image, but with sample pattern from the first pass -- used to verify that the pattern is different
	void drawPatternChangeReference (void)
	{
		const DeviceInterface&			vk					= m_context.getDeviceInterface();
		const VkDevice					device				= m_context.getDevice();
		const VkViewport				viewport			= makeViewport(m_renderSize);
		const VkRect2D					renderArea			= makeRect2D(m_renderSize);
		const VkRect2D					scissor				= makeRect2D(m_renderSize);
		const Unique<VkShaderModule>	vertexModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
		const Unique<VkShaderModule>	fragmentModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
		const Unique<VkPipelineLayout>	pipelineLayout		(makePipelineLayout(vk, device));
		const VkSampleLocationsInfoEXT	sampleLocationsInfo	= makeSampleLocationsInfo(m_pixelGrids[0]);
		const VkClearValue				clearColor0			= (m_params.clears == TEST_CLEARS_NO_CLEAR ? makeClearValueColor(CLEAR_COLOR_0) : makeClearValueColor(CLEAR_COLOR_1));

		RenderTarget rt;

		rt.addAttachment(
			*m_colorImageView,											// VkImageView					imageView,
			(VkAttachmentDescriptionFlags)0,							// VkAttachmentDescriptionFlags	flags,
			m_colorFormat,												// VkFormat						format,
			m_params.numSamples,										// VkSampleCountFlagBits		numSamples,
			VK_ATTACHMENT_LOAD_OP_CLEAR,								// VkAttachmentLoadOp			loadOp,
			VK_ATTACHMENT_STORE_OP_STORE,								// VkAttachmentStoreOp			storeOp,
			VK_ATTACHMENT_LOAD_OP_DONT_CARE,							// VkAttachmentLoadOp			stencilLoadOp,
			VK_ATTACHMENT_STORE_OP_DONT_CARE,							// VkAttachmentStoreOp			stencilStoreOp,
			VK_IMAGE_LAYOUT_UNDEFINED,									// VkImageLayout				initialLayout,
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,					// VkImageLayout				finalLayout,
			clearColor0);												// VkClearValue					clearValue,

		rt.addAttachment(
			*m_resolveImageView,										// VkImageView					imageView,
			(VkAttachmentDescriptionFlags)0,							// VkAttachmentDescriptionFlags	flags,
			m_colorFormat,												// VkFormat						format,
			VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits		numSamples,
			VK_ATTACHMENT_LOAD_OP_DONT_CARE,							// VkAttachmentLoadOp			loadOp,
			VK_ATTACHMENT_STORE_OP_STORE,								// VkAttachmentStoreOp			storeOp,
			VK_ATTACHMENT_LOAD_OP_DONT_CARE,							// VkAttachmentLoadOp			stencilLoadOp,
			VK_ATTACHMENT_STORE_OP_DONT_CARE,							// VkAttachmentStoreOp			stencilStoreOp,
			VK_IMAGE_LAYOUT_UNDEFINED,									// VkImageLayout				initialLayout,
			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,						// VkImageLayout				finalLayout,
			VkClearValue());											// VkClearValue					clearValue,

		rt.addSubpassColorAttachmentWithResolve(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
												1u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);

		if (useDepth() || useStencil())
		{
			rt.addAttachment(
				*m_depthStencilImageView,										// VkImageView					imageView,
				(VkAttachmentDescriptionFlags)0,								// VkAttachmentDescriptionFlags	flags,
				m_depthStencilFormat,											// VkFormat						format,
				m_params.numSamples,											// VkSampleCountFlagBits		numSamples,
				VK_ATTACHMENT_LOAD_OP_CLEAR,									// VkAttachmentLoadOp			loadOp,
				VK_ATTACHMENT_STORE_OP_STORE,									// VkAttachmentStoreOp			storeOp,
				VK_ATTACHMENT_LOAD_OP_CLEAR,									// VkAttachmentLoadOp			stencilLoadOp,
				VK_ATTACHMENT_STORE_OP_STORE,									// VkAttachmentStoreOp			stencilStoreOp,
				VK_IMAGE_LAYOUT_UNDEFINED,										// VkImageLayout				initialLayout,
				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,				// VkImageLayout				finalLayout,
				makeClearValueDepthStencil(DEPTH_CLEAR, STENCIL_REFERENCE),		// VkClearValue					clearValue,
				&sampleLocationsInfo);											// VkSampleLocationsInfoEXT*	pInitialSampleLocations

			rt.addSubpassDepthStencilAttachment(2u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, &sampleLocationsInfo);
		}

		rt.bake(vk, device, m_renderSize);

		const Unique<VkPipeline> pipeline(makeGraphicsPipeline(
				vk, device, std::vector<VkDynamicState>(), *pipelineLayout, rt.getRenderPass(), *vertexModule, *fragmentModule,
				/*subpass index*/ 0u, viewport, scissor, m_params.numSamples, /*use sample locations*/ true, sampleLocationsInfo,
				useDepth(), useStencil(), VERTEX_INPUT_VEC4_VEC4, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, stencilOpStateDrawOnce()));

		const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_context.getUniversalQueueFamilyIndex()));
		const Unique<VkCommandBuffer>	cmdBuffer			(makeCommandBuffer(vk, device, *cmdPool));
		Move<VkCommandBuffer>			secondaryCmdBuffer;
		VkCommandBuffer					currentCmdBuffer	= *cmdBuffer;

		beginCommandBuffer(vk, currentCmdBuffer);
		rt.recordBeginRenderPass(vk, currentCmdBuffer, renderArea, (useSecondaryCmdBuffer() ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE));

		// For maximum consistency also use a secondary command buffer, if the two-pass path uses it
		if (useSecondaryCmdBuffer())
		{
			secondaryCmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
			currentCmdBuffer = *secondaryCmdBuffer;

			beginSecondaryCommandBuffer(vk, currentCmdBuffer, rt.getRenderPass(), /*subpass*/ 0u, rt.getFramebuffer());
		}

		vk.cmdBindVertexBuffers(currentCmdBuffer, /*first binding*/ 0u, /*num bindings*/ 1u, &m_vertexBuffer.get(), /*offsets*/ &ZERO);
		vk.cmdBindPipeline(currentCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

		// Draw the right shape only
		vk.cmdDraw(currentCmdBuffer, m_numVertices, /*instance count*/ 1u, /*first vertex*/ 0u, /*first instance*/ 1u);

		if (useSecondaryCmdBuffer())
		{
			endCommandBuffer(vk, currentCmdBuffer);
			currentCmdBuffer = *cmdBuffer;

			vk.cmdExecuteCommands(currentCmdBuffer, 1u, &secondaryCmdBuffer.get());
		}

		endRenderPass(vk, *cmdBuffer);

		// Resolve image -> host buffer
		recordImageBarrier(vk, *cmdBuffer, *m_resolveImage,
						VK_IMAGE_ASPECT_COLOR_BIT,								// VkImageAspectFlags	aspect,
						VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,			// VkPipelineStageFlags srcStageMask,
						VK_PIPELINE_STAGE_TRANSFER_BIT,							// VkPipelineStageFlags dstStageMask,
						VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,					// VkAccessFlags		srcAccessMask,
						VK_ACCESS_TRANSFER_READ_BIT,							// VkAccessFlags		dstAccessMask,
						VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,					// VkImageLayout		oldLayout,
						VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);					// VkImageLayout		newLayout)

		recordCopyImageToBuffer(vk, *cmdBuffer, m_renderSize, *m_resolveImage, *m_colorBuffer);

		endCommandBuffer(vk, *cmdBuffer);
		submitCommandsAndWait(vk, device, m_context.getUniversalQueue(), *cmdBuffer);

		invalidateAlloc(vk, device, *m_colorBufferAlloc);
	}

	//! Draw two shapes with distinct sample patterns, each in its own render pass
	void drawRenderPasses (void)
	{
		const DeviceInterface&			vk					= m_context.getDeviceInterface();
		const VkDevice					device				= m_context.getDevice();
		const VkViewport				viewport			= makeViewport(m_renderSize);
		const VkRect2D					renderArea			= makeRect2D(m_renderSize);
		const VkRect2D					scissor				= makeRect2D(m_renderSize);
		const Unique<VkShaderModule>	vertexModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
		const Unique<VkShaderModule>	fragmentModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
		const Unique<VkPipelineLayout>	pipelineLayout		(makePipelineLayout(vk, device));
		const VkClearValue				clearColor0			= makeClearValueColor(CLEAR_COLOR_0);
		const VkClearValue				clearColor1			= makeClearValueColor(CLEAR_COLOR_1);
		const VkClearValue				clearDepthStencil0	= makeClearValueDepthStencil(DEPTH_CLEAR, STENCIL_REFERENCE);
		const VkSampleLocationsInfoEXT	sampleLocationsInfo	[NUM_PASSES] =
		{
			makeSampleLocationsInfo(m_pixelGrids[0]),
			makeSampleLocationsInfo(m_pixelGrids[useSameSamplePattern() ? 0 : 1]),
		};
		const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_context.getUniversalQueueFamilyIndex()));
		Move<VkCommandBuffer>			cmdBuffer			[NUM_PASSES] =
		{
			makeCommandBuffer(vk, device, *cmdPool),
			makeCommandBuffer(vk, device, *cmdPool),
		};
		Move<VkCommandBuffer>			secondaryCmdBuffer	[NUM_PASSES];
		RenderTarget					rt					[NUM_PASSES];
		Move<VkPipeline>				pipeline			[NUM_PASSES];
		Move<VkEvent>					event				[2];	/*color and depth/stencil*/

		// Layouts expected by the second render pass
		const VkImageLayout	colorLayout1		= useGeneralLayout() && !(useDepth() || useStencil()) ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
		const VkImageLayout	depthStencilLayout1	= useGeneralLayout() && (useDepth() || useStencil())  ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

		// First render pass - no resolves
		{
			rt[0].addAttachment(
				*m_colorImageView,											// VkImageView					imageView,
				(VkAttachmentDescriptionFlags)0,							// VkAttachmentDescriptionFlags	flags,
				m_colorFormat,												// VkFormat						format,
				m_params.numSamples,										// VkSampleCountFlagBits		numSamples,
				VK_ATTACHMENT_LOAD_OP_CLEAR,								// VkAttachmentLoadOp			loadOp,
				VK_ATTACHMENT_STORE_OP_STORE,								// VkAttachmentStoreOp			storeOp,
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,							// VkAttachmentLoadOp			stencilLoadOp,
				VK_ATTACHMENT_STORE_OP_DONT_CARE,							// VkAttachmentStoreOp			stencilStoreOp,
				VK_IMAGE_LAYOUT_UNDEFINED,									// VkImageLayout				initialLayout,
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,					// VkImageLayout				finalLayout,
				clearColor0);												// VkClearValue					clearValue,

			rt[0].addSubpassColorAttachment(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);

			if (useDepth() || useStencil())
			{
				rt[0].addAttachment(
					*m_depthStencilImageView,										// VkImageView					imageView,
					(VkAttachmentDescriptionFlags)0,								// VkAttachmentDescriptionFlags	flags,
					m_depthStencilFormat,											// VkFormat						format,
					m_params.numSamples,											// VkSampleCountFlagBits		numSamples,
					VK_ATTACHMENT_LOAD_OP_CLEAR,									// VkAttachmentLoadOp			loadOp,
					VK_ATTACHMENT_STORE_OP_STORE,									// VkAttachmentStoreOp			storeOp,
					VK_ATTACHMENT_LOAD_OP_CLEAR,									// VkAttachmentLoadOp			stencilLoadOp,
					VK_ATTACHMENT_STORE_OP_STORE,									// VkAttachmentStoreOp			stencilStoreOp,
					VK_IMAGE_LAYOUT_UNDEFINED,										// VkImageLayout				initialLayout,
					VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,				// VkImageLayout				finalLayout,
					clearDepthStencil0,												// VkClearValue					clearValue,
					&sampleLocationsInfo[0]);										// VkSampleLocationsInfoEXT*	pInitialSampleLocations

				rt[0].addSubpassDepthStencilAttachment(1u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, &sampleLocationsInfo[0]);
			}

			rt[0].bake(vk, device, m_renderSize);
		}

		// Second render pass
		{
			const VkAttachmentLoadOp loadOp	= (m_params.clears == TEST_CLEARS_LOAD_OP_CLEAR ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD);

			rt[1].addAttachment(
				*m_colorImageView,											// VkImageView					imageView,
				(VkAttachmentDescriptionFlags)0,							// VkAttachmentDescriptionFlags	flags,
				m_colorFormat,												// VkFormat						format,
				m_params.numSamples,										// VkSampleCountFlagBits		numSamples,
				loadOp,														// VkAttachmentLoadOp			loadOp,
				VK_ATTACHMENT_STORE_OP_STORE,								// VkAttachmentStoreOp			storeOp,
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,							// VkAttachmentLoadOp			stencilLoadOp,
				VK_ATTACHMENT_STORE_OP_DONT_CARE,							// VkAttachmentStoreOp			stencilStoreOp,
				colorLayout1,												// VkImageLayout				initialLayout,
				colorLayout1,												// VkImageLayout				finalLayout,
				clearColor1);												// VkClearValue					clearValue,

			rt[1].addAttachment(
				*m_resolveImageView,										// VkImageView					imageView,
				(VkAttachmentDescriptionFlags)0,							// VkAttachmentDescriptionFlags	flags,
				m_colorFormat,												// VkFormat						format,
				VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits		numSamples,
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,							// VkAttachmentLoadOp			loadOp,
				VK_ATTACHMENT_STORE_OP_STORE,								// VkAttachmentStoreOp			storeOp,
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,							// VkAttachmentLoadOp			stencilLoadOp,
				VK_ATTACHMENT_STORE_OP_DONT_CARE,							// VkAttachmentStoreOp			stencilStoreOp,
				VK_IMAGE_LAYOUT_UNDEFINED,									// VkImageLayout				initialLayout,
				VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,						// VkImageLayout				finalLayout,
				VkClearValue());											// VkClearValue					clearValue,

			rt[1].addSubpassColorAttachmentWithResolve(0u, colorLayout1,
													   1u, colorLayout1);

			if (useDepth() || useStencil())
			{
				rt[1].addAttachment(
					*m_depthStencilImageView,										// VkImageView					imageView,
					(VkAttachmentDescriptionFlags)0,								// VkAttachmentDescriptionFlags	flags,
					m_depthStencilFormat,											// VkFormat						format,
					m_params.numSamples,											// VkSampleCountFlagBits		numSamples,
					loadOp,															// VkAttachmentLoadOp			loadOp,
					VK_ATTACHMENT_STORE_OP_STORE,									// VkAttachmentStoreOp			storeOp,
					loadOp,															// VkAttachmentLoadOp			stencilLoadOp,
					VK_ATTACHMENT_STORE_OP_STORE,									// VkAttachmentStoreOp			stencilStoreOp,
					depthStencilLayout1,											// VkImageLayout				initialLayout,
					depthStencilLayout1,											// VkImageLayout				finalLayout,
					clearDepthStencil0,												// VkClearValue					clearValue,
					&sampleLocationsInfo[1]);										// VkSampleLocationsInfoEXT*	pInitialSampleLocations

				rt[1].addSubpassDepthStencilAttachment(2u, depthStencilLayout1, &sampleLocationsInfo[1]);
			}

			rt[1].bake(vk, device, m_renderSize);
		}

		// Pipelines

		if (useDynamicState())
		{
			std::vector<VkDynamicState>	dynamicState;
			dynamicState.push_back(VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT);

			for (deUint32 passNdx = 0; passNdx < NUM_PASSES; ++passNdx)
			{
				pipeline[passNdx] = makeGraphicsPipeline(
					vk, device, dynamicState, *pipelineLayout, rt[passNdx].getRenderPass(), *vertexModule, *fragmentModule,
					/*subpass index*/ 0u, viewport, scissor, m_params.numSamples, /*use sample locations*/ true, makeEmptySampleLocationsInfo(),
					useDepth(), useStencil(), VERTEX_INPUT_VEC4_VEC4, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, stencilOpStateDrawOnce());
			}
		}
		else for (deUint32 passNdx = 0; passNdx < NUM_PASSES; ++passNdx)
		{
			pipeline[passNdx] = makeGraphicsPipeline(
				vk, device, std::vector<VkDynamicState>(), *pipelineLayout, rt[passNdx].getRenderPass(), *vertexModule, *fragmentModule,
				/*subpass index*/ 0u, viewport, scissor, m_params.numSamples, /*use sample locations*/ true, sampleLocationsInfo[passNdx],
				useDepth(), useStencil(), VERTEX_INPUT_VEC4_VEC4, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, stencilOpStateDrawOnce());
		}

		// Record secondary command buffers

		if (useSecondaryCmdBuffer())
		{
			secondaryCmdBuffer[0] = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
			secondaryCmdBuffer[1] = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);

			// First render pass contents
			beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer[0], rt[0].getRenderPass(), /*subpass*/ 0u, rt[0].getFramebuffer());
			recordFirstPassContents(*secondaryCmdBuffer[0], *pipeline[0], sampleLocationsInfo[0]);
			endCommandBuffer(vk, *secondaryCmdBuffer[0]);

			// Second render pass contents
			beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer[1], rt[1].getRenderPass(), /*subpass*/ 0u, rt[1].getFramebuffer());
			recordSecondPassContents(*secondaryCmdBuffer[1], *pipeline[1], sampleLocationsInfo[1], clearColor1, clearDepthStencil0, scissor);
			endCommandBuffer(vk, *secondaryCmdBuffer[1]);
		}

		// Record primary command buffers

		VkCommandBuffer currentCmdBuffer = *cmdBuffer[0];
		beginCommandBuffer(vk, currentCmdBuffer);

		// First render pass
		if (useSecondaryCmdBuffer())
		{
			rt[0].recordBeginRenderPass(vk, currentCmdBuffer, renderArea, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
			vk.cmdExecuteCommands(currentCmdBuffer, 1u, &secondaryCmdBuffer[0].get());
			endRenderPass(vk, currentCmdBuffer);
		}
		else
		{
			rt[0].recordBeginRenderPass(vk, currentCmdBuffer, renderArea, VK_SUBPASS_CONTENTS_INLINE);
			recordFirstPassContents(currentCmdBuffer, *pipeline[0], sampleLocationsInfo[0]);
			endRenderPass(vk, currentCmdBuffer);
		}

		endCommandBuffer(vk, currentCmdBuffer);

		// Record the second primary command buffer
		currentCmdBuffer = *cmdBuffer[1];
		beginCommandBuffer(vk, currentCmdBuffer);

		if (m_params.clears == TEST_CLEARS_CMD_CLEAR_IMAGE)
		{
			{
				const VkImageLayout finalLayout = (useWaitEvents() ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : colorLayout1);

				recordImageBarrier(vk, currentCmdBuffer, *m_colorImage,
									VK_IMAGE_ASPECT_COLOR_BIT,								// VkImageAspectFlags	aspect,
									VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,			// VkPipelineStageFlags srcStageMask,
									VK_PIPELINE_STAGE_TRANSFER_BIT,							// VkPipelineStageFlags dstStageMask,
									VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,					// VkAccessFlags		srcAccessMask,
									VK_ACCESS_TRANSFER_WRITE_BIT,							// VkAccessFlags		dstAccessMask,
									VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout		oldLayout,
									VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);					// VkImageLayout		newLayout)

				const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
				vk.cmdClearColorImage(currentCmdBuffer, *m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor1.color, 1u, &subresourceRange);

				recordImageBarrier(vk, currentCmdBuffer, *m_colorImage,
						VK_IMAGE_ASPECT_COLOR_BIT,											// VkImageAspectFlags	aspect,
						VK_PIPELINE_STAGE_TRANSFER_BIT,										// VkPipelineStageFlags srcStageMask,
						VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,						// VkPipelineStageFlags dstStageMask,
						VK_ACCESS_TRANSFER_WRITE_BIT,										// VkAccessFlags		srcAccessMask,
						(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
						 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT),								// VkAccessFlags		dstAccessMask,
						VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,								// VkImageLayout		oldLayout,
						finalLayout);														// VkImageLayout		newLayout)
			}

			if (useDepth() || useStencil())
			{
				const VkImageLayout finalLayout = (useWaitEvents() ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : depthStencilLayout1);

				recordImageBarrier(vk, currentCmdBuffer, *m_depthStencilImage,
								   getImageAspectFlags(m_depthStencilFormat),			// VkImageAspectFlags	aspect,
								   VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,			// VkPipelineStageFlags srcStageMask,
								   VK_PIPELINE_STAGE_TRANSFER_BIT,						// VkPipelineStageFlags dstStageMask,
								   VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags		srcAccessMask,
								   VK_ACCESS_TRANSFER_WRITE_BIT,						// VkAccessFlags		dstAccessMask,
								   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout		oldLayout,
								   VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout		newLayout)
								   &sampleLocationsInfo[0]);							// VkSampleLocationsInfoEXT

				const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(m_depthStencilAspect, 0u, 1u, 0u, 1u);
				vk.cmdClearDepthStencilImage(currentCmdBuffer, *m_depthStencilImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearDepthStencil0.depthStencil, 1u, &subresourceRange);

				recordImageBarrier(vk, currentCmdBuffer, *m_depthStencilImage,
								   getImageAspectFlags(m_depthStencilFormat),			// VkImageAspectFlags	aspect,
								   VK_PIPELINE_STAGE_TRANSFER_BIT,						// VkPipelineStageFlags srcStageMask,
								   VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,			// VkPipelineStageFlags dstStageMask,
								   VK_ACCESS_TRANSFER_WRITE_BIT,						// VkAccessFlags		srcAccessMask,
								   (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
									VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT),		// VkAccessFlags		dstAccessMask,
								   VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout		oldLayout,
								   finalLayout,											// VkImageLayout		newLayout)
								   &sampleLocationsInfo[0]);							// VkSampleLocationsInfoEXT
			}
		}
		else if (!useWaitEvents())
		{
			// Barrier between the render passes

			recordImageBarrier(vk, currentCmdBuffer, *m_colorImage,
							   VK_IMAGE_ASPECT_COLOR_BIT,								// VkImageAspectFlags	aspect,
							   VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,			// VkPipelineStageFlags srcStageMask,
							   VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,			// VkPipelineStageFlags dstStageMask,
							   VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,					// VkAccessFlags		srcAccessMask,
							   (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
								VK_ACCESS_COLOR_ATTACHMENT_READ_BIT),					// VkAccessFlags		dstAccessMask,
							   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout		oldLayout,
							   colorLayout1);											// VkImageLayout		newLayout)

			if (useDepth() || useStencil())
			{
				recordImageBarrier(vk, currentCmdBuffer, *m_depthStencilImage,
								   getImageAspectFlags(m_depthStencilFormat),			// VkImageAspectFlags	aspect,
								   VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,			// VkPipelineStageFlags srcStageMask,
								   VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,			// VkPipelineStageFlags dstStageMask,
								   VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags		srcAccessMask,
								   (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
									VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT),		// VkAccessFlags		dstAccessMask,
								   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout		oldLayout,
								   depthStencilLayout1);								// VkImageLayout		newLayout)
			}
		}

		if (useWaitEvents())
		{
			// Use events to sync both render passes
			event[0] = makeEvent(vk, device);
			vk.cmdSetEvent(currentCmdBuffer, *event[0], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);

			recordWaitEventWithImage(vk, currentCmdBuffer, *event[0], *m_colorImage,
									 VK_IMAGE_ASPECT_COLOR_BIT,								// VkImageAspectFlags		aspect,
									 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,			// VkPipelineStageFlags		srcStageMask,
									 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,			// VkPipelineStageFlags		dstStageMask,
									 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,					// VkAccessFlags			srcAccessMask,
									 (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
									  VK_ACCESS_COLOR_ATTACHMENT_READ_BIT),					// VkAccessFlags			dstAccessMask,
									 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout			oldLayout,
									 colorLayout1);											// VkImageLayout			newLayout,

			if (useDepth() || useStencil())
			{
				event[1] = makeEvent(vk, device);
				vk.cmdSetEvent(currentCmdBuffer, *event[1], VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);

				recordWaitEventWithImage(vk, currentCmdBuffer, *event[1], *m_depthStencilImage,
										 getImageAspectFlags(m_depthStencilFormat),			// VkImageAspectFlags		aspect,
										 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,			// VkPipelineStageFlags		srcStageMask,
										 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,		// VkPipelineStageFlags		dstStageMask,
										 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask,
										 (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
										  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT),		// VkAccessFlags			dstAccessMask,
										 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout			oldLayout,
										 depthStencilLayout1);								// VkImageLayout			newLayout,
			}
		}

		// Second render pass
		if (useSecondaryCmdBuffer())
		{
			rt[1].recordBeginRenderPass(vk, currentCmdBuffer, renderArea, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
			vk.cmdExecuteCommands(currentCmdBuffer, 1u, &secondaryCmdBuffer[1].get());
			endRenderPass(vk, currentCmdBuffer);
		}
		else
		{
			rt[1].recordBeginRenderPass(vk, currentCmdBuffer, renderArea, VK_SUBPASS_CONTENTS_INLINE);
			recordSecondPassContents(currentCmdBuffer, *pipeline[1], sampleLocationsInfo[1], clearColor1, clearDepthStencil0, scissor);
			endRenderPass(vk, currentCmdBuffer);
		}

		// Resolve image -> host buffer
		recordImageBarrier(vk, currentCmdBuffer, *m_resolveImage,
						VK_IMAGE_ASPECT_COLOR_BIT,								// VkImageAspectFlags	aspect,
						VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,			// VkPipelineStageFlags srcStageMask,
						VK_PIPELINE_STAGE_TRANSFER_BIT,							// VkPipelineStageFlags dstStageMask,
						VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,					// VkAccessFlags		srcAccessMask,
						VK_ACCESS_TRANSFER_READ_BIT,							// VkAccessFlags		dstAccessMask,
						VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,					// VkImageLayout		oldLayout,
						VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);					// VkImageLayout		newLayout)

		recordCopyImageToBuffer(vk, currentCmdBuffer, m_renderSize, *m_resolveImage, *m_colorBuffer);

		endCommandBuffer(vk, currentCmdBuffer);

		// Submit work
		{
			const Unique<VkFence>	fence	(createFence(vk, device));
			const VkCommandBuffer	buffers	[NUM_PASSES] =
			{
				*cmdBuffer[0],
				*cmdBuffer[1],
			};

			const VkSubmitInfo submitInfo =
			{
				VK_STRUCTURE_TYPE_SUBMIT_INFO,		// VkStructureType                sType;
				DE_NULL,							// const void*                    pNext;
				0u,									// uint32_t                       waitSemaphoreCount;
				DE_NULL,							// const VkSemaphore*             pWaitSemaphores;
				DE_NULL,							// const VkPipelineStageFlags*    pWaitDstStageMask;
				DE_LENGTH_OF_ARRAY(buffers),		// uint32_t                       commandBufferCount;
				buffers,							// const VkCommandBuffer*         pCommandBuffers;
				0u,									// uint32_t                       signalSemaphoreCount;
				DE_NULL,							// const VkSemaphore*             pSignalSemaphores;
			};
			VK_CHECK(vk.queueSubmit(m_context.getUniversalQueue(), 1u, &submitInfo, *fence));
			VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
		}

		invalidateAlloc(vk, device, *m_colorBufferAlloc);
	}

	void recordFirstPassContents (const VkCommandBuffer				cmdBuffer,
								  const VkPipeline					pipeline,
								  const VkSampleLocationsInfoEXT&	sampleLocationsInfo)
	{
		const DeviceInterface& vk = m_context.getDeviceInterface();

		vk.cmdBindVertexBuffers(cmdBuffer, /*first binding*/ 0u, /*num bindings*/ 1u, &m_vertexBuffer.get(), /*offsets*/ &ZERO);
		vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);

		if (useDynamicState())
			vk.cmdSetSampleLocationsEXT(cmdBuffer, &sampleLocationsInfo);

		if (m_params.clears == TEST_CLEARS_NO_CLEAR)
			vk.cmdDraw(cmdBuffer, m_numVertices, /*instance count*/ 1u, /*first vertex*/ 0u, /*first instance*/ 0u);			// left shape only
		else
			vk.cmdDraw(cmdBuffer, m_numVertices, /*instance count*/ NUM_PASSES, /*first vertex*/ 0u, /*first instance*/ 0u);	// both shapes
	}

	void recordSecondPassContents (const VkCommandBuffer			cmdBuffer,
								   const VkPipeline					pipeline,
								   const VkSampleLocationsInfoEXT&	sampleLocationsInfo,
								   const VkClearValue&				clearColor,
								   const VkClearValue&				clearDepthStencil,
								   const VkRect2D&					clearRect)
	{
		const DeviceInterface& vk = m_context.getDeviceInterface();

		vk.cmdBindVertexBuffers(cmdBuffer, /*first binding*/ 0u, /*num bindings*/ 1u, &m_vertexBuffer.get(), /*offsets*/ &ZERO);
		vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);

		if (m_params.clears == TEST_CLEARS_CMD_CLEAR_ATTACHMENTS)
			recordClearAttachments(vk, cmdBuffer, 0u, clearColor, m_depthStencilAspect, clearDepthStencil, clearRect);

		if (useDynamicState())
			vk.cmdSetSampleLocationsEXT(cmdBuffer, &sampleLocationsInfo);

		// Draw the right shape only
		vk.cmdDraw(cmdBuffer, m_numVertices, /*instance count*/ 1u, /*first vertex*/ 0u, /*first instance*/ 1u);
	}

	//! Draw two shapes in two subpasses of the same render pass
	void drawSubpasses (void)
	{
		DE_ASSERT(m_params.clears != TEST_CLEARS_CMD_CLEAR_IMAGE);			// not possible in a render pass
		DE_ASSERT(m_params.clears != TEST_CLEARS_LOAD_OP_CLEAR);			// can't specify a load op for a subpass
		DE_ASSERT((m_params.options & TEST_OPTION_WAIT_EVENTS_BIT) == 0);	// can't change layouts inside a subpass

		const DeviceInterface&			vk					= m_context.getDeviceInterface();
		const VkDevice					device				= m_context.getDevice();
		const VkViewport				viewport			= makeViewport(m_renderSize);
		const VkRect2D					renderArea			= makeRect2D(m_renderSize);
		const VkRect2D					scissor				= makeRect2D(m_renderSize);
		const Unique<VkShaderModule>	vertexModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
		const Unique<VkShaderModule>	fragmentModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
		const Unique<VkPipelineLayout>	pipelineLayout		(makePipelineLayout(vk, device));
		const VkClearValue				clearColor0			= makeClearValueColor(CLEAR_COLOR_0);
		const VkClearValue				clearColor1			= makeClearValueColor(CLEAR_COLOR_1);
		const VkClearValue				clearDepthStencil0	= makeClearValueDepthStencil(DEPTH_CLEAR, STENCIL_REFERENCE);
		const VkSampleLocationsInfoEXT	sampleLocationsInfo	[NUM_PASSES] =
		{
			makeSampleLocationsInfo(m_pixelGrids[0]),
			makeSampleLocationsInfo(m_pixelGrids[useSameSamplePattern() ? 0 : 1]),
		};
		const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_context.getUniversalQueueFamilyIndex()));
		const Unique<VkCommandBuffer>	cmdBuffer			(makeCommandBuffer(vk, device, *cmdPool));
		Move<VkCommandBuffer>			secondaryCmdBuffer	[NUM_PASSES];
		RenderTarget					rt;
		Move<VkPipeline>				pipeline			[NUM_PASSES];
		Move<VkEvent>					event;

		// Layouts used in the second subpass
		const VkImageLayout	colorLayout1		= useGeneralLayout() && !(useDepth() || useStencil()) ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
		const VkImageLayout	depthStencilLayout1	= useGeneralLayout() && (useDepth() || useStencil())  ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

		// Prepare the render pass
		{
			rt.addAttachment(
				*m_colorImageView,											// VkImageView					imageView,
				(VkAttachmentDescriptionFlags)0,							// VkAttachmentDescriptionFlags	flags,
				m_colorFormat,												// VkFormat						format,
				m_params.numSamples,										// VkSampleCountFlagBits		numSamples,
				VK_ATTACHMENT_LOAD_OP_CLEAR,								// VkAttachmentLoadOp			loadOp,
				VK_ATTACHMENT_STORE_OP_STORE,								// VkAttachmentStoreOp			storeOp,
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,							// VkAttachmentLoadOp			stencilLoadOp,
				VK_ATTACHMENT_STORE_OP_DONT_CARE,							// VkAttachmentStoreOp			stencilStoreOp,
				VK_IMAGE_LAYOUT_UNDEFINED,									// VkImageLayout				initialLayout,
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,					// VkImageLayout				finalLayout,
				clearColor0);												// VkClearValue					clearValue,

			rt.addAttachment(
				*m_resolveImageView,										// VkImageView					imageView,
				(VkAttachmentDescriptionFlags)0,							// VkAttachmentDescriptionFlags	flags,
				m_colorFormat,												// VkFormat						format,
				VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits		numSamples,
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,							// VkAttachmentLoadOp			loadOp,
				VK_ATTACHMENT_STORE_OP_STORE,								// VkAttachmentStoreOp			storeOp,
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,							// VkAttachmentLoadOp			stencilLoadOp,
				VK_ATTACHMENT_STORE_OP_DONT_CARE,							// VkAttachmentStoreOp			stencilStoreOp,
				VK_IMAGE_LAYOUT_UNDEFINED,									// VkImageLayout				initialLayout,
				VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,						// VkImageLayout				finalLayout,
				VkClearValue());											// VkClearValue					clearValue,

			// First subpass
			rt.addSubpassColorAttachment(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);

			if (useDepth() || useStencil())
			{
				rt.addAttachment(
					*m_depthStencilImageView,										// VkImageView					imageView,
					(VkAttachmentDescriptionFlags)0,								// VkAttachmentDescriptionFlags	flags,
					m_depthStencilFormat,											// VkFormat						format,
					m_params.numSamples,											// VkSampleCountFlagBits		numSamples,
					VK_ATTACHMENT_LOAD_OP_CLEAR,									// VkAttachmentLoadOp			loadOp,
					VK_ATTACHMENT_STORE_OP_STORE,									// VkAttachmentStoreOp			storeOp,
					VK_ATTACHMENT_LOAD_OP_CLEAR,									// VkAttachmentLoadOp			stencilLoadOp,
					VK_ATTACHMENT_STORE_OP_STORE,									// VkAttachmentStoreOp			stencilStoreOp,
					VK_IMAGE_LAYOUT_UNDEFINED,										// VkImageLayout				initialLayout,
					VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,				// VkImageLayout				finalLayout,
					clearDepthStencil0,												// VkClearValue					clearValue,
					&sampleLocationsInfo[0]);										// VkSampleLocationsInfoEXT*	pInitialSampleLocations

				rt.addSubpassDepthStencilAttachment(2u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, &sampleLocationsInfo[0]);
			}

			// Second subpass
			rt.nextSubpass();
			rt.addSubpassColorAttachmentWithResolve(0u, colorLayout1,
													1u, colorLayout1);

			if (useDepth() || useStencil())
				rt.addSubpassDepthStencilAttachment(2u, depthStencilLayout1, &sampleLocationsInfo[1]);

			rt.bake(vk, device, m_renderSize);
		}

		// Pipelines

		if (useDynamicState())
		{
			std::vector<VkDynamicState>	dynamicState;
			dynamicState.push_back(VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT);

			for (deUint32 passNdx = 0; passNdx < NUM_PASSES; ++passNdx)
			{
				pipeline[passNdx] = makeGraphicsPipeline(
					vk, device, dynamicState, *pipelineLayout, rt.getRenderPass(), *vertexModule, *fragmentModule,
					/*subpass*/ passNdx, viewport, scissor, m_params.numSamples, /*use sample locations*/ true, makeEmptySampleLocationsInfo(),
					useDepth(), useStencil(), VERTEX_INPUT_VEC4_VEC4, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, stencilOpStateDrawOnce());
			}
		}
		else for (deUint32 passNdx = 0; passNdx < NUM_PASSES; ++passNdx)
		{
			pipeline[passNdx] = makeGraphicsPipeline(
				vk, device, std::vector<VkDynamicState>(), *pipelineLayout, rt.getRenderPass(), *vertexModule, *fragmentModule,
				/*subpass*/ passNdx, viewport, scissor, m_params.numSamples, /*use sample locations*/ true, sampleLocationsInfo[passNdx],
				useDepth(), useStencil(), VERTEX_INPUT_VEC4_VEC4, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, stencilOpStateDrawOnce());
		}

		// Record secondary command buffers

		if (useSecondaryCmdBuffer())
		{
			secondaryCmdBuffer[0] = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
			secondaryCmdBuffer[1] = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);

			// First subpass contents
			beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer[0], rt.getRenderPass(), /*subpass*/ 0u, rt.getFramebuffer());
			recordFirstPassContents(*secondaryCmdBuffer[0], *pipeline[0], sampleLocationsInfo[0]);
			endCommandBuffer(vk, *secondaryCmdBuffer[0]);

			// Second subpass contents
			beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer[1], rt.getRenderPass(), /*subpass*/ 1u, rt.getFramebuffer());
			recordSecondPassContents(*secondaryCmdBuffer[1], *pipeline[1], sampleLocationsInfo[1], clearColor1, clearDepthStencil0, scissor);
			endCommandBuffer(vk, *secondaryCmdBuffer[1]);
		}

		// Record primary command buffer

		beginCommandBuffer(vk, *cmdBuffer);

		if (useSecondaryCmdBuffer())
		{
			rt.recordBeginRenderPass(vk, *cmdBuffer, renderArea, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
			vk.cmdExecuteCommands(*cmdBuffer, 1u, &secondaryCmdBuffer[0].get());

			vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
			vk.cmdExecuteCommands(*cmdBuffer, 1u, &secondaryCmdBuffer[1].get());
		}
		else
		{
			rt.recordBeginRenderPass(vk, *cmdBuffer, renderArea, VK_SUBPASS_CONTENTS_INLINE);
			recordFirstPassContents(*cmdBuffer, *pipeline[0], sampleLocationsInfo[0]);

			vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
			recordSecondPassContents(*cmdBuffer, *pipeline[1], sampleLocationsInfo[1], clearColor1, clearDepthStencil0, scissor);
		}

		endRenderPass(vk, *cmdBuffer);

		// Resolve image -> host buffer
		recordImageBarrier(vk, *cmdBuffer, *m_resolveImage,
						VK_IMAGE_ASPECT_COLOR_BIT,								// VkImageAspectFlags	aspect,
						VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,			// VkPipelineStageFlags srcStageMask,
						VK_PIPELINE_STAGE_TRANSFER_BIT,							// VkPipelineStageFlags dstStageMask,
						VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,					// VkAccessFlags		srcAccessMask,
						VK_ACCESS_TRANSFER_READ_BIT,							// VkAccessFlags		dstAccessMask,
						VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,					// VkImageLayout		oldLayout,
						VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);					// VkImageLayout		newLayout)

		recordCopyImageToBuffer(vk, *cmdBuffer, m_renderSize, *m_resolveImage, *m_colorBuffer);

		endCommandBuffer(vk, *cmdBuffer);

		submitCommandsAndWait(vk, device, m_context.getUniversalQueue(), *cmdBuffer);
		invalidateAlloc(vk, device, *m_colorBufferAlloc);
	}

	//! Draw two shapes within the same subpass of a renderpass
	void drawSameSubpass (void)
	{
		DE_ASSERT(m_params.clears != TEST_CLEARS_CMD_CLEAR_IMAGE);				// not possible in a render pass
		DE_ASSERT(m_params.clears != TEST_CLEARS_LOAD_OP_CLEAR);				// can't specify a load op for a subpass
		DE_ASSERT((m_params.options & TEST_OPTION_WAIT_EVENTS_BIT) == 0);		// can't change layouts inside a subpass
		DE_ASSERT((m_params.options & TEST_OPTION_GENERAL_LAYOUT_BIT) == 0);	// can't change layouts inside a subpass

		const DeviceInterface&			vk					= m_context.getDeviceInterface();
		const VkDevice					device				= m_context.getDevice();
		const VkViewport				viewport			= makeViewport(m_renderSize);
		const VkRect2D					renderArea			= makeRect2D(m_renderSize);
		const VkRect2D					scissor				= makeRect2D(m_renderSize);
		const Unique<VkShaderModule>	vertexModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
		const Unique<VkShaderModule>	fragmentModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
		const Unique<VkPipelineLayout>	pipelineLayout		(makePipelineLayout(vk, device));
		const VkClearValue				clearColor0			= makeClearValueColor(CLEAR_COLOR_0);
		const VkClearValue				clearColor1			= makeClearValueColor(CLEAR_COLOR_1);
		const VkClearValue				clearDepthStencil0	= makeClearValueDepthStencil(DEPTH_CLEAR, STENCIL_REFERENCE);
		const VkSampleLocationsInfoEXT	sampleLocationsInfo	[NUM_PASSES] =
		{
			makeSampleLocationsInfo(m_pixelGrids[0]),
			makeSampleLocationsInfo(m_pixelGrids[useSameSamplePattern() ? 0 : 1]),
		};
		const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_context.getUniversalQueueFamilyIndex()));
		const Unique<VkCommandBuffer>	cmdBuffer			(makeCommandBuffer(vk, device, *cmdPool));
		Move<VkCommandBuffer>			secondaryCmdBuffer;
		RenderTarget					rt;
		Move<VkPipeline>				pipeline			[NUM_PASSES];
		Move<VkEvent>					event;

		// Prepare the render pass
		{
			rt.addAttachment(
				*m_colorImageView,											// VkImageView					imageView,
				(VkAttachmentDescriptionFlags)0,							// VkAttachmentDescriptionFlags	flags,
				m_colorFormat,												// VkFormat						format,
				m_params.numSamples,										// VkSampleCountFlagBits		numSamples,
				VK_ATTACHMENT_LOAD_OP_CLEAR,								// VkAttachmentLoadOp			loadOp,
				VK_ATTACHMENT_STORE_OP_STORE,								// VkAttachmentStoreOp			storeOp,
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,							// VkAttachmentLoadOp			stencilLoadOp,
				VK_ATTACHMENT_STORE_OP_DONT_CARE,							// VkAttachmentStoreOp			stencilStoreOp,
				VK_IMAGE_LAYOUT_UNDEFINED,									// VkImageLayout				initialLayout,
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,					// VkImageLayout				finalLayout,
				clearColor0);												// VkClearValue					clearValue,

			rt.addAttachment(
				*m_resolveImageView,										// VkImageView					imageView,
				(VkAttachmentDescriptionFlags)0,							// VkAttachmentDescriptionFlags	flags,
				m_colorFormat,												// VkFormat						format,
				VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits		numSamples,
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,							// VkAttachmentLoadOp			loadOp,
				VK_ATTACHMENT_STORE_OP_STORE,								// VkAttachmentStoreOp			storeOp,
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,							// VkAttachmentLoadOp			stencilLoadOp,
				VK_ATTACHMENT_STORE_OP_DONT_CARE,							// VkAttachmentStoreOp			stencilStoreOp,
				VK_IMAGE_LAYOUT_UNDEFINED,									// VkImageLayout				initialLayout,
				VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,						// VkImageLayout				finalLayout,
				VkClearValue());											// VkClearValue					clearValue,

			rt.addSubpassColorAttachmentWithResolve(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
													1u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);

			if (useDepth() || useStencil())
			{
				rt.addAttachment(
					*m_depthStencilImageView,										// VkImageView					imageView,
					(VkAttachmentDescriptionFlags)0,								// VkAttachmentDescriptionFlags	flags,
					m_depthStencilFormat,											// VkFormat						format,
					m_params.numSamples,											// VkSampleCountFlagBits		numSamples,
					VK_ATTACHMENT_LOAD_OP_CLEAR,									// VkAttachmentLoadOp			loadOp,
					VK_ATTACHMENT_STORE_OP_STORE,									// VkAttachmentStoreOp			storeOp,
					VK_ATTACHMENT_LOAD_OP_CLEAR,									// VkAttachmentLoadOp			stencilLoadOp,
					VK_ATTACHMENT_STORE_OP_STORE,									// VkAttachmentStoreOp			stencilStoreOp,
					VK_IMAGE_LAYOUT_UNDEFINED,										// VkImageLayout				initialLayout,
					VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,				// VkImageLayout				finalLayout,
					clearDepthStencil0,												// VkClearValue					clearValue,
					&sampleLocationsInfo[0]);										// VkSampleLocationsInfoEXT*	pInitialSampleLocations

				rt.addSubpassDepthStencilAttachment(2u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, &sampleLocationsInfo[0]);
			}

			rt.bake(vk, device, m_renderSize);
		}

		// Pipelines

		if (useDynamicState())
		{
			std::vector<VkDynamicState>	dynamicState;
			dynamicState.push_back(VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT);

			for (deUint32 passNdx = 0; passNdx < NUM_PASSES; ++passNdx)
			{
				pipeline[passNdx] = makeGraphicsPipeline(
					vk, device, dynamicState, *pipelineLayout, rt.getRenderPass(), *vertexModule, *fragmentModule,
					/*subpass*/ 0u, viewport, scissor, m_params.numSamples, /*use sample locations*/ true, makeEmptySampleLocationsInfo(),
					useDepth(), useStencil(), VERTEX_INPUT_VEC4_VEC4, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, stencilOpStateDrawOnce());
			}
		}
		else for (deUint32 passNdx = 0; passNdx < NUM_PASSES; ++passNdx)
		{
			pipeline[passNdx] = makeGraphicsPipeline(
				vk, device, std::vector<VkDynamicState>(), *pipelineLayout, rt.getRenderPass(), *vertexModule, *fragmentModule,
				/*subpass*/ 0u, viewport, scissor, m_params.numSamples, /*use sample locations*/ true, sampleLocationsInfo[passNdx],
				useDepth(), useStencil(), VERTEX_INPUT_VEC4_VEC4, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, stencilOpStateDrawOnce());
		}

		// Record secondary command buffers

		if (useSecondaryCmdBuffer())
		{
			secondaryCmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);

			beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer, rt.getRenderPass(), /*subpass*/ 0u, rt.getFramebuffer());
			recordFirstPassContents(*secondaryCmdBuffer, *pipeline[0], sampleLocationsInfo[0]);
			recordSecondPassContents(*secondaryCmdBuffer, *pipeline[1], sampleLocationsInfo[1], clearColor1, clearDepthStencil0, scissor);
			endCommandBuffer(vk, *secondaryCmdBuffer);
		}

		// Record primary command buffer

		beginCommandBuffer(vk, *cmdBuffer);

		if (useSecondaryCmdBuffer())
		{
			rt.recordBeginRenderPass(vk, *cmdBuffer, renderArea, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
			vk.cmdExecuteCommands(*cmdBuffer, 1u, &secondaryCmdBuffer.get());
		}
		else
		{
			rt.recordBeginRenderPass(vk, *cmdBuffer, renderArea, VK_SUBPASS_CONTENTS_INLINE);
			recordFirstPassContents(*cmdBuffer, *pipeline[0], sampleLocationsInfo[0]);
			recordSecondPassContents(*cmdBuffer, *pipeline[1], sampleLocationsInfo[1], clearColor1, clearDepthStencil0, scissor);
		}

		endRenderPass(vk, *cmdBuffer);

		// Resolve image -> host buffer
		recordImageBarrier(vk, *cmdBuffer, *m_resolveImage,
						VK_IMAGE_ASPECT_COLOR_BIT,								// VkImageAspectFlags	aspect,
						VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,			// VkPipelineStageFlags srcStageMask,
						VK_PIPELINE_STAGE_TRANSFER_BIT,							// VkPipelineStageFlags dstStageMask,
						VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,					// VkAccessFlags		srcAccessMask,
						VK_ACCESS_TRANSFER_READ_BIT,							// VkAccessFlags		dstAccessMask,
						VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,					// VkImageLayout		oldLayout,
						VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);					// VkImageLayout		newLayout)

		recordCopyImageToBuffer(vk, *cmdBuffer, m_renderSize, *m_resolveImage, *m_colorBuffer);

		endCommandBuffer(vk, *cmdBuffer);

		submitCommandsAndWait(vk, device, m_context.getUniversalQueue(), *cmdBuffer);
		invalidateAlloc(vk, device, *m_colorBufferAlloc);
	}

	const TestParams									m_params;
	const VkPhysicalDeviceSampleLocationsPropertiesEXT	m_sampleLocationsProperties;
	const UVec2											m_renderSize;
	UVec2												m_gridSize;
	std::vector<MultisamplePixelGrid>					m_pixelGrids;
	deUint32											m_numVertices;
	Move<VkBuffer>										m_vertexBuffer;
	MovePtr<Allocation>									m_vertexBufferAlloc;
	const VkFormat										m_colorFormat;
	Move<VkImage>										m_colorImage;
	Move<VkImageView>									m_colorImageView;
	MovePtr<Allocation>									m_colorImageAlloc;
	VkFormat											m_depthStencilFormat;
	VkImageAspectFlags									m_depthStencilAspect;
	Move<VkImage>										m_depthStencilImage;
	Move<VkImageView>									m_depthStencilImageView;
	MovePtr<Allocation>									m_depthStencilImageAlloc;
	Move<VkImage>										m_resolveImage;
	Move<VkImageView>									m_resolveImageView;
	MovePtr<Allocation>									m_resolveImageAlloc;
	Move<VkBuffer>										m_colorBuffer;
	MovePtr<Allocation>									m_colorBufferAlloc;
};

} // Draw

void createTestsInGroup (tcu::TestCaseGroup* rootGroup)
{
	// Queries
	{
		MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(rootGroup->getTestContext(), "query", ""));

		addFunctionCase(group.get(), "sample_locations_properties", "", testQuerySampleLocationProperties);
		addFunctionCase(group.get(), "multisample_properties",		"", testQueryMultisampleProperties);

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

	const VkSampleCountFlagBits	sampleCountRange[] =
	{
		VK_SAMPLE_COUNT_2_BIT,
		VK_SAMPLE_COUNT_4_BIT,
		VK_SAMPLE_COUNT_8_BIT,
		VK_SAMPLE_COUNT_16_BIT,
		// There are no implementations that support 32 or 64 programmable samples currently
	};

	// Verify custom sample locations and interpolation
	{
		using namespace VerifySamples;

		MovePtr<tcu::TestCaseGroup> groupLocation		(new tcu::TestCaseGroup(rootGroup->getTestContext(), "verify_location", ""));
		MovePtr<tcu::TestCaseGroup> groupInterpolation	(new tcu::TestCaseGroup(rootGroup->getTestContext(), "verify_interpolation", ""));

		for (const VkSampleCountFlagBits* pLoopNumSamples = sampleCountRange; pLoopNumSamples < DE_ARRAY_END(sampleCountRange); ++pLoopNumSamples)
		{
			addCases<VerifyLocationTest>	 (groupLocation.get(),		*pLoopNumSamples, addProgramsVerifyLocationGeometry);
			addCases<VerifyInterpolationTest>(groupInterpolation.get(),	*pLoopNumSamples, addProgramsVerifyInterpolation);
		}

		rootGroup->addChild(groupLocation.release());
		rootGroup->addChild(groupInterpolation.release());
	}

	// Draw with custom samples and various options
	{
		using namespace Draw;

		const deUint32 optionSets[] =
		{
			TEST_OPTION_SAME_PATTERN_BIT,
			0u,
			TEST_OPTION_DYNAMIC_STATE_BIT,
			TEST_OPTION_SECONDARY_COMMAND_BUFFER_BIT,
			TEST_OPTION_DYNAMIC_STATE_BIT | TEST_OPTION_SECONDARY_COMMAND_BUFFER_BIT,
			TEST_OPTION_GENERAL_LAYOUT_BIT,
			TEST_OPTION_GENERAL_LAYOUT_BIT | TEST_OPTION_DYNAMIC_STATE_BIT,
			TEST_OPTION_GENERAL_LAYOUT_BIT | TEST_OPTION_SECONDARY_COMMAND_BUFFER_BIT,
			TEST_OPTION_GENERAL_LAYOUT_BIT | TEST_OPTION_DYNAMIC_STATE_BIT | TEST_OPTION_SECONDARY_COMMAND_BUFFER_BIT,
			TEST_OPTION_WAIT_EVENTS_BIT,
			TEST_OPTION_WAIT_EVENTS_BIT | TEST_OPTION_GENERAL_LAYOUT_BIT,
			TEST_OPTION_WAIT_EVENTS_BIT | TEST_OPTION_GENERAL_LAYOUT_BIT | TEST_OPTION_SECONDARY_COMMAND_BUFFER_BIT,
		};

		const struct
		{
			TestDrawIn	drawIn;
			TestClears	clears;
		} drawClearSets[] =
		{
			{ TEST_DRAW_IN_RENDER_PASSES,	TEST_CLEARS_NO_CLEAR				},
			{ TEST_DRAW_IN_RENDER_PASSES,	TEST_CLEARS_LOAD_OP_CLEAR			},
			{ TEST_DRAW_IN_RENDER_PASSES,	TEST_CLEARS_CMD_CLEAR_ATTACHMENTS	},
			{ TEST_DRAW_IN_RENDER_PASSES,	TEST_CLEARS_CMD_CLEAR_IMAGE			},
			{ TEST_DRAW_IN_SUBPASSES,		TEST_CLEARS_NO_CLEAR				},
			{ TEST_DRAW_IN_SUBPASSES,		TEST_CLEARS_CMD_CLEAR_ATTACHMENTS	},
			{ TEST_DRAW_IN_SAME_SUBPASS,	TEST_CLEARS_NO_CLEAR				},
			{ TEST_DRAW_IN_SAME_SUBPASS,	TEST_CLEARS_CMD_CLEAR_ATTACHMENTS	},
		};

		const TestImageAspect aspectRange[] =
		{
			TEST_IMAGE_ASPECT_COLOR,
			TEST_IMAGE_ASPECT_DEPTH,
			TEST_IMAGE_ASPECT_STENCIL,
		};

		MovePtr<tcu::TestCaseGroup> drawGroup (new tcu::TestCaseGroup(rootGroup->getTestContext(), "draw", ""));
		for (const TestImageAspect* pLoopImageAspect = aspectRange; pLoopImageAspect != DE_ARRAY_END(aspectRange); ++pLoopImageAspect)
		{
			MovePtr<tcu::TestCaseGroup> aspectGroup (new tcu::TestCaseGroup(drawGroup->getTestContext(), getString(*pLoopImageAspect), ""));
			for (const VkSampleCountFlagBits* pLoopNumSamples = sampleCountRange; pLoopNumSamples < DE_ARRAY_END(sampleCountRange); ++pLoopNumSamples)
			{
				MovePtr<tcu::TestCaseGroup> samplesGroup (new tcu::TestCaseGroup(aspectGroup->getTestContext(), getString(*pLoopNumSamples).c_str(), ""));

				for (deUint32		 loopDrawSetNdx = 0u;		  loopDrawSetNdx <  DE_LENGTH_OF_ARRAY(drawClearSets); ++loopDrawSetNdx)
				for (const deUint32* pLoopOptions	= optionSets; pLoopOptions	 != DE_ARRAY_END(optionSets);		   ++pLoopOptions)
				{
					const TestParams params =
					{
						*pLoopNumSamples,							// VkSampleCountFlagBits	numSamples;
						*pLoopOptions,								// TestOptionFlags			options;
						drawClearSets[loopDrawSetNdx].drawIn,		// TestDrawIn				drawIn;
						drawClearSets[loopDrawSetNdx].clears,		// TestClears				clears;
						*pLoopImageAspect,							// TestImageAspect			imageAspect;
					};

					// Filter out incompatible parameter combinations
					if (params.imageAspect != TEST_IMAGE_ASPECT_COLOR)
					{
						// If the sample pattern is changed, the D/S image must be cleared or the result is undefined
						if (((params.options & TEST_OPTION_SAME_PATTERN_BIT) == 0u) && (params.clears == TEST_CLEARS_NO_CLEAR))
							continue;
					}

					// We are using events to change image layout and this is only allowed outside a render pass
					if (((params.options & TEST_OPTION_WAIT_EVENTS_BIT) != 0u) && (params.drawIn != TEST_DRAW_IN_RENDER_PASSES))
						continue;

					// Can't change image layout inside a subpass
					if (((params.options & TEST_OPTION_GENERAL_LAYOUT_BIT) != 0u) && (params.drawIn == TEST_DRAW_IN_SAME_SUBPASS))
						continue;

					std::ostringstream caseName;
					caseName << getString(params.drawIn) << "_"
							 << getString(params.clears) << (params.options != 0 ? "_" : "")
							 << getTestOptionFlagsString(params.options);

					addInstanceTestCaseWithPrograms<DrawTest>(samplesGroup.get(), caseName.str().c_str(), "", initPrograms, params);
				}
				aspectGroup->addChild(samplesGroup.release());
			}
			drawGroup->addChild(aspectGroup.release());
		}
		rootGroup->addChild(drawGroup.release());
	}
}

} // anonymous ns

tcu::TestCaseGroup* createMultisampleSampleLocationsExtTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "sample_locations_ext", "Test a graphics pipeline with user-defined sample locations", createTestsInGroup);
}

} // pipeline
} // vkt
