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

#include "es31fTessellationTests.hpp"
#include "glsTextureTestUtil.hpp"
#include "gluShaderProgram.hpp"
#include "gluRenderContext.hpp"
#include "gluPixelTransfer.hpp"
#include "gluDrawUtil.hpp"
#include "gluObjectWrapper.hpp"
#include "gluStrUtil.hpp"
#include "gluContextInfo.hpp"
#include "gluVarType.hpp"
#include "gluVarTypeUtil.hpp"
#include "tcuTestLog.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuSurface.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuImageIO.hpp"
#include "tcuResource.hpp"
#include "tcuImageCompare.hpp"
#include "deRandom.hpp"
#include "deStringUtil.hpp"
#include "deSharedPtr.hpp"
#include "deString.h"
#include "deMath.h"

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

#include <vector>
#include <string>
#include <algorithm>
#include <functional>
#include <set>
#include <limits>

using glu::ShaderProgram;
using glu::RenderContext;
using tcu::RenderTarget;
using tcu::TestLog;
using tcu::Vec2;
using tcu::Vec3;
using tcu::Vec4;
using de::Random;
using de::SharedPtr;

using std::vector;
using std::string;

using namespace glw; // For GL types.

namespace deqp
{

using gls::TextureTestUtil::RandomViewport;

namespace gles31
{
namespace Functional
{

enum
{
	MINIMUM_MAX_TESS_GEN_LEVEL = 64 //!< GL-defined minimum for GL_MAX_TESS_GEN_LEVEL.
};

static inline bool vec3XLessThan (const Vec3& a, const Vec3& b) { return a.x() < b.x(); }

template <typename IterT>
static string elemsStr (const IterT& begin, const IterT& end, int wrapLengthParam = 0, int numIndentationSpaces = 0)
{
	const string	baseIndentation	= string(numIndentationSpaces, ' ');
	const string	deepIndentation	= baseIndentation + string(4, ' ');
	const int		wrapLength		= wrapLengthParam > 0 ? wrapLengthParam : std::numeric_limits<int>::max();
	const int		length			= (int)std::distance(begin, end);
	string			result;

	if (length > wrapLength)
		result += "(amount: " + de::toString(length) + ") ";
	result += string() + "{" + (length > wrapLength ? "\n"+deepIndentation : " ");

	{
		int index = 0;
		for (IterT it = begin; it != end; ++it)
		{
			if (it != begin)
				result += string() + ", " + (index % wrapLength == 0 ? "\n"+deepIndentation : "");
			result += de::toString(*it);
			index++;
		}

		result += length > wrapLength ? "\n"+baseIndentation : " ";
	}

	result += "}";
	return result;
}

template <typename ContainerT>
static string containerStr (const ContainerT& c, int wrapLengthParam = 0, int numIndentationSpaces = 0)
{
	return elemsStr(c.begin(), c.end(), wrapLengthParam, numIndentationSpaces);
}

template <typename T, int N>
static string arrayStr (const T (&arr)[N], int wrapLengthParam = 0, int numIndentationSpaces = 0)
{
	return elemsStr(DE_ARRAY_BEGIN(arr), DE_ARRAY_END(arr), wrapLengthParam, numIndentationSpaces);
}

template <typename T, int N>
static T arrayMax (const T (&arr)[N])
{
	return *std::max_element(DE_ARRAY_BEGIN(arr), DE_ARRAY_END(arr));
}

template <typename T, typename MembT>
static vector<MembT> members (const vector<T>& objs, MembT T::* membP)
{
	vector<MembT> result(objs.size());
	for (int i = 0; i < (int)objs.size(); i++)
		result[i] = objs[i].*membP;
	return result;
}

template <typename T, int N>
static vector<T> arrayToVector (const T (&arr)[N])
{
	return vector<T>(DE_ARRAY_BEGIN(arr), DE_ARRAY_END(arr));
}

template <typename ContainerT, typename T>
static inline bool contains (const ContainerT& c, const T& key)
{
	return c.find(key) != c.end();
}

template <int Size>
static inline tcu::Vector<bool, Size> singleTrueMask (int index)
{
	DE_ASSERT(de::inBounds(index, 0, Size));
	tcu::Vector<bool, Size> result;
	result[index] = true;
	return result;
}

static int intPow (int base, int exp)
{
	DE_ASSERT(exp >= 0);
	if (exp == 0)
		return 1;
	else
	{
		const int sub = intPow(base, exp/2);
		if (exp % 2 == 0)
			return sub*sub;
		else
			return sub*sub*base;
	}
}

tcu::Surface getPixels (const glu::RenderContext& rCtx, int x, int y, int width, int height)
{
	tcu::Surface result(width, height);
	glu::readPixels(rCtx, x, y, result.getAccess());
	return result;
}

tcu::Surface getPixels (const glu::RenderContext& rCtx, const RandomViewport& vp)
{
	return getPixels(rCtx, vp.x, vp.y, vp.width, vp.height);
}

static inline void checkRenderTargetSize (const RenderTarget& renderTarget, int minSize)
{
	if (renderTarget.getWidth() < minSize || renderTarget.getHeight() < minSize)
		throw tcu::NotSupportedError("Render target width and height must be at least " + de::toString(minSize));
}

tcu::TextureLevel getPNG (const tcu::Archive& archive, const string& filename)
{
	tcu::TextureLevel result;
	tcu::ImageIO::loadPNG(result, archive, filename.c_str());
	return result;
}

static int numBasicSubobjects (const glu::VarType& type)
{
	if (type.isBasicType())
		return 1;
	else if (type.isArrayType())
		return type.getArraySize()*numBasicSubobjects(type.getElementType());
	else if (type.isStructType())
	{
		const glu::StructType&	structType	= *type.getStructPtr();
		int						result		= 0;
		for (int i = 0; i < structType.getNumMembers(); i++)
			result += numBasicSubobjects(structType.getMember(i).getType());
		return result;
	}
	else
	{
		DE_ASSERT(false);
		return -1;
	}
}

static inline int numVerticesPerPrimitive (deUint32 primitiveTypeGL)
{
	switch (primitiveTypeGL)
	{
		case GL_POINTS:		return 1;
		case GL_TRIANGLES:	return 3;
		case GL_LINES:		return 2;
		default:
			DE_ASSERT(false);
			return -1;
	}
}

static inline void setViewport (const glw::Functions& gl, const RandomViewport& vp)
{
	gl.viewport(vp.x, vp.y, vp.width, vp.height);
}

static inline deUint32 getQueryResult (const glw::Functions& gl, deUint32 queryObject)
{
	deUint32 result = (deUint32)-1;
	gl.getQueryObjectuiv(queryObject, GL_QUERY_RESULT, &result);
	TCU_CHECK(result != (deUint32)-1);
	return result;
}

template <typename T>
static void readDataMapped (const glw::Functions& gl, deUint32 bufferTarget, int numElems, T* dst)
{
	const int							numBytes	= numElems*(int)sizeof(T);
	const T* const						mappedData	= (const T*)gl.mapBufferRange(bufferTarget, 0, numBytes, GL_MAP_READ_BIT);
	GLU_EXPECT_NO_ERROR(gl.getError(), (string() + "glMapBufferRange(" + glu::getBufferTargetName((int)bufferTarget) + ", 0, " + de::toString(numBytes) + ", GL_MAP_READ_BIT)").c_str());
	TCU_CHECK(mappedData != DE_NULL);

	for (int i = 0; i < numElems; i++)
		dst[i] = mappedData[i];

	gl.unmapBuffer(bufferTarget);
}

template <typename T>
static vector<T> readDataMapped (const glw::Functions& gl, deUint32 bufferTarget, int numElems)
{
	vector<T> result(numElems);
	readDataMapped(gl, bufferTarget, numElems, &result[0]);
	return result;
}

namespace
{

template <typename ArgT, bool res>
struct ConstantUnaryPredicate
{
	bool operator() (const ArgT&) const { return res; }
};

//! Helper for handling simple, one-varying transform feedbacks.
template <typename VaryingT>
class TransformFeedbackHandler
{
public:
	struct Result
	{
		int					numPrimitives;
		vector<VaryingT>	varying;

		Result (void)								: numPrimitives(-1) {}
		Result (int n, const vector<VaryingT>& v)	: numPrimitives(n), varying(v) {}
	};

									TransformFeedbackHandler	(const glu::RenderContext& renderCtx, int maxNumVertices);

	Result							renderAndGetPrimitives		(deUint32 programGL, deUint32 tfPrimTypeGL, int numBindings, const glu::VertexArrayBinding* bindings, int numVertices) const;

private:
	const glu::RenderContext&		m_renderCtx;
	const glu::TransformFeedback	m_tf;
	const glu::Buffer				m_tfBuffer;
	const glu::Query				m_tfPrimQuery;
};

template <typename AttribType>
TransformFeedbackHandler<AttribType>::TransformFeedbackHandler (const glu::RenderContext& renderCtx, int maxNumVertices)
	: m_renderCtx		(renderCtx)
	, m_tf				(renderCtx)
	, m_tfBuffer		(renderCtx)
	, m_tfPrimQuery		(renderCtx)
{
	const glw::Functions&	gl			= m_renderCtx.getFunctions();
	// \note Room for 1 extra triangle, to detect if GL returns too many primitives.
	const int				bufferSize	= (maxNumVertices + 3) * (int)sizeof(AttribType);

	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, *m_tfBuffer);
	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_READ);
}

template <typename AttribType>
typename TransformFeedbackHandler<AttribType>::Result TransformFeedbackHandler<AttribType>::renderAndGetPrimitives (deUint32 programGL, deUint32 tfPrimTypeGL, int numBindings, const glu::VertexArrayBinding* bindings, int numVertices) const
{
	DE_ASSERT(tfPrimTypeGL == GL_POINTS || tfPrimTypeGL == GL_LINES || tfPrimTypeGL == GL_TRIANGLES);

	const glw::Functions& gl = m_renderCtx.getFunctions();

	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, *m_tf);
	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, *m_tfBuffer);
	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, *m_tfBuffer);

	gl.beginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, *m_tfPrimQuery);
	gl.beginTransformFeedback(tfPrimTypeGL);

	glu::draw(m_renderCtx, programGL, numBindings, bindings, glu::pr::Patches(numVertices));
	GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed");

	gl.endTransformFeedback();
	gl.endQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);

	{
		const int numPrimsWritten = (int)getQueryResult(gl, *m_tfPrimQuery);
		return Result(numPrimsWritten, readDataMapped<AttribType>(gl, GL_TRANSFORM_FEEDBACK_BUFFER, numPrimsWritten * numVerticesPerPrimitive(tfPrimTypeGL)));
	}
}

template <typename T>
class SizeLessThan
{
public:
	bool operator() (const T& a, const T& b) const { return a.size() < b.size(); }
};

//! Predicate functor for comparing structs by their members.
template <typename Pred, typename T, typename MembT>
class MemberPred
{
public:
				MemberPred	(MembT T::* membP) : m_membP(membP), m_pred(Pred()) {}
	bool		operator()	(const T& a, const T& b) const { return m_pred(a.*m_membP, b.*m_membP); }

private:
	MembT T::*	m_membP;
	Pred		m_pred;
};

//! Convenience wrapper for MemberPred, because class template arguments aren't deduced based on constructor arguments.
template <template <typename> class Pred, typename T, typename MembT>
static MemberPred<Pred<MembT>, T, MembT> memberPred (MembT T::* membP) { return MemberPred<Pred<MembT>, T, MembT>(membP); }

template <typename SeqT, int Size, typename Pred>
class LexCompare
{
public:
	LexCompare (void) : m_pred(Pred()) {}

	bool operator() (const SeqT& a, const SeqT& b) const
	{
		for (int i = 0; i < Size; i++)
		{
			if (m_pred(a[i], b[i]))
				return true;
			if (m_pred(b[i], a[i]))
				return false;
		}
		return false;
	}

private:
	Pred m_pred;
};

template <int Size>
class VecLexLessThan : public LexCompare<tcu::Vector<float, Size>, Size, std::less<float> >
{
};

enum TessPrimitiveType
{
	TESSPRIMITIVETYPE_TRIANGLES = 0,
	TESSPRIMITIVETYPE_QUADS,
	TESSPRIMITIVETYPE_ISOLINES,

	TESSPRIMITIVETYPE_LAST
};

enum SpacingMode
{
	SPACINGMODE_EQUAL,
	SPACINGMODE_FRACTIONAL_ODD,
	SPACINGMODE_FRACTIONAL_EVEN,

	SPACINGMODE_LAST
};

enum Winding
{
	WINDING_CCW = 0,
	WINDING_CW,

	WINDING_LAST
};

static inline const char* getTessPrimitiveTypeShaderName (TessPrimitiveType type)
{
	switch (type)
	{
		case TESSPRIMITIVETYPE_TRIANGLES:	return "triangles";
		case TESSPRIMITIVETYPE_QUADS:		return "quads";
		case TESSPRIMITIVETYPE_ISOLINES:	return "isolines";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

static inline const char* getSpacingModeShaderName (SpacingMode mode)
{
	switch (mode)
	{
		case SPACINGMODE_EQUAL:				return "equal_spacing";
		case SPACINGMODE_FRACTIONAL_ODD:	return "fractional_odd_spacing";
		case SPACINGMODE_FRACTIONAL_EVEN:	return "fractional_even_spacing";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

static inline const char* getWindingShaderName (Winding winding)
{
	switch (winding)
	{
		case WINDING_CCW:	return "ccw";
		case WINDING_CW:	return "cw";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

static inline string getTessellationEvaluationInLayoutString (TessPrimitiveType primType, SpacingMode spacing, Winding winding, bool usePointMode=false)
{
	return string() + "layout (" + getTessPrimitiveTypeShaderName(primType)
								 + ", " + getSpacingModeShaderName(spacing)
								 + ", " + getWindingShaderName(winding)
								 + (usePointMode ? ", point_mode" : "")
								 + ") in;\n";
}

static inline string getTessellationEvaluationInLayoutString (TessPrimitiveType primType, SpacingMode spacing, bool usePointMode=false)
{
	return string() + "layout (" + getTessPrimitiveTypeShaderName(primType)
								 + ", " + getSpacingModeShaderName(spacing)
								 + (usePointMode ? ", point_mode" : "")
								 + ") in;\n";
}

static inline string getTessellationEvaluationInLayoutString (TessPrimitiveType primType, Winding winding, bool usePointMode=false)
{
	return string() + "layout (" + getTessPrimitiveTypeShaderName(primType)
								 + ", " + getWindingShaderName(winding)
								 + (usePointMode ? ", point_mode" : "")
								 + ") in;\n";
}

static inline string getTessellationEvaluationInLayoutString (TessPrimitiveType primType, bool usePointMode=false)
{
	return string() + "layout (" + getTessPrimitiveTypeShaderName(primType)
								 + (usePointMode ? ", point_mode" : "")
								 + ") in;\n";
}

static inline deUint32 outputPrimitiveTypeGL (TessPrimitiveType tessPrimType, bool usePointMode)
{
	if (usePointMode)
		return GL_POINTS;
	else
	{
		switch (tessPrimType)
		{
			case TESSPRIMITIVETYPE_TRIANGLES:	return GL_TRIANGLES;
			case TESSPRIMITIVETYPE_QUADS:		return GL_TRIANGLES;
			case TESSPRIMITIVETYPE_ISOLINES:	return GL_LINES;
			default:
				DE_ASSERT(false);
				return (deUint32)-1;
		}
	}
}

static inline int numInnerTessellationLevels (TessPrimitiveType primType)
{
	switch (primType)
	{
		case TESSPRIMITIVETYPE_TRIANGLES:	return 1;
		case TESSPRIMITIVETYPE_QUADS:		return 2;
		case TESSPRIMITIVETYPE_ISOLINES:	return 0;
		default: DE_ASSERT(false); return -1;
	}
}

static inline int numOuterTessellationLevels (TessPrimitiveType primType)
{
	switch (primType)
	{
		case TESSPRIMITIVETYPE_TRIANGLES:	return 3;
		case TESSPRIMITIVETYPE_QUADS:		return 4;
		case TESSPRIMITIVETYPE_ISOLINES:	return 2;
		default: DE_ASSERT(false); return -1;
	}
}

static string tessellationLevelsString (const float* inner, int numInner, const float* outer, int numOuter)
{
	DE_ASSERT(numInner >= 0 && numOuter >= 0);
	return "inner: " + elemsStr(inner, inner+numInner) + ", outer: " + elemsStr(outer, outer+numOuter);
}

static string tessellationLevelsString (const float* inner, const float* outer, TessPrimitiveType primType)
{
	return tessellationLevelsString(inner, numInnerTessellationLevels(primType), outer, numOuterTessellationLevels(primType));
}

static string tessellationLevelsString (const float* inner, const float* outer)
{
	return tessellationLevelsString(inner, 2, outer, 4);
}

static inline float getClampedTessLevel (SpacingMode mode, float tessLevel)
{
	switch (mode)
	{
		case SPACINGMODE_EQUAL:				return de::max(1.0f, tessLevel);
		case SPACINGMODE_FRACTIONAL_ODD:	return de::max(1.0f, tessLevel);
		case SPACINGMODE_FRACTIONAL_EVEN:	return de::max(2.0f, tessLevel);
		default:
			DE_ASSERT(false);
			return -1.0f;
	}
}

static inline int getRoundedTessLevel (SpacingMode mode, float clampedTessLevel)
{
	int result = (int)deFloatCeil(clampedTessLevel);

	switch (mode)
	{
		case SPACINGMODE_EQUAL:											break;
		case SPACINGMODE_FRACTIONAL_ODD:	result += 1 - result % 2;	break;
		case SPACINGMODE_FRACTIONAL_EVEN:	result += result % 2;		break;
		default:
			DE_ASSERT(false);
	}
	DE_ASSERT(de::inRange<int>(result, 1, MINIMUM_MAX_TESS_GEN_LEVEL));

	return result;
}

static int getClampedRoundedTessLevel (SpacingMode mode, float tessLevel)
{
	return getRoundedTessLevel(mode, getClampedTessLevel(mode, tessLevel));
}

//! A description of an outer edge of a triangle, quad or isolines.
//! An outer edge can be described by the index of a u/v/w coordinate
//! and the coordinate's value along that edge.
struct OuterEdgeDescription
{
	int		constantCoordinateIndex;
	float	constantCoordinateValueChoices[2];
	int		numConstantCoordinateValueChoices;

	OuterEdgeDescription (int i, float c0)			: constantCoordinateIndex(i), numConstantCoordinateValueChoices(1) { constantCoordinateValueChoices[0] = c0; }
	OuterEdgeDescription (int i, float c0, float c1)	: constantCoordinateIndex(i), numConstantCoordinateValueChoices(2) { constantCoordinateValueChoices[0] = c0; constantCoordinateValueChoices[1] = c1; }

	string description (void) const
	{
		static const char* const	coordinateNames[] = { "u", "v", "w" };
		string						result;
		for (int i = 0; i < numConstantCoordinateValueChoices; i++)
			result += string() + (i > 0 ? " or " : "") + coordinateNames[constantCoordinateIndex] + "=" + de::toString(constantCoordinateValueChoices[i]);
		return result;
	}

	bool contains (const Vec3& v) const
	{
		for (int i = 0; i < numConstantCoordinateValueChoices; i++)
			if (v[constantCoordinateIndex] == constantCoordinateValueChoices[i])
				return true;
		return false;
	}
};

static vector<OuterEdgeDescription> outerEdgeDescriptions (TessPrimitiveType primType)
{
	static const OuterEdgeDescription triangleOuterEdgeDescriptions[3] =
	{
		OuterEdgeDescription(0, 0.0f),
		OuterEdgeDescription(1, 0.0f),
		OuterEdgeDescription(2, 0.0f)
	};

	static const OuterEdgeDescription quadOuterEdgeDescriptions[4] =
	{
		OuterEdgeDescription(0, 0.0f),
		OuterEdgeDescription(1, 0.0f),
		OuterEdgeDescription(0, 1.0f),
		OuterEdgeDescription(1, 1.0f)
	};

	static const OuterEdgeDescription isolinesOuterEdgeDescriptions[1] =
	{
		OuterEdgeDescription(0, 0.0f, 1.0f),
	};

	switch (primType)
	{
		case TESSPRIMITIVETYPE_TRIANGLES:	return arrayToVector(triangleOuterEdgeDescriptions);
		case TESSPRIMITIVETYPE_QUADS:		return arrayToVector(quadOuterEdgeDescriptions);
		case TESSPRIMITIVETYPE_ISOLINES:	return arrayToVector(isolinesOuterEdgeDescriptions);
		default: DE_ASSERT(false); return vector<OuterEdgeDescription>();
	}
}

// \note The tessellation coordinates generated by this function could break some of the rules given in the spec (e.g. it may not exactly hold that u+v+w == 1.0f, or [uvw] + (1.0f-[uvw]) == 1.0f).
static vector<Vec3> generateReferenceTriangleTessCoords (SpacingMode spacingMode, int inner, int outer0, int outer1, int outer2)
{
	vector<Vec3> tessCoords;

	if (inner == 1)
	{
		if (outer0 == 1 && outer1 == 1 && outer2 == 1)
		{
			tessCoords.push_back(Vec3(1.0f, 0.0f, 0.0f));
			tessCoords.push_back(Vec3(0.0f, 1.0f, 0.0f));
			tessCoords.push_back(Vec3(0.0f, 0.0f, 1.0f));
			return tessCoords;
		}
		else
			return generateReferenceTriangleTessCoords(spacingMode, spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
																	outer0, outer1, outer2);
	}
	else
	{
		for (int i = 0; i < outer0; i++) { const float v = (float)i / (float)outer0; tessCoords.push_back(Vec3(	   0.0f,		   v,	1.0f - v)); }
		for (int i = 0; i < outer1; i++) { const float v = (float)i / (float)outer1; tessCoords.push_back(Vec3(1.0f - v,		0.0f,		   v)); }
		for (int i = 0; i < outer2; i++) { const float v = (float)i / (float)outer2; tessCoords.push_back(Vec3(		  v,	1.0f - v,		0.0f)); }

		const int numInnerTriangles = inner/2;
		for (int innerTriangleNdx = 0; innerTriangleNdx < numInnerTriangles; innerTriangleNdx++)
		{
			const int curInnerTriangleLevel = inner - 2*(innerTriangleNdx+1);

			if (curInnerTriangleLevel == 0)
				tessCoords.push_back(Vec3(1.0f/3.0f));
			else
			{
				const float		minUVW		= (float)(2 * (innerTriangleNdx + 1)) / (float)(3 * inner);
				const float		maxUVW		= 1.0f - 2.0f*minUVW;
				const Vec3		corners[3]	=
				{
					Vec3(maxUVW, minUVW, minUVW),
					Vec3(minUVW, maxUVW, minUVW),
					Vec3(minUVW, minUVW, maxUVW)
				};

				for (int i = 0; i < curInnerTriangleLevel; i++)
				{
					const float f = (float)i / (float)curInnerTriangleLevel;
					for (int j = 0; j < 3; j++)
						tessCoords.push_back((1.0f - f)*corners[j] + f*corners[(j+1)%3]);
				}
			}
		}

		return tessCoords;
	}
}

static int referenceTriangleNonPointModePrimitiveCount (SpacingMode spacingMode, int inner, int outer0, int outer1, int outer2)
{
	if (inner == 1)
	{
		if (outer0 == 1 && outer1 == 1 && outer2 == 1)
			return 1;
		else
			return referenceTriangleNonPointModePrimitiveCount(spacingMode, spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
																			outer0, outer1, outer2);
	}
	else
	{
		int result = outer0 + outer1 + outer2;

		const int numInnerTriangles = inner/2;
		for (int innerTriangleNdx = 0; innerTriangleNdx < numInnerTriangles; innerTriangleNdx++)
		{
			const int curInnerTriangleLevel = inner - 2*(innerTriangleNdx+1);

			if (curInnerTriangleLevel == 1)
				result += 4;
			else
				result += 2*3*curInnerTriangleLevel;
		}

		return result;
	}
}

// \note The tessellation coordinates generated by this function could break some of the rules given in the spec (e.g. it may not exactly hold that [uv] + (1.0f-[uv]) == 1.0f).
static vector<Vec3> generateReferenceQuadTessCoords (SpacingMode spacingMode, int inner0, int inner1, int outer0, int outer1, int outer2, int outer3)
{
	vector<Vec3> tessCoords;

	if (inner0 == 1 || inner1 == 1)
	{
		if (inner0 == 1 && inner1 == 1 && outer0 == 1 && outer1 == 1 && outer2 == 1 && outer3 == 1)
		{
			tessCoords.push_back(Vec3(0.0f, 0.0f, 0.0f));
			tessCoords.push_back(Vec3(1.0f, 0.0f, 0.0f));
			tessCoords.push_back(Vec3(0.0f, 1.0f, 0.0f));
			tessCoords.push_back(Vec3(1.0f, 1.0f, 0.0f));
			return tessCoords;
		}
		else
			return generateReferenceQuadTessCoords(spacingMode, inner0 > 1 ? inner0 : spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
																inner1 > 1 ? inner1 : spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
																outer0, outer1, outer2, outer3);
	}
	else
	{
		for (int i = 0; i < outer0; i++) { const float v = (float)i / (float)outer0; tessCoords.push_back(Vec3(0.0f,	v,			0.0f)); }
		for (int i = 0; i < outer1; i++) { const float v = (float)i / (float)outer1; tessCoords.push_back(Vec3(1.0f-v,	0.0f,		0.0f)); }
		for (int i = 0; i < outer2; i++) { const float v = (float)i / (float)outer2; tessCoords.push_back(Vec3(1.0f,	1.0f-v,		0.0f)); }
		for (int i = 0; i < outer3; i++) { const float v = (float)i / (float)outer3; tessCoords.push_back(Vec3(v,		1.0f,		0.0f)); }

		for (int innerVtxY = 0; innerVtxY < inner1-1; innerVtxY++)
		for (int innerVtxX = 0; innerVtxX < inner0-1; innerVtxX++)
			tessCoords.push_back(Vec3((float)(innerVtxX + 1) / (float)inner0,
									  (float)(innerVtxY + 1) / (float)inner1,
									  0.0f));

		return tessCoords;
	}
}

static int referenceQuadNonPointModePrimitiveCount (SpacingMode spacingMode, int inner0, int inner1, int outer0, int outer1, int outer2, int outer3)
{
	vector<Vec3> tessCoords;

	if (inner0 == 1 || inner1 == 1)
	{
		if (inner0 == 1 && inner1 == 1 && outer0 == 1 && outer1 == 1 && outer2 == 1 && outer3 == 1)
			return 2;
		else
			return referenceQuadNonPointModePrimitiveCount(spacingMode, inner0 > 1 ? inner0 : spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
																		inner1 > 1 ? inner1 : spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
																		outer0, outer1, outer2, outer3);
	}
	else
		return 2*(inner0-2)*(inner1-2) + 2*(inner0-2) + 2*(inner1-2) + outer0+outer1+outer2+outer3;
}

// \note The tessellation coordinates generated by this function could break some of the rules given in the spec (e.g. it may not exactly hold that [uv] + (1.0f-[uv]) == 1.0f).
static vector<Vec3> generateReferenceIsolineTessCoords (int outer0, int outer1)
{
	vector<Vec3> tessCoords;

	for (int y = 0; y < outer0;		y++)
	for (int x = 0; x < outer1+1;	x++)
		tessCoords.push_back(Vec3((float)x / (float)outer1,
												  (float)y / (float)outer0,
												  0.0f));

	return tessCoords;
}

static int referenceIsolineNonPointModePrimitiveCount (int outer0, int outer1)
{
	return outer0*outer1;
}

static void getClampedRoundedTriangleTessLevels (SpacingMode spacingMode, const float* innerSrc, const float* outerSrc, int* innerDst, int *outerDst)
{
	innerDst[0] = getClampedRoundedTessLevel(spacingMode, innerSrc[0]);
	for (int i = 0; i < 3; i++)
		outerDst[i] = getClampedRoundedTessLevel(spacingMode, outerSrc[i]);
}

static void getClampedRoundedQuadTessLevels (SpacingMode spacingMode, const float* innerSrc, const float* outerSrc, int* innerDst, int *outerDst)
{
	for (int i = 0; i < 2; i++)
		innerDst[i] = getClampedRoundedTessLevel(spacingMode, innerSrc[i]);
	for (int i = 0; i < 4; i++)
		outerDst[i] = getClampedRoundedTessLevel(spacingMode, outerSrc[i]);
}

static void getClampedRoundedIsolineTessLevels (SpacingMode spacingMode, const float* outerSrc, int* outerDst)
{
	outerDst[0] = getClampedRoundedTessLevel(SPACINGMODE_EQUAL,	outerSrc[0]);
	outerDst[1] = getClampedRoundedTessLevel(spacingMode,		outerSrc[1]);
}

static inline bool isPatchDiscarded (TessPrimitiveType primitiveType, const float* outerLevels)
{
	const int numOuterLevels = numOuterTessellationLevels(primitiveType);
	for (int i = 0; i < numOuterLevels; i++)
		if (outerLevels[i] <= 0.0f)
			return true;
	return false;
}

static vector<Vec3> generateReferenceTessCoords (TessPrimitiveType primitiveType, SpacingMode spacingMode, const float* innerLevels, const float* outerLevels)
{
	if (isPatchDiscarded(primitiveType, outerLevels))
		return vector<Vec3>();

	switch (primitiveType)
	{
		case TESSPRIMITIVETYPE_TRIANGLES:
		{
			int inner;
			int outer[3];
			getClampedRoundedTriangleTessLevels(spacingMode, innerLevels, outerLevels, &inner, &outer[0]);

			if (spacingMode != SPACINGMODE_EQUAL)
			{
				// \note For fractional spacing modes, exact results are implementation-defined except in special cases.
				DE_ASSERT(de::abs(innerLevels[0] - (float)inner) < 0.001f);
				for (int i = 0; i < 3; i++)
					DE_ASSERT(de::abs(outerLevels[i] - (float)outer[i]) < 0.001f);
				DE_ASSERT(inner > 1 || (outer[0] == 1 && outer[1] == 1 && outer[2] == 1));
			}

			return generateReferenceTriangleTessCoords(spacingMode, inner, outer[0], outer[1], outer[2]);
		}

		case TESSPRIMITIVETYPE_QUADS:
		{
			int inner[2];
			int outer[4];
			getClampedRoundedQuadTessLevels(spacingMode, innerLevels, outerLevels, &inner[0], &outer[0]);

			if (spacingMode != SPACINGMODE_EQUAL)
			{
				// \note For fractional spacing modes, exact results are implementation-defined except in special cases.
				for (int i = 0; i < 2; i++)
					DE_ASSERT(de::abs(innerLevels[i] - (float)inner[i]) < 0.001f);
				for (int i = 0; i < 4; i++)
					DE_ASSERT(de::abs(outerLevels[i] - (float)outer[i]) < 0.001f);

				DE_ASSERT((inner[0] > 1 && inner[1] > 1) || (inner[0] == 1 && inner[1] == 1 && outer[0] == 1 && outer[1] == 1 && outer[2] == 1 && outer[3] == 1));
			}

			return generateReferenceQuadTessCoords(spacingMode, inner[0], inner[1], outer[0], outer[1], outer[2], outer[3]);
		}

		case TESSPRIMITIVETYPE_ISOLINES:
		{
			int outer[2];
			getClampedRoundedIsolineTessLevels(spacingMode, &outerLevels[0], &outer[0]);

			if (spacingMode != SPACINGMODE_EQUAL)
			{
				// \note For fractional spacing modes, exact results are implementation-defined except in special cases.
				DE_ASSERT(de::abs(outerLevels[1] - (float)outer[1]) < 0.001f);
			}

			return generateReferenceIsolineTessCoords(outer[0], outer[1]);
		}

		default:
			DE_ASSERT(false);
			return vector<Vec3>();
	}
}

static int referencePointModePrimitiveCount (TessPrimitiveType primitiveType, SpacingMode spacingMode, const float* innerLevels, const float* outerLevels)
{
	if (isPatchDiscarded(primitiveType, outerLevels))
		return 0;

	switch (primitiveType)
	{
		case TESSPRIMITIVETYPE_TRIANGLES:
		{
			int inner;
			int outer[3];
			getClampedRoundedTriangleTessLevels(spacingMode, innerLevels, outerLevels, &inner, &outer[0]);
			return (int)generateReferenceTriangleTessCoords(spacingMode, inner, outer[0], outer[1], outer[2]).size();
		}

		case TESSPRIMITIVETYPE_QUADS:
		{
			int inner[2];
			int outer[4];
			getClampedRoundedQuadTessLevels(spacingMode, innerLevels, outerLevels, &inner[0], &outer[0]);
			return (int)generateReferenceQuadTessCoords(spacingMode, inner[0], inner[1], outer[0], outer[1], outer[2], outer[3]).size();
		}

		case TESSPRIMITIVETYPE_ISOLINES:
		{
			int outer[2];
			getClampedRoundedIsolineTessLevels(spacingMode, &outerLevels[0], &outer[0]);
			return (int)generateReferenceIsolineTessCoords(outer[0], outer[1]).size();
		}

		default:
			DE_ASSERT(false);
			return -1;
	}
}

static int referenceNonPointModePrimitiveCount (TessPrimitiveType primitiveType, SpacingMode spacingMode, const float* innerLevels, const float* outerLevels)
{
	if (isPatchDiscarded(primitiveType, outerLevels))
		return 0;

	switch (primitiveType)
	{
		case TESSPRIMITIVETYPE_TRIANGLES:
		{
			int inner;
			int outer[3];
			getClampedRoundedTriangleTessLevels(spacingMode, innerLevels, outerLevels, &inner, &outer[0]);
			return referenceTriangleNonPointModePrimitiveCount(spacingMode, inner, outer[0], outer[1], outer[2]);
		}

		case TESSPRIMITIVETYPE_QUADS:
		{
			int inner[2];
			int outer[4];
			getClampedRoundedQuadTessLevels(spacingMode, innerLevels, outerLevels, &inner[0], &outer[0]);
			return referenceQuadNonPointModePrimitiveCount(spacingMode, inner[0], inner[1], outer[0], outer[1], outer[2], outer[3]);
		}

		case TESSPRIMITIVETYPE_ISOLINES:
		{
			int outer[2];
			getClampedRoundedIsolineTessLevels(spacingMode, &outerLevels[0], &outer[0]);
			return referenceIsolineNonPointModePrimitiveCount(outer[0], outer[1]);
		}

		default:
			DE_ASSERT(false);
			return -1;
	}
}

static int referencePrimitiveCount (TessPrimitiveType primitiveType, SpacingMode spacingMode, bool usePointMode, const float* innerLevels, const float* outerLevels)
{
	return usePointMode ? referencePointModePrimitiveCount		(primitiveType, spacingMode, innerLevels, outerLevels)
						: referenceNonPointModePrimitiveCount	(primitiveType, spacingMode, innerLevels, outerLevels);
}

static int referenceVertexCount (TessPrimitiveType primitiveType, SpacingMode spacingMode, bool usePointMode, const float* innerLevels, const float* outerLevels)
{
	return referencePrimitiveCount(primitiveType, spacingMode, usePointMode, innerLevels, outerLevels)
		   * numVerticesPerPrimitive(outputPrimitiveTypeGL(primitiveType, usePointMode));
}

//! Helper for calling referenceVertexCount multiple times with different tessellation levels.
//! \note Levels contains inner and outer levels, per patch, in order IIOOOO. The full 6 levels must always be present, irrespective of primitiveType.
static int multiplePatchReferenceVertexCount (TessPrimitiveType primitiveType, SpacingMode spacingMode, bool usePointMode, const float* levels, int numPatches)
{
	int result = 0;
	for (int patchNdx = 0; patchNdx < numPatches; patchNdx++)
		result += referenceVertexCount(primitiveType, spacingMode, usePointMode, &levels[6*patchNdx + 0], &levels[6*patchNdx + 2]);
	return result;
}

vector<float> generateRandomPatchTessLevels (int numPatches, int constantOuterLevelIndex, float constantOuterLevel, de::Random& rnd)
{
	vector<float> tessLevels(numPatches*6);

	for (int patchNdx = 0; patchNdx < numPatches; patchNdx++)
	{
		float* const inner = &tessLevels[patchNdx*6 + 0];
		float* const outer = &tessLevels[patchNdx*6 + 2];

		for (int j = 0; j < 2; j++)
			inner[j] = rnd.getFloat(1.0f, 62.0f);
		for (int j = 0; j < 4; j++)
			outer[j] = j == constantOuterLevelIndex ? constantOuterLevel : rnd.getFloat(1.0f, 62.0f);
	}

	return tessLevels;
}

static inline void drawPoint (tcu::Surface& dst, int centerX, int centerY, const tcu::RGBA& color, int size)
{
	const int width		= dst.getWidth();
	const int height	= dst.getHeight();
	DE_ASSERT(de::inBounds(centerX, 0, width) && de::inBounds(centerY, 0, height));
	DE_ASSERT(size > 0);

	for (int yOff = -((size-1)/2); yOff <= size/2; yOff++)
	for (int xOff = -((size-1)/2); xOff <= size/2; xOff++)
	{
		const int pixX = centerX + xOff;
		const int pixY = centerY + yOff;
		if (de::inBounds(pixX, 0, width) && de::inBounds(pixY, 0, height))
			dst.setPixel(pixX, pixY, color);
	}
}

static void drawTessCoordPoint (tcu::Surface& dst, TessPrimitiveType primitiveType, const Vec3& pt, const tcu::RGBA& color, int size)
{
	// \note These coordinates should match the description in the log message in TessCoordCase::iterate.

	static const Vec2 triangleCorners[3] =
	{
		Vec2(0.95f, 0.95f),
		Vec2(0.5f,  0.95f - 0.9f*deFloatSqrt(3.0f/4.0f)),
		Vec2(0.05f, 0.95f)
	};

	static const float quadIsolineLDRU[4] =
	{
		0.1f, 0.9f, 0.9f, 0.1f
	};

	const Vec2 dstPos = primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? pt.x()*triangleCorners[0]
																	 + pt.y()*triangleCorners[1]
																	 + pt.z()*triangleCorners[2]

					  : primitiveType == TESSPRIMITIVETYPE_QUADS ||
						primitiveType == TESSPRIMITIVETYPE_ISOLINES ? Vec2((1.0f - pt.x())*quadIsolineLDRU[0] + pt.x()*quadIsolineLDRU[2],
																		   (1.0f - pt.y())*quadIsolineLDRU[1] + pt.y()*quadIsolineLDRU[3])

					  : Vec2(-1.0f);

	drawPoint(dst, (int)(dstPos.x()*dst.getWidth()), (int)(dstPos.y()*dst.getHeight()), color, size);
}

static void drawTessCoordVisualization (tcu::Surface& dst, TessPrimitiveType primitiveType, const vector<Vec3>& coords)
{
	const int		imageWidth		= 256;
	const int		imageHeight		= 256;
	const Vec2		imageSizeFloat	((float)imageWidth, (float)imageHeight);
	dst.setSize(imageWidth, imageHeight);

	tcu::clear(dst.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));

	for (int i = 0; i < (int)coords.size(); i++)
		drawTessCoordPoint(dst, primitiveType, coords[i], tcu::RGBA::white, 2);
}

static int binarySearchFirstVec3WithXAtLeast (const vector<Vec3>& sorted, float x)
{
	const Vec3 ref(x, 0.0f, 0.0f);
	const vector<Vec3>::const_iterator first = std::lower_bound(sorted.begin(), sorted.end(), ref, vec3XLessThan);
	if (first == sorted.end())
		return -1;
	return (int)std::distance(sorted.begin(), first);
}

template <typename T, typename P>
static vector<T> sorted (const vector<T>& unsorted, P pred)
{
	vector<T> result = unsorted;
	std::sort(result.begin(), result.end(), pred);
	return result;
}

template <typename T>
static vector<T> sorted (const vector<T>& unsorted)
{
	vector<T> result = unsorted;
	std::sort(result.begin(), result.end());
	return result;
}

// Check that all points in subset are (approximately) present also in superset.
static bool oneWayComparePointSets (TestLog&				log,
									tcu::Surface&			errorDst,
									TessPrimitiveType		primitiveType,
									const vector<Vec3>&		subset,
									const vector<Vec3>&		superset,
									const char*				subsetName,
									const char*				supersetName,
									const tcu::RGBA&		errorColor)
{
	const vector<Vec3>	supersetSorted			= sorted(superset, vec3XLessThan);
	const float			epsilon					= 0.01f;
	const int			maxNumFailurePrints		= 5;
	int					numFailuresDetected		= 0;

	for (int subNdx = 0; subNdx < (int)subset.size(); subNdx++)
	{
		const Vec3& subPt = subset[subNdx];

		bool matchFound = false;

		{
			// Binary search the index of the first point in supersetSorted with x in the [subPt.x() - epsilon, subPt.x() + epsilon] range.
			const Vec3	matchMin			= subPt - epsilon;
			const Vec3	matchMax			= subPt + epsilon;
			int			firstCandidateNdx	= binarySearchFirstVec3WithXAtLeast(supersetSorted, matchMin.x());

			if (firstCandidateNdx >= 0)
			{
				// Compare subPt to all points in supersetSorted with x in the [subPt.x() - epsilon, subPt.x() + epsilon] range.
				for (int superNdx = firstCandidateNdx; superNdx < (int)supersetSorted.size() && supersetSorted[superNdx].x() <= matchMax.x(); superNdx++)
				{
					const Vec3& superPt = supersetSorted[superNdx];

					if (tcu::boolAll(tcu::greaterThanEqual	(superPt, matchMin)) &&
						tcu::boolAll(tcu::lessThanEqual		(superPt, matchMax)))
					{
						matchFound = true;
						break;
					}
				}
			}
		}

		if (!matchFound)
		{
			numFailuresDetected++;
			if (numFailuresDetected < maxNumFailurePrints)
				log << TestLog::Message << "Failure: no matching " << supersetName << " point found for " << subsetName << " point " << subPt << TestLog::EndMessage;
			else if (numFailuresDetected == maxNumFailurePrints)
				log << TestLog::Message << "Note: More errors follow" << TestLog::EndMessage;

			drawTessCoordPoint(errorDst, primitiveType, subPt, errorColor, 4);
		}
	}

	return numFailuresDetected == 0;
}

static bool compareTessCoords (TestLog& log, TessPrimitiveType primitiveType, const vector<Vec3>& refCoords, const vector<Vec3>& resCoords)
{
	tcu::Surface	refVisual;
	tcu::Surface	resVisual;
	bool			success = true;

	drawTessCoordVisualization(refVisual, primitiveType, refCoords);
	drawTessCoordVisualization(resVisual, primitiveType, resCoords);

	// Check that all points in reference also exist in result.
	success = oneWayComparePointSets(log, refVisual, primitiveType, refCoords, resCoords, "reference", "result", tcu::RGBA::blue) && success;
	// Check that all points in result also exist in reference.
	success = oneWayComparePointSets(log, resVisual, primitiveType, resCoords, refCoords, "result", "reference", tcu::RGBA::red) && success;

	if (!success)
	{
		log << TestLog::Message << "Note: in the following reference visualization, points that are missing in result point set are blue (if any)" << TestLog::EndMessage
			<< TestLog::Image("RefTessCoordVisualization", "Reference tessCoord visualization", refVisual)
			<< TestLog::Message << "Note: in the following result visualization, points that are missing in reference point set are red (if any)" << TestLog::EndMessage;
	}

	log << TestLog::Image("ResTessCoordVisualization", "Result tessCoord visualization", resVisual);

	return success;
}

namespace VerifyFractionalSpacingSingleInternal
{

struct Segment
{
	int		index; //!< Index of left coordinate in sortedXCoords.
	float	length;
	Segment (void)						: index(-1),		length(-1.0f)	{}
	Segment (int index_, float length_)	: index(index_),	length(length_)	{}

	static vector<float> lengths (const vector<Segment>& segments) { return members(segments, &Segment::length); }
};

}

/*--------------------------------------------------------------------*//*!
 * \brief Verify fractional spacing conditions for a single line
 *
 * Verify that the splitting of an edge (resulting from e.g. an isoline
 * with outer levels { 1.0, tessLevel }) with a given fractional spacing
 * mode fulfills certain conditions given in the spec.
 *
 * Note that some conditions can't be checked from just one line
 * (specifically, that the additional segment decreases monotonically
 * length and the requirement that the additional segments be placed
 * identically for identical values of clamped level).
 *
 * Therefore, the function stores some values to additionalSegmentLengthDst
 * and additionalSegmentLocationDst that can later be given to
 * verifyFractionalSpacingMultiple(). A negative value in length means that
 * no additional segments are present, i.e. there's just one segment.
 * A negative value in location means that the value wasn't determinable,
 * i.e. all segments had same length.
 * The values are not stored if false is returned.
 *//*--------------------------------------------------------------------*/
static bool verifyFractionalSpacingSingle (TestLog& log, SpacingMode spacingMode, float tessLevel, const vector<float>& coords, float& additionalSegmentLengthDst, int& additionalSegmentLocationDst)
{
	using namespace VerifyFractionalSpacingSingleInternal;

	DE_ASSERT(spacingMode == SPACINGMODE_FRACTIONAL_ODD || spacingMode == SPACINGMODE_FRACTIONAL_EVEN);

	const float				clampedLevel	= getClampedTessLevel(spacingMode, tessLevel);
	const int				finalLevel		= getRoundedTessLevel(spacingMode, clampedLevel);
	const vector<float>		sortedCoords	= sorted(coords);
	string					failNote		= "Note: tessellation level is " + de::toString(tessLevel) + "\nNote: sorted coordinates are:\n    " + containerStr(sortedCoords);

	if ((int)coords.size() != finalLevel + 1)
	{
		log << TestLog::Message << "Failure: number of vertices is " << coords.size() << "; expected " << finalLevel + 1
			<< " (clamped tessellation level is " << clampedLevel << ")"
			<< "; final level (clamped level rounded up to " << (spacingMode == SPACINGMODE_FRACTIONAL_EVEN ? "even" : "odd") << ") is " << finalLevel
			<< " and should equal the number of segments, i.e. number of vertices minus 1" << TestLog::EndMessage
			<< TestLog::Message << failNote << TestLog::EndMessage;
		return false;
	}

	if (sortedCoords[0] != 0.0f || sortedCoords.back() != 1.0f)
	{
		log << TestLog::Message << "Failure: smallest coordinate should be 0.0 and biggest should be 1.0" << TestLog::EndMessage
			<< TestLog::Message << failNote << TestLog::EndMessage;
		return false;
	}

	{
		vector<Segment> segments(finalLevel);
		for (int i = 0; i < finalLevel; i++)
			segments[i] = Segment(i, sortedCoords[i+1] - sortedCoords[i]);

		failNote += "\nNote: segment lengths are, from left to right:\n    " + containerStr(Segment::lengths(segments));

		{
			// Divide segments to two different groups based on length.

			vector<Segment> segmentsA;
			vector<Segment> segmentsB;
			segmentsA.push_back(segments[0]);

			for (int segNdx = 1; segNdx < (int)segments.size(); segNdx++)
			{
				const float		epsilon		= 0.001f;
				const Segment&	seg			= segments[segNdx];

				if (de::abs(seg.length - segmentsA[0].length) < epsilon)
					segmentsA.push_back(seg);
				else if (segmentsB.empty() || de::abs(seg.length - segmentsB[0].length) < epsilon)
					segmentsB.push_back(seg);
				else
				{
					log << TestLog::Message << "Failure: couldn't divide segments to 2 groups by length; "
											<< "e.g. segment of length " << seg.length << " isn't approximately equal to either "
											<< segmentsA[0].length << " or " << segmentsB[0].length << TestLog::EndMessage
											<< TestLog::Message << failNote << TestLog::EndMessage;
					return false;
				}
			}

			if (clampedLevel == (float)finalLevel)
			{
				// All segments should be of equal length.
				if (!segmentsA.empty() && !segmentsB.empty())
				{
					log << TestLog::Message << "Failure: clamped and final tessellation level are equal, but not all segments are of equal length." << TestLog::EndMessage
						<< TestLog::Message << failNote << TestLog::EndMessage;
					return false;
				}
			}

			if (segmentsA.empty() || segmentsB.empty()) // All segments have same length. This is ok.
			{
				additionalSegmentLengthDst		= segments.size() == 1 ? -1.0f : segments[0].length;
				additionalSegmentLocationDst	= -1;
				return true;
			}

			if (segmentsA.size() != 2 && segmentsB.size() != 2)
			{
				log << TestLog::Message << "Failure: when dividing the segments to 2 groups by length, neither of the two groups has exactly 2 or 0 segments in it" << TestLog::EndMessage
					<< TestLog::Message << failNote << TestLog::EndMessage;
				return false;
			}

			// For convenience, arrange so that the 2-segment group is segmentsB.
			if (segmentsB.size() != 2)
				std::swap(segmentsA, segmentsB);

			// \note For 4-segment lines both segmentsA and segmentsB have 2 segments each.
			//		 Thus, we can't be sure which ones were meant as the additional segments.
			//		 We give the benefit of the doubt by assuming that they're the shorter
			//		 ones (as they should).

			if (segmentsA.size() != 2)
			{
				if (segmentsB[0].length > segmentsA[0].length + 0.001f)
				{
					log << TestLog::Message << "Failure: the two additional segments are longer than the other segments" << TestLog::EndMessage
						<< TestLog::Message << failNote << TestLog::EndMessage;
					return false;
				}
			}
			else
			{
				// We have 2 segmentsA and 2 segmentsB, ensure segmentsB has the shorter lengths
				if (segmentsB[0].length > segmentsA[0].length)
					std::swap(segmentsA, segmentsB);
			}

			// Check that the additional segments are placed symmetrically.
			if (segmentsB[0].index + segmentsB[1].index + 1 != (int)segments.size())
			{
				log << TestLog::Message << "Failure: the two additional segments aren't placed symmetrically; "
										<< "one is at index " << segmentsB[0].index << " and other is at index " << segmentsB[1].index
										<< " (note: the two indexes should sum to " << (int)segments.size()-1 << ", i.e. numberOfSegments-1)" << TestLog::EndMessage
					<< TestLog::Message << failNote << TestLog::EndMessage;
				return false;
			}

			additionalSegmentLengthDst = segmentsB[0].length;
			if (segmentsA.size() != 2)
				additionalSegmentLocationDst = de::min(segmentsB[0].index, segmentsB[1].index);
			else
				additionalSegmentLocationDst = segmentsB[0].length < segmentsA[0].length - 0.001f ? de::min(segmentsB[0].index, segmentsB[1].index)
											 : -1; // \note -1 when can't reliably decide which ones are the additional segments, a or b.

			return true;
		}
	}
}

namespace VerifyFractionalSpacingMultipleInternal
{

struct LineData
{
	float	tessLevel;
	float	additionalSegmentLength;
	int		additionalSegmentLocation;
	LineData (float lev, float len, int loc) : tessLevel(lev), additionalSegmentLength(len), additionalSegmentLocation(loc) {}
};

}

/*--------------------------------------------------------------------*//*!
 * \brief Verify fractional spacing conditions between multiple lines
 *
 * Verify the fractional spacing conditions that are not checked in
 * verifyFractionalSpacingSingle(). Uses values given by said function
 * as parameters, in addition to the spacing mode and tessellation level.
 *//*--------------------------------------------------------------------*/
static bool verifyFractionalSpacingMultiple (TestLog& log, SpacingMode spacingMode, const vector<float>& tessLevels, const vector<float>& additionalSegmentLengths, const vector<int>& additionalSegmentLocations)
{
	using namespace VerifyFractionalSpacingMultipleInternal;

	DE_ASSERT(spacingMode == SPACINGMODE_FRACTIONAL_ODD || spacingMode == SPACINGMODE_FRACTIONAL_EVEN);
	DE_ASSERT(tessLevels.size() == additionalSegmentLengths.size() &&
			  tessLevels.size() == additionalSegmentLocations.size());

	vector<LineData> lineDatas;

	for (int i = 0; i < (int)tessLevels.size(); i++)
		lineDatas.push_back(LineData(tessLevels[i], additionalSegmentLengths[i], additionalSegmentLocations[i]));

	{
		const vector<LineData> lineDatasSortedByLevel = sorted(lineDatas, memberPred<std::less>(&LineData::tessLevel));

		// Check that lines with identical clamped tessellation levels have identical additionalSegmentLocation.

		for (int lineNdx = 1; lineNdx < (int)lineDatasSortedByLevel.size(); lineNdx++)
		{
			const LineData& curData		= lineDatasSortedByLevel[lineNdx];
			const LineData& prevData	= lineDatasSortedByLevel[lineNdx-1];

			if (curData.additionalSegmentLocation < 0 || prevData.additionalSegmentLocation < 0)
				continue; // Unknown locations, skip.

			if (getClampedTessLevel(spacingMode, curData.tessLevel) == getClampedTessLevel(spacingMode, prevData.tessLevel) &&
				curData.additionalSegmentLocation != prevData.additionalSegmentLocation)
			{
				log << TestLog::Message << "Failure: additional segments not located identically for two edges with identical clamped tessellation levels" << TestLog::EndMessage
					<< TestLog::Message << "Note: tessellation levels are " << curData.tessLevel << " and " << prevData.tessLevel
										<< " (clamped level " << getClampedTessLevel(spacingMode, curData.tessLevel) << ")"
										<< "; but first additional segments located at indices "
										<< curData.additionalSegmentLocation << " and " << prevData.additionalSegmentLocation << ", respectively" << TestLog::EndMessage;
				return false;
			}
		}

		// Check that, among lines with same clamped rounded tessellation level, additionalSegmentLength is monotonically decreasing with "clampedRoundedTessLevel - clampedTessLevel" (the "fraction").

		for (int lineNdx = 1; lineNdx < (int)lineDatasSortedByLevel.size(); lineNdx++)
		{
			const LineData&		curData				= lineDatasSortedByLevel[lineNdx];
			const LineData&		prevData			= lineDatasSortedByLevel[lineNdx-1];

			if (curData.additionalSegmentLength < 0.0f || prevData.additionalSegmentLength < 0.0f)
				continue; // Unknown segment lengths, skip.

			const float			curClampedLevel		= getClampedTessLevel(spacingMode, curData.tessLevel);
			const float			prevClampedLevel	= getClampedTessLevel(spacingMode, prevData.tessLevel);
			const int			curFinalLevel		= getRoundedTessLevel(spacingMode, curClampedLevel);
			const int			prevFinalLevel		= getRoundedTessLevel(spacingMode, prevClampedLevel);

			if (curFinalLevel != prevFinalLevel)
				continue;

			const float			curFraction		= curFinalLevel - curClampedLevel;
			const float			prevFraction	= prevFinalLevel - prevClampedLevel;

			if (curData.additionalSegmentLength < prevData.additionalSegmentLength ||
				(curClampedLevel == prevClampedLevel && curData.additionalSegmentLength != prevData.additionalSegmentLength))
			{
				log << TestLog::Message << "Failure: additional segment length isn't monotonically decreasing with the fraction <n> - <f>, among edges with same final tessellation level" << TestLog::EndMessage
					<< TestLog::Message << "Note: <f> stands for the clamped tessellation level and <n> for the final (rounded and clamped) tessellation level" << TestLog::EndMessage
					<< TestLog::Message << "Note: two edges have tessellation levels " << prevData.tessLevel << " and " << curData.tessLevel << " respectively"
										<< ", clamped " << prevClampedLevel << " and " << curClampedLevel << ", final " << prevFinalLevel << " and " << curFinalLevel
										<< "; fractions are " << prevFraction << " and " << curFraction
										<< ", but resulted in segment lengths " << prevData.additionalSegmentLength << " and " << curData.additionalSegmentLength << TestLog::EndMessage;
				return false;
			}
		}
	}

	return true;
}

//! Compare triangle sets, ignoring triangle order and vertex order within triangle, and possibly exclude some triangles too.
template <typename IsTriangleRelevantT>
static bool compareTriangleSets (const vector<Vec3>&			coordsA,
								 const vector<Vec3>&			coordsB,
								 TestLog&						log,
								 const IsTriangleRelevantT&		isTriangleRelevant,
								 const char*					ignoredTriangleDescription = DE_NULL)
{
	typedef tcu::Vector<Vec3, 3>							Triangle;
	typedef LexCompare<Triangle, 3, VecLexLessThan<3> >		TriangleLexLessThan;
	typedef std::set<Triangle, TriangleLexLessThan>			TriangleSet;

	DE_ASSERT(coordsA.size() % 3 == 0 && coordsB.size() % 3 == 0);

	const int		numTrianglesA = (int)coordsA.size()/3;
	const int		numTrianglesB = (int)coordsB.size()/3;
	TriangleSet		trianglesA;
	TriangleSet		trianglesB;

	for (int aOrB = 0; aOrB < 2; aOrB++)
	{
		const vector<Vec3>&		coords			= aOrB == 0 ? coordsA			: coordsB;
		const int				numTriangles	= aOrB == 0 ? numTrianglesA		: numTrianglesB;
		TriangleSet&			triangles		= aOrB == 0 ? trianglesA		: trianglesB;

		for (int triNdx = 0; triNdx < numTriangles; triNdx++)
		{
			Triangle triangle(coords[3*triNdx + 0],
							  coords[3*triNdx + 1],
							  coords[3*triNdx + 2]);

			if (isTriangleRelevant(triangle.getPtr()))
			{
				std::sort(triangle.getPtr(), triangle.getPtr()+3, VecLexLessThan<3>());
				triangles.insert(triangle);
			}
		}
	}

	{
		TriangleSet::const_iterator aIt = trianglesA.begin();
		TriangleSet::const_iterator bIt = trianglesB.begin();

		while (aIt != trianglesA.end() || bIt != trianglesB.end())
		{
			const bool aEnd = aIt == trianglesA.end();
			const bool bEnd = bIt == trianglesB.end();

			if (aEnd || bEnd || *aIt != *bIt)
			{
				log << TestLog::Message << "Failure: triangle sets in two cases are not equal (when ignoring triangle and vertex order"
					<< (ignoredTriangleDescription == DE_NULL ? "" : string() + ", and " + ignoredTriangleDescription) << ")" << TestLog::EndMessage;

				if (!aEnd && (bEnd || TriangleLexLessThan()(*aIt, *bIt)))
					log << TestLog::Message << "Note: e.g. triangle " << *aIt << " exists for first case but not for second" << TestLog::EndMessage;
				else
					log << TestLog::Message << "Note: e.g. triangle " << *bIt << " exists for second case but not for first" << TestLog::EndMessage;

				return false;
			}

			++aIt;
			++bIt;
		}

		return true;
	}
}

static bool compareTriangleSets (const vector<Vec3>& coordsA, const vector<Vec3>& coordsB, TestLog& log)
{
	return compareTriangleSets(coordsA, coordsB, log, ConstantUnaryPredicate<const Vec3*, true>());
}

static void checkExtensionSupport (Context& context, const char* extName)
{
	if (!context.getContextInfo().isExtensionSupported(extName))
		throw tcu::NotSupportedError(string(extName) + " not supported");
}

static void checkTessellationSupport (Context& context)
{
	checkExtensionSupport(context, "GL_EXT_tessellation_shader");
}

// Draw primitives with shared edges and check that no cracks are visible at the shared edges.
class CommonEdgeCase : public TestCase
{
public:
	enum CaseType
	{
		CASETYPE_BASIC = 0,		//!< Order patch vertices such that when two patches share a vertex, it's at the same index for both.
		CASETYPE_PRECISE,		//!< Vertex indices don't match like for CASETYPE_BASIC, but other measures are taken, using the 'precise' qualifier.

		CASETYPE_LAST
	};

	CommonEdgeCase (Context& context, const char* name, const char* description, TessPrimitiveType primitiveType, SpacingMode spacing, CaseType caseType)
		: TestCase			(context, name, description)
		, m_primitiveType	(primitiveType)
		, m_spacing			(spacing)
		, m_caseType		(caseType)
	{
		DE_ASSERT(m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES || m_primitiveType == TESSPRIMITIVETYPE_QUADS);
	}

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

private:
	static const int				RENDER_SIZE = 256;

	const TessPrimitiveType			m_primitiveType;
	const SpacingMode				m_spacing;
	const CaseType					m_caseType;

	SharedPtr<const ShaderProgram>	m_program;
};

void CommonEdgeCase::init (void)
{
	checkTessellationSupport(m_context);

	if (m_caseType == CASETYPE_PRECISE)
		checkExtensionSupport(m_context, "GL_EXT_gpu_shader5");

	checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE);

	m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
			<< glu::VertexSource					("#version 310 es\n"
													 "\n"
													 "in highp vec2 in_v_position;\n"
													 "in highp float in_v_tessParam;\n"
													 "\n"
													 "out highp vec2 in_tc_position;\n"
													 "out highp float in_tc_tessParam;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	in_tc_position = in_v_position;\n"
													 "	in_tc_tessParam = in_v_tessParam;\n"
													 "}\n")

			<< glu::TessellationControlSource		("#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													 + string(m_caseType == CASETYPE_PRECISE ? "#extension GL_EXT_gpu_shader5 : require\n" : "") +
													 "\n"
													 "layout (vertices = " + string(m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? "3" : m_primitiveType == TESSPRIMITIVETYPE_QUADS ? "4" : DE_NULL) + ") out;\n"
													 "\n"
													 "in highp vec2 in_tc_position[];\n"
													 "in highp float in_tc_tessParam[];\n"
													 "\n"
													 "out highp vec2 in_te_position[];\n"
													 "\n"
													 + (m_caseType == CASETYPE_PRECISE ? "precise gl_TessLevelOuter;\n\n" : "") +
													 "void main (void)\n"
													 "{\n"
													 "	in_te_position[gl_InvocationID] = in_tc_position[gl_InvocationID];\n"
													 "\n"
													 "	gl_TessLevelInner[0] = 5.0;\n"
													 "	gl_TessLevelInner[1] = 5.0;\n"
													 "\n"
													 + (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ?
														"	gl_TessLevelOuter[0] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[1] + in_tc_tessParam[2]);\n"
														"	gl_TessLevelOuter[1] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[2] + in_tc_tessParam[0]);\n"
														"	gl_TessLevelOuter[2] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[0] + in_tc_tessParam[1]);\n"
													  : m_primitiveType == TESSPRIMITIVETYPE_QUADS ?
														"	gl_TessLevelOuter[0] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[0] + in_tc_tessParam[2]);\n"
														"	gl_TessLevelOuter[1] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[1] + in_tc_tessParam[0]);\n"
														"	gl_TessLevelOuter[2] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[3] + in_tc_tessParam[1]);\n"
														"	gl_TessLevelOuter[3] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[2] + in_tc_tessParam[3]);\n"
													  : DE_NULL) +
													 "}\n")

			<< glu::TessellationEvaluationSource	("#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													 + string(m_caseType == CASETYPE_PRECISE ? "#extension GL_EXT_gpu_shader5 : require\n" : "") +
													 "\n"
													 + getTessellationEvaluationInLayoutString(m_primitiveType, m_spacing) +
													 "\n"
													 "in highp vec2 in_te_position[];\n"
													 "\n"
													 "out mediump vec4 in_f_color;\n"
													 "\n"
													 + (m_caseType == CASETYPE_PRECISE ? "precise gl_Position;\n\n" : "") +
													 "void main (void)\n"
													 "{\n"
													 + (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ?
														string(m_caseType == CASETYPE_PRECISE
															? "\t// Note: when this is an edge vertex, at most two of the following terms are non-zero (so order doesn't matter)\n"
															: "") +
														"	highp vec2 pos = gl_TessCoord.x*in_te_position[0] + gl_TessCoord.y*in_te_position[1] + gl_TessCoord.z*in_te_position[2];\n"
														"\n"
														"	highp float f = sqrt(3.0 * min(gl_TessCoord.x, min(gl_TessCoord.y, gl_TessCoord.z))) * 0.5 + 0.5;\n"
														"	in_f_color = vec4(gl_TessCoord*f, 1.0);\n"
													  : m_primitiveType == TESSPRIMITIVETYPE_QUADS ?
													    string()
														+ (m_caseType == CASETYPE_BASIC ?
															"	highp vec2 pos = (1.0-gl_TessCoord.x)*(1.0-gl_TessCoord.y)*in_te_position[0]\n"
															"	               + (    gl_TessCoord.x)*(1.0-gl_TessCoord.y)*in_te_position[1]\n"
															"	               + (1.0-gl_TessCoord.x)*(    gl_TessCoord.y)*in_te_position[2]\n"
															"	               + (    gl_TessCoord.x)*(    gl_TessCoord.y)*in_te_position[3];\n"
														 : m_caseType == CASETYPE_PRECISE ?
															"	highp vec2 a = (1.0-gl_TessCoord.x)*(1.0-gl_TessCoord.y)*in_te_position[0];\n"
															"	highp vec2 b = (    gl_TessCoord.x)*(1.0-gl_TessCoord.y)*in_te_position[1];\n"
															"	highp vec2 c = (1.0-gl_TessCoord.x)*(    gl_TessCoord.y)*in_te_position[2];\n"
															"	highp vec2 d = (    gl_TessCoord.x)*(    gl_TessCoord.y)*in_te_position[3];\n"
															"	// Note: when this is an edge vertex, at most two of the following terms are non-zero (so order doesn't matter)\n"
															"	highp vec2 pos = a+b+c+d;\n"
														 : DE_NULL) +
														"\n"
														"	highp float f = sqrt(1.0 - 2.0 * max(abs(gl_TessCoord.x - 0.5), abs(gl_TessCoord.y - 0.5)))*0.5 + 0.5;\n"
														"	in_f_color = vec4(0.1, gl_TessCoord.xy*f, 1.0);\n"
													  : DE_NULL) +
													 "\n"
													 "	// Offset the position slightly, based on the parity of the bits in the float representation.\n"
													 "	// This is done to detect possible small differences in edge vertex positions between patches.\n"
													 "	uvec2 bits = floatBitsToUint(pos);\n"
													 "	uint numBits = 0u;\n"
													 "	for (uint i = 0u; i < 32u; i++)\n"
													 "		numBits += ((bits[0] >> i) & 1u) + ((bits[1] >> i) & 1u);\n"
													 "	pos += float(numBits&1u)*0.04;\n"
													 "\n"
													 "	gl_Position = vec4(pos, 0.0, 1.0);\n"
													 "}\n")

			<< glu::FragmentSource					("#version 310 es\n"
													 "\n"
													 "layout (location = 0) out mediump vec4 o_color;\n"
													 "\n"
													 "in mediump vec4 in_f_color;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	o_color = in_f_color;\n"
													 "}\n")));

	m_testCtx.getLog() << *m_program;
	if (!m_program->isOk())
		TCU_FAIL("Program compilation failed");
}

void CommonEdgeCase::deinit (void)
{
	m_program.clear();
}

CommonEdgeCase::IterateResult CommonEdgeCase::iterate (void)
{
	TestLog&					log						= m_testCtx.getLog();
	const RenderContext&		renderCtx				= m_context.getRenderContext();
	const RandomViewport		viewport				(renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName()));
	const deUint32				programGL				= m_program->getProgram();
	const glw::Functions&		gl						= renderCtx.getFunctions();

	const int					gridWidth				= 4;
	const int					gridHeight				= 4;
	const int					numVertices				= (gridWidth+1)*(gridHeight+1);
	const int					numIndices				= gridWidth*gridHeight * (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3*2 : m_primitiveType == TESSPRIMITIVETYPE_QUADS ? 4 : -1);
	const int					numPosCompsPerVertex	= 2;
	const int					totalNumPosComps		= numPosCompsPerVertex*numVertices;
	vector<float>				gridPosComps;
	vector<float>				gridTessParams;
	vector<deUint16>			gridIndices;

	gridPosComps.reserve(totalNumPosComps);
	gridTessParams.reserve(numVertices);
	gridIndices.reserve(numIndices);

	{
		Random constantSeedRnd(42);

		for (int i = 0; i < gridHeight+1; i++)
		for (int j = 0; j < gridWidth+1; j++)
		{
			gridPosComps.push_back(-1.0f + 2.0f * ((float)j + 0.5f) / (float)(gridWidth+1));
			gridPosComps.push_back(-1.0f + 2.0f * ((float)i + 0.5f) / (float)(gridHeight+1));
			gridTessParams.push_back((float)(i*(gridWidth+1) + j) / (float)(numVertices-1));
		}
	}

	// Generate patch vertex indices.
	// \note If CASETYPE_BASIC, the vertices are ordered such that when multiple
	//		 triangles/quads share a vertex, it's at the same index for everyone.

	if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES)
	{
		for (int i = 0; i < gridHeight; i++)
		for (int j = 0; j < gridWidth; j++)
		{
			const int corners[4] =
			{
				(i+0)*(gridWidth+1) + j+0,
				(i+0)*(gridWidth+1) + j+1,
				(i+1)*(gridWidth+1) + j+0,
				(i+1)*(gridWidth+1) + j+1
			};

			const int secondTriangleVertexIndexOffset = m_caseType == CASETYPE_BASIC	? 0
													  : m_caseType == CASETYPE_PRECISE	? 1
													  : -1;
			DE_ASSERT(secondTriangleVertexIndexOffset != -1);

			for (int k = 0; k < 3; k++)
				gridIndices.push_back(corners[(k+0 + i + (2-j%3)) % 3]);
			for (int k = 0; k < 3; k++)
				gridIndices.push_back(corners[(k+2 + i + (2-j%3) + secondTriangleVertexIndexOffset) % 3 + 1]);
		}
	}
	else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS)
	{
		for (int i = 0; i < gridHeight; i++)
		for (int j = 0; j < gridWidth; j++)
		{
			// \note The vertices are ordered such that when multiple quads
			//		 share a vertices, it's at the same index for everyone.
			for (int m = 0; m < 2; m++)
			for (int n = 0; n < 2; n++)
				gridIndices.push_back((i+(i+m)%2)*(gridWidth+1) + j+(j+n)%2);

			if(m_caseType == CASETYPE_PRECISE && (i+j) % 2 == 0)
				std::reverse(gridIndices.begin() + (gridIndices.size() - 4),
							 gridIndices.begin() + gridIndices.size());
		}
	}
	else
		DE_ASSERT(false);

	DE_ASSERT((int)gridPosComps.size() == totalNumPosComps);
	DE_ASSERT((int)gridTessParams.size() == numVertices);
	DE_ASSERT((int)gridIndices.size() == numIndices);

	setViewport(gl, viewport);
	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.useProgram(programGL);

	{
		gl.patchParameteri(GL_PATCH_VERTICES, m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3 : m_primitiveType == TESSPRIMITIVETYPE_QUADS ? 4 : -1);
		gl.clear(GL_COLOR_BUFFER_BIT);

		const glu::VertexArrayBinding attrBindings[] =
		{
			glu::va::Float("in_v_position", numPosCompsPerVertex, numVertices, 0, &gridPosComps[0]),
			glu::va::Float("in_v_tessParam", 1, numVertices, 0, &gridTessParams[0])
		};

		glu::draw(renderCtx, programGL, DE_LENGTH_OF_ARRAY(attrBindings), &attrBindings[0],
			glu::pr::Patches((int)gridIndices.size(), &gridIndices[0]));
		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed");
	}

	{
		const tcu::Surface rendered = getPixels(renderCtx, viewport);

		log << TestLog::Image("RenderedImage", "Rendered Image", rendered)
			<< TestLog::Message << "Note: coloring is done to clarify the positioning and orientation of the "
								<< (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? "triangles" : m_primitiveType == TESSPRIMITIVETYPE_QUADS ? "quads" : DE_NULL)
								<< "; the color of a vertex corresponds to the index of that vertex in the patch"
								<< TestLog::EndMessage;

		if (m_caseType == CASETYPE_BASIC)
			log << TestLog::Message << "Note: each shared vertex has the same index among the primitives it belongs to" << TestLog::EndMessage;
		else if (m_caseType == CASETYPE_PRECISE)
			log << TestLog::Message << "Note: the 'precise' qualifier is used to avoid cracks between primitives" << TestLog::EndMessage;
		else
			DE_ASSERT(false);

		// Ad-hoc result verification - check that a certain rectangle in the image contains no black pixels.

		const int startX	= (int)(0.15f * (float)rendered.getWidth());
		const int endX		= (int)(0.85f * (float)rendered.getWidth());
		const int startY	= (int)(0.15f * (float)rendered.getHeight());
		const int endY		= (int)(0.85f * (float)rendered.getHeight());

		for (int y = startY; y < endY; y++)
		for (int x = startX; x < endX; x++)
		{
			const tcu::RGBA pixel = rendered.getPixel(x, y);

			if (pixel.getRed() == 0 && pixel.getGreen() == 0 && pixel.getBlue() == 0)
			{
				log << TestLog::Message << "Failure: there seem to be cracks in the rendered result" << TestLog::EndMessage
					<< TestLog::Message << "Note: pixel with zero r, g and b channels found at " << tcu::IVec2(x, y) << TestLog::EndMessage;

				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
				return STOP;
			}
		}

		log << TestLog::Message << "Success: there seem to be no cracks in the rendered result" << TestLog::EndMessage;
	}

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

// Check tessellation coordinates (read with transform feedback).
class TessCoordCase : public TestCase
{
public:
					TessCoordCase (Context& context, const char* name, const char* description, TessPrimitiveType primitiveType, SpacingMode spacing)
						: TestCase			(context, name, description)
						, m_primitiveType	(primitiveType)
						, m_spacing			(spacing)
					{
					}

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

private:
	struct TessLevels
	{
		float inner[2];
		float outer[4];
	};

	static const int				RENDER_SIZE = 16;

	vector<TessLevels>				genTessLevelCases (void) const;

	const TessPrimitiveType			m_primitiveType;
	const SpacingMode				m_spacing;

	SharedPtr<const ShaderProgram>	m_program;
};

void TessCoordCase::init (void)
{
	checkTessellationSupport(m_context);
	checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE);

	m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
			<< glu::VertexSource					("#version 310 es\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "}\n")

			<< glu::TessellationControlSource		("#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													 "\n"
													 "layout (vertices = 1) out;\n"
													 "\n"
													 "uniform mediump float u_tessLevelInner0;\n"
													 "uniform mediump float u_tessLevelInner1;\n"
													 "\n"
													 "uniform mediump float u_tessLevelOuter0;\n"
													 "uniform mediump float u_tessLevelOuter1;\n"
													 "uniform mediump float u_tessLevelOuter2;\n"
													 "uniform mediump float u_tessLevelOuter3;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	gl_TessLevelInner[0] = u_tessLevelInner0;\n"
													 "	gl_TessLevelInner[1] = u_tessLevelInner1;\n"
													 "\n"
													 "	gl_TessLevelOuter[0] = u_tessLevelOuter0;\n"
													 "	gl_TessLevelOuter[1] = u_tessLevelOuter1;\n"
													 "	gl_TessLevelOuter[2] = u_tessLevelOuter2;\n"
													 "	gl_TessLevelOuter[3] = u_tessLevelOuter3;\n"
													 "}\n")

			<< glu::TessellationEvaluationSource	("#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													 "\n"
													 + getTessellationEvaluationInLayoutString(m_primitiveType, m_spacing, true) +
													 "\n"
													 "out highp vec3 out_te_tessCoord;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	out_te_tessCoord = gl_TessCoord;\n"
													 "	gl_Position = vec4(gl_TessCoord.xy*1.6 - 0.8, 0.0, 1.0);\n"
													 "}\n")

			<< glu::FragmentSource					("#version 310 es\n"
													 "\n"
													 "layout (location = 0) out mediump vec4 o_color;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	o_color = vec4(1.0);\n"
													 "}\n")

			<< glu::TransformFeedbackVarying		("out_te_tessCoord")
			<< glu::TransformFeedbackMode			(GL_INTERLEAVED_ATTRIBS)));

	m_testCtx.getLog() << *m_program;
	if (!m_program->isOk())
		TCU_FAIL("Program compilation failed");
}

void TessCoordCase::deinit (void)
{
	m_program.clear();
}

vector<TessCoordCase::TessLevels> TessCoordCase::genTessLevelCases (void) const
{
	static const TessLevels rawTessLevelCases[] =
	{
		{ { 1.0f,	1.0f	},	{ 1.0f,		1.0f,	1.0f,	1.0f	} },
		{ { 63.0f,	24.0f	},	{ 15.0f,	42.0f,	10.0f,	12.0f	} },
		{ { 3.0f,	2.0f	},	{ 6.0f,		8.0f,	7.0f,	9.0f	} },
		{ { 4.0f,	6.0f	},	{ 2.0f,		3.0f,	1.0f,	4.0f	} },
		{ { 2.0f,	2.0f	},	{ 6.0f,		8.0f,	7.0f,	9.0f	} },
		{ { 5.0f,	6.0f	},	{ 1.0f,		1.0f,	1.0f,	1.0f	} },
		{ { 1.0f,	6.0f	},	{ 2.0f,		3.0f,	1.0f,	4.0f	} },
		{ { 5.0f,	1.0f	},	{ 2.0f,		3.0f,	1.0f,	4.0f	} },
		{ { 5.2f,	1.6f	},	{ 2.9f,		3.4f,	1.5f,	4.1f	} }
	};

	if (m_spacing == SPACINGMODE_EQUAL)
		return vector<TessLevels>(DE_ARRAY_BEGIN(rawTessLevelCases), DE_ARRAY_END(rawTessLevelCases));
	else
	{
		vector<TessLevels> result;
		result.reserve(DE_LENGTH_OF_ARRAY(rawTessLevelCases));

		for (int tessLevelCaseNdx = 0; tessLevelCaseNdx < DE_LENGTH_OF_ARRAY(rawTessLevelCases); tessLevelCaseNdx++)
		{
			TessLevels curTessLevelCase = rawTessLevelCases[tessLevelCaseNdx];

			float* const inner = &curTessLevelCase.inner[0];
			float* const outer = &curTessLevelCase.outer[0];

			for (int j = 0; j < 2; j++) inner[j] = (float)getClampedRoundedTessLevel(m_spacing, inner[j]);
			for (int j = 0; j < 4; j++) outer[j] = (float)getClampedRoundedTessLevel(m_spacing, outer[j]);

			if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES)
			{
				if (outer[0] > 1.0f || outer[1] > 1.0f || outer[2] > 1.0f)
				{
					if (inner[0] == 1.0f)
						inner[0] = (float)getClampedRoundedTessLevel(m_spacing, inner[0] + 0.1f);
				}
			}
			else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS)
			{
				if (outer[0] > 1.0f || outer[1] > 1.0f || outer[2] > 1.0f || outer[3] > 1.0f)
				{
					if (inner[0] == 1.0f) inner[0] = (float)getClampedRoundedTessLevel(m_spacing, inner[0] + 0.1f);
					if (inner[1] == 1.0f) inner[1] = (float)getClampedRoundedTessLevel(m_spacing, inner[1] + 0.1f);
				}
			}

			result.push_back(curTessLevelCase);
		}

		DE_ASSERT((int)result.size() == DE_LENGTH_OF_ARRAY(rawTessLevelCases));
		return result;
	}
}

TessCoordCase::IterateResult TessCoordCase::iterate (void)
{
	typedef TransformFeedbackHandler<Vec3> TFHandler;

	TestLog&						log							= m_testCtx.getLog();
	const RenderContext&			renderCtx					= m_context.getRenderContext();
	const RandomViewport			viewport					(renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName()));
	const deUint32					programGL					= m_program->getProgram();
	const glw::Functions&			gl							= renderCtx.getFunctions();

	const int						tessLevelInner0Loc			= gl.getUniformLocation(programGL, "u_tessLevelInner0");
	const int						tessLevelInner1Loc			= gl.getUniformLocation(programGL, "u_tessLevelInner1");
	const int						tessLevelOuter0Loc			= gl.getUniformLocation(programGL, "u_tessLevelOuter0");
	const int						tessLevelOuter1Loc			= gl.getUniformLocation(programGL, "u_tessLevelOuter1");
	const int						tessLevelOuter2Loc			= gl.getUniformLocation(programGL, "u_tessLevelOuter2");
	const int						tessLevelOuter3Loc			= gl.getUniformLocation(programGL, "u_tessLevelOuter3");

	const vector<TessLevels>		tessLevelCases				= genTessLevelCases();
	vector<vector<Vec3> >			caseReferences				(tessLevelCases.size());

	for (int i = 0; i < (int)tessLevelCases.size(); i++)
		caseReferences[i] = generateReferenceTessCoords(m_primitiveType, m_spacing, &tessLevelCases[i].inner[0], &tessLevelCases[i].outer[0]);

	const int						maxNumVertices				= (int)std::max_element(caseReferences.begin(), caseReferences.end(), SizeLessThan<vector<Vec3> >())->size();
	const TFHandler					tfHandler					(m_context.getRenderContext(), maxNumVertices);

	bool							success						= true;

	setViewport(gl, viewport);
	gl.useProgram(programGL);

	gl.patchParameteri(GL_PATCH_VERTICES, 1);

	for (int tessLevelCaseNdx = 0; tessLevelCaseNdx < (int)tessLevelCases.size(); tessLevelCaseNdx++)
	{
		const float* const innerLevels = &tessLevelCases[tessLevelCaseNdx].inner[0];
		const float* const outerLevels = &tessLevelCases[tessLevelCaseNdx].outer[0];

		log << TestLog::Message << "Tessellation levels: " << tessellationLevelsString(innerLevels, outerLevels, m_primitiveType) << TestLog::EndMessage;

		gl.uniform1f(tessLevelInner0Loc, innerLevels[0]);
		gl.uniform1f(tessLevelInner1Loc, innerLevels[1]);
		gl.uniform1f(tessLevelOuter0Loc, outerLevels[0]);
		gl.uniform1f(tessLevelOuter1Loc, outerLevels[1]);
		gl.uniform1f(tessLevelOuter2Loc, outerLevels[2]);
		gl.uniform1f(tessLevelOuter3Loc, outerLevels[3]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Setup failed");

		{
			const vector<Vec3>&			tessCoordsRef	= caseReferences[tessLevelCaseNdx];
			const TFHandler::Result		tfResult		= tfHandler.renderAndGetPrimitives(programGL, GL_POINTS, 0, DE_NULL, 1);

			if (tfResult.numPrimitives != (int)tessCoordsRef.size())
			{
				log << TestLog::Message << "Failure: GL reported GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN to be "
										<< tfResult.numPrimitives << ", reference value is " << tessCoordsRef.size()
										<< " (logging further info anyway)" << TestLog::EndMessage;
				success = false;
			}
			else
				log << TestLog::Message << "Note: GL reported GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN to be " << tfResult.numPrimitives << TestLog::EndMessage;

			if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES)
				log << TestLog::Message << "Note: in the following visualization(s), the u=1, v=1, w=1 corners are at the right, top, and left corners, respectively" << TestLog::EndMessage;
			else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS || m_primitiveType == TESSPRIMITIVETYPE_ISOLINES)
				log << TestLog::Message << "Note: in the following visualization(s), u and v coordinate go left-to-right and bottom-to-top, respectively" << TestLog::EndMessage;
			else
				DE_ASSERT(false);

			success = compareTessCoords(log, m_primitiveType, tessCoordsRef, tfResult.varying) && success;
		}

		if (!success)
			break;
		else
			log << TestLog::Message << "All OK" << TestLog::EndMessage;
	}

	m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, success ? "Pass" : "Invalid tessellation coordinates");
	return STOP;
}

// Check validity of fractional spacing modes. Draws a single isoline, reads tesscoords with transform feedback.
class FractionalSpacingModeCase : public TestCase
{
public:
					FractionalSpacingModeCase (Context& context, const char* name, const char* description, SpacingMode spacing)
						: TestCase	(context, name, description)
						, m_spacing	(spacing)
					{
						DE_ASSERT(m_spacing == SPACINGMODE_FRACTIONAL_EVEN || m_spacing == SPACINGMODE_FRACTIONAL_ODD);
					}

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

private:
	static const int				RENDER_SIZE = 16;

	static vector<float>			genTessLevelCases (void);

	const SpacingMode				m_spacing;

	SharedPtr<const ShaderProgram>	m_program;
};

void FractionalSpacingModeCase::init (void)
{
	checkTessellationSupport(m_context);
	checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE);

	m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
			<< glu::VertexSource					("#version 310 es\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "}\n")

			<< glu::TessellationControlSource		("#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													 "\n"
													 "layout (vertices = 1) out;\n"
													 "\n"
													 "uniform mediump float u_tessLevelOuter1;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	gl_TessLevelOuter[0] = 1.0;\n"
													 "	gl_TessLevelOuter[1] = u_tessLevelOuter1;\n"
													 "}\n")

			<< glu::TessellationEvaluationSource	("#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													 "\n"
													 + getTessellationEvaluationInLayoutString(TESSPRIMITIVETYPE_ISOLINES, m_spacing, true) +
													 "\n"
													 "out highp float out_te_tessCoord;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	out_te_tessCoord = gl_TessCoord.x;\n"
													 "	gl_Position = vec4(gl_TessCoord.xy*1.6 - 0.8, 0.0, 1.0);\n"
													 "}\n")

			<< glu::FragmentSource					("#version 310 es\n"
													 "\n"
													 "layout (location = 0) out mediump vec4 o_color;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	o_color = vec4(1.0);\n"
													 "}\n")

			<< glu::TransformFeedbackVarying		("out_te_tessCoord")
			<< glu::TransformFeedbackMode			(GL_INTERLEAVED_ATTRIBS)));

	m_testCtx.getLog() << *m_program;
	if (!m_program->isOk())
		TCU_FAIL("Program compilation failed");
}

void FractionalSpacingModeCase::deinit (void)
{
	m_program.clear();
}

vector<float> FractionalSpacingModeCase::genTessLevelCases (void)
{
	vector<float> result;

	// Ranges [7.0 .. 8.0), [8.0 .. 9.0) and [9.0 .. 10.0)
	{
		static const float	rangeStarts[]		= { 7.0f, 8.0f, 9.0f };
		const int			numSamplesPerRange	= 10;

		for (int rangeNdx = 0; rangeNdx < DE_LENGTH_OF_ARRAY(rangeStarts); rangeNdx++)
			for (int i = 0; i < numSamplesPerRange; i++)
				result.push_back(rangeStarts[rangeNdx] + (float)i/(float)numSamplesPerRange);
	}

	// 0.3, 1.3, 2.3,  ... , 62.3
	for (int i = 0; i <= 62; i++)
		result.push_back((float)i + 0.3f);

	return result;
}

FractionalSpacingModeCase::IterateResult FractionalSpacingModeCase::iterate (void)
{
	typedef TransformFeedbackHandler<float> TFHandler;

	TestLog&						log							= m_testCtx.getLog();
	const RenderContext&			renderCtx					= m_context.getRenderContext();
	const RandomViewport			viewport					(renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName()));
	const deUint32					programGL					= m_program->getProgram();
	const glw::Functions&			gl							= renderCtx.getFunctions();

	const int						tessLevelOuter1Loc			= gl.getUniformLocation(programGL, "u_tessLevelOuter1");

	// Second outer tessellation levels.
	const vector<float>				tessLevelCases				= genTessLevelCases();
	const int						maxNumVertices				= 1 + getClampedRoundedTessLevel(m_spacing, *std::max_element(tessLevelCases.begin(), tessLevelCases.end()));
	vector<float>					additionalSegmentLengths;
	vector<int>						additionalSegmentLocations;

	const TFHandler					tfHandler					(m_context.getRenderContext(), maxNumVertices);

	bool							success						= true;

	setViewport(gl, viewport);
	gl.useProgram(programGL);

	gl.patchParameteri(GL_PATCH_VERTICES, 1);

	for (int tessLevelCaseNdx = 0; tessLevelCaseNdx < (int)tessLevelCases.size(); tessLevelCaseNdx++)
	{
		const float outerLevel1 = tessLevelCases[tessLevelCaseNdx];

		gl.uniform1f(tessLevelOuter1Loc, outerLevel1);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Setup failed");

		{
			const TFHandler::Result		tfResult = tfHandler.renderAndGetPrimitives(programGL, GL_POINTS, 0, DE_NULL, 1);
			float						additionalSegmentLength;
			int							additionalSegmentLocation;

			success = verifyFractionalSpacingSingle(log, m_spacing, outerLevel1, tfResult.varying,
													additionalSegmentLength, additionalSegmentLocation);

			if (!success)
				break;

			additionalSegmentLengths.push_back(additionalSegmentLength);
			additionalSegmentLocations.push_back(additionalSegmentLocation);
		}
	}

	if (success)
		success = verifyFractionalSpacingMultiple(log, m_spacing, tessLevelCases, additionalSegmentLengths, additionalSegmentLocations);

	m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, success ? "Pass" : "Invalid tessellation coordinates");
	return STOP;
}

// Base class for a case with one input attribute (in_v_position) and optionally a TCS; tests with a couple of different sets of tessellation levels.
class BasicVariousTessLevelsPosAttrCase : public TestCase
{
public:
					BasicVariousTessLevelsPosAttrCase (Context&				context,
													   const char*			name,
													   const char*			description,
													   TessPrimitiveType	primitiveType,
													   SpacingMode			spacing,
													   const char*			referenceImagePathPrefix)
						: TestCase						(context, name, description)
						, m_primitiveType				(primitiveType)
						, m_spacing						(spacing)
						, m_referenceImagePathPrefix	(referenceImagePathPrefix)
					{
					}

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

protected:
	virtual const glu::ProgramSources	makeSources (TessPrimitiveType, SpacingMode, const char* vtxOutPosAttrName) const = DE_NULL;

private:
	static const int					RENDER_SIZE = 256;

	const TessPrimitiveType				m_primitiveType;
	const SpacingMode					m_spacing;
	const string						m_referenceImagePathPrefix;

	SharedPtr<const ShaderProgram>		m_program;
};

void BasicVariousTessLevelsPosAttrCase::init (void)
{
	checkTessellationSupport(m_context);
	checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE);

	{
		glu::ProgramSources sources = makeSources(m_primitiveType, m_spacing, "in_tc_position");
		DE_ASSERT(sources.sources[glu::SHADERTYPE_TESSELLATION_CONTROL].empty());

		sources << glu::TessellationControlSource(	"#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													"\n"
													"layout (vertices = " + string(m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? "3" : "4") + ") out;\n"
													"\n"
													"in highp vec2 in_tc_position[];\n"
													"\n"
													"out highp vec2 in_te_position[];\n"
													"\n"
													"uniform mediump float u_tessLevelInner0;\n"
													"uniform mediump float u_tessLevelInner1;\n"
													"uniform mediump float u_tessLevelOuter0;\n"
													"uniform mediump float u_tessLevelOuter1;\n"
													"uniform mediump float u_tessLevelOuter2;\n"
													"uniform mediump float u_tessLevelOuter3;\n"
													"\n"
													"void main (void)\n"
													"{\n"
													"	in_te_position[gl_InvocationID] = in_tc_position[gl_InvocationID];\n"
													"\n"
													"	gl_TessLevelInner[0] = u_tessLevelInner0;\n"
													"	gl_TessLevelInner[1] = u_tessLevelInner1;\n"
													"\n"
													"	gl_TessLevelOuter[0] = u_tessLevelOuter0;\n"
													"	gl_TessLevelOuter[1] = u_tessLevelOuter1;\n"
													"	gl_TessLevelOuter[2] = u_tessLevelOuter2;\n"
													"	gl_TessLevelOuter[3] = u_tessLevelOuter3;\n"
													"}\n");

		m_program = SharedPtr<const ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(), sources));
	}

	m_testCtx.getLog() << *m_program;
	if (!m_program->isOk())
		TCU_FAIL("Program compilation failed");
}

void BasicVariousTessLevelsPosAttrCase::deinit (void)
{
	m_program.clear();
}

BasicVariousTessLevelsPosAttrCase::IterateResult BasicVariousTessLevelsPosAttrCase::iterate (void)
{
	static const struct
	{
		float inner[2];
		float outer[4];
	} tessLevelCases[] =
	{
		{ { 9.0f,	9.0f	},	{ 9.0f,		9.0f,	9.0f,	9.0f	} },
		{ { 8.0f,	11.0f	},	{ 13.0f,	15.0f,	18.0f,	21.0f	} },
		{ { 17.0f,	14.0f	},	{ 3.0f,		6.0f,	9.0f,	12.0f	} }
	};

	TestLog&				log					= m_testCtx.getLog();
	const RenderContext&	renderCtx			= m_context.getRenderContext();
	const RandomViewport	viewport			(renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName()));
	const deUint32			programGL			= m_program->getProgram();
	const glw::Functions&	gl					= renderCtx.getFunctions();
	const int				patchSize			= m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES	? 3
												: m_primitiveType == TESSPRIMITIVETYPE_QUADS		? 4
												: m_primitiveType == TESSPRIMITIVETYPE_ISOLINES		? 4
												: -1;

	setViewport(gl, viewport);
	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.useProgram(programGL);

	gl.patchParameteri(GL_PATCH_VERTICES, patchSize);

	for (int tessLevelCaseNdx = 0; tessLevelCaseNdx < DE_LENGTH_OF_ARRAY(tessLevelCases); tessLevelCaseNdx++)
	{
		float innerLevels[2];
		float outerLevels[4];

		for (int i = 0; i < DE_LENGTH_OF_ARRAY(innerLevels); i++)
			innerLevels[i] = (float)getClampedRoundedTessLevel(m_spacing, tessLevelCases[tessLevelCaseNdx].inner[i]);

		for (int i = 0; i < DE_LENGTH_OF_ARRAY(outerLevels); i++)
			outerLevels[i] = (float)getClampedRoundedTessLevel(m_spacing, tessLevelCases[tessLevelCaseNdx].outer[i]);

		log << TestLog::Message << "Tessellation levels: " << tessellationLevelsString(&innerLevels[0], &outerLevels[0], m_primitiveType) << TestLog::EndMessage;

		gl.uniform1f(gl.getUniformLocation(programGL, "u_tessLevelInner0"), innerLevels[0]);
		gl.uniform1f(gl.getUniformLocation(programGL, "u_tessLevelInner1"), innerLevels[1]);
		gl.uniform1f(gl.getUniformLocation(programGL, "u_tessLevelOuter0"), outerLevels[0]);
		gl.uniform1f(gl.getUniformLocation(programGL, "u_tessLevelOuter1"), outerLevels[1]);
		gl.uniform1f(gl.getUniformLocation(programGL, "u_tessLevelOuter2"), outerLevels[2]);
		gl.uniform1f(gl.getUniformLocation(programGL, "u_tessLevelOuter3"), outerLevels[3]);

		gl.clear(GL_COLOR_BUFFER_BIT);

		{
			vector<Vec2> positions;
			positions.reserve(4);

			if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES)
			{
				positions.push_back(Vec2( 0.8f,    0.6f));
				positions.push_back(Vec2( 0.0f, -0.786f));
				positions.push_back(Vec2(-0.8f,    0.6f));
			}
			else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS || m_primitiveType == TESSPRIMITIVETYPE_ISOLINES)
			{
				positions.push_back(Vec2(-0.8f, -0.8f));
				positions.push_back(Vec2( 0.8f, -0.8f));
				positions.push_back(Vec2(-0.8f,  0.8f));
				positions.push_back(Vec2( 0.8f,  0.8f));
			}
			else
				DE_ASSERT(false);

			DE_ASSERT((int)positions.size() == patchSize);

			const glu::VertexArrayBinding attrBindings[] =
			{
				glu::va::Float("in_v_position", 2, (int)positions.size(), 0, &positions[0].x())
			};

			glu::draw(m_context.getRenderContext(), programGL, DE_LENGTH_OF_ARRAY(attrBindings), &attrBindings[0],
				glu::pr::Patches(patchSize));
			GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed");
		}

		{
			const tcu::Surface			rendered	= getPixels(renderCtx, viewport);
			const tcu::TextureLevel		reference	= getPNG(m_testCtx.getArchive(), m_referenceImagePathPrefix + "_" + de::toString(tessLevelCaseNdx) + ".png");
			const bool					success		= tcu::fuzzyCompare(log, "ImageComparison", "Image Comparison", reference.getAccess(), rendered.getAccess(), 0.002f, tcu::COMPARE_LOG_RESULT);

			if (!success)
			{
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
				return STOP;
			}
		}
	}

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

// Test that there are no obvious gaps in the triangulation of a tessellated triangle or quad.
class BasicTriangleFillCoverCase : public BasicVariousTessLevelsPosAttrCase
{
public:
	BasicTriangleFillCoverCase (Context& context, const char* name, const char* description, TessPrimitiveType primitiveType, SpacingMode spacing, const char* referenceImagePathPrefix)
		: BasicVariousTessLevelsPosAttrCase (context, name, description, primitiveType, spacing, referenceImagePathPrefix)
	{
		DE_ASSERT(primitiveType == TESSPRIMITIVETYPE_TRIANGLES || primitiveType == TESSPRIMITIVETYPE_QUADS);
	}

protected:
	const glu::ProgramSources makeSources (TessPrimitiveType primitiveType, SpacingMode spacing, const char* vtxOutPosAttrName) const
	{
		return glu::ProgramSources()
			<< glu::VertexSource					("#version 310 es\n"
													 "\n"
													 "in highp vec2 in_v_position;\n"
													 "\n"
													 "out highp vec2 " + string(vtxOutPosAttrName) + ";\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	" + vtxOutPosAttrName + " = in_v_position;\n"
													 "}\n")

			<< glu::TessellationEvaluationSource	("#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													 "\n"
													 + getTessellationEvaluationInLayoutString(primitiveType, spacing) +
													 "\n"
													 "in highp vec2 in_te_position[];\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 + (primitiveType == TESSPRIMITIVETYPE_TRIANGLES ?
														"\n"
														"	highp float d = 3.0 * min(gl_TessCoord.x, min(gl_TessCoord.y, gl_TessCoord.z));\n"
														"	highp vec2 corner0 = in_te_position[0];\n"
														"	highp vec2 corner1 = in_te_position[1];\n"
														"	highp vec2 corner2 = in_te_position[2];\n"
														"	highp vec2 pos =  corner0*gl_TessCoord.x + corner1*gl_TessCoord.y + corner2*gl_TessCoord.z;\n"
														"	highp vec2 fromCenter = pos - (corner0 + corner1 + corner2) / 3.0;\n"
														"	highp float f = (1.0 - length(fromCenter)) * (1.5 - d);\n"
														"	pos += 0.75 * f * fromCenter / (length(fromCenter) + 0.3);\n"
														"	gl_Position = vec4(pos, 0.0, 1.0);\n"
													  : primitiveType == TESSPRIMITIVETYPE_QUADS ?
														"	highp vec2 corner0 = in_te_position[0];\n"
														"	highp vec2 corner1 = in_te_position[1];\n"
														"	highp vec2 corner2 = in_te_position[2];\n"
														"	highp vec2 corner3 = in_te_position[3];\n"
														"	highp vec2 pos = (1.0-gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner0\n"
														"	               + (    gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner1\n"
														"	               + (1.0-gl_TessCoord.x)*(    gl_TessCoord.y)*corner2\n"
														"	               + (    gl_TessCoord.x)*(    gl_TessCoord.y)*corner3;\n"
														"	highp float d = 2.0 * min(abs(gl_TessCoord.x-0.5), abs(gl_TessCoord.y-0.5));\n"
														"	highp vec2 fromCenter = pos - (corner0 + corner1 + corner2 + corner3) / 4.0;\n"
														"	highp float f = (1.0 - length(fromCenter)) * sqrt(1.7 - d);\n"
														"	pos += 0.75 * f * fromCenter / (length(fromCenter) + 0.3);\n"
														"	gl_Position = vec4(pos, 0.0, 1.0);\n"
													  : DE_NULL) +
													 "}\n")

			<< glu::FragmentSource					("#version 310 es\n"
													 "\n"
													 "layout (location = 0) out mediump vec4 o_color;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	o_color = vec4(1.0);\n"
													 "}\n");
	}
};

// Check that there are no obvious overlaps in the triangulation of a tessellated triangle or quad.
class BasicTriangleFillNonOverlapCase : public BasicVariousTessLevelsPosAttrCase
{
public:
	BasicTriangleFillNonOverlapCase (Context& context, const char* name, const char* description, TessPrimitiveType primitiveType, SpacingMode spacing, const char* referenceImagePathPrefix)
		: BasicVariousTessLevelsPosAttrCase (context, name, description, primitiveType, spacing, referenceImagePathPrefix)
	{
		DE_ASSERT(primitiveType == TESSPRIMITIVETYPE_TRIANGLES || primitiveType == TESSPRIMITIVETYPE_QUADS);
	}

protected:
	const glu::ProgramSources makeSources (TessPrimitiveType primitiveType, SpacingMode spacing, const char* vtxOutPosAttrName) const
	{
		return glu::ProgramSources()
			<< glu::VertexSource					("#version 310 es\n"
													 "\n"
													 "in highp vec2 in_v_position;\n"
													 "\n"
													 "out highp vec2 " + string(vtxOutPosAttrName) + ";\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	" + vtxOutPosAttrName + " = in_v_position;\n"
													 "}\n")

			<< glu::TessellationEvaluationSource	("#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													 "\n"
													 + getTessellationEvaluationInLayoutString(primitiveType, spacing) +
													 "\n"
													 "in highp vec2 in_te_position[];\n"
													 "\n"
													 "out mediump vec4 in_f_color;\n"
													 "\n"
													 "uniform mediump float u_tessLevelInner0;\n"
													 "uniform mediump float u_tessLevelInner1;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 + (primitiveType == TESSPRIMITIVETYPE_TRIANGLES ?
														"\n"
														"	highp vec2 corner0 = in_te_position[0];\n"
														"	highp vec2 corner1 = in_te_position[1];\n"
														"	highp vec2 corner2 = in_te_position[2];\n"
														"	highp vec2 pos =  corner0*gl_TessCoord.x + corner1*gl_TessCoord.y + corner2*gl_TessCoord.z;\n"
														"	gl_Position = vec4(pos, 0.0, 1.0);\n"
														"	highp int numConcentricTriangles = int(round(u_tessLevelInner0)) / 2 + 1;\n"
														"	highp float d = 3.0 * min(gl_TessCoord.x, min(gl_TessCoord.y, gl_TessCoord.z));\n"
														"	highp int phase = int(d*float(numConcentricTriangles)) % 3;\n"
														"	in_f_color = phase == 0 ? vec4(1.0, 0.0, 0.0, 1.0)\n"
														"	           : phase == 1 ? vec4(0.0, 1.0, 0.0, 1.0)\n"
														"	           :              vec4(0.0, 0.0, 1.0, 1.0);\n"
													  : primitiveType == TESSPRIMITIVETYPE_QUADS ?
														"	highp vec2 corner0 = in_te_position[0];\n"
														"	highp vec2 corner1 = in_te_position[1];\n"
														"	highp vec2 corner2 = in_te_position[2];\n"
														"	highp vec2 corner3 = in_te_position[3];\n"
														"	highp vec2 pos = (1.0-gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner0\n"
														"	               + (    gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner1\n"
														"	               + (1.0-gl_TessCoord.x)*(    gl_TessCoord.y)*corner2\n"
														"	               + (    gl_TessCoord.x)*(    gl_TessCoord.y)*corner3;\n"
														"	gl_Position = vec4(pos, 0.0, 1.0);\n"
														"	highp int phaseX = int(round((0.5 - abs(gl_TessCoord.x-0.5)) * u_tessLevelInner0));\n"
														"	highp int phaseY = int(round((0.5 - abs(gl_TessCoord.y-0.5)) * u_tessLevelInner1));\n"
														"	highp int phase = min(phaseX, phaseY) % 3;\n"
														"	in_f_color = phase == 0 ? vec4(1.0, 0.0, 0.0, 1.0)\n"
														"	           : phase == 1 ? vec4(0.0, 1.0, 0.0, 1.0)\n"
														"	           :              vec4(0.0, 0.0, 1.0, 1.0);\n"
													  : DE_NULL) +
													 "}\n")

			<< glu::FragmentSource					("#version 310 es\n"
													 "\n"
													 "layout (location = 0) out mediump vec4 o_color;\n"
													 "\n"
													 "in mediump vec4 in_f_color;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	o_color = in_f_color;\n"
													 "}\n");
	}
};

// Basic isolines rendering case.
class IsolinesRenderCase : public BasicVariousTessLevelsPosAttrCase
{
public:
	IsolinesRenderCase (Context& context, const char* name, const char* description, SpacingMode spacing, const char* referenceImagePathPrefix)
		: BasicVariousTessLevelsPosAttrCase (context, name, description, TESSPRIMITIVETYPE_ISOLINES, spacing, referenceImagePathPrefix)
	{
	}

protected:
	const glu::ProgramSources makeSources (TessPrimitiveType primitiveType, SpacingMode spacing, const char* vtxOutPosAttrName) const
	{
		DE_ASSERT(primitiveType == TESSPRIMITIVETYPE_ISOLINES);
		DE_UNREF(primitiveType);

		return glu::ProgramSources()
			<< glu::VertexSource					("#version 310 es\n"
													 "\n"
													 "in highp vec2 in_v_position;\n"
													 "\n"
													 "out highp vec2 " + string(vtxOutPosAttrName) + ";\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	" + vtxOutPosAttrName + " = in_v_position;\n"
													 "}\n")

			<< glu::TessellationEvaluationSource	("#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													 "\n"
													 + getTessellationEvaluationInLayoutString(TESSPRIMITIVETYPE_ISOLINES, spacing) +
													 "\n"
													 "in highp vec2 in_te_position[];\n"
													 "\n"
													 "out mediump vec4 in_f_color;\n"
													 "\n"
													 "uniform mediump float u_tessLevelOuter0;\n"
													 "uniform mediump float u_tessLevelOuter1;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	highp vec2 corner0 = in_te_position[0];\n"
													 "	highp vec2 corner1 = in_te_position[1];\n"
													 "	highp vec2 corner2 = in_te_position[2];\n"
													 "	highp vec2 corner3 = in_te_position[3];\n"
													 "	highp vec2 pos = (1.0-gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner0\n"
													 "	               + (    gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner1\n"
													 "	               + (1.0-gl_TessCoord.x)*(    gl_TessCoord.y)*corner2\n"
													 "	               + (    gl_TessCoord.x)*(    gl_TessCoord.y)*corner3;\n"
													 "	pos.y += 0.15*sin(gl_TessCoord.x*10.0);\n"
													 "	gl_Position = vec4(pos, 0.0, 1.0);\n"
													 "	highp int phaseX = int(round(gl_TessCoord.x*u_tessLevelOuter1));\n"
													 "	highp int phaseY = int(round(gl_TessCoord.y*u_tessLevelOuter0));\n"
													 "	highp int phase = (phaseX + phaseY) % 3;\n"
													 "	in_f_color = phase == 0 ? vec4(1.0, 0.0, 0.0, 1.0)\n"
													 "	           : phase == 1 ? vec4(0.0, 1.0, 0.0, 1.0)\n"
													 "	           :              vec4(0.0, 0.0, 1.0, 1.0);\n"
													 "}\n")

			<< glu::FragmentSource					("#version 310 es\n"
													 "\n"
													 "layout (location = 0) out mediump vec4 o_color;\n"
													 "\n"
													 "in mediump vec4 in_f_color;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	o_color = in_f_color;\n"
													 "}\n");
	}
};

// Test the "cw" and "ccw" TES input layout qualifiers.
class WindingCase : public TestCase
{
public:
					WindingCase (Context& context, const char* name, const char* description, TessPrimitiveType primitiveType, Winding winding)
						: TestCase			(context, name, description)
						, m_primitiveType	(primitiveType)
						, m_winding			(winding)
					{
						DE_ASSERT(primitiveType == TESSPRIMITIVETYPE_TRIANGLES || primitiveType == TESSPRIMITIVETYPE_QUADS);
					}

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

private:
	static const int				RENDER_SIZE = 64;

	const TessPrimitiveType			m_primitiveType;
	const Winding					m_winding;

	SharedPtr<const ShaderProgram>	m_program;
};

void WindingCase::init (void)
{
	checkTessellationSupport(m_context);
	checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE);

	m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
			<< glu::VertexSource					("#version 310 es\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "}\n")

			<< glu::TessellationControlSource		("#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													 "\n"
													 "layout (vertices = 1) out;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	gl_TessLevelInner[0] = 5.0;\n"
													 "	gl_TessLevelInner[1] = 5.0;\n"
													 "\n"
													 "	gl_TessLevelOuter[0] = 5.0;\n"
													 "	gl_TessLevelOuter[1] = 5.0;\n"
													 "	gl_TessLevelOuter[2] = 5.0;\n"
													 "	gl_TessLevelOuter[3] = 5.0;\n"
													 "}\n")

			<< glu::TessellationEvaluationSource	("#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													 "\n"
													 + getTessellationEvaluationInLayoutString(m_primitiveType, m_winding) +
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	gl_Position = vec4(gl_TessCoord.xy*2.0 - 1.0, 0.0, 1.0);\n"
													 "}\n")

			<< glu::FragmentSource					("#version 310 es\n"
													 "\n"
													 "layout (location = 0) out mediump vec4 o_color;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	o_color = vec4(1.0);\n"
													 "}\n")));

	m_testCtx.getLog() << *m_program;
	if (!m_program->isOk())
		TCU_FAIL("Program compilation failed");
}

void WindingCase::deinit (void)
{
	m_program.clear();
}

WindingCase::IterateResult WindingCase::iterate (void)
{
	TestLog&						log							= m_testCtx.getLog();
	const RenderContext&			renderCtx					= m_context.getRenderContext();
	const RandomViewport			viewport					(renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName()));
	const deUint32					programGL					= m_program->getProgram();
	const glw::Functions&			gl							= renderCtx.getFunctions();
	const glu::VertexArray			vao							(renderCtx);

	bool							success						= true;

	setViewport(gl, viewport);
	gl.clearColor(1.0f, 0.0f, 0.0f, 1.0f);
	gl.useProgram(programGL);

	gl.patchParameteri(GL_PATCH_VERTICES, 1);

	gl.enable(GL_CULL_FACE);

	gl.bindVertexArray(*vao);

	log << TestLog::Message << "Face culling enabled" << TestLog::EndMessage;

	for (int frontFaceWinding = 0; frontFaceWinding < WINDING_LAST; frontFaceWinding++)
	{
		log << TestLog::Message << "Setting glFrontFace(" << (frontFaceWinding == WINDING_CW ? "GL_CW" : "GL_CCW") << ")" << TestLog::EndMessage;

		gl.frontFace(frontFaceWinding == WINDING_CW ? GL_CW : GL_CCW);

		gl.clear(GL_COLOR_BUFFER_BIT);
		gl.drawArrays(GL_PATCHES, 0, 1);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed");

		{
			const tcu::Surface rendered = getPixels(renderCtx, viewport);
			log << TestLog::Image("RenderedImage", "Rendered Image", rendered);

			{
				const int totalNumPixels		= rendered.getWidth()*rendered.getHeight();
				const int badPixelTolerance		= m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 5*de::max(rendered.getWidth(), rendered.getHeight()) : 0;

				int numWhitePixels	= 0;
				int numRedPixels	= 0;
				for (int y = 0; y < rendered.getHeight();	y++)
				for (int x = 0; x < rendered.getWidth();	x++)
				{
					numWhitePixels	+= rendered.getPixel(x, y) == tcu::RGBA::white	? 1 : 0;
					numRedPixels	+= rendered.getPixel(x, y) == tcu::RGBA::red	? 1 : 0;
				}

				DE_ASSERT(numWhitePixels + numRedPixels <= totalNumPixels);

				log << TestLog::Message << "Note: got " << numWhitePixels << " white and " << numRedPixels << " red pixels" << TestLog::EndMessage;

				if (totalNumPixels - numWhitePixels - numRedPixels > badPixelTolerance)
				{
					log << TestLog::Message << "Failure: Got " << totalNumPixels - numWhitePixels - numRedPixels << " other than white or red pixels (maximum tolerance " << badPixelTolerance << ")" << TestLog::EndMessage;
					success = false;
					break;
				}

				if ((Winding)frontFaceWinding == m_winding)
				{
					if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES)
					{
						if (de::abs(numWhitePixels - totalNumPixels/2) > badPixelTolerance)
						{
							log << TestLog::Message << "Failure: wrong number of white pixels; expected approximately " << totalNumPixels/2 << TestLog::EndMessage;
							success = false;
							break;
						}
					}
					else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS)
					{
						if (numWhitePixels != totalNumPixels)
						{
							log << TestLog::Message << "Failure: expected only white pixels (full-viewport quad)" << TestLog::EndMessage;
							success = false;
							break;
						}
					}
					else
						DE_ASSERT(false);
				}
				else
				{
					if (numWhitePixels != 0)
					{
						log << TestLog::Message << "Failure: expected only red pixels (everything culled)" << TestLog::EndMessage;
						success = false;
						break;
					}
				}
			}
		}
	}

	m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, success ? "Pass" : "Image verification failed");
	return STOP;
}

// Test potentially differing input and output patch sizes.
class PatchVertexCountCase : public TestCase
{
public:
	PatchVertexCountCase (Context& context, const char* name, const char* description, int inputPatchSize, int outputPatchSize, const char* referenceImagePath)
		: TestCase				(context, name, description)
		, m_inputPatchSize		(inputPatchSize)
		, m_outputPatchSize		(outputPatchSize)
		, m_referenceImagePath	(referenceImagePath)
	{
	}

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

private:
	static const int				RENDER_SIZE = 256;

	const int						m_inputPatchSize;
	const int						m_outputPatchSize;

	const string					m_referenceImagePath;

	SharedPtr<const ShaderProgram>	m_program;
};

void PatchVertexCountCase::init (void)
{
	checkTessellationSupport(m_context);
	checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE);

	const string inSizeStr		= de::toString(m_inputPatchSize);
	const string outSizeStr		= de::toString(m_outputPatchSize);

	m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
			<< glu::VertexSource					("#version 310 es\n"
													 "\n"
													 "in highp float in_v_attr;\n"
													 "\n"
													 "out highp float in_tc_attr;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	in_tc_attr = in_v_attr;\n"
													 "}\n")

			<< glu::TessellationControlSource		("#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													 "\n"
													 "layout (vertices = " + outSizeStr + ") out;\n"
													 "\n"
													 "in highp float in_tc_attr[];\n"
													 "\n"
													 "out highp float in_te_attr[];\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	in_te_attr[gl_InvocationID] = in_tc_attr[gl_InvocationID*" + inSizeStr + "/" + outSizeStr + "];\n"
													 "\n"
													 "	gl_TessLevelInner[0] = 5.0;\n"
													 "	gl_TessLevelInner[1] = 5.0;\n"
													 "\n"
													"	gl_TessLevelOuter[0] = 5.0;\n"
													"	gl_TessLevelOuter[1] = 5.0;\n"
													"	gl_TessLevelOuter[2] = 5.0;\n"
													"	gl_TessLevelOuter[3] = 5.0;\n"
													 "}\n")

			<< glu::TessellationEvaluationSource	("#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													 "\n"
													 + getTessellationEvaluationInLayoutString(TESSPRIMITIVETYPE_QUADS) +
													 "\n"
													 "in highp float in_te_attr[];\n"
													 "\n"
													 "out mediump vec4 in_f_color;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	highp float x = gl_TessCoord.x*2.0 - 1.0;\n"
													 "	highp float y = gl_TessCoord.y - in_te_attr[int(round(gl_TessCoord.x*float(" + outSizeStr + "-1)))];\n"
													 "	gl_Position = vec4(x, y, 0.0, 1.0);\n"
													 "	in_f_color = vec4(1.0);\n"
													 "}\n")

			<< glu::FragmentSource					("#version 310 es\n"
													 "\n"
													 "layout (location = 0) out mediump vec4 o_color;\n"
													 "\n"
													 "in mediump vec4 in_f_color;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	o_color = in_f_color;\n"
													 "}\n")));

	m_testCtx.getLog() << *m_program;
	if (!m_program->isOk())
		TCU_FAIL("Program compilation failed");
}

void PatchVertexCountCase::deinit (void)
{
	m_program.clear();
}

PatchVertexCountCase::IterateResult PatchVertexCountCase::iterate (void)
{
	TestLog&					log						= m_testCtx.getLog();
	const RenderContext&		renderCtx				= m_context.getRenderContext();
	const RandomViewport		viewport				(renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName()));
	const deUint32				programGL				= m_program->getProgram();
	const glw::Functions&		gl						= renderCtx.getFunctions();

	setViewport(gl, viewport);
	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.useProgram(programGL);

	log << TestLog::Message << "Note: input patch size is " << m_inputPatchSize << ", output patch size is " << m_outputPatchSize << TestLog::EndMessage;

	{
		vector<float> attributeData;
		attributeData.reserve(m_inputPatchSize);

		for (int i = 0; i < m_inputPatchSize; i++)
		{
			const float f = (float)i / (float)(m_inputPatchSize-1);
			attributeData.push_back(f*f);
		}

		gl.patchParameteri(GL_PATCH_VERTICES, m_inputPatchSize);
		gl.clear(GL_COLOR_BUFFER_BIT);

		const glu::VertexArrayBinding attrBindings[] =
		{
			glu::va::Float("in_v_attr", 1, (int)attributeData.size(), 0, &attributeData[0])
		};

		glu::draw(m_context.getRenderContext(), programGL, DE_LENGTH_OF_ARRAY(attrBindings), &attrBindings[0],
			glu::pr::Patches(m_inputPatchSize));
		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed");
	}

	{
		const tcu::Surface			rendered	= getPixels(renderCtx, viewport);
		const tcu::TextureLevel		reference	= getPNG(m_testCtx.getArchive(), m_referenceImagePath);
		const bool					success		= tcu::fuzzyCompare(log, "ImageComparison", "Image Comparison", reference.getAccess(), rendered.getAccess(), 0.02f, tcu::COMPARE_LOG_RESULT);

		m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, success ? "Pass" : "Image comparison failed");
		return STOP;
	}
}

// Test per-patch inputs/outputs.
class PerPatchDataCase : public TestCase
{
public:
	enum CaseType
	{
		CASETYPE_PRIMITIVE_ID_TCS = 0,
		CASETYPE_PRIMITIVE_ID_TES,
		CASETYPE_PATCH_VERTICES_IN_TCS,
		CASETYPE_PATCH_VERTICES_IN_TES,
		CASETYPE_TESS_LEVEL_INNER0_TES,
		CASETYPE_TESS_LEVEL_INNER1_TES,
		CASETYPE_TESS_LEVEL_OUTER0_TES,
		CASETYPE_TESS_LEVEL_OUTER1_TES,
		CASETYPE_TESS_LEVEL_OUTER2_TES,
		CASETYPE_TESS_LEVEL_OUTER3_TES,

		CASETYPE_LAST
	};

	PerPatchDataCase (Context& context, const char* name, const char* description, CaseType caseType, const char* referenceImagePath)
		: TestCase				(context, name, description)
		, m_caseType			(caseType)
		, m_referenceImagePath	(caseTypeUsesRefImageFromFile(caseType) ? referenceImagePath : "")
	{
		DE_ASSERT(caseTypeUsesRefImageFromFile(caseType) == (referenceImagePath != DE_NULL));
	}

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

	static const char*				getCaseTypeName					(CaseType);
	static const char*				getCaseTypeDescription			(CaseType);
	static bool						caseTypeUsesRefImageFromFile	(CaseType);

private:
	static const int				RENDER_SIZE = 256;
	static const int				INPUT_PATCH_SIZE;
	static const int				OUTPUT_PATCH_SIZE;

	const CaseType					m_caseType;
	const string					m_referenceImagePath;

	SharedPtr<const ShaderProgram>	m_program;
};

const int PerPatchDataCase::INPUT_PATCH_SIZE	= 10;
const int PerPatchDataCase::OUTPUT_PATCH_SIZE	= 5;

const char* PerPatchDataCase::getCaseTypeName (CaseType type)
{
	switch (type)
	{
		case CASETYPE_PRIMITIVE_ID_TCS:			return "primitive_id_tcs";
		case CASETYPE_PRIMITIVE_ID_TES:			return "primitive_id_tes";
		case CASETYPE_PATCH_VERTICES_IN_TCS:	return "patch_vertices_in_tcs";
		case CASETYPE_PATCH_VERTICES_IN_TES:	return "patch_vertices_in_tes";
		case CASETYPE_TESS_LEVEL_INNER0_TES:	return "tess_level_inner_0_tes";
		case CASETYPE_TESS_LEVEL_INNER1_TES:	return "tess_level_inner_1_tes";
		case CASETYPE_TESS_LEVEL_OUTER0_TES:	return "tess_level_outer_0_tes";
		case CASETYPE_TESS_LEVEL_OUTER1_TES:	return "tess_level_outer_1_tes";
		case CASETYPE_TESS_LEVEL_OUTER2_TES:	return "tess_level_outer_2_tes";
		case CASETYPE_TESS_LEVEL_OUTER3_TES:	return "tess_level_outer_3_tes";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

const char* PerPatchDataCase::getCaseTypeDescription (CaseType type)
{
	switch (type)
	{
		case CASETYPE_PRIMITIVE_ID_TCS:			return "Read gl_PrimitiveID in TCS and pass it as patch output to TES";
		case CASETYPE_PRIMITIVE_ID_TES:			return "Read gl_PrimitiveID in TES";
		case CASETYPE_PATCH_VERTICES_IN_TCS:	return "Read gl_PatchVerticesIn in TCS and pass it as patch output to TES";
		case CASETYPE_PATCH_VERTICES_IN_TES:	return "Read gl_PatchVerticesIn in TES";
		case CASETYPE_TESS_LEVEL_INNER0_TES:	return "Read gl_TessLevelInner[0] in TES";
		case CASETYPE_TESS_LEVEL_INNER1_TES:	return "Read gl_TessLevelInner[1] in TES";
		case CASETYPE_TESS_LEVEL_OUTER0_TES:	return "Read gl_TessLevelOuter[0] in TES";
		case CASETYPE_TESS_LEVEL_OUTER1_TES:	return "Read gl_TessLevelOuter[1] in TES";
		case CASETYPE_TESS_LEVEL_OUTER2_TES:	return "Read gl_TessLevelOuter[2] in TES";
		case CASETYPE_TESS_LEVEL_OUTER3_TES:	return "Read gl_TessLevelOuter[3] in TES";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

bool PerPatchDataCase::caseTypeUsesRefImageFromFile (CaseType type)
{
	switch (type)
	{
		case CASETYPE_PRIMITIVE_ID_TCS:
		case CASETYPE_PRIMITIVE_ID_TES:
			return true;

		default:
			return false;
	}
}

void PerPatchDataCase::init (void)
{
	checkTessellationSupport(m_context);
	checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE);

	DE_ASSERT(OUTPUT_PATCH_SIZE < INPUT_PATCH_SIZE);

	const string inSizeStr		= de::toString(INPUT_PATCH_SIZE);
	const string outSizeStr		= de::toString(OUTPUT_PATCH_SIZE);

	m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
			<< glu::VertexSource					("#version 310 es\n"
													 "\n"
													 "in highp float in_v_attr;\n"
													 "\n"
													 "out highp float in_tc_attr;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	in_tc_attr = in_v_attr;\n"
													 "}\n")

			<< glu::TessellationControlSource		("#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													 "\n"
													 "layout (vertices = " + outSizeStr + ") out;\n"
													 "\n"
													 "in highp float in_tc_attr[];\n"
													 "\n"
													 "out highp float in_te_attr[];\n"
													 + (m_caseType == CASETYPE_PRIMITIVE_ID_TCS			? "patch out mediump int in_te_primitiveIDFromTCS;\n"
													  : m_caseType == CASETYPE_PATCH_VERTICES_IN_TCS	? "patch out mediump int in_te_patchVerticesInFromTCS;\n"
													  : "") +
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	in_te_attr[gl_InvocationID] = in_tc_attr[gl_InvocationID];\n"
													 + (m_caseType == CASETYPE_PRIMITIVE_ID_TCS			? "\tin_te_primitiveIDFromTCS = gl_PrimitiveID;\n"
													  : m_caseType == CASETYPE_PATCH_VERTICES_IN_TCS	? "\tin_te_patchVerticesInFromTCS = gl_PatchVerticesIn;\n"
													  : "") +
													 "\n"
													 "	gl_TessLevelInner[0] = 9.0;\n"
													 "	gl_TessLevelInner[1] = 8.0;\n"
													 "\n"
													"	gl_TessLevelOuter[0] = 7.0;\n"
													"	gl_TessLevelOuter[1] = 6.0;\n"
													"	gl_TessLevelOuter[2] = 5.0;\n"
													"	gl_TessLevelOuter[3] = 4.0;\n"
													 "}\n")

			<< glu::TessellationEvaluationSource	("#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													 "\n"
													 + getTessellationEvaluationInLayoutString(TESSPRIMITIVETYPE_QUADS) +
													 "\n"
													 "in highp float in_te_attr[];\n"
													 + (m_caseType == CASETYPE_PRIMITIVE_ID_TCS			? "patch in mediump int in_te_primitiveIDFromTCS;\n"
													  : m_caseType == CASETYPE_PATCH_VERTICES_IN_TCS	? "patch in mediump int in_te_patchVerticesInFromTCS;\n"
													  : string()) +
													 "\n"
													 "out mediump vec4 in_f_color;\n"
													 "\n"
													 "uniform highp float u_xScale;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	highp float x = (gl_TessCoord.x*u_xScale + in_te_attr[0]) * 2.0 - 1.0;\n"
													 "	highp float y = gl_TessCoord.y*2.0 - 1.0;\n"
													 "	gl_Position = vec4(x, y, 0.0, 1.0);\n"
													 + (m_caseType == CASETYPE_PRIMITIVE_ID_TCS			? "\tbool ok = in_te_primitiveIDFromTCS == 3;\n"
													  : m_caseType == CASETYPE_PRIMITIVE_ID_TES			? "\tbool ok = gl_PrimitiveID == 3;\n"
													  : m_caseType == CASETYPE_PATCH_VERTICES_IN_TCS	? "\tbool ok = in_te_patchVerticesInFromTCS == " + inSizeStr + ";\n"
													  : m_caseType == CASETYPE_PATCH_VERTICES_IN_TES	? "\tbool ok = gl_PatchVerticesIn == " + outSizeStr + ";\n"
													  : m_caseType == CASETYPE_TESS_LEVEL_INNER0_TES	? "\tbool ok = abs(gl_TessLevelInner[0] - 9.0) < 0.1f;\n"
													  : m_caseType == CASETYPE_TESS_LEVEL_INNER1_TES	? "\tbool ok = abs(gl_TessLevelInner[1] - 8.0) < 0.1f;\n"
													  : m_caseType == CASETYPE_TESS_LEVEL_OUTER0_TES	? "\tbool ok = abs(gl_TessLevelOuter[0] - 7.0) < 0.1f;\n"
													  : m_caseType == CASETYPE_TESS_LEVEL_OUTER1_TES	? "\tbool ok = abs(gl_TessLevelOuter[1] - 6.0) < 0.1f;\n"
													  : m_caseType == CASETYPE_TESS_LEVEL_OUTER2_TES	? "\tbool ok = abs(gl_TessLevelOuter[2] - 5.0) < 0.1f;\n"
													  : m_caseType == CASETYPE_TESS_LEVEL_OUTER3_TES	? "\tbool ok = abs(gl_TessLevelOuter[3] - 4.0) < 0.1f;\n"
													  : DE_NULL) +
													  "	in_f_color = ok ? vec4(1.0) : vec4(vec3(0.0), 1.0);\n"
													 "}\n")

			<< glu::FragmentSource					("#version 310 es\n"
													 "\n"
													 "layout (location = 0) out mediump vec4 o_color;\n"
													 "\n"
													 "in mediump vec4 in_f_color;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	o_color = in_f_color;\n"
													 "}\n")));

	m_testCtx.getLog() << *m_program;
	if (!m_program->isOk())
		TCU_FAIL("Program compilation failed");
}

void PerPatchDataCase::deinit (void)
{
	m_program.clear();
}

PerPatchDataCase::IterateResult PerPatchDataCase::iterate (void)
{
	TestLog&					log						= m_testCtx.getLog();
	const RenderContext&		renderCtx				= m_context.getRenderContext();
	const RandomViewport		viewport				(renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName()));
	const deUint32				programGL				= m_program->getProgram();
	const glw::Functions&		gl						= renderCtx.getFunctions();

	setViewport(gl, viewport);
	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.useProgram(programGL);

	log << TestLog::Message << "Note: input patch size is " << INPUT_PATCH_SIZE << ", output patch size is " << OUTPUT_PATCH_SIZE << TestLog::EndMessage;

	{
		const int numPrimitives = m_caseType == CASETYPE_PRIMITIVE_ID_TCS || m_caseType == CASETYPE_PRIMITIVE_ID_TES ? 8 : 1;

		vector<float> attributeData;
		attributeData.reserve(numPrimitives*INPUT_PATCH_SIZE);

		for (int i = 0; i < numPrimitives; i++)
		{
			attributeData.push_back((float)i / (float)numPrimitives);
			for (int j = 0; j < INPUT_PATCH_SIZE-1; j++)
				attributeData.push_back(0.0f);
		}

		gl.patchParameteri(GL_PATCH_VERTICES, INPUT_PATCH_SIZE);
		gl.clear(GL_COLOR_BUFFER_BIT);

		gl.uniform1f(gl.getUniformLocation(programGL, "u_xScale"), 1.0f / (float)numPrimitives);

		const glu::VertexArrayBinding attrBindings[] =
		{
			glu::va::Float("in_v_attr", 1, (int)attributeData.size(), 0, &attributeData[0])
		};

		glu::draw(m_context.getRenderContext(), programGL, DE_LENGTH_OF_ARRAY(attrBindings), &attrBindings[0],
			glu::pr::Patches(numPrimitives*INPUT_PATCH_SIZE));
		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed");
	}

	{
		const tcu::Surface rendered = getPixels(renderCtx, viewport);

		if (m_caseType == CASETYPE_PRIMITIVE_ID_TCS || m_caseType == CASETYPE_PRIMITIVE_ID_TES)
		{
			DE_ASSERT(caseTypeUsesRefImageFromFile(m_caseType));

			const tcu::TextureLevel		reference	= getPNG(m_testCtx.getArchive(), m_referenceImagePath);
			const bool					success		= tcu::fuzzyCompare(log, "ImageComparison", "Image Comparison", reference.getAccess(), rendered.getAccess(), 0.02f, tcu::COMPARE_LOG_RESULT);

			m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, success ? "Pass" : "Image comparison failed");
			return STOP;
		}
		else
		{
			DE_ASSERT(!caseTypeUsesRefImageFromFile(m_caseType));

			log << TestLog::Image("RenderedImage", "Rendered Image", rendered);

			for (int y = 0; y < rendered.getHeight();	y++)
			for (int x = 0; x < rendered.getWidth();	x++)
			{
				if (rendered.getPixel(x, y) != tcu::RGBA::white)
				{
					log << TestLog::Message << "Failure: expected all white pixels" << TestLog::EndMessage;
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
					return STOP;
				}
			}

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

// Basic barrier() usage in TCS.
class BarrierCase : public TestCase
{
public:
	BarrierCase (Context& context, const char* name, const char* description, const char* referenceImagePath)
		: TestCase				(context, name, description)
		, m_referenceImagePath	(referenceImagePath)
	{
	}

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

private:
	static const int				RENDER_SIZE = 256;
	static const int				NUM_VERTICES;

	const string					m_referenceImagePath;

	SharedPtr<const ShaderProgram>	m_program;
};

const int BarrierCase::NUM_VERTICES = 32;

void BarrierCase::init (void)
{
	checkTessellationSupport(m_context);
	checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE);

	const string numVertsStr = de::toString(NUM_VERTICES);

	m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
			<< glu::VertexSource					("#version 310 es\n"
													 "\n"
													 "in highp float in_v_attr;\n"
													 "\n"
													 "out highp float in_tc_attr;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	in_tc_attr = in_v_attr;\n"
													 "}\n")

			<< glu::TessellationControlSource		("#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													 "\n"
													 "layout (vertices = " + numVertsStr + ") out;\n"
													 "\n"
													 "in highp float in_tc_attr[];\n"
													 "\n"
													 "out highp float in_te_attr[];\n"
													 "patch out highp float in_te_patchAttr;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	in_te_attr[gl_InvocationID] = in_tc_attr[gl_InvocationID];\n"
													 "	in_te_patchAttr = 0.0f;\n"
													 "	barrier();\n"
													 "	if (gl_InvocationID == 5)\n"
													 "		in_te_patchAttr = float(gl_InvocationID)*0.1;\n"
													 "	barrier();\n"
													 "	highp float temp = in_te_patchAttr + in_te_attr[gl_InvocationID];\n"
													 "	barrier();\n"
													 "	if (gl_InvocationID == " + numVertsStr + "-1)\n"
													 "		in_te_patchAttr = float(gl_InvocationID);\n"
													 "	barrier();\n"
													 "	in_te_attr[gl_InvocationID] = temp;\n"
													 "	barrier();\n"
													 "	temp = temp + in_te_attr[(gl_InvocationID+1) % " + numVertsStr + "];\n"
													 "	barrier();\n"
													 "	in_te_attr[gl_InvocationID] = 0.25*temp;\n"
													 "\n"
													 "	gl_TessLevelInner[0] = 32.0;\n"
													 "	gl_TessLevelInner[1] = 32.0;\n"
													 "\n"
													 "	gl_TessLevelOuter[0] = 32.0;\n"
													 "	gl_TessLevelOuter[1] = 32.0;\n"
													 "	gl_TessLevelOuter[2] = 32.0;\n"
													 "	gl_TessLevelOuter[3] = 32.0;\n"
													 "}\n")

			<< glu::TessellationEvaluationSource	("#version 310 es\n"
													 "#extension GL_EXT_tessellation_shader : require\n"
													 "\n"
													 + getTessellationEvaluationInLayoutString(TESSPRIMITIVETYPE_QUADS) +
													 "\n"
													 "in highp float in_te_attr[];\n"
													 "patch in highp float in_te_patchAttr;\n"
													 "\n"
													 "out highp float in_f_blue;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	highp float x = gl_TessCoord.x*2.0 - 1.0;\n"
													 "	highp float y = gl_TessCoord.y - in_te_attr[int(round(gl_TessCoord.x*float(" + numVertsStr + "-1)))];\n"
													 "	gl_Position = vec4(x, y, 0.0, 1.0);\n"
													 "	in_f_blue = abs(in_te_patchAttr - float(" + numVertsStr + "-1));\n"
													 "}\n")

			<< glu::FragmentSource					("#version 310 es\n"
													 "\n"
													 "layout (location = 0) out mediump vec4 o_color;\n"
													 "\n"
													 "in highp float in_f_blue;\n"
													 "\n"
													 "void main (void)\n"
													 "{\n"
													 "	o_color = vec4(1.0, 0.0, in_f_blue, 1.0);\n"
													 "}\n")));

	m_testCtx.getLog() << *m_program;
	if (!m_program->isOk())
		TCU_FAIL("Program compilation failed");
}

void BarrierCase::deinit (void)
{
	m_program.clear();
}

BarrierCase::IterateResult BarrierCase::iterate (void)
{
	TestLog&					log						= m_testCtx.getLog();
	const RenderContext&		renderCtx				= m_context.getRenderContext();
	const RandomViewport		viewport				(renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName()));
	const deUint32				programGL				= m_program->getProgram();
	const glw::Functions&		gl						= renderCtx.getFunctions();

	setViewport(gl, viewport);
	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.useProgram(programGL);

	{
		vector<float> attributeData(NUM_VERTICES);

		for (int i = 0; i < NUM_VERTICES; i++)
			attributeData[i] = (float)i / (float)(NUM_VERTICES-1);

		gl.patchParameteri(GL_PATCH_VERTICES, NUM_VERTICES);
		gl.clear(GL_COLOR_BUFFER_BIT);

		const glu::VertexArrayBinding attrBindings[] =
		{
			glu::va::Float("in_v_attr", 1, (int)attributeData.size(), 0, &attributeData[0])
		};

		glu::draw(m_context.getRenderContext(), programGL, DE_LENGTH_OF_ARRAY(attrBindings), &attrBindings[0],
			glu::pr::Patches(NUM_VERTICES));
		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed");
	}

	{
		const tcu::Surface			rendered	= getPixels(renderCtx, viewport);
		const tcu::TextureLevel		reference	= getPNG(m_testCtx.getArchive(), m_referenceImagePath);
		const bool					success		= tcu::fuzzyCompare(log, "ImageComparison", "Image Comparison", reference.getAccess(), rendered.getAccess(), 0.02f, tcu::COMPARE_LOG_RESULT);

		m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, success ? "Pass" : "Image comparison failed");
		return STOP;
	}
}

/*--------------------------------------------------------------------*//*!
 * \brief Base class for testing invariance of entire primitive set
 *
 * Draws two patches with identical tessellation levels and compares the
 * results. Repeats the same with other programs that are only different
 * in irrelevant ways; compares the results between these two programs.
 * Also potentially compares to results produced by different tessellation
 * levels (see e.g. invariance rule #6).
 * Furthermore, repeats the above with multiple different tessellation
 * value sets.
 *
 * The manner of primitive set comparison is defined by subclass. E.g.
 * case for invariance rule #1 tests that same vertices come out, in same
 * order; rule #5 only requires that the same triangles are output, but
 * not necessarily in the same order.
 *//*--------------------------------------------------------------------*/
class PrimitiveSetInvarianceCase : public TestCase
{
public:
	enum WindingUsage
	{
		WINDINGUSAGE_CCW = 0,
		WINDINGUSAGE_CW,
		WINDINGUSAGE_VARY,

		WINDINGUSAGE_LAST
	};

	PrimitiveSetInvarianceCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing, bool usePointMode, WindingUsage windingUsage)
		: TestCase			(context, name, description)
		, m_primitiveType	(primType)
		, m_spacing			(spacing)
		, m_usePointMode	(usePointMode)
		, m_windingUsage	(windingUsage)
	{
	}

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

protected:
	struct TessLevels
	{
		float inner[2];
		float outer[4];
		string description (void) const { return tessellationLevelsString(&inner[0], &outer[0]); }
	};
	struct LevelCase
	{
		vector<TessLevels>	levels;
		int					mem; //!< Subclass-defined arbitrary piece of data, for type of the levelcase, if needed. Passed to compare().
		LevelCase (const TessLevels& lev) : levels(vector<TessLevels>(1, lev)), mem(0) {}
		LevelCase (void) : mem(0) {}
	};

	virtual vector<LevelCase>	genTessLevelCases	(void) const;
	virtual bool				compare				(const vector<Vec3>& coordsA, const vector<Vec3>& coordsB, int levelCaseMem) const = 0;

	const TessPrimitiveType		m_primitiveType;

private:
	struct Program
	{
		Winding							winding;
		SharedPtr<const ShaderProgram>	program;

				Program			(Winding w, const SharedPtr<const ShaderProgram>& prog) : winding(w), program(prog) {}

		string	description		(void) const { return string() + "winding mode " + getWindingShaderName(winding); };
	};

	static const int			RENDER_SIZE = 16;

	const SpacingMode			m_spacing;
	const bool					m_usePointMode;
	const WindingUsage			m_windingUsage;

	vector<Program>				m_programs;
};

vector<PrimitiveSetInvarianceCase::LevelCase> PrimitiveSetInvarianceCase::genTessLevelCases (void) const
{
	static const TessLevels basicTessLevelCases[] =
	{
		{ { 1.0f,	1.0f	},	{ 1.0f,		1.0f,	1.0f,	1.0f	} },
		{ { 63.0f,	24.0f	},	{ 15.0f,	42.0f,	10.0f,	12.0f	} },
		{ { 3.0f,	2.0f	},	{ 6.0f,		8.0f,	7.0f,	9.0f	} },
		{ { 4.0f,	6.0f	},	{ 2.0f,		3.0f,	1.0f,	4.0f	} },
		{ { 2.0f,	2.0f	},	{ 6.0f,		8.0f,	7.0f,	9.0f	} },
		{ { 5.0f,	6.0f	},	{ 1.0f,		1.0f,	1.0f,	1.0f	} },
		{ { 1.0f,	6.0f	},	{ 2.0f,		3.0f,	1.0f,	4.0f	} },
		{ { 5.0f,	1.0f	},	{ 2.0f,		3.0f,	1.0f,	4.0f	} },
		{ { 5.2f,	1.6f	},	{ 2.9f,		3.4f,	1.5f,	4.1f	} }
	};

	vector<LevelCase> result;
	for (int i = 0; i < DE_LENGTH_OF_ARRAY(basicTessLevelCases); i++)
		result.push_back(LevelCase(basicTessLevelCases[i]));

	{
		de::Random rnd(123);
		for (int i = 0; i < 10; i++)
		{
			TessLevels levels;
			for (int j = 0; j < DE_LENGTH_OF_ARRAY(levels.inner); j++)
				levels.inner[j] = rnd.getFloat(1.0f, 16.0f);
			for (int j = 0; j < DE_LENGTH_OF_ARRAY(levels.outer); j++)
				levels.outer[j] = rnd.getFloat(1.0f, 16.0f);
			result.push_back(LevelCase(levels));
		}
	}

	return result;
}

void PrimitiveSetInvarianceCase::init (void)
{
	const int			numDifferentConstantExprCases = 2;
	vector<Winding>		windings;
	switch (m_windingUsage)
	{
		case WINDINGUSAGE_CCW:		windings.push_back(WINDING_CCW); break;
		case WINDINGUSAGE_CW:		windings.push_back(WINDING_CW); break;
		case WINDINGUSAGE_VARY:		windings.push_back(WINDING_CCW);
									windings.push_back(WINDING_CW); break;
		default: DE_ASSERT(false);
	}

	checkTessellationSupport(m_context);
	checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE);

	for (int constantExprCaseNdx = 0; constantExprCaseNdx < numDifferentConstantExprCases; constantExprCaseNdx++)
	{
		for (int windingCaseNdx = 0; windingCaseNdx < (int)windings.size(); windingCaseNdx++)
		{
			const string	floatLit01 = de::floatToString(10.0f / (float)(constantExprCaseNdx + 10), 2);
			const int		programNdx = (int)m_programs.size();

			m_programs.push_back(Program(windings[windingCaseNdx],
										 SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
					<< glu::VertexSource					("#version 310 es\n"
															 "\n"
															 "in highp float in_v_attr;\n"
															 "out highp float in_tc_attr;\n"
															 "\n"
															 "void main (void)\n"
															 "{\n"
															 "	in_tc_attr = in_v_attr;\n"
															 "}\n")

					<< glu::TessellationControlSource		("#version 310 es\n"
															 "#extension GL_EXT_tessellation_shader : require\n"
															 "\n"
															 "layout (vertices = " + de::toString(constantExprCaseNdx+1) + ") out;\n"
															 "\n"
															 "in highp float in_tc_attr[];\n"
															 "\n"
															 "patch out highp float in_te_positionOffset;\n"
															 "\n"
															 "void main (void)\n"
															 "{\n"
															 "	in_te_positionOffset = in_tc_attr[6];\n"
															 "\n"
															 "	gl_TessLevelInner[0] = in_tc_attr[0];\n"
															 "	gl_TessLevelInner[1] = in_tc_attr[1];\n"
															 "\n"
															 "	gl_TessLevelOuter[0] = in_tc_attr[2];\n"
															 "	gl_TessLevelOuter[1] = in_tc_attr[3];\n"
															 "	gl_TessLevelOuter[2] = in_tc_attr[4];\n"
															 "	gl_TessLevelOuter[3] = in_tc_attr[5];\n"
															 "}\n")

					<< glu::TessellationEvaluationSource	("#version 310 es\n"
															 "#extension GL_EXT_tessellation_shader : require\n"
															 "\n"
															 + getTessellationEvaluationInLayoutString(m_primitiveType, m_spacing, windings[windingCaseNdx], m_usePointMode) +
															 "\n"
															 "patch in highp float in_te_positionOffset;\n"
															 "\n"
															 "out highp vec4 in_f_color;\n"
															 "invariant out highp vec3 out_te_tessCoord;\n"
															 "\n"
															 "void main (void)\n"
															 "{\n"
															 "	gl_Position = vec4(gl_TessCoord.xy*" + floatLit01 + " - in_te_positionOffset + float(gl_PrimitiveID)*0.1, 0.0, 1.0);\n"
															 "	in_f_color = vec4(" + floatLit01 + ");\n"
															 "	out_te_tessCoord = gl_TessCoord;\n"
															 "}\n")

					<< glu::FragmentSource					("#version 310 es\n"
															 "\n"
															 "layout (location = 0) out mediump vec4 o_color;\n"
															 "\n"
															 "in highp vec4 in_f_color;\n"
															 "\n"
															 "void main (void)\n"
															 "{\n"
															 "	o_color = in_f_color;\n"
															 "}\n")

					<< glu::TransformFeedbackVarying		("out_te_tessCoord")
					<< glu::TransformFeedbackMode			(GL_INTERLEAVED_ATTRIBS)))));

			{
				const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program" + de::toString(programNdx), "Program " + de::toString(programNdx));

				if (programNdx == 0 || !m_programs.back().program->isOk())
					m_testCtx.getLog() << *m_programs.back().program;

				if (!m_programs.back().program->isOk())
					TCU_FAIL("Program compilation failed");

				if (programNdx > 0)
					m_testCtx.getLog() << TestLog::Message << "Note: program " << programNdx << " is similar to above, except some constants are different, and: " << m_programs.back().description() << TestLog::EndMessage;
			}
		}
	}
}

void PrimitiveSetInvarianceCase::deinit (void)
{
	m_programs.clear();
}

PrimitiveSetInvarianceCase::IterateResult PrimitiveSetInvarianceCase::iterate (void)
{
	typedef TransformFeedbackHandler<Vec3> TFHandler;

	TestLog&					log					= m_testCtx.getLog();
	const RenderContext&		renderCtx			= m_context.getRenderContext();
	const RandomViewport		viewport			(renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName()));
	const glw::Functions&		gl					= renderCtx.getFunctions();
	const vector<LevelCase>		tessLevelCases		= genTessLevelCases();
	vector<vector<int> >		primitiveCounts;
	int							maxNumPrimitives	= -1;

	for (int caseNdx = 0; caseNdx < (int)tessLevelCases.size(); caseNdx++)
	{
		primitiveCounts.push_back(vector<int>());
		for (int i = 0; i < (int)tessLevelCases[caseNdx].levels.size(); i++)
		{
			const int primCount = referencePrimitiveCount(m_primitiveType, m_spacing, m_usePointMode,
														  &tessLevelCases[caseNdx].levels[i].inner[0], &tessLevelCases[caseNdx].levels[i].outer[0]);
			primitiveCounts.back().push_back(primCount);
			maxNumPrimitives = de::max(maxNumPrimitives, primCount);
		}
	}

	const deUint32				primitiveTypeGL		= outputPrimitiveTypeGL(m_primitiveType, m_usePointMode);
	const TFHandler				transformFeedback	(m_context.getRenderContext(), 2*maxNumPrimitives*numVerticesPerPrimitive(primitiveTypeGL));

	setViewport(gl, viewport);
	gl.patchParameteri(GL_PATCH_VERTICES, 7);

	for (int tessLevelCaseNdx = 0; tessLevelCaseNdx < (int)tessLevelCases.size(); tessLevelCaseNdx++)
	{
		const LevelCase&	levelCase = tessLevelCases[tessLevelCaseNdx];
		vector<Vec3>		firstPrimVertices;

		{
			string tessLevelsStr;
			for (int i = 0; i < (int)levelCase.levels.size(); i++)
				tessLevelsStr += (levelCase.levels.size() > 1 ? "\n" : "") + levelCase.levels[i].description();
			log << TestLog::Message << "Tessellation level sets: " << tessLevelsStr << TestLog::EndMessage;
		}

		for (int subTessLevelCaseNdx = 0; subTessLevelCaseNdx < (int)levelCase.levels.size(); subTessLevelCaseNdx++)
		{
			const TessLevels&				tessLevels		= levelCase.levels[subTessLevelCaseNdx];
			const float						(&inner)[2]		= tessLevels.inner;
			const float						(&outer)[4]		= tessLevels.outer;
			const float						attribute[2*7]	= { inner[0], inner[1], outer[0], outer[1], outer[2], outer[3], 0.0f,
																inner[0], inner[1], outer[0], outer[1], outer[2], outer[3], 0.5f };
			const glu::VertexArrayBinding	bindings[]		= { glu::va::Float("in_v_attr", 1, DE_LENGTH_OF_ARRAY(attribute), 0, &attribute[0]) };

			for (int programNdx = 0; programNdx < (int)m_programs.size(); programNdx++)
			{
				const deUint32				programGL	= m_programs[programNdx].program->getProgram();
				gl.useProgram(programGL);
				const TFHandler::Result		tfResult	= transformFeedback.renderAndGetPrimitives(programGL, primitiveTypeGL, DE_LENGTH_OF_ARRAY(bindings), &bindings[0], DE_LENGTH_OF_ARRAY(attribute));

				if (tfResult.numPrimitives != 2*primitiveCounts[tessLevelCaseNdx][subTessLevelCaseNdx])
				{
					log << TestLog::Message << "Failure: GL reported GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN to be "
											<< tfResult.numPrimitives << ", reference value is " << 2*primitiveCounts[tessLevelCaseNdx][subTessLevelCaseNdx]
											<< TestLog::EndMessage;

					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of primitives");
					return STOP;
				}

				{
					const int			half			= (int)tfResult.varying.size()/2;
					const vector<Vec3>	prim0Vertices	= vector<Vec3>(tfResult.varying.begin(), tfResult.varying.begin() + half);
					const Vec3* const	prim1Vertices	= &tfResult.varying[half];

					for (int vtxNdx = 0; vtxNdx < (int)prim0Vertices.size(); vtxNdx++)
					{
						if (prim0Vertices[vtxNdx] != prim1Vertices[vtxNdx])
						{
							log << TestLog::Message << "Failure: tessellation coordinate at index " << vtxNdx << " differs between two primitives drawn in one draw call" << TestLog::EndMessage
								<< TestLog::Message << "Note: the coordinate is " << prim0Vertices[vtxNdx] << " for the first primitive and " << prim1Vertices[vtxNdx] << " for the second" << TestLog::EndMessage
								<< TestLog::Message << "Note: tessellation levels for both primitives were: " << tessellationLevelsString(&inner[0], &outer[0]) << TestLog::EndMessage;
							m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of primitives");
							return STOP;
						}
					}

					if (programNdx == 0 && subTessLevelCaseNdx == 0)
						firstPrimVertices = prim0Vertices;
					else
					{
						const bool compareOk = compare(firstPrimVertices, prim0Vertices, levelCase.mem);
						if (!compareOk)
						{
							log << TestLog::Message << "Note: comparison of tessellation coordinates failed; comparison was made between following cases:\n"
													<< "  - case A: program 0, tessellation levels: " << tessLevelCases[tessLevelCaseNdx].levels[0].description() << "\n"
													<< "  - case B: program " << programNdx << ", tessellation levels: " << tessLevels.description() << TestLog::EndMessage;
							m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of primitives");
							return STOP;
						}
					}
				}
			}
		}
	}

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

/*--------------------------------------------------------------------*//*!
 * \brief Test invariance rule #1
 *
 * Test that the sequence of primitives input to the TES only depends on
 * the tessellation levels, tessellation mode, spacing mode, winding, and
 * point mode.
 *//*--------------------------------------------------------------------*/
class InvariantPrimitiveSetCase : public PrimitiveSetInvarianceCase
{
public:
	InvariantPrimitiveSetCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing, Winding winding, bool usePointMode)
		: PrimitiveSetInvarianceCase(context, name, description, primType, spacing, usePointMode, winding == WINDING_CCW	? WINDINGUSAGE_CCW
																								: winding == WINDING_CW		? WINDINGUSAGE_CW
																								: WINDINGUSAGE_LAST)
	{
	}

protected:
	virtual bool compare (const vector<Vec3>& coordsA, const vector<Vec3>& coordsB, int) const
	{
		for (int vtxNdx = 0; vtxNdx < (int)coordsA.size(); vtxNdx++)
		{
			if (coordsA[vtxNdx] != coordsB[vtxNdx])
			{
				m_testCtx.getLog() << TestLog::Message << "Failure: tessellation coordinate at index " << vtxNdx << " differs between two programs" << TestLog::EndMessage
								   << TestLog::Message << "Note: the coordinate is " << coordsA[vtxNdx] << " for the first program and " << coordsB[vtxNdx] << " for the other" << TestLog::EndMessage;
				return false;
			}
		}
		return true;
	}
};

/*--------------------------------------------------------------------*//*!
 * \brief Test invariance rule #2
 *
 * Test that the set of vertices along an outer edge of a quad or triangle
 * only depends on that edge's tessellation level, and spacing.
 *
 * For each (outer) edge in the quad or triangle, draw multiple patches
 * with identical tessellation levels for that outer edge but with
 * different values for the other outer edges; compare, among the
 * primitives, the vertices generated for that outer edge. Repeat with
 * different programs, using different winding etc. settings. Compare
 * the edge's vertices between different programs.
 *//*--------------------------------------------------------------------*/
class InvariantOuterEdgeCase : public TestCase
{
public:
	InvariantOuterEdgeCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing)
		: TestCase			(context, name, description)
		, m_primitiveType	(primType)
		, m_spacing			(spacing)
	{
		DE_ASSERT(primType == TESSPRIMITIVETYPE_TRIANGLES || primType == TESSPRIMITIVETYPE_QUADS);
	}

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

private:
	struct Program
	{
		Winding							winding;
		bool							usePointMode;
		SharedPtr<const ShaderProgram>	program;

				Program			(Winding w, bool point, const SharedPtr<const ShaderProgram>& prog) : winding(w), usePointMode(point), program(prog) {}

		string	description		(void) const { return string() + "winding mode " + getWindingShaderName(winding) + ", " + (usePointMode ? "" : "don't ") + "use point mode"; };
	};

	static vector<float>		generatePatchTessLevels (int numPatches, int constantOuterLevelIndex, float constantOuterLevel);

	static const int			RENDER_SIZE = 16;

	const TessPrimitiveType		m_primitiveType;
	const SpacingMode			m_spacing;

	vector<Program>				m_programs;
};

vector<float> InvariantOuterEdgeCase::generatePatchTessLevels (int numPatches, int constantOuterLevelIndex, float constantOuterLevel)
{
	de::Random rnd(123);
	return generateRandomPatchTessLevels(numPatches, constantOuterLevelIndex, constantOuterLevel, rnd);
}

void InvariantOuterEdgeCase::init (void)
{
	checkTessellationSupport(m_context);
	checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE);

	for (int windingI = 0; windingI < WINDING_LAST; windingI++)
	{
		const Winding winding = (Winding)windingI;

		for (int usePointModeI = 0; usePointModeI <= 1; usePointModeI++)
		{
			const bool		usePointMode	= usePointModeI != 0;
			const int		programNdx		= (int)m_programs.size();
			const string	floatLit01		= de::floatToString(10.0f / (float)(programNdx + 10), 2);

			m_programs.push_back(Program(winding, usePointMode,
										 SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
				<< glu::VertexSource					("#version 310 es\n"
														 "\n"
														 "in highp float in_v_attr;\n"
														 "out highp float in_tc_attr;\n"
														 "\n"
														 "void main (void)\n"
														 "{\n"
														 "	in_tc_attr = in_v_attr;\n"
														 "}\n")

				<< glu::TessellationControlSource		("#version 310 es\n"
														 "#extension GL_EXT_tessellation_shader : require\n"
														 "\n"
														 "layout (vertices = " + de::toString(programNdx+1) + ") out;\n"
														 "\n"
														 "in highp float in_tc_attr[];\n"
														 "\n"
														 "void main (void)\n"
														 "{\n"
														 "	gl_TessLevelInner[0] = in_tc_attr[0];\n"
														 "	gl_TessLevelInner[1] = in_tc_attr[1];\n"
														 "\n"
														 "	gl_TessLevelOuter[0] = in_tc_attr[2];\n"
														 "	gl_TessLevelOuter[1] = in_tc_attr[3];\n"
														 "	gl_TessLevelOuter[2] = in_tc_attr[4];\n"
														 "	gl_TessLevelOuter[3] = in_tc_attr[5];\n"
														 "}\n")

				<< glu::TessellationEvaluationSource	("#version 310 es\n"
														 "#extension GL_EXT_tessellation_shader : require\n"
														 "\n"
														 + getTessellationEvaluationInLayoutString(m_primitiveType, m_spacing, winding, usePointMode) +
														 "\n"
														 "out highp vec4 in_f_color;\n"
														 "invariant out highp vec3 out_te_tessCoord;\n"
														 "\n"
														 "void main (void)\n"
														 "{\n"
														 "	gl_Position = vec4(gl_TessCoord.xy*" + floatLit01 + " - float(gl_PrimitiveID)*0.05, 0.0, 1.0);\n"
														 "	in_f_color = vec4(" + floatLit01 + ");\n"
														 "	out_te_tessCoord = gl_TessCoord;\n"
														 "}\n")

				<< glu::FragmentSource					("#version 310 es\n"
														 "\n"
														 "layout (location = 0) out mediump vec4 o_color;\n"
														 "\n"
														 "in highp vec4 in_f_color;\n"
														 "\n"
														 "void main (void)\n"
														 "{\n"
														 "	o_color = in_f_color;\n"
														 "}\n")

				<< glu::TransformFeedbackVarying		("out_te_tessCoord")
				<< glu::TransformFeedbackMode			(GL_INTERLEAVED_ATTRIBS)))));

			{
				const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program" + de::toString(programNdx), "Program " + de::toString(programNdx));

				if (programNdx == 0 || !m_programs.back().program->isOk())
					m_testCtx.getLog() << *m_programs.back().program;

				if (!m_programs.back().program->isOk())
					TCU_FAIL("Program compilation failed");

				if (programNdx > 0)
					m_testCtx.getLog() << TestLog::Message << "Note: program " << programNdx << " is similar to above, except some constants are different, and: " << m_programs.back().description() << TestLog::EndMessage;
			}
		}
	}
}

void InvariantOuterEdgeCase::deinit (void)
{
	m_programs.clear();
}

InvariantOuterEdgeCase::IterateResult InvariantOuterEdgeCase::iterate (void)
{
	typedef TransformFeedbackHandler<Vec3> TFHandler;

	TestLog&							log							= m_testCtx.getLog();
	const RenderContext&				renderCtx					= m_context.getRenderContext();
	const RandomViewport				viewport					(renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName()));
	const glw::Functions&				gl							= renderCtx.getFunctions();

	static const float					singleOuterEdgeLevels[]		= { 1.0f, 1.2f, 1.9f, 2.3f, 2.8f, 3.3f, 3.8f, 10.2f, 1.6f, 24.4f, 24.7f, 63.0f };
	const int							numPatchesPerDrawCall		= 10;
	const vector<OuterEdgeDescription>	edgeDescriptions			= outerEdgeDescriptions(m_primitiveType);

	{
		// Compute the number vertices in the largest draw call, so we can allocate the TF buffer just once.
		int maxNumVerticesInDrawCall = 0;
		{
			const vector<float> patchTessLevels = generatePatchTessLevels(numPatchesPerDrawCall, 0 /* outer-edge index doesn't affect vertex count */, arrayMax(singleOuterEdgeLevels));

			for (int usePointModeI = 0; usePointModeI <= 1; usePointModeI++)
				maxNumVerticesInDrawCall = de::max(maxNumVerticesInDrawCall,
												   multiplePatchReferenceVertexCount(m_primitiveType, m_spacing, usePointModeI != 0, &patchTessLevels[0], numPatchesPerDrawCall));
		}

		{
			const TFHandler tfHandler(m_context.getRenderContext(), maxNumVerticesInDrawCall);

			setViewport(gl, viewport);
			gl.patchParameteri(GL_PATCH_VERTICES, 6);

			for (int outerEdgeIndex = 0; outerEdgeIndex < (int)edgeDescriptions.size(); outerEdgeIndex++)
			{
				const OuterEdgeDescription& edgeDesc = edgeDescriptions[outerEdgeIndex];

				for (int outerEdgeLevelCaseNdx = 0; outerEdgeLevelCaseNdx < DE_LENGTH_OF_ARRAY(singleOuterEdgeLevels); outerEdgeLevelCaseNdx++)
				{
					typedef std::set<Vec3, VecLexLessThan<3> > Vec3Set;

					const vector<float>				patchTessLevels		= generatePatchTessLevels(numPatchesPerDrawCall, outerEdgeIndex, singleOuterEdgeLevels[outerEdgeLevelCaseNdx]);
					const glu::VertexArrayBinding	bindings[]			= { glu::va::Float("in_v_attr", 1, (int)patchTessLevels.size(), 0, &patchTessLevels[0]) };
					Vec3Set							firstOuterEdgeVertices; // Vertices of the outer edge of the first patch of the first program's draw call; used for comparison with other patches.

					log << TestLog::Message << "Testing with outer tessellation level " << singleOuterEdgeLevels[outerEdgeLevelCaseNdx]
											<< " for the " << edgeDesc.description() << " edge, and with various levels for other edges, and with all programs" << TestLog::EndMessage;

					for (int programNdx = 0; programNdx < (int)m_programs.size(); programNdx++)
					{
						const Program& program		= m_programs[programNdx];
						const deUint32 programGL	= program.program->getProgram();

						gl.useProgram(programGL);

						{
							const TFHandler::Result		tfResult			= tfHandler.renderAndGetPrimitives(programGL, outputPrimitiveTypeGL(m_primitiveType, program.usePointMode),
																											   DE_LENGTH_OF_ARRAY(bindings), &bindings[0], (int)patchTessLevels.size());
							const int					refNumVertices		= multiplePatchReferenceVertexCount(m_primitiveType, m_spacing, program.usePointMode, &patchTessLevels[0], numPatchesPerDrawCall);
							int							numVerticesRead		= 0;

							if ((int)tfResult.varying.size() != refNumVertices)
							{
								log << TestLog::Message << "Failure: the number of vertices returned by transform feedback is "
														<< tfResult.varying.size() << ", expected " << refNumVertices << TestLog::EndMessage
									<< TestLog::Message << "Note: rendered " << numPatchesPerDrawCall
														<< " patches in one draw call; tessellation levels for each patch are (in order [inner0, inner1, outer0, outer1, outer2, outer3]):\n"
														<< containerStr(patchTessLevels, 6) << TestLog::EndMessage;

								m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of vertices");
								return STOP;
							}

							// Check the vertices of each patch.

							for (int patchNdx = 0; patchNdx < numPatchesPerDrawCall; patchNdx++)
							{
								const float* const	innerLevels			= &patchTessLevels[6*patchNdx + 0];
								const float* const	outerLevels			= &patchTessLevels[6*patchNdx + 2];
								const int			patchNumVertices	= referenceVertexCount(m_primitiveType, m_spacing, program.usePointMode, innerLevels, outerLevels);
								Vec3Set				outerEdgeVertices;

								// We're interested in just the vertices on the current outer edge.
								for(int vtxNdx = numVerticesRead; vtxNdx < numVerticesRead + patchNumVertices; vtxNdx++)
								{
									const Vec3& vtx = tfResult.varying[vtxNdx];
									if (edgeDesc.contains(vtx))
										outerEdgeVertices.insert(tfResult.varying[vtxNdx]);
								}

								// Check that the outer edge contains an appropriate number of vertices.
								{
									const int refNumVerticesOnOuterEdge = 1 + getClampedRoundedTessLevel(m_spacing, singleOuterEdgeLevels[outerEdgeLevelCaseNdx]);

									if ((int)outerEdgeVertices.size() != refNumVerticesOnOuterEdge)
									{
										log << TestLog::Message << "Failure: the number of vertices on outer edge is " << outerEdgeVertices.size()
																<< ", expected " << refNumVerticesOnOuterEdge << TestLog::EndMessage
											<< TestLog::Message << "Note: vertices on the outer edge are:\n" << containerStr(outerEdgeVertices, 5, 0) << TestLog::EndMessage
											<< TestLog::Message << "Note: the following parameters were used: " << program.description()
																<< ", tessellation levels: " << tessellationLevelsString(innerLevels, outerLevels) << TestLog::EndMessage;
										m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of vertices");
										return STOP;
									}
								}

								// Compare the vertices to those of the first patch (unless this is the first patch).

								if (programNdx == 0 && patchNdx == 0)
									firstOuterEdgeVertices = outerEdgeVertices;
								else
								{
									if (firstOuterEdgeVertices != outerEdgeVertices)
									{
										log << TestLog::Message << "Failure: vertices generated for the edge differ between the following cases:\n"
																<< "  - case A: " << m_programs[0].description() << ", tessellation levels: "
																				  << tessellationLevelsString(&patchTessLevels[0], &patchTessLevels[2]) << "\n"
																<< "  - case B: " << program.description() << ", tessellation levels: "
																				  << tessellationLevelsString(innerLevels, outerLevels) << TestLog::EndMessage;

										log << TestLog::Message << "Note: resulting vertices for the edge for the cases were:\n"
																<< "  - case A: " << containerStr(firstOuterEdgeVertices, 5, 14) << "\n"
																<< "  - case B: " << containerStr(outerEdgeVertices, 5, 14) << TestLog::EndMessage;

										m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of vertices");
										return STOP;
									}
								}

								numVerticesRead += patchNumVertices;
							}

							DE_ASSERT(numVerticesRead == (int)tfResult.varying.size());
						}
					}
				}
			}
		}
	}

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

/*--------------------------------------------------------------------*//*!
 * \brief Test invariance rule #3
 *
 * Test that the vertices along an outer edge are placed symmetrically.
 *
 * Draw multiple patches with different tessellation levels and different
 * point_mode, winding etc. Before outputting tesscoords with TF, mirror
 * the vertices in the TES such that every vertex on an outer edge -
 * except the possible middle vertex - should be duplicated in the output.
 * Check that appropriate duplicates exist.
 *//*--------------------------------------------------------------------*/
class SymmetricOuterEdgeCase : public TestCase
{
public:
	SymmetricOuterEdgeCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing, Winding winding, bool usePointMode)
		: TestCase			(context, name, description)
		, m_primitiveType	(primType)
		, m_spacing			(spacing)
		, m_winding			(winding)
		, m_usePointMode	(usePointMode)
	{
	}

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

private:
	static vector<float>					generatePatchTessLevels (int numPatches, int constantOuterLevelIndex, float constantOuterLevel);

	static const int						RENDER_SIZE = 16;

	const TessPrimitiveType					m_primitiveType;
	const SpacingMode						m_spacing;
	const Winding							m_winding;
	const bool								m_usePointMode;

	SharedPtr<const glu::ShaderProgram>		m_program;
};

vector<float> SymmetricOuterEdgeCase::generatePatchTessLevels (int numPatches, int constantOuterLevelIndex, float constantOuterLevel)
{
	de::Random rnd(123);
	return generateRandomPatchTessLevels(numPatches, constantOuterLevelIndex, constantOuterLevel, rnd);
}

void SymmetricOuterEdgeCase::init (void)
{
	checkTessellationSupport(m_context);
	checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE);

	m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
		<< glu::VertexSource					("#version 310 es\n"
												 "\n"
												 "in highp float in_v_attr;\n"
												 "out highp float in_tc_attr;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	in_tc_attr = in_v_attr;\n"
												 "}\n")

		<< glu::TessellationControlSource		("#version 310 es\n"
												 "#extension GL_EXT_tessellation_shader : require\n"
												 "\n"
												 "layout (vertices = 1) out;\n"
												 "\n"
												 "in highp float in_tc_attr[];\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	gl_TessLevelInner[0] = in_tc_attr[0];\n"
												 "	gl_TessLevelInner[1] = in_tc_attr[1];\n"
												 "\n"
												 "	gl_TessLevelOuter[0] = in_tc_attr[2];\n"
												 "	gl_TessLevelOuter[1] = in_tc_attr[3];\n"
												 "	gl_TessLevelOuter[2] = in_tc_attr[4];\n"
												 "	gl_TessLevelOuter[3] = in_tc_attr[5];\n"
												 "}\n")

		<< glu::TessellationEvaluationSource	("#version 310 es\n"
												 "#extension GL_EXT_tessellation_shader : require\n"
												 "\n"
												 + getTessellationEvaluationInLayoutString(m_primitiveType, m_spacing, m_winding, m_usePointMode) +
												 "\n"
												 "out highp vec4 in_f_color;\n"
												 "out highp vec4 out_te_tessCoord_isMirrored;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 + (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ?
													"	float x = gl_TessCoord.x;\n"
													"	float y = gl_TessCoord.y;\n"
													"	float z = gl_TessCoord.z;\n"
													"	// Mirror one half of each outer edge onto the other half, except the endpoints (because they belong to two edges)\n"
													"	out_te_tessCoord_isMirrored = z == 0.0 && x > 0.5 && x != 1.0 ? vec4(1.0-x,  1.0-y,    0.0, 1.0)\n"
													"	                            : y == 0.0 && z > 0.5 && z != 1.0 ? vec4(1.0-x,    0.0,  1.0-z, 1.0)\n"
													"	                            : x == 0.0 && y > 0.5 && y != 1.0 ? vec4(  0.0,  1.0-y,  1.0-z, 1.0)\n"
													"	                            : vec4(x, y, z, 0.0);\n"
												  : m_primitiveType == TESSPRIMITIVETYPE_QUADS ?
													"	float x = gl_TessCoord.x;\n"
													"	float y = gl_TessCoord.y;\n"
													"	// Mirror one half of each outer edge onto the other half, except the endpoints (because they belong to two edges)\n"
													"	out_te_tessCoord_isMirrored = (x == 0.0 || x == 1.0) && y > 0.5 && y != 1.0 ? vec4(    x, 1.0-y, 0.0, 1.0)\n"
													"	                            : (y == 0.0 || y == 1.0) && x > 0.5 && x != 1.0 ? vec4(1.0-x,     y, 0.0, 1.0)\n"
													"	                            : vec4(x, y, 0.0, 0.0);\n"
												  : m_primitiveType == TESSPRIMITIVETYPE_ISOLINES ?
													"	float x = gl_TessCoord.x;\n"
													"	float y = gl_TessCoord.y;\n"
													"	// Mirror one half of each outer edge onto the other half\n"
													"	out_te_tessCoord_isMirrored = (x == 0.0 || x == 1.0) && y > 0.5 ? vec4(x, 1.0-y, 0.0, 1.0)\n"
													"	                            : vec4(x, y, 0.0, 0.0f);\n"
												  : DE_NULL) +
												 "\n"
												 "	gl_Position = vec4(gl_TessCoord.xy, 0.0, 1.0);\n"
												 "	in_f_color = vec4(1.0);\n"
												 "}\n")

		<< glu::FragmentSource					("#version 310 es\n"
												 "\n"
												 "layout (location = 0) out mediump vec4 o_color;\n"
												 "\n"
												 "in highp vec4 in_f_color;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	o_color = in_f_color;\n"
												 "}\n")

		<< glu::TransformFeedbackVarying		("out_te_tessCoord_isMirrored")
		<< glu::TransformFeedbackMode			(GL_INTERLEAVED_ATTRIBS)));

	m_testCtx.getLog() << *m_program;
	if (!m_program->isOk())
		TCU_FAIL("Program compilation failed");
}

void SymmetricOuterEdgeCase::deinit (void)
{
	m_program.clear();
}

SymmetricOuterEdgeCase::IterateResult SymmetricOuterEdgeCase::iterate (void)
{
	typedef TransformFeedbackHandler<Vec4> TFHandler;

	TestLog&							log							= m_testCtx.getLog();
	const RenderContext&				renderCtx					= m_context.getRenderContext();
	const RandomViewport				viewport					(renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName()));
	const glw::Functions&				gl							= renderCtx.getFunctions();

	static const float					singleOuterEdgeLevels[]		= { 1.0f, 1.2f, 1.9f, 2.3f, 2.8f, 3.3f, 3.8f, 10.2f, 1.6f, 24.4f, 24.7f, 63.0f };
	const vector<OuterEdgeDescription>	edgeDescriptions			= outerEdgeDescriptions(m_primitiveType);

	{
		// Compute the number vertices in the largest draw call, so we can allocate the TF buffer just once.
		int maxNumVerticesInDrawCall;
		{
			const vector<float> patchTessLevels = generatePatchTessLevels(1, 0 /* outer-edge index doesn't affect vertex count */, arrayMax(singleOuterEdgeLevels));
			maxNumVerticesInDrawCall = referenceVertexCount(m_primitiveType, m_spacing, m_usePointMode, &patchTessLevels[0], &patchTessLevels[2]);
		}

		{
			const TFHandler tfHandler(m_context.getRenderContext(), maxNumVerticesInDrawCall);

			setViewport(gl, viewport);
			gl.patchParameteri(GL_PATCH_VERTICES, 6);

			for (int outerEdgeIndex = 0; outerEdgeIndex < (int)edgeDescriptions.size(); outerEdgeIndex++)
			{
				const OuterEdgeDescription& edgeDesc = edgeDescriptions[outerEdgeIndex];

				for (int outerEdgeLevelCaseNdx = 0; outerEdgeLevelCaseNdx < DE_LENGTH_OF_ARRAY(singleOuterEdgeLevels); outerEdgeLevelCaseNdx++)
				{
					typedef std::set<Vec3, VecLexLessThan<3> > Vec3Set;

					const vector<float>				patchTessLevels		= generatePatchTessLevels(1, outerEdgeIndex, singleOuterEdgeLevels[outerEdgeLevelCaseNdx]);
					const glu::VertexArrayBinding	bindings[]			= { glu::va::Float("in_v_attr", 1, (int)patchTessLevels.size(), 0, &patchTessLevels[0]) };

					log << TestLog::Message << "Testing with outer tessellation level " << singleOuterEdgeLevels[outerEdgeLevelCaseNdx]
											<< " for the " << edgeDesc.description() << " edge, and with various levels for other edges" << TestLog::EndMessage;

					{
						const deUint32 programGL = m_program->getProgram();

						gl.useProgram(programGL);

						{
							const TFHandler::Result		tfResult		= tfHandler.renderAndGetPrimitives(programGL, outputPrimitiveTypeGL(m_primitiveType, m_usePointMode),
																										   DE_LENGTH_OF_ARRAY(bindings), &bindings[0], (int)patchTessLevels.size());
							const int					refNumVertices	= referenceVertexCount(m_primitiveType, m_spacing, m_usePointMode, &patchTessLevels[0], &patchTessLevels[2]);

							if ((int)tfResult.varying.size() != refNumVertices)
							{
								log << TestLog::Message << "Failure: the number of vertices returned by transform feedback is "
														<< tfResult.varying.size() << ", expected " << refNumVertices << TestLog::EndMessage
									<< TestLog::Message << "Note: rendered 1 patch, tessellation levels are (in order [inner0, inner1, outer0, outer1, outer2, outer3]):\n"
														<< containerStr(patchTessLevels, 6) << TestLog::EndMessage;

								m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of vertices");
								return STOP;
							}

							// Check the vertices.

							{
								Vec3Set nonMirroredEdgeVertices;
								Vec3Set mirroredEdgeVertices;

								// We're interested in just the vertices on the current outer edge.
								for(int vtxNdx = 0; vtxNdx < refNumVertices; vtxNdx++)
								{
									const Vec3& vtx = tfResult.varying[vtxNdx].swizzle(0,1,2);
									if (edgeDesc.contains(vtx))
									{
										// Ignore the middle vertex of the outer edge, as it's exactly at the mirroring point;
										// for isolines, also ignore (0, 0) and (1, 0) because there's no mirrored counterpart for them.
										if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES && vtx == tcu::select(Vec3(0.0f), Vec3(0.5f), singleTrueMask<3>(edgeDesc.constantCoordinateIndex)))
											continue;
										if (m_primitiveType == TESSPRIMITIVETYPE_QUADS && vtx.swizzle(0,1) == tcu::select(Vec2(edgeDesc.constantCoordinateValueChoices[0]),
																															   Vec2(0.5f),
																															   singleTrueMask<2>(edgeDesc.constantCoordinateIndex)))
											continue;
										if (m_primitiveType == TESSPRIMITIVETYPE_ISOLINES && (vtx == Vec3(0.0f, 0.5f, 0.0f) || vtx == Vec3(1.0f, 0.5f, 0.0f) ||
																							  vtx == Vec3(0.0f, 0.0f, 0.0f) || vtx == Vec3(1.0f, 0.0f, 0.0f)))
											continue;

										const bool isMirrored = tfResult.varying[vtxNdx].w() > 0.5f;
										if (isMirrored)
											mirroredEdgeVertices.insert(vtx);
										else
											nonMirroredEdgeVertices.insert(vtx);
									}
								}

								if (m_primitiveType != TESSPRIMITIVETYPE_ISOLINES)
								{
									// Check that both endpoints are present. Note that endpoints aren't mirrored by the shader, since they belong to more than one edge.

									Vec3 endpointA;
									Vec3 endpointB;

									if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES)
									{
										endpointA = tcu::select(Vec3(1.0f), Vec3(0.0f), singleTrueMask<3>((edgeDesc.constantCoordinateIndex + 1) % 3));
										endpointB = tcu::select(Vec3(1.0f), Vec3(0.0f), singleTrueMask<3>((edgeDesc.constantCoordinateIndex + 2) % 3));
									}
									else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS)
									{
										endpointA.xy() = tcu::select(Vec2(edgeDesc.constantCoordinateValueChoices[0]), Vec2(0.0f), singleTrueMask<2>(edgeDesc.constantCoordinateIndex));
										endpointB.xy() = tcu::select(Vec2(edgeDesc.constantCoordinateValueChoices[0]), Vec2(1.0f), singleTrueMask<2>(edgeDesc.constantCoordinateIndex));
									}
									else
										DE_ASSERT(false);

									if (!contains(nonMirroredEdgeVertices, endpointA) ||
										!contains(nonMirroredEdgeVertices, endpointB))
									{
										log << TestLog::Message << "Failure: edge doesn't contain both endpoints, " << endpointA << " and " << endpointB << TestLog::EndMessage
											<< TestLog::Message << "Note: non-mirrored vertices:\n" << containerStr(nonMirroredEdgeVertices, 5)
																<< "\nmirrored vertices:\n" << containerStr(mirroredEdgeVertices, 5) << TestLog::EndMessage;
										m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of vertices");
										return STOP;
									}
									nonMirroredEdgeVertices.erase(endpointA);
									nonMirroredEdgeVertices.erase(endpointB);
								}

								if (nonMirroredEdgeVertices != mirroredEdgeVertices)
								{
									log << TestLog::Message << "Failure: the set of mirrored edges isn't equal to the set of non-mirrored edges (ignoring endpoints and possible middle)" << TestLog::EndMessage
										<< TestLog::Message << "Note: non-mirrored vertices:\n" << containerStr(nonMirroredEdgeVertices, 5)
																<< "\nmirrored vertices:\n" << containerStr(mirroredEdgeVertices, 5) << TestLog::EndMessage;
									m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of vertices");
									return STOP;
								}
							}
						}
					}
				}
			}
		}
	}

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

/*--------------------------------------------------------------------*//*!
 * \brief Test invariance rule #4
 *
 * Test that the vertices on an outer edge don't depend on which of the
 * edges it is, other than with respect to component order.
 *//*--------------------------------------------------------------------*/
class OuterEdgeVertexSetIndexIndependenceCase : public TestCase
{
public:
	OuterEdgeVertexSetIndexIndependenceCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing, Winding winding, bool usePointMode)
		: TestCase			(context, name, description)
		, m_primitiveType	(primType)
		, m_spacing			(spacing)
		, m_winding			(winding)
		, m_usePointMode	(usePointMode)
	{
		DE_ASSERT(primType == TESSPRIMITIVETYPE_TRIANGLES || primType == TESSPRIMITIVETYPE_QUADS);
	}

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

private:
	static vector<float>					generatePatchTessLevels (int numPatches, int constantOuterLevelIndex, float constantOuterLevel);

	static const int						RENDER_SIZE = 16;

	const TessPrimitiveType					m_primitiveType;
	const SpacingMode						m_spacing;
	const Winding							m_winding;
	const bool								m_usePointMode;

	SharedPtr<const glu::ShaderProgram>		m_program;
};

vector<float> OuterEdgeVertexSetIndexIndependenceCase::generatePatchTessLevels (int numPatches, int constantOuterLevelIndex, float constantOuterLevel)
{
	de::Random rnd(123);
	return generateRandomPatchTessLevels(numPatches, constantOuterLevelIndex, constantOuterLevel, rnd);
}

void OuterEdgeVertexSetIndexIndependenceCase::init (void)
{
	checkTessellationSupport(m_context);
	checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE);

	m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
		<< glu::VertexSource					("#version 310 es\n"
												 "\n"
												 "in highp float in_v_attr;\n"
												 "out highp float in_tc_attr;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	in_tc_attr = in_v_attr;\n"
												 "}\n")

		<< glu::TessellationControlSource		("#version 310 es\n"
												 "#extension GL_EXT_tessellation_shader : require\n"
												 "\n"
												 "layout (vertices = 1) out;\n"
												 "\n"
												 "in highp float in_tc_attr[];\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	gl_TessLevelInner[0] = in_tc_attr[0];\n"
												 "	gl_TessLevelInner[1] = in_tc_attr[1];\n"
												 "\n"
												 "	gl_TessLevelOuter[0] = in_tc_attr[2];\n"
												 "	gl_TessLevelOuter[1] = in_tc_attr[3];\n"
												 "	gl_TessLevelOuter[2] = in_tc_attr[4];\n"
												 "	gl_TessLevelOuter[3] = in_tc_attr[5];\n"
												 "}\n")

		<< glu::TessellationEvaluationSource	("#version 310 es\n"
												 "#extension GL_EXT_tessellation_shader : require\n"
												 "\n"
												 + getTessellationEvaluationInLayoutString(m_primitiveType, m_spacing, m_winding, m_usePointMode) +
												 "\n"
												 "out highp vec4 in_f_color;\n"
												 "out highp vec3 out_te_tessCoord;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	out_te_tessCoord = gl_TessCoord;"
												 "	gl_Position = vec4(gl_TessCoord.xy, 0.0, 1.0);\n"
												 "	in_f_color = vec4(1.0);\n"
												 "}\n")

		<< glu::FragmentSource					("#version 310 es\n"
												 "\n"
												 "layout (location = 0) out mediump vec4 o_color;\n"
												 "\n"
												 "in highp vec4 in_f_color;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	o_color = in_f_color;\n"
												 "}\n")

		<< glu::TransformFeedbackVarying		("out_te_tessCoord")
		<< glu::TransformFeedbackMode			(GL_INTERLEAVED_ATTRIBS)));

	m_testCtx.getLog() << *m_program;
	if (!m_program->isOk())
		TCU_FAIL("Program compilation failed");
}

void OuterEdgeVertexSetIndexIndependenceCase::deinit (void)
{
	m_program.clear();
}

OuterEdgeVertexSetIndexIndependenceCase::IterateResult OuterEdgeVertexSetIndexIndependenceCase::iterate (void)
{
	typedef TransformFeedbackHandler<Vec3> TFHandler;

	TestLog&							log							= m_testCtx.getLog();
	const RenderContext&				renderCtx					= m_context.getRenderContext();
	const RandomViewport				viewport					(renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName()));
	const glw::Functions&				gl							= renderCtx.getFunctions();
	const deUint32						programGL					= m_program->getProgram();

	static const float					singleOuterEdgeLevels[]		= { 1.0f, 1.2f, 1.9f, 2.3f, 2.8f, 3.3f, 3.8f, 10.2f, 1.6f, 24.4f, 24.7f, 63.0f };
	const vector<OuterEdgeDescription>	edgeDescriptions			= outerEdgeDescriptions(m_primitiveType);

	gl.useProgram(programGL);
	setViewport(gl, viewport);
	gl.patchParameteri(GL_PATCH_VERTICES, 6);

	{
		// Compute the number vertices in the largest draw call, so we can allocate the TF buffer just once.
		int maxNumVerticesInDrawCall = 0;
		{
			const vector<float> patchTessLevels = generatePatchTessLevels(1, 0 /* outer-edge index doesn't affect vertex count */, arrayMax(singleOuterEdgeLevels));
			maxNumVerticesInDrawCall = referenceVertexCount(m_primitiveType, m_spacing, m_usePointMode, &patchTessLevels[0], &patchTessLevels[2]);
		}

		{
			const TFHandler tfHandler(m_context.getRenderContext(), maxNumVerticesInDrawCall);

			for (int outerEdgeLevelCaseNdx = 0; outerEdgeLevelCaseNdx < DE_LENGTH_OF_ARRAY(singleOuterEdgeLevels); outerEdgeLevelCaseNdx++)
			{
				typedef std::set<Vec3, VecLexLessThan<3> > Vec3Set;

				Vec3Set firstEdgeVertices;

				for (int outerEdgeIndex = 0; outerEdgeIndex < (int)edgeDescriptions.size(); outerEdgeIndex++)
				{
					const OuterEdgeDescription&		edgeDesc			= edgeDescriptions[outerEdgeIndex];
					const vector<float>				patchTessLevels		= generatePatchTessLevels(1, outerEdgeIndex, singleOuterEdgeLevels[outerEdgeLevelCaseNdx]);
					const glu::VertexArrayBinding	bindings[]			= { glu::va::Float("in_v_attr", 1, (int)patchTessLevels.size(), 0, &patchTessLevels[0]) };

					log << TestLog::Message << "Testing with outer tessellation level " << singleOuterEdgeLevels[outerEdgeLevelCaseNdx]
											<< " for the " << edgeDesc.description() << " edge, and with various levels for other edges" << TestLog::EndMessage;

					{
						const TFHandler::Result		tfResult		= tfHandler.renderAndGetPrimitives(programGL, outputPrimitiveTypeGL(m_primitiveType, m_usePointMode),
																										DE_LENGTH_OF_ARRAY(bindings), &bindings[0], (int)patchTessLevels.size());
						const int					refNumVertices	= referenceVertexCount(m_primitiveType, m_spacing, m_usePointMode, &patchTessLevels[0], &patchTessLevels[2]);

						if ((int)tfResult.varying.size() != refNumVertices)
						{
							log << TestLog::Message << "Failure: the number of vertices returned by transform feedback is "
													<< tfResult.varying.size() << ", expected " << refNumVertices << TestLog::EndMessage
								<< TestLog::Message << "Note: rendered 1 patch, tessellation levels are (in order [inner0, inner1, outer0, outer1, outer2, outer3]):\n"
													<< containerStr(patchTessLevels, 6) << TestLog::EndMessage;

							m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of vertices");
							return STOP;
						}

						{
							Vec3Set currentEdgeVertices;

							// Get the vertices on the current outer edge.
							for(int vtxNdx = 0; vtxNdx < refNumVertices; vtxNdx++)
							{
								const Vec3& vtx = tfResult.varying[vtxNdx];
								if (edgeDesc.contains(vtx))
								{
									// Swizzle components to match the order of the first edge.
									if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES)
									{
										currentEdgeVertices.insert(outerEdgeIndex == 0 ? vtx
																	: outerEdgeIndex == 1 ? vtx.swizzle(1, 0, 2)
																	: outerEdgeIndex == 2 ? vtx.swizzle(2, 1, 0)
																	: Vec3(-1.0f));
									}
									else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS)
									{
										currentEdgeVertices.insert(Vec3(outerEdgeIndex == 0 ? vtx.y()
																		: outerEdgeIndex == 1 ? vtx.x()
																		: outerEdgeIndex == 2 ? vtx.y()
																		: outerEdgeIndex == 3 ? vtx.x()
																		: -1.0f,
																		0.0f, 0.0f));
									}
									else
										DE_ASSERT(false);
								}
							}

							if (outerEdgeIndex == 0)
								firstEdgeVertices = currentEdgeVertices;
							else
							{
								// Compare vertices of this edge to those of the first edge.

								if (currentEdgeVertices != firstEdgeVertices)
								{
									const char* const swizzleDesc = m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? (outerEdgeIndex == 1 ? "(y, x, z)"
																													: outerEdgeIndex == 2 ? "(z, y, x)"
																													: DE_NULL)
																	: m_primitiveType == TESSPRIMITIVETYPE_QUADS ? (outerEdgeIndex == 1 ? "(x, 0)"
																												: outerEdgeIndex == 2 ? "(y, 0)"
																												: outerEdgeIndex == 3 ? "(x, 0)"
																												: DE_NULL)
																	: DE_NULL;

									log << TestLog::Message << "Failure: the set of vertices on the " << edgeDesc.description() << " edge"
															<< " doesn't match the set of vertices on the " << edgeDescriptions[0].description() << " edge" << TestLog::EndMessage
										<< TestLog::Message << "Note: set of vertices on " << edgeDesc.description() << " edge, components swizzled like " << swizzleDesc
															<< " to match component order on first edge:\n" << containerStr(currentEdgeVertices, 5)
															<< "\non " << edgeDescriptions[0].description() << " edge:\n" << containerStr(firstEdgeVertices, 5) << TestLog::EndMessage;
									m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of vertices");
									return STOP;
								}
							}
						}
					}
				}
			}
		}
	}

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

/*--------------------------------------------------------------------*//*!
 * \brief Test invariance rule #5
 *
 * Test that the set of triangles input to the TES only depends on the
 * tessellation levels, tessellation mode and spacing mode. Specifically,
 * winding doesn't change the set of triangles, though it can change the
 * order in which they are input to TES, and can (and will) change the
 * vertex order within a triangle.
 *//*--------------------------------------------------------------------*/
class InvariantTriangleSetCase : public PrimitiveSetInvarianceCase
{
public:
	InvariantTriangleSetCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing)
		: PrimitiveSetInvarianceCase(context, name, description, primType, spacing, false, WINDINGUSAGE_VARY)
	{
		DE_ASSERT(primType == TESSPRIMITIVETYPE_TRIANGLES || primType == TESSPRIMITIVETYPE_QUADS);
	}

protected:
	virtual bool compare (const vector<Vec3>& coordsA, const vector<Vec3>& coordsB, int) const
	{
		return compareTriangleSets(coordsA, coordsB, m_testCtx.getLog());
	}
};

/*--------------------------------------------------------------------*//*!
 * \brief Test invariance rule #6
 *
 * Test that the set of inner triangles input to the TES only depends on
 * the inner tessellation levels, tessellation mode and spacing mode.
 *//*--------------------------------------------------------------------*/
class InvariantInnerTriangleSetCase : public PrimitiveSetInvarianceCase
{
public:
	InvariantInnerTriangleSetCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing)
		: PrimitiveSetInvarianceCase(context, name, description, primType, spacing, false, WINDINGUSAGE_VARY)
	{
		DE_ASSERT(primType == TESSPRIMITIVETYPE_TRIANGLES || primType == TESSPRIMITIVETYPE_QUADS);
	}

protected:
	virtual vector<LevelCase> genTessLevelCases (void) const
	{
		const int					numSubCases		= 4;
		const vector<LevelCase>		baseResults		= PrimitiveSetInvarianceCase::genTessLevelCases();
		vector<LevelCase>			result;
		de::Random					rnd				(123);

		// Generate variants with different values for irrelevant levels.
		for (int baseNdx = 0; baseNdx < (int)baseResults.size(); baseNdx++)
		{
			const TessLevels&	base	= baseResults[baseNdx].levels[0];
			TessLevels			levels	= base;
			LevelCase			levelCase;

			for (int subNdx = 0; subNdx < numSubCases; subNdx++)
			{
				levelCase.levels.push_back(levels);

				for (int i = 0; i < DE_LENGTH_OF_ARRAY(levels.outer); i++)
					levels.outer[i] = rnd.getFloat(2.0f, 16.0f);
				if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES)
					levels.inner[1] = rnd.getFloat(2.0f, 16.0f);
			}

			result.push_back(levelCase);
		}

		return result;
	}

	struct IsInnerTriangleTriangle
	{
		bool operator() (const Vec3* vertices) const
		{
			for (int v = 0; v < 3; v++)
				for (int c = 0; c < 3; c++)
					if (vertices[v][c] == 0.0f)
						return false;
			return true;
		}
	};

	struct IsInnerQuadTriangle
	{
		bool operator() (const Vec3* vertices) const
		{
			for (int v = 0; v < 3; v++)
				for (int c = 0; c < 2; c++)
					if (vertices[v][c] == 0.0f || vertices[v][c] == 1.0f)
						return false;
			return true;
		}
	};

	virtual bool compare (const vector<Vec3>& coordsA, const vector<Vec3>& coordsB, int) const
	{
		if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES)
			return compareTriangleSets(coordsA, coordsB, m_testCtx.getLog(), IsInnerTriangleTriangle(), "outer triangles");
		else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS)
			return compareTriangleSets(coordsA, coordsB, m_testCtx.getLog(), IsInnerQuadTriangle(), "outer triangles");
		else
		{
			DE_ASSERT(false);
			return false;
		}
	}
};

/*--------------------------------------------------------------------*//*!
 * \brief Test invariance rule #7
 *
 * Test that the set of outer triangles input to the TES only depends on
 * tessellation mode, spacing mode and the inner and outer tessellation
 * levels corresponding to the inner and outer edges relevant to that
 * triangle.
 *//*--------------------------------------------------------------------*/
class InvariantOuterTriangleSetCase : public PrimitiveSetInvarianceCase
{
public:
	InvariantOuterTriangleSetCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing)
		: PrimitiveSetInvarianceCase(context, name, description, primType, spacing, false, WINDINGUSAGE_VARY)
	{
		DE_ASSERT(primType == TESSPRIMITIVETYPE_TRIANGLES || primType == TESSPRIMITIVETYPE_QUADS);
	}

protected:
	virtual vector<LevelCase> genTessLevelCases (void) const
	{
		const int					numSubCasesPerEdge	= 4;
		const int					numEdges			= m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES	? 3
														: m_primitiveType == TESSPRIMITIVETYPE_QUADS		? 4
														: -1;
		const vector<LevelCase>		baseResult			= PrimitiveSetInvarianceCase::genTessLevelCases();
		vector<LevelCase>			result;
		de::Random					rnd					(123);

		// Generate variants with different values for irrelevant levels.
		for (int baseNdx = 0; baseNdx < (int)baseResult.size(); baseNdx++)
		{
			const TessLevels& base = baseResult[baseNdx].levels[0];
			if (base.inner[0] == 1.0f || (m_primitiveType == TESSPRIMITIVETYPE_QUADS && base.inner[1] == 1.0f))
				continue;

			for (int edgeNdx = 0; edgeNdx < numEdges; edgeNdx++)
			{
				TessLevels	levels = base;
				LevelCase	levelCase;
				levelCase.mem = edgeNdx;

				for (int subCaseNdx = 0; subCaseNdx < numSubCasesPerEdge; subCaseNdx++)
				{
					levelCase.levels.push_back(levels);

					for (int i = 0; i < DE_LENGTH_OF_ARRAY(levels.outer); i++)
					{
						if (i != edgeNdx)
							levels.outer[i] = rnd.getFloat(2.0f, 16.0f);
					}

					if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES)
						levels.inner[1] = rnd.getFloat(2.0f, 16.0f);
				}

				result.push_back(levelCase);
			}
		}

		return result;
	}

	class IsTriangleTriangleOnOuterEdge
	{
	public:
		IsTriangleTriangleOnOuterEdge (int edgeNdx) : m_edgeNdx(edgeNdx) {}
		bool operator() (const Vec3* vertices) const
		{
			bool touchesAppropriateEdge = false;
			for (int v = 0; v < 3; v++)
				if (vertices[v][m_edgeNdx] == 0.0f)
					touchesAppropriateEdge = true;

			if (touchesAppropriateEdge)
			{
				const Vec3 avg = (vertices[0] + vertices[1] + vertices[2]) / 3.0f;
				return avg[m_edgeNdx] < avg[(m_edgeNdx+1)%3] &&
					   avg[m_edgeNdx] < avg[(m_edgeNdx+2)%3];
			}
			return false;
		}

	private:
		int m_edgeNdx;
	};

	class IsQuadTriangleOnOuterEdge
	{
	public:
		IsQuadTriangleOnOuterEdge (int edgeNdx) : m_edgeNdx(edgeNdx) {}

		bool onEdge (const Vec3& v) const
		{
			return v[m_edgeNdx%2] == (m_edgeNdx <= 1 ? 0.0f : 1.0f);
		}

		static inline bool onAnyEdge (const Vec3& v)
		{
			return v[0] == 0.0f || v[0] == 1.0f || v[1] == 0.0f || v[1] == 1.0f;
		}

		bool operator() (const Vec3* vertices) const
		{
			for (int v = 0; v < 3; v++)
			{
				const Vec3& a = vertices[v];
				const Vec3& b = vertices[(v+1)%3];
				const Vec3& c = vertices[(v+2)%3];
				if (onEdge(a) && onEdge(b))
					return true;
				if (onEdge(c) && !onAnyEdge(a) && !onAnyEdge(b) && a[m_edgeNdx%2] == b[m_edgeNdx%2])
					return true;
			}

			return false;
		}

	private:
		int m_edgeNdx;
	};

	virtual bool compare (const vector<Vec3>& coordsA, const vector<Vec3>& coordsB, int outerEdgeNdx) const
	{
		if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES)
		{
			return compareTriangleSets(coordsA, coordsB, m_testCtx.getLog(),
									   IsTriangleTriangleOnOuterEdge(outerEdgeNdx),
									   ("inner triangles, and outer triangles corresponding to other edge than edge "
										+ outerEdgeDescriptions(m_primitiveType)[outerEdgeNdx].description()).c_str());
		}
		else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS)
		{
			return compareTriangleSets(coordsA, coordsB, m_testCtx.getLog(),
									   IsQuadTriangleOnOuterEdge(outerEdgeNdx),
									   ("inner triangles, and outer triangles corresponding to other edge than edge "
										+ outerEdgeDescriptions(m_primitiveType)[outerEdgeNdx].description()).c_str());
		}
		else
			DE_ASSERT(false);

		return true;
	}
};

/*--------------------------------------------------------------------*//*!
 * \brief Base class for testing individual components of tess coords
 *
 * Useful for testing parts of invariance rule #8.
 *//*--------------------------------------------------------------------*/
class TessCoordComponentInvarianceCase : public TestCase
{
public:
	TessCoordComponentInvarianceCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing, Winding winding, bool usePointMode)
		: TestCase			(context, name, description)
		, m_primitiveType	(primType)
		, m_spacing			(spacing)
		, m_winding			(winding)
		, m_usePointMode	(usePointMode)
	{
	}

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

protected:
	virtual string							tessEvalOutputComponentStatements	(const char* tessCoordComponentName, const char* outputComponentName) const = 0;
	virtual bool							checkTessCoordComponent				(float component) const = 0;

private:
	static vector<float>					genTessLevelCases (int numCases);

	static const int						RENDER_SIZE = 16;

	const TessPrimitiveType					m_primitiveType;
	const SpacingMode						m_spacing;
	const Winding							m_winding;
	const bool								m_usePointMode;

	SharedPtr<const glu::ShaderProgram>		m_program;
};

void TessCoordComponentInvarianceCase::init (void)
{
	checkTessellationSupport(m_context);
	checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE);

	m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
		<< glu::VertexSource					("#version 310 es\n"
												 "\n"
												 "in highp float in_v_attr;\n"
												 "out highp float in_tc_attr;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	in_tc_attr = in_v_attr;\n"
												 "}\n")

		<< glu::TessellationControlSource		("#version 310 es\n"
												 "#extension GL_EXT_tessellation_shader : require\n"
												 "\n"
												 "layout (vertices = 1) out;\n"
												 "\n"
												 "in highp float in_tc_attr[];\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	gl_TessLevelInner[0] = in_tc_attr[0];\n"
												 "	gl_TessLevelInner[1] = in_tc_attr[1];\n"
												 "\n"
												 "	gl_TessLevelOuter[0] = in_tc_attr[2];\n"
												 "	gl_TessLevelOuter[1] = in_tc_attr[3];\n"
												 "	gl_TessLevelOuter[2] = in_tc_attr[4];\n"
												 "	gl_TessLevelOuter[3] = in_tc_attr[5];\n"
												 "}\n")

		<< glu::TessellationEvaluationSource	("#version 310 es\n"
												 "#extension GL_EXT_tessellation_shader : require\n"
												 "\n"
												 + getTessellationEvaluationInLayoutString(m_primitiveType, m_spacing, m_winding, m_usePointMode) +
												 "\n"
												 "out highp vec4 in_f_color;\n"
												 "out highp vec3 out_te_output;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 + tessEvalOutputComponentStatements("gl_TessCoord.x", "out_te_output.x")
												 + tessEvalOutputComponentStatements("gl_TessCoord.y", "out_te_output.y")

												 + (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ?
													tessEvalOutputComponentStatements("gl_TessCoord.z", "out_te_output.z") :
													"	out_te_output.z = 0.0f;\n") +
												 "	gl_Position = vec4(gl_TessCoord.xy, 0.0, 1.0);\n"
												 "	in_f_color = vec4(1.0);\n"
												 "}\n")

		<< glu::FragmentSource					("#version 310 es\n"
												 "\n"
												 "layout (location = 0) out mediump vec4 o_color;\n"
												 "\n"
												 "in highp vec4 in_f_color;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	o_color = in_f_color;\n"
												 "}\n")

		<< glu::TransformFeedbackVarying		("out_te_output")
		<< glu::TransformFeedbackMode			(GL_INTERLEAVED_ATTRIBS)));

	m_testCtx.getLog() << *m_program;
	if (!m_program->isOk())
		TCU_FAIL("Program compilation failed");
}

void TessCoordComponentInvarianceCase::deinit (void)
{
	m_program.clear();
}

vector<float> TessCoordComponentInvarianceCase::genTessLevelCases (int numCases)
{
	de::Random		rnd(123);
	vector<float>	result;

	for (int i = 0; i < numCases; i++)
		for (int j = 0; j < 6; j++)
			result.push_back(rnd.getFloat(1.0f, 63.0f));

	return result;
}

TessCoordComponentInvarianceCase::IterateResult TessCoordComponentInvarianceCase::iterate (void)
{
	typedef TransformFeedbackHandler<Vec3> TFHandler;

	TestLog&				log					= m_testCtx.getLog();
	const RenderContext&	renderCtx			= m_context.getRenderContext();
	const RandomViewport	viewport			(renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName()));
	const glw::Functions&	gl					= renderCtx.getFunctions();
	const int				numTessLevelCases	= 32;
	const vector<float>		tessLevels			= genTessLevelCases(numTessLevelCases);
	const deUint32			programGL			= m_program->getProgram();

	gl.useProgram(programGL);
	setViewport(gl, viewport);
	gl.patchParameteri(GL_PATCH_VERTICES, 6);

	{
		// Compute the number vertices in the largest draw call, so we can allocate the TF buffer just once.
		int maxNumVerticesInDrawCall = 0;
		for (int i = 0; i < numTessLevelCases; i++)
			maxNumVerticesInDrawCall = de::max(maxNumVerticesInDrawCall, referenceVertexCount(m_primitiveType, m_spacing, m_usePointMode, &tessLevels[6*i+0], &tessLevels[6*i+2]));

		{
			const TFHandler tfHandler(m_context.getRenderContext(), maxNumVerticesInDrawCall);

			for (int tessLevelCaseNdx = 0; tessLevelCaseNdx < numTessLevelCases; tessLevelCaseNdx++)
			{
				log << TestLog::Message << "Testing with tessellation levels: " << tessellationLevelsString(&tessLevels[6*tessLevelCaseNdx+0], &tessLevels[6*tessLevelCaseNdx+2]) << TestLog::EndMessage;

				const glu::VertexArrayBinding bindings[] = { glu::va::Float("in_v_attr", 1, (int)6, 0, &tessLevels[6*tessLevelCaseNdx]) };
				const TFHandler::Result tfResult = tfHandler.renderAndGetPrimitives(programGL, outputPrimitiveTypeGL(m_primitiveType, m_usePointMode),
																					DE_LENGTH_OF_ARRAY(bindings), &bindings[0], 6);

				for (int vtxNdx = 0; vtxNdx < (int)tfResult.varying.size(); vtxNdx++)
				{
					const Vec3&		vec			= tfResult.varying[vtxNdx];
					const int		numComps	= m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3 : 2;

					for (int compNdx = 0; compNdx < numComps; compNdx++)
					{
						if (!checkTessCoordComponent(vec[compNdx]))
						{
							log << TestLog::Message << "Note: output value at index " << vtxNdx << " is "
													<< (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? de::toString(vec) : de::toString(vec.swizzle(0,1)))
													<< TestLog::EndMessage;
							m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid tessellation coordinate component");
							return STOP;
						}
					}
				}
			}
		}
	}

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

/*--------------------------------------------------------------------*//*!
 * \brief Test first part of invariance rule #8
 *
 * Test that all (relevant) components of tess coord are in [0,1].
 *//*--------------------------------------------------------------------*/
class TessCoordComponentRangeCase : public TessCoordComponentInvarianceCase
{
public:
	TessCoordComponentRangeCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing, Winding winding, bool usePointMode)
		: TessCoordComponentInvarianceCase(context, name, description, primType, spacing, winding, usePointMode)
	{
	}

protected:
	virtual string tessEvalOutputComponentStatements (const char* tessCoordComponentName, const char* outputComponentName) const
	{
		return string() + "\t" + outputComponentName + " = " + tessCoordComponentName + ";\n";
	}

	virtual bool checkTessCoordComponent (float component) const
	{
		if (!de::inRange(component, 0.0f, 1.0f))
		{
			m_testCtx.getLog() << TestLog::Message << "Failure: tess coord component isn't in range [0,1]" << TestLog::EndMessage;
			return false;
		}
		return true;
	}
};

/*--------------------------------------------------------------------*//*!
 * \brief Test second part of invariance rule #8
 *
 * Test that all (relevant) components of tess coord are in [0,1] and
 * 1.0-c is exact for every such component c.
 *//*--------------------------------------------------------------------*/
class OneMinusTessCoordComponentCase : public TessCoordComponentInvarianceCase
{
public:
	OneMinusTessCoordComponentCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing, Winding winding, bool usePointMode)
		: TessCoordComponentInvarianceCase(context, name, description, primType, spacing, winding, usePointMode)
	{
	}

protected:
	virtual string tessEvalOutputComponentStatements (const char* tessCoordComponentName, const char* outputComponentName) const
	{
		return string() + "	{\n"
						  "		float oneMinusComp = 1.0 - " + tessCoordComponentName + ";\n"
						  "		" + outputComponentName + " = " + tessCoordComponentName + " + oneMinusComp;\n"
						  "	}\n";
	}

	virtual bool checkTessCoordComponent (float component) const
	{
		if (component != 1.0f)
		{
			m_testCtx.getLog() << TestLog::Message << "Failure: comp + (1.0-comp) doesn't equal 1.0 for some component of tessellation coordinate" << TestLog::EndMessage;
			return false;
		}
		return true;
	}
};

/*--------------------------------------------------------------------*//*!
 * \brief Test that patch is discarded if relevant outer level <= 0.0
 *
 * Draws patches with different combinations of tessellation levels,
 * varying which levels are negative. Verifies by checking that colored
 * pixels exist inside the area of valid primitives, and only black pixels
 * exist inside the area of discarded primitives. An additional sanity
 * test is done, checking that the number of primitives written by TF is
 * correct.
 *//*--------------------------------------------------------------------*/
class PrimitiveDiscardCase : public TestCase
{
public:
	PrimitiveDiscardCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing, Winding winding, bool usePointMode)
		: TestCase			(context, name, description)
		, m_primitiveType	(primType)
		, m_spacing			(spacing)
		, m_winding			(winding)
		, m_usePointMode	(usePointMode)
	{
	}

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

private:
	static vector<float>					genAttributes (void);

	static const int						RENDER_SIZE = 256;

	const TessPrimitiveType					m_primitiveType;
	const SpacingMode						m_spacing;
	const Winding							m_winding;
	const bool								m_usePointMode;

	SharedPtr<const glu::ShaderProgram>		m_program;
};

void PrimitiveDiscardCase::init (void)
{
	checkTessellationSupport(m_context);
	checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE);

	m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
		<< glu::VertexSource					("#version 310 es\n"
												 "\n"
												 "in highp float in_v_attr;\n"
												 "out highp float in_tc_attr;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	in_tc_attr = in_v_attr;\n"
												 "}\n")

		<< glu::TessellationControlSource		("#version 310 es\n"
												 "#extension GL_EXT_tessellation_shader : require\n"
												 "\n"
												 "layout (vertices = 1) out;\n"
												 "\n"
												 "in highp float in_tc_attr[];\n"
												 "\n"
												 "patch out highp vec2 in_te_positionScale;\n"
												 "patch out highp vec2 in_te_positionOffset;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	in_te_positionScale  = vec2(in_tc_attr[6], in_tc_attr[7]);\n"
												 "	in_te_positionOffset = vec2(in_tc_attr[8], in_tc_attr[9]);\n"
												 "\n"
												 "	gl_TessLevelInner[0] = in_tc_attr[0];\n"
												 "	gl_TessLevelInner[1] = in_tc_attr[1];\n"
												 "\n"
												 "	gl_TessLevelOuter[0] = in_tc_attr[2];\n"
												 "	gl_TessLevelOuter[1] = in_tc_attr[3];\n"
												 "	gl_TessLevelOuter[2] = in_tc_attr[4];\n"
												 "	gl_TessLevelOuter[3] = in_tc_attr[5];\n"
												 "}\n")

		<< glu::TessellationEvaluationSource	("#version 310 es\n"
												 "#extension GL_EXT_tessellation_shader : require\n"
												 "\n"
												 + getTessellationEvaluationInLayoutString(m_primitiveType, m_spacing, m_winding, m_usePointMode) +
												 "\n"
												 "patch in highp vec2 in_te_positionScale;\n"
												 "patch in highp vec2 in_te_positionOffset;\n"
												 "\n"
												 "out highp vec3 out_te_tessCoord;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	out_te_tessCoord = gl_TessCoord;\n"
												 "	gl_Position = vec4(gl_TessCoord.xy*in_te_positionScale + in_te_positionOffset, 0.0, 1.0);\n"
												 "}\n")

		<< glu::FragmentSource					("#version 310 es\n"
												 "\n"
												 "layout (location = 0) out mediump vec4 o_color;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	o_color = vec4(1.0);\n"
												 "}\n")

		<< glu::TransformFeedbackVarying		("out_te_tessCoord")
		<< glu::TransformFeedbackMode			(GL_INTERLEAVED_ATTRIBS)));

	m_testCtx.getLog() << *m_program;
	if (!m_program->isOk())
		TCU_FAIL("Program compilation failed");
}

void PrimitiveDiscardCase::deinit (void)
{
	m_program.clear();
}

vector<float> PrimitiveDiscardCase::genAttributes (void)
{
	// Generate input attributes (tessellation levels, and position scale and
	// offset) for a number of primitives. Each primitive has a different
	// combination of tessellatio levels; each level is either a valid
	// value or an "invalid" value (negative or zero, chosen from
	// invalidTessLevelChoices).

	// \note The attributes are generated in such an order that all of the
	//		 valid attribute tuples come before the first invalid one both
	//		 in the result vector, and when scanning the resulting 2d grid
	//		 of primitives is scanned in y-major order. This makes
	//		 verification somewhat simpler.

	static const float	baseTessLevels[6]			= { 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f };
	static const float	invalidTessLevelChoices[]	= { -0.42f, 0.0f };
	const int			numChoices					= 1 + DE_LENGTH_OF_ARRAY(invalidTessLevelChoices);
	float				choices[6][numChoices];
	vector<float>		result;

	for (int levelNdx = 0; levelNdx < 6; levelNdx++)
		for (int choiceNdx = 0; choiceNdx < numChoices; choiceNdx++)
			choices[levelNdx][choiceNdx] = choiceNdx == 0 ? baseTessLevels[levelNdx] : invalidTessLevelChoices[choiceNdx-1];

	{
		const int	numCols			= intPow(numChoices, 6/2); // sqrt(numChoices**6) == sqrt(number of primitives)
		const int	numRows			= numCols;
		int			index			= 0;
		int			i[6];
		// We could do this with some generic combination-generation function, but meh, it's not that bad.
		for (i[2] = 0; i[2] < numChoices; i[2]++) // First  outer
		for (i[3] = 0; i[3] < numChoices; i[3]++) // Second outer
		for (i[4] = 0; i[4] < numChoices; i[4]++) // Third  outer
		for (i[5] = 0; i[5] < numChoices; i[5]++) // Fourth outer
		for (i[0] = 0; i[0] < numChoices; i[0]++) // First  inner
		for (i[1] = 0; i[1] < numChoices; i[1]++) // Second inner
		{
			for (int j = 0; j < 6; j++)
				result.push_back(choices[j][i[j]]);

			{
				const int col = index % numCols;
				const int row = index / numCols;
				// Position scale.
				result.push_back((float)2.0f / (float)numCols);
				result.push_back((float)2.0f / (float)numRows);
				// Position offset.
				result.push_back((float)col / (float)numCols * 2.0f - 1.0f);
				result.push_back((float)row / (float)numRows * 2.0f - 1.0f);
			}

			index++;
		}
	}

	return result;
}

PrimitiveDiscardCase::IterateResult PrimitiveDiscardCase::iterate (void)
{
	typedef TransformFeedbackHandler<Vec3> TFHandler;

	TestLog&				log						= m_testCtx.getLog();
	const RenderContext&	renderCtx				= m_context.getRenderContext();
	const RandomViewport	viewport				(renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName()));
	const glw::Functions&	gl						= renderCtx.getFunctions();
	const vector<float>		attributes				= genAttributes();
	const int				numAttribsPerPrimitive	= 6+2+2; // Tess levels, scale, offset.
	const int				numPrimitives			= (int)attributes.size() / numAttribsPerPrimitive;
	const deUint32			programGL				= m_program->getProgram();

	gl.useProgram(programGL);
	setViewport(gl, viewport);
	gl.patchParameteri(GL_PATCH_VERTICES, numAttribsPerPrimitive);

	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.clear(GL_COLOR_BUFFER_BIT);

	// Check the convenience assertion that all discarded patches come after the last non-discarded patch.
	{
		bool discardedPatchEncountered = false;
		for (int patchNdx = 0; patchNdx < numPrimitives; patchNdx++)
		{
			const bool discard = isPatchDiscarded(m_primitiveType, &attributes[numAttribsPerPrimitive*patchNdx + 2]);
			DE_ASSERT(discard || !discardedPatchEncountered);
			discardedPatchEncountered = discard;
		}
		DE_UNREF(discardedPatchEncountered);
	}

	{
		int numVerticesInDrawCall = 0;
		for (int patchNdx = 0; patchNdx < numPrimitives; patchNdx++)
			numVerticesInDrawCall += referenceVertexCount(m_primitiveType, m_spacing, m_usePointMode, &attributes[numAttribsPerPrimitive*patchNdx+0], &attributes[numAttribsPerPrimitive*patchNdx+2]);

		log << TestLog::Message << "Note: rendering " << numPrimitives << " patches; first patches have valid relevant outer levels, "
								<< "but later patches have one or more invalid (i.e. less than or equal to 0.0) relevant outer levels" << TestLog::EndMessage;

		{
			const TFHandler					tfHandler	(m_context.getRenderContext(), numVerticesInDrawCall);
			const glu::VertexArrayBinding	bindings[]	= { glu::va::Float("in_v_attr", 1, (int)attributes.size(), 0, &attributes[0]) };
			const TFHandler::Result			tfResult	= tfHandler.renderAndGetPrimitives(programGL, outputPrimitiveTypeGL(m_primitiveType, m_usePointMode),
																						   DE_LENGTH_OF_ARRAY(bindings), &bindings[0], (int)attributes.size());
			const tcu::Surface				pixels		= getPixels(renderCtx, viewport);

			log << TestLog::Image("RenderedImage", "Rendered image", pixels);

			if ((int)tfResult.varying.size() != numVerticesInDrawCall)
			{
				log << TestLog::Message << "Failure: expected " << numVerticesInDrawCall << " vertices from transform feedback, got " << tfResult.varying.size() << TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrong number of tessellation coordinates");
				return STOP;
			}

			// Check that white pixels are found around every non-discarded
			// patch, and that only black pixels are found after the last
			// non-discarded patch.
			{
				int lastWhitePixelRow									= 0;
				int secondToLastWhitePixelRow							= 0;
				int	lastWhitePixelColumnOnSecondToLastWhitePixelRow		= 0;

				for (int patchNdx = 0; patchNdx < numPrimitives; patchNdx++)
				{
					const float* const	attr			= &attributes[numAttribsPerPrimitive*patchNdx];
					const bool			validLevels		= !isPatchDiscarded(m_primitiveType, &attr[2]);

					if (validLevels)
					{
						// Not a discarded patch; check that at least one white pixel is found in its area.

						const float* const	scale		= &attr[6];
						const float* const	offset		= &attr[8];
						const int			x0			= (int)((			offset[0] + 1.0f)*0.5f*(float)pixels.getWidth()) - 1;
						const int			x1			= (int)((scale[0] + offset[0] + 1.0f)*0.5f*(float)pixels.getWidth()) + 1;
						const int			y0			= (int)((			offset[1] + 1.0f)*0.5f*(float)pixels.getHeight()) - 1;
						const int			y1			= (int)((scale[1] + offset[1] + 1.0f)*0.5f*(float)pixels.getHeight()) + 1;
						const bool			isMSAA		= renderCtx.getRenderTarget().getNumSamples() > 1;
						bool				pixelOk		= false;

						if (y1 > lastWhitePixelRow)
						{
							secondToLastWhitePixelRow	= lastWhitePixelRow;
							lastWhitePixelRow			= y1;
						}
						lastWhitePixelColumnOnSecondToLastWhitePixelRow = x1;

						for (int y = y0; y <= y1 && !pixelOk; y++)
						for (int x = x0; x <= x1 && !pixelOk; x++)
						{
							if (!de::inBounds(x, 0, pixels.getWidth()) || !de::inBounds(y, 0, pixels.getHeight()))
								continue;

							if (isMSAA)
							{
								if (pixels.getPixel(x, y) != tcu::RGBA::black)
									pixelOk = true;
							}
							else
							{
								if (pixels.getPixel(x, y) == tcu::RGBA::white)
									pixelOk = true;
							}
						}

						if (!pixelOk)
						{
							log << TestLog::Message << "Failure: expected at least one " << (isMSAA ? "non-black" : "white") << " pixel in the rectangle "
													<< "[x0=" << x0 << ", y0=" << y0 << ", x1=" << x1 << ", y1=" << y1 << "]" << TestLog::EndMessage
								<< TestLog::Message << "Note: the rectangle approximately corresponds to the patch with these tessellation levels: "
													<< tessellationLevelsString(&attr[0], &attr[1]) << TestLog::EndMessage;
							m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
							return STOP;
						}
					}
					else
					{
						// First discarded primitive patch; the remaining are guaranteed to be discarded ones as well.

						for (int y = 0; y < pixels.getHeight(); y++)
						for (int x = 0; x < pixels.getWidth(); x++)
						{
							if (y > lastWhitePixelRow || (y > secondToLastWhitePixelRow && x > lastWhitePixelColumnOnSecondToLastWhitePixelRow))
							{
								if (pixels.getPixel(x, y) != tcu::RGBA::black)
								{
									log << TestLog::Message << "Failure: expected all pixels to be black in the area "
															<< (lastWhitePixelColumnOnSecondToLastWhitePixelRow < pixels.getWidth()-1
																	? string() + "y > " + de::toString(lastWhitePixelRow) + " || (y > " + de::toString(secondToLastWhitePixelRow)
																			   + " && x > " + de::toString(lastWhitePixelColumnOnSecondToLastWhitePixelRow) + ")"
																	: string() + "y > " + de::toString(lastWhitePixelRow))
															<< " (they all correspond to patches that should be discarded)" << TestLog::EndMessage
										<< TestLog::Message << "Note: pixel " << tcu::IVec2(x, y) << " isn't black" << TestLog::EndMessage;
									m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
									return STOP;
								}
							}
						}

						break;
					}
				}
			}
		}
	}

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

/*--------------------------------------------------------------------*//*!
 * \brief Case testing user-defined IO between TCS and TES
 *
 * TCS outputs various values to TES, including aggregates. The outputs
 * can be per-patch or per-vertex, and if per-vertex, they can also be in
 * an IO block. Per-vertex input array size can be left implicit (i.e.
 * inputArray[]) or explicit either by gl_MaxPatchVertices or an integer
 * literal whose value is queried from GL.
 *
 * The values output are generated in TCS and verified in TES against
 * similarly generated values. In case a verification of a value fails, the
 * index of the invalid value is output with TF.
 * As a sanity check, also the rendering result is verified (against pre-
 * rendered reference).
 *//*--------------------------------------------------------------------*/
class UserDefinedIOCase : public TestCase
{
public:
	enum IOType
	{
		IO_TYPE_PER_PATCH = 0,
		IO_TYPE_PER_PATCH_ARRAY,
		IO_TYPE_PER_VERTEX,
		IO_TYPE_PER_VERTEX_BLOCK,

		IO_TYPE_LAST
	};

	enum VertexIOArraySize
	{
		VERTEX_IO_ARRAY_SIZE_IMPLICIT = 0,
		VERTEX_IO_ARRAY_SIZE_EXPLICIT_SHADER_BUILTIN,		//!< Use gl_MaxPatchVertices as size for per-vertex input array.
		VERTEX_IO_ARRAY_SIZE_EXPLICIT_QUERY,				//!< Query GL_MAX_PATCH_VERTICES, and use that as size for per-vertex input array.

		VERTEX_IO_ARRAY_SIZE_LAST
	};

	UserDefinedIOCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, IOType ioType, VertexIOArraySize vertexIOArraySize, const char* referenceImagePath)
		: TestCase				(context, name, description)
		, m_primitiveType		(primType)
		, m_ioType				(ioType)
		, m_vertexIOArraySize	(vertexIOArraySize)
		, m_referenceImagePath	(referenceImagePath)
	{
	}

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

private:
	typedef string (*BasicTypeVisitFunc)(const string& name, glu::DataType type, int indentationDepth); //!< See glslTraverseBasicTypes below.

	class TopLevelObject
	{
	public:
		virtual			~TopLevelObject					(void) {}

		virtual string	name							(void) const = 0;
		virtual string	declare							(const string& arraySizeExpr) const = 0;
		virtual string	glslTraverseBasicTypes			(int numArrayElements, //!< If negative, traverse just array[gl_InvocationID], not all indices.
														 int indentationDepth,
														 BasicTypeVisitFunc) const = 0;
		virtual int		numBasicSubobjectsInElementType	(void) const = 0;
		virtual string	basicSubobjectAtIndex			(int index, int arraySize) const = 0;
	};

	class Variable : public TopLevelObject
	{
	public:
		Variable (const string& name_, const glu::VarType& type, bool isArray)
			: m_name		(name_)
			, m_type		(type)
			, m_isArray		(isArray)
		{
			DE_ASSERT(!type.isArrayType());
		}

		string	name								(void) const { return m_name; }
		string	declare								(const string& arraySizeExpr) const;
		string	glslTraverseBasicTypes				(int numArrayElements, int indentationDepth, BasicTypeVisitFunc) const;
		int		numBasicSubobjectsInElementType		(void) const;
		string	basicSubobjectAtIndex				(int index, int arraySize) const;

	private:
		string			m_name;
		glu::VarType	m_type; //!< If this Variable is an array element, m_type is the element type; otherwise just the variable type.
		const bool		m_isArray;
	};

	class IOBlock : public TopLevelObject
	{
	public:
		struct Member
		{
			string			name;
			glu::VarType	type;
			Member (const string& n, const glu::VarType& t) : name(n), type(t) {}
		};

		IOBlock (const string& blockName, const string& interfaceName, const vector<Member>& members)
			: m_blockName		(blockName)
			, m_interfaceName	(interfaceName)
			, m_members			(members)
		{
		}

		string	name								(void) const { return m_interfaceName; }
		string	declare								(const string& arraySizeExpr) const;
		string	glslTraverseBasicTypes				(int numArrayElements, int indentationDepth, BasicTypeVisitFunc) const;
		int		numBasicSubobjectsInElementType		(void) const;
		string	basicSubobjectAtIndex				(int index, int arraySize) const;

	private:
		string			m_blockName;
		string			m_interfaceName;
		vector<Member>	m_members;
	};

	static string							glslTraverseBasicTypes				(const string&			rootName,
																				 const glu::VarType&	rootType,
																				 int					arrayNestingDepth,
																				 int					indentationDepth,
																				 BasicTypeVisitFunc		visit);

	static string							glslAssignBasicTypeObject			(const string& name, glu::DataType, int indentationDepth);
	static string							glslCheckBasicTypeObject			(const string& name, glu::DataType, int indentationDepth);
	static int								numBasicSubobjectsInElementType		(const vector<SharedPtr<TopLevelObject> >&);
	static string							basicSubobjectAtIndex				(int index, const vector<SharedPtr<TopLevelObject> >&, int topLevelArraySizes);

	static const int						RENDER_SIZE = 256;
	static const int						NUM_OUTPUT_VERTICES;
	static const int						NUM_PER_PATCH_ARRAY_ELEMS;

	const TessPrimitiveType					m_primitiveType;
	const IOType							m_ioType;
	const VertexIOArraySize					m_vertexIOArraySize;
	const string							m_referenceImagePath;

	vector<glu::StructType>					m_structTypes;
	vector<SharedPtr<TopLevelObject> >		m_tcsOutputs;
	vector<SharedPtr<TopLevelObject> >		m_tesInputs;

	SharedPtr<const glu::ShaderProgram>		m_program;
};

const int UserDefinedIOCase::NUM_OUTPUT_VERTICES			= 5;
const int UserDefinedIOCase::NUM_PER_PATCH_ARRAY_ELEMS		= 3;

/*--------------------------------------------------------------------*//*!
 * \brief Generate GLSL code to traverse (possibly aggregate) object
 *
 * Generates a string that represents GLSL code that traverses the
 * basic-type subobjects in a rootType-typed object named rootName. Arrays
 * are traversed with loops and struct members are each traversed
 * separately. The code for each basic-type subobject is generated with
 * the function given as the 'visit' argument.
 *//*--------------------------------------------------------------------*/
string UserDefinedIOCase::glslTraverseBasicTypes (const string&			rootName,
												  const glu::VarType&	rootType,
												  int					arrayNestingDepth,
												  int					indentationDepth,
												  BasicTypeVisitFunc	visit)
{
	if (rootType.isBasicType())
		return visit(rootName, rootType.getBasicType(), indentationDepth);
	else if (rootType.isArrayType())
	{
		const string indentation	= string(indentationDepth, '\t');
		const string loopIndexName	= "i" + de::toString(arrayNestingDepth);
		const string arrayLength	= de::toString(rootType.getArraySize());
		return indentation + "for (int " + loopIndexName + " = 0; " + loopIndexName + " < " + de::toString(rootType.getArraySize()) + "; " + loopIndexName + "++)\n" +
			   indentation + "{\n" +
			   glslTraverseBasicTypes(rootName + "[" + loopIndexName + "]", rootType.getElementType(), arrayNestingDepth+1, indentationDepth+1, visit) +
			   indentation + "}\n";
	}
	else if (rootType.isStructType())
	{
		const glu::StructType&	structType = *rootType.getStructPtr();
		const int				numMembers = structType.getNumMembers();
		string					result;

		for (int membNdx = 0; membNdx < numMembers; membNdx++)
		{
			const glu::StructMember& member = structType.getMember(membNdx);
			result += glslTraverseBasicTypes(rootName + "." + member.getName(), member.getType(), arrayNestingDepth, indentationDepth, visit);
		}

		return result;
	}
	else
	{
		DE_ASSERT(false);
		return DE_NULL;
	}
}

string UserDefinedIOCase::Variable::declare (const string& sizeExpr) const
{
	return de::toString(glu::declare(m_type, m_name)) + (m_isArray ? "[" + sizeExpr + "]" : "") + ";\n";
}

string UserDefinedIOCase::IOBlock::declare (const string& sizeExpr) const
{
	string result = m_blockName + "\n" +
					"{\n";
	for (int i = 0; i < (int)m_members.size(); i++)
		result += "\t" + de::toString(glu::declare(m_members[i].type, m_members[i].name)) + ";\n";
	result += "} " + m_interfaceName + "[" + sizeExpr + "]" + ";\n";
	return result;
}

string UserDefinedIOCase::Variable::glslTraverseBasicTypes (int numArrayElements, int indentationDepth, BasicTypeVisitFunc visit) const
{
	const bool				traverseAsArray		= m_isArray && numArrayElements >= 0;
	const string			traversedName		= m_name + (m_isArray && !traverseAsArray ? "[gl_InvocationID]" : "");
	const glu::VarType		type				= traverseAsArray ? glu::VarType(m_type, numArrayElements) : m_type;

	return UserDefinedIOCase::glslTraverseBasicTypes(traversedName, type, 0, indentationDepth, visit);
}

string UserDefinedIOCase::IOBlock::glslTraverseBasicTypes (int numArrayElements, int indentationDepth, BasicTypeVisitFunc visit) const
{
	if (numArrayElements >= 0)
	{
		const string	indentation			= string(indentationDepth, '\t');
		string			result				= indentation + "for (int i0 = 0; i0 < " + de::toString(numArrayElements) + "; i0++)\n" +
											  indentation + "{\n";
		for (int i = 0; i < (int)m_members.size(); i++)
			result += UserDefinedIOCase::glslTraverseBasicTypes(m_interfaceName + "[i0]." + m_members[i].name, m_members[i].type, 1, indentationDepth+1, visit);
		result += indentation + "}\n";
		return result;
	}
	else
	{
		string result;
		for (int i = 0; i < (int)m_members.size(); i++)
			result += UserDefinedIOCase::glslTraverseBasicTypes(m_interfaceName + "[gl_InvocationID]." + m_members[i].name, m_members[i].type, 0, indentationDepth, visit);
		return result;
	}
}

int UserDefinedIOCase::Variable::numBasicSubobjectsInElementType (void) const
{
	return numBasicSubobjects(m_type);
}

int UserDefinedIOCase::IOBlock::numBasicSubobjectsInElementType (void) const
{
	int result = 0;
	for (int i = 0; i < (int)m_members.size(); i++)
		result += numBasicSubobjects(m_members[i].type);
	return result;
}

string UserDefinedIOCase::Variable::basicSubobjectAtIndex (int subobjectIndex, int arraySize) const
{
	const glu::VarType	type			= m_isArray ? glu::VarType(m_type, arraySize) : m_type;
	int					currentIndex	= 0;

	for (glu::BasicTypeIterator basicIt = glu::BasicTypeIterator::begin(&type);
		 basicIt != glu::BasicTypeIterator::end(&type);
		 ++basicIt)
	{
		if (currentIndex == subobjectIndex)
			return m_name + de::toString(glu::TypeAccessFormat(type, basicIt.getPath()));
		currentIndex++;
	}
	DE_ASSERT(false);
	return DE_NULL;
}

string UserDefinedIOCase::IOBlock::basicSubobjectAtIndex (int subobjectIndex, int arraySize) const
{
	int currentIndex = 0;
	for (int arrayNdx = 0; arrayNdx < arraySize; arrayNdx++)
	{
		for (int memberNdx = 0; memberNdx < (int)m_members.size(); memberNdx++)
		{
			const glu::VarType& membType = m_members[memberNdx].type;
			for (glu::BasicTypeIterator basicIt = glu::BasicTypeIterator::begin(&membType);
				 basicIt != glu::BasicTypeIterator::end(&membType);
				 ++basicIt)
			{
				if (currentIndex == subobjectIndex)
					return m_interfaceName + "[" + de::toString(arrayNdx) + "]." + m_members[memberNdx].name + de::toString(glu::TypeAccessFormat(membType, basicIt.getPath()));
				currentIndex++;
			}
		}
	}
	DE_ASSERT(false);
	return DE_NULL;
}

// Used as the 'visit' argument for glslTraverseBasicTypes.
string UserDefinedIOCase::glslAssignBasicTypeObject (const string& name, glu::DataType type, int indentationDepth)
{
	const int		scalarSize		= glu::getDataTypeScalarSize(type);
	const string	indentation		= string(indentationDepth, '\t');
	string			result;

	result += indentation + name + " = ";

	if (type != glu::TYPE_FLOAT)
		result += string() + glu::getDataTypeName(type) + "(";
	for (int i = 0; i < scalarSize; i++)
		result += (i > 0 ? ", v+" + de::floatToString(0.8f*(float)i, 1)
						 : "v");
	if (type != glu::TYPE_FLOAT)
		result += ")";
	result += ";\n" +
			  indentation + "v += 0.4;\n";
	return result;
}

// Used as the 'visit' argument for glslTraverseBasicTypes.
string UserDefinedIOCase::glslCheckBasicTypeObject (const string& name, glu::DataType type, int indentationDepth)
{
	const int		scalarSize		= glu::getDataTypeScalarSize(type);
	const string	indentation		= string(indentationDepth, '\t');
	string			result;

	result += indentation + "allOk = allOk && compare_" + glu::getDataTypeName(type) + "(" + name + ", ";

	if (type != glu::TYPE_FLOAT)
		result += string() + glu::getDataTypeName(type) + "(";
	for (int i = 0; i < scalarSize; i++)
		result += (i > 0 ? ", v+" + de::floatToString(0.8f*(float)i, 1)
						 : "v");
	if (type != glu::TYPE_FLOAT)
		result += ")";
	result += ");\n" +
			  indentation + "v += 0.4;\n" +
			  indentation + "if (allOk) firstFailedInputIndex++;\n";

	return result;
}

int UserDefinedIOCase::numBasicSubobjectsInElementType (const vector<SharedPtr<TopLevelObject> >& objects)
{
	int result = 0;
	for (int i = 0; i < (int)objects.size(); i++)
		result += objects[i]->numBasicSubobjectsInElementType();
	return result;
}

string UserDefinedIOCase::basicSubobjectAtIndex (int subobjectIndex, const vector<SharedPtr<TopLevelObject> >& objects, int topLevelArraySize)
{
	int currentIndex	= 0;
	int objectIndex		= 0;
	for (; currentIndex < subobjectIndex; objectIndex++)
		currentIndex += objects[objectIndex]->numBasicSubobjectsInElementType() * topLevelArraySize;
	if (currentIndex > subobjectIndex)
	{
		objectIndex--;
		currentIndex -= objects[objectIndex]->numBasicSubobjectsInElementType() * topLevelArraySize;
	}

	return objects[objectIndex]->basicSubobjectAtIndex(subobjectIndex - currentIndex, topLevelArraySize);
}

void UserDefinedIOCase::init (void)
{
	checkTessellationSupport(m_context);
	checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE);

	const bool			isPerPatchIO				= m_ioType == IO_TYPE_PER_PATCH || m_ioType == IO_TYPE_PER_PATCH_ARRAY;
	const bool			isExplicitVertexArraySize	= m_vertexIOArraySize == VERTEX_IO_ARRAY_SIZE_EXPLICIT_SHADER_BUILTIN ||
													  m_vertexIOArraySize == VERTEX_IO_ARRAY_SIZE_EXPLICIT_QUERY;

	const string		vertexAttrArrayInputSize	= m_vertexIOArraySize == VERTEX_IO_ARRAY_SIZE_IMPLICIT					? ""
													: m_vertexIOArraySize == VERTEX_IO_ARRAY_SIZE_EXPLICIT_SHADER_BUILTIN	? "gl_MaxPatchVertices"
													: m_vertexIOArraySize == VERTEX_IO_ARRAY_SIZE_EXPLICIT_QUERY			? de::toString(m_context.getContextInfo().getInt(GL_MAX_PATCH_VERTICES))
													: DE_NULL;

	const char* const	maybePatch					= isPerPatchIO ? "patch " : "";
	const string		outMaybePatch				= string() + maybePatch + "out ";
	const string		inMaybePatch				= string() + maybePatch + "in ";
	const bool			useBlock					= m_ioType == IO_TYPE_PER_VERTEX_BLOCK;

	string				tcsDeclarations;
	string				tcsStatements;

	string				tesDeclarations;
	string				tesStatements;

	{
		m_structTypes.push_back(glu::StructType("S"));

		const glu::VarType	highpFloat		(glu::TYPE_FLOAT, glu::PRECISION_HIGHP);
		glu::StructType&	structType		= m_structTypes.back();
		const glu::VarType	structVarType	(&structType);

		structType.addMember("x", glu::VarType(glu::TYPE_INT, glu::PRECISION_HIGHP));
		structType.addMember("y", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP));
		structType.addMember("z", glu::VarType(highpFloat, 2));

		if (useBlock)
		{
			vector<IOBlock::Member> blockMembers;
			blockMembers.push_back(IOBlock::Member("blockS",	structVarType));
			blockMembers.push_back(IOBlock::Member("blockFa",	glu::VarType(highpFloat, 3)));
			blockMembers.push_back(IOBlock::Member("blockSa",	glu::VarType(structVarType, 2)));
			blockMembers.push_back(IOBlock::Member("blockF",	highpFloat));

			m_tcsOutputs.push_back	(SharedPtr<TopLevelObject>(new IOBlock("TheBlock", "tcBlock", blockMembers)));
			m_tesInputs.push_back	(SharedPtr<TopLevelObject>(new IOBlock("TheBlock", "teBlock", blockMembers)));
		}
		else
		{
			const Variable var0("in_te_s", structVarType,	m_ioType != IO_TYPE_PER_PATCH);
			const Variable var1("in_te_f", highpFloat,		m_ioType != IO_TYPE_PER_PATCH);

			m_tcsOutputs.push_back	(SharedPtr<TopLevelObject>(new Variable(var0)));
			m_tesInputs.push_back	(SharedPtr<TopLevelObject>(new Variable(var0)));
			m_tcsOutputs.push_back	(SharedPtr<TopLevelObject>(new Variable(var1)));
			m_tesInputs.push_back	(SharedPtr<TopLevelObject>(new Variable(var1)));
		}

		tcsDeclarations += "in " + Variable("in_tc_attr", highpFloat, true).declare(vertexAttrArrayInputSize);
		tcsDeclarations += de::toString(glu::declare(structType)) + ";\n";
		tcsStatements += "\t{\n"
						 "\t\thighp float v = 1.3;\n";

		for (int tcsOutputNdx = 0; tcsOutputNdx < (int)m_tcsOutputs.size(); tcsOutputNdx++)
		{
			const TopLevelObject& output = *m_tcsOutputs[tcsOutputNdx];

			tcsDeclarations += outMaybePatch + output.declare(m_ioType == IO_TYPE_PER_PATCH_ARRAY	? de::toString(NUM_PER_PATCH_ARRAY_ELEMS)
															  : isExplicitVertexArraySize			? de::toString(NUM_OUTPUT_VERTICES)
															  : "");
			if (!isPerPatchIO)
				tcsStatements += "\t\tv += float(gl_InvocationID)*" + de::floatToString(0.4f*output.numBasicSubobjectsInElementType(), 1) + ";\n";

			tcsStatements += "\n\t\t// Assign values to output " + output.name() + "\n" +
							 output.glslTraverseBasicTypes(isPerPatchIO ? NUM_PER_PATCH_ARRAY_ELEMS : -1, 2, glslAssignBasicTypeObject);

			if (!isPerPatchIO)
				tcsStatements += "\t\tv += float(" + de::toString(NUM_OUTPUT_VERTICES) + "-gl_InvocationID-1)*" + de::floatToString(0.4f*output.numBasicSubobjectsInElementType(), 1) + ";\n";
		}
		tcsStatements += "\t}\n";

		tesDeclarations += de::toString(glu::declare(structType)) + ";\n";
		tesStatements += "\tbool allOk = true;\n"
						 "\thighp uint firstFailedInputIndex = 0u;\n"
						 "\t{\n"
						 "\t\thighp float v = 1.3;\n";
		for (int tesInputNdx = 0; tesInputNdx < (int)m_tesInputs.size(); tesInputNdx++)
		{
			const TopLevelObject& input = *m_tesInputs[tesInputNdx];
			tesDeclarations += inMaybePatch + input.declare(m_ioType == IO_TYPE_PER_PATCH_ARRAY	? de::toString(NUM_PER_PATCH_ARRAY_ELEMS)
														  : isExplicitVertexArraySize			? de::toString(vertexAttrArrayInputSize)
														  : "");
			tesStatements += "\n\t\t// Check values in input " + input.name() + "\n" +
							 input.glslTraverseBasicTypes(isPerPatchIO ? NUM_PER_PATCH_ARRAY_ELEMS : NUM_OUTPUT_VERTICES, 2, glslCheckBasicTypeObject);
		}
		tesStatements += "\t}\n";
	}

	m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
		<< glu::VertexSource					("#version 310 es\n"
												 "\n"
												 "in highp float in_v_attr;\n"
												 "out highp float in_tc_attr;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	in_tc_attr = in_v_attr;\n"
												 "}\n")

		<< glu::TessellationControlSource		("#version 310 es\n"
												 "#extension GL_EXT_tessellation_shader : require\n"
												 "\n"
												 "layout (vertices = " + de::toString(NUM_OUTPUT_VERTICES) + ") out;\n"
												 "\n"
												 + tcsDeclarations +
												 "\n"
												 "patch out highp vec2 in_te_positionScale;\n"
												 "patch out highp vec2 in_te_positionOffset;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 + tcsStatements +
												 "\n"
												 "	in_te_positionScale  = vec2(in_tc_attr[6], in_tc_attr[7]);\n"
												 "	in_te_positionOffset = vec2(in_tc_attr[8], in_tc_attr[9]);\n"
												 "\n"
												 "	gl_TessLevelInner[0] = in_tc_attr[0];\n"
												 "	gl_TessLevelInner[1] = in_tc_attr[1];\n"
												 "\n"
												 "	gl_TessLevelOuter[0] = in_tc_attr[2];\n"
												 "	gl_TessLevelOuter[1] = in_tc_attr[3];\n"
												 "	gl_TessLevelOuter[2] = in_tc_attr[4];\n"
												 "	gl_TessLevelOuter[3] = in_tc_attr[5];\n"
												 "}\n")

		<< glu::TessellationEvaluationSource	("#version 310 es\n"
												 "#extension GL_EXT_tessellation_shader : require\n"
												 "\n"
												 + getTessellationEvaluationInLayoutString(m_primitiveType) +
												 "\n"
												 + tesDeclarations +
												 "\n"
												 "patch in highp vec2 in_te_positionScale;\n"
												 "patch in highp vec2 in_te_positionOffset;\n"
												 "\n"
												 "out highp vec4 in_f_color;\n"
												 "// Will contain the index of the first incorrect input,\n"
												 "// or the number of inputs if all are correct\n"
												 "flat out highp uint out_te_firstFailedInputIndex;\n"
												 "\n"
												 "bool compare_int   (int   a, int   b) { return a == b; }\n"
												 "bool compare_float (float a, float b) { return abs(a - b) < 0.01f; }\n"
												 "bool compare_vec4  (vec4  a, vec4  b) { return all(lessThan(abs(a - b), vec4(0.01f))); }\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 + tesStatements +
												 "\n"
												 "	gl_Position = vec4(gl_TessCoord.xy*in_te_positionScale + in_te_positionOffset, 0.0, 1.0);\n"
												 "	in_f_color = allOk ? vec4(0.0, 1.0, 0.0, 1.0)\n"
												 "	                   : vec4(1.0, 0.0, 0.0, 1.0);\n"
												 "	out_te_firstFailedInputIndex = firstFailedInputIndex;\n"
												 "}\n")

		<< glu::FragmentSource					("#version 310 es\n"
												 "\n"
												 "layout (location = 0) out mediump vec4 o_color;\n"
												 "\n"
												 "in highp vec4 in_f_color;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	o_color = in_f_color;\n"
												 "}\n")

		<< glu::TransformFeedbackVarying		("out_te_firstFailedInputIndex")
		<< glu::TransformFeedbackMode			(GL_INTERLEAVED_ATTRIBS)));

	m_testCtx.getLog() << *m_program;
	if (!m_program->isOk())
		TCU_FAIL("Program compilation failed");
}

void UserDefinedIOCase::deinit (void)
{
	m_program.clear();
}

UserDefinedIOCase::IterateResult UserDefinedIOCase::iterate (void)
{
	typedef TransformFeedbackHandler<deUint32> TFHandler;

	TestLog&				log						= m_testCtx.getLog();
	const RenderContext&	renderCtx				= m_context.getRenderContext();
	const RandomViewport	viewport				(renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName()));
	const glw::Functions&	gl						= renderCtx.getFunctions();
	static const float		attributes[6+2+2]		= { /* inner */ 3.0f, 4.0f, /* outer */ 5.0f, 6.0f, 7.0f, 8.0f, /* pos. scale */ 1.2f, 1.3f, /* pos. offset */ -0.3f, -0.4f };
	const deUint32			programGL				= m_program->getProgram();
	const int				numVertices				= referenceVertexCount(m_primitiveType, SPACINGMODE_EQUAL, false, &attributes[0], &attributes[2]);
	const TFHandler			tfHandler				(renderCtx, numVertices);

	gl.useProgram(programGL);
	setViewport(gl, viewport);
	gl.patchParameteri(GL_PATCH_VERTICES, DE_LENGTH_OF_ARRAY(attributes));

	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.clear(GL_COLOR_BUFFER_BIT);

	{
		const glu::VertexArrayBinding	bindings[]	= { glu::va::Float("in_v_attr", 1, DE_LENGTH_OF_ARRAY(attributes), 0, &attributes[0]) };
		const TFHandler::Result			tfResult	= tfHandler.renderAndGetPrimitives(programGL, outputPrimitiveTypeGL(m_primitiveType, false),
																					   DE_LENGTH_OF_ARRAY(bindings), &bindings[0], DE_LENGTH_OF_ARRAY(attributes));

		{
			const tcu::Surface			pixels		= getPixels(renderCtx, viewport);
			const tcu::TextureLevel		reference	= getPNG(m_testCtx.getArchive(), m_referenceImagePath.c_str());
			const bool					success		= tcu::fuzzyCompare(log, "ImageComparison", "Image Comparison", reference.getAccess(), pixels.getAccess(), 0.02f, tcu::COMPARE_LOG_RESULT);

			if (!success)
			{
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
				return STOP;
			}
		}

		if ((int)tfResult.varying.size() != numVertices)
		{
			log << TestLog::Message << "Failure: transform feedback returned " << tfResult.varying.size() << " vertices; expected " << numVertices << TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrong number of vertices");
			return STOP;
		}

		{
			const int topLevelArraySize		= (m_ioType == IO_TYPE_PER_PATCH		? 1
											 : m_ioType == IO_TYPE_PER_PATCH_ARRAY	? NUM_PER_PATCH_ARRAY_ELEMS
											 : NUM_OUTPUT_VERTICES);
			const int numTEInputs			= numBasicSubobjectsInElementType(m_tesInputs) * topLevelArraySize;

			for (int vertexNdx = 0; vertexNdx < (int)numVertices; vertexNdx++)
			{
				if (tfResult.varying[vertexNdx] > (deUint32)numTEInputs)
				{
					log << TestLog::Message << "Failure: out_te_firstFailedInputIndex has value " << tfResult.varying[vertexNdx]
											<< ", should be in range [0, " << numTEInputs << "]" << TestLog::EndMessage;
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid transform feedback output");
					return STOP;
				}
				else if (tfResult.varying[vertexNdx] != (deUint32)numTEInputs)
				{
					log << TestLog::Message << "Failure: in tessellation evaluation shader, check for input "
											<< basicSubobjectAtIndex(tfResult.varying[vertexNdx], m_tesInputs, topLevelArraySize) << " failed" << TestLog::EndMessage;
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid input value in tessellation evaluation shader");
					return STOP;
				}
			}
		}
	}

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

/*--------------------------------------------------------------------*//*!
 * \brief Pass gl_Position between VS and TCS, or between TCS and TES.
 *
 * In TCS gl_Position is in the gl_out[] block and in TES in the gl_in[]
 * block, and has no special semantics in those. Arbitrary vec4 data can
 * thus be passed there.
 *//*--------------------------------------------------------------------*/
class GLPositionCase : public TestCase
{
public:
	enum CaseType
	{
		CASETYPE_VS_TO_TCS = 0,
		CASETYPE_TCS_TO_TES,
		CASETYPE_VS_TO_TCS_TO_TES,

		CASETYPE_LAST
	};

	GLPositionCase (Context& context, const char* name, const char* description, CaseType caseType, const char* referenceImagePath)
		: TestCase				(context, name, description)
		, m_caseType			(caseType)
		, m_referenceImagePath	(referenceImagePath)
	{
	}

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

	static const char*						getCaseTypeName		(CaseType type);

private:
	static const int						RENDER_SIZE = 256;

	const CaseType							m_caseType;
	const string							m_referenceImagePath;

	SharedPtr<const glu::ShaderProgram>		m_program;
};

const char* GLPositionCase::getCaseTypeName (CaseType type)
{
	switch (type)
	{
		case CASETYPE_VS_TO_TCS:			return "gl_position_vs_to_tcs";
		case CASETYPE_TCS_TO_TES:			return "gl_position_tcs_to_tes";
		case CASETYPE_VS_TO_TCS_TO_TES:		return "gl_position_vs_to_tcs_to_tes";
		default:
			DE_ASSERT(false); return DE_NULL;
	}
}

void GLPositionCase::init (void)
{
	checkTessellationSupport(m_context);
	checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE);

	const bool		vsToTCS		= m_caseType == CASETYPE_VS_TO_TCS		|| m_caseType == CASETYPE_VS_TO_TCS_TO_TES;
	const bool		tcsToTES	= m_caseType == CASETYPE_TCS_TO_TES		|| m_caseType == CASETYPE_VS_TO_TCS_TO_TES;

	const string	tesIn0		= tcsToTES ? "gl_in[0].gl_Position" : "in_te_attr[0]";
	const string	tesIn1		= tcsToTES ? "gl_in[1].gl_Position" : "in_te_attr[1]";
	const string	tesIn2		= tcsToTES ? "gl_in[2].gl_Position" : "in_te_attr[2]";

	m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
		<< glu::VertexSource					("#version 310 es\n"
												 "\n"
												 "in highp vec4 in_v_attr;\n"
												 + string(!vsToTCS ? "out highp vec4 in_tc_attr;\n" : "") +
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	" + (vsToTCS ? "gl_Position" : "in_tc_attr") + " = in_v_attr;\n"
												 "}\n")

		<< glu::TessellationControlSource		("#version 310 es\n"
												 "#extension GL_EXT_tessellation_shader : require\n"
												 "\n"
												 "layout (vertices = 3) out;\n"
												 "\n"
												 + string(!vsToTCS ? "in highp vec4 in_tc_attr[];\n" : "") +
												 "\n"
												 + (!tcsToTES ? "out highp vec4 in_te_attr[];\n" : "") +
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	" + (tcsToTES ? "gl_out[gl_InvocationID].gl_Position" : "in_te_attr[gl_InvocationID]") + " = "
													  + (vsToTCS ? "gl_in[gl_InvocationID].gl_Position" : "in_tc_attr[gl_InvocationID]") + ";\n"
												 "\n"
												 "	gl_TessLevelInner[0] = 2.0;\n"
												 "	gl_TessLevelInner[1] = 3.0;\n"
												 "\n"
												 "	gl_TessLevelOuter[0] = 4.0;\n"
												 "	gl_TessLevelOuter[1] = 5.0;\n"
												 "	gl_TessLevelOuter[2] = 6.0;\n"
												 "	gl_TessLevelOuter[3] = 7.0;\n"
												 "}\n")

		<< glu::TessellationEvaluationSource	("#version 310 es\n"
												 "#extension GL_EXT_tessellation_shader : require\n"
												 "\n"
												 + getTessellationEvaluationInLayoutString(TESSPRIMITIVETYPE_TRIANGLES) +
												 "\n"
												 + (!tcsToTES ? "in highp vec4 in_te_attr[];\n" : "") +
												 "\n"
												 "out highp vec4 in_f_color;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	highp vec2 xy = gl_TessCoord.x * " + tesIn0 + ".xy\n"
												 "	              + gl_TessCoord.y * " + tesIn1 + ".xy\n"
												 "	              + gl_TessCoord.z * " + tesIn2 + ".xy;\n"
												 "	gl_Position = vec4(xy, 0.0, 1.0);\n"
												 "	in_f_color = vec4(" + tesIn0 + ".z + " + tesIn1 + ".w,\n"
												 "	                  " + tesIn2 + ".z + " + tesIn0 + ".w,\n"
												 "	                  " + tesIn1 + ".z + " + tesIn2 + ".w,\n"
												 "	                  1.0);\n"
												 "}\n")

		<< glu::FragmentSource					("#version 310 es\n"
												 "\n"
												 "layout (location = 0) out mediump vec4 o_color;\n"
												 "\n"
												 "in highp vec4 in_f_color;\n"
												 "\n"
												 "void main (void)\n"
												 "{\n"
												 "	o_color = in_f_color;\n"
												 "}\n")));

	m_testCtx.getLog() << *m_program;
	if (!m_program->isOk())
		TCU_FAIL("Program compilation failed");
}

void GLPositionCase::deinit (void)
{
	m_program.clear();
}

GLPositionCase::IterateResult GLPositionCase::iterate (void)
{
	TestLog&				log						= m_testCtx.getLog();
	const RenderContext&	renderCtx				= m_context.getRenderContext();
	const RandomViewport	viewport				(renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName()));
	const glw::Functions&	gl						= renderCtx.getFunctions();
	const deUint32			programGL				= m_program->getProgram();

	static const float attributes[3*4] =
	{
		-0.8f, -0.7f, 0.1f, 0.7f,
		-0.5f,  0.4f, 0.2f, 0.5f,
		 0.3f,  0.2f, 0.3f, 0.45f
	};

	gl.useProgram(programGL);
	setViewport(gl, viewport);
	gl.patchParameteri(GL_PATCH_VERTICES, 3);

	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.clear(GL_COLOR_BUFFER_BIT);

	log << TestLog::Message << "Note: input data for in_v_attr:\n" << arrayStr(attributes, 4) << TestLog::EndMessage;

	{
		const glu::VertexArrayBinding bindings[] = { glu::va::Float("in_v_attr", 4, 3, 0, &attributes[0]) };
		glu::draw(renderCtx, programGL, DE_LENGTH_OF_ARRAY(bindings), &bindings[0], glu::pr::Patches(3));

		{
			const tcu::Surface			pixels		= getPixels(renderCtx, viewport);
			const tcu::TextureLevel		reference	= getPNG(m_testCtx.getArchive(), m_referenceImagePath.c_str());
			const bool					success		= tcu::fuzzyCompare(log, "ImageComparison", "Image Comparison", reference.getAccess(), pixels.getAccess(), 0.02f, tcu::COMPARE_LOG_RESULT);

			if (!success)
			{
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
				return STOP;
			}
		}
	}

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

} // anonymous

TessellationTests::TessellationTests (Context& context)
	: TestCaseGroup(context, "tessellation", "Tessellation Tests")
{
}

TessellationTests::~TessellationTests (void)
{
}

void TessellationTests::init (void)
{
	{
		TestCaseGroup* const tessCoordGroup = new TestCaseGroup(m_context, "tesscoord", "Get tessellation coordinates with transform feedback and validate them");
		addChild(tessCoordGroup);

		for (int primitiveTypeI = 0; primitiveTypeI < TESSPRIMITIVETYPE_LAST; primitiveTypeI++)
		{
			const TessPrimitiveType primitiveType = (TessPrimitiveType)primitiveTypeI;

			for (int spacingI = 0; spacingI < SPACINGMODE_LAST; spacingI++)
				tessCoordGroup->addChild(new TessCoordCase(m_context,
														   (string() + getTessPrimitiveTypeShaderName(primitiveType) + "_" + getSpacingModeShaderName((SpacingMode)spacingI)).c_str(), "",
														   primitiveType, (SpacingMode)spacingI));
		}
	}

	{
		TestCaseGroup* const windingGroup = new TestCaseGroup(m_context, "winding", "Test the cw and ccw input layout qualifiers");
		addChild(windingGroup);

		for (int primitiveTypeI = 0; primitiveTypeI < TESSPRIMITIVETYPE_LAST; primitiveTypeI++)
		{
			const TessPrimitiveType primitiveType = (TessPrimitiveType)primitiveTypeI;
			if (primitiveType == TESSPRIMITIVETYPE_ISOLINES)
				continue;

			for (int windingI = 0; windingI < WINDING_LAST; windingI++)
			{
				const Winding winding = (Winding)windingI;
				windingGroup->addChild(new WindingCase(m_context, (string() + getTessPrimitiveTypeShaderName(primitiveType) + "_" + getWindingShaderName(winding)).c_str(), "", primitiveType, winding));
			}
		}
	}

	{
		TestCaseGroup* const shaderInputOutputGroup = new TestCaseGroup(m_context, "shader_input_output", "Test tessellation control and evaluation shader inputs and outputs");
		addChild(shaderInputOutputGroup);

		{
			static const struct
			{
				int inPatchSize;
				int outPatchSize;
			} patchVertexCountCases[] =
			{
				{  5, 10 },
				{ 10,  5 }
			};

			for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(patchVertexCountCases); caseNdx++)
			{
				const int inSize	= patchVertexCountCases[caseNdx].inPatchSize;
				const int outSize	= patchVertexCountCases[caseNdx].outPatchSize;

				const string caseName = "patch_vertices_" + de::toString(inSize) + "_in_" + de::toString(outSize) + "_out";

				shaderInputOutputGroup->addChild(new PatchVertexCountCase(m_context, caseName.c_str(), "Test input and output patch vertex counts", inSize, outSize,
																		  ("data/tessellation/" + caseName + "_ref.png").c_str()));
			}
		}

		for (int caseTypeI = 0; caseTypeI < PerPatchDataCase::CASETYPE_LAST; caseTypeI++)
		{
			const PerPatchDataCase::CaseType	caseType	= (PerPatchDataCase::CaseType)caseTypeI;
			const char* const					caseName	= PerPatchDataCase::getCaseTypeName(caseType);

			shaderInputOutputGroup->addChild(new PerPatchDataCase(m_context, caseName, PerPatchDataCase::getCaseTypeDescription(caseType), caseType,
																  PerPatchDataCase::caseTypeUsesRefImageFromFile(caseType) ? (string() + "data/tessellation/" + caseName + "_ref.png").c_str() : DE_NULL));
		}

		for (int caseTypeI = 0; caseTypeI < GLPositionCase::CASETYPE_LAST; caseTypeI++)
		{
			const GLPositionCase::CaseType	caseType	= (GLPositionCase::CaseType)caseTypeI;
			const char* const				caseName	= GLPositionCase::getCaseTypeName(caseType);

			shaderInputOutputGroup->addChild(new GLPositionCase(m_context, caseName, "", caseType, "data/tessellation/gl_position_ref.png"));
		}

		shaderInputOutputGroup->addChild(new BarrierCase(m_context, "barrier", "Basic barrier usage", "data/tessellation/barrier_ref.png"));
	}

	{
		TestCaseGroup* const miscDrawGroup = new TestCaseGroup(m_context, "misc_draw", "Miscellaneous draw-result-verifying cases");
		addChild(miscDrawGroup);

		for (int primitiveTypeI = 0; primitiveTypeI < TESSPRIMITIVETYPE_LAST; primitiveTypeI++)
		{
			const TessPrimitiveType primitiveType = (TessPrimitiveType)primitiveTypeI;
			if (primitiveType == TESSPRIMITIVETYPE_ISOLINES)
				continue;

			const char* const primTypeName = getTessPrimitiveTypeShaderName(primitiveType);

			for (int spacingI = 0; spacingI < SPACINGMODE_LAST; spacingI++)
			{
				const string caseName = string() + "fill_cover_" + primTypeName + "_" + getSpacingModeShaderName((SpacingMode)spacingI);

				miscDrawGroup->addChild(new BasicTriangleFillCoverCase(m_context,
																	   caseName.c_str(), "Check that there are no obvious gaps in the triangle-filled area of a tessellated shape",
																	   primitiveType, (SpacingMode)spacingI,
																	   ("data/tessellation/" + caseName + "_ref").c_str()));
			}
		}

		for (int primitiveTypeI = 0; primitiveTypeI < TESSPRIMITIVETYPE_LAST; primitiveTypeI++)
		{
			const TessPrimitiveType primitiveType = (TessPrimitiveType)primitiveTypeI;
			if (primitiveType == TESSPRIMITIVETYPE_ISOLINES)
				continue;

			const char* const primTypeName = getTessPrimitiveTypeShaderName(primitiveType);

			for (int spacingI = 0; spacingI < SPACINGMODE_LAST; spacingI++)
			{
				const string caseName = string() + "fill_overlap_" + primTypeName + "_" + getSpacingModeShaderName((SpacingMode)spacingI);

				miscDrawGroup->addChild(new BasicTriangleFillNonOverlapCase(m_context,
																			caseName.c_str(), "Check that there are no obvious triangle overlaps in the triangle-filled area of a tessellated shape",
																			primitiveType, (SpacingMode)spacingI,
																			("data/tessellation/" + caseName + "_ref").c_str()));
			}
		}

		for (int spacingI = 0; spacingI < SPACINGMODE_LAST; spacingI++)
		{
			const string caseName = string() + "isolines_" + getSpacingModeShaderName((SpacingMode)spacingI);

			miscDrawGroup->addChild(new IsolinesRenderCase(m_context,
														   caseName.c_str(), "Basic isolines render test",
														   (SpacingMode)spacingI,
														   ("data/tessellation/" + caseName + "_ref").c_str()));
		}
	}

	{
		TestCaseGroup* const commonEdgeGroup = new TestCaseGroup(m_context, "common_edge", "Draw multiple adjacent shapes and check that no cracks appear between them");
		addChild(commonEdgeGroup);

		for (int caseTypeI = 0; caseTypeI < CommonEdgeCase::CASETYPE_LAST; caseTypeI++)
		{
			for (int primitiveTypeI = 0; primitiveTypeI < TESSPRIMITIVETYPE_LAST; primitiveTypeI++)
			{
				const CommonEdgeCase::CaseType	caseType		= (CommonEdgeCase::CaseType)caseTypeI;
				const TessPrimitiveType			primitiveType	= (TessPrimitiveType)primitiveTypeI;
				if (primitiveType == TESSPRIMITIVETYPE_ISOLINES)
						continue;

				for (int spacingI = 0; spacingI < SPACINGMODE_LAST; spacingI++)
				{
					const SpacingMode	spacing		= (SpacingMode)spacingI;
					const string		caseName	= (string() + getTessPrimitiveTypeShaderName(primitiveType)
																+ "_" + getSpacingModeShaderName(spacing)
																+ (caseType == CommonEdgeCase::CASETYPE_BASIC		? ""
																 : caseType == CommonEdgeCase::CASETYPE_PRECISE		? "_precise"
																 : DE_NULL));

					commonEdgeGroup->addChild(new CommonEdgeCase(m_context, caseName.c_str(), "", primitiveType, spacing, caseType));
				}
			}
		}
	}

	{
		TestCaseGroup* const fractionalSpacingModeGroup = new TestCaseGroup(m_context, "fractional_spacing", "Test fractional spacing modes");
		addChild(fractionalSpacingModeGroup);

		fractionalSpacingModeGroup->addChild(new FractionalSpacingModeCase(m_context, "odd",	"", SPACINGMODE_FRACTIONAL_ODD));
		fractionalSpacingModeGroup->addChild(new FractionalSpacingModeCase(m_context, "even",	"", SPACINGMODE_FRACTIONAL_EVEN));
	}

	{
		TestCaseGroup* const primitiveDiscardGroup = new TestCaseGroup(m_context, "primitive_discard", "Test primitive discard with relevant outer tessellation level <= 0.0");
		addChild(primitiveDiscardGroup);

		for (int primitiveTypeI = 0; primitiveTypeI < TESSPRIMITIVETYPE_LAST; primitiveTypeI++)
		{
			for (int spacingI = 0; spacingI < SPACINGMODE_LAST; spacingI++)
			{
				for (int windingI = 0; windingI < WINDING_LAST; windingI++)
				{
					for (int usePointModeI = 0; usePointModeI <= 1; usePointModeI++)
					{
						const TessPrimitiveType		primitiveType	= (TessPrimitiveType)primitiveTypeI;
						const SpacingMode			spacing			= (SpacingMode)spacingI;
						const Winding				winding			= (Winding)windingI;
						const bool					usePointMode	= usePointModeI != 0;

						primitiveDiscardGroup->addChild(new PrimitiveDiscardCase(m_context, (string() + getTessPrimitiveTypeShaderName(primitiveType)
																									  + "_" + getSpacingModeShaderName(spacing)
																									  + "_" + getWindingShaderName(winding)
																									  + (usePointMode ? "_point_mode" : "")).c_str(), "",
																				 primitiveType, spacing, winding, usePointMode));
					}
				}
			}
		}
	}

	{
		TestCaseGroup* const invarianceGroup							= new TestCaseGroup(m_context, "invariance",						"Test tessellation invariance rules");

		TestCaseGroup* const invariantPrimitiveSetGroup					= new TestCaseGroup(m_context, "primitive_set",						"Test invariance rule #1");
		TestCaseGroup* const invariantOuterEdgeGroup					= new TestCaseGroup(m_context, "outer_edge_division",				"Test invariance rule #2");
		TestCaseGroup* const symmetricOuterEdgeGroup					= new TestCaseGroup(m_context, "outer_edge_symmetry",				"Test invariance rule #3");
		TestCaseGroup* const outerEdgeVertexSetIndexIndependenceGroup	= new TestCaseGroup(m_context, "outer_edge_index_independence",		"Test invariance rule #4");
		TestCaseGroup* const invariantTriangleSetGroup					= new TestCaseGroup(m_context, "triangle_set",						"Test invariance rule #5");
		TestCaseGroup* const invariantInnerTriangleSetGroup				= new TestCaseGroup(m_context, "inner_triangle_set",				"Test invariance rule #6");
		TestCaseGroup* const invariantOuterTriangleSetGroup				= new TestCaseGroup(m_context, "outer_triangle_set",				"Test invariance rule #7");
		TestCaseGroup* const tessCoordComponentRangeGroup				= new TestCaseGroup(m_context, "tess_coord_component_range",		"Test invariance rule #8, first part");
		TestCaseGroup* const oneMinusTessCoordComponentGroup			= new TestCaseGroup(m_context, "one_minus_tess_coord_component",	"Test invariance rule #8, second part");

		addChild(invarianceGroup);
		invarianceGroup->addChild(invariantPrimitiveSetGroup);
		invarianceGroup->addChild(invariantOuterEdgeGroup);
		invarianceGroup->addChild(symmetricOuterEdgeGroup);
		invarianceGroup->addChild(outerEdgeVertexSetIndexIndependenceGroup);
		invarianceGroup->addChild(invariantTriangleSetGroup);
		invarianceGroup->addChild(invariantInnerTriangleSetGroup);
		invarianceGroup->addChild(invariantOuterTriangleSetGroup);
		invarianceGroup->addChild(tessCoordComponentRangeGroup);
		invarianceGroup->addChild(oneMinusTessCoordComponentGroup);

		for (int primitiveTypeI = 0; primitiveTypeI < TESSPRIMITIVETYPE_LAST; primitiveTypeI++)
		{
			const TessPrimitiveType		primitiveType	= (TessPrimitiveType)primitiveTypeI;
			const string				primName		= getTessPrimitiveTypeShaderName(primitiveType);
			const bool					triOrQuad		= primitiveType == TESSPRIMITIVETYPE_TRIANGLES || primitiveType == TESSPRIMITIVETYPE_QUADS;

			for (int spacingI = 0; spacingI < SPACINGMODE_LAST; spacingI++)
			{
				const SpacingMode	spacing			= (SpacingMode)spacingI;
				const string		primSpacName	= primName + "_" + getSpacingModeShaderName(spacing);

				if (triOrQuad)
				{
					invariantOuterEdgeGroup->addChild		(new InvariantOuterEdgeCase			(m_context, primSpacName.c_str(), "", primitiveType, spacing));
					invariantTriangleSetGroup->addChild		(new InvariantTriangleSetCase		(m_context, primSpacName.c_str(), "", primitiveType, spacing));
					invariantInnerTriangleSetGroup->addChild(new InvariantInnerTriangleSetCase	(m_context, primSpacName.c_str(), "", primitiveType, spacing));
					invariantOuterTriangleSetGroup->addChild(new InvariantOuterTriangleSetCase	(m_context, primSpacName.c_str(), "", primitiveType, spacing));
				}

				for (int windingI = 0; windingI < WINDING_LAST; windingI++)
				{
					const Winding	winding				= (Winding)windingI;
					const string	primSpacWindName	= primSpacName + "_" + getWindingShaderName(winding);

					for (int usePointModeI = 0; usePointModeI <= 1; usePointModeI++)
					{
						const bool		usePointMode			= usePointModeI != 0;
						const string	primSpacWindPointName	= primSpacWindName + (usePointMode ? "_point_mode" : "");

						invariantPrimitiveSetGroup->addChild		(new InvariantPrimitiveSetCase			(m_context, primSpacWindPointName.c_str(), "", primitiveType, spacing, winding, usePointMode));
						symmetricOuterEdgeGroup->addChild			(new SymmetricOuterEdgeCase				(m_context, primSpacWindPointName.c_str(), "", primitiveType, spacing, winding, usePointMode));
						tessCoordComponentRangeGroup->addChild		(new TessCoordComponentRangeCase		(m_context, primSpacWindPointName.c_str(), "", primitiveType, spacing, winding, usePointMode));
						oneMinusTessCoordComponentGroup->addChild	(new OneMinusTessCoordComponentCase		(m_context, primSpacWindPointName.c_str(), "", primitiveType, spacing, winding, usePointMode));

						if (triOrQuad)
							outerEdgeVertexSetIndexIndependenceGroup->addChild(new OuterEdgeVertexSetIndexIndependenceCase(m_context, primSpacWindPointName.c_str(), "",
																														   primitiveType, spacing, winding, usePointMode));
					}
				}
			}
		}
	}

	{
		TestCaseGroup* const userDefinedIOGroup = new TestCaseGroup(m_context, "user_defined_io", "Test non-built-in per-patch and per-vertex inputs and outputs");
		addChild(userDefinedIOGroup);

		for (int ioTypeI = 0; ioTypeI < UserDefinedIOCase::IO_TYPE_LAST; ioTypeI++)
		{
			const UserDefinedIOCase::IOType		ioType			= (UserDefinedIOCase::IOType)ioTypeI;
			TestCaseGroup* const				ioTypeGroup		= new TestCaseGroup(m_context,
																					ioType == UserDefinedIOCase::IO_TYPE_PER_PATCH			? "per_patch"
																				  : ioType == UserDefinedIOCase::IO_TYPE_PER_PATCH_ARRAY	? "per_patch_array"
																				  : ioType == UserDefinedIOCase::IO_TYPE_PER_VERTEX			? "per_vertex"
																				  : ioType == UserDefinedIOCase::IO_TYPE_PER_VERTEX_BLOCK	? "per_vertex_block"
																				  : DE_NULL,
																					ioType == UserDefinedIOCase::IO_TYPE_PER_PATCH			? "Per-patch TCS outputs"
																				  : ioType == UserDefinedIOCase::IO_TYPE_PER_PATCH_ARRAY	? "Per-patch array TCS outputs"
																				  : ioType == UserDefinedIOCase::IO_TYPE_PER_VERTEX			? "Per-vertex TCS outputs"
																				  : ioType == UserDefinedIOCase::IO_TYPE_PER_VERTEX_BLOCK	? "Per-vertex TCS outputs in IO block"
																				  : DE_NULL);
			userDefinedIOGroup->addChild(ioTypeGroup);

			for (int vertexArraySizeI = 0; vertexArraySizeI < UserDefinedIOCase::VERTEX_IO_ARRAY_SIZE_LAST; vertexArraySizeI++)
			{
				const UserDefinedIOCase::VertexIOArraySize	vertexArraySize			= (UserDefinedIOCase::VertexIOArraySize)vertexArraySizeI;
				TestCaseGroup* const						vertexArraySizeGroup	= new TestCaseGroup(m_context,
																										vertexArraySizeI == UserDefinedIOCase::VERTEX_IO_ARRAY_SIZE_IMPLICIT
																											? "vertex_io_array_size_implicit"
																									  : vertexArraySizeI == UserDefinedIOCase::VERTEX_IO_ARRAY_SIZE_EXPLICIT_SHADER_BUILTIN
																											? "vertex_io_array_size_shader_builtin"
																									  : vertexArraySizeI == UserDefinedIOCase::VERTEX_IO_ARRAY_SIZE_EXPLICIT_QUERY
																											? "vertex_io_array_size_query"
																									  : DE_NULL,
																									    "");
				ioTypeGroup->addChild(vertexArraySizeGroup);

				for (int primitiveTypeI = 0; primitiveTypeI < TESSPRIMITIVETYPE_LAST; primitiveTypeI++)
				{
					const TessPrimitiveType primitiveType = (TessPrimitiveType)primitiveTypeI;
					vertexArraySizeGroup->addChild(new UserDefinedIOCase(m_context, getTessPrimitiveTypeShaderName(primitiveType), "", primitiveType, ioType, vertexArraySize,
																		 (string() + "data/tessellation/user_defined_io_" + getTessPrimitiveTypeShaderName(primitiveType) + "_ref.png").c_str()));
				}
			}
		}
	}
}

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