/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * 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 Vulkan Multi View Render Tests
 *//*--------------------------------------------------------------------*/

#include "vktMultiViewRenderTests.hpp"
#include "vktMultiViewRenderUtil.hpp"
#include "vktMultiViewRenderPassUtil.hpp"

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

#include "tcuTestLog.hpp"
#include "tcuResource.hpp"
#include "tcuImageCompare.hpp"
#include "tcuCommandLine.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuRGBA.hpp"

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

namespace vkt
{
namespace MultiView
{
namespace
{

using namespace vk;
using de::MovePtr;
using de::UniquePtr;
using std::vector;
using std::map;
using std::string;

enum TestType
{
	TEST_TYPE_VIEW_MASK,
	TEST_TYPE_VIEW_INDEX_IN_VERTEX,
	TEST_TYPE_VIEW_INDEX_IN_FRAGMENT,
	TEST_TYPE_VIEW_INDEX_IN_GEOMETRY,
	TEST_TYPE_VIEW_INDEX_IN_TESELLATION,
	TEST_TYPE_INPUT_ATTACHMENTS,
	TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY,
	TEST_TYPE_INSTANCED_RENDERING,
	TEST_TYPE_INPUT_RATE_INSTANCE,
	TEST_TYPE_DRAW_INDIRECT,
	TEST_TYPE_DRAW_INDIRECT_INDEXED,
	TEST_TYPE_DRAW_INDEXED,
	TEST_TYPE_CLEAR_ATTACHMENTS,
	TEST_TYPE_SECONDARY_CMD_BUFFER,
	TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY,
	TEST_TYPE_POINT_SIZE,
	TEST_TYPE_MULTISAMPLE,
	TEST_TYPE_QUERIES,
	TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR,
	TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR,
	TEST_TYPE_DEPTH,
	TEST_TYPE_STENCIL,
	TEST_TYPE_LAST
};

enum RenderPassType
{
	RENDERPASS_TYPE_LEGACY = 0,
	RENDERPASS_TYPE_RENDERPASS2,
};

struct TestParameters
{
	VkExtent3D				extent;
	vector<deUint32>		viewMasks;
	TestType				viewIndex;
	VkSampleCountFlagBits	samples;
	VkFormat				colorFormat;
	RenderPassType			renderPassType;
};

const int	TEST_POINT_SIZE_SMALL	= 2;
const int	TEST_POINT_SIZE_WIDE	= 4;

vk::Move<vk::VkRenderPass> makeRenderPass (const DeviceInterface&		vk,
										   const VkDevice				device,
										   const VkFormat				colorFormat,
										   const vector<deUint32>&		viewMasks,
										   RenderPassType				renderPassType,
										   const VkSampleCountFlagBits	samples = VK_SAMPLE_COUNT_1_BIT,
										   const VkAttachmentLoadOp		colorLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
										   const VkFormat				dsFormat = VK_FORMAT_UNDEFINED)
{
	switch (renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:
			return MultiView::makeRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, device, colorFormat, viewMasks, samples, colorLoadOp, dsFormat);
		case RENDERPASS_TYPE_RENDERPASS2:
			return MultiView::makeRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, device, colorFormat, viewMasks, samples, colorLoadOp, dsFormat);
		default:
			TCU_THROW(InternalError, "Impossible");
	}
}

vk::Move<vk::VkRenderPass> makeRenderPassWithAttachments (const DeviceInterface&	vk,
														  const VkDevice			device,
														  const VkFormat			colorFormat,
														  const vector<deUint32>&	viewMasks,
														  RenderPassType			renderPassType)
{
	switch (renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:
			return MultiView::makeRenderPassWithAttachments<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, device, colorFormat, viewMasks, renderPassType == RENDERPASS_TYPE_RENDERPASS2);
		case RENDERPASS_TYPE_RENDERPASS2:
			return MultiView::makeRenderPassWithAttachments<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, device, colorFormat, viewMasks, renderPassType == RENDERPASS_TYPE_RENDERPASS2);
		default:
			TCU_THROW(InternalError, "Impossible");
	}
}

vk::Move<vk::VkRenderPass> makeRenderPassWithDepth (const DeviceInterface&	vk,
													const VkDevice			device,
													const VkFormat			colorFormat,
													const vector<deUint32>&	viewMasks,
													const					VkFormat dsFormat,
													RenderPassType			renderPassType)
{
	switch (renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:
			return MultiView::makeRenderPassWithDepth<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, device, colorFormat, viewMasks, dsFormat);
		case RENDERPASS_TYPE_RENDERPASS2:
			return MultiView::makeRenderPassWithDepth<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, device, colorFormat, viewMasks, dsFormat);
		default:
			TCU_THROW(InternalError, "Impossible");
	}
}

template<typename RenderpassSubpass>
void cmdBeginRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassContents contents)
{
	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, contents);

	RenderpassSubpass::cmdBeginRenderPass(vkd, cmdBuffer, pRenderPassBegin, &subpassBeginInfo);
}

void cmdBeginRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassContents contents, RenderPassType renderPassType)
{
	switch (renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:		cmdBeginRenderPass<RenderpassSubpass1>(vkd, cmdBuffer, pRenderPassBegin, contents);	break;
		case RENDERPASS_TYPE_RENDERPASS2:	cmdBeginRenderPass<RenderpassSubpass2>(vkd, cmdBuffer, pRenderPassBegin, contents);	break;
		default:							TCU_THROW(InternalError, "Impossible");
	}
}

template<typename RenderpassSubpass>
void cmdNextSubpass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkSubpassContents contents)
{
	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, contents);
	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo		(DE_NULL);

	RenderpassSubpass::cmdNextSubpass(vkd, cmdBuffer, &subpassBeginInfo, &subpassEndInfo);
}

void cmdNextSubpass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkSubpassContents contents, RenderPassType renderPassType)
{
	switch (renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:		cmdNextSubpass<RenderpassSubpass1>(vkd, cmdBuffer, contents);	break;
		case RENDERPASS_TYPE_RENDERPASS2:	cmdNextSubpass<RenderpassSubpass2>(vkd, cmdBuffer, contents);	break;
		default:							TCU_THROW(InternalError, "Impossible");
	}
}

template<typename RenderpassSubpass>
void cmdEndRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer)
{
	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo	(DE_NULL);

	RenderpassSubpass::cmdEndRenderPass(vkd, cmdBuffer, &subpassEndInfo);
}

void cmdEndRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, RenderPassType renderPassType)
{
	switch (renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:		cmdEndRenderPass<RenderpassSubpass1>(vkd, cmdBuffer);	break;
		case RENDERPASS_TYPE_RENDERPASS2:	cmdEndRenderPass<RenderpassSubpass2>(vkd, cmdBuffer);	break;
		default:							TCU_THROW(InternalError, "Impossible");
	}
}

class ImageAttachment
{
public:
				ImageAttachment	(VkDevice logicalDevice, DeviceInterface& device, Allocator& allocator, const VkExtent3D extent, VkFormat colorFormat, const VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT);
	VkImageView	getImageView	(void) const
	{
		return *m_imageView;
	}
	VkImage		getImage		(void) const
	{
		return *m_image;
	}
private:
	Move<VkImage>			m_image;
	MovePtr<Allocation>		m_allocationImage;
	Move<VkImageView>		m_imageView;
};

ImageAttachment::ImageAttachment (VkDevice logicalDevice, DeviceInterface& device, Allocator& allocator, const VkExtent3D extent, VkFormat colorFormat, const VkSampleCountFlagBits samples)
{
	const bool						depthStencilFormat			= isDepthStencilFormat(colorFormat);
	const VkImageAspectFlags		aspectFlags					= depthStencilFormat ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
	const VkImageSubresourceRange	colorImageSubresourceRange	= makeImageSubresourceRange(aspectFlags, 0u, 1u, 0u, extent.depth);
	const VkImageUsageFlags			imageUsageFlagsDependent	= depthStencilFormat ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
	const VkImageUsageFlags			imageUsageFlags				= imageUsageFlagsDependent | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
	const VkImageCreateInfo			colorAttachmentImageInfo	= makeImageCreateInfo(VK_IMAGE_TYPE_2D, extent, colorFormat, imageUsageFlags, samples);

	m_image							= createImage(device, logicalDevice, &colorAttachmentImageInfo);
	m_allocationImage				= allocator.allocate(getImageMemoryRequirements(device, logicalDevice, *m_image), MemoryRequirement::Any);
	VK_CHECK(device.bindImageMemory(logicalDevice, *m_image, m_allocationImage->getMemory(), m_allocationImage->getOffset()));
	m_imageView						= makeImageView(device, logicalDevice, *m_image, VK_IMAGE_VIEW_TYPE_2D_ARRAY, colorFormat, colorImageSubresourceRange);
}

class MultiViewRenderTestInstance : public TestInstance
{
public:
									MultiViewRenderTestInstance	(Context& context, const TestParameters& parameters);
protected:
	typedef de::SharedPtr<Unique<VkPipeline> >		PipelineSp;
	typedef de::SharedPtr<Unique<VkShaderModule> >	ShaderModuleSP;

	virtual tcu::TestStatus			iterate					(void);
	virtual void					beforeDraw				(void);
	virtual void					afterDraw				(void);
	virtual void					draw					(const deUint32			subpassCount,
															 VkRenderPass			renderPass,
															 VkFramebuffer			frameBuffer,
															 vector<PipelineSp>&	pipelines);
	virtual void					createVertexData		(void);
	TestParameters					fillMissingParameters	(const TestParameters&	parameters);
	void							createVertexBuffer		(void);
	void							createMultiViewDevices	(void);
	void							createCommandBuffer		(void);
	void							madeShaderModule		(map<VkShaderStageFlagBits,ShaderModuleSP>& shaderModule, vector<VkPipelineShaderStageCreateInfo>& shaderStageParams);
	Move<VkPipeline>				makeGraphicsPipeline	(const VkRenderPass							renderPass,
															 const VkPipelineLayout						pipelineLayout,
															 const deUint32								pipelineShaderStageCount,
															 const VkPipelineShaderStageCreateInfo*		pipelineShaderStageCreate,
															 const deUint32								subpass,
															 const VkVertexInputRate					vertexInputRate = VK_VERTEX_INPUT_RATE_VERTEX,
															 const bool									useDepthTest = false,
															 const bool									useStencilTest = false);
	void							readImage				(VkImage image, const tcu::PixelBufferAccess& dst);
	bool							checkImage				(tcu::ConstPixelBufferAccess& dst);
	MovePtr<tcu::Texture2DArray>	imageData				(void);
	const tcu::Vec4					getQuarterRefColor		(const deUint32 quarterNdx, const int colorNdx, const int layerNdx, const bool background = true, const deUint32 subpassNdx = 0u);
	void							appendVertex			(const tcu::Vec4& coord, const tcu::Vec4& color);
	void							setPoint				(const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& pointColor, const int pointSize, const int layerNdx, const deUint32 quarter);
	void							fillTriangle			(const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter);
	void							fillLayer				(const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx);
	void							fillQuarter				(const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter, const deUint32 subpassNdx);

	const bool						m_extensionSupported;
	const TestParameters			m_parameters;
	const int						m_seed;
	const deUint32					m_squareCount;
	Move<VkDevice>					m_logicalDevice;
	MovePtr<DeviceInterface>		m_device;
	MovePtr<Allocator>				m_allocator;
	deUint32						m_queueFamilyIndex;
	VkQueue							m_queue;
	vector<tcu::Vec4>				m_vertexCoord;
	Move<VkBuffer>					m_vertexCoordBuffer;
	MovePtr<Allocation>				m_vertexCoordAlloc;
	vector<tcu::Vec4>				m_vertexColor;
	Move<VkBuffer>					m_vertexColorBuffer;
	MovePtr<Allocation>				m_vertexColorAlloc;
	vector<deUint32>				m_vertexIndices;
	Move<VkBuffer>					m_vertexIndicesBuffer;
	MovePtr<Allocation>				m_vertexIndicesAllocation;
	Move<VkCommandPool>				m_cmdPool;
	Move<VkCommandBuffer>			m_cmdBuffer;
	de::SharedPtr<ImageAttachment>	m_colorAttachment;
	VkBool32						m_hasMultiDrawIndirect;
	vector<tcu::Vec4>				m_colorTable;
};

MultiViewRenderTestInstance::MultiViewRenderTestInstance (Context& context, const TestParameters& parameters)
	: TestInstance			(context)
	, m_extensionSupported	((parameters.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceExtension("VK_KHR_create_renderpass2"))
	, m_parameters			(fillMissingParameters(parameters))
	, m_seed				(context.getTestContext().getCommandLine().getBaseSeed())
	, m_squareCount			(4u)
	, m_queueFamilyIndex	(0u)
{
	if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_multiview"))
		throw tcu::NotSupportedError("VK_KHR_multiview is not supported");

	const float v	= 0.75f;
	const float o	= 0.25f;

	m_colorTable.push_back(tcu::Vec4(v, o, o, 1.0f));
	m_colorTable.push_back(tcu::Vec4(o, v, o, 1.0f));
	m_colorTable.push_back(tcu::Vec4(o, o, v, 1.0f));
	m_colorTable.push_back(tcu::Vec4(o, v, v, 1.0f));
	m_colorTable.push_back(tcu::Vec4(v, o, v, 1.0f));
	m_colorTable.push_back(tcu::Vec4(v, v, o, 1.0f));
	m_colorTable.push_back(tcu::Vec4(o, o, o, 1.0f));
	m_colorTable.push_back(tcu::Vec4(v, v, v, 1.0f));

	createMultiViewDevices();

	// Color attachment
	m_colorAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat, m_parameters.samples));
}

tcu::TestStatus MultiViewRenderTestInstance::iterate (void)
{
	const deUint32								subpassCount				= static_cast<deUint32>(m_parameters.viewMasks.size());

	// FrameBuffer & renderPass
	Unique<VkRenderPass>						renderPass					(makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderPassType));

	Unique<VkFramebuffer>						frameBuffer					(makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height));

	// pipelineLayout
	Unique<VkPipelineLayout>					pipelineLayout				(makePipelineLayout(*m_device, *m_logicalDevice));

	// pipelines
	map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
	vector<PipelineSp>							pipelines(subpassCount);
	const VkVertexInputRate						vertexInputRate				= (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;

	{
		vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;
		madeShaderModule(shaderModule, shaderStageParams);
		for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
			pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx, vertexInputRate))));
	}

	createCommandBuffer();
	createVertexData();
	createVertexBuffer();

	draw(subpassCount, *renderPass, *frameBuffer, pipelines);

	{
		vector<deUint8>			pixelAccessData	(m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
		tcu::PixelBufferAccess	dst				(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());

		readImage(m_colorAttachment->getImage(), dst);

		if (!checkImage(dst))
			return tcu::TestStatus::fail("Fail");
	}

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

void MultiViewRenderTestInstance::beforeDraw (void)
{
	const VkImageSubresourceRange	subresourceRange		=
	{
		VK_IMAGE_ASPECT_COLOR_BIT,	//VkImageAspectFlags	aspectMask;
		0u,							//deUint32				baseMipLevel;
		1u,							//deUint32				levelCount;
		0u,							//deUint32				baseArrayLayer;
		m_parameters.extent.depth,	//deUint32				layerCount;
	};
	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
		VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
		0, VK_ACCESS_TRANSFER_WRITE_BIT,
		VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);

	const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f));
	m_device->cmdClearColorImage(*m_cmdBuffer, m_colorAttachment->getImage(),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &renderPassClearValue.color, 1, &subresourceRange);

	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
		VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
		VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
}

void MultiViewRenderTestInstance::afterDraw (void)
{
	const VkImageSubresourceRange	subresourceRange		=
	{
		VK_IMAGE_ASPECT_COLOR_BIT,	//VkImageAspectFlags	aspectMask;
		0u,							//deUint32				baseMipLevel;
		1u,							//deUint32				levelCount;
		0u,							//deUint32				baseArrayLayer;
		m_parameters.extent.depth,	//deUint32				layerCount;
	};

	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
		VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
}

void MultiViewRenderTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
{
	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;

	const VkRenderPassBeginInfo		renderPassBeginInfo		=
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
		DE_NULL,									// const void*			pNext;
		renderPass,									// VkRenderPass			renderPass;
		frameBuffer,								// VkFramebuffer		framebuffer;
		renderArea,									// VkRect2D				renderArea;
		1u,											// uint32_t				clearValueCount;
		&renderPassClearValue,						// const VkClearValue*	pClearValues;
	};

	beginCommandBuffer(*m_device, *m_cmdBuffer);

	beforeDraw();

	cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);

	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);

	if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED)
		m_device->cmdBindIndexBuffer(*m_cmdBuffer, *m_vertexIndicesBuffer, 0u, VK_INDEX_TYPE_UINT32);

	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
	{
		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);

		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
			if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED)
				m_device->cmdDrawIndexed(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u, 0u);
			else
				m_device->cmdDraw(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u);

		if (subpassNdx < subpassCount - 1u)
			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
	}

	cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);

	afterDraw();

	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
}

void MultiViewRenderTestInstance::createVertexData (void)
{
	tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f);

	appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);

	color = tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f);
	appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color);

	color = tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f);
	appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 1.0f,-1.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color);

	color = tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 1.0f, 1.0f, 1.0f, 1.0f), color);

	if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED || m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
	{
		const size_t		verticesCount	= m_vertexCoord.size();
		vector<tcu::Vec4>	vertexColor		(verticesCount);
		vector<tcu::Vec4>	vertexCoord		(verticesCount);

		m_vertexIndices.clear();
		m_vertexIndices.reserve(verticesCount);
		for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx)
			m_vertexIndices.push_back(vertexIdx);

		de::Random(m_seed).shuffle(m_vertexIndices.begin(), m_vertexIndices.end());

		for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx)
			vertexColor[m_vertexIndices[vertexIdx]] = m_vertexColor[vertexIdx];
		m_vertexColor.assign(vertexColor.begin(), vertexColor.end());

		for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx)
			vertexCoord[m_vertexIndices[vertexIdx]] = m_vertexCoord[vertexIdx];
		m_vertexCoord.assign(vertexCoord.begin(), vertexCoord.end());
	}
}

TestParameters MultiViewRenderTestInstance::fillMissingParameters (const TestParameters& parameters)
{
	if (!parameters.viewMasks.empty())
		return parameters;
	else
	{
		if (!isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_KHR_multiview"))
			throw tcu::NotSupportedError("VK_KHR_multiview is not supported");

		const InstanceInterface&			instance			= m_context.getInstanceInterface();
		const VkPhysicalDevice				physicalDevice		= m_context.getPhysicalDevice();

		VkPhysicalDeviceMultiviewProperties multiviewProperties =
		{
			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR,	// VkStructureType	sType;
			DE_NULL,													// void*			pNext;
			0u,															// deUint32			maxMultiviewViewCount;
			0u															// deUint32			maxMultiviewInstanceIndex;
		};

		VkPhysicalDeviceProperties2 deviceProperties2;
		deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
		deviceProperties2.pNext = &multiviewProperties;

		instance.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties2);

		TestParameters newParameters = parameters;
		newParameters.extent.depth = multiviewProperties.maxMultiviewViewCount;

		vector<deUint32> viewMasks(multiviewProperties.maxMultiviewViewCount);
		for (deUint32 i = 0; i < multiviewProperties.maxMultiviewViewCount; i++)
			viewMasks[i] = 1 << i;
		newParameters.viewMasks = viewMasks;

		return newParameters;
	}
}

void MultiViewRenderTestInstance::createVertexBuffer (void)
{
	DE_ASSERT(m_vertexCoord.size() == m_vertexColor.size());
	DE_ASSERT(m_vertexCoord.size() != 0);

	const size_t	nonCoherentAtomSize	= static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize);

	// Upload vertex coordinates
	{
		const size_t				dataSize		= static_cast<size_t>(m_vertexCoord.size() * sizeof(m_vertexCoord[0]));
		const VkDeviceSize			bufferDataSize	= static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize));
		const VkBufferCreateInfo	bufferInfo		= makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);

		m_vertexCoordBuffer	= createBuffer(*m_device, *m_logicalDevice, &bufferInfo);
		m_vertexCoordAlloc	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexCoordBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexCoordBuffer, m_vertexCoordAlloc->getMemory(), m_vertexCoordAlloc->getOffset()));
		deMemcpy(m_vertexCoordAlloc->getHostPtr(), m_vertexCoord.data(), static_cast<size_t>(dataSize));
		flushMappedMemoryRange(*m_device, *m_logicalDevice, m_vertexCoordAlloc->getMemory(), m_vertexCoordAlloc->getOffset(), static_cast<size_t>(bufferDataSize));
	}

	// Upload vertex colors
	{
		const size_t				dataSize		= static_cast<size_t>(m_vertexColor.size() * sizeof(m_vertexColor[0]));
		const VkDeviceSize			bufferDataSize	= static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize));
		const VkBufferCreateInfo	bufferInfo		= makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);

		m_vertexColorBuffer	= createBuffer(*m_device, *m_logicalDevice, &bufferInfo);
		m_vertexColorAlloc	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexColorBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexColorBuffer, m_vertexColorAlloc->getMemory(), m_vertexColorAlloc->getOffset()));
		deMemcpy(m_vertexColorAlloc->getHostPtr(), m_vertexColor.data(), static_cast<size_t>(dataSize));
		flushMappedMemoryRange(*m_device, *m_logicalDevice, m_vertexColorAlloc->getMemory(), m_vertexColorAlloc->getOffset(), static_cast<size_t>(bufferDataSize));
	}

	// Upload vertex indices
	if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED || m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
	{
		const size_t				dataSize		= static_cast<size_t>(m_vertexIndices.size() * sizeof(m_vertexIndices[0]));
		const VkDeviceSize			bufferDataSize	= static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize));
		const VkBufferCreateInfo	bufferInfo		= makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);

		DE_ASSERT(m_vertexIndices.size() == m_vertexCoord.size());

		m_vertexIndicesBuffer		= createBuffer(*m_device, *m_logicalDevice, &bufferInfo);
		m_vertexIndicesAllocation	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexIndicesBuffer), MemoryRequirement::HostVisible);

		// Init host buffer data
		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexIndicesBuffer, m_vertexIndicesAllocation->getMemory(), m_vertexIndicesAllocation->getOffset()));
		deMemcpy(m_vertexIndicesAllocation->getHostPtr(), m_vertexIndices.data(), static_cast<size_t>(dataSize));
		flushMappedMemoryRange(*m_device, *m_logicalDevice, m_vertexIndicesAllocation->getMemory(), m_vertexIndicesAllocation->getOffset(), static_cast<size_t>(bufferDataSize));
	}
	else
		DE_ASSERT(m_vertexIndices.empty());
}

void MultiViewRenderTestInstance::createMultiViewDevices (void)
{
	const InstanceInterface&				instance				= m_context.getInstanceInterface();
	const VkPhysicalDevice					physicalDevice			= m_context.getPhysicalDevice();
	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instance, physicalDevice);

	for (; m_queueFamilyIndex < queueFamilyProperties.size(); ++m_queueFamilyIndex)
	{
		if ((queueFamilyProperties[m_queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)
			break;
	}

	const float								queuePriorities			= 1.0f;
	const VkDeviceQueueCreateInfo			queueInfo				=
	{
		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,					//VkStructureType			sType;
		DE_NULL,													//const void*				pNext;
		(VkDeviceQueueCreateFlags)0u,								//VkDeviceQueueCreateFlags	flags;
		m_queueFamilyIndex,											//deUint32					queueFamilyIndex;
		1u,															//deUint32					queueCount;
		&queuePriorities											//const float*				pQueuePriorities;
	};

	VkPhysicalDeviceMultiviewFeatures		multiviewFeatures		=
	{
		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR,	// VkStructureType			sType;
		DE_NULL,													// void*					pNext;
		DE_FALSE,													// VkBool32					multiview;
		DE_FALSE,													// VkBool32					multiviewGeometryShader;
		DE_FALSE,													// VkBool32					multiviewTessellationShader;
	};

	VkPhysicalDeviceFeatures2				enabledFeatures;
	enabledFeatures.sType					= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
	enabledFeatures.pNext					= &multiviewFeatures;

	instance.getPhysicalDeviceFeatures2(physicalDevice, &enabledFeatures);

	if (!multiviewFeatures.multiview)
		TCU_THROW(NotSupportedError, "MultiView not supported");

	bool requiresGeomShader = (TEST_TYPE_VIEW_INDEX_IN_GEOMETRY == m_parameters.viewIndex) ||
								(TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY == m_parameters.viewIndex) ||
								(TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY == m_parameters.viewIndex);

	if (requiresGeomShader && !multiviewFeatures.multiviewGeometryShader)
		TCU_THROW(NotSupportedError, "Geometry shader is not supported");

	if (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex && !multiviewFeatures.multiviewTessellationShader)
		TCU_THROW(NotSupportedError, "Tessellation shader is not supported");

	VkPhysicalDeviceMultiviewProperties	multiviewProperties			=
	{
		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR,	//VkStructureType	sType;
		DE_NULL,													//void*				pNext;
		0u,															//deUint32			maxMultiviewViewCount;
		0u															//deUint32			maxMultiviewInstanceIndex;
	};

	VkPhysicalDeviceProperties2			propertiesDeviceProperties2;
	propertiesDeviceProperties2.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
	propertiesDeviceProperties2.pNext	= &multiviewProperties;

	instance.getPhysicalDeviceProperties2(physicalDevice, &propertiesDeviceProperties2);

	if (multiviewProperties.maxMultiviewViewCount < 6u)
		TCU_FAIL("maxMultiviewViewCount below min value");

	if (multiviewProperties.maxMultiviewInstanceIndex < 134217727u) //134217727u = 2^27 -1
		TCU_FAIL("maxMultiviewInstanceIndex below min value");

	if (multiviewProperties.maxMultiviewViewCount <m_parameters.extent.depth)
		TCU_THROW(NotSupportedError, "Limit MaxMultiviewViewCount to small to run this test");

	m_hasMultiDrawIndirect = enabledFeatures.features.multiDrawIndirect;

	{
		vector<const char*>							deviceExtensions;

		if (!isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_multiview"))
			deviceExtensions.push_back("VK_KHR_multiview");

		if (m_parameters.renderPassType == RENDERPASS_TYPE_RENDERPASS2)
			if (!isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_create_renderpass2"))
				deviceExtensions.push_back("VK_KHR_create_renderpass2");

		const VkDeviceCreateInfo		deviceInfo			=
		{
			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							//VkStructureType					sType;
			&enabledFeatures,												//const void*						pNext;
			0u,																//VkDeviceCreateFlags				flags;
			1u,																//deUint32							queueCreateInfoCount;
			&queueInfo,														//const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
			0u,																//deUint32							enabledLayerCount;
			DE_NULL,														//const char* const*				ppEnabledLayerNames;
			static_cast<deUint32>(deviceExtensions.size()),					//deUint32							enabledExtensionCount;
			deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0],		//const char* const*				pEnabledExtensionNames;
			DE_NULL															//const VkPhysicalDeviceFeatures*	pEnabledFeatures;
		};

		m_logicalDevice					= createDevice(m_context.getPlatformInterface(), m_context.getInstance(), instance, physicalDevice, &deviceInfo);
		m_device						= MovePtr<DeviceDriver>(new DeviceDriver(m_context.getPlatformInterface(), m_context.getInstance(), *m_logicalDevice));
		m_allocator						= MovePtr<Allocator>(new SimpleAllocator(*m_device, *m_logicalDevice, getPhysicalDeviceMemoryProperties(instance, physicalDevice)));
		m_device->getDeviceQueue		(*m_logicalDevice, m_queueFamilyIndex, 0u, &m_queue);
	}
}

void MultiViewRenderTestInstance::createCommandBuffer (void)
{
	// cmdPool
	{
		const VkCommandPoolCreateInfo cmdPoolParams =
		{
			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// VkStructureType		sType;
			DE_NULL,											// const void*			pNext;
			VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// VkCmdPoolCreateFlags	flags;
			m_queueFamilyIndex,									// deUint32				queueFamilyIndex;
		};
		m_cmdPool = createCommandPool(*m_device, *m_logicalDevice, &cmdPoolParams);
	}

	// cmdBuffer
	{
		const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
		{
			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,		// VkStructureType		sType;
			DE_NULL,											// const void*			pNext;
			*m_cmdPool,											// VkCommandPool		commandPool;
			VK_COMMAND_BUFFER_LEVEL_PRIMARY,					// VkCommandBufferLevel	level;
			1u,													// deUint32				bufferCount;
		};
		m_cmdBuffer	= allocateCommandBuffer(*m_device, *m_logicalDevice, &cmdBufferAllocateInfo);
	}
}

void MultiViewRenderTestInstance::madeShaderModule (map<VkShaderStageFlagBits, ShaderModuleSP>& shaderModule, vector<VkPipelineShaderStageCreateInfo>& shaderStageParams)
{
	// create shaders modules
	switch (m_parameters.viewIndex)
	{
		case TEST_TYPE_VIEW_MASK:
		case TEST_TYPE_VIEW_INDEX_IN_VERTEX:
		case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT:
		case TEST_TYPE_INSTANCED_RENDERING:
		case TEST_TYPE_INPUT_RATE_INSTANCE:
		case TEST_TYPE_DRAW_INDIRECT:
		case TEST_TYPE_DRAW_INDIRECT_INDEXED:
		case TEST_TYPE_DRAW_INDEXED:
		case TEST_TYPE_CLEAR_ATTACHMENTS:
		case TEST_TYPE_SECONDARY_CMD_BUFFER:
		case TEST_TYPE_INPUT_ATTACHMENTS:
		case TEST_TYPE_POINT_SIZE:
		case TEST_TYPE_MULTISAMPLE:
		case TEST_TYPE_QUERIES:
		case TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR:
		case TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR:
		case TEST_TYPE_DEPTH:
		case TEST_TYPE_STENCIL:
			shaderModule[VK_SHADER_STAGE_VERTEX_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0))));
			shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0))));
			break;
		case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY:
		case TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY:
		case TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY:
			shaderModule[VK_SHADER_STAGE_VERTEX_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0))));
			shaderModule[VK_SHADER_STAGE_GEOMETRY_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("geometry"), 0))));
			shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0))));
			break;
		case TEST_TYPE_VIEW_INDEX_IN_TESELLATION:
			shaderModule[VK_SHADER_STAGE_VERTEX_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0))));
			shaderModule[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT]		= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("tessellation_control"), 0))));
			shaderModule[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT]	= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("tessellation_evaluation"), 0))));
			shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0))));
			break;
		default:
			DE_ASSERT(0);
		break;
	};

	VkPipelineShaderStageCreateInfo	pipelineShaderStage	=
	{
			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
			DE_NULL,												// const void*							pNext;
			(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
			(VkShaderStageFlagBits)0,								// VkShaderStageFlagBits				stage;
			(VkShaderModule)0,										// VkShaderModule						module;
			"main",													// const char*							pName;
			(const VkSpecializationInfo*)DE_NULL,					// const VkSpecializationInfo*			pSpecializationInfo;
	};

	for (map<VkShaderStageFlagBits, ShaderModuleSP>::iterator it=shaderModule.begin(); it!=shaderModule.end(); ++it)
	{
		pipelineShaderStage.stage	= it->first;
		pipelineShaderStage.module	= **it->second;
		shaderStageParams.push_back(pipelineShaderStage);
	}
}

Move<VkPipeline> MultiViewRenderTestInstance::makeGraphicsPipeline (const VkRenderPass							renderPass,
																	const VkPipelineLayout						pipelineLayout,
																	const deUint32								pipelineShaderStageCount,
																	const VkPipelineShaderStageCreateInfo*		pipelineShaderStageCreate,
																	const deUint32								subpass,
																	const VkVertexInputRate						vertexInputRate,
																	const bool									useDepthTest,
																	const bool									useStencilTest)
{
	const VkVertexInputBindingDescription			vertexInputBindingDescriptions[]	=
	{
		{
			0u,													// binding;
			static_cast<deUint32>(sizeof(m_vertexCoord[0])),	// stride;
			vertexInputRate										// inputRate
		},
		{
			1u,													// binding;
			static_cast<deUint32>(sizeof(m_vertexColor[0])),	// stride;
			vertexInputRate										// inputRate
		}
	};

	const VkVertexInputAttributeDescription			vertexInputAttributeDescriptions[]	=
	{
		{
			0u,											// deUint32	location;
			0u,											// deUint32	binding;
			VK_FORMAT_R32G32B32A32_SFLOAT,				// VkFormat	format;
			0u											// deUint32	offset;
		},	// VertexElementData::position
		{
			1u,											// deUint32	location;
			1u,											// deUint32	binding;
			VK_FORMAT_R32G32B32A32_SFLOAT,				// VkFormat	format;
			0u											// deUint32	offset;
		},	// VertexElementData::color
	};

	const VkPipelineVertexInputStateCreateInfo		vertexInputStateParams				=
	{
		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
		NULL,															// const void*								pNext;
		0u,																// VkPipelineVertexInputStateCreateFlags	flags;
		DE_LENGTH_OF_ARRAY(vertexInputBindingDescriptions),				// deUint32									vertexBindingDescriptionCount;
		vertexInputBindingDescriptions,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
		DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),			// deUint32									vertexAttributeDescriptionCount;
		vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
	};

	const VkPrimitiveTopology						topology							= (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST :
																						  (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex) ? VK_PRIMITIVE_TOPOLOGY_POINT_LIST :
																						  VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;

	const VkPipelineInputAssemblyStateCreateInfo	inputAssemblyStateParams			=
	{
		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,														// const void*								pNext;
		0u,																// VkPipelineInputAssemblyStateCreateFlags	flags;
		topology,														// VkPrimitiveTopology						topology;
		VK_FALSE,														// VkBool32									primitiveRestartEnable;
	};

	const VkViewport								viewport							= makeViewport(m_parameters.extent);
	const VkRect2D									scissor								= makeRect2D(m_parameters.extent);

	const VkPipelineViewportStateCreateInfo			viewportStateParams					=
	{
		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType						sType;
		DE_NULL,												// const void*							pNext;
		0u,														// VkPipelineViewportStateCreateFlags	flags;
		1u,														// deUint32								viewportCount;
		&viewport,												// const VkViewport*					pViewports;
		1u,														// deUint32								scissorCount;
		&scissor												// const VkRect2D*						pScissors;
	};

	const VkPipelineRasterizationStateCreateInfo	rasterStateParams					=
	{
		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,													// const void*								pNext;
		0u,															// VkPipelineRasterizationStateCreateFlags	flags;
		VK_FALSE,													// VkBool32									depthClampEnable;
		VK_FALSE,													// VkBool32									rasterizerDiscardEnable;
		VK_POLYGON_MODE_FILL,										// VkPolygonMode							polygonMode;
		VK_CULL_MODE_NONE,											// VkCullModeFlags							cullMode;
		VK_FRONT_FACE_COUNTER_CLOCKWISE,							// VkFrontFace								frontFace;
		VK_FALSE,													// VkBool32									depthBiasEnable;
		0.0f,														// float									depthBiasConstantFactor;
		0.0f,														// float									depthBiasClamp;
		0.0f,														// float									depthBiasSlopeFactor;
		1.0f,														// float									lineWidth;
	};

	const VkSampleCountFlagBits						sampleCountFlagBits					= (TEST_TYPE_MULTISAMPLE == m_parameters.viewIndex) ? VK_SAMPLE_COUNT_4_BIT :
																						  VK_SAMPLE_COUNT_1_BIT;
	const VkPipelineMultisampleStateCreateInfo		multisampleStateParams				=
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,													// const void*								pNext;
		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
		sampleCountFlagBits,										// VkSampleCountFlagBits					rasterizationSamples;
		VK_FALSE,													// VkBool32									sampleShadingEnable;
		0.0f,														// float									minSampleShading;
		DE_NULL,													// const VkSampleMask*						pSampleMask;
		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
		VK_FALSE,													// VkBool32									alphaToOneEnable;
	};

	VkPipelineDepthStencilStateCreateInfo			depthStencilStateParams				=
	{
		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,													// const void*								pNext;
		0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
		useDepthTest ? VK_TRUE : VK_FALSE,							// VkBool32									depthTestEnable;
		useDepthTest ? VK_TRUE : VK_FALSE,							// VkBool32									depthWriteEnable;
		VK_COMPARE_OP_LESS_OR_EQUAL,								// VkCompareOp								depthCompareOp;
		VK_FALSE,													// VkBool32									depthBoundsTestEnable;
		useStencilTest ? VK_TRUE : VK_FALSE,						// VkBool32									stencilTestEnable;
		// VkStencilOpState front;
		{
			VK_STENCIL_OP_KEEP,					// VkStencilOp	failOp;
			VK_STENCIL_OP_INCREMENT_AND_CLAMP,	// VkStencilOp	passOp;
			VK_STENCIL_OP_KEEP,					// VkStencilOp	depthFailOp;
			VK_COMPARE_OP_ALWAYS,				// VkCompareOp	compareOp;
			~0u,								// deUint32		compareMask;
			~0u,								// deUint32		writeMask;
			0u,									// deUint32		reference;
		},
		// VkStencilOpState back;
		{
			VK_STENCIL_OP_KEEP,					// VkStencilOp	failOp;
			VK_STENCIL_OP_INCREMENT_AND_CLAMP,	// VkStencilOp	passOp;
			VK_STENCIL_OP_KEEP,					// VkStencilOp	depthFailOp;
			VK_COMPARE_OP_ALWAYS,				// VkCompareOp	compareOp;
			~0u,								// deUint32		compareMask;
			~0u,								// deUint32		writeMask;
			0u,									// deUint32		reference;
		},
		0.0f,	// float	minDepthBounds;
		1.0f,	// float	maxDepthBounds;
	};

	const VkPipelineColorBlendAttachmentState		colorBlendAttachmentState			=
	{
		VK_FALSE,								// VkBool32					blendEnable;
		VK_BLEND_FACTOR_SRC_ALPHA,				// VkBlendFactor			srcColorBlendFactor;
		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,	// VkBlendFactor			dstColorBlendFactor;
		VK_BLEND_OP_ADD,						// VkBlendOp				colorBlendOp;
		VK_BLEND_FACTOR_ONE,					// VkBlendFactor			srcAlphaBlendFactor;
		VK_BLEND_FACTOR_ONE,					// VkBlendFactor			dstAlphaBlendFactor;
		VK_BLEND_OP_ADD,						// VkBlendOp				alphaBlendOp;
		VK_COLOR_COMPONENT_R_BIT |				// VkColorComponentFlags	colorWriteMask;
		VK_COLOR_COMPONENT_G_BIT |
		VK_COLOR_COMPONENT_B_BIT |
		VK_COLOR_COMPONENT_A_BIT
	};

	const VkPipelineColorBlendStateCreateInfo		colorBlendStateParams				=
	{
		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
		DE_NULL,													// const void*									pNext;
		0u,															// VkPipelineColorBlendStateCreateFlags			flags;
		VK_FALSE,													// VkBool32										logicOpEnable;
		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
		1u,															// deUint32										attachmentCount;
		&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments;
		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConst[4];
	};

	VkPipelineTessellationStateCreateInfo			TessellationState					=
	{
		VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,													// const void*								pNext;
		(VkPipelineTessellationStateCreateFlags)0,					// VkPipelineTessellationStateCreateFlags	flags;
		4u															// deUint32									patchControlPoints;
	};

	const VkGraphicsPipelineCreateInfo				graphicsPipelineParams				=
	{
		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,												// VkStructureType									sType;
		DE_NULL,																						// const void*										pNext;
		(VkPipelineCreateFlags)0u,																		// VkPipelineCreateFlags							flags;
		pipelineShaderStageCount,																		// deUint32											stageCount;
		pipelineShaderStageCreate,																		// const VkPipelineShaderStageCreateInfo*			pStages;
		&vertexInputStateParams,																		// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
		&inputAssemblyStateParams,																		// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
		(TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex)? &TessellationState : DE_NULL,	// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
		&viewportStateParams,																			// const VkPipelineViewportStateCreateInfo*			pViewportState;
		&rasterStateParams,																				// const VkPipelineRasterizationStateCreateInfo*	pRasterState;
		&multisampleStateParams,																		// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
		&depthStencilStateParams,																		// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
		&colorBlendStateParams,																			// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
		(const VkPipelineDynamicStateCreateInfo*)DE_NULL,												// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
		pipelineLayout,																					// VkPipelineLayout									layout;
		renderPass,																						// VkRenderPass										renderPass;
		subpass,																						// deUint32											subpass;
		0u,																								// VkPipeline										basePipelineHandle;
		0,																								// deInt32											basePipelineIndex;
	};

	return createGraphicsPipeline(*m_device, *m_logicalDevice, DE_NULL, &graphicsPipelineParams);
}

void MultiViewRenderTestInstance::readImage (VkImage image, const tcu::PixelBufferAccess& dst)
{
	Move<VkBuffer>				buffer;
	MovePtr<Allocation>			bufferAlloc;
	const VkDeviceSize			pixelDataSize	= dst.getWidth() * dst.getHeight() * dst.getDepth() * mapVkFormat(m_parameters.colorFormat).getPixelSize();

	// Create destination buffer
	{
		const VkBufferCreateInfo bufferParams	=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			0u,										// VkBufferCreateFlags	flags;
			pixelDataSize,							// VkDeviceSize			size;
			VK_BUFFER_USAGE_TRANSFER_DST_BIT,		// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyIndexCount;
			&m_queueFamilyIndex,					// const deUint32*		pQueueFamilyIndices;
		};

		buffer		= createBuffer(*m_device, *m_logicalDevice, &bufferParams);
		bufferAlloc	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible);
		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));

		deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
		flushMappedMemoryRange(*m_device, *m_logicalDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
	}

	const VkBufferMemoryBarrier	bufferBarrier	=
	{
		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,					// deUint32			srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
		*buffer,									// VkBuffer			buffer;
		0u,											// VkDeviceSize		offset;
		pixelDataSize								// VkDeviceSize		size;
	};

	// Copy image to buffer
	const VkImageAspectFlags	aspect			= getAspectFlags(dst.getFormat());
	const VkBufferImageCopy		copyRegion		=
	{
		0u,										// VkDeviceSize				bufferOffset;
		(deUint32)dst.getWidth(),				// deUint32					bufferRowLength;
		(deUint32)dst.getHeight(),				// deUint32					bufferImageHeight;
		{
			aspect,								// VkImageAspectFlags		aspect;
			0u,									// deUint32					mipLevel;
			0u,									// deUint32					baseArrayLayer;
			m_parameters.extent.depth,			// deUint32					layerCount;
		},										// VkImageSubresourceLayers	imageSubresource;
		{ 0, 0, 0 },							// VkOffset3D				imageOffset;
		{ m_parameters.extent.width, m_parameters.extent.height, 1u }	// VkExtent3D				imageExtent;
	};

	beginCommandBuffer (*m_device, *m_cmdBuffer);
	{
		VkImageSubresourceRange	subresourceRange	=
		{
			aspect,						// VkImageAspectFlags	aspectMask;
			0u,							// deUint32				baseMipLevel;
			1u,							// deUint32				mipLevels;
			0u,							// deUint32				baseArraySlice;
			m_parameters.extent.depth,	// deUint32				arraySize;
		};

		imageBarrier (*m_device, *m_cmdBuffer, image, subresourceRange,
			VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);

		m_device->cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
		m_device->cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0u, DE_NULL);
	}
	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);

	// Read buffer data
	invalidateMappedMemoryRange(*m_device, *m_logicalDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
	tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
}

bool MultiViewRenderTestInstance::checkImage (tcu::ConstPixelBufferAccess& renderedFrame)
{
	const MovePtr<tcu::Texture2DArray>	referenceFrame	= imageData();
	const bool							result			= tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
															"Result", "Image comparison result", referenceFrame->getLevel(0), renderedFrame, tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR);

	if (!result)
		for (deUint32 layerNdx = 0u; layerNdx < m_parameters.extent.depth; layerNdx++)
		{
			tcu::ConstPixelBufferAccess ref (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, 1u, referenceFrame->getLevel(0).getPixelPtr(0, 0, layerNdx));
			tcu::ConstPixelBufferAccess dst (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, 1u, renderedFrame.getPixelPtr(0 ,0, layerNdx));
			tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", ref, dst, tcu::Vec4(0.01f), tcu::COMPARE_LOG_EVERYTHING);
		}

	return result;
}

const tcu::Vec4 MultiViewRenderTestInstance::getQuarterRefColor (const deUint32 quarterNdx, const int colorNdx, const int layerNdx, const bool background, const deUint32 subpassNdx)
{
	switch (m_parameters.viewIndex)
	{
		case TEST_TYPE_VIEW_MASK:
			return m_vertexColor[colorNdx];

		case TEST_TYPE_DRAW_INDEXED:
			return m_vertexColor[m_vertexIndices[colorNdx]];

		case TEST_TYPE_INSTANCED_RENDERING:
			return m_vertexColor[0] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, static_cast<float>(quarterNdx + 1u) * 0.10f, 0.0);

		case TEST_TYPE_INPUT_RATE_INSTANCE:
			return m_vertexColor[colorNdx / 4] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, static_cast<float>(quarterNdx + 1u) * 0.10f, 0.0);

		case TEST_TYPE_DRAW_INDIRECT_INDEXED:
			return m_vertexColor[m_vertexIndices[colorNdx]] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0);

		case TEST_TYPE_VIEW_INDEX_IN_VERTEX:
		case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT:
		case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY:
		case TEST_TYPE_VIEW_INDEX_IN_TESELLATION:
		case TEST_TYPE_INPUT_ATTACHMENTS:
		case TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY:
		case TEST_TYPE_DRAW_INDIRECT:
		case TEST_TYPE_CLEAR_ATTACHMENTS:
		case TEST_TYPE_SECONDARY_CMD_BUFFER:
		case TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY:
			return m_vertexColor[colorNdx] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0);

		case TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR:
			if (background)
				return m_colorTable[4 + quarterNdx % 4];
			else
				return m_colorTable[layerNdx % 4];

		case TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR:
			if (background)
				return m_colorTable[4 + quarterNdx % 4];
			else
				return m_colorTable[0];

		case TEST_TYPE_POINT_SIZE:
		case TEST_TYPE_MULTISAMPLE:
			if (background)
				return tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
			else
				return m_vertexColor[colorNdx];

		case TEST_TYPE_DEPTH:
			if (background)
				if (subpassNdx < 4)
					return tcu::Vec4(0.66f, 0.0f, 0.0f, 1.0f);
				else
					return tcu::Vec4(0.33f, 0.0f, 0.0f, 1.0f);
			else
				return tcu::Vec4(0.99f, 0.0f, 0.0f, 1.0f);

		case TEST_TYPE_STENCIL:
			if (background)
				return tcu::Vec4(0.33f, 0.0f, 0.0f, 0.0f); // Increment value
			else
				return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);

		default:
			TCU_THROW(InternalError, "Impossible");
	}
}

void MultiViewRenderTestInstance::setPoint (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& pointColor, const int pointSize, const int layerNdx, const deUint32 quarter)
{
	DE_ASSERT(TEST_POINT_SIZE_WIDE > TEST_POINT_SIZE_SMALL);

	const int	pointOffset	= 1 + TEST_POINT_SIZE_WIDE / 2 - (pointSize + 1) / 2;
	const int	offsetX		= pointOffset + static_cast<int>((quarter == 0u || quarter == 1u) ? 0 : m_parameters.extent.width / 2u);
	const int	offsetY		= pointOffset + static_cast<int>((quarter == 0u || quarter == 2u) ? 0 : m_parameters.extent.height / 2u);

	for (int y = 0; y < pointSize; ++y)
	for (int x = 0; x < pointSize; ++x)
		pixelBuffer.setPixel(pointColor, offsetX + x, offsetY + y, layerNdx);
}

void MultiViewRenderTestInstance::fillTriangle (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter)
{
	const int		offsetX				= static_cast<int>((quarter == 0u || quarter == 1u) ? 0 : m_parameters.extent.width / 2u);
	const int		offsetY				= static_cast<int>((quarter == 0u || quarter == 2u) ? 0 : m_parameters.extent.height / 2u);
	const int		maxY				= static_cast<int>(m_parameters.extent.height / 2u);
	const tcu::Vec4	multisampledColor	= tcu::Vec4(color[0], color[1], color[2], color[3]) * 0.5f;

	for (int y = 0; y < maxY; ++y)
	{
		for (int x = 0; x < y; ++x)
			pixelBuffer.setPixel(color, offsetX + x, offsetY + (maxY - 1) - y, layerNdx);

		// Multisampled pixel is on the triangle margin
		pixelBuffer.setPixel(multisampledColor, offsetX + y, offsetY + (maxY - 1) - y, layerNdx);
	}
}

void MultiViewRenderTestInstance::fillLayer (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx)
{
	for (deUint32 y = 0u; y < m_parameters.extent.height; ++y)
	for (deUint32 x = 0u; x < m_parameters.extent.width; ++x)
		pixelBuffer.setPixel(color, x, y, layerNdx);
}

void MultiViewRenderTestInstance::fillQuarter (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter, const deUint32 subpassNdx)
{
	const int h		= m_parameters.extent.height;
	const int h2	= h / 2;
	const int w		= m_parameters.extent.width;
	const int w2	= w / 2;
	int xStart		= 0;
	int xEnd		= 0;
	int yStart		= 0;
	int yEnd		= 0;

	switch (quarter)
	{
		case 0:	xStart = 0u; xEnd = w2; yStart = 0u; yEnd = h2; break;
		case 1:	xStart = 0u; xEnd = w2; yStart = h2; yEnd = h;  break;
		case 2:	xStart = w2; xEnd = w;  yStart = 0u; yEnd = h2; break;
		case 3:	xStart = w2; xEnd = w;  yStart = h2; yEnd = h;  break;
		default: TCU_THROW(InternalError, "Impossible");
	}

	if (TEST_TYPE_STENCIL == m_parameters.viewIndex || TEST_TYPE_DEPTH == m_parameters.viewIndex)
	{
		if (subpassNdx < 4)
		{	// Part A: Horizontal bars near X axis
			yStart	= h2 + (yStart - h2) / 2;
			yEnd	= h2 + (yEnd - h2) / 2;
		}
		else
		{	// Part B: Vertical bars near Y axis (drawn twice)
			xStart	= w2 + (xStart - w2) / 2;
			xEnd	= w2 + (xEnd - w2) / 2;
		}

		// Update pixels in area
		if (TEST_TYPE_STENCIL == m_parameters.viewIndex)
		{
			for (int y = yStart; y < yEnd; ++y)
			for (int x = xStart; x < xEnd; ++x)
				pixelBuffer.setPixel(pixelBuffer.getPixel(x, y, layerNdx) + color, x, y, layerNdx);
		}

		if (TEST_TYPE_DEPTH == m_parameters.viewIndex)
		{
			for (int y = yStart; y < yEnd; ++y)
			for (int x = xStart; x < xEnd; ++x)
			{
				const tcu::Vec4		currentColor	= pixelBuffer.getPixel(x, y, layerNdx);
				const tcu::Vec4&	newColor		= (currentColor[0] < color[0]) ? currentColor : color;

				pixelBuffer.setPixel(newColor, x, y, layerNdx);
			}
		}
	}
	else
	{
		for (int y = yStart; y < yEnd; ++y)
		for (int x = xStart; x < xEnd; ++x)
			pixelBuffer.setPixel(color , x, y, layerNdx);
	}
}

MovePtr<tcu::Texture2DArray> MultiViewRenderTestInstance::imageData (void)
{
	MovePtr<tcu::Texture2DArray>	referenceFrame	= MovePtr<tcu::Texture2DArray>(new tcu::Texture2DArray(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth));
	const deUint32					subpassCount	= static_cast<deUint32>(m_parameters.viewMasks.size());
	referenceFrame->allocLevel(0);

	deMemset (referenceFrame->getLevel(0).getDataPtr(), 0, m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth* mapVkFormat(m_parameters.colorFormat).getPixelSize());

	if (TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR == m_parameters.viewIndex || TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR == m_parameters.viewIndex)
	{
		deUint32	clearedViewMask	= 0;

		// Start from last clear command color, which actually takes effect
		for (int subpassNdx = static_cast<int>(subpassCount) - 1; subpassNdx >= 0; --subpassNdx)
		{
			deUint32	subpassToClearViewMask	= m_parameters.viewMasks[subpassNdx] & ~clearedViewMask;

			if (subpassToClearViewMask == 0)
				continue;

			for (deUint32 layerNdx = 0; layerNdx < m_parameters.extent.depth; ++layerNdx)
				if ((subpassToClearViewMask & (1 << layerNdx)) != 0 && (clearedViewMask & (1 << layerNdx)) == 0)
					fillLayer(referenceFrame->getLevel(0), getQuarterRefColor(0u, 0u, subpassNdx, false), layerNdx);

			// These has been cleared. Exclude these layers from upcoming attempts to clear
			clearedViewMask |= subpassToClearViewMask;
		}
	}

	if (TEST_TYPE_DEPTH == m_parameters.viewIndex || TEST_TYPE_STENCIL == m_parameters.viewIndex)
		for (deUint32 layerNdx = 0; layerNdx < m_parameters.extent.depth; ++layerNdx)
			fillLayer(referenceFrame->getLevel(0), getQuarterRefColor(0u, 0u, 0u, false), layerNdx);

	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
	{
		int			layerNdx	= 0;
		deUint32	mask		= m_parameters.viewMasks[subpassNdx];

		while (mask > 0u)
		{
			int colorNdx	= 0;

			if (mask & 1u)
			{
				if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex)
				{
					struct ColorDataRGBA
					{
						deUint8	r;
						deUint8	g;
						deUint8	b;
						deUint8	a;
					};

					ColorDataRGBA	clear		=
					{
						tcu::floatToU8 (1.0f),
						tcu::floatToU8 (0.0f),
						tcu::floatToU8 (0.0f),
						tcu::floatToU8 (1.0f)
					};

					ColorDataRGBA*	dataSrc		= (ColorDataRGBA*)referenceFrame->getLevel(0).getPixelPtr(0, 0, layerNdx);
					ColorDataRGBA*	dataDes		= dataSrc + 1;
					deUint32		copySize	= 1u;
					deUint32		layerSize	= m_parameters.extent.width * m_parameters.extent.height - copySize;
					deMemcpy(dataSrc, &clear, sizeof(ColorDataRGBA));

					while (layerSize > 0)
					{
						deMemcpy(dataDes, dataSrc, copySize * sizeof(ColorDataRGBA));
						dataDes = dataDes + copySize;
						layerSize = layerSize - copySize;
						copySize = 2u * copySize;
						if (copySize >= layerSize)
							copySize = layerSize;
					}
				}

				const deUint32 subpassQuarterNdx = subpassNdx % m_squareCount;
				if (subpassQuarterNdx == 0u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
				{
					const tcu::Vec4 color = getQuarterRefColor(0u, colorNdx, layerNdx, true, subpassNdx);

					fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 0u, subpassNdx);
				}

				colorNdx += 4;
				if (subpassQuarterNdx == 1u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
				{
					const tcu::Vec4 color = getQuarterRefColor(1u, colorNdx, layerNdx, true, subpassNdx);

					fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 1u, subpassNdx);
				}

				colorNdx += 4;
				if (subpassQuarterNdx == 2u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
				{
					const tcu::Vec4 color = getQuarterRefColor(2u, colorNdx, layerNdx, true, subpassNdx);

					fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 2u, subpassNdx);
				}

				colorNdx += 4;
				if (subpassQuarterNdx == 3u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
				{
					const tcu::Vec4 color = getQuarterRefColor(3u, colorNdx, layerNdx, true, subpassNdx);

					fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 3u, subpassNdx);
				}

				if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex)
				{
					const tcu::Vec4	color	(0.0f, 0.0f, 1.0f, 1.0f);
					const int		maxY	= static_cast<int>(static_cast<float>(m_parameters.extent.height) * 0.75f);
					const int		maxX	= static_cast<int>(static_cast<float>(m_parameters.extent.width) * 0.75f);
					for (int y = static_cast<int>(m_parameters.extent.height / 4u); y < maxY; ++y)
					for (int x = static_cast<int>(m_parameters.extent.width / 4u); x < maxX; ++x)
						referenceFrame->getLevel(0).setPixel(color, x, y, layerNdx);
				}

				if (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex)
				{
					const deUint32	vertexPerPrimitive	= 1u;
					const deUint32	dummyQuarterNdx		= 0u;
					const int		pointSize			= static_cast<int>(layerNdx == 0u ? TEST_POINT_SIZE_WIDE : TEST_POINT_SIZE_SMALL);

					if (subpassCount == 1)
						for (deUint32 drawNdx = 0u; drawNdx < m_squareCount; ++drawNdx)
							setPoint(referenceFrame->getLevel(0), getQuarterRefColor(dummyQuarterNdx, vertexPerPrimitive * drawNdx, layerNdx, false), pointSize, layerNdx, drawNdx);
					else
						setPoint(referenceFrame->getLevel(0), getQuarterRefColor(dummyQuarterNdx, vertexPerPrimitive * subpassQuarterNdx, layerNdx, false), pointSize, layerNdx, subpassQuarterNdx);
				}

				if (TEST_TYPE_MULTISAMPLE == m_parameters.viewIndex)
				{
					const deUint32	vertexPerPrimitive	= 3u;
					const deUint32	dummyQuarterNdx		= 0u;

					if (subpassCount == 1)
						for (deUint32 drawNdx = 0u; drawNdx < m_squareCount; ++drawNdx)
							fillTriangle(referenceFrame->getLevel(0), getQuarterRefColor(dummyQuarterNdx, vertexPerPrimitive * drawNdx, layerNdx, false), layerNdx, drawNdx);
					else
						fillTriangle(referenceFrame->getLevel(0), getQuarterRefColor(dummyQuarterNdx, vertexPerPrimitive * subpassQuarterNdx, layerNdx, false), layerNdx, subpassQuarterNdx);
				}
			}

			mask = mask >> 1;
			++layerNdx;
		}
	}
	return referenceFrame;
}

void MultiViewRenderTestInstance::appendVertex (const tcu::Vec4& coord, const tcu::Vec4& color)
{
	m_vertexCoord.push_back(coord);
	m_vertexColor.push_back(color);
}

class MultiViewAttachmentsTestInstance : public MultiViewRenderTestInstance
{
public:
						MultiViewAttachmentsTestInstance	(Context& context, const TestParameters& parameters);
protected:
	tcu::TestStatus		iterate								(void);
	void				beforeDraw							(void);
	void				setImageData						(VkImage image);
	de::SharedPtr<ImageAttachment>	m_inputAttachment;
	Move<VkDescriptorPool>			m_descriptorPool;
	Move<VkDescriptorSet>			m_descriptorSet;
	Move<VkDescriptorSetLayout>		m_descriptorSetLayout;
	Move<VkPipelineLayout>			m_pipelineLayout;

};

MultiViewAttachmentsTestInstance::MultiViewAttachmentsTestInstance (Context& context, const TestParameters& parameters)
	: MultiViewRenderTestInstance	(context, parameters)
{
}

tcu::TestStatus MultiViewAttachmentsTestInstance::iterate (void)
{
	const deUint32								subpassCount			= static_cast<deUint32>(m_parameters.viewMasks.size());
	// All color attachment
	m_colorAttachment	= de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat));
	m_inputAttachment	= de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat));

	// FrameBuffer & renderPass
	Unique<VkRenderPass>						renderPass				(makeRenderPassWithAttachments(*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderPassType));

	vector<VkImageView>							attachments;
	attachments.push_back(m_colorAttachment->getImageView());
	attachments.push_back(m_inputAttachment->getImageView());
	Unique<VkFramebuffer>						frameBuffer				(makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, static_cast<deUint32>(attachments.size()), attachments.data(), m_parameters.extent.width, m_parameters.extent.height));

	// pipelineLayout
	m_descriptorSetLayout	= makeDescriptorSetLayout(*m_device, *m_logicalDevice);
	m_pipelineLayout		= makePipelineLayout(*m_device, *m_logicalDevice, m_descriptorSetLayout.get());

	// pipelines
	map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
	vector<PipelineSp>							pipelines(subpassCount);

	{
		vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;
		madeShaderModule(shaderModule, shaderStageParams);
		for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
			pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *m_pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx))));
	}

	createVertexData();
	createVertexBuffer();

	createCommandBuffer();
	setImageData(m_inputAttachment->getImage());
	draw(subpassCount, *renderPass, *frameBuffer, pipelines);

	{
		vector<deUint8>			pixelAccessData	(m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
		tcu::PixelBufferAccess	dst				(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());

		readImage (m_colorAttachment->getImage(), dst);
		if (!checkImage(dst))
			return tcu::TestStatus::fail("Fail");
	}

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

void MultiViewAttachmentsTestInstance::beforeDraw (void)
{
	const VkDescriptorPoolSize poolSize =
	{
		vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
		1u
	};

	const VkDescriptorPoolCreateInfo createInfo =
	{
		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
		DE_NULL,
		VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
		1u,
		1u,
		&poolSize
	};

	m_descriptorPool = createDescriptorPool(*m_device, *m_logicalDevice, &createInfo);

	const VkDescriptorSetAllocateInfo	allocateInfo =
	{
		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
		DE_NULL,
		*m_descriptorPool,
		1u,
		&m_descriptorSetLayout.get()
	};

	m_descriptorSet	= vk::allocateDescriptorSet(*m_device, *m_logicalDevice, &allocateInfo);

	const VkDescriptorImageInfo	imageInfo =
	{
		(VkSampler)0,
		m_inputAttachment->getImageView(),
		VK_IMAGE_LAYOUT_GENERAL
	};

	const VkWriteDescriptorSet	write =
	{
		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	//VkStructureType				sType;
		DE_NULL,								//const void*					pNext;
		*m_descriptorSet,						//VkDescriptorSet				dstSet;
		0u,										//deUint32						dstBinding;
		0u,										//deUint32						dstArrayElement;
		1u,										//deUint32						descriptorCount;
		VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,	//VkDescriptorType				descriptorType;
		&imageInfo,								//const VkDescriptorImageInfo*	pImageInfo;
		DE_NULL,								//const VkDescriptorBufferInfo*	pBufferInfo;
		DE_NULL,								//const VkBufferView*			pTexelBufferView;
	};

	m_device->updateDescriptorSets(*m_logicalDevice, (deUint32)1u, &write, 0u, DE_NULL);

	const VkImageSubresourceRange	subresourceRange	=
	{
		VK_IMAGE_ASPECT_COLOR_BIT,	//VkImageAspectFlags	aspectMask;
		0u,							//deUint32				baseMipLevel;
		1u,							//deUint32				levelCount;
		0u,							//deUint32				baseArrayLayer;
		m_parameters.extent.depth,	//deUint32				layerCount;
	};
	m_device->cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &(*m_descriptorSet), 0u, NULL);

	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
		VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
		0, VK_ACCESS_TRANSFER_WRITE_BIT,
		VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);

	const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f));
	m_device->cmdClearColorImage(*m_cmdBuffer, m_colorAttachment->getImage(),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &renderPassClearValue.color, 1, &subresourceRange);

	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
		VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
		VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
}

void MultiViewAttachmentsTestInstance::setImageData (VkImage image)
{
	const MovePtr<tcu::Texture2DArray>		data		= imageData();
	Move<VkBuffer>					buffer;
	const deUint32					bufferSize	= m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * tcu::getPixelSize(mapVkFormat(m_parameters.colorFormat));
	MovePtr<Allocation>				bufferAlloc;

	// Create source buffer
	{
		const VkBufferCreateInfo		bufferParams			=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			bufferSize,									// VkDeviceSize			size;
			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyIndexCount;
			&m_queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
		};

		buffer		= createBuffer(*m_device, *m_logicalDevice, &bufferParams);
		bufferAlloc = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible);
		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
	}

	// Barriers for copying buffer to image
	const VkBufferMemoryBarrier				preBufferBarrier		=
	{
		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType	sType;
		DE_NULL,										// const void*		pNext;
		VK_ACCESS_HOST_WRITE_BIT,						// VkAccessFlags	srcAccessMask;
		VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags	dstAccessMask;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
		*buffer,										// VkBuffer			buffer;
		0u,												// VkDeviceSize		offset;
		bufferSize										// VkDeviceSize		size;
	};

	const VkImageAspectFlags				formatAspect			= getAspectFlags(mapVkFormat(m_parameters.colorFormat));
	VkImageSubresourceRange					subresourceRange		=
	{												// VkImageSubresourceRange	subresourceRange;
		formatAspect,				// VkImageAspectFlags	aspect;
		0u,							// deUint32				baseMipLevel;
		1u,							// deUint32				mipLevels;
		0u,							// deUint32				baseArraySlice;
		m_parameters.extent.depth,	// deUint32				arraySize;
	};

	const VkBufferImageCopy					copyRegion				=
	{
		0u,															// VkDeviceSize				bufferOffset;
		(deUint32)data->getLevel(0).getWidth(),						// deUint32					bufferRowLength;
		(deUint32)data->getLevel(0).getHeight(),					// deUint32					bufferImageHeight;
		{
			VK_IMAGE_ASPECT_COLOR_BIT,								// VkImageAspectFlags		aspect;
			0u,														// deUint32					mipLevel;
			0u,														// deUint32					baseArrayLayer;
			m_parameters.extent.depth,								// deUint32					layerCount;
		},															// VkImageSubresourceLayers	imageSubresource;
		{ 0, 0, 0 },												// VkOffset3D				imageOffset;
		{m_parameters.extent.width, m_parameters.extent.height, 1u}	// VkExtent3D				imageExtent;
	};

	// Write buffer data
	deMemcpy(bufferAlloc->getHostPtr(), data->getLevel(0).getDataPtr(), bufferSize);
	flushMappedMemoryRange(*m_device, *m_logicalDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);

	beginCommandBuffer(*m_device, *m_cmdBuffer);

	m_device->cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
	imageBarrier(*m_device, *m_cmdBuffer, image, subresourceRange,
		VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
		0u, VK_ACCESS_TRANSFER_WRITE_BIT,
		VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
	m_device->cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
	imageBarrier(*m_device, *m_cmdBuffer, image, subresourceRange,
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
		VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
		VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));

	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
}

class MultiViewInstancedTestInstance : public MultiViewRenderTestInstance
{
public:
						MultiViewInstancedTestInstance	(Context& context, const TestParameters& parameters);
protected:
	void				createVertexData				(void);
	void				draw							(const deUint32			subpassCount,
														 VkRenderPass			renderPass,
														 VkFramebuffer			frameBuffer,
														 vector<PipelineSp>&	pipelines);
};

MultiViewInstancedTestInstance::MultiViewInstancedTestInstance (Context& context, const TestParameters& parameters)
	: MultiViewRenderTestInstance	(context, parameters)
{
}

void MultiViewInstancedTestInstance::createVertexData (void)
{
	const tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f);

	appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
}

void MultiViewInstancedTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
{
	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
	const VkRenderPassBeginInfo		renderPassBeginInfo		=
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
		DE_NULL,									// const void*			pNext;
		renderPass,									// VkRenderPass			renderPass;
		frameBuffer,								// VkFramebuffer		framebuffer;
		renderArea,									// VkRect2D				renderArea;
		1u,											// uint32_t				clearValueCount;
		&renderPassClearValue,						// const VkClearValue*	pClearValues;
	};

	beginCommandBuffer(*m_device, *m_cmdBuffer);

	beforeDraw();

	cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);

	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);

	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
	{
		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);

		m_device->cmdDraw(*m_cmdBuffer, 4u, drawCountPerSubpass, 0u, subpassNdx % m_squareCount);

		if (subpassNdx < subpassCount - 1u)
			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
	}

	cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);

	afterDraw();

	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
}

class MultiViewInputRateInstanceTestInstance : public MultiViewRenderTestInstance
{
public:
				MultiViewInputRateInstanceTestInstance	(Context& context, const TestParameters& parameters);
protected:
	void		createVertexData						(void);

	void		draw									(const deUint32			subpassCount,
														 VkRenderPass			renderPass,
														 VkFramebuffer			frameBuffer,
														 vector<PipelineSp>&	pipelines);
};

MultiViewInputRateInstanceTestInstance::MultiViewInputRateInstanceTestInstance (Context& context, const TestParameters& parameters)
	: MultiViewRenderTestInstance	(context, parameters)
{
}

void MultiViewInputRateInstanceTestInstance::createVertexData (void)
{
	appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f));
	appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f));
	appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f));
	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f));
}

void MultiViewInputRateInstanceTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
{
	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
	const VkRenderPassBeginInfo		renderPassBeginInfo		=
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
		DE_NULL,									// const void*			pNext;
		renderPass,									// VkRenderPass			renderPass;
		frameBuffer,								// VkFramebuffer		framebuffer;
		renderArea,									// VkRect2D				renderArea;
		1u,											// uint32_t				clearValueCount;
		&renderPassClearValue,						// const VkClearValue*	pClearValues;
	};

	beginCommandBuffer(*m_device, *m_cmdBuffer);

	beforeDraw();

	cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);

	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);

	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
	{
		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);

		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
			m_device->cmdDraw(*m_cmdBuffer, 4u, 4u, 0u, 0u);

		if (subpassNdx < subpassCount - 1u)
			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
	}

	cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);

	afterDraw();

	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
}

class MultiViewDrawIndirectTestInstance : public MultiViewRenderTestInstance
{
public:
				MultiViewDrawIndirectTestInstance	(Context& context, const TestParameters& parameters);
protected:

	void		draw								(const deUint32			subpassCount,
													 VkRenderPass			renderPass,
													 VkFramebuffer			frameBuffer,
													 vector<PipelineSp>&	pipelines);
};

MultiViewDrawIndirectTestInstance::MultiViewDrawIndirectTestInstance (Context& context, const TestParameters& parameters)
	: MultiViewRenderTestInstance	(context, parameters)
{
}

void MultiViewDrawIndirectTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
{
	typedef de::SharedPtr<Unique<VkBuffer> >		BufferSP;
	typedef de::SharedPtr<UniquePtr<Allocation> >	AllocationSP;

	const size_t					nonCoherentAtomSize		= static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize);
	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
	const deUint32					strideInBuffer			= (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
															? static_cast<deUint32>(sizeof(vk::VkDrawIndexedIndirectCommand))
															: static_cast<deUint32>(sizeof(vk::VkDrawIndirectCommand));
	vector< BufferSP >				indirectBuffers			(subpassCount);
	vector< AllocationSP >			indirectAllocations		(subpassCount);

	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
	{
		vector<VkDrawIndirectCommand>			drawCommands;
		vector<VkDrawIndexedIndirectCommand>	drawCommandsIndexed;

		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
		{
			if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
			{
				const VkDrawIndexedIndirectCommand	drawCommandIndexed	=
				{
					4u,												//  deUint32	indexCount;
					1u,												//  deUint32	instanceCount;
					(drawNdx + subpassNdx % m_squareCount) * 4u,	//  deUint32	firstIndex;
					0u,												//  deInt32		vertexOffset;
					0u,												//  deUint32	firstInstance;
				};

				drawCommandsIndexed.push_back(drawCommandIndexed);
			}
			else
			{
				const VkDrawIndirectCommand	drawCommand	=
				{
					4u,												//  deUint32	vertexCount;
					1u,												//  deUint32	instanceCount;
					(drawNdx + subpassNdx % m_squareCount) * 4u,	//  deUint32	firstVertex;
					0u												//  deUint32	firstInstance;
				};

				drawCommands.push_back(drawCommand);
			}
		}

		const size_t				drawCommandsLength	= (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
														? drawCommandsIndexed.size()
														: drawCommands.size();
		const void*					drawCommandsDataPtr	= (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
														? (void*)&drawCommandsIndexed[0]
														: (void*)&drawCommands[0];
		const size_t				dataSize			= static_cast<size_t>(drawCommandsLength * strideInBuffer);
		const VkDeviceSize			bufferDataSize		= static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize));
		const VkBufferCreateInfo	bufferInfo			= makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
		Move<VkBuffer>				indirectBuffer		= createBuffer(*m_device, *m_logicalDevice, &bufferInfo);
		MovePtr<Allocation>			allocationBuffer	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *indirectBuffer),  MemoryRequirement::HostVisible);

		DE_ASSERT(drawCommandsLength != 0);

		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *indirectBuffer, allocationBuffer->getMemory(), allocationBuffer->getOffset()));

		deMemcpy(allocationBuffer->getHostPtr(), drawCommandsDataPtr, static_cast<size_t>(dataSize));

		flushMappedMemoryRange(*m_device, *m_logicalDevice, allocationBuffer->getMemory(), allocationBuffer->getOffset(), static_cast<size_t>(bufferDataSize));
		indirectBuffers[subpassNdx] = (BufferSP(new Unique<VkBuffer>(indirectBuffer)));
		indirectAllocations[subpassNdx] = (AllocationSP(new UniquePtr<Allocation>(allocationBuffer)));
	}

	const VkRenderPassBeginInfo		renderPassBeginInfo		=
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
		DE_NULL,									// const void*			pNext;
		renderPass,									// VkRenderPass			renderPass;
		frameBuffer,								// VkFramebuffer		framebuffer;
		renderArea,									// VkRect2D				renderArea;
		1u,											// uint32_t				clearValueCount;
		&renderPassClearValue,						// const VkClearValue*	pClearValues;
	};

	beginCommandBuffer(*m_device, *m_cmdBuffer);

	beforeDraw();

	cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);

	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);

	if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
		m_device->cmdBindIndexBuffer(*m_cmdBuffer, *m_vertexIndicesBuffer, 0u, VK_INDEX_TYPE_UINT32);

	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
	{
		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);

		if (m_hasMultiDrawIndirect)
		{
			if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
				m_device->cmdDrawIndexedIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], 0u, drawCountPerSubpass, strideInBuffer);
			else
				m_device->cmdDrawIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], 0u, drawCountPerSubpass, strideInBuffer);
		}
		else
		{
			for (deUint32 drawNdx = 0; drawNdx < drawCountPerSubpass; drawNdx++)
			{
				if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
					m_device->cmdDrawIndexedIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], drawNdx * strideInBuffer, 1, strideInBuffer);
				else
					m_device->cmdDrawIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], drawNdx * strideInBuffer, 1, strideInBuffer);
			}
		}

		if (subpassNdx < subpassCount - 1u)
			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
	}

	cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);

	afterDraw();

	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
}

class MultiViewClearAttachmentsTestInstance : public MultiViewRenderTestInstance
{
public:
				MultiViewClearAttachmentsTestInstance	(Context& context, const TestParameters& parameters);
protected:
	void		draw									(const deUint32			subpassCount,
														 VkRenderPass			renderPass,
														 VkFramebuffer			frameBuffer,
														 vector<PipelineSp>&	pipelines);
};

MultiViewClearAttachmentsTestInstance::MultiViewClearAttachmentsTestInstance (Context& context, const TestParameters& parameters)
	: MultiViewRenderTestInstance	(context, parameters)
{
}

void MultiViewClearAttachmentsTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
{
	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;

	const VkRenderPassBeginInfo		renderPassBeginInfo		=
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
		DE_NULL,									// const void*			pNext;
		renderPass,									// VkRenderPass			renderPass;
		frameBuffer,								// VkFramebuffer		framebuffer;
		renderArea,									// VkRect2D				renderArea;
		1u,											// uint32_t				clearValueCount;
		&renderPassClearValue,						// const VkClearValue*	pClearValues;
	};

	beginCommandBuffer(*m_device, *m_cmdBuffer);

	beforeDraw();

	cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);

	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);

	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
	{
		VkClearAttachment	clearAttachment	=
		{
			VK_IMAGE_ASPECT_COLOR_BIT,								// VkImageAspectFlags	aspectMask
			0u,														// deUint32				colorAttachment
			makeClearValueColor(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f))	// VkClearValue			clearValue
		};

		const VkOffset2D	offset[2]		=
		{
			{0, 0},
			{static_cast<deInt32>(static_cast<float>(m_parameters.extent.width) * 0.25f), static_cast<deInt32>(static_cast<float>(m_parameters.extent.height) * 0.25f)}
		};

		const VkExtent2D	extent[2]		=
		{
			{m_parameters.extent.width, m_parameters.extent.height},
			{static_cast<deUint32>(static_cast<float>(m_parameters.extent.width) * 0.5f), static_cast<deUint32>(static_cast<float>(m_parameters.extent.height) * 0.5f)}
		};

		const VkRect2D		rect2D[2]		=
		{
			{offset[0], extent[0]},
			{offset[1], extent[1]}
		};

		VkClearRect			clearRect		=
		{
			rect2D[0],	// VkRect2D	rect
			0u,			// deUint32	baseArrayLayer
			1u,			// deUint32	layerCount
		};

		m_device->cmdClearAttachments(*m_cmdBuffer, 1u, &clearAttachment, 1u, &clearRect);
		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);

		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
			m_device->cmdDraw(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u);

		clearRect.rect = rect2D[1];
		clearAttachment.clearValue = makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
		m_device->cmdClearAttachments(*m_cmdBuffer, 1u, &clearAttachment, 1u, &clearRect);

		if (subpassNdx < subpassCount - 1u)
			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
	}

	cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);

	afterDraw();

	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
}

class MultiViewSecondaryCommandBufferTestInstance : public MultiViewRenderTestInstance
{
public:
				MultiViewSecondaryCommandBufferTestInstance	(Context& context, const TestParameters& parameters);
protected:
	void		draw										(const deUint32			subpassCount,
															 VkRenderPass			renderPass,
															 VkFramebuffer			frameBuffer,
															 vector<PipelineSp>&	pipelines);
};

MultiViewSecondaryCommandBufferTestInstance::MultiViewSecondaryCommandBufferTestInstance (Context& context, const TestParameters& parameters)
	: MultiViewRenderTestInstance	(context, parameters)
{
}

void MultiViewSecondaryCommandBufferTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
{
	typedef de::SharedPtr<Unique<VkCommandBuffer> >	VkCommandBufferSp;

	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
	const VkRenderPassBeginInfo		renderPassBeginInfo		=
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
		DE_NULL,									// const void*			pNext;
		renderPass,									// VkRenderPass			renderPass;
		frameBuffer,								// VkFramebuffer		framebuffer;
		renderArea,									// VkRect2D				renderArea;
		1u,											// uint32_t				clearValueCount;
		&renderPassClearValue,						// const VkClearValue*	pClearValues;
	};

	beginCommandBuffer(*m_device, *m_cmdBuffer);

	beforeDraw();

	cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, m_parameters.renderPassType);

	//Create secondary buffer
	const VkCommandBufferAllocateInfo	cmdBufferAllocateInfo	=
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
		DE_NULL,										// const void*				pNext;
		*m_cmdPool,										// VkCommandPool			commandPool;
		VK_COMMAND_BUFFER_LEVEL_SECONDARY,				// VkCommandBufferLevel		level;
		1u,												// deUint32					bufferCount;
	};
	vector<VkCommandBufferSp>	cmdBufferSecondary;

	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
	{
		cmdBufferSecondary.push_back(VkCommandBufferSp(new Unique<VkCommandBuffer>(allocateCommandBuffer(*m_device, *m_logicalDevice, &cmdBufferAllocateInfo))));

		beginSecondaryCommandBuffer(*m_device, cmdBufferSecondary.back().get()->get(), renderPass, subpassNdx, frameBuffer);
		m_device->cmdBindVertexBuffers(cmdBufferSecondary.back().get()->get(), 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
		m_device->cmdBindPipeline(cmdBufferSecondary.back().get()->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);

		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
			m_device->cmdDraw(cmdBufferSecondary.back().get()->get(), 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u);

		VK_CHECK(m_device->endCommandBuffer(cmdBufferSecondary.back().get()->get()));

		m_device->cmdExecuteCommands(*m_cmdBuffer, 1u, &cmdBufferSecondary.back().get()->get());
		if (subpassNdx < subpassCount - 1u)
			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, m_parameters.renderPassType);
	}

	cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);

	afterDraw();

	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
}

class MultiViewPointSizeTestInstance : public MultiViewRenderTestInstance
{
public:
				MultiViewPointSizeTestInstance	(Context& context, const TestParameters& parameters);
protected:
	void		validatePointSize				(const VkPhysicalDeviceLimits& limits, const deUint32 pointSize);
	void		createVertexData				(void);
	void		draw							(const deUint32			subpassCount,
												 VkRenderPass			renderPass,
												 VkFramebuffer			frameBuffer,
												 vector<PipelineSp>&	pipelines);
};

MultiViewPointSizeTestInstance::MultiViewPointSizeTestInstance (Context& context, const TestParameters& parameters)
	: MultiViewRenderTestInstance	(context, parameters)
{
	const InstanceInterface&		vki					= m_context.getInstanceInterface();
	const VkPhysicalDevice			physDevice			= m_context.getPhysicalDevice();
	const VkPhysicalDeviceLimits	limits				= getPhysicalDeviceProperties(vki, physDevice).limits;

	validatePointSize(limits, static_cast<deUint32>(TEST_POINT_SIZE_WIDE));
	validatePointSize(limits, static_cast<deUint32>(TEST_POINT_SIZE_SMALL));
}

void MultiViewPointSizeTestInstance::validatePointSize (const VkPhysicalDeviceLimits& limits, const deUint32 pointSize)
{
	const float	testPointSizeFloat	= static_cast<float>(pointSize);
	float		granuleCount		= 0.0f;

	if (!de::inRange(testPointSizeFloat, limits.pointSizeRange[0], limits.pointSizeRange[1]))
		TCU_THROW(NotSupportedError, "Required point size is outside of the the limits range");

	granuleCount = static_cast<float>(deCeilFloatToInt32((testPointSizeFloat - limits.pointSizeRange[0]) / limits.pointSizeGranularity));

	if (limits.pointSizeRange[0] + granuleCount * limits.pointSizeGranularity != testPointSizeFloat)
		TCU_THROW(NotSupportedError, "Granuliraty does not allow to get required point size");

	DE_ASSERT(pointSize + 1 <= m_parameters.extent.width / 2);
	DE_ASSERT(pointSize + 1 <= m_parameters.extent.height / 2);
}

void MultiViewPointSizeTestInstance::createVertexData (void)
{
	const float		pixelStepX	= 2.0f / static_cast<float>(m_parameters.extent.width);
	const float		pixelStepY	= 2.0f / static_cast<float>(m_parameters.extent.height);
	const int		pointMargin	= 1 + TEST_POINT_SIZE_WIDE / 2;

	appendVertex(tcu::Vec4(-1.0f + pointMargin * pixelStepX,-1.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
	appendVertex(tcu::Vec4(-1.0f + pointMargin * pixelStepX, 0.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
	appendVertex(tcu::Vec4( 0.0f + pointMargin * pixelStepX,-1.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
	appendVertex(tcu::Vec4( 0.0f + pointMargin * pixelStepX, 0.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(1.0f, 0.5f, 0.3f, 1.0f));
}

void MultiViewPointSizeTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
{
	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;

	const VkRenderPassBeginInfo		renderPassBeginInfo		=
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
		DE_NULL,									// const void*			pNext;
		renderPass,									// VkRenderPass			renderPass;
		frameBuffer,								// VkFramebuffer		framebuffer;
		renderArea,									// VkRect2D				renderArea;
		1u,											// uint32_t				clearValueCount;
		&renderPassClearValue,						// const VkClearValue*	pClearValues;
	};

	beginCommandBuffer(*m_device, *m_cmdBuffer);

	beforeDraw();

	cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);

	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);

	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
	{
		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);

		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
			m_device->cmdDraw(*m_cmdBuffer, 1u, 1u, drawNdx + subpassNdx % m_squareCount, 0u);

		if (subpassNdx < subpassCount - 1u)
			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
	}

	cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);

	afterDraw();

	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
}

class MultiViewMultsampleTestInstance : public MultiViewRenderTestInstance
{
public:
					MultiViewMultsampleTestInstance	(Context& context, const TestParameters& parameters);
protected:
	tcu::TestStatus	iterate							(void);
	void			createVertexData				(void);

	void			draw							(const deUint32			subpassCount,
													 VkRenderPass			renderPass,
													 VkFramebuffer			frameBuffer,
													 vector<PipelineSp>&	pipelines);
	void			afterDraw						(void);
private:
	de::SharedPtr<ImageAttachment>	m_resolveAttachment;
};

MultiViewMultsampleTestInstance::MultiViewMultsampleTestInstance (Context& context, const TestParameters& parameters)
	: MultiViewRenderTestInstance	(context, parameters)
{
	// Color attachment
	m_resolveAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat, VK_SAMPLE_COUNT_1_BIT));
}

tcu::TestStatus MultiViewMultsampleTestInstance::iterate (void)
{
	const deUint32								subpassCount				= static_cast<deUint32>(m_parameters.viewMasks.size());

	// FrameBuffer & renderPass
	Unique<VkRenderPass>						renderPass					(makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderPassType, VK_SAMPLE_COUNT_4_BIT));

	Unique<VkFramebuffer>						frameBuffer					(makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height));

	// pipelineLayout
	Unique<VkPipelineLayout>					pipelineLayout				(makePipelineLayout(*m_device, *m_logicalDevice));

	// pipelines
	map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
	vector<PipelineSp>							pipelines(subpassCount);
	const VkVertexInputRate						vertexInputRate				= (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;

	{
		vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;
		madeShaderModule(shaderModule, shaderStageParams);
		for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
			pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx, vertexInputRate))));
	}

	createCommandBuffer();
	createVertexData();
	createVertexBuffer();

	draw(subpassCount, *renderPass, *frameBuffer, pipelines);

	{
		vector<deUint8>			pixelAccessData	(m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
		tcu::PixelBufferAccess	dst				(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());

		readImage(m_resolveAttachment->getImage(), dst);

		if (!checkImage(dst))
			return tcu::TestStatus::fail("Fail");
	}

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

void MultiViewMultsampleTestInstance::createVertexData (void)
{
	tcu::Vec4	color	= tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);

	color	= tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
	appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color);

	color	= tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
	appendVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);

	color	= tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 1.0f,-1.0f, 1.0f, 1.0f), color);

	color	= tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
	appendVertex(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color);
}

void MultiViewMultsampleTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
{
	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
	const deUint32					vertexPerPrimitive		= 3u;
	const VkImageSubresourceLayers	subresourceLayer		=
	{
		VK_IMAGE_ASPECT_COLOR_BIT,	//  VkImageAspectFlags	aspectMask;
		0u,							//  deUint32			mipLevel;
		0u,							//  deUint32			baseArrayLayer;
		m_parameters.extent.depth,	//  deUint32			layerCount;
	};
	const VkImageResolve			imageResolveRegion		=
	{
		subresourceLayer,															//  VkImageSubresourceLayers	srcSubresource;
		makeOffset3D(0, 0, 0),														//  VkOffset3D					srcOffset;
		subresourceLayer,															//  VkImageSubresourceLayers	dstSubresource;
		makeOffset3D(0, 0, 0),														//  VkOffset3D					dstOffset;
		makeExtent3D(m_parameters.extent.width, m_parameters.extent.height, 1u),	//  VkExtent3D					extent;
	};

	const VkRenderPassBeginInfo		renderPassBeginInfo		=
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
		DE_NULL,									// const void*			pNext;
		renderPass,									// VkRenderPass			renderPass;
		frameBuffer,								// VkFramebuffer		framebuffer;
		renderArea,									// VkRect2D				renderArea;
		1u,											// uint32_t				clearValueCount;
		&renderPassClearValue,						// const VkClearValue*	pClearValues;
	};

	beginCommandBuffer(*m_device, *m_cmdBuffer);

	beforeDraw();

	cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);

	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);

	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
	{
		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);

		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
			m_device->cmdDraw(*m_cmdBuffer, vertexPerPrimitive, 1u, (drawNdx + subpassNdx % m_squareCount) * vertexPerPrimitive, 0u);

		if (subpassNdx < subpassCount - 1u)
			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
	}

	cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);

	afterDraw();

	m_device->cmdResolveImage(*m_cmdBuffer, m_colorAttachment->getImage(), VK_IMAGE_LAYOUT_GENERAL, m_resolveAttachment->getImage(), VK_IMAGE_LAYOUT_GENERAL, 1u, &imageResolveRegion);

	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
}

void MultiViewMultsampleTestInstance::afterDraw (void)
{
	const VkImageSubresourceRange	subresourceRange		=
	{
		VK_IMAGE_ASPECT_COLOR_BIT,	//  VkImageAspectFlags	aspectMask;
		0u,							//  deUint32			baseMipLevel;
		1u,							//  deUint32			levelCount;
		0u,							//  deUint32			baseArrayLayer;
		m_parameters.extent.depth,	//  deUint32			layerCount;
	};

	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
		VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);

	imageBarrier(*m_device, *m_cmdBuffer, m_resolveAttachment->getImage(), subresourceRange,
		VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
		0u, VK_ACCESS_TRANSFER_WRITE_BIT,
		VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
}

class MultiViewQueriesTestInstance : public MultiViewRenderTestInstance
{
public:
						MultiViewQueriesTestInstance	(Context& context, const TestParameters& parameters);
protected:
	tcu::TestStatus		iterate							(void);
	void				createVertexData				(void);

	void				draw							(const deUint32			subpassCount,
														 VkRenderPass			renderPass,
														 VkFramebuffer			frameBuffer,
														 vector<PipelineSp>&	pipelines);
	deUint32			getUsedViewsCount				(const deUint32			viewMaskIndex);
	deUint32			getQueryCountersNumber			();
private:
	const deUint32		m_verticesPerPrimitive;
	deUint64			m_timestampMask;
	vector<deUint64>	m_timestampStartValues;
	vector<deUint64>	m_timestampEndValues;
	vector<deBool>		m_counterSeriesStart;
	vector<deBool>		m_counterSeriesEnd;
	vector<deUint64>	m_occlusionValues;
	vector<deUint64>	m_occlusionExpectedValues;
	deUint32			m_occlusionObjectsOffset;
	vector<deUint64>	m_occlusionObjectPixelsCount;
};

MultiViewQueriesTestInstance::MultiViewQueriesTestInstance (Context& context, const TestParameters& parameters)
	: MultiViewRenderTestInstance	(context, parameters)
	, m_verticesPerPrimitive(4u)
{
	// Generate the timestamp mask
	const std::vector<VkQueueFamilyProperties>	queueProperties = vk::getPhysicalDeviceQueueFamilyProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice());

	if(queueProperties[0].timestampValidBits == 0)
		TCU_THROW(NotSupportedError, "Device does not support timestamp.");

	m_timestampMask = 0xFFFFFFFFFFFFFFFFull >> (64 - queueProperties[0].timestampValidBits);
}

tcu::TestStatus MultiViewQueriesTestInstance::iterate (void)
{
	const deUint32								subpassCount			= static_cast<deUint32>(m_parameters.viewMasks.size());
	Unique<VkRenderPass>						renderPass				(makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderPassType));
	Unique<VkFramebuffer>						frameBuffer				(makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height));
	Unique<VkPipelineLayout>					pipelineLayout			(makePipelineLayout(*m_device, *m_logicalDevice));
	vector<PipelineSp>							pipelines				(subpassCount);
	deUint64									occlusionValue			= 0;
	deUint64									occlusionExpectedValue	= 0;
	map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;

	{
		vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;

		madeShaderModule(shaderModule, shaderStageParams);
		for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
			pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx))));
	}

	createCommandBuffer();
	createVertexData();
	createVertexBuffer();

	draw(subpassCount, *renderPass, *frameBuffer, pipelines);

	DE_ASSERT(!m_occlusionValues.empty());
	DE_ASSERT(m_occlusionValues.size() == m_occlusionExpectedValues.size());
	DE_ASSERT(m_occlusionValues.size() == m_counterSeriesEnd.size());
	for (size_t ndx = 0; ndx < m_counterSeriesEnd.size(); ++ndx)
	{
		occlusionValue			+= m_occlusionValues[ndx];
		occlusionExpectedValue	+= m_occlusionExpectedValues[ndx];

		if (m_counterSeriesEnd[ndx])
			if (occlusionExpectedValue != occlusionValue)
				return tcu::TestStatus::fail("occlusion, result:" + de::toString(occlusionValue) + ", expected:" + de::toString(occlusionExpectedValue));
	}

	DE_ASSERT(!m_timestampStartValues.empty());
	DE_ASSERT(m_timestampStartValues.size() == m_timestampEndValues.size());
	DE_ASSERT(m_timestampStartValues.size() == m_counterSeriesStart.size());
	for (size_t ndx = 0; ndx < m_timestampStartValues.size(); ++ndx)
	{
		if (m_counterSeriesStart[ndx])
		{
			if (m_timestampEndValues[ndx] > 0 && m_timestampEndValues[ndx] >= m_timestampStartValues[ndx])
				continue;
		}
		else
		{
			if (m_timestampEndValues[ndx] > 0 && m_timestampEndValues[ndx] >= m_timestampStartValues[ndx])
				continue;

			if (m_timestampEndValues[ndx] == 0 && m_timestampStartValues[ndx] == 0)
				continue;
		}

		return tcu::TestStatus::fail("timestamp");
	}

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

void MultiViewQueriesTestInstance::createVertexData (void)
{
	tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f);

	appendVertex(tcu::Vec4(-1.0f,-1.0f, 0.0f, 1.0f), color);
	appendVertex(tcu::Vec4(-1.0f, 0.0f, 0.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f,-1.0f, 0.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color);

	color = tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f);
	appendVertex(tcu::Vec4(-1.0f, 0.0f, 0.0f, 1.0f), color);
	appendVertex(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f), color);

	color = tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f);
	appendVertex(tcu::Vec4( 0.0f,-1.0f, 0.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 1.0f,-1.0f, 0.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 1.0f, 0.0f, 0.0f, 1.0f), color);

	color = tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 1.0f, 0.0f, 0.0f, 1.0f), color);
	appendVertex(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), color);

	// Create occluded square objects as zoom out of main
	const deUint32	mainObjectsVerticesCount		= static_cast<deUint32>(m_vertexCoord.size());
	const deUint32	mainObjectsCount				= mainObjectsVerticesCount / m_verticesPerPrimitive;
	const deUint32	occlusionObjectMultiplierX[]	= { 1, 2, 2, 1 };
	const deUint32	occlusionObjectMultiplierY[]	= { 1, 1, 3, 3 };
	const deUint32	occlusionObjectDivisor			= 4u;
	const float		occlusionObjectDivisorFloat		= static_cast<float>(occlusionObjectDivisor);

	DE_ASSERT(0 == m_parameters.extent.width  % (2 * occlusionObjectDivisor));
	DE_ASSERT(0 == m_parameters.extent.height % (2 * occlusionObjectDivisor));
	DE_ASSERT(DE_LENGTH_OF_ARRAY(occlusionObjectMultiplierX) == mainObjectsCount);
	DE_ASSERT(DE_LENGTH_OF_ARRAY(occlusionObjectMultiplierY) == mainObjectsCount);

	for (size_t objectNdx = 0; objectNdx < mainObjectsCount; ++objectNdx)
	{
		const size_t	objectStart			= objectNdx * m_verticesPerPrimitive;
		const float		xRatio				= static_cast<float>(occlusionObjectMultiplierX[objectNdx]) / occlusionObjectDivisorFloat;
		const float		yRatio				= static_cast<float>(occlusionObjectMultiplierY[objectNdx]) / occlusionObjectDivisorFloat;
		const double	areaRatio			= static_cast<double>(xRatio) * static_cast<double>(yRatio);
		const deUint64	occludedPixelsCount	= static_cast<deUint64>(areaRatio * (m_parameters.extent.width / 2) * (m_parameters.extent.height / 2));

		m_occlusionObjectPixelsCount.push_back(occludedPixelsCount);

		for (size_t vertexNdx = 0; vertexNdx < m_verticesPerPrimitive; ++vertexNdx)
		{
			const float		occludedObjectVertexXCoord	= m_vertexCoord[objectStart + vertexNdx][0] * xRatio;
			const float		occludedObjectVertexYCoord	= m_vertexCoord[objectStart + vertexNdx][1] * yRatio;
			const tcu::Vec4	occludedObjectVertexCoord	= tcu::Vec4(occludedObjectVertexXCoord, occludedObjectVertexYCoord, 1.0f, 1.0f);

			appendVertex(occludedObjectVertexCoord, m_vertexColor[objectStart + vertexNdx]);
		}
	}

	m_occlusionObjectsOffset = mainObjectsVerticesCount;
}

void MultiViewQueriesTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
{
	const VkRect2D				renderArea						= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
	const VkClearValue			renderPassClearValue			= makeClearValueColor(tcu::Vec4(0.0f));
	const VkBuffer				vertexBuffers[]					= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
	const VkDeviceSize			vertexBufferOffsets[]			= {                   0u,                   0u };
	const deUint32				drawCountPerSubpass				= (subpassCount == 1) ? m_squareCount : 1u;
	const deUint32				queryCountersNumber				= (subpassCount == 1) ? m_squareCount * getUsedViewsCount(0) : getQueryCountersNumber();
	const VkRenderPassBeginInfo	renderPassBeginInfo				=
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	//  VkStructureType		sType;
		DE_NULL,									//  const void*			pNext;
		renderPass,									//  VkRenderPass		renderPass;
		frameBuffer,								//  VkFramebuffer		framebuffer;
		renderArea,									//  VkRect2D			renderArea;
		1u,											//  uint32_t			clearValueCount;
		&renderPassClearValue,						//  const VkClearValue*	pClearValues;
	};
	const VkQueryPoolCreateInfo	occlusionQueryPoolCreateInfo	=
	{
		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,	//  VkStructureType					sType;
		DE_NULL,									//  const void*						pNext;
		(VkQueryPoolCreateFlags)0,					//  VkQueryPoolCreateFlags			flags;
		VK_QUERY_TYPE_OCCLUSION,					//  VkQueryType						queryType;
		queryCountersNumber,						//  deUint32						queryCount;
		0u,											//  VkQueryPipelineStatisticFlags	pipelineStatistics;
	};
	const VkQueryPoolCreateInfo	timestampQueryPoolCreateInfo	=
	{
		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,	//  VkStructureType					sType;
		DE_NULL,									//  const void*						pNext;
		(VkQueryPoolCreateFlags)0,					//  VkQueryPoolCreateFlags			flags;
		VK_QUERY_TYPE_TIMESTAMP,					//  VkQueryType						queryType;
		queryCountersNumber,						//  deUint32						queryCount;
		0u,											//  VkQueryPipelineStatisticFlags	pipelineStatistics;
	};
	const Unique<VkQueryPool>	occlusionQueryPool				(createQueryPool(*m_device, *m_logicalDevice, &occlusionQueryPoolCreateInfo));
	const Unique<VkQueryPool>	timestampStartQueryPool			(createQueryPool(*m_device, *m_logicalDevice, &timestampQueryPoolCreateInfo));
	const Unique<VkQueryPool>	timestampEndQueryPool			(createQueryPool(*m_device, *m_logicalDevice, &timestampQueryPoolCreateInfo));
	VkQueryControlFlags			occlusionQueryFlags				= VK_QUERY_CONTROL_PRECISE_BIT;
	deUint32					queryStartIndex					= 0;

	beginCommandBuffer(*m_device, *m_cmdBuffer);

	beforeDraw();

	// Query pools must be reset before use
	m_device->cmdResetQueryPool(*m_cmdBuffer, *occlusionQueryPool, queryStartIndex, queryCountersNumber);
	m_device->cmdResetQueryPool(*m_cmdBuffer, *timestampStartQueryPool, queryStartIndex, queryCountersNumber);
	m_device->cmdResetQueryPool(*m_cmdBuffer, *timestampEndQueryPool, queryStartIndex, queryCountersNumber);

	cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);

	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);

	m_occlusionExpectedValues.reserve(queryCountersNumber);
	m_counterSeriesStart.reserve(queryCountersNumber);
	m_counterSeriesEnd.reserve(queryCountersNumber);

	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
	{
		deUint32	queryCountersToUse	= getUsedViewsCount(subpassNdx);

		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);

		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
		{
			const deUint32 primitiveNumber	= drawNdx + subpassNdx % m_squareCount;
			const deUint32 firstVertex		= primitiveNumber * m_verticesPerPrimitive;

			m_device->cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, *timestampStartQueryPool, queryStartIndex);
			{
				m_device->cmdDraw(*m_cmdBuffer, m_verticesPerPrimitive, 1u, firstVertex, 0u);

				// Render occluded object
				m_device->cmdBeginQuery(*m_cmdBuffer, *occlusionQueryPool, queryStartIndex, occlusionQueryFlags);
				m_device->cmdDraw(*m_cmdBuffer, m_verticesPerPrimitive, 1u, m_occlusionObjectsOffset + firstVertex, 0u);
				m_device->cmdEndQuery(*m_cmdBuffer, *occlusionQueryPool, queryStartIndex);

				for (deUint32 viewMaskNdx = 0; viewMaskNdx < queryCountersToUse; ++viewMaskNdx)
				{
					m_occlusionExpectedValues.push_back(m_occlusionObjectPixelsCount[primitiveNumber]);
					m_counterSeriesStart.push_back(viewMaskNdx == 0);
					m_counterSeriesEnd.push_back(viewMaskNdx + 1 == queryCountersToUse);
				}
			}
			m_device->cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, *timestampEndQueryPool, queryStartIndex);

			queryStartIndex += queryCountersToUse;
		}

		if (subpassNdx < subpassCount - 1u)
			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
	}

	DE_ASSERT(queryStartIndex == queryCountersNumber);

	cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);

	afterDraw();

	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);

	m_occlusionValues.resize(queryCountersNumber, 0ull);
	m_device->getQueryPoolResults(*m_logicalDevice, *occlusionQueryPool, 0u, queryCountersNumber, sizeof(deUint64) * queryCountersNumber, (void*)&m_occlusionValues[0], sizeof(deUint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);

	m_timestampStartValues.resize(queryCountersNumber, 0ull);
	m_device->getQueryPoolResults(*m_logicalDevice, *timestampStartQueryPool, 0u, queryCountersNumber, sizeof(deUint64) * queryCountersNumber, (void*)&m_timestampStartValues[0], sizeof(deUint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
	for (deUint32 ndx = 0; ndx < m_timestampStartValues.size(); ++ndx)
		m_timestampStartValues[ndx] &= m_timestampMask;

	m_timestampEndValues.resize(queryCountersNumber, 0ull);
	m_device->getQueryPoolResults(*m_logicalDevice, *timestampEndQueryPool, 0u, queryCountersNumber, sizeof(deUint64) * queryCountersNumber, (void*)&m_timestampEndValues[0], sizeof(deUint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
	for (deUint32 ndx = 0; ndx < m_timestampEndValues.size(); ++ndx)
		m_timestampEndValues[ndx] &= m_timestampMask;
}

deUint32 MultiViewQueriesTestInstance::getUsedViewsCount (const deUint32 viewMaskIndex)
{
	deUint32 result = 0;

	for (deUint32 viewMask = m_parameters.viewMasks[viewMaskIndex]; viewMask != 0; viewMask >>= 1)
		if ((viewMask & 1) != 0)
			result++;

	return result;
}

deUint32 MultiViewQueriesTestInstance::getQueryCountersNumber ()
{
	deUint32 result = 0;

	for (deUint32 i = 0; i < m_parameters.viewMasks.size(); ++i)
		result += getUsedViewsCount(i);

	return result;
}

class MultiViewReadbackTestInstance : public MultiViewRenderTestInstance
{
public:
						MultiViewReadbackTestInstance	(Context& context, const TestParameters& parameters);
protected:
	tcu::TestStatus		iterate							(void);
	void				drawClears						(const deUint32				subpassCount,
														 VkRenderPass				renderPass,
														 VkFramebuffer				frameBuffer,
														 vector<PipelineSp>&		pipelines,
														 const bool					clearPass);
	void				clear							(const VkCommandBuffer		commandBuffer,
														 const VkRect2D&			clearRect2D,
														 const tcu::Vec4&			clearColor);
private:
	vector<VkRect2D>	m_quarters;
};

MultiViewReadbackTestInstance::MultiViewReadbackTestInstance (Context& context, const TestParameters& parameters)
	: MultiViewRenderTestInstance	(context, parameters)
{
	const deUint32 halfWidth	= m_parameters.extent.width / 2;
	const deUint32 halfHeight	= m_parameters.extent.height / 2;

	for (deInt32 x = 0; x < 2; ++x)
	for (deInt32 y = 0; y < 2; ++y)
	{
		const deInt32	offsetX	= static_cast<deInt32>(halfWidth) * x;
		const deInt32	offsetY	= static_cast<deInt32>(halfHeight) * y;
		const VkRect2D	area	= { { offsetX, offsetY}, {halfWidth, halfHeight} };

		m_quarters.push_back(area);
	}
}

tcu::TestStatus MultiViewReadbackTestInstance::iterate (void)
{
	const deUint32	subpassCount	= static_cast<deUint32>(m_parameters.viewMasks.size());

	createCommandBuffer();

	for (deUint32 pass = 0; pass < 2; ++pass)
	{
		const bool									fullClearPass	= (pass == 0);
		const VkAttachmentLoadOp					loadOp			= (!fullClearPass) ? VK_ATTACHMENT_LOAD_OP_LOAD :
																	  (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR) ? VK_ATTACHMENT_LOAD_OP_CLEAR :
																	  (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR) ? VK_ATTACHMENT_LOAD_OP_DONT_CARE :
																	  VK_ATTACHMENT_LOAD_OP_LAST;
		Unique<VkRenderPass>						renderPass		(makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderPassType, VK_SAMPLE_COUNT_1_BIT, loadOp));
		Unique<VkFramebuffer>						frameBuffer		(makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height));
		Unique<VkPipelineLayout>					pipelineLayout	(makePipelineLayout(*m_device, *m_logicalDevice));
		vector<PipelineSp>							pipelines		(subpassCount);
		map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;

		{
			vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;
			madeShaderModule(shaderModule, shaderStageParams);
			for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
				pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx))));
		}

		drawClears(subpassCount, *renderPass, *frameBuffer, pipelines, fullClearPass);
	}

	{
		vector<deUint8>			pixelAccessData	(m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
		tcu::PixelBufferAccess	dst				(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());

		readImage(m_colorAttachment->getImage(), dst);

		if (!checkImage(dst))
			return tcu::TestStatus::fail("Fail");
	}

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

void MultiViewReadbackTestInstance::drawClears (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines, const bool clearPass)
{
	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
	const VkClearValue				renderPassClearValue	= makeClearValueColor(m_colorTable[0]);
	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
	const bool						withClearColor			= (clearPass && m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR);
	const VkRenderPassBeginInfo		renderPassBeginInfo		=
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,			//  VkStructureType		sType;
		DE_NULL,											//  const void*			pNext;
		renderPass,											//  VkRenderPass		renderPass;
		frameBuffer,										//  VkFramebuffer		framebuffer;
		renderArea,											//  VkRect2D			renderArea;
		withClearColor ? 1u : 0u,							//  uint32_t			clearValueCount;
		withClearColor ? &renderPassClearValue : DE_NULL,	//  const VkClearValue*	pClearValues;
	};

	beginCommandBuffer(*m_device, *m_cmdBuffer);

	if (clearPass)
		beforeDraw();

	cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);

	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
	{
		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);

		if (clearPass)
		{
			if (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR)
				clear(*m_cmdBuffer, renderArea, m_colorTable[subpassNdx % 4]);
		}
		else
		{
			for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
			{
				const deUint32 primitiveNumber	= drawNdx + subpassNdx % m_squareCount;

				clear(*m_cmdBuffer, m_quarters[primitiveNumber], m_colorTable[4 + primitiveNumber]);
			}
		}

		if (subpassNdx < subpassCount - 1u)
			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
	}

	cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);

	if (!clearPass)
		afterDraw();

	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
}

void MultiViewReadbackTestInstance::clear (const VkCommandBuffer commandBuffer, const VkRect2D& clearRect2D, const tcu::Vec4& clearColor)
{
	const VkClearRect		clearRect		=
	{
		clearRect2D,						//  VkRect2D	rect
		0u,									//  deUint32	baseArrayLayer
		1u,									//  deUint32	layerCount
	};
	const VkClearAttachment	clearAttachment	=
	{
		VK_IMAGE_ASPECT_COLOR_BIT,			//  VkImageAspectFlags	aspectMask
		0u,									//  deUint32			colorAttachment
		makeClearValueColor(clearColor)		//  VkClearValue		clearValue
	};

	m_device->cmdClearAttachments(commandBuffer, 1u, &clearAttachment, 1u, &clearRect);
}

class MultiViewDepthStencilTestInstance : public MultiViewRenderTestInstance
{
public:
						MultiViewDepthStencilTestInstance	(Context& context, const TestParameters& parameters);
protected:
	tcu::TestStatus		iterate								(void);
	void				createVertexData					(void);

	void				draw								(const deUint32					subpassCount,
															 VkRenderPass					renderPass,
															 VkFramebuffer					frameBuffer,
															 vector<PipelineSp>&			pipelines);
	void				beforeDraw							(void);
	void				afterDraw							(void);
	vector<VkImageView>	makeAttachmentsVector				(void);
	void				readImage							(VkImage						image,
															 const tcu::PixelBufferAccess&	dst);
private:
	VkFormat						m_dsFormat;
	de::SharedPtr<ImageAttachment>	m_dsAttachment;
	bool							m_depthTest;
	bool							m_stencilTest;
};

MultiViewDepthStencilTestInstance::MultiViewDepthStencilTestInstance (Context& context, const TestParameters& parameters)
	: MultiViewRenderTestInstance	(context, parameters)
	, m_dsFormat					(VK_FORMAT_UNDEFINED)
	, m_depthTest					(m_parameters.viewIndex == TEST_TYPE_DEPTH)
	, m_stencilTest					(m_parameters.viewIndex == TEST_TYPE_STENCIL)
{
	const VkFormat formats[] = { VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT };

	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(formats); ++ndx)
	{
		const VkFormat				format				= formats[ndx];
		const VkFormatProperties	formatProperties	= getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);

		if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
		{
			m_dsFormat = format;

			break;
		}
	}

	if (m_dsFormat == VK_FORMAT_UNDEFINED)
		TCU_FAIL("Supported depth/stencil format not found, that violates specification");

	// Depth/stencil attachment
	m_dsAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_dsFormat));
}

vector<VkImageView>	MultiViewDepthStencilTestInstance::makeAttachmentsVector (void)
{
	vector<VkImageView> attachments;

	attachments.push_back(m_colorAttachment->getImageView());
	attachments.push_back(m_dsAttachment->getImageView());

	return attachments;
}

void MultiViewDepthStencilTestInstance::readImage (VkImage image, const tcu::PixelBufferAccess& dst)
{
	const VkFormat				bufferFormat	= m_depthTest ? getDepthBufferFormat(m_dsFormat) :
												  m_stencilTest ? getStencilBufferFormat(m_dsFormat) :
												  VK_FORMAT_UNDEFINED;
	const deUint32				imagePixelSize	= static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(bufferFormat)));
	const VkDeviceSize			pixelDataSize	= dst.getWidth() * dst.getHeight() * dst.getDepth() * imagePixelSize;
	const tcu::TextureFormat	tcuBufferFormat	= mapVkFormat(bufferFormat);
	Move<VkBuffer>				buffer;
	MovePtr<Allocation>			bufferAlloc;

	// Create destination buffer
	{
		const VkBufferCreateInfo bufferParams	=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			0u,										// VkBufferCreateFlags	flags;
			pixelDataSize,							// VkDeviceSize			size;
			VK_BUFFER_USAGE_TRANSFER_DST_BIT,		// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyIndexCount;
			&m_queueFamilyIndex,					// const deUint32*		pQueueFamilyIndices;
		};

		buffer		= createBuffer(*m_device, *m_logicalDevice, &bufferParams);
		bufferAlloc	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible);
		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));

		deMemset(bufferAlloc->getHostPtr(), 0xCC, static_cast<size_t>(pixelDataSize));
		flushMappedMemoryRange(*m_device, *m_logicalDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
	}

	const VkBufferMemoryBarrier	bufferBarrier	=
	{
		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,					// deUint32			srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
		*buffer,									// VkBuffer			buffer;
		0u,											// VkDeviceSize		offset;
		pixelDataSize								// VkDeviceSize		size;
	};

	// Copy image to buffer
	const VkImageAspectFlags	aspect			= m_depthTest ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT) :
												  m_stencilTest ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_STENCIL_BIT) :
												  static_cast<VkImageAspectFlags>(0u);
	const VkBufferImageCopy		copyRegion		=
	{
		0u,											// VkDeviceSize				bufferOffset;
		(deUint32)dst.getWidth(),					// deUint32					bufferRowLength;
		(deUint32)dst.getHeight(),					// deUint32					bufferImageHeight;
		{
			aspect,									// VkImageAspectFlags		aspect;
			0u,										// deUint32					mipLevel;
			0u,										// deUint32					baseArrayLayer;
			m_parameters.extent.depth,				// deUint32					layerCount;
		},											// VkImageSubresourceLayers	imageSubresource;
		{ 0, 0, 0 },								// VkOffset3D				imageOffset;
		{											// VkExtent3D				imageExtent;
			m_parameters.extent.width,
			m_parameters.extent.height,
			1u
		}
	};

	beginCommandBuffer (*m_device, *m_cmdBuffer);
	{
		m_device->cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
		m_device->cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0u, DE_NULL);
	}
	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);

	// Read buffer data
	invalidateMappedMemoryRange(*m_device, *m_logicalDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);

	if (m_depthTest)
	{
		// Translate depth into color space
		tcu::ConstPixelBufferAccess	pixelBuffer	(tcuBufferFormat, dst.getSize(), bufferAlloc->getHostPtr());

		for (int z = 0; z < pixelBuffer.getDepth(); z++)
		for (int y = 0; y < pixelBuffer.getHeight(); y++)
		for (int x = 0; x < pixelBuffer.getWidth(); x++)
		{
			const float		depth	= pixelBuffer.getPixDepth(x, y, z);
			const tcu::Vec4	color	= tcu::Vec4(depth, 0.0f, 0.0f, 1.0f);

			dst.setPixel(color, x, y, z);
		}
	}

	if (m_stencilTest)
	{
		// Translate stencil into color space
		tcu::ConstPixelBufferAccess	pixelBuffer	(tcuBufferFormat, dst.getSize(), bufferAlloc->getHostPtr());
		const tcu::Vec4				baseColor		= getQuarterRefColor(0u, 0u, 0u, false);
		const tcu::Vec4				colorStep		= getQuarterRefColor(0u, 0u, 0u, true);
		const tcu::Vec4				colorMap[4]		=
		{
			baseColor,
			tcu::Vec4(1.0f * colorStep[0], 0.0f, 0.0f, 1.0),
			tcu::Vec4(2.0f * colorStep[0], 0.0f, 0.0f, 1.0),
			tcu::Vec4(3.0f * colorStep[0], 0.0f, 0.0f, 1.0),
		};
		const tcu::Vec4				invalidColor	= tcu::Vec4(0.0f);

		for (int z = 0; z < pixelBuffer.getDepth(); z++)
		for (int y = 0; y < pixelBuffer.getHeight(); y++)
		for (int x = 0; x < pixelBuffer.getWidth(); x++)
		{
			const int			stencilInt	= pixelBuffer.getPixStencil(x, y, z);
			const tcu::Vec4&	color		= de::inRange(stencilInt, 0, DE_LENGTH_OF_ARRAY(colorMap)) ? colorMap[stencilInt] : invalidColor;

			dst.setPixel(color, x, y, z);
		}
	}

}

tcu::TestStatus MultiViewDepthStencilTestInstance::iterate (void)
{
	const deUint32								subpassCount				= static_cast<deUint32>(m_parameters.viewMasks.size());
	Unique<VkRenderPass>						renderPass					(makeRenderPassWithDepth (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_dsFormat, m_parameters.renderPassType));
	vector<VkImageView>							attachments					(makeAttachmentsVector());
	Unique<VkFramebuffer>						frameBuffer					(makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, static_cast<deUint32>(attachments.size()), attachments.data(), m_parameters.extent.width, m_parameters.extent.height, 1u));
	Unique<VkPipelineLayout>					pipelineLayout				(makePipelineLayout(*m_device, *m_logicalDevice));
	map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
	vector<PipelineSp>							pipelines(subpassCount);

	{
		vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;
		madeShaderModule(shaderModule, shaderStageParams);
		for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
			pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(),
				subpassNdx, VK_VERTEX_INPUT_RATE_VERTEX, m_depthTest, m_stencilTest))));
	}

	createCommandBuffer();
	createVertexData();
	createVertexBuffer();

	draw(subpassCount, *renderPass, *frameBuffer, pipelines);

	{
		vector<deUint8>			pixelAccessData	(m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
		tcu::PixelBufferAccess	dst				(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());

		readImage(m_dsAttachment->getImage(), dst);

		if (!checkImage(dst))
			return tcu::TestStatus::fail("Fail");
	}

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

void MultiViewDepthStencilTestInstance::createVertexData (void)
{
/*
	partA

	ViewMasks
	0011
	0110
	1100
	1001

	Layer3  Layer2  Layer1  Layer0
	  ^       ^       ^       ^
	00|10   00|10   01|00   01|00
	00|10   00|10   01|00   01|00
	--+-->  --+-->  --+-->  --+-->
	00|10   01|00   01|00   00|10
	00|10   01|00   01|00   00|10


	partB

	ViewMasks
	0110
	1100
	1001
	0011

	Layer3  Layer2  Layer1  Layer0
	  ^       ^       ^       ^
	00|00   00|00   00|00   00|00
	00|22   22|00   22|00   00|22
	--+-->  --+-->  --+-->  --+-->
	22|00   22|00   00|22   00|22
	00|00   00|00   00|00   00|00

	Final
	Layer3  Layer2  Layer1  Layer0
	  ^       ^       ^       ^
	00|10   00|10   01|00   01|00
	00|32   22|10   23|00   01|22
	--+-->  --+-->  --+-->  --+-->
	22|10   23|00   01|22   00|32
	00|10   01|00   01|00   00|10
*/
	tcu::Vec4	color	(0.0f, 0.0f, 0.0f, 1.0f); // is not essential in this test

	const tcu::Vec4	partAReference	= getQuarterRefColor(0u, 0u, 0u, true, 0u);
	const tcu::Vec4	partBReference	= getQuarterRefColor(0u, 0u, 0u, true, 4u);
	const float		depthA			= partAReference[0];
	const float		depthB			= partBReference[0];

	// part A
	appendVertex(tcu::Vec4(-1.0f,-0.5f, depthA, 1.0f), color);
	appendVertex(tcu::Vec4(-1.0f, 0.0f, depthA, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f,-0.5f, depthA, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, depthA, 1.0f), color);

	appendVertex(tcu::Vec4(-1.0f, 0.0f, depthA, 1.0f), color);
	appendVertex(tcu::Vec4(-1.0f, 0.5f, depthA, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, depthA, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 0.5f, depthA, 1.0f), color);

	appendVertex(tcu::Vec4( 0.0f,-0.5f, depthA, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, depthA, 1.0f), color);
	appendVertex(tcu::Vec4( 1.0f,-0.5f, depthA, 1.0f), color);
	appendVertex(tcu::Vec4( 1.0f, 0.0f, depthA, 1.0f), color);

	appendVertex(tcu::Vec4( 0.0f, 0.0f, depthA, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 0.5f, depthA, 1.0f), color);
	appendVertex(tcu::Vec4( 1.0f, 0.0f, depthA, 1.0f), color);
	appendVertex(tcu::Vec4( 1.0f, 0.5f, depthA, 1.0f), color);

	// part B
	appendVertex(tcu::Vec4(-0.5f,-1.0f, depthB, 1.0f), color);
	appendVertex(tcu::Vec4(-0.5f, 0.0f, depthB, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f,-1.0f, depthB, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, depthB, 1.0f), color);

	appendVertex(tcu::Vec4(-0.5f, 0.0f, depthB, 1.0f), color);
	appendVertex(tcu::Vec4(-0.5f, 1.0f, depthB, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, depthB, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 1.0f, depthB, 1.0f), color);

	appendVertex(tcu::Vec4( 0.0f,-1.0f, depthB, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 0.0f, depthB, 1.0f), color);
	appendVertex(tcu::Vec4( 0.5f,-1.0f, depthB, 1.0f), color);
	appendVertex(tcu::Vec4( 0.5f, 0.0f, depthB, 1.0f), color);

	appendVertex(tcu::Vec4( 0.0f, 0.0f, depthB, 1.0f), color);
	appendVertex(tcu::Vec4( 0.0f, 1.0f, depthB, 1.0f), color);
	appendVertex(tcu::Vec4( 0.5f, 0.0f, depthB, 1.0f), color);
	appendVertex(tcu::Vec4( 0.5f, 1.0f, depthB, 1.0f), color);
}

void MultiViewDepthStencilTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
{
	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
	const deUint32					vertexPerPrimitive		= 4u;
	const VkRenderPassBeginInfo		renderPassBeginInfo		=
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
		DE_NULL,									// const void*			pNext;
		renderPass,									// VkRenderPass			renderPass;
		frameBuffer,								// VkFramebuffer		framebuffer;
		renderArea,									// VkRect2D				renderArea;
		1u,											// uint32_t				clearValueCount;
		&renderPassClearValue,						// const VkClearValue*	pClearValues;
	};

	beginCommandBuffer(*m_device, *m_cmdBuffer);

	beforeDraw();

	cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);

	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);

	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
	{
		deUint32 firstVertexOffset = (subpassNdx < 4) ? 0u : m_squareCount * vertexPerPrimitive;

		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);

		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
			m_device->cmdDraw(*m_cmdBuffer, vertexPerPrimitive, 1u, firstVertexOffset + (drawNdx + subpassNdx % m_squareCount) * vertexPerPrimitive, 0u);

		if (subpassNdx < subpassCount - 1u)
			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
	}

	cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);

	afterDraw();

	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
}

void MultiViewDepthStencilTestInstance::beforeDraw (void)
{
	MultiViewRenderTestInstance::beforeDraw();

	const VkImageSubresourceRange	subresourceRange		=
	{
		VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,	//VkImageAspectFlags	aspectMask;
		0u,															//deUint32				baseMipLevel;
		1u,															//deUint32				levelCount;
		0u,															//deUint32				baseArrayLayer;
		m_parameters.extent.depth,									//deUint32				layerCount;
	};
	imageBarrier(*m_device, *m_cmdBuffer, m_dsAttachment->getImage(), subresourceRange,
		VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
		0, 0,
		VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);

	const tcu::Vec4		baseColor	= getQuarterRefColor(0u, 0u, 0u, false);
	const float			clearDepth	= baseColor[0];
	const VkClearValue	clearValue	= makeClearValueDepthStencil(clearDepth, 0);

	m_device->cmdClearDepthStencilImage(*m_cmdBuffer, m_dsAttachment->getImage(),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.depthStencil, 1, &subresourceRange);

	imageBarrier(*m_device, *m_cmdBuffer, m_dsAttachment->getImage(), subresourceRange,
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
		VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
		VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
}

void MultiViewDepthStencilTestInstance::afterDraw (void)
{
	MultiViewRenderTestInstance::afterDraw();

	const VkImageSubresourceRange	dsSubresourceRange		=
	{
		VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,	//  VkImageAspectFlags	aspectMask;
		0u,															//  deUint32			baseMipLevel;
		1u,															//  deUint32			levelCount;
		0u,															//  deUint32			baseArrayLayer;
		m_parameters.extent.depth,									//  deUint32			layerCount;
	};

	imageBarrier(*m_device, *m_cmdBuffer, m_dsAttachment->getImage(), dsSubresourceRange,
		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
		VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
		VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
}

class MultiViewRenderTestsCase : public vkt::TestCase
{
public:
	MultiViewRenderTestsCase (tcu::TestContext &context, const char *name, const char *description, const TestParameters& parameters)
		: TestCase			(context, name, description)
		, m_parameters		(parameters)
	{
		DE_ASSERT(m_parameters.extent.width == m_parameters.extent.height);
	}
private:
	const TestParameters	m_parameters;

	vkt::TestInstance*	createInstance		(vkt::Context& context) const
	{
		if (TEST_TYPE_INPUT_ATTACHMENTS == m_parameters.viewIndex ||
			TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY == m_parameters.viewIndex)
			return new MultiViewAttachmentsTestInstance(context, m_parameters);

		if (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex)
			return new MultiViewInstancedTestInstance(context, m_parameters);

		if (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
			return new MultiViewInputRateInstanceTestInstance(context, m_parameters);

		if (TEST_TYPE_DRAW_INDIRECT == m_parameters.viewIndex ||
			TEST_TYPE_DRAW_INDIRECT_INDEXED == m_parameters.viewIndex)
			return new MultiViewDrawIndirectTestInstance(context, m_parameters);

		if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex)
			return new MultiViewClearAttachmentsTestInstance(context, m_parameters);

		if (TEST_TYPE_SECONDARY_CMD_BUFFER == m_parameters.viewIndex ||
			TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY == m_parameters.viewIndex)
			return new MultiViewSecondaryCommandBufferTestInstance(context, m_parameters);

		if (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex)
			return new MultiViewPointSizeTestInstance(context, m_parameters);

		if (TEST_TYPE_MULTISAMPLE == m_parameters.viewIndex)
			return new MultiViewMultsampleTestInstance(context, m_parameters);

		if (TEST_TYPE_QUERIES == m_parameters.viewIndex)
			return new MultiViewQueriesTestInstance(context, m_parameters);

		if (TEST_TYPE_VIEW_MASK == m_parameters.viewIndex ||
			TEST_TYPE_VIEW_INDEX_IN_VERTEX == m_parameters.viewIndex ||
			TEST_TYPE_VIEW_INDEX_IN_FRAGMENT == m_parameters.viewIndex ||
			TEST_TYPE_VIEW_INDEX_IN_GEOMETRY == m_parameters.viewIndex ||
			TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex ||
			TEST_TYPE_DRAW_INDEXED == m_parameters.viewIndex)
			return new MultiViewRenderTestInstance(context, m_parameters);

		if (TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR == m_parameters.viewIndex ||
			TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR == m_parameters.viewIndex)
			return new MultiViewReadbackTestInstance(context, m_parameters);

		if (TEST_TYPE_DEPTH == m_parameters.viewIndex ||
			TEST_TYPE_STENCIL == m_parameters.viewIndex)
			return new MultiViewDepthStencilTestInstance(context, m_parameters);

		TCU_THROW(InternalError, "Unknown test type");
	}

	void				initPrograms		(SourceCollections& programCollection) const
	{
		// Create vertex shader
		if (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex)
		{
			std::ostringstream source;
			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
					<< "#extension GL_EXT_multiview : enable\n"
					<< "layout(location = 0) in highp vec4 in_position;\n"
					<< "layout(location = 1) in vec4 in_color;\n"
					<< "layout(location = 0) out vec4 out_color;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	int modInstance = gl_InstanceIndex % 4;\n"
					<< "	int instance    = gl_InstanceIndex + 1;\n"
					<< "	gl_Position = in_position;\n"
					<< "	if (modInstance == 1)\n"
					<< "		gl_Position = in_position + vec4(0.0f, 1.0f, 0.0f, 0.0f);\n"
					<< "	if (modInstance == 2)\n"
					<< "		gl_Position = in_position + vec4(1.0f, 0.0f, 0.0f, 0.0f);\n"
					<< "	if (modInstance == 3)\n"
					<< "		gl_Position =  in_position + vec4(1.0f, 1.0f, 0.0f, 0.0f);\n"
					<< "	out_color = in_color + vec4(0.0f, gl_ViewIndex * 0.10f, instance * 0.10f, 0.0f);\n"
					<< "}\n";
			programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
		}
		else if (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
		{
			std::ostringstream source;
			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
					<< "#extension GL_EXT_multiview : enable\n"
					<< "layout(location = 0) in highp vec4 in_position;\n"
					<< "layout(location = 1) in vec4 in_color;\n"
					<< "layout(location = 0) out vec4 out_color;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	int instance = gl_InstanceIndex + 1;\n"
					<< "	gl_Position = in_position;\n"
					<< "	if (gl_VertexIndex == 1)\n"
					<< "		gl_Position.y += 1.0f;\n"
					<< "	else if (gl_VertexIndex == 2)\n"
					<< "		gl_Position.x += 1.0f;\n"
					<< "	else if (gl_VertexIndex == 3)\n"
					<< "	{\n"
					<< "		gl_Position.x += 1.0f;\n"
					<< "		gl_Position.y += 1.0f;\n"
					<< "	}\n"
					<< "	out_color = in_color + vec4(0.0f, gl_ViewIndex * 0.10f, instance * 0.10f, 0.0f);\n"
					<< "}\n";
			programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
		}
		else if (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex)
		{
			std::ostringstream source;
			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
					<< "#extension GL_EXT_multiview : enable\n"
					<< "layout(location = 0) in highp vec4 in_position;\n"
					<< "layout(location = 1) in highp vec4 in_color;\n"
					<< "layout(location = 0) out vec4 out_color;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	gl_Position = in_position;\n"
					<< "	if (gl_ViewIndex == 0)\n"
					<< "		gl_PointSize = " << de::floatToString(static_cast<float>(TEST_POINT_SIZE_WIDE), 1) << "f;\n"
					<< "	else\n"
					<< "		gl_PointSize = " << de::floatToString(static_cast<float>(TEST_POINT_SIZE_SMALL), 1) << "f;\n"
					<< "	out_color = in_color;\n"
					<< "}\n";
			programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
		}
		else
		{
			const bool generateColor	=  (TEST_TYPE_VIEW_INDEX_IN_VERTEX == m_parameters.viewIndex)
										|| (TEST_TYPE_DRAW_INDIRECT == m_parameters.viewIndex)
										|| (TEST_TYPE_DRAW_INDIRECT_INDEXED == m_parameters.viewIndex)
										|| (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex);
			std::ostringstream source;
			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
					<< "#extension GL_EXT_multiview : enable\n"
					<< "layout(location = 0) in highp vec4 in_position;\n"
					<< "layout(location = 1) in vec4 in_color;\n"
					<< "layout(location = 0) out vec4 out_color;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	gl_Position = in_position;\n";
				if (generateColor)
					source << "	out_color = in_color + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n";
				else
					source << "	out_color = in_color;\n";
			source	<< "}\n";
			programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
		}

		if (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex)
		{// Tessellation control & evaluation
			std::ostringstream source_tc;
			source_tc	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
						<< "#extension GL_EXT_multiview : enable\n"
						<< "#extension GL_EXT_tessellation_shader : require\n"
						<< "layout(vertices = 4) out;\n"
						<< "layout(location = 0) in vec4 in_color[];\n"
						<< "layout(location = 0) out vec4 out_color[];\n"
						<< "\n"
						<< "void main (void)\n"
						<< "{\n"
						<< "	if ( gl_InvocationID == 0 )\n"
						<< "	{\n"
						<< "		gl_TessLevelInner[0] = 4.0f;\n"
						<< "		gl_TessLevelInner[1] = 4.0f;\n"
						<< "		gl_TessLevelOuter[0] = 4.0f;\n"
						<< "		gl_TessLevelOuter[1] = 4.0f;\n"
						<< "		gl_TessLevelOuter[2] = 4.0f;\n"
						<< "		gl_TessLevelOuter[3] = 4.0f;\n"
						<< "	}\n"
						<< "	out_color[gl_InvocationID] = in_color[gl_InvocationID];\n"
						<< "	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
						<< "}\n";
			programCollection.glslSources.add("tessellation_control") << glu::TessellationControlSource(source_tc.str());

			std::ostringstream source_te;
			source_te	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
						<< "#extension GL_EXT_multiview : enable\n"
						<< "#extension GL_EXT_tessellation_shader : require\n"
						<< "layout( quads, equal_spacing, ccw ) in;\n"
						<< "layout(location = 0) in vec4 in_color[];\n"
						<< "layout(location = 0) out vec4 out_color;\n"
						<< "void main (void)\n"
						<< "{\n"
						<< "	const float u = gl_TessCoord.x;\n"
						<< "	const float v = gl_TessCoord.y;\n"
						<< "	const float w = gl_TessCoord.z;\n"
						<< "	gl_Position = (1 - u) * (1 - v) * gl_in[0].gl_Position +(1 - u) * v * gl_in[1].gl_Position + u * (1 - v) * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position;\n"
						<< "	out_color = in_color[0]+ vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
						<< "}\n";
			programCollection.glslSources.add("tessellation_evaluation") << glu::TessellationEvaluationSource(source_te.str());
		}

		if (TEST_TYPE_VIEW_INDEX_IN_GEOMETRY		== m_parameters.viewIndex ||
			TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY	== m_parameters.viewIndex ||
			TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY	== m_parameters.viewIndex)
		{// Geometry Shader
			std::ostringstream	source;
			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
					<< "#extension GL_EXT_multiview : enable\n"
					<< "layout(triangles) in;\n"
					<< "layout(triangle_strip, max_vertices = 16) out;\n"
					<< "layout(location = 0) in vec4 in_color[];\n"
					<< "layout(location = 0) out vec4 out_color;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
					<< "	gl_Position = gl_in[0].gl_Position;\n"
					<< "	EmitVertex();\n"
					<< "	out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
					<< "	gl_Position = gl_in[1].gl_Position;\n"
					<< "	EmitVertex();\n"
					<< "	out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
					<< "	gl_Position = gl_in[2].gl_Position;\n"
					<< "	EmitVertex();\n"
					<< "	out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
					<< "	gl_Position = vec4(gl_in[2].gl_Position.x, gl_in[1].gl_Position.y, 1.0, 1.0);\n"
					<< "	EmitVertex();\n"
					<< "	EndPrimitive();\n"
					<< "}\n";
			programCollection.glslSources.add("geometry") << glu::GeometrySource(source.str());
		}

		if (TEST_TYPE_INPUT_ATTACHMENTS == m_parameters.viewIndex)
		{// Create fragment shader read/write attachment
			std::ostringstream source;
			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
					<< "#extension GL_EXT_multiview : enable\n"
					<< "layout(location = 0) in vec4 in_color;\n"
					<< "layout(location = 0) out vec4 out_color;\n"
					<< "layout(input_attachment_index = 0, set=0, binding=0) uniform highp subpassInput in_color_attachment;\n"
					<< "void main()\n"
					<<"{\n"
					<< "	out_color = vec4(subpassLoad(in_color_attachment));\n"
					<< "}\n";
			programCollection.glslSources.add("fragment") << glu::FragmentSource(source.str());
		}
		else
		{// Create fragment shader
			std::ostringstream source;
			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
					<< "#extension GL_EXT_multiview : enable\n"
					<< "layout(location = 0) in vec4 in_color;\n"
					<< "layout(location = 0) out vec4 out_color;\n"
					<< "void main()\n"
					<<"{\n";
				if (TEST_TYPE_VIEW_INDEX_IN_FRAGMENT == m_parameters.viewIndex ||
					TEST_TYPE_SECONDARY_CMD_BUFFER == m_parameters.viewIndex)
					source << "	out_color = in_color + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n";
				else
					source << "	out_color = in_color;\n";
			source	<< "}\n";
			programCollection.glslSources.add("fragment") << glu::FragmentSource(source.str());
		}
	}
};
} //anonymous

static std::string createViewMasksName(const std::vector<deUint32>& viewMasks)
{
	std::ostringstream		masks;

	for (size_t ndx = 0u; ndx < viewMasks.size(); ++ndx)
	{
		masks << viewMasks[ndx];
		if (viewMasks.size() - 1 != ndx)
			masks << "_";
	}

	return masks.str();
}

static std::vector<deUint32> tripleDepthStencilMasks(std::vector<deUint32>& baseMasks)
{
	std::vector<deUint32> tripledMasks(baseMasks);
	std::vector<deUint32> partBMasks;

	// a,b,c,d  =>  b,c,d,a
	partBMasks.insert(partBMasks.end(), baseMasks.begin() + 1, baseMasks.end());
	partBMasks.push_back(baseMasks[0]);

	tripledMasks.insert(tripledMasks.end(), partBMasks.begin(), partBMasks.end());
	tripledMasks.insert(tripledMasks.end(), partBMasks.begin(), partBMasks.end());

	return tripledMasks;
}

void multiViewRenderCreateTests (tcu::TestCaseGroup* group)
{
	const deUint32				testCaseCount				= 7u;
	const string				shaderName[TEST_TYPE_LAST]	=
	{
		"masks",
		"vertex_shader",
		"fragment_shader",
		"geometry_shader",
		"tesellation_shader",
		"input_attachments",
		"input_attachments_geometry",
		"instanced",
		"input_instance",
		"draw_indirect",
		"draw_indirect_indexed",
		"draw_indexed",
		"clear_attachments",
		"secondary_cmd_buffer",
		"secondary_cmd_buffer_geometry",
		"point_size",
		"multisample",
		"queries",
		"readback_implicit_clear",
		"readback_explicit_clear",
		"depth",
		"stencil",
	};
	const VkExtent3D			extent3D[testCaseCount]		=
	{
		{16u,	16u,	4u},
		{64u,	64u,	8u},
		{128u,	128u,	4u},
		{32u,	32u,	5u},
		{64u,	64u,	6u},
		{32u,	32u,	4u},
		{16u,	16u,	10u},
	};
	vector<deUint32>			viewMasks[testCaseCount];

	viewMasks[0].push_back(15u);	//1111

	viewMasks[1].push_back(8u);		//1000

	viewMasks[2].push_back(1u);		//0001
	viewMasks[2].push_back(2u);		//0010
	viewMasks[2].push_back(4u);		//0100
	viewMasks[2].push_back(8u);		//1000

	viewMasks[3].push_back(15u);	//1111
	viewMasks[3].push_back(15u);	//1111
	viewMasks[3].push_back(15u);	//1111
	viewMasks[3].push_back(15u);	//1111

	viewMasks[4].push_back(8u);		//1000
	viewMasks[4].push_back(1u);		//0001
	viewMasks[4].push_back(1u);		//0001
	viewMasks[4].push_back(8u);		//1000

	viewMasks[5].push_back(5u);		//0101
	viewMasks[5].push_back(10u);	//1010
	viewMasks[5].push_back(5u);		//0101
	viewMasks[5].push_back(10u);	//1010

	const deUint32 minSupportedMultiviewViewCount	= 6u;
	const deUint32 maxViewMask						= (1u << minSupportedMultiviewViewCount) - 1u;

	for (deUint32 mask = 1u; mask <= maxViewMask; mask = mask << 1u)
		viewMasks[testCaseCount - 1].push_back(mask);

	vector<deUint32>			depthStencilMasks;

	depthStencilMasks.push_back(3u);	// 0011
	depthStencilMasks.push_back(6u);	// 0110
	depthStencilMasks.push_back(12u);	// 1100
	depthStencilMasks.push_back(9u);	// 1001

	for (int renderPassTypeNdx = 0; renderPassTypeNdx < 2; ++renderPassTypeNdx)
	{
		RenderPassType				renderPassType		((renderPassTypeNdx == 0) ? RENDERPASS_TYPE_LEGACY : RENDERPASS_TYPE_RENDERPASS2);
		MovePtr<tcu::TestCaseGroup>	groupRenderPass2	((renderPassTypeNdx == 0) ? DE_NULL : new tcu::TestCaseGroup(group->getTestContext(), "renderpass2", "RenderPass2 index tests"));
		tcu::TestCaseGroup*			targetGroup			((renderPassTypeNdx == 0) ? group : groupRenderPass2.get());
		tcu::TestContext&			testCtx				(targetGroup->getTestContext());
		MovePtr<tcu::TestCaseGroup>	groupViewIndex		(new tcu::TestCaseGroup(testCtx, "index", "ViewIndex rendering tests."));

		for (int testTypeNdx = TEST_TYPE_VIEW_MASK; testTypeNdx < TEST_TYPE_LAST; ++testTypeNdx)
		{
			MovePtr<tcu::TestCaseGroup>	groupShader			(new tcu::TestCaseGroup(testCtx, shaderName[testTypeNdx].c_str(), ""));
			const TestType				testType			= static_cast<TestType>(testTypeNdx);
			const VkSampleCountFlagBits	sampleCountFlags	= (testType == TEST_TYPE_MULTISAMPLE) ? VK_SAMPLE_COUNT_4_BIT : VK_SAMPLE_COUNT_1_BIT;
			const VkFormat				colorFormat			= (testType == TEST_TYPE_MULTISAMPLE) ? VK_FORMAT_R32G32B32A32_SFLOAT : VK_FORMAT_R8G8B8A8_UNORM;

			if (testTypeNdx == TEST_TYPE_DEPTH || testTypeNdx == TEST_TYPE_STENCIL)
			{
				const VkExtent3D		dsTestExtent3D	= { 64u, 64u, 4u };
				const TestParameters	parameters		= { dsTestExtent3D, tripleDepthStencilMasks(depthStencilMasks), testType, sampleCountFlags, colorFormat, renderPassType };
				const std::string		testName		= createViewMasksName(parameters.viewMasks);

				groupShader->addChild(new MultiViewRenderTestsCase(testCtx, testName.c_str(), "", parameters));
			}
			else
			{
				for (deUint32 testCaseNdx = 0u; testCaseNdx < testCaseCount; ++testCaseNdx)
				{
					const TestParameters	parameters	=	{ extent3D[testCaseNdx], viewMasks[testCaseNdx], testType, sampleCountFlags, colorFormat, renderPassType };
					const std::string		testName	=	createViewMasksName(parameters.viewMasks);

					groupShader->addChild(new MultiViewRenderTestsCase(testCtx, testName.c_str(), "", parameters));
				}

				// maxMultiviewViewCount case
				{
					const VkExtent3D		incompleteExtent3D	= { 16u, 16u, 0u };
					const vector<deUint32>	dummyMasks;
					const TestParameters	parameters			= { incompleteExtent3D, dummyMasks, testType, sampleCountFlags, colorFormat, renderPassType };

					groupShader->addChild(new MultiViewRenderTestsCase(testCtx, "max_multi_view_view_count", "", parameters));
				}
			}

			switch (testType)
			{
				case TEST_TYPE_VIEW_MASK:
				case TEST_TYPE_INPUT_ATTACHMENTS:
				case TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY:
				case TEST_TYPE_INSTANCED_RENDERING:
				case TEST_TYPE_INPUT_RATE_INSTANCE:
				case TEST_TYPE_DRAW_INDIRECT:
				case TEST_TYPE_DRAW_INDIRECT_INDEXED:
				case TEST_TYPE_DRAW_INDEXED:
				case TEST_TYPE_CLEAR_ATTACHMENTS:
				case TEST_TYPE_SECONDARY_CMD_BUFFER:
				case TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY:
				case TEST_TYPE_POINT_SIZE:
				case TEST_TYPE_MULTISAMPLE:
				case TEST_TYPE_QUERIES:
				case TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR:
				case TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR:
				case TEST_TYPE_DEPTH:
				case TEST_TYPE_STENCIL:
					targetGroup->addChild(groupShader.release());
					break;
				case TEST_TYPE_VIEW_INDEX_IN_VERTEX:
				case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT:
				case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY:
				case TEST_TYPE_VIEW_INDEX_IN_TESELLATION:
					groupViewIndex->addChild(groupShader.release());
					break;
				default:
					DE_ASSERT(0);
					break;
			};
		}

		targetGroup->addChild(groupViewIndex.release());

		if (renderPassTypeNdx == 1)
			group->addChild(groupRenderPass2.release());
	}
}

} //MultiView
} //vkt

