/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 The Khronos Group Inc.
 * Copyright (c) 2015 Imagination Technologies Ltd.
 *
 * 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 Input Assembly Tests
 *//*--------------------------------------------------------------------*/

#include "vktPipelineInputAssemblyTests.hpp"
#include "vktPipelineClearUtil.hpp"
#include "vktPipelineImageUtil.hpp"
#include "vktPipelineVertexUtil.hpp"
#include "vktPipelineReferenceRenderer.hpp"
#include "vktTestCase.hpp"
#include "vkImageUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkPrograms.hpp"
#include "vkQueryUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include "tcuImageCompare.hpp"
#include "deMath.h"
#include "deMemory.h"
#include "deRandom.hpp"
#include "deStringUtil.hpp"
#include "deUniquePtr.hpp"

#include <algorithm>
#include <sstream>
#include <vector>

namespace vkt
{
namespace pipeline
{

using namespace vk;

namespace
{

class InputAssemblyTest : public vkt::TestCase
{
public:
	const static VkPrimitiveTopology	s_primitiveTopologies[];
	const static deUint32				s_restartIndex32;
	const static deUint16				s_restartIndex16;
    const static deUint8				s_restartIndex8;

										InputAssemblyTest		(tcu::TestContext&		testContext,
																 const std::string&		name,
																 const std::string&		description,
																 VkPrimitiveTopology	primitiveTopology,
																 int					primitiveCount,
																 bool					testPrimitiveRestart,
																 VkIndexType			indexType);
	virtual								~InputAssemblyTest		(void) {}
	virtual void						initPrograms			(SourceCollections& sourceCollections) const;
	virtual void						checkSupport			(Context& context) const;
	virtual TestInstance*				createInstance			(Context& context) const;
	static bool							isRestartIndex			(VkIndexType indexType, deUint32 indexValue);
	static deUint32						getRestartIndex			(VkIndexType indexType);

protected:
	virtual void						createBufferData		(VkPrimitiveTopology		topology,
																 int						primitiveCount,
																 VkIndexType				indexType,
																 std::vector<deUint32>&		indexData,
																 std::vector<Vertex4RGBA>&	vertexData) const = 0;

private:
	VkPrimitiveTopology					m_primitiveTopology;
	const int							m_primitiveCount;
	bool								m_testPrimitiveRestart;
	VkIndexType							m_indexType;
};

class PrimitiveTopologyTest : public InputAssemblyTest
{
public:
										PrimitiveTopologyTest	(tcu::TestContext&		testContext,
																 const std::string&		name,
																 const std::string&		description,
																 VkPrimitiveTopology	primitiveTopology,
																 VkIndexType			indexType);
	virtual								~PrimitiveTopologyTest	(void) {}

protected:
	virtual void						createBufferData		(VkPrimitiveTopology		topology,
																 int						primitiveCount,
																 VkIndexType				indexType,
																 std::vector<deUint32>&		indexData,
																 std::vector<Vertex4RGBA>&	vertexData) const;

private:
};

class PrimitiveRestartTest : public InputAssemblyTest
{
public:
										PrimitiveRestartTest	(tcu::TestContext&		testContext,
																 const std::string&		name,
																 const std::string&		description,
																 VkPrimitiveTopology	primitiveTopology,
																 VkIndexType			indexType);
	virtual								~PrimitiveRestartTest	(void) {}

protected:
	virtual void						createBufferData		(VkPrimitiveTopology		topology,
																 int						primitiveCount,
																 VkIndexType				indexType,
																 std::vector<deUint32>&		indexData,
																 std::vector<Vertex4RGBA>&	vertexData) const;

private:
	bool								isRestartPrimitive		(int primitiveIndex) const;

	std::vector<deUint32>				m_restartPrimitives;
};

class InputAssemblyInstance : public vkt::TestInstance
{
public:
										InputAssemblyInstance	(Context&							context,
																 VkPrimitiveTopology				primitiveTopology,
																 bool								testPrimitiveRestart,
																 VkIndexType						indexType,
																 const std::vector<deUint32>&		indexBufferData,
																 const std::vector<Vertex4RGBA>&	vertexBufferData);
	virtual								~InputAssemblyInstance	(void);
	virtual tcu::TestStatus				iterate					(void);

private:
	tcu::TestStatus						verifyImage				(void);
	void								uploadIndexBufferData16	(deUint16* destPtr, const std::vector<deUint32>& indexBufferData);
	void								uploadIndexBufferData8	(deUint8* destPtr, const std::vector<deUint32>& indexBufferData);

	VkPrimitiveTopology					m_primitiveTopology;
	bool								m_primitiveRestartEnable;
	VkIndexType							m_indexType;

	Move<VkBuffer>						m_vertexBuffer;
	std::vector<Vertex4RGBA>			m_vertices;
	de::MovePtr<Allocation>				m_vertexBufferAlloc;

	Move<VkBuffer>						m_indexBuffer;
	std::vector<deUint32>				m_indices;
	de::MovePtr<Allocation>				m_indexBufferAlloc;

	const tcu::UVec2					m_renderSize;

	const VkFormat						m_colorFormat;
	VkImageCreateInfo					m_colorImageCreateInfo;
	Move<VkImage>						m_colorImage;
	de::MovePtr<Allocation>				m_colorImageAlloc;
	Move<VkImageView>					m_colorAttachmentView;
	Move<VkRenderPass>					m_renderPass;
	Move<VkFramebuffer>					m_framebuffer;

	Move<VkShaderModule>				m_vertexShaderModule;
	Move<VkShaderModule>				m_fragmentShaderModule;

	Move<VkPipelineLayout>				m_pipelineLayout;
	Move<VkPipeline>					m_graphicsPipeline;

	Move<VkCommandPool>					m_cmdPool;
	Move<VkCommandBuffer>				m_cmdBuffer;
};


// InputAssemblyTest

const VkPrimitiveTopology InputAssemblyTest::s_primitiveTopologies[] =
{
	VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
	VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
	VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
	VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
	VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
	VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
	VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
	VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
	VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY,
	VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY
};

const deUint32 InputAssemblyTest::s_restartIndex32	= ~((deUint32)0u);
const deUint16 InputAssemblyTest::s_restartIndex16	= ~((deUint16)0u);
const deUint8 InputAssemblyTest::s_restartIndex8	= ~((deUint8)0u);

InputAssemblyTest::InputAssemblyTest (tcu::TestContext&		testContext,
									  const std::string&	name,
									  const std::string&	description,
									  VkPrimitiveTopology	primitiveTopology,
									  int					primitiveCount,
									  bool					testPrimitiveRestart,
									  VkIndexType			indexType)

	: vkt::TestCase				(testContext, name, description)
	, m_primitiveTopology		(primitiveTopology)
	, m_primitiveCount			(primitiveCount)
	, m_testPrimitiveRestart	(testPrimitiveRestart)
	, m_indexType				(indexType)
{
}

void InputAssemblyTest::checkSupport (Context& context) const
{
	if (m_indexType == VK_INDEX_TYPE_UINT8_EXT)
		context.requireDeviceFunctionality("VK_EXT_index_type_uint8");

	switch (m_primitiveTopology)
	{
		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
			context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
			break;

		case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
			context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
			break;

		default:
			break;
	}
}

TestInstance* InputAssemblyTest::createInstance (Context& context) const
{
	std::vector<deUint32>		indexBufferData;
	std::vector<Vertex4RGBA>	vertexBufferData;

	createBufferData(m_primitiveTopology, m_primitiveCount, m_indexType, indexBufferData, vertexBufferData);

	return new InputAssemblyInstance(context, m_primitiveTopology, m_testPrimitiveRestart, m_indexType, indexBufferData, vertexBufferData);
}

void InputAssemblyTest::initPrograms (SourceCollections& sourceCollections) const
{
	std::ostringstream vertexSource;

	vertexSource <<
		"#version 310 es\n"
		"layout(location = 0) in vec4 position;\n"
		"layout(location = 1) in vec4 color;\n"
		"layout(location = 0) out highp vec4 vtxColor;\n"
		"void main (void)\n"
		"{\n"
		"	gl_Position = position;\n"
		<< (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST ? "	gl_PointSize = 3.0;\n"
																	: "" )
		<< "	vtxColor = color;\n"
		"}\n";

	sourceCollections.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());

	sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(
		"#version 310 es\n"
		"layout(location = 0) in highp vec4 vtxColor;\n"
		"layout(location = 0) out highp vec4 fragColor;\n"
		"void main (void)\n"
		"{\n"
		"	fragColor = vtxColor;\n"
		"}\n");
}

bool InputAssemblyTest::isRestartIndex (VkIndexType indexType, deUint32 indexValue)
{
	if (indexType == VK_INDEX_TYPE_UINT16)
		return indexValue == s_restartIndex16;
	else if (indexType == VK_INDEX_TYPE_UINT8_EXT)
		return indexValue == s_restartIndex8;
	else
		return indexValue == s_restartIndex32;
}

deUint32 InputAssemblyTest::getRestartIndex (VkIndexType indexType)
{
	if (indexType == VK_INDEX_TYPE_UINT16)
		return InputAssemblyTest::s_restartIndex16;
	else if (indexType == VK_INDEX_TYPE_UINT8_EXT)
		return InputAssemblyTest::s_restartIndex8;
	else
		return InputAssemblyTest::s_restartIndex32;
}


// PrimitiveTopologyTest

PrimitiveTopologyTest::PrimitiveTopologyTest (tcu::TestContext&		testContext,
											  const std::string&	name,
											  const std::string&	description,
											  VkPrimitiveTopology	primitiveTopology,
											  VkIndexType			indexType)
	: InputAssemblyTest	(testContext, name, description, primitiveTopology, 10, false, indexType)
{
}

void PrimitiveTopologyTest::createBufferData (VkPrimitiveTopology topology, int primitiveCount, VkIndexType indexType, std::vector<deUint32>& indexData, std::vector<Vertex4RGBA>& vertexData) const
{
	DE_ASSERT(primitiveCount > 0);
	DE_UNREF(indexType);

	const tcu::Vec4				red						(1.0f, 0.0f, 0.0f, 1.0f);
	const tcu::Vec4				green					(0.0f, 1.0f, 0.0f, 1.0f);
	const float					border					= 0.2f;
	const float					originX					= -1.0f + border;
	const float					originY					= -1.0f + border;
	const Vertex4RGBA			defaultVertex			= { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), green };
	float						primitiveSizeY			= (2.0f - 2.0f * border);
	float						primitiveSizeX;
	std::vector<deUint32>		indices;
	std::vector<Vertex4RGBA>	vertices;


	// Calculate primitive size
	switch (topology)
	{
		case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
			primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount / 2 + primitiveCount % 2 - 1);
			break;

		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
			primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount - 1);
			break;

		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
			primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount / 2);
			break;

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
			primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount + primitiveCount / 2 + primitiveCount % 2 - 1);
			break;

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
			primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount / 2 + primitiveCount % 2);
			break;

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
			primitiveSizeX = 1.0f - border;
			primitiveSizeY = 1.0f - border;
			break;

		default:
			primitiveSizeX = 0.0f; // Garbage
			DE_ASSERT(false);
	}

	switch (topology)
	{
		case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
			for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
			{
				const Vertex4RGBA vertex =
				{
					tcu::Vec4(originX + float(primitiveNdx / 2) * primitiveSizeX, originY + float(primitiveNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
					red
				};

				vertices.push_back(vertex);
				indices.push_back(primitiveNdx);
			}
			break;

		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
			for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
			{
				for (int vertexNdx = 0; vertexNdx < 2; vertexNdx++)
				{
					const Vertex4RGBA vertex =
					{
						tcu::Vec4(originX + float((primitiveNdx * 2 + vertexNdx) / 2) * primitiveSizeX, originY + float(vertexNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
						red
					};

					vertices.push_back(vertex);
					indices.push_back((primitiveNdx * 2 + vertexNdx));
				}
			}
			break;

		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
			for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
			{
				if (primitiveNdx == 0)
				{
					Vertex4RGBA vertex =
					{
						tcu::Vec4(originX, originY, 0.0f, 1.0f),
						red
					};

					vertices.push_back(vertex);
					indices.push_back(0);

					vertex.position = tcu::Vec4(originX, originY + primitiveSizeY, 0.0f, 1.0f);
					vertices.push_back(vertex);
					indices.push_back(1);
				}
				else
				{
					const Vertex4RGBA vertex =
					{
						tcu::Vec4(originX + float((primitiveNdx + 1) / 2) * primitiveSizeX, originY + float((primitiveNdx + 1) % 2) * primitiveSizeY, 0.0f, 1.0f),
						red
					};

					vertices.push_back(vertex);
					indices.push_back(primitiveNdx + 1);
				}
			}
			break;

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
			for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
			{
				for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
				{
					const Vertex4RGBA vertex =
					{
						tcu::Vec4(originX + float((primitiveNdx * 3 + vertexNdx) / 2) * primitiveSizeX, originY + float((primitiveNdx * 3 + vertexNdx)% 2) * primitiveSizeY, 0.0f, 1.0f),
						red
					};

					vertices.push_back(vertex);
					indices.push_back(primitiveNdx * 3 + vertexNdx);
				}
			}
			break;

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
			for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
			{
				if (primitiveNdx == 0)
				{
					for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
					{
						const Vertex4RGBA vertex =
						{
							tcu::Vec4(originX + float(vertexNdx / 2) * primitiveSizeX, originY + float(vertexNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
							red
						};

						vertices.push_back(vertex);
						indices.push_back(vertexNdx);
					}
				}
				else
				{
					const Vertex4RGBA vertex =
					{
						tcu::Vec4(originX + float((primitiveNdx + 2) / 2) * primitiveSizeX, originY + float((primitiveNdx + 2) % 2) * primitiveSizeY, 0.0f, 1.0f),
						red
					};

					vertices.push_back(vertex);
					indices.push_back(primitiveNdx + 2);
				}
			}
			break;

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
		{
			const float stepAngle = de::min(DE_PI * 0.5f, (2 * DE_PI) / float(primitiveCount));

			for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
			{
				if (primitiveNdx == 0)
				{
					Vertex4RGBA vertex =
					{
						tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
						red
					};

					vertices.push_back(vertex);
					indices.push_back(0);

					vertex.position = tcu::Vec4(primitiveSizeX, 0.0f, 0.0f, 1.0f);
					vertices.push_back(vertex);
					indices.push_back(1);

					vertex.position = tcu::Vec4(primitiveSizeX * deFloatCos(stepAngle), primitiveSizeY * deFloatSin(stepAngle), 0.0f, 1.0f);
					vertices.push_back(vertex);
					indices.push_back(2);
				}
				else
				{
					const Vertex4RGBA vertex =
					{
						tcu::Vec4(primitiveSizeX * deFloatCos(stepAngle * float(primitiveNdx + 1)), primitiveSizeY * deFloatSin(stepAngle * float(primitiveNdx + 1)), 0.0f, 1.0f),
						red
					};

					vertices.push_back(vertex);
					indices.push_back(primitiveNdx + 2);
				}
			}
			break;
		}

		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
			vertices.push_back(defaultVertex);

			for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
			{
				indices.push_back(0);

				for (int vertexNdx = 0; vertexNdx < 2; vertexNdx++)
				{
					const Vertex4RGBA vertex =
					{
						tcu::Vec4(originX + float((primitiveNdx * 2 + vertexNdx) / 2) * primitiveSizeX, originY + float(vertexNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
						red
					};

					vertices.push_back(vertex);
					indices.push_back(primitiveNdx * 2 + vertexNdx + 1);
				}

				indices.push_back(0);
			}
			break;


		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
			vertices.push_back(defaultVertex);
			indices.push_back(0);

			for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
			{
				if (primitiveNdx == 0)
				{
					Vertex4RGBA vertex =
					{
						tcu::Vec4(originX, originY, 0.0f, 1.0f),
						red
					};

					vertices.push_back(vertex);
					indices.push_back(1);

					vertex.position = tcu::Vec4(originX, originY + primitiveSizeY, 0.0f, 1.0f);
					vertices.push_back(vertex);
					indices.push_back(2);
				}
				else
				{
					const Vertex4RGBA vertex =
					{
						tcu::Vec4(originX + float((primitiveNdx + 1) / 2) * primitiveSizeX, originY + float((primitiveNdx + 1) % 2) * primitiveSizeY, 0.0f, 1.0f),
						red
					};

					vertices.push_back(vertex);
					indices.push_back(primitiveNdx + 2);
				}
			}

			indices.push_back(0);
			break;

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
			vertices.push_back(defaultVertex);

			for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
			{
				for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
				{
					const Vertex4RGBA vertex =
					{
						tcu::Vec4(originX + float((primitiveNdx * 3 + vertexNdx) / 2) * primitiveSizeX, originY + float((primitiveNdx * 3 + vertexNdx)% 2) * primitiveSizeY, 0.0f, 1.0f),
						red
					};

					vertices.push_back(vertex);
					indices.push_back(primitiveNdx * 3 + vertexNdx + 1);
					indices.push_back(0);
				}
			}
			break;

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
			vertices.push_back(defaultVertex);

			for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
			{
				if (primitiveNdx == 0)
				{
					for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
					{
						const Vertex4RGBA vertex =
						{
							tcu::Vec4(originX + float(vertexNdx / 2) * primitiveSizeX, originY + float(vertexNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
							red
						};

						vertices.push_back(vertex);
						indices.push_back(vertexNdx + 1);
						indices.push_back(0);
					}
				}
				else
				{
					const Vertex4RGBA vertex =
					{
						tcu::Vec4(originX + float((primitiveNdx + 2) / 2) * primitiveSizeX, originY + float((primitiveNdx + 2) % 2) * primitiveSizeY, 0.0f, 1.0f),
						red
					};

					vertices.push_back(vertex);
					indices.push_back(primitiveNdx + 2 + 1);
					indices.push_back(0);
				}
			}
			break;

		default:
			DE_ASSERT(false);
			break;
	}

	vertexData	= vertices;
	indexData	= indices;
}


// PrimitiveRestartTest

PrimitiveRestartTest::PrimitiveRestartTest (tcu::TestContext&		testContext,
											const std::string&		name,
											const std::string&		description,
											VkPrimitiveTopology		primitiveTopology,
											VkIndexType				indexType)

	: InputAssemblyTest	(testContext, name, description, primitiveTopology, 10, true, indexType)
{
	DE_ASSERT(primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP ||
			  primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP ||
			  primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN ||
			  primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY ||
			  primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY);

	deUint32 restartPrimitives[] = { 1, 5 };

	m_restartPrimitives = std::vector<deUint32>(restartPrimitives, restartPrimitives + sizeof(restartPrimitives) / sizeof(deUint32));
}

void PrimitiveRestartTest::createBufferData (VkPrimitiveTopology topology, int primitiveCount, VkIndexType indexType, std::vector<deUint32>& indexData, std::vector<Vertex4RGBA>& vertexData) const
{
	DE_ASSERT(primitiveCount > 0);
	DE_UNREF(indexType);

	const tcu::Vec4				red						(1.0f, 0.0f, 0.0f, 1.0f);
	const tcu::Vec4				green					(0.0f, 1.0f, 0.0f, 1.0f);
	const float					border					= 0.2f;
	const float					originX					= -1.0f + border;
	const float					originY					= -1.0f + border;
	const Vertex4RGBA			defaultVertex			= { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), green };
	float						primitiveSizeY			= (2.0f - 2.0f * border);
	float						primitiveSizeX;
	bool						primitiveStart			= true;
	std::vector<deUint32>		indices;
	std::vector<Vertex4RGBA>	vertices;


	// Calculate primitive size
	switch (topology)
	{
		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
			primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount / 2);
			break;

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
			primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount / 2 + primitiveCount % 2);
			break;

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
			primitiveSizeX = 1.0f - border;
			primitiveSizeY = 1.0f - border;
			break;

		default:
			primitiveSizeX = 0.0f; // Garbage
			DE_ASSERT(false);
	}

	switch (topology)
	{
		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
			for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
			{
				if (isRestartPrimitive(primitiveNdx))
				{
					indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
					primitiveStart = true;
				}
				else
				{
					if (primitiveStart)
					{
						const Vertex4RGBA vertex =
						{
							tcu::Vec4(originX + float(primitiveNdx / 2) * primitiveSizeX, originY + float(primitiveNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
							red
						};

						vertices.push_back(vertex);
						indices.push_back((deUint32)vertices.size() - 1);

						primitiveStart = false;
					}

					const Vertex4RGBA vertex =
					{
						tcu::Vec4(originX + float((primitiveNdx + 1) / 2) * primitiveSizeX, originY + float((primitiveNdx + 1) % 2) * primitiveSizeY, 0.0f, 1.0f),
						red
					};

					vertices.push_back(vertex);
					indices.push_back((deUint32)vertices.size() - 1);
				}
			}
			break;

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
		{
			for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
			{
				if (isRestartPrimitive(primitiveNdx))
				{
					indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
					primitiveStart = true;
				}
				else
				{
					if (primitiveStart)
					{
						for (int vertexNdx = 0; vertexNdx < 2; vertexNdx++)
						{
							const Vertex4RGBA vertex =
							{
								tcu::Vec4(originX + float((primitiveNdx + vertexNdx) / 2) * primitiveSizeX, originY + float((primitiveNdx + vertexNdx) % 2) * primitiveSizeY, 0.0f, 1.0f),
								red
							};

							vertices.push_back(vertex);
							indices.push_back((deUint32)vertices.size() - 1);
						}

						primitiveStart = false;
					}
					const Vertex4RGBA vertex =
					{
						tcu::Vec4(originX + float((primitiveNdx + 2) / 2) * primitiveSizeX, originY + float((primitiveNdx + 2) % 2) * primitiveSizeY, 0.0f, 1.0f),
						red
					};

					vertices.push_back(vertex);
					indices.push_back((deUint32)vertices.size() - 1);
				}
			}
			break;
		}

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
		{
			const float stepAngle = de::min(DE_PI * 0.5f, (2 * DE_PI) / float(primitiveCount));

			for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
			{
				if (isRestartPrimitive(primitiveNdx))
				{
					indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
					primitiveStart = true;
				}
				else
				{
					if (primitiveStart)
					{
						Vertex4RGBA vertex =
						{
							tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
							red
						};

						vertices.push_back(vertex);
						indices.push_back((deUint32)vertices.size() - 1);

						vertex.position = tcu::Vec4(primitiveSizeX * deFloatCos(stepAngle * float(primitiveNdx)), primitiveSizeY * deFloatSin(stepAngle * float(primitiveNdx)), 0.0f, 1.0f),
						vertices.push_back(vertex);
						indices.push_back((deUint32)vertices.size() - 1);

						primitiveStart = false;
					}

					const Vertex4RGBA vertex =
					{
						tcu::Vec4(primitiveSizeX * deFloatCos(stepAngle * float(primitiveNdx + 1)), primitiveSizeY * deFloatSin(stepAngle * float(primitiveNdx + 1)), 0.0f, 1.0f),
						red
					};

					vertices.push_back(vertex);
					indices.push_back((deUint32)vertices.size() - 1);
				}
			}
			break;
		}

		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
			vertices.push_back(defaultVertex);

			for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
			{
				if (isRestartPrimitive(primitiveNdx))
				{
					indices.push_back(0);
					indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
					primitiveStart = true;
				}
				else
				{
					if (primitiveStart)
					{
						indices.push_back(0);

						const Vertex4RGBA vertex =
						{
							tcu::Vec4(originX + float(primitiveNdx / 2) * primitiveSizeX, originY + float(primitiveNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
							red
						};

						vertices.push_back(vertex);
						indices.push_back((deUint32)vertices.size() - 1);

						primitiveStart = false;
					}

					const Vertex4RGBA vertex =
					{
						tcu::Vec4(originX + float((primitiveNdx + 1) / 2) * primitiveSizeX, originY + float((primitiveNdx + 1) % 2) * primitiveSizeY, 0.0f, 1.0f),
						red
					};

					vertices.push_back(vertex);
					indices.push_back((deUint32)vertices.size() - 1);
				}
			}

			indices.push_back(0);
			break;

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
			vertices.push_back(defaultVertex);

			for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
			{
				if (isRestartPrimitive(primitiveNdx))
				{
					indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
					primitiveStart = true;
				}
				else
				{
					if (primitiveStart)
					{
						for (int vertexNdx = 0; vertexNdx < 2; vertexNdx++)
						{
							const Vertex4RGBA vertex =
							{
								tcu::Vec4(originX + float((primitiveNdx + vertexNdx) / 2) * primitiveSizeX, originY + float((primitiveNdx + vertexNdx) % 2) * primitiveSizeY, 0.0f, 1.0f),
								red
							};

							vertices.push_back(vertex);
							indices.push_back((deUint32)vertices.size() - 1);
							indices.push_back(0);
						}

						primitiveStart = false;
					}

					const Vertex4RGBA vertex =
					{
						tcu::Vec4(originX + float((primitiveNdx + 2) / 2) * primitiveSizeX, originY + float((primitiveNdx + 2) % 2) * primitiveSizeY, 0.0f, 1.0f),
						red
					};

					vertices.push_back(vertex);
					indices.push_back((deUint32)vertices.size() - 1);
					indices.push_back(0);
				}
			}
			break;

		default:
			DE_ASSERT(false);
			break;
	}

	vertexData	= vertices;
	indexData	= indices;
}

bool PrimitiveRestartTest::isRestartPrimitive (int primitiveIndex) const
{
	return std::find(m_restartPrimitives.begin(), m_restartPrimitives.end(), primitiveIndex) != m_restartPrimitives.end();
}


// InputAssemblyInstance

InputAssemblyInstance::InputAssemblyInstance (Context&							context,
											  VkPrimitiveTopology				primitiveTopology,
											  bool								testPrimitiveRestart,
											  VkIndexType						indexType,
											  const std::vector<deUint32>&		indexBufferData,
											  const std::vector<Vertex4RGBA>&	vertexBufferData)

	: vkt::TestInstance			(context)
	, m_primitiveTopology		(primitiveTopology)
	, m_primitiveRestartEnable	(testPrimitiveRestart)
	, m_indexType				(indexType)
	, m_vertices				(vertexBufferData)
	, m_indices					(indexBufferData)
	, m_renderSize				((primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN) ? tcu::UVec2(32, 32) : tcu::UVec2(64, 16))
	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
{
	const DeviceInterface&			vk						= context.getDeviceInterface();
	const VkDevice					vkDevice				= context.getDevice();
	const deUint32					queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
	SimpleAllocator					memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
	const VkComponentMapping		componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };

	// Create color image
	{
		const VkImageCreateInfo colorImageParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
			DE_NULL,																	// const void*				pNext;
			0u,																			// VkImageCreateFlags		flags;
			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
			m_colorFormat,																// VkFormat					format;
			{ m_renderSize.x(), m_renderSize.y(), 1u },									// VkExtent3D				extent;
			1u,																			// deUint32					mipLevels;
			1u,																			// deUint32					arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,														// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,		// VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode;
			1u,																			// deUint32					queueFamilyIndexCount;
			&queueFamilyIndex,															// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED													// VkImageLayout			initialLayout;
		};

		m_colorImageCreateInfo	= colorImageParams;
		m_colorImage			= createImage(vk, vkDevice, &m_colorImageCreateInfo);

		// Allocate and bind color image memory
		m_colorImageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
	}

	// Create color attachment view
	{
		const VkImageViewCreateInfo colorAttachmentViewParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
			DE_NULL,											// const void*				pNext;
			0u,													// VkImageViewCreateFlags	flags;
			*m_colorImage,										// VkImage					image;
			VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
			m_colorFormat,										// VkFormat					format;
			componentMappingRGBA,								// VkComponentMapping		components;
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },		// VkImageSubresourceRange	subresourceRange;
		};

		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
	}

	// Create render pass
	m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat);

	// Create framebuffer
	{
		const VkFramebufferCreateInfo framebufferParams =
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType			sType;
			DE_NULL,											// const void*				pNext;
			0u,													// VkFramebufferCreateFlags	flags;
			*m_renderPass,										// VkRenderPass				renderPass;
			1u,													// deUint32					attachmentCount;
			&m_colorAttachmentView.get(),						// const VkImageView*		pAttachments;
			(deUint32)m_renderSize.x(),							// deUint32					width;
			(deUint32)m_renderSize.y(),							// deUint32					height;
			1u													// deUint32					layers;
		};

		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
	}

	// Create pipeline layout
	{
		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
			DE_NULL,											// const void*						pNext;
			0u,													// VkPipelineLayoutCreateFlags		flags;
			0u,													// deUint32							setLayoutCount;
			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
			0u,													// deUint32							pushConstantRangeCount;
			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
		};

		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
	}

	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);

	// Create pipeline
	{
		const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
		{
			{
				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
				DE_NULL,													// const void*							pNext;
				0u,															// VkPipelineShaderStageCreateFlags		flags;
				VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStageFlagBits				stage;
				*m_vertexShaderModule,										// VkShaderModule						module;
				"main",														// const char*							pName;
				DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
			},
			{
				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
				DE_NULL,													// const void*							pNext;
				0u,															// VkPipelineShaderStageCreateFlags		flags;
				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlagBits				stage;
				*m_fragmentShaderModule,									// VkShaderModule						module;
				"main",														// const char*							pName;
				DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
			}
		};

		const VkVertexInputBindingDescription vertexInputBindingDescription =
		{
			0u,								// deUint32					binding;
			sizeof(Vertex4RGBA),			// deUint32					stride;
			VK_VERTEX_INPUT_RATE_VERTEX		// VkVertexInputRate		inputRate;
		};

		const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
		{
			{
				0u,									// deUint32	location;
				0u,									// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
				0u									// deUint32	offset;
			},
			{
				1u,									// deUint32	location;
				0u,									// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
				DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32	offset;
			}
		};

		const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType								sType;
			DE_NULL,														// const void*									pNext;
			0u,																// VkPipelineVertexInputStateCreateFlags		flags;
			1u,																// deUint32										vertexBindingDescriptionCount;
			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*		pVertexBindingDescriptions;
			2u,																// deUint32										vertexAttributeDescriptionCount;
			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*		pVertexAttributeDescriptions;
		};

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

		const VkViewport	viewport	= makeViewport(m_renderSize);
		const VkRect2D		scissor		= makeRect2D(m_renderSize);

		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;
			false,															// VkBool32									depthClampEnable;
			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 VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
		{
			false,															// VkBool32					blendEnable;
			VK_BLEND_FACTOR_ONE,											// VkBlendFactor			srcColorBlendFactor;
			VK_BLEND_FACTOR_ZERO,											// VkBlendFactor			dstColorBlendFactor;
			VK_BLEND_OP_ADD,												// VkBlendOp				colorBlendOp;
			VK_BLEND_FACTOR_ONE,											// VkBlendFactor			srcAlphaBlendFactor;
			VK_BLEND_FACTOR_ZERO,											// VkBlendFactor			dstAlphaBlendFactor;
			VK_BLEND_OP_ADD,												// VkBlendOp				alphaBlendOp;
			VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |			// VkColorComponentFlags	colorWriteMask;
				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;
			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										blendConstants[4];
		};

		const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
			DE_NULL,													// const void*								pNext;
			0u,															// VkPipelineMultisampleStateCreateFlags	flags;
			VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
			false,														// VkBool32									sampleShadingEnable;
			0.0f,														// float									minSampleShading;
			DE_NULL,													// const VkSampleMask*						pSampleMask;
			false,														// VkBool32									alphaToCoverageEnable;
			false														// VkBool32									alphaToOneEnable;
		};

		VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
			DE_NULL,													// const void*								pNext;
			0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
			false,														// VkBool32									depthTestEnable;
			false,														// VkBool32									depthWriteEnable;
			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
			false,														// VkBool32									depthBoundsTestEnable;
			false,														// VkBool32									stencilTestEnable;
			// VkStencilOpState	front;
			{
				VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
				VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
				VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
				VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
				0u,						// deUint32		compareMask;
				0u,						// deUint32		writeMask;
				0u,						// deUint32		reference;
			},
			// VkStencilOpState	back;
			{
				VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
				VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
				VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
				VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
				0u,						// deUint32		compareMask;
				0u,						// deUint32		writeMask;
				0u,						// deUint32		reference;
			},
			0.0f,														// float			minDepthBounds;
			1.0f														// float			maxDepthBounds;
		};

		const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
		{
			VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
			DE_NULL,											// const void*										pNext;
			0u,													// VkPipelineCreateFlags							flags;
			2u,													// deUint32											stageCount;
			shaderStageParams,									// const VkPipelineShaderStageCreateInfo*			pStages;
			&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
			&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
			DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
			&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*			pViewportState;
			&rasterStateParams,									// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
			&multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
			&depthStencilStateParams,							// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
			&colorBlendStateParams,								// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
			(const VkPipelineDynamicStateCreateInfo*)DE_NULL,	// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
			*m_pipelineLayout,									// VkPipelineLayout									layout;
			*m_renderPass,										// VkRenderPass										renderPass;
			0u,													// deUint32											subpass;
			0u,													// VkPipeline										basePipelineHandle;
			0u													// deInt32											basePipelineIndex;
		};

		m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
	}

	// Create vertex and index buffer
	{
		const VkBufferCreateInfo indexBufferParams =
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			m_indices.size() * sizeof(deUint32),		// VkDeviceSize			size;
			VK_BUFFER_USAGE_INDEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyIndexCount;
			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
		};

		const VkBufferCreateInfo vertexBufferParams =
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			m_vertices.size() * sizeof(Vertex4RGBA),	// VkDeviceSize			size;
			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyIndexCount;
			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
		};

		m_indexBuffer		= createBuffer(vk, vkDevice, &indexBufferParams);
		m_indexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_indexBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_indexBuffer, m_indexBufferAlloc->getMemory(), m_indexBufferAlloc->getOffset()));

		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));

		// Load vertices into index buffer
		if (m_indexType == VK_INDEX_TYPE_UINT32)
		{
			deMemcpy(m_indexBufferAlloc->getHostPtr(), m_indices.data(), m_indices.size() * sizeof(deUint32));
		}
		else if (m_indexType == VK_INDEX_TYPE_UINT8_EXT)
		{
			uploadIndexBufferData8((deUint8*)m_indexBufferAlloc->getHostPtr(), m_indices);
		}
		else // m_indexType == VK_INDEX_TYPE_UINT16
		{
			uploadIndexBufferData16((deUint16*)m_indexBufferAlloc->getHostPtr(), m_indices);
		}

		// Load vertices into vertex buffer
		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));

		flushAlloc(vk, vkDevice, *m_indexBufferAlloc);
		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
	}

	// Create command pool
	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);

	// Create command buffer
	{
		const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);

		const VkImageMemoryBarrier attachmentLayoutBarrier =
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
			DE_NULL,										// const void*				pNext;
			0u,												// VkAccessFlags			srcAccessMask;
			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
			*m_colorImage,									// VkImage					image;
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
		};

		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

		beginCommandBuffer(vk, *m_cmdBuffer, 0u);

		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0,
			0u, DE_NULL, 0u, DE_NULL, 1u, &attachmentLayoutBarrier);

		beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);

		const VkDeviceSize vertexBufferOffset = 0;

		vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
		vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
		vk.cmdBindIndexBuffer(*m_cmdBuffer, *m_indexBuffer, 0, m_indexType);
		vk.cmdDrawIndexed(*m_cmdBuffer, (deUint32)m_indices.size(), 1, 0, 0, 0);

		endRenderPass(vk, *m_cmdBuffer);
		endCommandBuffer(vk, *m_cmdBuffer);
	}
}

InputAssemblyInstance::~InputAssemblyInstance (void)
{
}

tcu::TestStatus InputAssemblyInstance::iterate (void)
{
	const DeviceInterface&		vk			= m_context.getDeviceInterface();
	const VkDevice				vkDevice	= m_context.getDevice();
	const VkQueue				queue		= m_context.getUniversalQueue();

	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());

	return verifyImage();
}

tcu::TestStatus InputAssemblyInstance::verifyImage (void)
{
	const tcu::TextureFormat	tcuColorFormat		= mapVkFormat(m_colorFormat);
	const tcu::TextureFormat	tcuStencilFormat	= tcu::TextureFormat();
	const ColorVertexShader		vertexShader;
	const ColorFragmentShader	fragmentShader		(tcuColorFormat, tcuStencilFormat);
	const rr::Program			program				(&vertexShader, &fragmentShader);
	ReferenceRenderer			refRenderer			(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuStencilFormat, &program);
	bool						compareOk			= false;

	// Render reference image
	{
		const rr::PrimitiveType		topology	= mapVkPrimitiveTopology(m_primitiveTopology);
		rr::RenderState				renderState	(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits);

		if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
			renderState.point.pointSize = 3.0f;

		if (m_primitiveRestartEnable)
		{
			std::vector<deUint32> indicesRange;

			for (size_t indexNdx = 0; indexNdx < m_indices.size(); indexNdx++)
			{
				const bool isRestart = InputAssemblyTest::isRestartIndex(m_indexType, m_indices[indexNdx]);

				if (!isRestart)
					indicesRange.push_back(m_indices[indexNdx]);

				if (isRestart || indexNdx == (m_indices.size() - 1))
				{
					// Draw the range of indices found so far

					std::vector<Vertex4RGBA> nonIndexedVertices;
					for (size_t i = 0; i < indicesRange.size(); i++)
						nonIndexedVertices.push_back(m_vertices[indicesRange[i]]);

					refRenderer.draw(renderState, topology, nonIndexedVertices);
					indicesRange.clear();
				}
			}
		}
		else
		{
			std::vector<Vertex4RGBA> nonIndexedVertices;
			for (size_t i = 0; i < m_indices.size(); i++)
				nonIndexedVertices.push_back(m_vertices[m_indices[i]]);

			refRenderer.draw(renderState, topology, nonIndexedVertices);
		}
	}

	// Compare result with reference image
	{
		const DeviceInterface&				vk					= m_context.getDeviceInterface();
		const VkDevice						vkDevice			= m_context.getDevice();
		const VkQueue						queue				= m_context.getUniversalQueue();
		const deUint32						queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
		SimpleAllocator						allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
		de::UniquePtr<tcu::TextureLevel>	result				(readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize).release());

		compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
															  "IntImageCompare",
															  "Image comparison",
															  refRenderer.getAccess(),
															  result->getAccess(),
															  tcu::UVec4(2, 2, 2, 2),
															  tcu::IVec3(1, 1, 0),
															  true,
															  tcu::COMPARE_LOG_RESULT);
	}

	if (compareOk)
		return tcu::TestStatus::pass("Result image matches reference");
	else
		return tcu::TestStatus::fail("Image mismatch");
}

void InputAssemblyInstance::uploadIndexBufferData16	(deUint16* destPtr, const std::vector<deUint32>& indexBufferData)
{
	for (size_t i = 0; i < indexBufferData.size(); i++)
	{
		DE_ASSERT(indexBufferData[i] <= 0xFFFF);
		destPtr[i] = (deUint16)indexBufferData[i];
	}
}

void InputAssemblyInstance::uploadIndexBufferData8	(deUint8* destPtr, const std::vector<deUint32>& indexBufferData)
{
	for (size_t i = 0; i < indexBufferData.size(); i++)
	{
		DE_ASSERT(indexBufferData[i] <= 0xFF);
		destPtr[i] = (deUint8)indexBufferData[i];
	}
}


// Utilities for test names

std::string getPrimitiveTopologyCaseName (VkPrimitiveTopology topology)
{
	const std::string  fullName = getPrimitiveTopologyName(topology);

	DE_ASSERT(de::beginsWith(fullName, "VK_PRIMITIVE_TOPOLOGY_"));

	return de::toLower(fullName.substr(22));
}

de::MovePtr<tcu::TestCaseGroup> createPrimitiveTopologyTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> primitiveTopologyTests (new tcu::TestCaseGroup(testCtx, "primitive_topology", ""));

	de::MovePtr<tcu::TestCaseGroup> indexUint16Tests (new tcu::TestCaseGroup(testCtx, "index_type_uint16", ""));
	de::MovePtr<tcu::TestCaseGroup> indexUint32Tests (new tcu::TestCaseGroup(testCtx, "index_type_uint32", ""));
	de::MovePtr<tcu::TestCaseGroup> indexUint8Tests (new tcu::TestCaseGroup(testCtx, "index_type_uint8", ""));

	for (int topologyNdx = 0; topologyNdx < DE_LENGTH_OF_ARRAY(InputAssemblyTest::s_primitiveTopologies); topologyNdx++)
	{
		const VkPrimitiveTopology topology = InputAssemblyTest::s_primitiveTopologies[topologyNdx];

		indexUint16Tests->addChild(new PrimitiveTopologyTest(testCtx,
															 getPrimitiveTopologyCaseName(topology),
															 "",
															 topology,
															 VK_INDEX_TYPE_UINT16));

		indexUint32Tests->addChild(new PrimitiveTopologyTest(testCtx,
															 getPrimitiveTopologyCaseName(topology),
															 "",
															 topology,
															 VK_INDEX_TYPE_UINT32));

		indexUint8Tests->addChild(new PrimitiveTopologyTest(testCtx,
															 getPrimitiveTopologyCaseName(topology),
															 "",
															 topology,
															 VK_INDEX_TYPE_UINT8_EXT));
	}

	primitiveTopologyTests->addChild(indexUint16Tests.release());
	primitiveTopologyTests->addChild(indexUint32Tests.release());
	primitiveTopologyTests->addChild(indexUint8Tests.release());

	return primitiveTopologyTests;
}

de::MovePtr<tcu::TestCaseGroup> createPrimitiveRestartTests (tcu::TestContext& testCtx)
{
	const VkPrimitiveTopology primitiveRestartTopologies[] =
	{
		VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
		VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY
	};

	de::MovePtr<tcu::TestCaseGroup> primitiveRestartTests (new tcu::TestCaseGroup(testCtx, "primitive_restart", "Restarts indices of "));

	de::MovePtr<tcu::TestCaseGroup> indexUint16Tests (new tcu::TestCaseGroup(testCtx, "index_type_uint16", ""));
	de::MovePtr<tcu::TestCaseGroup> indexUint32Tests (new tcu::TestCaseGroup(testCtx, "index_type_uint32", ""));
	de::MovePtr<tcu::TestCaseGroup> indexUint8Tests (new tcu::TestCaseGroup(testCtx, "index_type_uint8", ""));

	for (int topologyNdx = 0; topologyNdx < DE_LENGTH_OF_ARRAY(primitiveRestartTopologies); topologyNdx++)
	{
		const VkPrimitiveTopology topology = primitiveRestartTopologies[topologyNdx];

		indexUint16Tests->addChild(new PrimitiveRestartTest(testCtx,
															getPrimitiveTopologyCaseName(topology),
															"",
															topology,
															VK_INDEX_TYPE_UINT16));

		indexUint32Tests->addChild(new PrimitiveRestartTest(testCtx,
															getPrimitiveTopologyCaseName(topology),
															"",
															topology,
															VK_INDEX_TYPE_UINT32));

		indexUint8Tests->addChild(new PrimitiveRestartTest(testCtx,
															getPrimitiveTopologyCaseName(topology),
															"",
															topology,
															VK_INDEX_TYPE_UINT8_EXT));
	}

	primitiveRestartTests->addChild(indexUint16Tests.release());
	primitiveRestartTests->addChild(indexUint32Tests.release());
	primitiveRestartTests->addChild(indexUint8Tests.release());

	return primitiveRestartTests;
}

} // anonymous

tcu::TestCaseGroup* createInputAssemblyTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup>		inputAssemblyTests (new tcu::TestCaseGroup(testCtx, "input_assembly", "Input assembly tests"));

	inputAssemblyTests->addChild(createPrimitiveTopologyTests(testCtx).release());
	inputAssemblyTests->addChild(createPrimitiveRestartTests(testCtx).release());

	return inputAssemblyTests.release();
}

} // pipeline
} // vkt
