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

	static const char* 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
