/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.0 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * 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 Primitive restart tests.
 *//*--------------------------------------------------------------------*/

#include "es3fPrimitiveRestartTests.hpp"
#include "gluShaderProgram.hpp"
#include "gluPixelTransfer.hpp"
#include "tcuTestLog.hpp"
#include "tcuSurface.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"
#include "deRandom.hpp"
#include "deMath.h"
#include "deString.h"

#include "glw.h"

using tcu::Vec4;

namespace deqp
{
namespace gles3
{
namespace Functional
{

static const int		MAX_RENDER_WIDTH				= 256;
static const int		MAX_RENDER_HEIGHT				= 256;

static const deUint32	MAX_UNSIGNED_BYTE				= (1<<8) - 1;
static const deUint32	MAX_UNSIGNED_SHORT				= (1<<16) - 1;
static const deUint32	MAX_UNSIGNED_INT				= (deUint32)((1ULL << 32) - 1);

static const deUint8	RESTART_INDEX_UNSIGNED_BYTE		= (deUint8)MAX_UNSIGNED_BYTE;
static const deUint16	RESTART_INDEX_UNSIGNED_SHORT	= (deUint16)MAX_UNSIGNED_SHORT;
static const deUint32	RESTART_INDEX_UNSIGNED_INT		= MAX_UNSIGNED_INT;

class PrimitiveRestartCase : public TestCase
{
public:
	enum PrimitiveType
	{
		PRIMITIVE_POINTS = 0,
		PRIMITIVE_LINE_STRIP,
		PRIMITIVE_LINE_LOOP,
		PRIMITIVE_LINES,
		PRIMITIVE_TRIANGLE_STRIP,
		PRIMITIVE_TRIANGLE_FAN,
		PRIMITIVE_TRIANGLES,

		PRIMITIVE_LAST
	};

	enum IndexType
	{
		INDEX_UNSIGNED_BYTE = 0,
		INDEX_UNSIGNED_SHORT,
		INDEX_UNSIGNED_INT,

		INDEX_LAST
	};

	enum Function
	{
		FUNCTION_DRAW_ELEMENTS = 0,
		FUNCTION_DRAW_ELEMENTS_INSTANCED,
		FUNCTION_DRAW_RANGE_ELEMENTS,

		FUNCTION_LAST
	};

							PrimitiveRestartCase	(Context& context, const char* name, const char* description, PrimitiveType primType, IndexType indexType, Function function, bool beginWithRestart, bool endWithRestart, bool duplicateRestarts);
							~PrimitiveRestartCase	(void);

	void					init					(void);
	void					deinit					(void);
	IterateResult			iterate					(void);

private:
							PrimitiveRestartCase	(const PrimitiveRestartCase& other);
	PrimitiveRestartCase&	operator=				(const PrimitiveRestartCase& other);

	void					draw					(int startNdx, int count);

	void					renderWithRestart		(void);
	void					renderWithoutRestart	(void);

	// Helper functions for handling the appropriate index vector (according to m_indexType).
	void					addIndex				(deUint32 index);
	deUint32				getIndex				(int indexNdx);
	int						getNumIndices			(void);
	void*					getIndexPtr				(int indexNdx);

	// \note Only one of the following index vectors is used (according to m_indexType).
	std::vector<deUint8>	m_indicesUB;
	std::vector<deUint16>	m_indicesUS;
	std::vector<deUint32>	m_indicesUI;

	std::vector<float>		m_positions;

	PrimitiveType			m_primType;
	IndexType				m_indexType;
	Function				m_function;

	bool					m_beginWithRestart;		// Whether there will be restart indices at the beginning of the index array.
	bool					m_endWithRestart;		// Whether there will be restart indices at the end of the index array.
	bool					m_duplicateRestarts;	// Whether two consecutive restarts are used instead of one.

	glu::ShaderProgram*		m_program;
};

PrimitiveRestartCase::PrimitiveRestartCase (Context& context, const char* name, const char* description, PrimitiveType primType, IndexType indexType, Function function, bool beginWithRestart, bool endWithRestart, bool duplicateRestarts)
	: TestCase				(context, name, description)
	, m_primType			(primType)
	, m_indexType			(indexType)
	, m_function			(function)
	, m_beginWithRestart	(beginWithRestart)
	, m_endWithRestart		(endWithRestart)
	, m_duplicateRestarts	(duplicateRestarts)
	, m_program				(DE_NULL)
{
}

PrimitiveRestartCase::~PrimitiveRestartCase (void)
{
	PrimitiveRestartCase::deinit();
}

void PrimitiveRestartCase::deinit (void)
{
	delete m_program;
	m_program = DE_NULL;
}

void PrimitiveRestartCase::addIndex (deUint32 index)
{
	if (m_indexType == INDEX_UNSIGNED_BYTE)
	{
		DE_ASSERT(de::inRange(index, (deUint32)0, MAX_UNSIGNED_BYTE));
		m_indicesUB.push_back((deUint8)index);
	}
	else if (m_indexType == INDEX_UNSIGNED_SHORT)
	{
		DE_ASSERT(de::inRange(index, (deUint32)0, MAX_UNSIGNED_SHORT));
		m_indicesUS.push_back((deUint16)index);
	}
	else if (m_indexType == INDEX_UNSIGNED_INT)
	{
		DE_ASSERT(de::inRange(index, (deUint32)0, MAX_UNSIGNED_INT));
		m_indicesUI.push_back((deUint32)index);
	}
	else
		DE_ASSERT(DE_FALSE);
}

deUint32 PrimitiveRestartCase::getIndex (int indexNdx)
{
	switch (m_indexType)
	{
		case INDEX_UNSIGNED_BYTE:	return (deUint32)m_indicesUB[indexNdx];
		case INDEX_UNSIGNED_SHORT:	return (deUint32)m_indicesUS[indexNdx];
		case INDEX_UNSIGNED_INT:	return m_indicesUI[indexNdx];
		default:
			DE_ASSERT(DE_FALSE);
			return 0;
	}
}

int PrimitiveRestartCase::getNumIndices (void)
{
	switch (m_indexType)
	{
		case INDEX_UNSIGNED_BYTE:	return (int)m_indicesUB.size();
		case INDEX_UNSIGNED_SHORT:	return (int)m_indicesUS.size();
		case INDEX_UNSIGNED_INT:	return (int)m_indicesUI.size();
		default:
			DE_ASSERT(DE_FALSE);
			return 0;
	}
}

// Pointer to the index value at index indexNdx.
void* PrimitiveRestartCase::getIndexPtr (int indexNdx)
{
	switch (m_indexType)
	{
		case INDEX_UNSIGNED_BYTE:	return (void*)&m_indicesUB[indexNdx];
		case INDEX_UNSIGNED_SHORT:	return (void*)&m_indicesUS[indexNdx];
		case INDEX_UNSIGNED_INT:	return (void*)&m_indicesUI[indexNdx];
		default:
			DE_ASSERT(DE_FALSE);
			return DE_NULL;
	}
}

void PrimitiveRestartCase::init (void)
{
	// Create shader program.
	std::string vertShaderSource;
	if (m_primType == PRIMITIVE_POINTS)
	{
		vertShaderSource =
			"#version 300 es\n"
			"in highp vec4 a_position;\n"
			"\n"
			"void main()\n"
			"{\n"
			"	gl_Position = a_position;\n"
			"	gl_PointSize = 1.0f;\n"
			"}\n";
	}
	else
	{
		vertShaderSource =
			"#version 300 es\n"
			"in highp vec4 a_position;\n"
			"\n"
			"void main()\n"
			"{\n"
			"	gl_Position = a_position;\n"
			"}\n";
	}

	static const char* fragShaderSource =
		"#version 300 es\n"
		"layout(location = 0) out mediump vec4 o_color;\n"
		"\n"
		"void main()\n"
		"{\n"
		"	o_color = vec4(1.0f);\n"
		"}\n";

	DE_ASSERT(!m_program);
	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertShaderSource, fragShaderSource));

	if(!m_program->isOk())
	{
		m_testCtx.getLog() << *m_program;
		TCU_FAIL("Failed to compile shader");
	}

	deUint32 restartIndex = m_indexType == INDEX_UNSIGNED_BYTE	? RESTART_INDEX_UNSIGNED_BYTE
						  : m_indexType == INDEX_UNSIGNED_SHORT	? RESTART_INDEX_UNSIGNED_SHORT
						  : m_indexType == INDEX_UNSIGNED_INT	? RESTART_INDEX_UNSIGNED_INT
						  : 0;

	DE_ASSERT(restartIndex != 0);

	DE_ASSERT(getNumIndices() == 0);

	// If testing a case with restart at beginning, add it there.
	if (m_beginWithRestart)
	{
		addIndex(restartIndex);
		if (m_duplicateRestarts)
			addIndex(restartIndex);
	}

	// Generate vertex positions and indices depending on primitive type.
	// \note At this point, restarts shall not be added to the start or the end of the index vector. Those are special cases, and are done above and after the following if-else chain, respectively.

	if (m_primType == PRIMITIVE_POINTS)
	{
		// Generate rows with different numbers of points.

		deUint32	curIndex			= 0;
		const int	numRows				= 20;

		for (int row = 0; row < numRows; row++)
		{
			for (int col = 0; col < row + 1; col++)
			{
				float fx = -1.0f + 2.0f * ((float)col + 0.5f) / (float)numRows;
				float fy = -1.0f + 2.0f * ((float)row + 0.5f) / (float)numRows;

				m_positions.push_back(fx);
				m_positions.push_back(fy);

				addIndex(curIndex++);
			}

			if (row < numRows - 1) // Add a restart after all but last row.
			{
				addIndex(restartIndex);
				if (m_duplicateRestarts)
					addIndex(restartIndex);
			}
		}
	}
	else if (m_primType == PRIMITIVE_LINE_STRIP || m_primType == PRIMITIVE_LINE_LOOP || m_primType == PRIMITIVE_LINES)
	{
		// Generate a numRows x numCols arrangement of line polygons of different vertex counts.

		deUint32	curIndex	= 0;
		const int	numRows		= 4;
		const int	numCols		= 4;

		for (int row = 0; row < numRows; row++)
		{
			float centerY = -1.0f + 2.0f * ((float)row + 0.5f) / (float)numRows;

			for (int col = 0; col < numCols; col++)
			{
				float	centerX		= -1.0f + 2.0f * ((float)col + 0.5f) / (float)numCols;
				int		numVertices	= row*numCols + col + 1;

				for (int i = 0; i < numVertices; i++)
				{
					float fx = centerX + 0.9f * deFloatCos((float)i*2.0f*DE_PI / (float)numVertices) / (float)numCols;
					float fy = centerY + 0.9f * deFloatSin((float)i*2.0f*DE_PI / (float)numVertices) / (float)numRows;

					m_positions.push_back(fx);
					m_positions.push_back(fy);

					addIndex(curIndex++);
				}

				if (col < numCols - 1 || row < numRows - 1) // Add a restart after all but last polygon.
				{
					addIndex(restartIndex);
					if (m_duplicateRestarts)
						addIndex(restartIndex);
				}
			}
		}
	}
	else if (m_primType == PRIMITIVE_TRIANGLE_STRIP)
	{
		// Generate a number of horizontal triangle strips of different lengths.

		deUint32	curIndex	= 0;
		const int	numStrips	= 20;

		for (int stripNdx = 0; stripNdx < numStrips; stripNdx++)
		{
			int numVertices = stripNdx + 1;

			for (int i = 0; i < numVertices; i++)
			{
				float fx = -0.9f + 1.8f * (float)(i/2*2) / numStrips;
				float fy = -0.9f + 1.8f * ((float)stripNdx + (i%2 == 0 ? 0.0f : 0.8f)) / numStrips;

				m_positions.push_back(fx);
				m_positions.push_back(fy);

				addIndex(curIndex++);
			}

			if (stripNdx < numStrips - 1) // Add a restart after all but last strip.
			{
				addIndex(restartIndex);
				if (m_duplicateRestarts)
					addIndex(restartIndex);
			}
		}
	}
	else if (m_primType == PRIMITIVE_TRIANGLE_FAN)
	{
		// Generate a numRows x numCols arrangement of triangle fan polygons of different vertex counts.

		deUint32	curIndex	= 0;
		const int	numRows		= 4;
		const int	numCols		= 4;

		for (int row = 0; row < numRows; row++)
		{
			float centerY = -1.0f + 2.0f * ((float)row + 0.5f) / (float)numRows;

			for (int col = 0; col < numCols; col++)
			{
				float	centerX			= -1.0f + 2.0f * ((float)col + 0.5f) / (float)numCols;
				int		numArcVertices	= row*numCols + col;

				m_positions.push_back(centerX);
				m_positions.push_back(centerY);

				addIndex(curIndex++);

				for (int i = 0; i < numArcVertices; i++)
				{
					float fx = centerX + 0.9f * deFloatCos((float)i*2.0f*DE_PI / (float)numArcVertices) / (float)numCols;
					float fy = centerY + 0.9f * deFloatSin((float)i*2.0f*DE_PI / (float)numArcVertices) / (float)numRows;

					m_positions.push_back(fx);
					m_positions.push_back(fy);

					addIndex(curIndex++);
				}

				if (col < numCols - 1 || row < numRows - 1) // Add a restart after all but last polygon.
				{
					addIndex(restartIndex);
					if (m_duplicateRestarts)
						addIndex(restartIndex);
				}
			}
		}
	}
	else if (m_primType == PRIMITIVE_TRIANGLES)
	{
		// Generate a number of rows with (potentially incomplete) triangles.

		deUint32	curIndex	= 0;
		const int	numRows		= 3*7;

		for (int rowNdx = 0; rowNdx < numRows; rowNdx++)
		{
			int numVertices = rowNdx + 1;

			for (int i = 0; i < numVertices; i++)
			{
				float fx = -0.9f + 1.8f * ((float)(i/3) + (i%3 == 2 ? 0.8f : 0.0f)) * 3 / numRows;
				float fy = -0.9f + 1.8f * ((float)rowNdx + (i%3 == 0 ? 0.0f : 0.8f)) / numRows;

				m_positions.push_back(fx);
				m_positions.push_back(fy);

				addIndex(curIndex++);
			}

			if (rowNdx < numRows - 1) // Add a restart after all but last row.
			{
				addIndex(restartIndex);
				if (m_duplicateRestarts)
					addIndex(restartIndex);
			}
		}
	}
	else
		DE_ASSERT(DE_FALSE);

	// If testing a case with restart at end, add it there.
	if (m_endWithRestart)
	{
		addIndex(restartIndex);
		if (m_duplicateRestarts)
			addIndex(restartIndex);
	}

	// Special case assertions.

	int numIndices = getNumIndices();

	DE_ASSERT(numIndices > 0);
	DE_ASSERT(m_beginWithRestart || getIndex(0) != restartIndex);						// We don't want restarts at beginning unless the case is a special case.
	DE_ASSERT(m_endWithRestart || getIndex(numIndices-1) != restartIndex);			// We don't want restarts at end unless the case is a special case.

	if (!m_duplicateRestarts)
		for (int i = 1; i < numIndices; i++)
			DE_ASSERT(getIndex(i) != restartIndex || getIndex(i-1) != restartIndex);	// We don't want duplicate restarts unless the case is a special case.
}

PrimitiveRestartCase::IterateResult PrimitiveRestartCase::iterate (void)
{
	int							width			= deMin32(m_context.getRenderTarget().getWidth(), MAX_RENDER_WIDTH);
	int							height			= deMin32(m_context.getRenderTarget().getHeight(), MAX_RENDER_HEIGHT);

	int							xOffsetMax		= m_context.getRenderTarget().getWidth() - width;
	int							yOffsetMax		= m_context.getRenderTarget().getHeight() - height;

	de::Random					rnd				(deStringHash(getName()));

	int							xOffset			= rnd.getInt(0, xOffsetMax);
	int							yOffset			= rnd.getInt(0, yOffsetMax);
	tcu::Surface				referenceImg	(width, height);
	tcu::Surface				resultImg		(width, height);

	glViewport(xOffset, yOffset, width, height);
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

	deUint32 program = m_program->getProgram();
	glUseProgram(program);

	// Setup position attribute.

	int loc = glGetAttribLocation(program, "a_position");
	glEnableVertexAttribArray(loc);
	glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, &m_positions[0]);

	// Render result.

	renderWithRestart();
	glu::readPixels(m_context.getRenderContext(), xOffset, yOffset, resultImg.getAccess());

	// Render reference (same scene as the real deal, but emulate primitive restart without actually using it).

	renderWithoutRestart();
	glu::readPixels(m_context.getRenderContext(), xOffset, yOffset, referenceImg.getAccess());

	// Compare.

	bool testOk = tcu::pixelThresholdCompare(m_testCtx.getLog(), "ComparisonResult", "Image comparison result", referenceImg, resultImg, tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);

	m_testCtx.setTestResult(testOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
							testOk ? "Pass"					: "Fail");

	glUseProgram(0);

	return STOP;
}

// Draw with the appropriate GLES3 draw function.
void PrimitiveRestartCase::draw (int startNdx, int count)
{
	GLenum primTypeGL;

	switch (m_primType)
	{
		case PRIMITIVE_POINTS:			primTypeGL = GL_POINTS;			break;
		case PRIMITIVE_LINE_STRIP:		primTypeGL = GL_LINE_STRIP;		break;
		case PRIMITIVE_LINE_LOOP:		primTypeGL = GL_LINE_LOOP;		break;
		case PRIMITIVE_LINES:			primTypeGL = GL_LINES;			break;
		case PRIMITIVE_TRIANGLE_STRIP:	primTypeGL = GL_TRIANGLE_STRIP;	break;
		case PRIMITIVE_TRIANGLE_FAN:	primTypeGL = GL_TRIANGLE_FAN;	break;
		case PRIMITIVE_TRIANGLES:		primTypeGL = GL_TRIANGLES;		break;
		default:
			DE_ASSERT(DE_FALSE);
			primTypeGL = 0;
	}

	GLenum indexTypeGL;

	switch (m_indexType)
	{
		case INDEX_UNSIGNED_BYTE:	indexTypeGL = GL_UNSIGNED_BYTE;		break;
		case INDEX_UNSIGNED_SHORT:	indexTypeGL = GL_UNSIGNED_SHORT;	break;
		case INDEX_UNSIGNED_INT:	indexTypeGL = GL_UNSIGNED_INT;		break;
		default:
			DE_ASSERT(DE_FALSE);
			indexTypeGL = 0;
	}

	deUint32 restartIndex = m_indexType == INDEX_UNSIGNED_BYTE	? RESTART_INDEX_UNSIGNED_BYTE
						  : m_indexType == INDEX_UNSIGNED_SHORT	? RESTART_INDEX_UNSIGNED_SHORT
						  : m_indexType == INDEX_UNSIGNED_INT	? RESTART_INDEX_UNSIGNED_INT
						  : 0;

	DE_ASSERT(restartIndex != 0);

	if (m_function == FUNCTION_DRAW_ELEMENTS)
		glDrawElements(primTypeGL, (GLsizei)count, indexTypeGL, (GLvoid*)getIndexPtr(startNdx));
	else if (m_function == FUNCTION_DRAW_ELEMENTS_INSTANCED)
		glDrawElementsInstanced(primTypeGL, (GLsizei)count, indexTypeGL, (GLvoid*)getIndexPtr(startNdx), 1);
	else
	{
		DE_ASSERT(m_function == FUNCTION_DRAW_RANGE_ELEMENTS);

		// Find the largest non-restart index in the index array (for glDrawRangeElements() end parameter).

		deUint32 max = 0;

		int numIndices = getNumIndices();
		for (int i = 0; i < numIndices; i++)
		{
			deUint32 index = getIndex(i);
			if (index != restartIndex && index > max)
				max = index;
		}

		glDrawRangeElements(primTypeGL, 0, (GLuint)max, (GLsizei)count, indexTypeGL, (GLvoid*)getIndexPtr(startNdx));
	}
}

void PrimitiveRestartCase::renderWithRestart (void)
{
	GLU_CHECK_MSG("PrimitiveRestartCase::renderWithRestart() begin");

	glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
	GLU_CHECK_MSG("Enable primitive restart");
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
	GLU_CHECK_MSG("Clear in PrimitiveRestartCase::renderWithRestart()");

	draw(0, getNumIndices());

	GLU_CHECK_MSG("Draw in PrimitiveRestartCase::renderWithRestart()");

	GLU_CHECK_MSG("PrimitiveRestartCase::renderWithRestart() end");
}

void PrimitiveRestartCase::renderWithoutRestart (void)
{
	GLU_CHECK_MSG("PrimitiveRestartCase::renderWithoutRestart() begin");

	deUint32 restartIndex = m_indexType == INDEX_UNSIGNED_BYTE	? RESTART_INDEX_UNSIGNED_BYTE
						  : m_indexType == INDEX_UNSIGNED_SHORT	? RESTART_INDEX_UNSIGNED_SHORT
						  : m_indexType == INDEX_UNSIGNED_INT	? RESTART_INDEX_UNSIGNED_INT
						  : 0;

	DE_ASSERT(restartIndex != 0);

	glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
	GLU_CHECK_MSG("Disable primitive restart");
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
	GLU_CHECK_MSG("Clear in PrimitiveRestartCase::renderWithoutRestart()");

	// Draw, emulating primitive restart.

	int numIndices = getNumIndices();

	DE_ASSERT(numIndices >= 0);

	int indexArrayStartNdx = 0; // Keep track of the draw start index - first index after a primitive restart, or initially the first index altogether.

	for (int indexArrayNdx = 0; indexArrayNdx <= numIndices; indexArrayNdx++) // \note Goes one "too far" in order to detect end of array as well.
	{
		if (indexArrayNdx >= numIndices || getIndex(indexArrayNdx) == restartIndex) // \note Handle end of array the same way as a restart index encounter.
		{
			if (indexArrayStartNdx < numIndices)
			{
				// Draw from index indexArrayStartNdx to index indexArrayNdx-1 .

				draw(indexArrayStartNdx, indexArrayNdx - indexArrayStartNdx);
				GLU_CHECK_MSG("Draw in PrimitiveRestartCase::renderWithoutRestart()");
			}

			indexArrayStartNdx = indexArrayNdx + 1; // Next draw starts just after this restart index.
		}
	}

	GLU_CHECK_MSG("PrimitiveRestartCase::renderWithoutRestart() end");
}

PrimitiveRestartTests::PrimitiveRestartTests (Context& context)
	: TestCaseGroup(context, "primitive_restart", "Primitive restart tests")
{
}

PrimitiveRestartTests::~PrimitiveRestartTests (void)
{
}

void PrimitiveRestartTests::init (void)
{
	for (int isRestartBeginCaseI = 0; isRestartBeginCaseI <= 1; isRestartBeginCaseI++)
	for (int isRestartEndCaseI = 0; isRestartEndCaseI <= 1; isRestartEndCaseI++)
	for (int isDuplicateRestartCaseI = 0; isDuplicateRestartCaseI <= 1; isDuplicateRestartCaseI++)
	{
		bool			isRestartBeginCase		= isRestartBeginCaseI != 0;
		bool			isRestartEndCase		= isRestartEndCaseI != 0;
		bool			isDuplicateRestartCase	= isDuplicateRestartCaseI != 0;

		std::string		specialCaseGroupName;

		if (isRestartBeginCase)		specialCaseGroupName = "begin_restart";
		if (isRestartEndCase)		specialCaseGroupName += std::string(specialCaseGroupName.empty() ? "" : "_") + "end_restart";
		if (isDuplicateRestartCase)	specialCaseGroupName += std::string(specialCaseGroupName.empty() ? "" : "_") + "duplicate_restarts";

		if (specialCaseGroupName.empty())
			specialCaseGroupName = "basic";

		TestCaseGroup* specialCaseGroup = new TestCaseGroup(m_context, specialCaseGroupName.c_str(), "");
		addChild(specialCaseGroup);

		for (int primType = 0; primType < (int)PrimitiveRestartCase::PRIMITIVE_LAST; primType++)
		{
			const char* primTypeName = primType == (int)PrimitiveRestartCase::PRIMITIVE_POINTS			? "points"
									 : primType == (int)PrimitiveRestartCase::PRIMITIVE_LINE_STRIP		? "line_strip"
									 : primType == (int)PrimitiveRestartCase::PRIMITIVE_LINE_LOOP		? "line_loop"
									 : primType == (int)PrimitiveRestartCase::PRIMITIVE_LINES			? "lines"
									 : primType == (int)PrimitiveRestartCase::PRIMITIVE_TRIANGLE_STRIP	? "triangle_strip"
									 : primType == (int)PrimitiveRestartCase::PRIMITIVE_TRIANGLE_FAN	? "triangle_fan"
									 : primType == (int)PrimitiveRestartCase::PRIMITIVE_TRIANGLES		? "triangles"
									 : DE_NULL;

			DE_ASSERT(primTypeName != DE_NULL);

			TestCaseGroup* primTypeGroup = new TestCaseGroup(m_context, primTypeName, "");
			specialCaseGroup->addChild(primTypeGroup);

			for (int indexType = 0; indexType < (int)PrimitiveRestartCase::INDEX_LAST; indexType++)
			{
				const char *indexTypeName = indexType == (int)PrimitiveRestartCase::INDEX_UNSIGNED_BYTE		? "unsigned_byte"
										  : indexType == (int)PrimitiveRestartCase::INDEX_UNSIGNED_SHORT	? "unsigned_short"
										  : indexType == (int)PrimitiveRestartCase::INDEX_UNSIGNED_INT		? "unsigned_int"
										  : DE_NULL;

				DE_ASSERT(indexTypeName != DE_NULL);

				TestCaseGroup* indexTypeGroup = new TestCaseGroup(m_context, indexTypeName, "");
				primTypeGroup->addChild(indexTypeGroup);

				for (int function = 0; function < (int)PrimitiveRestartCase::FUNCTION_LAST; function++)
				{
					const char* functionName = function == (int)PrimitiveRestartCase::FUNCTION_DRAW_ELEMENTS			? "draw_elements"
											 : function == (int)PrimitiveRestartCase::FUNCTION_DRAW_ELEMENTS_INSTANCED	? "draw_elements_instanced"
											 : function == (int)PrimitiveRestartCase::FUNCTION_DRAW_RANGE_ELEMENTS		? "draw_range_elements"
											 : DE_NULL;

					DE_ASSERT(functionName != DE_NULL);

					indexTypeGroup->addChild(new PrimitiveRestartCase(m_context,
																	  functionName,
																	  "",
																	  (PrimitiveRestartCase::PrimitiveType)primType,
																	  (PrimitiveRestartCase::IndexType)indexType,
																	  (PrimitiveRestartCase::Function)function,
																	  isRestartBeginCase,
																	  isRestartEndCase,
																	  isDuplicateRestartCase));
				}
			}
		}
	}
}

} // Functional
} // gles3
} // deqp
