/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 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 gl_HelperInvocation tests.
 *//*--------------------------------------------------------------------*/

#include "es31fShaderHelperInvocationTests.hpp"

#include "gluObjectWrapper.hpp"
#include "gluShaderProgram.hpp"
#include "gluDrawUtil.hpp"
#include "gluPixelTransfer.hpp"

#include "glwFunctions.hpp"
#include "glwEnums.hpp"

#include "tcuTestLog.hpp"
#include "tcuVector.hpp"
#include "tcuSurface.hpp"

#include "deUniquePtr.hpp"
#include "deStringUtil.hpp"
#include "deRandom.hpp"
#include "deString.h"

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace
{

using glu::ShaderProgram;
using tcu::TestLog;
using tcu::Vec2;
using tcu::IVec2;
using de::MovePtr;
using std::string;
using std::vector;

enum PrimitiveType
{
	PRIMITIVETYPE_TRIANGLE = 0,
	PRIMITIVETYPE_LINE,
	PRIMITIVETYPE_WIDE_LINE,
	PRIMITIVETYPE_POINT,
	PRIMITIVETYPE_WIDE_POINT,

	PRIMITIVETYPE_LAST
};

static int getNumVerticesPerPrimitive (PrimitiveType primType)
{
	switch (primType)
	{
		case PRIMITIVETYPE_TRIANGLE:	return 3;
		case PRIMITIVETYPE_LINE:		return 2;
		case PRIMITIVETYPE_WIDE_LINE:	return 2;
		case PRIMITIVETYPE_POINT:		return 1;
		case PRIMITIVETYPE_WIDE_POINT:	return 1;
		default:
			DE_ASSERT(false);
			return 0;
	}
}

static glu::PrimitiveType getGluPrimitiveType (PrimitiveType primType)
{
	switch (primType)
	{
		case PRIMITIVETYPE_TRIANGLE:	return glu::PRIMITIVETYPE_TRIANGLES;
		case PRIMITIVETYPE_LINE:		return glu::PRIMITIVETYPE_LINES;
		case PRIMITIVETYPE_WIDE_LINE:	return glu::PRIMITIVETYPE_LINES;
		case PRIMITIVETYPE_POINT:		return glu::PRIMITIVETYPE_POINTS;
		case PRIMITIVETYPE_WIDE_POINT:	return glu::PRIMITIVETYPE_POINTS;
		default:
			DE_ASSERT(false);
			return glu::PRIMITIVETYPE_LAST;
	}
}

static void genVertices (PrimitiveType primType, int numPrimitives, de::Random* rnd, vector<Vec2>* dst)
{
	const bool		isTri		= primType == PRIMITIVETYPE_TRIANGLE;
	const float		minCoord	= isTri ? -1.5f : -1.0f;
	const float		maxCoord	= isTri ? +1.5f : +1.0f;
	const int		numVert		= getNumVerticesPerPrimitive(primType)*numPrimitives;

	dst->resize(numVert);

	for (size_t ndx = 0; ndx < dst->size(); ndx++)
	{
		(*dst)[ndx][0] = rnd->getFloat(minCoord, maxCoord);
		(*dst)[ndx][1] = rnd->getFloat(minCoord, maxCoord);
	}
}

static int getInteger (const glw::Functions& gl, deUint32 pname)
{
	int v = 0;
	gl.getIntegerv(pname, &v);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
	return v;
}

static Vec2 getRange (const glw::Functions& gl, deUint32 pname)
{
	Vec2 v(0.0f);
	gl.getFloatv(pname, v.getPtr());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFloatv()");
	return v;
}

static void drawRandomPrimitives (const glu::RenderContext& renderCtx, deUint32 program, PrimitiveType primType, int numPrimitives, de::Random* rnd)
{
	const glw::Functions&			gl				= renderCtx.getFunctions();
	const float						minPointSize	= 16.0f;
	const float						maxPointSize	= 32.0f;
	const float						minLineWidth	= 16.0f;
	const float						maxLineWidth	= 32.0f;
	vector<Vec2>					vertices;
	vector<glu::VertexArrayBinding>	vertexArrays;

	genVertices(primType, numPrimitives, rnd, &vertices);

	vertexArrays.push_back(glu::va::Float("a_position", 2, (int)vertices.size(), 0, (const float*)&vertices[0]));

	gl.useProgram(program);

	// Special state for certain primitives
	if (primType == PRIMITIVETYPE_POINT || primType == PRIMITIVETYPE_WIDE_POINT)
	{
		const Vec2		range			= getRange(gl, GL_ALIASED_POINT_SIZE_RANGE);
		const bool		isWidePoint		= primType == PRIMITIVETYPE_WIDE_POINT;
		const float		pointSize		= isWidePoint ? de::min(rnd->getFloat(minPointSize, maxPointSize), range.y()) : 1.0f;
		const int		pointSizeLoc	= gl.getUniformLocation(program, "u_pointSize");

		gl.uniform1f(pointSizeLoc, pointSize);
	}
	else if (primType == PRIMITIVETYPE_WIDE_LINE)
	{
		const Vec2		range			= getRange(gl, GL_ALIASED_LINE_WIDTH_RANGE);
		const float		lineWidth		= de::min(rnd->getFloat(minLineWidth, maxLineWidth), range.y());

		gl.lineWidth(lineWidth);
	}

	glu::draw(renderCtx, program, (int)vertexArrays.size(), &vertexArrays[0],
			  glu::PrimitiveList(getGluPrimitiveType(primType), (int)vertices.size()));
}

class FboHelper
{
public:
								FboHelper			(const glu::RenderContext& renderCtx, int width, int height, deUint32 format, int numSamples);
								~FboHelper			(void);

	void						bindForRendering	(void);
	void						readPixels			(int x, int y, const tcu::PixelBufferAccess& dst);

private:
	const glu::RenderContext&	m_renderCtx;
	const int					m_numSamples;

	glu::Renderbuffer			m_colorbuffer;
	glu::Framebuffer			m_framebuffer;
	glu::Renderbuffer			m_resolveColorbuffer;
	glu::Framebuffer			m_resolveFramebuffer;
};

FboHelper::FboHelper (const glu::RenderContext& renderCtx, int width, int height, deUint32 format, int numSamples)
	: m_renderCtx			(renderCtx)
	, m_numSamples			(numSamples)
	, m_colorbuffer			(renderCtx)
	, m_framebuffer			(renderCtx)
	, m_resolveColorbuffer	(renderCtx)
	, m_resolveFramebuffer	(renderCtx)
{
	const glw::Functions&	gl			= m_renderCtx.getFunctions();
	const int				maxSamples	= getInteger(gl, GL_MAX_SAMPLES);

	gl.bindRenderbuffer(GL_RENDERBUFFER, *m_colorbuffer);
	gl.renderbufferStorageMultisample(GL_RENDERBUFFER, m_numSamples, format, width, height);
	gl.bindFramebuffer(GL_FRAMEBUFFER, *m_framebuffer);
	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *m_colorbuffer);

	if (m_numSamples > maxSamples && gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
		throw tcu::NotSupportedError("Sample count exceeds GL_MAX_SAMPLES");

	TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);

	if (m_numSamples != 0)
	{
		gl.bindRenderbuffer(GL_RENDERBUFFER, *m_resolveColorbuffer);
		gl.renderbufferStorage(GL_RENDERBUFFER, format, width, height);
		gl.bindFramebuffer(GL_FRAMEBUFFER, *m_resolveFramebuffer);
		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *m_resolveColorbuffer);
		TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create framebuffer");
}

FboHelper::~FboHelper (void)
{
}

void FboHelper::bindForRendering (void)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();
	gl.bindFramebuffer(GL_FRAMEBUFFER, *m_framebuffer);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer()");
}

void FboHelper::readPixels (int x, int y, const tcu::PixelBufferAccess& dst)
{
	const glw::Functions&	gl		= m_renderCtx.getFunctions();
	const int				width	= dst.getWidth();
	const int				height	= dst.getHeight();

	if (m_numSamples != 0)
	{
		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, *m_resolveFramebuffer);
		gl.blitFramebuffer(x, y, width, height, x, y, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
		gl.bindFramebuffer(GL_READ_FRAMEBUFFER, *m_resolveFramebuffer);
	}

	glu::readPixels(m_renderCtx, x, y, dst);
}

enum
{
	FRAMEBUFFER_WIDTH	= 256,
	FRAMEBUFFER_HEIGHT	= 256,
	FRAMEBUFFER_FORMAT	= GL_RGBA8,
	NUM_SAMPLES_MAX		= -1
};

//! Verifies that gl_HelperInvocation is false in all rendered pixels.
class HelperInvocationValueCase : public TestCase
{
public:
							HelperInvocationValueCase	(Context& context, const char* name, const char* description, PrimitiveType primType, int numSamples);
							~HelperInvocationValueCase	(void);

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

private:
	const PrimitiveType		m_primitiveType;
	const int				m_numSamples;

	const int				m_numIters;
	const int				m_numPrimitivesPerIter;

	MovePtr<ShaderProgram>	m_program;
	MovePtr<FboHelper>		m_fbo;
	int						m_iterNdx;
};

HelperInvocationValueCase::HelperInvocationValueCase (Context& context, const char* name, const char* description, PrimitiveType primType, int numSamples)
	: TestCase					(context, name, description)
	, m_primitiveType			(primType)
	, m_numSamples				(numSamples)
	, m_numIters				(5)
	, m_numPrimitivesPerIter	(10)
	, m_iterNdx					(0)
{
}

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

void HelperInvocationValueCase::init (void)
{
	const glu::RenderContext&	renderCtx		= m_context.getRenderContext();
	const glw::Functions&		gl				= renderCtx.getFunctions();
	const int					maxSamples		= getInteger(gl, GL_MAX_SAMPLES);
	const int					actualSamples	= m_numSamples == NUM_SAMPLES_MAX ? maxSamples : m_numSamples;

	m_program = MovePtr<ShaderProgram>(new ShaderProgram(m_context.getRenderContext(),
		glu::ProgramSources()
			<< glu::VertexSource(
				"#version 310 es\n"
				"in highp vec2 a_position;\n"
				"uniform highp float u_pointSize;\n"
				"void main (void)\n"
				"{\n"
				"	gl_Position = vec4(a_position, 0.0, 1.0);\n"
				"	gl_PointSize = u_pointSize;\n"
				"}\n")
			<< glu::FragmentSource(
				"#version 310 es\n"
				"out mediump vec4 o_color;\n"
				"void main (void)\n"
				"{\n"
				"	if (gl_HelperInvocation)\n"
				"		o_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
				"	else\n"
				"		o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
				"}\n")));

	m_testCtx.getLog() << *m_program;

	if (!m_program->isOk())
	{
		m_program.clear();
		TCU_FAIL("Compile failed");
	}

	m_testCtx.getLog() << TestLog::Message << "Using GL_RGBA8 framebuffer with "
					   << actualSamples << " samples" << TestLog::EndMessage;

	m_fbo = MovePtr<FboHelper>(new FboHelper(renderCtx, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
											 FRAMEBUFFER_FORMAT, actualSamples));

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
}

void HelperInvocationValueCase::deinit (void)
{
	m_program.clear();
	m_fbo.clear();
}

static bool verifyHelperInvocationValue (TestLog& log, const tcu::Surface& result, bool isMultiSample)
{
	const tcu::RGBA		bgRef				(0, 0, 0, 255);
	const tcu::RGBA		fgRef				(0, 255, 0, 255);
	const tcu::RGBA		threshold			(1, isMultiSample ? 254 : 1, 1, 1);
	int					numInvalidPixels	= 0;

	for (int y = 0; y < result.getHeight(); ++y)
	{
		for (int x = 0; x < result.getWidth(); ++x)
		{
			const tcu::RGBA	resPix	= result.getPixel(x, y);

			if (!tcu::compareThreshold(resPix, bgRef, threshold) &&
				!tcu::compareThreshold(resPix, fgRef, threshold))
				numInvalidPixels += 1;
		}
	}

	if (numInvalidPixels > 0)
	{
		log << TestLog::Image("Result", "Result image", result);
		log << TestLog::Message << "ERROR: Found " << numInvalidPixels << " invalid result pixels!" << TestLog::EndMessage;
	}
	else
		log << TestLog::Message << "All result pixels are valid" << TestLog::EndMessage;

	return numInvalidPixels == 0;
}

HelperInvocationValueCase::IterateResult HelperInvocationValueCase::iterate (void)
{
	const glu::RenderContext&		renderCtx	= m_context.getRenderContext();
	const glw::Functions&			gl			= renderCtx.getFunctions();
	const string					sectionName	= string("Iteration ") + de::toString(m_iterNdx+1) + " / " + de::toString(m_numIters);
	const tcu::ScopedLogSection		section		(m_testCtx.getLog(), (string("Iter") + de::toString(m_iterNdx)), sectionName);
	de::Random						rnd			(deStringHash(getName()) ^ deInt32Hash(m_iterNdx));
	tcu::Surface					result		(FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT);

	m_fbo->bindForRendering();
	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.clear(GL_COLOR_BUFFER_BIT);

	drawRandomPrimitives(renderCtx, m_program->getProgram(), m_primitiveType, m_numPrimitivesPerIter, &rnd);

	m_fbo->readPixels(0, 0, result.getAccess());

	if (!verifyHelperInvocationValue(m_testCtx.getLog(), result, m_numSamples != 0))
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid pixels found");

	m_iterNdx += 1;
	return (m_iterNdx < m_numIters) ? CONTINUE : STOP;
}

//! Checks derivates when value depends on gl_HelperInvocation.
class HelperInvocationDerivateCase : public TestCase
{
public:
							HelperInvocationDerivateCase	(Context& context, const char* name, const char* description, PrimitiveType primType, int numSamples, const char* derivateFunc);
							~HelperInvocationDerivateCase	(void);

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

private:
	const PrimitiveType		m_primitiveType;
	const int				m_numSamples;
	const std::string		m_derivateFunc;

	const int				m_numIters;

	MovePtr<ShaderProgram>	m_program;
	MovePtr<FboHelper>		m_fbo;
	int						m_iterNdx;
};

HelperInvocationDerivateCase::HelperInvocationDerivateCase (Context& context, const char* name, const char* description, PrimitiveType primType, int numSamples, const char* derivateFunc)
	: TestCase					(context, name, description)
	, m_primitiveType			(primType)
	, m_numSamples				(numSamples)
	, m_derivateFunc			(derivateFunc)
	, m_numIters				(16)
	, m_iterNdx					(0)
{
}

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

void HelperInvocationDerivateCase::init (void)
{
	const glu::RenderContext&	renderCtx		= m_context.getRenderContext();
	const glw::Functions&		gl				= renderCtx.getFunctions();
	const int					maxSamples		= getInteger(gl, GL_MAX_SAMPLES);
	const int					actualSamples	= m_numSamples == NUM_SAMPLES_MAX ? maxSamples : m_numSamples;

	m_program = MovePtr<ShaderProgram>(new ShaderProgram(m_context.getRenderContext(),
		glu::ProgramSources()
			<< glu::VertexSource(
				"#version 310 es\n"
				"in highp vec2 a_position;\n"
				"uniform highp float u_pointSize;\n"
				"void main (void)\n"
				"{\n"
				"	gl_Position = vec4(a_position, 0.0, 1.0);\n"
				"	gl_PointSize = u_pointSize;\n"
				"}\n")
			<< glu::FragmentSource(string(
				"#version 310 es\n"
				"out mediump vec4 o_color;\n"
				"void main (void)\n"
				"{\n"
				"	highp float value		= gl_HelperInvocation ? 1.0 : 0.0;\n"
				"	highp float derivate	= ") + m_derivateFunc + "(value);\n"
				"	if (gl_HelperInvocation)\n"
				"		o_color = vec4(1.0, 0.0, derivate, 1.0);\n"
				"	else\n"
				"		o_color = vec4(0.0, 1.0, derivate, 1.0);\n"
				"}\n")));

	m_testCtx.getLog() << *m_program;

	if (!m_program->isOk())
	{
		m_program.clear();
		TCU_FAIL("Compile failed");
	}

	m_testCtx.getLog() << TestLog::Message << "Using GL_RGBA8 framebuffer with "
					   << actualSamples << " samples" << TestLog::EndMessage;

	m_fbo = MovePtr<FboHelper>(new FboHelper(renderCtx, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
											 FRAMEBUFFER_FORMAT, actualSamples));

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
}

void HelperInvocationDerivateCase::deinit (void)
{
	m_program.clear();
	m_fbo.clear();
}

static bool hasNeighborWithColor (const tcu::Surface& surface, int x, int y, tcu::RGBA color, tcu::RGBA threshold)
{
	static const IVec2 s_neighbors[] =
	{
		IVec2(-1, -1),
		IVec2( 0, -1),
		IVec2(+1, -1),
		IVec2(-1,  0),
		IVec2(+1,  0),
		IVec2(-1, +1),
		IVec2( 0, +1),
		IVec2(+1, +1)
	};

	const int	w	= surface.getWidth();
	const int	h	= surface.getHeight();

	for (int sample = 0; sample < DE_LENGTH_OF_ARRAY(s_neighbors); sample++)
	{
		const IVec2	pos	= IVec2(x, y) + s_neighbors[sample];

		if (de::inBounds(pos.x(), 0, w) && de::inBounds(pos.y(), 0, h))
		{
			const tcu::RGBA neighborColor = surface.getPixel(pos.x(), pos.y());

			if (tcu::compareThreshold(color, neighborColor, threshold))
				return true;
		}
		else
			return true; // Can't know for certain
	}

	return false;
}

static bool verifyHelperInvocationDerivate (TestLog& log, const tcu::Surface& result, bool isMultiSample)
{
	const tcu::RGBA		bgRef				(0, 0, 0, 255);
	const tcu::RGBA		fgRef				(0, 255, 0, 255);
	const tcu::RGBA		isBgThreshold		(1, isMultiSample ? 254 : 1, 0, 1);
	const tcu::RGBA		isFgThreshold		(1, isMultiSample ? 254 : 1, 255, 1);
	int					numInvalidPixels	= 0;
	int					numNonZeroDeriv		= 0;

	for (int y = 0; y < result.getHeight(); ++y)
	{
		for (int x = 0; x < result.getWidth(); ++x)
		{
			const tcu::RGBA	resPix			= result.getPixel(x, y);
			const bool		isBg			= tcu::compareThreshold(resPix, bgRef, isBgThreshold);
			const bool		isFg			= tcu::compareThreshold(resPix, fgRef, isFgThreshold);
			const bool		nonZeroDeriv	= resPix.getBlue() > 0;
			const bool		neighborBg		= nonZeroDeriv ? hasNeighborWithColor(result, x, y, bgRef, isBgThreshold) : false;

			if (nonZeroDeriv)
				numNonZeroDeriv	+= 1;

			if ((!isBg && !isFg) ||				// Neither of valid colors (ignoring blue channel that has derivate)
				(nonZeroDeriv && !neighborBg))	// Has non-zero derivate, but sample not at primitive edge
				numInvalidPixels += 1;
		}
	}

	if (numInvalidPixels > 0)
	{
		log << TestLog::Image("Result", "Result image", result);
		log << TestLog::Message << "ERROR: Found " << numInvalidPixels << " invalid result pixels!" << TestLog::EndMessage;
	}
	else
		log << TestLog::Message << "All result pixels are valid" << TestLog::EndMessage;

	log << TestLog::Message << "Found " << numNonZeroDeriv << " pixels with non-zero derivate (neighbor sample has gl_HelperInvocation = true)" << TestLog::EndMessage;

	return numInvalidPixels == 0;
}

HelperInvocationDerivateCase::IterateResult HelperInvocationDerivateCase::iterate (void)
{
	const glu::RenderContext&		renderCtx	= m_context.getRenderContext();
	const glw::Functions&			gl			= renderCtx.getFunctions();
	const string					sectionName	= string("Iteration ") + de::toString(m_iterNdx+1) + " / " + de::toString(m_numIters);
	const tcu::ScopedLogSection		section		(m_testCtx.getLog(), (string("Iter") + de::toString(m_iterNdx)), sectionName);
	de::Random						rnd			(deStringHash(getName()) ^ deInt32Hash(m_iterNdx));
	tcu::Surface					result		(FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT);

	m_fbo->bindForRendering();
	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.clear(GL_COLOR_BUFFER_BIT);

	drawRandomPrimitives(renderCtx, m_program->getProgram(), m_primitiveType, 1, &rnd);

	m_fbo->readPixels(0, 0, result.getAccess());

	if (!verifyHelperInvocationDerivate(m_testCtx.getLog(), result, m_numSamples != 0))
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid pixels found");

	m_iterNdx += 1;
	return (m_iterNdx < m_numIters) ? CONTINUE : STOP;
}

} // anonymous

ShaderHelperInvocationTests::ShaderHelperInvocationTests (Context& context)
	: TestCaseGroup(context, "helper_invocation", "gl_HelperInvocation tests")
{
}

ShaderHelperInvocationTests::~ShaderHelperInvocationTests (void)
{
}

void ShaderHelperInvocationTests::init (void)
{
	static const struct
	{
		const char*		caseName;
		PrimitiveType	primType;
	} s_primTypes[] =
	{
		{ "triangles",		PRIMITIVETYPE_TRIANGLE		},
		{ "lines",			PRIMITIVETYPE_LINE			},
		{ "wide_lines",		PRIMITIVETYPE_WIDE_LINE		},
		{ "points",			PRIMITIVETYPE_POINT			},
		{ "wide_points",	PRIMITIVETYPE_WIDE_POINT	}
	};

	static const struct
	{
		const char*		suffix;
		int				numSamples;
	} s_sampleCounts[] =
	{
		{ "",					0				},
		{ "_4_samples",			4				},
		{ "_8_samples",			8				},
		{ "_max_samples",		NUM_SAMPLES_MAX	}
	};

	// value
	{
		tcu::TestCaseGroup* const valueGroup = new tcu::TestCaseGroup(m_testCtx, "value", "gl_HelperInvocation value in rendered pixels");
		addChild(valueGroup);

		for (int sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(s_sampleCounts); sampleCountNdx++)
		{
			for (int primTypeNdx = 0; primTypeNdx < DE_LENGTH_OF_ARRAY(s_primTypes); primTypeNdx++)
			{
				const string		name		= string(s_primTypes[primTypeNdx].caseName) + s_sampleCounts[sampleCountNdx].suffix;
				const PrimitiveType	primType	= s_primTypes[primTypeNdx].primType;
				const int			numSamples	= s_sampleCounts[sampleCountNdx].numSamples;

				valueGroup->addChild(new HelperInvocationValueCase(m_context, name.c_str(), "", primType, numSamples));
			}
		}
	}

	// derivate
	{
		tcu::TestCaseGroup* const derivateGroup = new tcu::TestCaseGroup(m_testCtx, "derivate", "Derivate of gl_HelperInvocation-dependent value");
		addChild(derivateGroup);

		for (int sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(s_sampleCounts); sampleCountNdx++)
		{
			for (int primTypeNdx = 0; primTypeNdx < DE_LENGTH_OF_ARRAY(s_primTypes); primTypeNdx++)
			{
				const string		name		= string(s_primTypes[primTypeNdx].caseName) + s_sampleCounts[sampleCountNdx].suffix;
				const PrimitiveType	primType	= s_primTypes[primTypeNdx].primType;
				const int			numSamples	= s_sampleCounts[sampleCountNdx].numSamples;

				derivateGroup->addChild(new HelperInvocationDerivateCase(m_context, (name + "_dfdx").c_str(),	"", primType, numSamples, "dFdx"));
				derivateGroup->addChild(new HelperInvocationDerivateCase(m_context, (name + "_dfdy").c_str(),	"", primType, numSamples, "dFdy"));
				derivateGroup->addChild(new HelperInvocationDerivateCase(m_context, (name + "_fwidth").c_str(),	"", primType, numSamples, "fwidth"));
			}
		}
	}
}

} // Functional
} // gles31
} // deqp
