/*-------------------------------------------------------------------------
 * 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 "glsShaderLibrary.hpp"
#include "glsStateQueryUtil.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 "gluCallLogWrapper.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
{

using namespace gls::StateQueryUtil;

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;
	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 ?
														"	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"
															"	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);

	{
		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:
	void init (void)
	{
		checkExtensionSupport(m_context, "GL_EXT_gpu_shader5");
		BasicVariousTessLevelsPosAttrCase::init();
	}

	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"
													 "#extension GL_EXT_gpu_shader5 : require\n"
													 "\n"
													 + getTessellationEvaluationInLayoutString(primitiveType, spacing) +
													 "\n"
													 "in highp vec2 in_te_position[];\n"
													 "\n"
													 "precise gl_Position;\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_PATCH_BLOCK,
		IO_TYPE_PER_PATCH_BLOCK_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							(void) const = 0;
		virtual string	declareArray					(const string& arraySizeExpr) const = 0;
		virtual string	glslTraverseBasicTypeArray		(int numArrayElements, //!< If negative, traverse just array[gl_InvocationID], not all indices.
														 int indentationDepth,
														 BasicTypeVisitFunc) const = 0;
		virtual string	glslTraverseBasicType			(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								(void) const;
		string	declareArray						(const string& arraySizeExpr) const;
		string	glslTraverseBasicTypeArray			(int numArrayElements, int indentationDepth, BasicTypeVisitFunc) const;
		string	glslTraverseBasicType				(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								(void) const;
		string	declareArray						(const string& arraySizeExpr) const;
		string	glslTraverseBasicTypeArray			(int numArrayElements, int indentationDepth, BasicTypeVisitFunc) const;
		string	glslTraverseBasicType				(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);

	enum
	{
		RENDER_SIZE = 256
	};
	enum
	{
		NUM_OUTPUT_VERTICES = 5
	};
	enum
	{
		NUM_PER_PATCH_ARRAY_ELEMS = 3
	};
	enum
	{
		NUM_PER_PATCH_BLOCKS = 2
	};

	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;
};

/*--------------------------------------------------------------------*//*!
 * \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 (void) const
{
	DE_ASSERT(!m_isArray);
	return de::toString(glu::declare(m_type, m_name)) + ";\n";
}

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

string UserDefinedIOCase::IOBlock::declare (void) const
{
	std::ostringstream buf;

	buf << m_blockName << "\n"
		<< "{\n";

	for (int i = 0; i < (int)m_members.size(); i++)
		buf << "\t" << glu::declare(m_members[i].type, m_members[i].name) << ";\n";

	buf << "} " << m_interfaceName << ";\n";
	return buf.str();
}

string UserDefinedIOCase::IOBlock::declareArray (const string& sizeExpr) const
{
	std::ostringstream buf;

	buf << m_blockName << "\n"
		<< "{\n";

	for (int i = 0; i < (int)m_members.size(); i++)
		buf << "\t" << glu::declare(m_members[i].type, m_members[i].name) << ";\n";

	buf << "} " << m_interfaceName << "[" << sizeExpr << "];\n";
	return buf.str();
}

string UserDefinedIOCase::Variable::glslTraverseBasicTypeArray (int numArrayElements, int indentationDepth, BasicTypeVisitFunc visit) const
{
	DE_ASSERT(m_isArray);

	const bool				traverseAsArray		= numArrayElements >= 0;
	const string			traversedName		= m_name + (!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::Variable::glslTraverseBasicType (int indentationDepth, BasicTypeVisitFunc visit) const
{
	DE_ASSERT(!m_isArray);

	return UserDefinedIOCase::glslTraverseBasicTypes(m_name, m_type, 0, indentationDepth, visit);
}

string UserDefinedIOCase::IOBlock::glslTraverseBasicTypeArray (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;
	}
}


string UserDefinedIOCase::IOBlock::glslTraverseBasicType (int indentationDepth, BasicTypeVisitFunc visit) const
{
	string result;
	for (int i = 0; i < (int)m_members.size(); i++)
		result += UserDefinedIOCase::glslTraverseBasicTypes(m_interfaceName + "." + 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		||
													  m_ioType == IO_TYPE_PER_PATCH_BLOCK		||
													  m_ioType == IO_TYPE_PER_PATCH_BLOCK_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		||
													  m_ioType == IO_TYPE_PER_PATCH_BLOCK		||
													  m_ioType == IO_TYPE_PER_PATCH_BLOCK_ARRAY;

	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);
		bool				usedStruct		= false;

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

		if (useBlock)
		{
			// It is illegal to have a structure containing an array as an output variable
			structType.addMember("z", glu::VarType(highpFloat, 2));
		}

		if (useBlock)
		{
			const bool				useLightweightBlock = (m_ioType == IO_TYPE_PER_PATCH_BLOCK_ARRAY); // use leaner block to make sure it is not larger than allowed (per-patch storage is very limited)
			vector<IOBlock::Member>	blockMembers;

			if (!useLightweightBlock)
				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)));

			usedStruct = true;
		}
		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);

			if (m_ioType != IO_TYPE_PER_PATCH_ARRAY)
			{
				// Arrays of structures are disallowed, add struct cases only if not arrayed variable
				m_tcsOutputs.push_back	(SharedPtr<TopLevelObject>(new Variable(var0)));
				m_tesInputs.push_back	(SharedPtr<TopLevelObject>(new Variable(var0)));

				usedStruct = true;
			}

			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).declareArray(vertexAttrArrayInputSize);

		if (usedStruct)
			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];
			const int				numElements	= !isPerPatchIO								? -1	//!< \note -1 means indexing with gl_InstanceID
												: m_ioType == IO_TYPE_PER_PATCH				? 1
												: m_ioType == IO_TYPE_PER_PATCH_ARRAY		? NUM_PER_PATCH_ARRAY_ELEMS
												: m_ioType == IO_TYPE_PER_PATCH_BLOCK		? 1
												: m_ioType == IO_TYPE_PER_PATCH_BLOCK_ARRAY	? NUM_PER_PATCH_BLOCKS
												: -2;
			const bool				isArray		= (numElements != 1);

			DE_ASSERT(numElements != -2);

			if (isArray)
				tcsDeclarations += outMaybePatch + output.declareArray(m_ioType == IO_TYPE_PER_PATCH_ARRAY			? de::toString(int(NUM_PER_PATCH_ARRAY_ELEMS))
																	   : m_ioType == IO_TYPE_PER_PATCH_BLOCK_ARRAY	? de::toString(int(NUM_PER_PATCH_BLOCKS))
																	   : isExplicitVertexArraySize					? de::toString(int(NUM_OUTPUT_VERTICES))
																	   : "");
			else
				tcsDeclarations += outMaybePatch + output.declare();

			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";
			if (isArray)
				tcsStatements += output.glslTraverseBasicTypeArray(numElements, 2, glslAssignBasicTypeObject);
			else
				tcsStatements += output.glslTraverseBasicType(2, glslAssignBasicTypeObject);

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

		if (usedStruct)
			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];
			const int				numElements	= !isPerPatchIO								? (int)NUM_OUTPUT_VERTICES
												: m_ioType == IO_TYPE_PER_PATCH				? 1
												: m_ioType == IO_TYPE_PER_PATCH_BLOCK		? 1
												: m_ioType == IO_TYPE_PER_PATCH_ARRAY		? NUM_PER_PATCH_ARRAY_ELEMS
												: m_ioType == IO_TYPE_PER_PATCH_BLOCK_ARRAY	? NUM_PER_PATCH_BLOCKS
												: -2;
			const bool				isArray		= (numElements != 1);

			DE_ASSERT(numElements != -2);

			if (isArray)
				tesDeclarations += inMaybePatch + input.declareArray(m_ioType == IO_TYPE_PER_PATCH_ARRAY			? de::toString(int(NUM_PER_PATCH_ARRAY_ELEMS))
																	 : m_ioType == IO_TYPE_PER_PATCH_BLOCK_ARRAY	? de::toString(int(NUM_PER_PATCH_BLOCKS))
																	 : isExplicitVertexArraySize					? de::toString(vertexAttrArrayInputSize)
																	 : "");
			else
				tesDeclarations += inMaybePatch + input.declare();

			tesStatements += "\n\t\t// Check values in input " + input.name() + "\n";
			if (isArray)
				tesStatements += input.glslTraverseBasicTypeArray(numElements, 2, glslCheckBasicTypeObject);
			else
				tesStatements += input.glslTraverseBasicType(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(int(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);
	tcu::ResultCollector	result;

	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)
				result.fail("Image comparison failed");
		}

		if ((int)tfResult.varying.size() != numVertices)
		{
			log << TestLog::Message << "Failure: transform feedback returned " << tfResult.varying.size() << " vertices; expected " << numVertices << TestLog::EndMessage;
			result.fail("Wrong number of vertices");
		}
		else
		{
			const int topLevelArraySize		= (m_ioType == IO_TYPE_PER_PATCH				? 1
											 : m_ioType == IO_TYPE_PER_PATCH_ARRAY			? NUM_PER_PATCH_ARRAY_ELEMS
											 : m_ioType == IO_TYPE_PER_PATCH_BLOCK			? 1
											 : m_ioType == IO_TYPE_PER_PATCH_BLOCK_ARRAY	? NUM_PER_PATCH_BLOCKS
											 : (int)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;
					result.fail("Invalid transform feedback output");
				}
				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;
					result.fail("Invalid input value in tessellation evaluation shader");
				}
			}
		}
	}

	result.setTestContextResult(m_testCtx);
	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;
}

class LimitQueryCase : public TestCase
{
public:
						LimitQueryCase	(Context& context, const char* name, const char* desc, glw::GLenum target, int minValue);
private:
	IterateResult		iterate			(void);

	const glw::GLenum	m_target;
	const int			m_minValue;
};

LimitQueryCase::LimitQueryCase (Context& context, const char* name, const char* desc, glw::GLenum target, int minValue)
	: TestCase			(context, name, desc)
	, m_target			(target)
	, m_minValue		(minValue)
{
}

LimitQueryCase::IterateResult LimitQueryCase::iterate (void)
{
	checkTessellationSupport(m_context);

	glu::CallLogWrapper 	gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");

	gl.enableLogging(true);
	verifyStateIntegerMin(result, gl, m_target, m_minValue, QUERY_INTEGER);

	{
		const tcu::ScopedLogSection	section(m_testCtx.getLog(), "Types", "Alternative queries");
		verifyStateIntegerMin(result, gl, m_target, m_minValue, QUERY_BOOLEAN);
		verifyStateIntegerMin(result, gl, m_target, m_minValue, QUERY_INTEGER64);
		verifyStateIntegerMin(result, gl, m_target, m_minValue, QUERY_FLOAT);
	}

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class CombinedUniformLimitCase : public TestCase
{
public:
						CombinedUniformLimitCase	(Context& context, const char* name, const char* desc, glw::GLenum combined, glw::GLenum numBlocks, glw::GLenum defaultComponents);
private:
	IterateResult		iterate						(void);

	const glw::GLenum	m_combined;
	const glw::GLenum	m_numBlocks;
	const glw::GLenum	m_defaultComponents;
};

CombinedUniformLimitCase::CombinedUniformLimitCase (Context& context, const char* name, const char* desc, glw::GLenum combined, glw::GLenum numBlocks, glw::GLenum defaultComponents)
	: TestCase				(context, name, desc)
	, m_combined			(combined)
	, m_numBlocks			(numBlocks)
	, m_defaultComponents	(defaultComponents)
{
}

CombinedUniformLimitCase::IterateResult CombinedUniformLimitCase::iterate (void)
{
	checkTessellationSupport(m_context);

	glu::CallLogWrapper		gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");

	gl.enableLogging(true);

	m_testCtx.getLog()	<< tcu::TestLog::Message
						<< "The minimum value of " << glu::getGettableStateStr(m_combined)
						<< " is " << glu::getGettableStateStr(m_numBlocks)
						<< " x MAX_UNIFORM_BLOCK_SIZE / 4 + "
						<< glu::getGettableStateStr(m_defaultComponents)
						<< tcu::TestLog::EndMessage;

	StateQueryMemoryWriteGuard<glw::GLint> maxUniformBlocks;
	gl.glGetIntegerv(m_numBlocks, &maxUniformBlocks);
	GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");

	StateQueryMemoryWriteGuard<glw::GLint> maxUniformBlockSize;
	gl.glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUniformBlockSize);
	GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");

	StateQueryMemoryWriteGuard<glw::GLint> maxUniformComponents;
	gl.glGetIntegerv(m_defaultComponents, &maxUniformComponents);
	GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");

	if (maxUniformBlocks.verifyValidity(result) && maxUniformBlockSize.verifyValidity(result) && maxUniformComponents.verifyValidity(result))
	{
		const int limit = ((int)maxUniformBlocks) * ((int)maxUniformBlockSize) / 4 + (int)maxUniformComponents;
		verifyStateIntegerMin(result, gl, m_combined, limit, QUERY_INTEGER);

		{
			const tcu::ScopedLogSection	section(m_testCtx.getLog(), "Types", "Alternative queries");
			verifyStateIntegerMin(result, gl, m_combined, limit, QUERY_BOOLEAN);
			verifyStateIntegerMin(result, gl, m_combined, limit, QUERY_INTEGER64);
			verifyStateIntegerMin(result, gl, m_combined, limit, QUERY_FLOAT);
		}
	}

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class PatchVerticesStateCase : public TestCase
{
public:
						PatchVerticesStateCase	(Context& context, const char* name, const char* desc);
private:
	IterateResult		iterate					(void);
};

PatchVerticesStateCase::PatchVerticesStateCase (Context& context, const char* name, const char* desc)
	: TestCase(context, name, desc)
{
}

PatchVerticesStateCase::IterateResult PatchVerticesStateCase::iterate (void)
{
	checkTessellationSupport(m_context);

	glu::CallLogWrapper 	gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");

	gl.enableLogging(true);

	// initial
	{
		const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial value");

		verifyStateInteger(result, gl, GL_PATCH_VERTICES, 3, QUERY_INTEGER);
	}

	// bind
	{
		const tcu::ScopedLogSection section(m_testCtx.getLog(), "set", "After set");

		gl.glPatchParameteri(GL_PATCH_VERTICES, 22);
		GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glPatchParameteri");

		verifyStateInteger(result, gl, GL_PATCH_VERTICES, 22, QUERY_INTEGER);
		{
			const tcu::ScopedLogSection	subsection(m_testCtx.getLog(), "Types", "Alternative queries");
			verifyStateIntegerMin(result, gl, GL_PATCH_VERTICES, 22, QUERY_BOOLEAN);
			verifyStateIntegerMin(result, gl, GL_PATCH_VERTICES, 22, QUERY_INTEGER64);
			verifyStateIntegerMin(result, gl, GL_PATCH_VERTICES, 22, QUERY_FLOAT);
		}
	}

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class PrimitiveRestartForPatchesSupportedCase : public TestCase
{
public:
						PrimitiveRestartForPatchesSupportedCase	(Context& context, const char* name, const char* desc);
private:
	IterateResult		iterate									(void);
};

PrimitiveRestartForPatchesSupportedCase::PrimitiveRestartForPatchesSupportedCase (Context& context, const char* name, const char* desc)
	: TestCase(context, name, desc)
{
}

PrimitiveRestartForPatchesSupportedCase::IterateResult PrimitiveRestartForPatchesSupportedCase::iterate (void)
{
	checkTessellationSupport(m_context);

	glu::CallLogWrapper 	gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");
	QueriedState			state;

	gl.enableLogging(true);

	queryState(result, gl, QUERY_BOOLEAN, GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED, state);

	if (!state.isUndefined())
	{
		const tcu::ScopedLogSection	subsection(m_testCtx.getLog(), "Types", "Alternative types");
		verifyStateBoolean(result, gl, GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED, state.getBoolAccess(), QUERY_INTEGER);
		verifyStateBoolean(result, gl, GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED, state.getBoolAccess(), QUERY_INTEGER64);
		verifyStateBoolean(result, gl, GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED, state.getBoolAccess(), QUERY_FLOAT);
	}

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class TessProgramQueryCase : public TestCase
{
public:
						TessProgramQueryCase	(Context& context, const char* name, const char* desc);

	std::string			getVertexSource			(void) const;
	std::string			getFragmentSource		(void) const;
	std::string			getTessCtrlSource		(const char* globalLayouts) const;
	std::string			getTessEvalSource		(const char* globalLayouts) const;
};

TessProgramQueryCase::TessProgramQueryCase (Context& context, const char* name, const char* desc)
	: TestCase(context, name, desc)
{
}

std::string TessProgramQueryCase::getVertexSource (void) const
{
	return	"#version 310 es\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = vec4(float(gl_VertexID), float(gl_VertexID / 2), 0.0, 1.0);\n"
			"}\n";
}

std::string TessProgramQueryCase::getFragmentSource (void) const
{
	return	"#version 310 es\n"
			"layout (location = 0) out mediump vec4 o_color;\n"
			"void main (void)\n"
			"{\n"
			"	o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
			"}\n";
}

std::string TessProgramQueryCase::getTessCtrlSource (const char* globalLayouts) const
{
	return	"#version 310 es\n"
			"#extension GL_EXT_tessellation_shader : require\n"
			+ std::string(globalLayouts) + ";\n"
			"void main (void)\n"
			"{\n"
			"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
			"	gl_TessLevelInner[0] = 2.8;\n"
			"	gl_TessLevelInner[1] = 2.8;\n"
			"	gl_TessLevelOuter[0] = 2.8;\n"
			"	gl_TessLevelOuter[1] = 2.8;\n"
			"	gl_TessLevelOuter[2] = 2.8;\n"
			"	gl_TessLevelOuter[3] = 2.8;\n"
			"}\n";
}

std::string TessProgramQueryCase::getTessEvalSource (const char* globalLayouts) const
{
	return	"#version 310 es\n"
			"#extension GL_EXT_tessellation_shader : require\n"
			+ std::string(globalLayouts) + ";\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = gl_TessCoord.x * gl_in[0].gl_Position\n"
			"	            + gl_TessCoord.y * gl_in[1].gl_Position\n"
			"	            + gl_TessCoord.y * gl_in[2].gl_Position\n"
			"	            + gl_TessCoord.z * gl_in[3].gl_Position;\n"
			"}\n";
}

class TessControlOutputVerticesCase : public TessProgramQueryCase
{
public:
						TessControlOutputVerticesCase	(Context& context, const char* name, const char* desc);
private:
	IterateResult		iterate							(void);
};

TessControlOutputVerticesCase::TessControlOutputVerticesCase (Context& context, const char* name, const char* desc)
	: TessProgramQueryCase(context, name, desc)
{
}

TessControlOutputVerticesCase::IterateResult TessControlOutputVerticesCase::iterate (void)
{
	checkTessellationSupport(m_context);

	glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources()
																<< glu::VertexSource(getVertexSource())
																<< glu::FragmentSource(getFragmentSource())
																<< glu::TessellationControlSource(getTessCtrlSource("layout(vertices=4) out"))
																<< glu::TessellationEvaluationSource(getTessEvalSource("layout(triangles) in")));

	m_testCtx.getLog() << program;
	if (!program.isOk())
		throw tcu::TestError("failed to build program");

	{
		glu::CallLogWrapper 	gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
		tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");

		gl.enableLogging(true);
		verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_CONTROL_OUTPUT_VERTICES, 4, QUERY_PROGRAM_INTEGER);

		result.setTestContextResult(m_testCtx);
	}
	return STOP;
}

class TessGenModeQueryCase : public TessProgramQueryCase
{
public:
						TessGenModeQueryCase	(Context& context, const char* name, const char* desc);
private:
	IterateResult		iterate					(void);
};

TessGenModeQueryCase::TessGenModeQueryCase (Context& context, const char* name, const char* desc)
	: TessProgramQueryCase(context, name, desc)
{
}

TessGenModeQueryCase::IterateResult TessGenModeQueryCase::iterate (void)
{
	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");
	glu::CallLogWrapper		gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());

	static const struct
	{
		const char* description;
		const char* layout;
		glw::GLenum mode;
	} s_modes[] =
	{
		{ "Triangles",	"layout(triangles) in",	GL_TRIANGLES	},
		{ "Isolines",	"layout(isolines) in",	GL_ISOLINES		},
		{ "Quads",		"layout(quads) in",		GL_QUADS		},
	};

	checkTessellationSupport(m_context);
	gl.enableLogging(true);

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_modes); ++ndx)
	{
		const tcu::ScopedLogSection	section(m_testCtx.getLog(), "Type", s_modes[ndx].description);

		glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources()
																	<< glu::VertexSource(getVertexSource())
																	<< glu::FragmentSource(getFragmentSource())
																	<< glu::TessellationControlSource(getTessCtrlSource("layout(vertices=6) out"))
																	<< glu::TessellationEvaluationSource(getTessEvalSource(s_modes[ndx].layout)));

		m_testCtx.getLog() << program;
		if (!program.isOk())
			result.fail("failed to build program");
		else
			verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_MODE, s_modes[ndx].mode, QUERY_PROGRAM_INTEGER);
	}

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class TessGenSpacingQueryCase : public TessProgramQueryCase
{
public:
						TessGenSpacingQueryCase	(Context& context, const char* name, const char* desc);
private:
	IterateResult		iterate					(void);
};

TessGenSpacingQueryCase::TessGenSpacingQueryCase (Context& context, const char* name, const char* desc)
	: TessProgramQueryCase(context, name, desc)
{
}

TessGenSpacingQueryCase::IterateResult TessGenSpacingQueryCase::iterate (void)
{
	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");
	glu::CallLogWrapper		gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());

	static const struct
	{
		const char* description;
		const char* layout;
		glw::GLenum spacing;
	} s_modes[] =
	{
		{ "Default spacing",			"layout(triangles) in",								GL_EQUAL			},
		{ "Equal spacing",				"layout(triangles, equal_spacing) in",				GL_EQUAL			},
		{ "Fractional even spacing",	"layout(triangles, fractional_even_spacing) in",	GL_FRACTIONAL_EVEN	},
		{ "Fractional odd spacing",		"layout(triangles, fractional_odd_spacing) in",		GL_FRACTIONAL_ODD	},
	};

	checkTessellationSupport(m_context);
	gl.enableLogging(true);

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_modes); ++ndx)
	{
		const tcu::ScopedLogSection	section(m_testCtx.getLog(), "Type", s_modes[ndx].description);

		glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources()
																	<< glu::VertexSource(getVertexSource())
																	<< glu::FragmentSource(getFragmentSource())
																	<< glu::TessellationControlSource(getTessCtrlSource("layout(vertices=6) out"))
																	<< glu::TessellationEvaluationSource(getTessEvalSource(s_modes[ndx].layout)));

		m_testCtx.getLog() << program;
		if (!program.isOk())
			result.fail("failed to build program");
		else
			verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_SPACING, s_modes[ndx].spacing, QUERY_PROGRAM_INTEGER);
	}

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class TessGenVertexOrderQueryCase : public TessProgramQueryCase
{
public:
						TessGenVertexOrderQueryCase	(Context& context, const char* name, const char* desc);
private:
	IterateResult		iterate						(void);
};

TessGenVertexOrderQueryCase::TessGenVertexOrderQueryCase (Context& context, const char* name, const char* desc)
	: TessProgramQueryCase(context, name, desc)
{
}

TessGenVertexOrderQueryCase::IterateResult TessGenVertexOrderQueryCase::iterate (void)
{
	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");
	glu::CallLogWrapper		gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());

	static const struct
	{
		const char* description;
		const char* layout;
		glw::GLenum order;
	} s_modes[] =
	{
		{ "Default order",	"layout(triangles) in",			GL_CCW	},
		{ "CW order",		"layout(triangles, cw) in",		GL_CW	},
		{ "CCW order",		"layout(triangles, ccw) in",	GL_CCW	},
	};

	checkTessellationSupport(m_context);
	gl.enableLogging(true);

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_modes); ++ndx)
	{
		const tcu::ScopedLogSection	section(m_testCtx.getLog(), "Type", s_modes[ndx].description);

		glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources()
																	<< glu::VertexSource(getVertexSource())
																	<< glu::FragmentSource(getFragmentSource())
																	<< glu::TessellationControlSource(getTessCtrlSource("layout(vertices=6) out"))
																	<< glu::TessellationEvaluationSource(getTessEvalSource(s_modes[ndx].layout)));

		m_testCtx.getLog() << program;
		if (!program.isOk())
			result.fail("failed to build program");
		else
			verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_VERTEX_ORDER, s_modes[ndx].order, QUERY_PROGRAM_INTEGER);
	}

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class TessGenPointModeQueryCase : public TessProgramQueryCase
{
public:
						TessGenPointModeQueryCase	(Context& context, const char* name, const char* desc);
private:
	IterateResult		iterate						(void);
};

TessGenPointModeQueryCase::TessGenPointModeQueryCase (Context& context, const char* name, const char* desc)
	: TessProgramQueryCase(context, name, desc)
{
}

TessGenPointModeQueryCase::IterateResult TessGenPointModeQueryCase::iterate (void)
{
	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");
	glu::CallLogWrapper		gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());

	static const struct
	{
		const char* description;
		const char* layout;
		glw::GLenum mode;
	} s_modes[] =
	{
		{ "Default mode",	"layout(triangles) in",			GL_FALSE	},
		{ "Point mode",		"layout(triangles, point_mode) in",		GL_TRUE		},
	};

	checkTessellationSupport(m_context);
	gl.enableLogging(true);

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_modes); ++ndx)
	{
		const tcu::ScopedLogSection	section(m_testCtx.getLog(), "Type", s_modes[ndx].description);

		glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources()
																	<< glu::VertexSource(getVertexSource())
																	<< glu::FragmentSource(getFragmentSource())
																	<< glu::TessellationControlSource(getTessCtrlSource("layout(vertices=6) out"))
																	<< glu::TessellationEvaluationSource(getTessEvalSource(s_modes[ndx].layout)));

		m_testCtx.getLog() << program;
		if (!program.isOk())
			result.fail("failed to build program");
		else
			verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_POINT_MODE, s_modes[ndx].mode, QUERY_PROGRAM_INTEGER);
	}

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class ReferencedByTessellationQueryCase : public TestCase
{
public:
					ReferencedByTessellationQueryCase	(Context& context, const char* name, const char* desc, bool isCtrlCase);
private:
	void			init								(void);
	IterateResult	iterate								(void);

	std::string		getVertexSource						(void) const;
	std::string		getFragmentSource					(void) const;
	std::string		getTessCtrlSource					(void) const;
	std::string		getTessEvalSource					(void) const;

	const bool		m_isCtrlCase;
};

ReferencedByTessellationQueryCase::ReferencedByTessellationQueryCase (Context& context, const char* name, const char* desc, bool isCtrlCase)
	: TestCase		(context, name, desc)
	, m_isCtrlCase	(isCtrlCase)
{
}

void ReferencedByTessellationQueryCase::init (void)
{
	checkTessellationSupport(m_context);
}

ReferencedByTessellationQueryCase::IterateResult ReferencedByTessellationQueryCase::iterate (void)
{
	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");
	glu::CallLogWrapper		gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	glu::ShaderProgram		program	(m_context.getRenderContext(), glu::ProgramSources()
																	<< glu::VertexSource(getVertexSource())
																	<< glu::FragmentSource(getFragmentSource())
																	<< glu::TessellationControlSource(getTessCtrlSource())
																	<< glu::TessellationEvaluationSource(getTessEvalSource()));

	gl.enableLogging(true);

	m_testCtx.getLog() << program;
	if (!program.isOk())
		result.fail("failed to build program");
	else
	{
		const deUint32 props[1] = { (deUint32)((m_isCtrlCase) ? (GL_REFERENCED_BY_TESS_CONTROL_SHADER) : (GL_REFERENCED_BY_TESS_EVALUATION_SHADER)) };

		{
			const tcu::ScopedLogSection section		(m_testCtx.getLog(), "UnreferencedUniform", "Unreferenced uniform u_unreferenced");
			deUint32					resourcePos;
			glw::GLsizei				length		= 0;
			glw::GLint					referenced	= 0;

			resourcePos = gl.glGetProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_unreferenced");
			m_testCtx.getLog() << tcu::TestLog::Message << "u_unreferenced resource index: " << resourcePos << tcu::TestLog::EndMessage;

			if (resourcePos == GL_INVALID_INDEX)
				result.fail("resourcePos was GL_INVALID_INDEX");
			else
			{
				gl.glGetProgramResourceiv(program.getProgram(), GL_UNIFORM, resourcePos, 1, props, 1, &length, &referenced);
				m_testCtx.getLog()
					<< tcu::TestLog::Message
					<< "Query " << glu::getProgramResourcePropertyStr(props[0])
					<< ", got " << length << " value(s), value[0] = " << glu::getBooleanStr(referenced)
					<< tcu::TestLog::EndMessage;

				GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "query resource");

				if (length == 0 || referenced != GL_FALSE)
					result.fail("expected GL_FALSE");
			}
		}

		{
			const tcu::ScopedLogSection section		(m_testCtx.getLog(), "ReferencedUniform", "Referenced uniform u_referenced");
			deUint32					resourcePos;
			glw::GLsizei				length		= 0;
			glw::GLint					referenced	= 0;

			resourcePos = gl.glGetProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_referenced");
			m_testCtx.getLog() << tcu::TestLog::Message << "u_referenced resource index: " << resourcePos << tcu::TestLog::EndMessage;

			if (resourcePos == GL_INVALID_INDEX)
				result.fail("resourcePos was GL_INVALID_INDEX");
			else
			{
				gl.glGetProgramResourceiv(program.getProgram(), GL_UNIFORM, resourcePos, 1, props, 1, &length, &referenced);
				m_testCtx.getLog()
					<< tcu::TestLog::Message
					<< "Query " << glu::getProgramResourcePropertyStr(props[0])
					<< ", got " << length << " value(s), value[0] = " << glu::getBooleanStr(referenced)
					<< tcu::TestLog::EndMessage;

				GLU_EXPECT_NO_ERROR(gl.glGetError(), "query resource");

				if (length == 0 || referenced != GL_TRUE)
					result.fail("expected GL_TRUE");
			}
		}
	}

	result.setTestContextResult(m_testCtx);
	return STOP;
}

std::string ReferencedByTessellationQueryCase::getVertexSource (void) const
{
	return	"#version 310 es\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = vec4(float(gl_VertexID), float(gl_VertexID / 2), 0.0, 1.0);\n"
			"}\n";
}

std::string ReferencedByTessellationQueryCase::getFragmentSource (void) const
{
	return	"#version 310 es\n"
			"layout (location = 0) out mediump vec4 o_color;\n"
			"void main (void)\n"
			"{\n"
			"	o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
			"}\n";
}

std::string ReferencedByTessellationQueryCase::getTessCtrlSource (void) const
{
	std::ostringstream buf;
	buf <<	"#version 310 es\n"
			"#extension GL_EXT_tessellation_shader : require\n"
			"layout(vertices = 3) out;\n"
			"uniform highp vec4 " << ((m_isCtrlCase) ? ("u_referenced") : ("u_unreferenced")) << ";\n"
			"void main (void)\n"
			"{\n"
			"	vec4 offset = " << ((m_isCtrlCase) ? ("u_referenced") : ("u_unreferenced")) << ";\n"
			"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position + offset;\n"
			"	gl_TessLevelInner[0] = 2.8;\n"
			"	gl_TessLevelInner[1] = 2.8;\n"
			"	gl_TessLevelOuter[0] = 2.8;\n"
			"	gl_TessLevelOuter[1] = 2.8;\n"
			"	gl_TessLevelOuter[2] = 2.8;\n"
			"	gl_TessLevelOuter[3] = 2.8;\n"
			"}\n";
	return buf.str();
}

std::string ReferencedByTessellationQueryCase::getTessEvalSource (void) const
{
	std::ostringstream buf;
	buf <<	"#version 310 es\n"
			"#extension GL_EXT_tessellation_shader : require\n"
			"layout(triangles) in;\n"
			"uniform highp vec4 " << ((m_isCtrlCase) ? ("u_unreferenced") : ("u_referenced")) << ";\n"
			"void main (void)\n"
			"{\n"
			"	vec4 offset = " << ((m_isCtrlCase) ? ("u_unreferenced") : ("u_referenced")) << ";\n"
			"	gl_Position = gl_TessCoord.x * gl_in[0].gl_Position\n"
			"	            + gl_TessCoord.y * gl_in[1].gl_Position\n"
			"	            + gl_TessCoord.z * gl_in[2].gl_Position\n"
			"	            + offset;\n"
			"}\n";

	return buf.str();
}

class IsPerPatchQueryCase : public TestCase
{
public:
					IsPerPatchQueryCase		(Context& context, const char* name, const char* desc);
private:
	void			init					(void);
	IterateResult	iterate					(void);
};

IsPerPatchQueryCase::IsPerPatchQueryCase (Context& context, const char* name, const char* desc)
	: TestCase(context, name, desc)
{
}

void IsPerPatchQueryCase::init (void)
{
	checkTessellationSupport(m_context);
}

IsPerPatchQueryCase::IterateResult IsPerPatchQueryCase::iterate (void)
{
	static const char* const s_controlSource =	"#version 310 es\n"
												"#extension GL_EXT_tessellation_shader : require\n"
												"layout(vertices = 3) out;\n"
												"patch out highp vec4 v_perPatch;\n"
												"out highp vec4 v_perVertex[];\n"
												"void main (void)\n"
												"{\n"
												"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
												"	v_perPatch = gl_in[0].gl_Position;\n"
												"	v_perVertex[gl_InvocationID] = -gl_in[gl_InvocationID].gl_Position;\n"
												"	gl_TessLevelInner[0] = 2.8;\n"
												"	gl_TessLevelInner[1] = 2.8;\n"
												"	gl_TessLevelOuter[0] = 2.8;\n"
												"	gl_TessLevelOuter[1] = 2.8;\n"
												"	gl_TessLevelOuter[2] = 2.8;\n"
												"	gl_TessLevelOuter[3] = 2.8;\n"
												"}\n";
	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");
	glu::CallLogWrapper		gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	glu::ShaderProgram		program	(m_context.getRenderContext(), glu::ProgramSources()
																	<< glu::TessellationControlSource(s_controlSource)
																	<< glu::ProgramSeparable(true));

	gl.enableLogging(true);

	m_testCtx.getLog() << program;
	if (!program.isOk())
		result.fail("failed to build program");
	else
	{
		const deUint32 props[1] = { GL_IS_PER_PATCH };

		{
			const tcu::ScopedLogSection section		(m_testCtx.getLog(), "PerPatchOutput", "Per patch v_perPatch");
			deUint32					resourcePos;
			glw::GLsizei				length		= 0;
			glw::GLint					referenced	= 0;

			resourcePos = gl.glGetProgramResourceIndex(program.getProgram(), GL_PROGRAM_OUTPUT, "v_perPatch");
			m_testCtx.getLog() << tcu::TestLog::Message << "v_perPatch resource index: " << resourcePos << tcu::TestLog::EndMessage;

			if (resourcePos == GL_INVALID_INDEX)
				result.fail("resourcePos was GL_INVALID_INDEX");
			else
			{
				gl.glGetProgramResourceiv(program.getProgram(), GL_PROGRAM_OUTPUT, resourcePos, 1, props, 1, &length, &referenced);
				m_testCtx.getLog()
					<< tcu::TestLog::Message
					<< "Query " << glu::getProgramResourcePropertyStr(props[0])
					<< ", got " << length << " value(s), value[0] = " << glu::getBooleanStr(referenced)
					<< tcu::TestLog::EndMessage;

				GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "query resource");

				if (length == 0 || referenced != GL_TRUE)
					result.fail("expected GL_TRUE");
			}
		}

		{
			const tcu::ScopedLogSection section		(m_testCtx.getLog(), "PerVertexhOutput", "Per vertex v_perVertex");
			deUint32					resourcePos;
			glw::GLsizei				length		= 0;
			glw::GLint					referenced	= 0;

			resourcePos = gl.glGetProgramResourceIndex(program.getProgram(), GL_PROGRAM_OUTPUT, "v_perVertex");
			m_testCtx.getLog() << tcu::TestLog::Message << "v_perVertex resource index: " << resourcePos << tcu::TestLog::EndMessage;

			if (resourcePos == GL_INVALID_INDEX)
				result.fail("resourcePos was GL_INVALID_INDEX");
			else
			{
				gl.glGetProgramResourceiv(program.getProgram(), GL_PROGRAM_OUTPUT, resourcePos, 1, props, 1, &length, &referenced);
				m_testCtx.getLog()
					<< tcu::TestLog::Message
					<< "Query " << glu::getProgramResourcePropertyStr(props[0])
					<< ", got " << length << " value(s), value[0] = " << glu::getBooleanStr(referenced)
					<< tcu::TestLog::EndMessage;

				GLU_EXPECT_NO_ERROR(gl.glGetError(), "query resource");

				if (length == 0 || referenced != GL_FALSE)
					result.fail("expected GL_FALSE");
			}
		}
	}

	result.setTestContextResult(m_testCtx);
	return STOP;
}

} // anonymous

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

TessellationTests::~TessellationTests (void)
{
}

void TessellationTests::init (void)
{
	{
		tcu::TestCaseGroup* const queryGroup = new tcu::TestCaseGroup(m_testCtx, "state_query", "Query tests");
		addChild(queryGroup);

		// new limits
		queryGroup->addChild(new LimitQueryCase(m_context, "max_patch_vertices",								"Test MAX_PATCH_VERTICES",								GL_MAX_PATCH_VERTICES,							32));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_gen_level",								"Test MAX_TESS_GEN_LEVEL",								GL_MAX_TESS_GEN_LEVEL,							64));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_uniform_components",				"Test MAX_TESS_CONTROL_UNIFORM_COMPONENTS",				GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS,			1024));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_uniform_components",			"Test MAX_TESS_EVALUATION_UNIFORM_COMPONENTS",			GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS,		1024));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_texture_image_units",				"Test MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS",			GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS,		16));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_texture_image_units",			"Test MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS",			GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS,		16));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_output_components",				"Test MAX_TESS_CONTROL_OUTPUT_COMPONENTS",				GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS,			128));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_patch_components",							"Test MAX_TESS_PATCH_COMPONENTS",						GL_MAX_TESS_PATCH_COMPONENTS,					120));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_total_output_components",			"Test MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS",		GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS,	4096));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_output_components",				"Test MAX_TESS_EVALUATION_OUTPUT_COMPONENTS",			GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS,		128));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_uniform_blocks",					"Test MAX_TESS_CONTROL_UNIFORM_BLOCKS",					GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS,				12));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_uniform_blocks",				"Test MAX_TESS_EVALUATION_UNIFORM_BLOCKS",				GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS,			12));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_input_components",					"Test MAX_TESS_CONTROL_INPUT_COMPONENTS",				GL_MAX_TESS_CONTROL_INPUT_COMPONENTS,			128));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_input_components",				"Test MAX_TESS_EVALUATION_INPUT_COMPONENTS",			GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS,		128));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_atomic_counter_buffers",			"Test MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS",			GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS,		0));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_atomic_counter_buffers",		"Test MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS",		GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS,	0));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_atomic_counters",					"Test MAX_TESS_CONTROL_ATOMIC_COUNTERS",				GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS,			0));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_atomic_counters",				"Test MAX_TESS_EVALUATION_ATOMIC_COUNTERS",				GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS,			0));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_image_uniforms",					"Test MAX_TESS_CONTROL_IMAGE_UNIFORMS",					GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS,				0));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_image_uniforms",				"Test MAX_TESS_EVALUATION_IMAGE_UNIFORMS",				GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS,			0));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_shader_storage_blocks",			"Test MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS",			GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS,		0));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_shader_storage_blocks",			"Test MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS",		GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS,	0));

		// modified limits
		queryGroup->addChild(new LimitQueryCase(m_context, "max_uniform_buffer_bindings",						"Test MAX_UNIFORM_BUFFER_BINDINGS",						GL_MAX_UNIFORM_BUFFER_BINDINGS,					72));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_combined_uniform_blocks",						"Test MAX_COMBINED_UNIFORM_BLOCKS",						GL_MAX_COMBINED_UNIFORM_BLOCKS,					60));
		queryGroup->addChild(new LimitQueryCase(m_context, "max_combined_texture_image_units",					"Test MAX_COMBINED_TEXTURE_IMAGE_UNITS",				GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,			96));

		// combined limits
		queryGroup->addChild(new CombinedUniformLimitCase(m_context, "max_combined_tess_control_uniform_components",		"Test MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS",	GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS,		GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS,		GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS));
		queryGroup->addChild(new CombinedUniformLimitCase(m_context, "max_combined_tess_evaluation_uniform_components",		"Test MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS",	GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS,		GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS,	GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS));

		// features
		queryGroup->addChild(new PrimitiveRestartForPatchesSupportedCase(m_context, "primitive_restart_for_patches_supported", "Test PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED"));

		// states
		queryGroup->addChild(new PatchVerticesStateCase(m_context, "patch_vertices", "Test PATCH_VERTICES"));

		// program states
		queryGroup->addChild(new TessControlOutputVerticesCase	(m_context, "tess_control_output_vertices",	"Test TESS_CONTROL_OUTPUT_VERTICES"));
		queryGroup->addChild(new TessGenModeQueryCase			(m_context, "tess_gen_mode",				"Test TESS_GEN_MODE"));
		queryGroup->addChild(new TessGenSpacingQueryCase		(m_context, "tess_gen_spacing",				"Test TESS_GEN_SPACING"));
		queryGroup->addChild(new TessGenVertexOrderQueryCase	(m_context, "tess_gen_vertex_order",		"Test TESS_GEN_VERTEX_ORDER"));
		queryGroup->addChild(new TessGenPointModeQueryCase		(m_context, "tess_gen_point_mode",			"Test TESS_GEN_POINT_MODE"));

		// resource queries
		queryGroup->addChild(new ReferencedByTessellationQueryCase	(m_context, "referenced_by_tess_control_shader",	"Test REFERENCED_BY_TESS_CONTROL_SHADER",		true));
		queryGroup->addChild(new ReferencedByTessellationQueryCase	(m_context, "referenced_by_tess_evaluation_shader",	"Test REFERENCED_BY_TESS_EVALUATION_SHADER",	false));
		queryGroup->addChild(new IsPerPatchQueryCase				(m_context, "is_per_patch",							"Test IS_PER_PATCH"));
	}

	{
		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));
					}
				}
			}
		}
	}

	{
		static const struct
		{
			const char*					name;
			const char*					description;
			UserDefinedIOCase::IOType	ioType;
		} ioCases[] =
		{
			{ "per_patch",					"Per-patch TCS outputs",					UserDefinedIOCase::IO_TYPE_PER_PATCH				},
			{ "per_patch_array",			"Per-patch array TCS outputs",				UserDefinedIOCase::IO_TYPE_PER_PATCH_ARRAY			},
			{ "per_patch_block",			"Per-patch TCS outputs in IO block",		UserDefinedIOCase::IO_TYPE_PER_PATCH_BLOCK			},
			{ "per_patch_block_array",		"Per-patch TCS outputs in IO block array",	UserDefinedIOCase::IO_TYPE_PER_PATCH_BLOCK_ARRAY	},
			{ "per_vertex",					"Per-vertex TCS outputs",					UserDefinedIOCase::IO_TYPE_PER_VERTEX				},
			{ "per_vertex_block",			"Per-vertex TCS outputs in IO block",		UserDefinedIOCase::IO_TYPE_PER_VERTEX_BLOCK			},
		};

		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 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(ioCases); ++ndx)
		{
			TestCaseGroup* const ioTypeGroup = new TestCaseGroup(m_context, ioCases[ndx].name, ioCases[ndx].description);
			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, ioCases[ndx].ioType, vertexArraySize,
																		 (string() + "data/tessellation/user_defined_io_" + getTessPrimitiveTypeShaderName(primitiveType) + "_ref.png").c_str()));
				}
			}
		}

		{
			TestCaseGroup* const				negativeGroup	= new TestCaseGroup(m_context, "negative", "Negative cases");
			gls::ShaderLibrary					shaderLibrary	(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo());
			const std::vector<tcu::TestNode*>	children		= shaderLibrary.loadShaderFile("shaders/tessellation_negative_user_defined_io.test");

			userDefinedIOGroup->addChild(negativeGroup);

			for (int i = 0; i < (int)children.size(); i++)
				negativeGroup->addChild(children[i]);
		}
	}
}

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