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