/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 2.0 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Shader compilation performance tests.
 *//*--------------------------------------------------------------------*/

#include "es2pShaderCompilationCases.hpp"
#include "tcuTestLog.hpp"
#include "tcuVector.hpp"
#include "tcuMatrix.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuPlatform.hpp"
#include "tcuCommandLine.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuCPUWarmup.hpp"
#include "tcuStringTemplate.hpp"
#include "gluTexture.hpp"
#include "gluPixelTransfer.hpp"
#include "gluRenderContext.hpp"
#include "deStringUtil.hpp"
#include "deRandom.hpp"
#include "deClock.h"
#include "deMath.h"

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

#include <map>
#include <algorithm>
#include <limits>
#include <iomanip>

using tcu::TestLog;
using tcu::Vec3;
using tcu::Vec4;
using tcu::Mat3;
using tcu::Mat4;
using std::string;
using std::vector;
using namespace glw; // GL types

namespace deqp
{

namespace gles2
{

namespace Performance
{

static const bool	WARMUP_CPU_AT_BEGINNING_OF_CASE					= false;
static const bool	WARMUP_CPU_BEFORE_EACH_MEASUREMENT				= true;

static const int	MAX_VIEWPORT_WIDTH								= 64;
static const int	MAX_VIEWPORT_HEIGHT								= 64;

static const int	DEFAULT_MINIMUM_MEASUREMENT_COUNT				= 15;
static const float	RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD	= 0.05f;

// Texture size for the light shader and texture lookup shader cases.
static const int	TEXTURE_WIDTH									= 64;
static const int	TEXTURE_HEIGHT									= 64;

template <typename T>
inline string toStringWithPadding (T value, int minLength)
{
	std::ostringstream s;
	s << std::setfill('0') << std::setw(minLength) << value;
	return s.str();
}

// Add some whitespace and comments to str. They should depend on uniqueNumber.
static string strWithWhiteSpaceAndComments (const string& str, deUint32 uniqueNumber)
{
	string res("");

	// Find the first newline.
	int firstLineEndNdx = 0;
	while (firstLineEndNdx < (int)str.size() && str[firstLineEndNdx] != '\n')
	{
		res += str[firstLineEndNdx];
		firstLineEndNdx++;
	}
	res += '\n';
	DE_ASSERT(firstLineEndNdx < (int)str.size());

	// Add the whitespaces and comments just after the first line.

	de::Random		rnd		(uniqueNumber);
	int				numWS	= rnd.getInt(10, 20);

	for (int i = 0; i < numWS; i++)
		res += " \t\n"[rnd.getInt(0, 2)];

	res += "/* unique comment " + de::toString(uniqueNumber) + " */\n";
	res += "// unique comment " + de::toString(uniqueNumber) + "\n";

	for (int i = 0; i < numWS; i++)
		res += " \t\n"[rnd.getInt(0, 2)];

	// Add the rest of the string.
	res.append(&str.c_str()[firstLineEndNdx + 1]);

	return res;
}

//! Helper for computing relative magnitudes while avoiding division by zero.
static float hackySafeRelativeResult (float x, float y)
{
	// \note A possible case is that x is standard deviation, and y is average
	//		 (or similarly for median or some such). So, if y is 0, that
	//		 probably means that x is also 0(ish) (because in practice we're
	//		 dealing with non-negative values, in which case an average of 0
	//		 implies that the samples are all 0 - note that the same isn't
	//		 strictly true for things like median) so a relative result of 0
	//		 wouldn't be that far from the truth.
	return y == 0.0f ? 0.0f : x/y;
}

template <typename T>
static float vectorFloatAverage (const vector<T>& v)
{
	DE_ASSERT(!v.empty());
	float result = 0.0f;
	for (int i = 0; i < (int)v.size(); i++)
		result += (float)v[i];
	return result / (float)v.size();
}

template <typename T>
static float vectorFloatMedian (const vector<T>& v)
{
	DE_ASSERT(!v.empty());
	vector<T> temp = v;
	std::sort(temp.begin(), temp.end());
	return temp.size() % 2 == 0
		   ? 0.5f * ((float)temp[temp.size()/2-1] + (float)temp[temp.size()/2])
		   : (float)temp[temp.size()/2];
}

template <typename T>
static float vectorFloatMinimum (const vector<T>& v)
{
	DE_ASSERT(!v.empty());
	return (float)*std::min_element(v.begin(), v.end());
}

template <typename T>
static float vectorFloatMaximum (const vector<T>& v)
{
	DE_ASSERT(!v.empty());
	return (float)*std::max_element(v.begin(), v.end());
}

template <typename T>
static float vectorFloatStandardDeviation (const vector<T>& v)
{
	float average	= vectorFloatAverage(v);
	float result	= 0.0f;
	for (int i = 0; i < (int)v.size(); i++)
	{
		float d = (float)v[i] - average;
		result += d*d;
	}
	return deFloatSqrt(result/(float)v.size());
}

template <typename T>
static float vectorFloatRelativeStandardDeviation (const vector<T>& v)
{
	return hackySafeRelativeResult(vectorFloatStandardDeviation(v), vectorFloatAverage(v));
}

template <typename T>
static float vectorFloatMedianAbsoluteDeviation (const vector<T>& v)
{
	float			median				= vectorFloatMedian(v);
	vector<float>	absoluteDeviations	(v.size());

	for (int i = 0; i < (int)v.size(); i++)
		absoluteDeviations[i] = deFloatAbs((float)v[i] - median);

	return vectorFloatMedian(absoluteDeviations);
}

template <typename T>
static float vectorFloatRelativeMedianAbsoluteDeviation (const vector<T>& v)
{
	return hackySafeRelativeResult(vectorFloatMedianAbsoluteDeviation(v), vectorFloatMedian(v));
}

template <typename T>
static float vectorFloatMaximumMinusMinimum (const vector<T>& v)
{
	return vectorFloatMaximum(v) - vectorFloatMinimum(v);
}

template <typename T>
static float vectorFloatRelativeMaximumMinusMinimum (const vector<T>& v)
{
	return hackySafeRelativeResult(vectorFloatMaximumMinusMinimum(v), vectorFloatMaximum(v));
}

template <typename T>
static vector<T> vectorLowestPercentage (const vector<T>& v, float factor)
{
	DE_ASSERT(0.0f < factor && factor <= 1.0f);

	int			targetSize	= (int)(deFloatCeil(factor*(float)v.size()));
	vector<T>	temp		= v;
	std::sort(temp.begin(), temp.end());

	while ((int)temp.size() > targetSize)
		temp.pop_back();

	return temp;
}

template <typename T>
static float vectorFloatFirstQuartile (const vector<T>& v)
{
	return vectorFloatMedian(vectorLowestPercentage(v, 0.5f));
}

// Helper function for combining 4 tcu::Vec4's into one tcu::Vector<float, 16>.
static tcu::Vector<float, 16> combineVec4ToVec16 (const Vec4& a0, const Vec4& a1, const Vec4& a2, const Vec4& a3)
{
	tcu::Vector<float, 16> result;

	for (int vecNdx = 0; vecNdx < 4; vecNdx++)
	{
		const Vec4& srcVec = vecNdx == 0 ? a0 : vecNdx == 1 ? a1 : vecNdx == 2 ? a2 : a3;
		for (int i = 0; i < 4; i++)
			result[vecNdx*4 + i] = srcVec[i];
	}

	return result;
}

// Helper function for extending an n-sized (n <= 16) vector to a 16-sized vector (padded with zeros).
template <int Size>
static tcu::Vector<float, 16> vecTo16 (const tcu::Vector<float, Size>& vec)
{
	DE_STATIC_ASSERT(Size <= 16);

	tcu::Vector<float, 16> res(0.0f);

	for (int i = 0; i < Size; i++)
		res[i] = vec[i];

	return res;
}

// Helper function for extending an n-sized (n <= 16) array to a 16-sized vector (padded with zeros).
template <int Size>
static tcu::Vector<float, 16> arrTo16 (const tcu::Array<float, Size>& arr)
{
	DE_STATIC_ASSERT(Size <= 16);

	tcu::Vector<float, 16> res(0.0f);

	for(int i = 0; i < Size; i++)
		res[i] = arr[i];

	return res;
}

static string getShaderInfoLog (const glw::Functions& gl, deUint32 shader)
{
	string			result;
	int				infoLogLen = 0;
	vector<char>	infoLogBuf;

	gl.getShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLen);
	infoLogBuf.resize(infoLogLen + 1);
	gl.getShaderInfoLog(shader, infoLogLen + 1, DE_NULL, &infoLogBuf[0]);
	result = &infoLogBuf[0];

	return result;
}

static string getProgramInfoLog (const glw::Functions& gl, deUint32 program)
{
	string			result;
	int				infoLogLen = 0;
	vector<char>	infoLogBuf;

	gl.getProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLen);
	infoLogBuf.resize(infoLogLen + 1);
	gl.getProgramInfoLog(program, infoLogLen + 1, DE_NULL, &infoLogBuf[0]);
	result = &infoLogBuf[0];

	return result;
}

enum LightType
{
	LIGHT_DIRECTIONAL = 0,
	LIGHT_POINT,

	LIGHT_LAST,
};

enum LoopType
{
	LOOP_TYPE_STATIC = 0,
	LOOP_TYPE_UNIFORM,
	LOOP_TYPE_DYNAMIC,

	LOOP_LAST
};

// For texture lookup cases: which texture lookups are inside a conditional statement.
enum ConditionalUsage
{
	CONDITIONAL_USAGE_NONE = 0,		// No conditional statements.
	CONDITIONAL_USAGE_FIRST_HALF,	// First numLookUps/2 lookups are inside a conditional statement.
	CONDITIONAL_USAGE_EVERY_OTHER,	// First, third etc. lookups are inside conditional statements.

	CONDITIONAL_USAGE_LAST
};

enum ConditionalType
{
	CONDITIONAL_TYPE_STATIC = 0,
	CONDITIONAL_TYPE_UNIFORM,
	CONDITIONAL_TYPE_DYNAMIC,

	CONDITIONAL_TYPE_LAST
};

// For the invalid shader compilation tests; what kind of invalidity a shader shall contain.
enum ShaderValidity
{
	SHADER_VALIDITY_VALID = 0,
	SHADER_VALIDITY_INVALID_CHAR,
	SHADER_VALIDITY_SEMANTIC_ERROR,

	SHADER_VALIDITY_LAST
};

class ShaderCompilerCase : public TestCase
{
public:
	struct AttribSpec
	{
		string					name;
		tcu::Vector<float, 16>	value;

		AttribSpec (const string& n, const tcu::Vector<float, 16>& v) : name(n), value(v) {}
	};

	struct UniformSpec
	{
		enum Type
		{
			TYPE_FLOAT = 0,
			TYPE_VEC2,
			TYPE_VEC3,
			TYPE_VEC4,

			TYPE_MAT3,
			TYPE_MAT4,

			TYPE_TEXTURE_UNIT,

			TYPE_LAST
		};

		string					name;
		Type					type;
		tcu::Vector<float, 16>	value;

		UniformSpec (const string& n, Type t, float v)							: name(n), type(t), value(v) {}
		UniformSpec (const string& n, Type t, const tcu::Vector<float, 16>& v)	: name(n), type(t), value(v) {}
	};

								ShaderCompilerCase		(Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments);
								~ShaderCompilerCase		(void);

	void						init					(void);

	IterateResult				iterate					(void);

protected:
	struct ProgramContext
	{
		string					vertShaderSource;
		string					fragShaderSource;
		vector<AttribSpec>		vertexAttributes;
		vector<UniformSpec>		uniforms;
	};

	deUint32					getSpecializationID		(int measurementNdx) const;		// Return an ID that depends on the case ID, current measurement index and time; used to specialize attribute names etc. (avoid shader caching).
	virtual ProgramContext		generateShaderData		(int measurementNdx) const = 0;	// Generate shader sources and inputs. Attribute etc. names depend on above name specialization.

private:
	struct Measurement
	{
		// \note All times in microseconds. 32-bit integers would probably suffice (would need over an hour of test case runtime to overflow), but better safe than sorry.
		deInt64 sourceSetTime;
		deInt64 vertexCompileTime;
		deInt64 fragmentCompileTime;
		deInt64 programLinkTime;
		deInt64 firstInputSetTime;
		deInt64 firstDrawTime;

		deInt64 secondInputSetTime;
		deInt64 secondDrawTime;

		deInt64 firstPhase				(void) const { return sourceSetTime + vertexCompileTime + fragmentCompileTime + programLinkTime + firstInputSetTime + firstDrawTime; }
		deInt64 secondPhase				(void) const { return secondInputSetTime + secondDrawTime; }

		deInt64 totalTimeWithoutDraw	(void) const { return firstPhase() - de::min(secondPhase(), firstInputSetTime + firstDrawTime); }

		Measurement (deInt64 sourceSetTime_,
					 deInt64 vertexCompileTime_,
					 deInt64 fragmentCompileTime_,
					 deInt64 programLinkTime_,
					 deInt64 firstInputSetTime_,
					 deInt64 firstDrawTime_,
					 deInt64 secondInputSetTime_,
					 deInt64 secondDrawTime_)
			: sourceSetTime			(sourceSetTime_)
			, vertexCompileTime		(vertexCompileTime_)
			, fragmentCompileTime	(fragmentCompileTime_)
			, programLinkTime		(programLinkTime_)
			, firstInputSetTime		(firstInputSetTime_)
			, firstDrawTime			(firstDrawTime_)
			, secondInputSetTime	(secondInputSetTime_)
			, secondDrawTime		(secondDrawTime_)
		{
		}
	};

	struct ShadersAndProgram
	{
		deUint32 vertShader;
		deUint32 fragShader;
		deUint32 program;
	};

	struct Logs
	{
		string vert;
		string frag;
		string link;
	};

	struct BuildInfo
	{
		bool vertCompileSuccess;
		bool fragCompileSuccess;
		bool linkSuccess;

		Logs logs;
	};

	ShadersAndProgram			createShadersAndProgram		(void) const;
	void						setShaderSources			(deUint32 vertShader, deUint32 fragShader, const ProgramContext&) const;
	bool						compileShader				(deUint32 shader) const;
	bool						linkAndUseProgram			(deUint32 program) const;
	void						setShaderInputs				(deUint32 program, const ProgramContext&) const;							// Set attribute pointers and uniforms.
	void						draw						(void) const;																// Clear, draw and finish.
	void						cleanup						(const ShadersAndProgram&, const ProgramContext&, bool linkSuccess) const;	// Do GL deinitializations.

	Logs						getLogs						(const ShadersAndProgram&) const;
	void						logProgramData				(const BuildInfo&, const ProgramContext&) const;
	bool						goodEnoughMeasurements		(const vector<Measurement>& measurements) const;

	int							m_viewportWidth;
	int							m_viewportHeight;

	bool						m_avoidCache;				// If true, avoid caching between measurements as well (and not only between test cases).
	bool						m_addWhitespaceAndComments;	// If true, add random whitespace and comments to the source (good caching should ignore those).
	deUint32					m_startHash;				// A hash from case id and time, at the time of construction.

	int							m_minimumMeasurementCount;
	int							m_maximumMeasurementCount;
};

class ShaderCompilerLightCase : public ShaderCompilerCase
{
public:
							ShaderCompilerLightCase		(Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, bool isVertexCase, int numLights, LightType lightType);
							~ShaderCompilerLightCase	(void);

	void					init						(void);
	void					deinit						(void);

protected:
	ProgramContext			generateShaderData			(int measurementNdx) const;

private:
	int						m_numLights;
	bool					m_isVertexCase;
	LightType				m_lightType;
	glu::Texture2D*			m_texture;
};

class ShaderCompilerTextureCase : public ShaderCompilerCase
{
public:
									ShaderCompilerTextureCase	(Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, int numLookups, ConditionalUsage conditionalUsage, ConditionalType conditionalType);
									~ShaderCompilerTextureCase	(void);

	void							init						(void);
	void							deinit						(void);

protected:
	ProgramContext					generateShaderData			(int measurementNdx) const;

private:
	int								m_numLookups;
	vector<glu::Texture2D*>			m_textures;
	ConditionalUsage				m_conditionalUsage;
	ConditionalType					m_conditionalType;
};

class ShaderCompilerLoopCase : public ShaderCompilerCase
{
public:
						ShaderCompilerLoopCase	(Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, bool isVertexCase, LoopType type, int numLoopIterations, int nestingDepth);
						~ShaderCompilerLoopCase	(void);

protected:
	ProgramContext		generateShaderData		(int measurementNdx) const;

private:
	int					m_numLoopIterations;
	int					m_nestingDepth;
	bool				m_isVertexCase;
	LoopType			m_type;
};

class ShaderCompilerOperCase : public ShaderCompilerCase
{
public:
						ShaderCompilerOperCase	(Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, bool isVertexCase, const char* oper, int numOperations);
						~ShaderCompilerOperCase	(void);

protected:
	ProgramContext		generateShaderData		(int measurementNdx) const;

private:
	string				m_oper;
	int					m_numOperations;
	bool				m_isVertexCase;
};

class ShaderCompilerMandelbrotCase : public ShaderCompilerCase
{
public:
						ShaderCompilerMandelbrotCase	(Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, int numFractalIterations);
						~ShaderCompilerMandelbrotCase	(void);

protected:
	ProgramContext		generateShaderData				(int measurementNdx) const;

private:
	int					m_numFractalIterations;
};

class InvalidShaderCompilerCase : public TestCase
{
public:
	// \note Similar to the ShaderValidity enum, but doesn't have a VALID type.
	enum InvalidityType
	{
		INVALIDITY_INVALID_CHAR = 0,
		INVALIDITY_SEMANTIC_ERROR,

		INVALIDITY_LAST
	};

						InvalidShaderCompilerCase	(Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType);
						~InvalidShaderCompilerCase	(void);

	IterateResult		iterate						(void);

protected:
	struct ProgramContext
	{
		string vertShaderSource;
		string fragShaderSource;
	};

	deUint32				getSpecializationID		(int measurementNdx) const;			// Return an ID that depends on the case ID, current measurement index and time; used to specialize attribute names etc. (avoid shader caching).
	virtual ProgramContext	generateShaderSources	(int measurementNdx) const = 0;		// Generate shader sources. Attribute etc. names depend on above name specialization.

	InvalidityType			m_invalidityType;

private:
	struct Measurement
	{
		// \note All times in microseconds. 32-bit integers would probably suffice (would need over an hour of test case runtime to overflow), but better safe than sorry.
		deInt64 sourceSetTime;
		deInt64 vertexCompileTime;
		deInt64 fragmentCompileTime;

		deInt64 totalTime (void) const { return sourceSetTime + vertexCompileTime + fragmentCompileTime; }

		Measurement (deInt64 sourceSetTime_,
					 deInt64 vertexCompileTime_,
					 deInt64 fragmentCompileTime_)
			: sourceSetTime			(sourceSetTime_)
			, vertexCompileTime		(vertexCompileTime_)
			, fragmentCompileTime	(fragmentCompileTime_)
		{
		}
	};

	struct Shaders
	{
		deUint32 vertShader;
		deUint32 fragShader;
	};

	struct Logs
	{
		string vert;
		string frag;
	};

	struct BuildInfo
	{
		bool vertCompileSuccess;
		bool fragCompileSuccess;

		Logs logs;
	};

	Shaders						createShaders			(void) const;
	void						setShaderSources		(const Shaders&, const ProgramContext&) const;
	bool						compileShader			(deUint32 shader) const;
	void						cleanup					(const Shaders&) const;

	Logs						getLogs					(const Shaders&) const;
	void						logProgramData			(const BuildInfo&, const ProgramContext&) const;
	bool						goodEnoughMeasurements	(const vector<Measurement>& measurements) const;

	deUint32					m_startHash; // A hash from case id and time, at the time of construction.

	int							m_minimumMeasurementCount;
	int							m_maximumMeasurementCount;
};

class InvalidShaderCompilerLightCase : public InvalidShaderCompilerCase
{
public:
							InvalidShaderCompilerLightCase	(Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, bool isVertexCase, int numLights, LightType lightType);
							~InvalidShaderCompilerLightCase	(void);

protected:
	ProgramContext			generateShaderSources			(int measurementNdx) const;

private:
	bool					m_isVertexCase;
	int						m_numLights;
	LightType				m_lightType;
};

class InvalidShaderCompilerTextureCase : public InvalidShaderCompilerCase
{
public:
							InvalidShaderCompilerTextureCase	(Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, int numLookups, ConditionalUsage conditionalUsage, ConditionalType conditionalType);
							~InvalidShaderCompilerTextureCase	(void);

protected:
	ProgramContext			generateShaderSources				(int measurementNdx) const;

private:
	int						m_numLookups;
	ConditionalUsage		m_conditionalUsage;
	ConditionalType			m_conditionalType;
};

class InvalidShaderCompilerLoopCase : public InvalidShaderCompilerCase
{
public:
						InvalidShaderCompilerLoopCase	(Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, bool , LoopType type, int numLoopIterations, int nestingDepth);
						~InvalidShaderCompilerLoopCase	(void);

protected:
	ProgramContext		generateShaderSources			(int measurementNdx) const;

private:
	bool				m_isVertexCase;
	int					m_numLoopIterations;
	int					m_nestingDepth;
	LoopType			m_type;
};

class InvalidShaderCompilerOperCase : public InvalidShaderCompilerCase
{
public:
						InvalidShaderCompilerOperCase	(Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, bool isVertexCase, const char* oper, int numOperations);
						~InvalidShaderCompilerOperCase	(void);

protected:
	ProgramContext		generateShaderSources			(int measurementNdx) const;

private:
	bool				m_isVertexCase;
	string				m_oper;
	int					m_numOperations;
};

class InvalidShaderCompilerMandelbrotCase : public InvalidShaderCompilerCase
{
public:
						InvalidShaderCompilerMandelbrotCase		(Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, int numFractalIterations);
						~InvalidShaderCompilerMandelbrotCase	(void);

protected:
	ProgramContext		generateShaderSources					(int measurementNdx) const;

private:
	int					m_numFractalIterations;
};

static string getNameSpecialization (deUint32 id)
{
	return "_" + toStringWithPadding(id, 10);
}

// Substitute StringTemplate parameters for attribute/uniform/varying name and constant expression specialization as well as possible shader compilation error causes.
static string specializeShaderSource (const string& shaderSourceTemplate, deUint32 cacheAvoidanceID, ShaderValidity validity)
{
	std::map<string, string> params;
	params["NAME_SPEC"]			= getNameSpecialization(cacheAvoidanceID);
	params["FLOAT01"]			= de::floatToString((float)cacheAvoidanceID / (float)(std::numeric_limits<deUint32>::max()), 6);
	params["SEMANTIC_ERROR"]	= validity != SHADER_VALIDITY_SEMANTIC_ERROR	? "" : "\tmediump float invalid = sin(1.0, 2.0);\n";
	params["INVALID_CHAR"]		= validity != SHADER_VALIDITY_INVALID_CHAR		? "" : "@\n"; // \note Some implementations crash when the invalid character is the last character in the source, so use newline.

	return tcu::StringTemplate(shaderSourceTemplate).specialize(params);
}

// Function for generating the vertex shader of a (directional or point) light case.
static string lightVertexTemplate (int numLights, bool isVertexCase, LightType lightType)
{
	string resultTemplate;

	resultTemplate +=
		"attribute highp vec4 a_position${NAME_SPEC};\n"
		"attribute mediump vec3 a_normal${NAME_SPEC};\n"
		"attribute mediump vec4 a_texCoord0${NAME_SPEC};\n"
		"uniform mediump vec3 u_material_ambientColor${NAME_SPEC};\n"
		"uniform mediump vec4 u_material_diffuseColor${NAME_SPEC};\n"
		"uniform mediump vec3 u_material_emissiveColor${NAME_SPEC};\n"
		"uniform mediump vec3 u_material_specularColor${NAME_SPEC};\n"
		"uniform mediump float u_material_shininess${NAME_SPEC};\n";

	for (int lightNdx = 0; lightNdx < numLights; lightNdx++)
	{
		string ndxStr = de::toString(lightNdx);

		resultTemplate +=
			"uniform mediump vec3 u_light" + ndxStr + "_color${NAME_SPEC};\n"
			"uniform mediump vec3 u_light" + ndxStr + "_direction${NAME_SPEC};\n";

		if (lightType == LIGHT_POINT)
			resultTemplate +=
				"uniform mediump vec4 u_light" + ndxStr + "_position${NAME_SPEC};\n"
				"uniform mediump float u_light" + ndxStr + "_constantAttenuation${NAME_SPEC};\n"
				"uniform mediump float u_light" + ndxStr + "_linearAttenuation${NAME_SPEC};\n"
				"uniform mediump float u_light" + ndxStr + "_quadraticAttenuation${NAME_SPEC};\n";
	}

	resultTemplate +=
		"uniform highp mat4 u_mvpMatrix${NAME_SPEC};\n"
		"uniform highp mat4 u_modelViewMatrix${NAME_SPEC};\n"
		"uniform mediump mat3 u_normalMatrix${NAME_SPEC};\n"
		"uniform mediump mat4 u_texCoordMatrix0${NAME_SPEC};\n"
		"varying mediump vec4 v_color${NAME_SPEC};\n"
		"varying mediump vec2 v_texCoord0${NAME_SPEC};\n";

	if (!isVertexCase)
	{
		resultTemplate += "varying mediump vec3 v_eyeNormal${NAME_SPEC};\n";

		if (lightType == LIGHT_POINT)
			resultTemplate +=
				"varying mediump vec3 v_directionToLight${NAME_SPEC}[" + de::toString(numLights) + "];\n"
				"varying mediump float v_distanceToLight${NAME_SPEC}[" + de::toString(numLights) + "];\n";
	}

	resultTemplate +=
		"mediump vec3 direction (mediump vec4 from, mediump vec4 to)\n"
		"{\n"
		"	return vec3(to.xyz * from.w - from.xyz * to.w);\n"
		"}\n"
		"\n"
		"mediump vec3 computeLighting (\n"
		"	mediump vec3 directionToLight,\n"
		"	mediump vec3 halfVector,\n"
		"	mediump vec3 normal,\n"
		"	mediump vec3 lightColor,\n"
		"	mediump vec3 diffuseColor,\n"
		"	mediump vec3 specularColor,\n"
		"	mediump float shininess)\n"
		"{\n"
		"	mediump float normalDotDirection  = max(dot(normal, directionToLight), 0.0);\n"
		"	mediump vec3  color               = normalDotDirection * diffuseColor * lightColor;\n"
		"\n"
		"	if (normalDotDirection != 0.0)\n"
		"		color += pow(max(dot(normal, halfVector), 0.0), shininess) * specularColor * lightColor;\n"
		"\n"
		"	return color;\n"
		"}\n"
		"\n";

	if (lightType == LIGHT_POINT)
		resultTemplate +=
			"mediump float computeDistanceAttenuation (mediump float distToLight, mediump float constAtt, mediump float linearAtt, mediump float quadraticAtt)\n"
			"{\n"
			"	return 1.0 / (constAtt + linearAtt * distToLight + quadraticAtt * distToLight * distToLight);\n"
			"}\n"
			"\n";

	resultTemplate +=
		"void main (void)\n"
		"{\n"
		"	highp vec4 position = a_position${NAME_SPEC};\n"
		"	highp vec3 normal = a_normal${NAME_SPEC};\n"
		"	gl_Position = u_mvpMatrix${NAME_SPEC} * position * (0.95 + 0.05*${FLOAT01});\n"
		"	v_texCoord0${NAME_SPEC} = (u_texCoordMatrix0${NAME_SPEC} * a_texCoord0${NAME_SPEC}).xy;\n"
		"	mediump vec4 color = vec4(u_material_emissiveColor${NAME_SPEC}, u_material_diffuseColor${NAME_SPEC}.a);\n"
		"\n"
		"	highp vec4 eyePosition = u_modelViewMatrix${NAME_SPEC} * position;\n"
		"	mediump vec3 eyeNormal = normalize(u_normalMatrix${NAME_SPEC} * normal);\n";

	if (!isVertexCase)
		resultTemplate += "\tv_eyeNormal${NAME_SPEC} = eyeNormal;\n";

	resultTemplate += "\n";

	for (int lightNdx = 0; lightNdx < numLights; lightNdx++)
	{
		string ndxStr = de::toString(lightNdx);

		resultTemplate +=
			"	/* Light " + ndxStr + " */\n";

		if (lightType == LIGHT_POINT)
		{
			resultTemplate +=
				"	mediump float distanceToLight" + ndxStr + " = distance(eyePosition, u_light" + ndxStr + "_position${NAME_SPEC});\n"
				"	mediump vec3 directionToLight" + ndxStr + " = normalize(direction(eyePosition, u_light" + ndxStr + "_position${NAME_SPEC}));\n";

			if (isVertexCase)
				resultTemplate +=
					"	mediump vec3 halfVector" + ndxStr + " = normalize(directionToLight" + ndxStr + " + vec3(0.0, 0.0, 1.0));\n"
					"	color.rgb += computeLighting(directionToLight" + ndxStr + ", halfVector" + ndxStr + ", eyeNormal, u_light" + ndxStr + "_color${NAME_SPEC}, u_material_diffuseColor${NAME_SPEC}.rgb, "
					"u_material_specularColor${NAME_SPEC}, u_material_shininess${NAME_SPEC}) * computeDistanceAttenuation(distanceToLight" + ndxStr + ", u_light" + ndxStr + "_constantAttenuation${NAME_SPEC}, "
					"u_light" + ndxStr + "_linearAttenuation${NAME_SPEC}, u_light" + ndxStr + "_quadraticAttenuation${NAME_SPEC});\n";
			else
				resultTemplate +=
					"	v_directionToLight${NAME_SPEC}[" + ndxStr + "] = directionToLight" + ndxStr + ";\n"
					"	v_distanceToLight${NAME_SPEC}[" + ndxStr + "]  = distanceToLight" + ndxStr + ";\n";
		}
		else if (lightType == LIGHT_DIRECTIONAL)
		{
			if (isVertexCase)
				resultTemplate +=
					"	mediump vec3 directionToLight" + ndxStr + " = -u_light" + ndxStr + "_direction${NAME_SPEC};\n"
					"	mediump vec3 halfVector" + ndxStr + " = normalize(directionToLight" + ndxStr + " + vec3(0.0, 0.0, 1.0));\n"
					"	color.rgb += computeLighting(directionToLight" + ndxStr + ", halfVector" + ndxStr + ", eyeNormal, u_light" + ndxStr + "_color${NAME_SPEC}, u_material_diffuseColor${NAME_SPEC}.rgb, u_material_specularColor${NAME_SPEC}, u_material_shininess${NAME_SPEC});\n";
		}
		else
			DE_ASSERT(DE_FALSE);

		resultTemplate += "\n";
	}

	resultTemplate +=
		"	v_color${NAME_SPEC} = color;\n"
		"${SEMANTIC_ERROR}"
		"}\n"
		"${INVALID_CHAR}";

	return resultTemplate;
}

// Function for generating the fragment shader of a (directional or point) light case.
static string lightFragmentTemplate (int numLights, bool isVertexCase, LightType lightType)
{
	string resultTemplate;

	if (!isVertexCase)
	{
		resultTemplate +=
			"uniform mediump vec3 u_material_ambientColor${NAME_SPEC};\n"
			"uniform mediump vec4 u_material_diffuseColor${NAME_SPEC};\n"
			"uniform mediump vec3 u_material_emissiveColor${NAME_SPEC};\n"
			"uniform mediump vec3 u_material_specularColor${NAME_SPEC};\n"
			"uniform mediump float u_material_shininess${NAME_SPEC};\n";

		for (int lightNdx = 0; lightNdx < numLights; lightNdx++)
		{
			string ndxStr = de::toString(lightNdx);

			resultTemplate +=
				"uniform mediump vec3 u_light" + ndxStr + "_color${NAME_SPEC};\n"
				"uniform mediump vec3 u_light" + ndxStr + "_direction${NAME_SPEC};\n";

			if (lightType == LIGHT_POINT)
				resultTemplate +=
					"uniform mediump vec4 u_light" + ndxStr + "_position${NAME_SPEC};\n"
					"uniform mediump float u_light" + ndxStr + "_constantAttenuation${NAME_SPEC};\n"
					"uniform mediump float u_light" + ndxStr + "_linearAttenuation${NAME_SPEC};\n"
					"uniform mediump float u_light" + ndxStr + "_quadraticAttenuation${NAME_SPEC};\n";
		}
	}

	resultTemplate +=
		"uniform sampler2D u_sampler0${NAME_SPEC};\n"
		"varying mediump vec4 v_color${NAME_SPEC};\n"
		"varying mediump vec2 v_texCoord0${NAME_SPEC};\n";

	if (!isVertexCase)
	{
		resultTemplate +=
			"varying mediump vec3 v_eyeNormal${NAME_SPEC};\n";

		if (lightType == LIGHT_POINT)
			resultTemplate +=
				"varying mediump vec3 v_directionToLight${NAME_SPEC}[" + de::toString(numLights) + "];\n"
				"varying mediump float v_distanceToLight${NAME_SPEC}[" + de::toString(numLights) + "];\n";

		resultTemplate +=
			"mediump vec3 direction (mediump vec4 from, mediump vec4 to)\n"
			"{\n"
			"	return vec3(to.xyz * from.w - from.xyz * to.w);\n"
			"}\n"
			"\n";

		resultTemplate +=
			"mediump vec3 computeLighting (\n"
			"	mediump vec3 directionToLight,\n"
			"	mediump vec3 halfVector,\n"
			"	mediump vec3 normal,\n"
			"	mediump vec3 lightColor,\n"
			"	mediump vec3 diffuseColor,\n"
			"	mediump vec3 specularColor,\n"
			"	mediump float shininess)\n"
			"{\n"
			"	mediump float normalDotDirection  = max(dot(normal, directionToLight), 0.0);\n"
			"	mediump vec3  color               = normalDotDirection * diffuseColor * lightColor;\n"
			"\n"
			"	if (normalDotDirection != 0.0)\n"
			"		color += pow(max(dot(normal, halfVector), 0.0), shininess) * specularColor * lightColor;\n"
			"\n"
			"	return color;\n"
			"}\n"
			"\n";

		if (lightType == LIGHT_POINT)
			resultTemplate +=
				"mediump float computeDistanceAttenuation (mediump float distToLight, mediump float constAtt, mediump float linearAtt, mediump float quadraticAtt)\n"
				"{\n"
				"	return 1.0 / (constAtt + linearAtt * distToLight + quadraticAtt * distToLight * distToLight);\n"
				"}\n"
				"\n";
	}

	resultTemplate +=
		"void main (void)\n"
		"{\n"
		"	mediump vec2 texCoord0 = v_texCoord0${NAME_SPEC}.xy;\n"
		"	mediump vec4 color = v_color${NAME_SPEC};\n";

	if (!isVertexCase)
	{
		resultTemplate +=
			"	mediump vec3 eyeNormal = normalize(v_eyeNormal${NAME_SPEC});\n"
			"\n";

		for (int lightNdx = 0; lightNdx < numLights; lightNdx++)
		{
			string ndxStr = de::toString(lightNdx);

			resultTemplate +=
				"	/* Light " + ndxStr + " */\n";

			if (lightType == LIGHT_POINT)
				resultTemplate +=
					"	mediump vec3 directionToLight" + ndxStr + " = normalize(v_directionToLight${NAME_SPEC}[" + ndxStr + "]);\n"
					"	mediump float distanceToLight" + ndxStr + " = v_distanceToLight${NAME_SPEC}[" + ndxStr + "];\n"
					"	mediump vec3 halfVector" + ndxStr + " = normalize(directionToLight" + ndxStr + " + vec3(0.0, 0.0, 1.0));\n"
					"	color.rgb += computeLighting(directionToLight" + ndxStr + ", halfVector" + ndxStr + ", eyeNormal, u_light" + ndxStr + "_color${NAME_SPEC}, u_material_diffuseColor${NAME_SPEC}.rgb, "
					"u_material_specularColor${NAME_SPEC}, u_material_shininess${NAME_SPEC}) * computeDistanceAttenuation(distanceToLight" + ndxStr + ", u_light" + ndxStr + "_constantAttenuation${NAME_SPEC}, "
					"u_light" + ndxStr + "_linearAttenuation${NAME_SPEC}, u_light" + ndxStr + "_quadraticAttenuation${NAME_SPEC});\n"
					"\n";
			else if (lightType == LIGHT_DIRECTIONAL)
				resultTemplate +=
					"	mediump vec3 directionToLight" + ndxStr + " = -u_light" + ndxStr + "_direction${NAME_SPEC};\n"
					"	mediump vec3 halfVector" + ndxStr + " = normalize(directionToLight" + ndxStr + " + vec3(0.0, 0.0, 1.0));\n"
					"	color.rgb += computeLighting(directionToLight" + ndxStr + ", halfVector" + ndxStr + ", eyeNormal, u_light" + ndxStr + "_color${NAME_SPEC}, u_material_diffuseColor${NAME_SPEC}.rgb, u_material_specularColor${NAME_SPEC}, u_material_shininess${NAME_SPEC});\n"
					"\n";
			else
				DE_ASSERT(DE_FALSE);
		}
	}

	resultTemplate +=
		"	color *= texture2D(u_sampler0${NAME_SPEC}, texCoord0);\n"
		"	gl_FragColor = color + ${FLOAT01};\n"
		"${SEMANTIC_ERROR}"
		"}\n"
		"${INVALID_CHAR}";

	return resultTemplate;
}

// Function for generating the shader attributes of a (directional or point) light case.
static vector<ShaderCompilerCase::AttribSpec> lightShaderAttributes (const string& nameSpecialization)
{
	vector<ShaderCompilerCase::AttribSpec> result;

	result.push_back(ShaderCompilerCase::AttribSpec("a_position" + nameSpecialization,
													combineVec4ToVec16(Vec4(-1.0f, -1.0f,  0.0f,  1.0f),
																	   Vec4(-1.0f,  1.0f,  0.0f,  1.0f),
																	   Vec4( 1.0f, -1.0f,  0.0f,  1.0f),
																	   Vec4( 1.0f,  1.0f,  0.0f,  1.0f))));

	result.push_back(ShaderCompilerCase::AttribSpec("a_normal" + nameSpecialization,
													combineVec4ToVec16(Vec4(0.0f, 0.0f, -1.0f, 0.0f),
																	   Vec4(0.0f, 0.0f, -1.0f, 0.0f),
																	   Vec4(0.0f, 0.0f, -1.0f, 0.0f),
																	   Vec4(0.0f, 0.0f, -1.0f, 0.0f))));

	result.push_back(ShaderCompilerCase::AttribSpec("a_texCoord0" + nameSpecialization,
													combineVec4ToVec16(Vec4(0.0f, 0.0f, 0.0f, 0.0f),
																	   Vec4(1.0f, 0.0f, 0.0f, 0.0f),
																	   Vec4(0.0f, 1.0f, 0.0f, 0.0f),
																	   Vec4(1.0f, 1.0f, 0.0f, 0.0f))));

	return result;
}

// Function for generating the shader uniforms of a (directional or point) light case.
static vector<ShaderCompilerCase::UniformSpec> lightShaderUniforms (const string& nameSpecialization, int numLights, LightType lightType)
{
	vector<ShaderCompilerCase::UniformSpec> result;

	result.push_back(ShaderCompilerCase::UniformSpec("u_material_ambientColor" + nameSpecialization,
													 ShaderCompilerCase::UniformSpec::TYPE_VEC3,
													 vecTo16(Vec3(0.5f, 0.7f, 0.9f))));

	result.push_back(ShaderCompilerCase::UniformSpec("u_material_diffuseColor" + nameSpecialization,
													 ShaderCompilerCase:: UniformSpec::TYPE_VEC4,
													 vecTo16(Vec4(0.3f, 0.4f, 0.5f, 1.0f))));

	result.push_back(ShaderCompilerCase::UniformSpec("u_material_emissiveColor" + nameSpecialization,
													 ShaderCompilerCase::UniformSpec::TYPE_VEC3,
													 vecTo16(Vec3(0.7f, 0.2f, 0.2f))));

	result.push_back(ShaderCompilerCase::UniformSpec("u_material_specularColor" + nameSpecialization,
													 ShaderCompilerCase::UniformSpec::TYPE_VEC3,
													 vecTo16(Vec3(0.2f, 0.6f, 1.0f))));

	result.push_back(ShaderCompilerCase::UniformSpec("u_material_shininess" + nameSpecialization,
													 ShaderCompilerCase::UniformSpec::TYPE_FLOAT,
													 0.8f));

	for (int lightNdx = 0; lightNdx < numLights; lightNdx++)
	{
		string ndxStr = de::toString(lightNdx);

		result.push_back(ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_color" + nameSpecialization,
														 ShaderCompilerCase::UniformSpec::TYPE_VEC3,
														 vecTo16(Vec3(0.8f, 0.6f, 0.3f))));

		result.push_back(ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_direction" + nameSpecialization,
														 ShaderCompilerCase::UniformSpec::TYPE_VEC3,
														 vecTo16(Vec3(0.2f, 0.3f, 0.4f))));

		if (lightType == LIGHT_POINT)
		{
			result.push_back(ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_position" + nameSpecialization,
															 ShaderCompilerCase::UniformSpec::TYPE_VEC4,
															 vecTo16(Vec4(1.0f, 0.6f, 0.3f, 0.2f))));

			result.push_back(ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_constantAttenuation" + nameSpecialization,
															 ShaderCompilerCase::UniformSpec::TYPE_FLOAT,
															 0.6f));

			result.push_back(ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_linearAttenuation" + nameSpecialization,
															 ShaderCompilerCase::UniformSpec::TYPE_FLOAT,
															 0.5f));

			result.push_back(ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_quadraticAttenuation" + nameSpecialization,
															 ShaderCompilerCase::UniformSpec::TYPE_FLOAT,
															 0.4f));
		}
	}

	result.push_back(ShaderCompilerCase::UniformSpec("u_mvpMatrix" + nameSpecialization,
													 ShaderCompilerCase::UniformSpec::TYPE_MAT4,
													 arrTo16(Mat4(1.0f).getColumnMajorData())));

	result.push_back(ShaderCompilerCase::UniformSpec("u_modelViewMatrix" + nameSpecialization,
													 ShaderCompilerCase::UniformSpec::TYPE_MAT4,
													 arrTo16(Mat4(1.0f).getColumnMajorData())));

	result.push_back(ShaderCompilerCase::UniformSpec("u_normalMatrix" + nameSpecialization,
													 ShaderCompilerCase::UniformSpec::TYPE_MAT3,
													 arrTo16(Mat3(1.0f).getColumnMajorData())));

	result.push_back(ShaderCompilerCase::UniformSpec("u_texCoordMatrix0" + nameSpecialization,
													 ShaderCompilerCase::UniformSpec::TYPE_MAT4,
													 arrTo16(Mat4(1.0f).getColumnMajorData())));

	result.push_back(ShaderCompilerCase::UniformSpec("u_sampler0" + nameSpecialization,
													 ShaderCompilerCase::UniformSpec::TYPE_TEXTURE_UNIT,
													 0.0f));

	return result;
}

// Function for generating a vertex shader with a for loop.
static string loopVertexTemplate (LoopType type, bool isVertexCase, int numLoopIterations, int nestingDepth)
{
	string resultTemplate;
	string loopBound		= type == LOOP_TYPE_STATIC	? de::toString(numLoopIterations)
							: type == LOOP_TYPE_UNIFORM	? "int(u_loopBound${NAME_SPEC})"
							: type == LOOP_TYPE_DYNAMIC	? "int(a_loopBound${NAME_SPEC})"
							: "";

	DE_ASSERT(!loopBound.empty());

	resultTemplate +=
		"attribute highp vec4 a_position${NAME_SPEC};\n";

	if (type == LOOP_TYPE_DYNAMIC)
		resultTemplate +=
			"attribute mediump float a_loopBound${NAME_SPEC};\n";

	resultTemplate +=
		"attribute mediump vec4 a_value${NAME_SPEC};\n"
		"varying mediump vec4 v_value${NAME_SPEC};\n";

	if (isVertexCase)
	{
		if (type == LOOP_TYPE_UNIFORM)
			resultTemplate += "uniform mediump float u_loopBound${NAME_SPEC};\n";

		resultTemplate +=
			"\n"
			"void main()\n"
			"{\n"
			"	gl_Position = a_position${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
			"	mediump vec4 value = a_value${NAME_SPEC};\n";

		for (int i = 0; i < nestingDepth; i++)
		{
			string iterName = "i" + de::toString(i);
			resultTemplate += string(i + 1, '\t') + "for (int " + iterName + " = 0; " + iterName + " < " + loopBound + "; " + iterName + "++)\n";
		}

		resultTemplate += string(nestingDepth + 1, '\t') + "value *= a_value${NAME_SPEC};\n";

		resultTemplate +=
			"	v_value${NAME_SPEC} = value;\n";
	}
	else
	{
		if (type == LOOP_TYPE_DYNAMIC)
			resultTemplate +=
				"varying mediump float v_loopBound${NAME_SPEC};\n";

		resultTemplate +=
			"\n"
			"void main()\n"
			"{\n"
			"	gl_Position = a_position${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
			"	v_value${NAME_SPEC} = a_value${NAME_SPEC};\n";

		if (type == LOOP_TYPE_DYNAMIC)
			resultTemplate +=
				"	v_loopBound${NAME_SPEC} = a_loopBound${NAME_SPEC};\n";
	}

	resultTemplate +=
		"${SEMANTIC_ERROR}"
		"}\n"
		"${INVALID_CHAR}";

	return resultTemplate;
}

// Function for generating a fragment shader with a for loop.
static string loopFragmentTemplate (LoopType type, bool isVertexCase, int numLoopIterations, int nestingDepth)
{
	string resultTemplate;
	string loopBound		= type == LOOP_TYPE_STATIC	? de::toString(numLoopIterations)
							: type == LOOP_TYPE_UNIFORM	? "int(u_loopBound${NAME_SPEC})"
							: type == LOOP_TYPE_DYNAMIC	? "int(v_loopBound${NAME_SPEC})"
							: "";

	DE_ASSERT(!loopBound.empty());

	resultTemplate +=
		"varying mediump vec4 v_value${NAME_SPEC};\n";

	if (!isVertexCase)
	{
		if (type == LOOP_TYPE_DYNAMIC)
			resultTemplate +=
				"varying mediump float v_loopBound${NAME_SPEC};\n";
		else if (type == LOOP_TYPE_UNIFORM)
			resultTemplate +=
				"uniform mediump float u_loopBound${NAME_SPEC};\n";

		resultTemplate +=
			"\n"
			"void main()\n"
			"{\n"
			"	mediump vec4 value = v_value${NAME_SPEC};\n";

		for (int i = 0; i < nestingDepth; i++)
		{
			string iterName = "i" + de::toString(i);
			resultTemplate += string(i + 1, '\t') + "for (int " + iterName + " = 0; " + iterName + " < " + loopBound + "; " + iterName + "++)\n";
		}

		resultTemplate += string(nestingDepth + 1, '\t') + "value *= v_value${NAME_SPEC};\n";

		resultTemplate +=
			"	gl_FragColor = value + ${FLOAT01};\n";
	}
	else
		resultTemplate +=
			"\n"
			"void main()\n"
			"{\n"
			"	gl_FragColor = v_value${NAME_SPEC} + ${FLOAT01};\n";

	resultTemplate +=
		"${SEMANTIC_ERROR}"
		"}\n"
		"${INVALID_CHAR}";

	return resultTemplate;
}

// Function for generating the shader attributes for a loop case.
static vector<ShaderCompilerCase::AttribSpec> loopShaderAttributes (const string& nameSpecialization, LoopType type, int numLoopIterations)
{
	vector<ShaderCompilerCase::AttribSpec> result;

	result.push_back(ShaderCompilerCase::AttribSpec("a_position" + nameSpecialization,
													combineVec4ToVec16(Vec4(-1.0f, -1.0f,  0.0f,  1.0f),
																	   Vec4(-1.0f,  1.0f,  0.0f,  1.0f),
																	   Vec4( 1.0f, -1.0f,  0.0f,  1.0f),
																	   Vec4( 1.0f,  1.0f,  0.0f,  1.0f))));

	result.push_back(ShaderCompilerCase::AttribSpec("a_value" + nameSpecialization,
													combineVec4ToVec16(Vec4( 1.0f,  1.0f,  1.0f,  1.0f),
																	   Vec4( 1.0f,  1.0f,  1.0f,  1.0f),
																	   Vec4( 1.0f,  1.0f,  1.0f,  1.0f),
																	   Vec4( 1.0f,  1.0f,  1.0f,  1.0f))));

	if (type == LOOP_TYPE_DYNAMIC)
		result.push_back(ShaderCompilerCase::AttribSpec("a_loopBound" + nameSpecialization,
														combineVec4ToVec16(Vec4((float)numLoopIterations, 0.0f, 0.0f, 0.0f),
																		   Vec4((float)numLoopIterations, 0.0f, 0.0f, 0.0f),
																		   Vec4((float)numLoopIterations, 0.0f, 0.0f, 0.0f),
																		   Vec4((float)numLoopIterations, 0.0f, 0.0f, 0.0f))));

	return result;
}

static vector<ShaderCompilerCase::UniformSpec> loopShaderUniforms (const string& nameSpecialization, LoopType type, int numLoopIterations)
{
	vector<ShaderCompilerCase::UniformSpec> result;

	if (type == LOOP_TYPE_UNIFORM)
		result.push_back(ShaderCompilerCase::UniformSpec("u_loopBound" + nameSpecialization,
														 ShaderCompilerCase::UniformSpec::TYPE_FLOAT,
														 (float)numLoopIterations));

	return result;
}

// Function for generating the shader attributes for a case with only one attribute value in addition to the position attribute.
static vector<ShaderCompilerCase::AttribSpec> singleValueShaderAttributes (const string& nameSpecialization)
{
	vector<ShaderCompilerCase::AttribSpec> result;

	result.push_back(ShaderCompilerCase::AttribSpec("a_position" + nameSpecialization,
													combineVec4ToVec16(Vec4(-1.0f, -1.0f,  0.0f,  1.0f),
																	   Vec4(-1.0f,  1.0f,  0.0f,  1.0f),
																	   Vec4( 1.0f, -1.0f,  0.0f,  1.0f),
																	   Vec4( 1.0f,  1.0f,  0.0f,  1.0f))));

	result.push_back(ShaderCompilerCase::AttribSpec("a_value" + nameSpecialization,
													combineVec4ToVec16(Vec4( 1.0f,  1.0f,  1.0f,  1.0f),
																	   Vec4( 1.0f,  1.0f,  1.0f,  1.0f),
																	   Vec4( 1.0f,  1.0f,  1.0f,  1.0f),
																	   Vec4( 1.0f,  1.0f,  1.0f,  1.0f))));

	return result;
}

// Function for generating a vertex shader with a binary operation chain.
static string binaryOpVertexTemplate (int numOperations, const char* op)
{
	string resultTemplate;

	resultTemplate +=
		"attribute highp vec4 a_position${NAME_SPEC};\n"
		"attribute mediump vec4 a_value${NAME_SPEC};\n"
		"varying mediump vec4 v_value${NAME_SPEC};\n"
		"\n"
		"void main()\n"
		"{\n"
		"	gl_Position = a_position${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
		"	mediump vec4 value = ";

	for (int i = 0; i < numOperations; i++)
		resultTemplate += string(i > 0 ? op : "") + "a_value${NAME_SPEC}";

	resultTemplate +=
		";\n"
		"	v_value${NAME_SPEC} = value;\n"
		"${SEMANTIC_ERROR}"
		"}\n"
		"${INVALID_CHAR}";

	return resultTemplate;
}

// Function for generating a fragment shader with a binary operation chain.
static string binaryOpFragmentTemplate (int numOperations, const char* op)
{
	string resultTemplate;

	resultTemplate +=
		"varying mediump vec4 v_value${NAME_SPEC};\n"
		"\n"
		"void main()\n"
		"{\n"
		"	mediump vec4 value = ";

	for (int i = 0; i < numOperations; i++)
		resultTemplate += string(i > 0 ? op : "") + "v_value${NAME_SPEC}";

	resultTemplate +=
		";\n"
		"	gl_FragColor = value + ${FLOAT01};\n"
		"${SEMANTIC_ERROR}"
		"}\n"
		"${INVALID_CHAR}";

	return resultTemplate;
}

// Function for generating a vertex that takes one attribute in addition to position and just passes it to the fragment shader as a varying.
static string singleVaryingVertexTemplate (void)
{
	const char* resultTemplate =
		"attribute highp vec4 a_position${NAME_SPEC};\n"
		"attribute mediump vec4 a_value${NAME_SPEC};\n"
		"varying mediump vec4 v_value${NAME_SPEC};\n"
		"\n"
		"void main()\n"
		"{\n"
		"	gl_Position = a_position${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
		"	v_value${NAME_SPEC} = a_value${NAME_SPEC};\n"
		"${SEMANTIC_ERROR}"
		"}\n"
		"${INVALID_CHAR}";

	return resultTemplate;
}

// Function for generating a fragment shader that takes a single varying and uses it as the color.
static string singleVaryingFragmentTemplate (void)
{
	const char* resultTemplate =
		"varying mediump vec4 v_value${NAME_SPEC};\n"
		"\n"
		"void main()\n"
		"{\n"
		"	gl_FragColor = v_value${NAME_SPEC} + ${FLOAT01};\n"
		"${SEMANTIC_ERROR}"
		"}\n"
		"${INVALID_CHAR}";

	return resultTemplate;
}

// Function for generating the vertex shader of a texture lookup case.
static string textureLookupVertexTemplate (ConditionalUsage conditionalUsage, ConditionalType conditionalType)
{
	string	resultTemplate;
	bool	conditionVaryingNeeded = conditionalUsage != CONDITIONAL_USAGE_NONE && conditionalType == CONDITIONAL_TYPE_DYNAMIC;

	resultTemplate +=
		"attribute highp vec4 a_position${NAME_SPEC};\n"
		"attribute mediump vec2 a_coords${NAME_SPEC};\n"
		"varying mediump vec2 v_coords${NAME_SPEC};\n";

	if (conditionVaryingNeeded)
		resultTemplate +=
			"attribute mediump float a_condition${NAME_SPEC};\n"
			"varying mediump float v_condition${NAME_SPEC};\n";

	resultTemplate +=
		"\n"
		"void main()\n"
		"{\n"
		"	gl_Position = a_position${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
		"	v_coords${NAME_SPEC} = a_coords${NAME_SPEC};\n";

	if (conditionVaryingNeeded)
		resultTemplate +=
			"	v_condition${NAME_SPEC} = a_condition${NAME_SPEC};\n";

	resultTemplate +=
		"${SEMANTIC_ERROR}"
		"}\n"
		"${INVALID_CHAR}";

	return resultTemplate;
}

// Function for generating the fragment shader of a texture lookup case.
static string textureLookupFragmentTemplate (int numLookups, ConditionalUsage conditionalUsage, ConditionalType conditionalType)
{
	string resultTemplate;

	resultTemplate +=
		"varying mediump vec2 v_coords${NAME_SPEC};\n";

	if (conditionalUsage != CONDITIONAL_USAGE_NONE && conditionalType == CONDITIONAL_TYPE_DYNAMIC)
		resultTemplate +=
			"varying mediump float v_condition${NAME_SPEC};\n";

	for (int i = 0; i < numLookups; i++)
		resultTemplate +=
			"uniform sampler2D u_sampler" + de::toString(i) + "${NAME_SPEC};\n";

	if (conditionalUsage != CONDITIONAL_USAGE_NONE && conditionalType == CONDITIONAL_TYPE_UNIFORM)
		resultTemplate +=
			"uniform mediump float u_condition${NAME_SPEC};\n";

	resultTemplate +=
		"\n"
		"void main()\n"
		"{\n"
		"	mediump vec4 color = vec4(0.0);\n";

	const char* conditionalTerm = conditionalType == CONDITIONAL_TYPE_STATIC	? "1.0 > 0.0"
								: conditionalType == CONDITIONAL_TYPE_UNIFORM	? "u_condition${NAME_SPEC} > 0.0"
								: conditionalType == CONDITIONAL_TYPE_DYNAMIC	? "v_condition${NAME_SPEC} > 0.0"
								: DE_NULL;

	DE_ASSERT(conditionalTerm != DE_NULL);

	if (conditionalUsage == CONDITIONAL_USAGE_FIRST_HALF)
		resultTemplate += string("") +
			"	if (" + conditionalTerm + ")\n"
			"	{\n";

	for (int i = 0; i < numLookups; i++)
	{
		if (conditionalUsage == CONDITIONAL_USAGE_FIRST_HALF)
		{
			if (i < (numLookups + 1) / 2)
				resultTemplate += "\t";
		}
		else if (conditionalUsage == CONDITIONAL_USAGE_EVERY_OTHER)
		{
			if (i % 2 == 0)
				resultTemplate += string("") +
					"	if (" + conditionalTerm + ")\n"
					"\t";
		}

		resultTemplate +=
			"	color += texture2D(u_sampler" + de::toString(i) + "${NAME_SPEC}, v_coords${NAME_SPEC});\n";

		if (conditionalUsage == CONDITIONAL_USAGE_FIRST_HALF && i == (numLookups - 1) / 2)
			resultTemplate += "\t}\n";
	}

	resultTemplate +=
		"	gl_FragColor = color/" + de::toString(numLookups) + ".0 + ${FLOAT01};\n" +
		"${SEMANTIC_ERROR}"
		"}\n"
		"${INVALID_CHAR}";

	return resultTemplate;
}

// Function for generating the shader attributes of a texture lookup case.
static vector<ShaderCompilerCase::AttribSpec> textureLookupShaderAttributes (const string& nameSpecialization, ConditionalUsage conditionalUsage, ConditionalType conditionalType)
{
	vector<ShaderCompilerCase::AttribSpec> result;

	result.push_back(ShaderCompilerCase::AttribSpec("a_position" + nameSpecialization,
													combineVec4ToVec16(Vec4(-1.0f, -1.0f,  0.0f,  1.0f),
																	   Vec4(-1.0f,  1.0f,  0.0f,  1.0f),
																	   Vec4( 1.0f, -1.0f,  0.0f,  1.0f),
																	   Vec4( 1.0f,  1.0f,  0.0f,  1.0f))));

	result.push_back(ShaderCompilerCase::AttribSpec("a_coords" + nameSpecialization,
													combineVec4ToVec16(Vec4(0.0f, 0.0f, 0.0f, 0.0f),
																	   Vec4(0.0f, 1.0f, 0.0f, 0.0f),
																	   Vec4(1.0f, 0.0f, 0.0f, 0.0f),
																	   Vec4(1.0f, 1.0f, 0.0f, 0.0f))));

	if (conditionalUsage != CONDITIONAL_USAGE_NONE && conditionalType == CONDITIONAL_TYPE_DYNAMIC)
		result.push_back(ShaderCompilerCase::AttribSpec("a_condition" + nameSpecialization,
														combineVec4ToVec16(Vec4(1.0f), Vec4(1.0f), Vec4(1.0f), Vec4(1.0f))));

	return result;
}

// Function for generating the shader uniforms of a texture lookup case.
static vector<ShaderCompilerCase::UniformSpec> textureLookupShaderUniforms (const string& nameSpecialization, int numLookups, ConditionalUsage conditionalUsage, ConditionalType conditionalType)
{
	vector<ShaderCompilerCase::UniformSpec> result;

	for (int i = 0; i < numLookups; i++)
		result.push_back(ShaderCompilerCase::UniformSpec("u_sampler" + de::toString(i) + nameSpecialization,
														 ShaderCompilerCase::UniformSpec::TYPE_TEXTURE_UNIT,
														 (float)i));

	if (conditionalUsage != CONDITIONAL_USAGE_NONE && conditionalType == CONDITIONAL_TYPE_UNIFORM)
		result.push_back(ShaderCompilerCase::UniformSpec("u_condition" + nameSpecialization,
														 ShaderCompilerCase::UniformSpec::TYPE_FLOAT,
														 1.0f));

	return result;
}

static string mandelbrotVertexTemplate (void)
{
	const char* resultTemplate =
		"uniform highp mat4 u_mvp${NAME_SPEC};\n"
		"\n"
		"attribute highp vec4 a_vertex${NAME_SPEC};\n"
		"attribute highp vec4 a_coord${NAME_SPEC};\n"
		"\n"
		"varying mediump vec2 v_coord${NAME_SPEC};\n"
		"\n"
		"void main(void)\n"
		"{\n"
		"	gl_Position = u_mvp${NAME_SPEC} * a_vertex${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
		"\n"
		"	float xMin = -2.0;\n"
		"	float xMax = +0.5;\n"
		"	float yMin = -1.5;\n"
		"	float yMax = +1.5;\n"
		"\n"
		"	v_coord${NAME_SPEC}.x = a_coord${NAME_SPEC}.x * (xMax - xMin) + xMin;\n"
		"	v_coord${NAME_SPEC}.y = a_coord${NAME_SPEC}.y * (yMax - yMin) + yMin;\n"
		"${SEMANTIC_ERROR}"
		"}\n"
		"${INVALID_CHAR}";

	return resultTemplate;
}

static string mandelbrotFragmentTemplate (int numFractalIterations)
{
	string resultTemplate =
		"varying mediump vec2 v_coord${NAME_SPEC};\n"
		"\n"
		"precision mediump float;\n"
		"\n"
		"#define NUM_ITERS " + de::toString(numFractalIterations) + "\n"
		"\n"
		"void main (void)\n"
		"{\n"
		"	vec2 coords = v_coord${NAME_SPEC};\n"
		"	float u_limit = 2.0 * 2.0;\n"
		"	vec2 tmp = vec2(0, 0);\n"
		"	int iter;\n"
		"\n"
		"	for (iter = 0; iter < NUM_ITERS; iter++)\n"
		"	{\n"
		"		tmp = vec2((tmp.x + tmp.y) * (tmp.x - tmp.y), 2.0 * (tmp.x * tmp.y)) + coords;\n"
		"\n"
		"		if (dot(tmp, tmp) > u_limit)\n"
		"			break;\n"
		"	}\n"
		"\n"
		"	vec3 color = vec3(float(iter) * (1.0 / float(NUM_ITERS)));\n"
		"\n"
		"	gl_FragColor = vec4(color, 1.0) + ${FLOAT01};\n"
		"${SEMANTIC_ERROR}"
		"}\n"
		"${INVALID_CHAR}";

	return resultTemplate;
}

static vector<ShaderCompilerCase::AttribSpec> mandelbrotShaderAttributes (const string& nameSpecialization)
{
	vector<ShaderCompilerCase::AttribSpec> result;

	result.push_back(ShaderCompilerCase::AttribSpec("a_vertex" + nameSpecialization,
													combineVec4ToVec16(Vec4(-1.0f, -1.0f,  0.0f,  1.0f),
																	   Vec4(-1.0f,  1.0f,  0.0f,  1.0f),
																	   Vec4( 1.0f, -1.0f,  0.0f,  1.0f),
																	   Vec4( 1.0f,  1.0f,  0.0f,  1.0f))));

	result.push_back(ShaderCompilerCase::AttribSpec("a_coord" + nameSpecialization,
													combineVec4ToVec16(Vec4(0.0f, 0.0f, 0.0f, 1.0f),
																	   Vec4(0.0f, 1.0f, 0.0f, 1.0f),
																	   Vec4(1.0f, 0.0f, 0.0f, 1.0f),
																	   Vec4(1.0f, 1.0f, 0.0f, 1.0f))));

	return result;
}

static vector<ShaderCompilerCase::UniformSpec> mandelbrotShaderUniforms (const string& nameSpecialization)
{
	vector<ShaderCompilerCase::UniformSpec> result;

	result.push_back(ShaderCompilerCase::UniformSpec("u_mvp" + nameSpecialization,
													 ShaderCompilerCase::UniformSpec::TYPE_MAT4,
													 arrTo16(Mat4(1.0f).getColumnMajorData())));

	return result;
}

ShaderCompilerCase::ShaderCompilerCase (Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments)
	: TestCase								(context, tcu::NODETYPE_PERFORMANCE, name, description)
	, m_viewportWidth						(0)
	, m_viewportHeight						(0)
	, m_avoidCache							(avoidCache)
	, m_addWhitespaceAndComments			(addWhitespaceAndComments)
	, m_startHash							((deUint32)(deUint64Hash(deGetTime()) ^ deUint64Hash(deGetMicroseconds()) ^ deInt32Hash(caseID)))
{
	int cmdLineIterCount = context.getTestContext().getCommandLine().getTestIterationCount();
	m_minimumMeasurementCount = cmdLineIterCount > 0 ? cmdLineIterCount : DEFAULT_MINIMUM_MEASUREMENT_COUNT;
	m_maximumMeasurementCount = m_minimumMeasurementCount*3;
}

ShaderCompilerCase::~ShaderCompilerCase (void)
{
}

deUint32 ShaderCompilerCase::getSpecializationID (int measurementNdx) const
{
	if (m_avoidCache)
		return m_startHash ^ (deUint32)deInt32Hash((deInt32)measurementNdx);
	else
		return m_startHash;
}

void ShaderCompilerCase::init (void)
{
	const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
	const tcu::RenderTarget&	renderTarget	= m_context.getRenderContext().getRenderTarget();

	m_viewportWidth		= deMin32(MAX_VIEWPORT_WIDTH, renderTarget.getWidth());
	m_viewportHeight	= deMin32(MAX_VIEWPORT_HEIGHT, renderTarget.getHeight());

	gl.viewport(0, 0, m_viewportWidth, m_viewportHeight);
}

ShaderCompilerCase::ShadersAndProgram ShaderCompilerCase::createShadersAndProgram (void) const
{
	const glw::Functions&	gl = m_context.getRenderContext().getFunctions();
	ShadersAndProgram		result;

	result.vertShader	= gl.createShader(GL_VERTEX_SHADER);
	result.fragShader	= gl.createShader(GL_FRAGMENT_SHADER);
	result.program		= gl.createProgram();

	gl.attachShader(result.program, result.vertShader);
	gl.attachShader(result.program, result.fragShader);

	return result;
}

void ShaderCompilerCase::setShaderSources (deUint32 vertShader, deUint32 fragShader, const ProgramContext& progCtx) const
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	const char* vertShaderSourceCStr = progCtx.vertShaderSource.c_str();
	const char* fragShaderSourceCStr = progCtx.fragShaderSource.c_str();
	gl.shaderSource(vertShader, 1, &vertShaderSourceCStr, DE_NULL);
	gl.shaderSource(fragShader, 1, &fragShaderSourceCStr, DE_NULL);
}

bool ShaderCompilerCase::compileShader (deUint32 shader) const
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	GLint status = 0;
	gl.compileShader(shader);
	gl.getShaderiv(shader, GL_COMPILE_STATUS, &status);
	return status != 0;
}

bool ShaderCompilerCase::linkAndUseProgram (deUint32 program) const
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	GLint linkStatus = 0;

	gl.linkProgram(program);
	gl.getProgramiv(program, GL_LINK_STATUS, &linkStatus);

	if (linkStatus != 0)
		gl.useProgram(program);

	return linkStatus != 0;
}

void ShaderCompilerCase::setShaderInputs (deUint32 program, const ProgramContext& progCtx) const
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	// Setup attributes.

	for (int attribNdx = 0; attribNdx < (int)progCtx.vertexAttributes.size(); attribNdx++)
	{
		int location = gl.getAttribLocation(program, progCtx.vertexAttributes[attribNdx].name.c_str());
		if (location >= 0)
		{
			gl.enableVertexAttribArray(location);
			gl.vertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, 0, progCtx.vertexAttributes[attribNdx].value.getPtr());
		}
	}

	// Setup uniforms.

	for (int uniformNdx = 0; uniformNdx < (int)progCtx.uniforms.size(); uniformNdx++)
	{
		int location = gl.getUniformLocation(program, progCtx.uniforms[uniformNdx].name.c_str());
		if (location >= 0)
		{
			const float* floatPtr = progCtx.uniforms[uniformNdx].value.getPtr();

			switch (progCtx.uniforms[uniformNdx].type)
			{
				case UniformSpec::TYPE_FLOAT:			gl.uniform1fv(location, 1, floatPtr);								break;
				case UniformSpec::TYPE_VEC2:			gl.uniform2fv(location, 1, floatPtr);								break;
				case UniformSpec::TYPE_VEC3:			gl.uniform3fv(location, 1, floatPtr);								break;
				case UniformSpec::TYPE_VEC4:			gl.uniform4fv(location, 1, floatPtr);								break;
				case UniformSpec::TYPE_MAT3:			gl.uniformMatrix3fv(location, 1, GL_FALSE, floatPtr);				break;
				case UniformSpec::TYPE_MAT4:			gl.uniformMatrix4fv(location, 1, GL_FALSE, floatPtr);				break;
				case UniformSpec::TYPE_TEXTURE_UNIT:	gl.uniform1i(location, (GLint)deRoundFloatToInt32(*floatPtr));		break;
				default:
					DE_ASSERT(DE_FALSE);
			}
		}
	}
}

void ShaderCompilerCase::draw (void) const
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	static const deUint8 indices[] =
	{
		0, 1, 2,
		2, 1, 3
	};

	gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
	gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(indices), GL_UNSIGNED_BYTE, indices);

	// \note Read one pixel to force compilation.
	deUint32 pixel;
	gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
}

void ShaderCompilerCase::cleanup (const ShadersAndProgram& shadersAndProgram, const ProgramContext& progCtx, bool linkSuccess) const
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (linkSuccess)
	{
		for (int attribNdx = 0; attribNdx < (int)progCtx.vertexAttributes.size(); attribNdx++)
		{
			int location = gl.getAttribLocation(shadersAndProgram.program, progCtx.vertexAttributes[attribNdx].name.c_str());
			if (location >= 0)
				gl.disableVertexAttribArray(location);
		}
	}

	gl.useProgram(0);
	gl.detachShader(shadersAndProgram.program, shadersAndProgram.vertShader);
	gl.detachShader(shadersAndProgram.program, shadersAndProgram.fragShader);
	gl.deleteShader(shadersAndProgram.vertShader);
	gl.deleteShader(shadersAndProgram.fragShader);
	gl.deleteProgram(shadersAndProgram.program);
}

void ShaderCompilerCase::logProgramData (const BuildInfo& buildInfo, const ProgramContext& progCtx) const
{
	m_testCtx.getLog() << TestLog::ShaderProgram(buildInfo.linkSuccess, buildInfo.logs.link)
					   << TestLog::Shader(QP_SHADER_TYPE_VERTEX,	progCtx.vertShaderSource, buildInfo.vertCompileSuccess, buildInfo.logs.vert)
					   << TestLog::Shader(QP_SHADER_TYPE_FRAGMENT,	progCtx.fragShaderSource, buildInfo.fragCompileSuccess, buildInfo.logs.frag)
					   << TestLog::EndShaderProgram;
}

ShaderCompilerCase::Logs ShaderCompilerCase::getLogs (const ShadersAndProgram& shadersAndProgram) const
{
	const glw::Functions&	gl = m_context.getRenderContext().getFunctions();
	Logs					result;

	result.vert = getShaderInfoLog(gl, shadersAndProgram.vertShader);
	result.frag = getShaderInfoLog(gl, shadersAndProgram.fragShader);
	result.link = getProgramInfoLog(gl, shadersAndProgram.program);

	return result;
}

bool ShaderCompilerCase::goodEnoughMeasurements (const vector<Measurement>& measurements) const
{
	if ((int)measurements.size() < m_minimumMeasurementCount)
		return false;
	else
	{
		if ((int)measurements.size() >= m_maximumMeasurementCount)
			return true;
		else
		{
			vector<deInt64> totalTimesWithoutDraw;
			for (int i = 0; i < (int)measurements.size(); i++)
				totalTimesWithoutDraw.push_back(measurements[i].totalTimeWithoutDraw());
			return vectorFloatRelativeMedianAbsoluteDeviation(vectorLowestPercentage(totalTimesWithoutDraw, 0.5f)) < RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD;
		}
	}
}

ShaderCompilerCase::IterateResult ShaderCompilerCase::iterate (void)
{
	// Before actual measurements, compile and draw with a dummy shader to avoid possible initial slowdowns in the actual test.
	{
		deUint32		specID = getSpecializationID(0);
		ProgramContext	progCtx;
		progCtx.vertShaderSource = specializeShaderSource(singleVaryingVertexTemplate(), specID, SHADER_VALIDITY_VALID);
		progCtx.fragShaderSource = specializeShaderSource(singleVaryingFragmentTemplate(), specID, SHADER_VALIDITY_VALID);
		progCtx.vertexAttributes = singleValueShaderAttributes(getNameSpecialization(specID));

		ShadersAndProgram shadersAndProgram = createShadersAndProgram();
		setShaderSources(shadersAndProgram.vertShader, shadersAndProgram.fragShader, progCtx);

		BuildInfo buildInfo;
		buildInfo.vertCompileSuccess	= compileShader(shadersAndProgram.vertShader);
		buildInfo.fragCompileSuccess	= compileShader(shadersAndProgram.fragShader);
		buildInfo.linkSuccess			= linkAndUseProgram(shadersAndProgram.program);
		if (!(buildInfo.vertCompileSuccess && buildInfo.fragCompileSuccess && buildInfo.linkSuccess))
		{
			buildInfo.logs = getLogs(shadersAndProgram);
			logProgramData(buildInfo, progCtx);
			cleanup(shadersAndProgram, progCtx, buildInfo.linkSuccess);
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compilation failed");
			return STOP;
		}
		setShaderInputs(shadersAndProgram.program, progCtx);
		draw();
		cleanup(shadersAndProgram, progCtx, buildInfo.linkSuccess);
	}

	vector<Measurement>		measurements;
	// \note These are logged after measurements are done.
	ProgramContext			latestProgramContext;
	BuildInfo				latestBuildInfo;

	if (WARMUP_CPU_AT_BEGINNING_OF_CASE)
		tcu::warmupCPU();

	// Actual test measurements.
	while (!goodEnoughMeasurements(measurements))
	{
		// Create shaders, compile & link, set shader inputs and draw. Time measurement is done at relevant points.
		// \note Setting inputs and drawing are done twice in order to find out the time for actual compiling.

		// \note Shader data (sources and inputs) are generated and GL shader and program objects are created before any time measurements.
		ProgramContext		progCtx				= generateShaderData((int)measurements.size());
		ShadersAndProgram	shadersAndProgram	= createShadersAndProgram();
		BuildInfo			buildInfo;

		if (m_addWhitespaceAndComments)
		{
			const deUint32 hash = m_startHash ^ (deUint32)deInt32Hash((deInt32)measurements.size());
			progCtx.vertShaderSource = strWithWhiteSpaceAndComments(progCtx.vertShaderSource, hash);
			progCtx.fragShaderSource = strWithWhiteSpaceAndComments(progCtx.fragShaderSource, hash);
		}

		if (WARMUP_CPU_BEFORE_EACH_MEASUREMENT)
			tcu::warmupCPU();

		// \note Do NOT do anything too hefty between the first and last deGetMicroseconds() here (other than the gl calls); it would disturb the measurement.

		deUint64 startTime = deGetMicroseconds();

		setShaderSources(shadersAndProgram.vertShader, shadersAndProgram.fragShader, progCtx);
		deUint64 shaderSourceSetEndTime = deGetMicroseconds();

		buildInfo.vertCompileSuccess = compileShader(shadersAndProgram.vertShader);
		deUint64 vertexShaderCompileEndTime = deGetMicroseconds();

		buildInfo.fragCompileSuccess = compileShader(shadersAndProgram.fragShader);
		deUint64 fragmentShaderCompileEndTime = deGetMicroseconds();

		buildInfo.linkSuccess = linkAndUseProgram(shadersAndProgram.program);
		deUint64 programLinkEndTime = deGetMicroseconds();

		// Check compilation and linking status here, after all compilation and linking gl calls are made.
		if (!(buildInfo.vertCompileSuccess && buildInfo.fragCompileSuccess && buildInfo.linkSuccess))
		{
			buildInfo.logs = getLogs(shadersAndProgram);
			logProgramData(buildInfo, progCtx);
			cleanup(shadersAndProgram, progCtx, buildInfo.linkSuccess);
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compilation failed");
			return STOP;
		}

		setShaderInputs(shadersAndProgram.program, progCtx);
		deUint64 firstShaderInputSetEndTime = deGetMicroseconds();

		// Draw for the first time.
		draw();
		deUint64 firstDrawEndTime = deGetMicroseconds();

		// Set inputs and draw again.

		setShaderInputs(shadersAndProgram.program, progCtx);
		deUint64 secondShaderInputSetEndTime = deGetMicroseconds();

		draw();
		deUint64 secondDrawEndTime = deGetMicroseconds();

		// De-initializations (detach shaders etc.).

		buildInfo.logs = getLogs(shadersAndProgram);
		cleanup(shadersAndProgram, progCtx, buildInfo.linkSuccess);

		// Output measurement log later (after last measurement).

		measurements.push_back(Measurement((deInt64)(shaderSourceSetEndTime			- startTime),
										   (deInt64)(vertexShaderCompileEndTime		- shaderSourceSetEndTime),
										   (deInt64)(fragmentShaderCompileEndTime	- vertexShaderCompileEndTime),
										   (deInt64)(programLinkEndTime				- fragmentShaderCompileEndTime),
										   (deInt64)(firstShaderInputSetEndTime		- programLinkEndTime),
										   (deInt64)(firstDrawEndTime				- firstShaderInputSetEndTime),
										   (deInt64)(secondShaderInputSetEndTime	- firstDrawEndTime),
										   (deInt64)(secondDrawEndTime				- secondShaderInputSetEndTime)));

		latestBuildInfo			= buildInfo;
		latestProgramContext	= progCtx;

		m_testCtx.touchWatchdog(); // \note Measurements may take a while in a bad case.
	}

	// End of test case, log information about measurements.
	{
		TestLog& log = m_testCtx.getLog();

		vector<deInt64> sourceSetTimes;
		vector<deInt64> vertexCompileTimes;
		vector<deInt64> fragmentCompileTimes;
		vector<deInt64> programLinkTimes;
		vector<deInt64> firstInputSetTimes;
		vector<deInt64> firstDrawTimes;
		vector<deInt64> secondInputTimes;
		vector<deInt64> secondDrawTimes;
		vector<deInt64> firstPhaseTimes;
		vector<deInt64> secondPhaseTimes;
		vector<deInt64> totalTimesWithoutDraw;
		vector<deInt64> specializationTimes;

		if (!m_avoidCache)
			log << TestLog::Message << "Note: Testing cache hits, so the medians and averages exclude the first iteration." << TestLog::EndMessage;

		log << TestLog::Message << "Note: \"Specialization time\" means first draw time minus second draw time." << TestLog::EndMessage
			<< TestLog::Message << "Note: \"Compilation time\" means the time up to (and including) linking, plus specialization time." << TestLog::EndMessage;

		log << TestLog::Section("IterationMeasurements", "Iteration measurements of compilation and linking times");

		DE_ASSERT((int)measurements.size() > (m_avoidCache ? 0 : 1));

		for (int ndx = 0; ndx < (int)measurements.size(); ndx++)
		{
			const Measurement& curMeas = measurements[ndx];

			// Subtract time of second phase (second input setup and draw) from first (from start to end of first draw).
			// \note Cap if second phase seems unreasonably high (higher than first input set and draw).
			deInt64 timeWithoutDraw		= curMeas.totalTimeWithoutDraw();

			// Specialization time = first draw - second draw time. Again, cap at 0 if second draw was longer than first draw.
			deInt64 specializationTime	= de::max<deInt64>(0, curMeas.firstDrawTime - curMeas.secondDrawTime);

			if (ndx > 0 || m_avoidCache) // \note When allowing cache hits, don't account for the first measurement when calculating median or average.
			{
				sourceSetTimes.push_back		(curMeas.sourceSetTime);
				vertexCompileTimes.push_back	(curMeas.vertexCompileTime);
				fragmentCompileTimes.push_back	(curMeas.fragmentCompileTime);
				programLinkTimes.push_back		(curMeas.programLinkTime);
				firstInputSetTimes.push_back	(curMeas.firstInputSetTime);
				firstDrawTimes.push_back		(curMeas.firstDrawTime);
				firstPhaseTimes.push_back		(curMeas.firstPhase());
				secondDrawTimes.push_back		(curMeas.secondDrawTime);
				secondInputTimes.push_back		(curMeas.secondInputSetTime);
				secondPhaseTimes.push_back		(curMeas.secondPhase());
				totalTimesWithoutDraw.push_back	(timeWithoutDraw);
				specializationTimes.push_back	(specializationTime);
			}

			// Log this measurement.
			log << TestLog::Float("Measurement" + de::toString(ndx) + "CompilationTime",
								  "Measurement " + de::toString(ndx) + " compilation time",
								  "ms", QP_KEY_TAG_TIME, (float)timeWithoutDraw / 1000.0f)
				<< TestLog::Float("Measurement" + de::toString(ndx) + "SpecializationTime",
								  "Measurement " + de::toString(ndx) + " specialization time",
								  "ms", QP_KEY_TAG_TIME, (float)specializationTime / 1000.0f);
		}

		// Log some statistics.

		for (int entireRangeOrLowestHalf = 0; entireRangeOrLowestHalf < 2; entireRangeOrLowestHalf++)
		{
			bool				isEntireRange				= entireRangeOrLowestHalf == 0;
			string				statNamePrefix				= isEntireRange ? "" : "LowestHalf";
			vector<deInt64>		rangeTotalTimes				= isEntireRange ? totalTimesWithoutDraw	: vectorLowestPercentage(totalTimesWithoutDraw,	0.5f);
			vector<deInt64>		rangeSpecializationTimes	= isEntireRange ? specializationTimes	: vectorLowestPercentage(specializationTimes,	0.5f);

#define LOG_COMPILE_SPECIALIZE_TIME_STAT(NAME, DESC, FUNC)																													\
	log << TestLog::Float(statNamePrefix + "CompilationTime" + (NAME), (DESC) + string(" of compilation time"), "ms", QP_KEY_TAG_TIME, (FUNC)(rangeTotalTimes)/1000.0f)		\
		<< TestLog::Float(statNamePrefix + "SpecializationTime" + (NAME), (DESC) + string(" of specialization time"), "ms", QP_KEY_TAG_TIME, (FUNC)(rangeSpecializationTimes)/1000.0f)

#define LOG_COMPILE_SPECIALIZE_RELATIVE_STAT(NAME, DESC, FUNC)																										\
	log << TestLog::Float(statNamePrefix + "CompilationTime" + (NAME), (DESC) + string(" of compilation time"), "", QP_KEY_TAG_NONE, (FUNC)(rangeTotalTimes))		\
		<< TestLog::Float(statNamePrefix + "SpecializationTime" + (NAME), (DESC) + string(" of specialization time"), "", QP_KEY_TAG_NONE, (FUNC)(rangeSpecializationTimes))

			log << TestLog::Message << "\nStatistics computed from "
									<< (isEntireRange ? "all" : "only the lowest 50%")
									<< " of the above measurements:"
									<< TestLog::EndMessage;

			LOG_COMPILE_SPECIALIZE_TIME_STAT		("Median",							"Median",								vectorFloatMedian);
			LOG_COMPILE_SPECIALIZE_TIME_STAT		("Average",							"Average",								vectorFloatAverage);
			LOG_COMPILE_SPECIALIZE_TIME_STAT		("Minimum",							"Minimum",								vectorFloatMinimum);
			LOG_COMPILE_SPECIALIZE_TIME_STAT		("Maximum",							"Maximum",								vectorFloatMaximum);
			LOG_COMPILE_SPECIALIZE_TIME_STAT		("MedianAbsoluteDeviation",			"Median absolute deviation",			vectorFloatMedianAbsoluteDeviation);
			LOG_COMPILE_SPECIALIZE_RELATIVE_STAT	("RelativeMedianAbsoluteDeviation",	"Relative median absolute deviation",	vectorFloatRelativeMedianAbsoluteDeviation);
			LOG_COMPILE_SPECIALIZE_TIME_STAT		("StandardDeviation",				"Standard deviation",					vectorFloatStandardDeviation);
			LOG_COMPILE_SPECIALIZE_RELATIVE_STAT	("RelativeStandardDeviation",		"Relative standard deviation",			vectorFloatRelativeStandardDeviation);
			LOG_COMPILE_SPECIALIZE_TIME_STAT		("MaxMinusMin",						"Max-min",								vectorFloatMaximumMinusMinimum);
			LOG_COMPILE_SPECIALIZE_RELATIVE_STAT	("RelativeMaxMinusMin",				"Relative max-min",						vectorFloatRelativeMaximumMinusMinimum);

#undef LOG_COMPILE_SPECIALIZE_RELATIVE_STAT
#undef LOG_COMPILE_SPECIALIZE_TIME_STAT

			if (!isEntireRange && vectorFloatRelativeMedianAbsoluteDeviation(rangeTotalTimes) > RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD)
				log << TestLog::Message << "\nWARNING: couldn't achieve relative median absolute deviation under threshold value "
										<< RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD
										<< " for compilation time of the lowest 50% of measurements" << TestLog::EndMessage;
		}

		log << TestLog::EndSection; // End section IterationMeasurements

		for (int medianOrAverage = 0; medianOrAverage < 2; medianOrAverage++)
		{
			typedef float (*VecFunc)(const vector<deInt64>&);

			bool	isMedian						= medianOrAverage == 0;
			string	singular						= isMedian ? "Median" : "Average";
			string	plural							= singular + "s";
			VecFunc	func							= isMedian ? (VecFunc) vectorFloatMedian<deInt64> : (VecFunc) vectorFloatAverage<deInt64>;

			log << TestLog::Section(plural + "PerPhase", plural + " per phase");

			for (int entireRangeOrLowestHalf = 0; entireRangeOrLowestHalf < 2; entireRangeOrLowestHalf++)
			{
				bool	isEntireRange	= entireRangeOrLowestHalf == 0;
				string	statNamePrefix	= isEntireRange ? "" : "LowestHalf";
				float	rangeSizeRatio	= isEntireRange ? 1.0f : 0.5f;

#define LOG_TIME(NAME, DESC, DATA) log << TestLog::Float(statNamePrefix + (NAME) + singular, singular + " of " + (DESC), "ms", QP_KEY_TAG_TIME, func(vectorLowestPercentage((DATA), rangeSizeRatio))/1000.0f);

				log << TestLog::Message << (isEntireRange ? "For all measurements:" : "\nFor only the lowest 50% of the measurements:") << TestLog::EndMessage;
				LOG_TIME("ShaderSourceSetTime",			"shader source set time",			sourceSetTimes);
				LOG_TIME("VertexShaderCompileTime",		"vertex shader compile time",		vertexCompileTimes);
				LOG_TIME("FragmentShaderCompileTime",	"fragment shader compile time",		fragmentCompileTimes);
				LOG_TIME("ProgramLinkTime",				"program link time",				programLinkTimes);
				LOG_TIME("FirstShaderInputSetTime",		"first shader input set time",		firstInputSetTimes);
				LOG_TIME("FirstDrawTime",				"first draw time",					firstDrawTimes);
				LOG_TIME("SecondShaderInputSetTime",	"second shader input set time",		secondInputTimes);
				LOG_TIME("SecondDrawTime",				"second draw time",					secondDrawTimes);

#undef LOG_TIME
			}

			log << TestLog::EndSection;
		}

		// Set result.

		{
			log << TestLog::Message << "Note: test result is the first quartile (i.e. median of the lowest half of measurements) of compilation times" << TestLog::EndMessage;
			float result = vectorFloatFirstQuartile(totalTimesWithoutDraw) / 1000.0f;
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(result, 2).c_str());
		}

		// Log shaders.

		if (m_avoidCache || m_addWhitespaceAndComments)
		{
			string msg = "Note: the following shaders are the ones from the last iteration; ";

			if (m_avoidCache)
				msg += "variables' names and some constant expressions";
			if (m_addWhitespaceAndComments)
				msg += string(m_avoidCache ? " as well as " : "") + "whitespace and comments";

			msg += " differ between iterations.";

			log << TestLog::Message << msg.c_str() << TestLog::EndMessage;
		}

		logProgramData(latestBuildInfo, latestProgramContext);

		return STOP;
	}
}

ShaderCompilerLightCase::ShaderCompilerLightCase (Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, bool isVertexCase, int numLights, LightType lightType)
	: ShaderCompilerCase	(context, name, description, caseID, avoidCache, addWhitespaceAndComments)
	, m_numLights			(numLights)
	, m_isVertexCase		(isVertexCase)
	, m_lightType			(lightType)
	, m_texture				(DE_NULL)
{
}

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

void ShaderCompilerLightCase::deinit (void)
{
	delete m_texture;
	m_texture = DE_NULL;
}

void ShaderCompilerLightCase::init (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	// Setup texture.

	DE_ASSERT(m_texture == DE_NULL);

	m_texture = new glu::Texture2D(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, TEXTURE_WIDTH, TEXTURE_HEIGHT);

	tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());

	m_texture->getRefTexture().allocLevel(0);
	tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), fmtInfo.valueMin, fmtInfo.valueMax);

	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	m_texture->upload();

	ShaderCompilerCase::init();
}

ShaderCompilerCase::ProgramContext ShaderCompilerLightCase::generateShaderData (int measurementNdx) const
{
	deUint32		specID		= getSpecializationID(measurementNdx);
	string			nameSpec	= getNameSpecialization(specID);
	ProgramContext	result;

	result.vertShaderSource		= specializeShaderSource(lightVertexTemplate(m_numLights, m_isVertexCase, m_lightType), specID, SHADER_VALIDITY_VALID);
	result.fragShaderSource		= specializeShaderSource(lightFragmentTemplate(m_numLights, m_isVertexCase, m_lightType), specID, SHADER_VALIDITY_VALID);
	result.vertexAttributes		= lightShaderAttributes(nameSpec);
	result.uniforms				= lightShaderUniforms(nameSpec, m_numLights, m_lightType);

	return result;
}

ShaderCompilerTextureCase::ShaderCompilerTextureCase (Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, int numLookups, ConditionalUsage conditionalUsage, ConditionalType conditionalType)
	: ShaderCompilerCase	(context, name, description, caseID, avoidCache, addWhitespaceAndComments)
	, m_numLookups			(numLookups)
	, m_conditionalUsage	(conditionalUsage)
	, m_conditionalType		(conditionalType)
{
}

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

void ShaderCompilerTextureCase::deinit (void)
{
	for (vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
		delete *i;
	m_textures.clear();
}

void ShaderCompilerTextureCase::init (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	// Setup texture.

	DE_ASSERT(m_textures.empty());

	m_textures.reserve(m_numLookups);

	for (int i = 0; i < m_numLookups; i++)
	{
		glu::Texture2D*			tex		= new glu::Texture2D(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, TEXTURE_WIDTH, TEXTURE_HEIGHT);
		tcu::TextureFormatInfo	fmtInfo	= tcu::getTextureFormatInfo(tex->getRefTexture().getFormat());

		tex->getRefTexture().allocLevel(0);
		tcu::fillWithComponentGradients(tex->getRefTexture().getLevel(0), fmtInfo.valueMin, fmtInfo.valueMax);

		gl.activeTexture(GL_TEXTURE0 + i);
		gl.bindTexture(GL_TEXTURE_2D, tex->getGLTexture());
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		tex->upload();

		m_textures.push_back(tex);
	}

	ShaderCompilerCase::init();
}

ShaderCompilerCase::ProgramContext ShaderCompilerTextureCase::generateShaderData (int measurementNdx) const
{
	deUint32		specID		= getSpecializationID(measurementNdx);
	string			nameSpec	= getNameSpecialization(specID);
	ProgramContext	result;

	result.vertShaderSource		= specializeShaderSource(textureLookupVertexTemplate(m_conditionalUsage, m_conditionalType), specID, SHADER_VALIDITY_VALID);
	result.fragShaderSource		= specializeShaderSource(textureLookupFragmentTemplate(m_numLookups, m_conditionalUsage, m_conditionalType), specID, SHADER_VALIDITY_VALID);
	result.vertexAttributes		= textureLookupShaderAttributes(nameSpec, m_conditionalUsage, m_conditionalType);
	result.uniforms				= textureLookupShaderUniforms(nameSpec, m_numLookups, m_conditionalUsage, m_conditionalType);

	return result;
}

ShaderCompilerLoopCase::ShaderCompilerLoopCase (Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, bool isVertexCase, LoopType type, int numLoopIterations, int nestingDepth)
	: ShaderCompilerCase	(context, name, description, caseID, avoidCache, addWhitespaceAndComments)
	, m_numLoopIterations	(numLoopIterations)
	, m_nestingDepth		(nestingDepth)
	, m_isVertexCase		(isVertexCase)
	, m_type				(type)
{
}

ShaderCompilerLoopCase::~ShaderCompilerLoopCase (void)
{
}

ShaderCompilerCase::ProgramContext ShaderCompilerLoopCase::generateShaderData (int measurementNdx) const
{
	deUint32		specID		= getSpecializationID(measurementNdx);
	string			nameSpec	= getNameSpecialization(specID);
	ProgramContext	result;

	result.vertShaderSource		= specializeShaderSource(loopVertexTemplate(m_type, m_isVertexCase, m_numLoopIterations, m_nestingDepth), specID, SHADER_VALIDITY_VALID);
	result.fragShaderSource		= specializeShaderSource(loopFragmentTemplate(m_type, m_isVertexCase, m_numLoopIterations, m_nestingDepth), specID, SHADER_VALIDITY_VALID);

	result.vertexAttributes		= loopShaderAttributes(nameSpec, m_type, m_numLoopIterations);
	result.uniforms				= loopShaderUniforms(nameSpec, m_type, m_numLoopIterations);

	return result;
}

ShaderCompilerOperCase::ShaderCompilerOperCase (Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, bool isVertexCase, const char* oper, int numOperations)
	: ShaderCompilerCase	(context, name, description, caseID, avoidCache, addWhitespaceAndComments)
	, m_oper				(oper)
	, m_numOperations		(numOperations)
	, m_isVertexCase		(isVertexCase)
{
}

ShaderCompilerOperCase::~ShaderCompilerOperCase (void)
{
}

ShaderCompilerCase::ProgramContext ShaderCompilerOperCase::generateShaderData (int measurementNdx) const
{
	deUint32		specID		= getSpecializationID(measurementNdx);
	string			nameSpec	= getNameSpecialization(specID);
	ProgramContext	result;

	if (m_isVertexCase)
	{
		result.vertShaderSource = specializeShaderSource(binaryOpVertexTemplate(m_numOperations, m_oper.c_str()), specID, SHADER_VALIDITY_VALID);
		result.fragShaderSource = specializeShaderSource(singleVaryingFragmentTemplate(), specID, SHADER_VALIDITY_VALID);
	}
	else
	{
		result.vertShaderSource = specializeShaderSource(singleVaryingVertexTemplate(), specID, SHADER_VALIDITY_VALID);
		result.fragShaderSource = specializeShaderSource(binaryOpFragmentTemplate(m_numOperations, m_oper.c_str()), specID, SHADER_VALIDITY_VALID);
	}

	result.vertexAttributes = singleValueShaderAttributes(nameSpec);

	result.uniforms.clear(); // No uniforms used.

	return result;
}

ShaderCompilerMandelbrotCase::ShaderCompilerMandelbrotCase (Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, int numFractalIterations)
	: ShaderCompilerCase		(context, name, description, caseID, avoidCache, addWhitespaceAndComments)
	, m_numFractalIterations	(numFractalIterations)
{
}

ShaderCompilerMandelbrotCase::~ShaderCompilerMandelbrotCase (void)
{
}

ShaderCompilerCase::ProgramContext ShaderCompilerMandelbrotCase::generateShaderData (int measurementNdx) const
{
	deUint32		specID		= getSpecializationID(measurementNdx);
	string			nameSpec	= getNameSpecialization(specID);
	ProgramContext	result;

	result.vertShaderSource = specializeShaderSource(mandelbrotVertexTemplate(), specID, SHADER_VALIDITY_VALID);
	result.fragShaderSource = specializeShaderSource(mandelbrotFragmentTemplate(m_numFractalIterations), specID, SHADER_VALIDITY_VALID);

	result.vertexAttributes = mandelbrotShaderAttributes(nameSpec);
	result.uniforms = mandelbrotShaderUniforms(nameSpec);

	return result;
}

InvalidShaderCompilerCase::InvalidShaderCompilerCase (Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType)
	: TestCase						(context, tcu::NODETYPE_PERFORMANCE, name, description)
	, m_invalidityType				(invalidityType)
	, m_startHash					((deUint32)(deUint64Hash(deGetTime()) ^ deUint64Hash(deGetMicroseconds()) ^ deInt32Hash(caseID)))
{
	int cmdLineIterCount = context.getTestContext().getCommandLine().getTestIterationCount();
	m_minimumMeasurementCount = cmdLineIterCount > 0 ? cmdLineIterCount : DEFAULT_MINIMUM_MEASUREMENT_COUNT;
	m_maximumMeasurementCount = 3*m_minimumMeasurementCount;
}

InvalidShaderCompilerCase::~InvalidShaderCompilerCase (void)
{
}

deUint32 InvalidShaderCompilerCase::getSpecializationID (int measurementNdx) const
{
	return m_startHash ^ (deUint32)deInt32Hash((deInt32)measurementNdx);
}

InvalidShaderCompilerCase::Shaders InvalidShaderCompilerCase::createShaders (void) const
{
	const glw::Functions&	gl = m_context.getRenderContext().getFunctions();
	Shaders					result;

	result.vertShader = gl.createShader(GL_VERTEX_SHADER);
	result.fragShader = gl.createShader(GL_FRAGMENT_SHADER);

	return result;
}

void InvalidShaderCompilerCase::setShaderSources (const Shaders& shaders, const ProgramContext& progCtx) const
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	const char* vertShaderSourceCStr = progCtx.vertShaderSource.c_str();
	const char* fragShaderSourceCStr = progCtx.fragShaderSource.c_str();
	gl.shaderSource(shaders.vertShader, 1, &vertShaderSourceCStr, DE_NULL);
	gl.shaderSource(shaders.fragShader, 1, &fragShaderSourceCStr, DE_NULL);
}

bool InvalidShaderCompilerCase::compileShader (deUint32 shader) const
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	GLint status;
	gl.compileShader(shader);
	gl.getShaderiv(shader, GL_COMPILE_STATUS, &status);
	return status != 0;
}

void InvalidShaderCompilerCase::logProgramData (const BuildInfo& buildInfo, const ProgramContext& progCtx) const
{
	m_testCtx.getLog() << TestLog::ShaderProgram(false, "(No linking done)")
					   << TestLog::Shader(QP_SHADER_TYPE_VERTEX,	progCtx.vertShaderSource, buildInfo.vertCompileSuccess, buildInfo.logs.vert)
					   << TestLog::Shader(QP_SHADER_TYPE_FRAGMENT,	progCtx.fragShaderSource, buildInfo.fragCompileSuccess, buildInfo.logs.frag)
					   << TestLog::EndShaderProgram;
}

InvalidShaderCompilerCase::Logs InvalidShaderCompilerCase::getLogs (const Shaders& shaders) const
{
	const glw::Functions&	gl = m_context.getRenderContext().getFunctions();
	Logs					result;

	result.vert = getShaderInfoLog(gl, shaders.vertShader);
	result.frag = getShaderInfoLog(gl, shaders.fragShader);

	return result;
}

void InvalidShaderCompilerCase::cleanup (const Shaders& shaders) const
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.deleteShader(shaders.vertShader);
	gl.deleteShader(shaders.fragShader);
}

bool InvalidShaderCompilerCase::goodEnoughMeasurements (const vector<Measurement>& measurements) const
{
	if ((int)measurements.size() < m_minimumMeasurementCount)
		return false;
	else
	{
		if ((int)measurements.size() >= m_maximumMeasurementCount)
			return true;
		else
		{
			vector<deInt64> totalTimes;
			for (int i = 0; i < (int)measurements.size(); i++)
				totalTimes.push_back(measurements[i].totalTime());
			return vectorFloatRelativeMedianAbsoluteDeviation(vectorLowestPercentage(totalTimes, 0.5f)) < RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD;
		}
	}
}

InvalidShaderCompilerCase::IterateResult InvalidShaderCompilerCase::iterate (void)
{
	ShaderValidity shaderValidity = m_invalidityType == INVALIDITY_INVALID_CHAR		? SHADER_VALIDITY_INVALID_CHAR
								  : m_invalidityType == INVALIDITY_SEMANTIC_ERROR	? SHADER_VALIDITY_SEMANTIC_ERROR
								  : SHADER_VALIDITY_LAST;

	DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);

	// Before actual measurements, compile a dummy shader to avoid possible initial slowdowns in the actual test.
	{
		deUint32		specID = getSpecializationID(0);
		ProgramContext	progCtx;
		progCtx.vertShaderSource = specializeShaderSource(singleVaryingVertexTemplate(), specID, shaderValidity);
		progCtx.fragShaderSource = specializeShaderSource(singleVaryingFragmentTemplate(), specID, shaderValidity);

		Shaders shaders = createShaders();
		setShaderSources(shaders, progCtx);

		BuildInfo buildInfo;
		buildInfo.vertCompileSuccess = compileShader(shaders.vertShader);
		buildInfo.fragCompileSuccess = compileShader(shaders.fragShader);
		if (buildInfo.vertCompileSuccess || buildInfo.fragCompileSuccess)
		{
			buildInfo.logs = getLogs(shaders);
			logProgramData(buildInfo, progCtx);
			cleanup(shaders);
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compilation of a shader erroneously succeeded");
			return STOP;
		}
		cleanup(shaders);
	}

	vector<Measurement>		measurements;
	// \note These are logged after measurements are done.
	ProgramContext			latestProgramContext;
	BuildInfo				latestBuildInfo;

	if (WARMUP_CPU_AT_BEGINNING_OF_CASE)
		tcu::warmupCPU();

	// Actual test measurements.
	while (!goodEnoughMeasurements(measurements))
	{
		// Create shader and compile. Measure time.

		// \note Shader sources are generated and GL shader objects are created before any time measurements.
		ProgramContext	progCtx		= generateShaderSources((int)measurements.size());
		Shaders			shaders		= createShaders();
		BuildInfo		buildInfo;

		if (WARMUP_CPU_BEFORE_EACH_MEASUREMENT)
			tcu::warmupCPU();

		// \note Do NOT do anything too hefty between the first and last deGetMicroseconds() here (other than the gl calls); it would disturb the measurement.

		deUint64 startTime = deGetMicroseconds();

		setShaderSources(shaders, progCtx);
		deUint64 shaderSourceSetEndTime = deGetMicroseconds();

		buildInfo.vertCompileSuccess = compileShader(shaders.vertShader);
		deUint64 vertexShaderCompileEndTime = deGetMicroseconds();

		buildInfo.fragCompileSuccess = compileShader(shaders.fragShader);
		deUint64 fragmentShaderCompileEndTime = deGetMicroseconds();

		buildInfo.logs = getLogs(shaders);

		// Both shader compilations should have failed.
		if (buildInfo.vertCompileSuccess || buildInfo.fragCompileSuccess)
		{
			logProgramData(buildInfo, progCtx);
			cleanup(shaders);
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compilation of a shader erroneously succeeded");
			return STOP;
		}

		// De-initializations (delete shaders).

		cleanup(shaders);

		// Output measurement log later (after last measurement).

		measurements.push_back(Measurement((deInt64)(shaderSourceSetEndTime			- startTime),
										   (deInt64)(vertexShaderCompileEndTime		- shaderSourceSetEndTime),
										   (deInt64)(fragmentShaderCompileEndTime	- vertexShaderCompileEndTime)));

		latestBuildInfo			= buildInfo;
		latestProgramContext	= progCtx;

		m_testCtx.touchWatchdog(); // \note Measurements may take a while in a bad case.
	}

	// End of test case, log information about measurements.
	{
		TestLog& log = m_testCtx.getLog();

		vector<deInt64> sourceSetTimes;
		vector<deInt64> vertexCompileTimes;
		vector<deInt64> fragmentCompileTimes;
		vector<deInt64> totalTimes;

		log << TestLog::Section("IterationMeasurements", "Iteration measurements of compilation times");

		for (int ndx = 0; ndx < (int)measurements.size(); ndx++)
		{
			sourceSetTimes.push_back		(measurements[ndx].sourceSetTime);
			vertexCompileTimes.push_back	(measurements[ndx].vertexCompileTime);
			fragmentCompileTimes.push_back	(measurements[ndx].fragmentCompileTime);
			totalTimes.push_back			(measurements[ndx].totalTime());

			// Log this measurement.
			log << TestLog::Float("Measurement" + de::toString(ndx) + "Time",
								  "Measurement " + de::toString(ndx) + " time",
								  "ms", QP_KEY_TAG_TIME, (float)measurements[ndx].totalTime()/1000.0f);
		}

		// Log some statistics.

		for (int entireRangeOrLowestHalf = 0; entireRangeOrLowestHalf < 2; entireRangeOrLowestHalf++)
		{
			bool				isEntireRange	= entireRangeOrLowestHalf == 0;
			string				statNamePrefix	= isEntireRange ? "" : "LowestHalf";
			vector<deInt64>		rangeTimes		= isEntireRange ? totalTimes : vectorLowestPercentage(totalTimes, 0.5f);

			log << TestLog::Message << "\nStatistics computed from "
									<< (isEntireRange ? "all" : "only the lowest 50%")
									<< " of the above measurements:"
									<< TestLog::EndMessage;

#define LOG_TIME_STAT(NAME, DESC, FUNC)			log << TestLog::Float(statNamePrefix + "TotalTime" + (NAME), (DESC) + string(" of total time"), "ms",	QP_KEY_TAG_TIME, (FUNC)(rangeTimes)/1000.0f)
#define LOG_RELATIVE_STAT(NAME, DESC, FUNC)		log << TestLog::Float(statNamePrefix + "TotalTime" + (NAME), (DESC) + string(" of total time"), "",		QP_KEY_TAG_NONE, (FUNC)(rangeTimes))

			LOG_TIME_STAT		("Median",							"Median",								vectorFloatMedian);
			LOG_TIME_STAT		("Average",							"Average",								vectorFloatAverage);
			LOG_TIME_STAT		("Minimum",							"Minimum",								vectorFloatMinimum);
			LOG_TIME_STAT		("Maximum",							"Maximum",								vectorFloatMaximum);
			LOG_TIME_STAT		("MedianAbsoluteDeviation",			"Median absolute deviation",			vectorFloatMedianAbsoluteDeviation);
			LOG_RELATIVE_STAT	("RelativeMedianAbsoluteDeviation",	"Relative median absolute deviation",	vectorFloatRelativeMedianAbsoluteDeviation);
			LOG_TIME_STAT		("StandardDeviation",				"Standard deviation",					vectorFloatStandardDeviation);
			LOG_RELATIVE_STAT	("RelativeStandardDeviation",		"Relative standard deviation",			vectorFloatRelativeStandardDeviation);
			LOG_TIME_STAT		("MaxMinusMin",						"Max-min",								vectorFloatMaximumMinusMinimum);
			LOG_RELATIVE_STAT	("RelativeMaxMinusMin",				"Relative max-min",						vectorFloatRelativeMaximumMinusMinimum);

#undef LOG_TIME_STAT
#undef LOG_RELATIVE_STAT

			if (!isEntireRange && vectorFloatRelativeMedianAbsoluteDeviation(rangeTimes) > RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD)
				log << TestLog::Message << "\nWARNING: couldn't achieve relative median absolute deviation under threshold value " << RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD << TestLog::EndMessage;
		}

		log << TestLog::EndSection; // End section IterationMeasurements

		for (int medianOrAverage = 0; medianOrAverage < 2; medianOrAverage++)
		{
			typedef float (*VecFunc)(const vector<deInt64>&);

			bool	isMedian						= medianOrAverage == 0;
			string	singular						= isMedian ? "Median" : "Average";
			string	plural							= singular + "s";
			VecFunc func							= isMedian ? (VecFunc) vectorFloatMedian<deInt64> : (VecFunc) vectorFloatAverage<deInt64>;

			log << TestLog::Section(plural + "PerPhase", plural + " per phase");

			for (int entireRangeOrLowestHalf = 0; entireRangeOrLowestHalf < 2; entireRangeOrLowestHalf++)
			{
				bool	isEntireRange	= entireRangeOrLowestHalf == 0;
				string	statNamePrefix	= isEntireRange ? "" : "LowestHalf";
				float	rangeSizeRatio	= isEntireRange ? 1.0f : 0.5f;

#define LOG_TIME(NAME, DESC, DATA) log << TestLog::Float(statNamePrefix + (NAME) + singular, singular + " of " + (DESC), "ms", QP_KEY_TAG_TIME, func(vectorLowestPercentage((DATA), rangeSizeRatio))/1000.0f);

				log << TestLog::Message << (isEntireRange ? "For all measurements:" : "\nFor only the lowest 50% of the measurements:") << TestLog::EndMessage;
				LOG_TIME("ShaderSourceSetTime",			"shader source set time",			sourceSetTimes);
				LOG_TIME("VertexShaderCompileTime",		"vertex shader compile time",		vertexCompileTimes);
				LOG_TIME("FragmentShaderCompileTime",	"fragment shader compile time",		fragmentCompileTimes);

#undef LOG_TIME
			}

			log << TestLog::EndSection;
		}

		// Set result.

		{
			log << TestLog::Message << "Note: test result is the first quartile (i.e. median of the lowest half of measurements) of total times" << TestLog::EndMessage;
			float result = vectorFloatFirstQuartile(totalTimes) / 1000.0f;
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(result, 2).c_str());
		}

		// Log shaders.

		log << TestLog::Message << "Note: the following shaders are the ones from the last iteration; variables' names and some constant expressions differ between iterations." << TestLog::EndMessage;

		logProgramData(latestBuildInfo, latestProgramContext);

		return STOP;
	}
}

InvalidShaderCompilerLightCase::InvalidShaderCompilerLightCase (Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, bool isVertexCase, int numLights, LightType lightType)
	: InvalidShaderCompilerCase	(context, name, description, caseID, invalidityType)
	, m_isVertexCase			(isVertexCase)
	, m_numLights				(numLights)
	, m_lightType				(lightType)
{
}

InvalidShaderCompilerLightCase::~InvalidShaderCompilerLightCase (void)
{
}

InvalidShaderCompilerCase::ProgramContext InvalidShaderCompilerLightCase::generateShaderSources (int measurementNdx) const
{
	deUint32		specID			= getSpecializationID(measurementNdx);
	ProgramContext	result;
	ShaderValidity	shaderValidity	= m_invalidityType == INVALIDITY_INVALID_CHAR	? SHADER_VALIDITY_INVALID_CHAR
									: m_invalidityType == INVALIDITY_SEMANTIC_ERROR	? SHADER_VALIDITY_SEMANTIC_ERROR
									: SHADER_VALIDITY_LAST;

	DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);

	result.vertShaderSource = specializeShaderSource(lightVertexTemplate(m_numLights, m_isVertexCase, m_lightType), specID, shaderValidity);
	result.fragShaderSource = specializeShaderSource(lightFragmentTemplate(m_numLights, m_isVertexCase, m_lightType), specID, shaderValidity);

	return result;
}

InvalidShaderCompilerTextureCase::InvalidShaderCompilerTextureCase (Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, int numLookups, ConditionalUsage conditionalUsage, ConditionalType conditionalType)
	: InvalidShaderCompilerCase	(context, name, description, caseID, invalidityType)
	, m_numLookups				(numLookups)
	, m_conditionalUsage		(conditionalUsage)
	, m_conditionalType			(conditionalType)
{
}

InvalidShaderCompilerTextureCase::~InvalidShaderCompilerTextureCase (void)
{
}

InvalidShaderCompilerCase::ProgramContext InvalidShaderCompilerTextureCase::generateShaderSources (int measurementNdx) const
{
	deUint32		specID			= getSpecializationID(measurementNdx);
	ProgramContext	result;
	ShaderValidity	shaderValidity	= m_invalidityType == INVALIDITY_INVALID_CHAR	? SHADER_VALIDITY_INVALID_CHAR
									: m_invalidityType == INVALIDITY_SEMANTIC_ERROR	? SHADER_VALIDITY_SEMANTIC_ERROR
									: SHADER_VALIDITY_LAST;

	DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);

	result.vertShaderSource = specializeShaderSource(textureLookupVertexTemplate(m_conditionalUsage, m_conditionalType), specID, shaderValidity);
	result.fragShaderSource = specializeShaderSource(textureLookupFragmentTemplate(m_numLookups, m_conditionalUsage, m_conditionalType), specID, shaderValidity);

	return result;
}

InvalidShaderCompilerLoopCase::InvalidShaderCompilerLoopCase (Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, bool isVertexCase, LoopType type, int numLoopIterations, int nestingDepth)
	: InvalidShaderCompilerCase	(context, name, description, caseID, invalidityType)
	, m_isVertexCase			(isVertexCase)
	, m_numLoopIterations		(numLoopIterations)
	, m_nestingDepth			(nestingDepth)
	, m_type					(type)
{
}

InvalidShaderCompilerLoopCase::~InvalidShaderCompilerLoopCase (void)
{
}

InvalidShaderCompilerCase::ProgramContext InvalidShaderCompilerLoopCase::generateShaderSources (int measurementNdx) const
{
	deUint32		specID			= getSpecializationID(measurementNdx);
	ProgramContext	result;
	ShaderValidity	shaderValidity	= m_invalidityType == INVALIDITY_INVALID_CHAR	? SHADER_VALIDITY_INVALID_CHAR
									: m_invalidityType == INVALIDITY_SEMANTIC_ERROR	? SHADER_VALIDITY_SEMANTIC_ERROR
									: SHADER_VALIDITY_LAST;

	DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);

	result.vertShaderSource = specializeShaderSource(loopVertexTemplate(m_type, m_isVertexCase, m_numLoopIterations, m_nestingDepth), specID, shaderValidity);
	result.fragShaderSource = specializeShaderSource(loopFragmentTemplate(m_type, m_isVertexCase, m_numLoopIterations, m_nestingDepth), specID, shaderValidity);

	return result;
}

InvalidShaderCompilerOperCase::InvalidShaderCompilerOperCase (Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, bool isVertexCase, const char* oper, int numOperations)
	: InvalidShaderCompilerCase	(context, name, description, caseID, invalidityType)
	, m_isVertexCase			(isVertexCase)
	, m_oper					(oper)
	, m_numOperations			(numOperations)
{
}

InvalidShaderCompilerOperCase::~InvalidShaderCompilerOperCase (void)
{
}

InvalidShaderCompilerCase::ProgramContext InvalidShaderCompilerOperCase::generateShaderSources (int measurementNdx) const
{
	deUint32		specID			= getSpecializationID(measurementNdx);
	ProgramContext	result;
	ShaderValidity	shaderValidity	= m_invalidityType == INVALIDITY_INVALID_CHAR	? SHADER_VALIDITY_INVALID_CHAR
									: m_invalidityType == INVALIDITY_SEMANTIC_ERROR	? SHADER_VALIDITY_SEMANTIC_ERROR
									: SHADER_VALIDITY_LAST;

	DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);

	if (m_isVertexCase)
	{
		result.vertShaderSource = specializeShaderSource(binaryOpVertexTemplate(m_numOperations, m_oper.c_str()), specID, shaderValidity);
		result.fragShaderSource = specializeShaderSource(singleVaryingFragmentTemplate(), specID, shaderValidity);
	}
	else
	{
		result.vertShaderSource = specializeShaderSource(singleVaryingVertexTemplate(), specID, shaderValidity);
		result.fragShaderSource = specializeShaderSource(binaryOpFragmentTemplate(m_numOperations, m_oper.c_str()), specID, shaderValidity);
	}

	return result;
}

InvalidShaderCompilerMandelbrotCase::InvalidShaderCompilerMandelbrotCase (Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, int numFractalIterations)
	: InvalidShaderCompilerCase	(context, name, description, caseID, invalidityType)
	, m_numFractalIterations	(numFractalIterations)
{
}

InvalidShaderCompilerMandelbrotCase::~InvalidShaderCompilerMandelbrotCase (void)
{
}

InvalidShaderCompilerCase::ProgramContext InvalidShaderCompilerMandelbrotCase::generateShaderSources (int measurementNdx) const
{
	deUint32		specID			= getSpecializationID(measurementNdx);
	ProgramContext	result;
	ShaderValidity	shaderValidity	= m_invalidityType == INVALIDITY_INVALID_CHAR	? SHADER_VALIDITY_INVALID_CHAR
									: m_invalidityType == INVALIDITY_SEMANTIC_ERROR	? SHADER_VALIDITY_SEMANTIC_ERROR
									: SHADER_VALIDITY_LAST;

	DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);

	result.vertShaderSource = specializeShaderSource(mandelbrotVertexTemplate(), specID, shaderValidity);
	result.fragShaderSource = specializeShaderSource(mandelbrotFragmentTemplate(m_numFractalIterations), specID, shaderValidity);

	return result;
}

void addShaderCompilationPerformanceCases (TestCaseGroup& parentGroup)
{
	Context&	context		= parentGroup.getContext();
	int			caseID		= 0; // Increment this after adding each case. Used for avoiding cache hits between cases.

	TestCaseGroup* validGroup			= new TestCaseGroup(context, "valid_shader",	"Valid Shader Compiler Cases");
	TestCaseGroup* invalidGroup			= new TestCaseGroup(context, "invalid_shader",	"Invalid Shader Compiler Cases");
	TestCaseGroup* cacheGroup			= new TestCaseGroup(context, "cache",			"Allow shader caching");
	parentGroup.addChild(validGroup);
	parentGroup.addChild(invalidGroup);
	parentGroup.addChild(cacheGroup);

	TestCaseGroup* invalidCharGroup		= new TestCaseGroup(context, "invalid_char",	"Invalid Character Shader Compiler Cases");
	TestCaseGroup* semanticErrorGroup	= new TestCaseGroup(context, "semantic_error",	"Semantic Error Shader Compiler Cases");
	invalidGroup->addChild(invalidCharGroup);
	invalidGroup->addChild(semanticErrorGroup);

	// Lighting shader compilation cases.

	{
		static const int lightCounts[] = { 1, 2, 4, 8 };

		TestCaseGroup* validLightingGroup			= new TestCaseGroup(context, "lighting", "Shader Compiler Lighting Cases");
		TestCaseGroup* invalidCharLightingGroup		= new TestCaseGroup(context, "lighting", "Invalid Character Shader Compiler Lighting Cases");
		TestCaseGroup* semanticErrorLightingGroup	= new TestCaseGroup(context, "lighting", "Semantic Error Shader Compiler Lighting Cases");
		TestCaseGroup* cacheLightingGroup			= new TestCaseGroup(context, "lighting", "Shader Compiler Lighting Cache Cases");
		validGroup->addChild(validLightingGroup);
		invalidCharGroup->addChild(invalidCharLightingGroup);
		semanticErrorGroup->addChild(semanticErrorLightingGroup);
		cacheGroup->addChild(cacheLightingGroup);

		for (int lightType = 0; lightType < (int)LIGHT_LAST; lightType++)
		{
			const char* lightTypeName = lightType == (int)LIGHT_DIRECTIONAL	? "directional"
									  : lightType == (int)LIGHT_POINT		? "point"
									  : DE_NULL;

			DE_ASSERT(lightTypeName != DE_NULL);

			for (int isFrag = 0; isFrag <= 1; isFrag++)
			{
				bool		isVertex	= isFrag == 0;
				const char*	vertFragStr	= isVertex ? "vertex" : "fragment";

				for (int lightCountNdx = 0; lightCountNdx < DE_LENGTH_OF_ARRAY(lightCounts); lightCountNdx++)
				{
					int numLights = lightCounts[lightCountNdx];

					string caseName = string("") + lightTypeName + "_" + de::toString(numLights) + "_lights_" + vertFragStr;

					// Valid shader case, no-cache and cache versions.

					validLightingGroup->addChild(new ShaderCompilerLightCase(context, caseName.c_str(), "", caseID++, true  /* avoid cache */, false, isVertex, numLights, (LightType)lightType));
					cacheLightingGroup->addChild(new ShaderCompilerLightCase(context, caseName.c_str(), "", caseID++, false /* allow cache */, false, isVertex, numLights, (LightType)lightType));

					// Invalid shader cases.

					for (int invalidityType = 0; invalidityType < (int)InvalidShaderCompilerCase::INVALIDITY_LAST; invalidityType++)
					{
						TestCaseGroup* curInvalidGroup	= invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_INVALID_CHAR		? invalidCharLightingGroup
														: invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_SEMANTIC_ERROR	? semanticErrorLightingGroup
														: DE_NULL;

						DE_ASSERT(curInvalidGroup != DE_NULL);

						curInvalidGroup->addChild(new InvalidShaderCompilerLightCase(context, caseName.c_str(), "", caseID++, (InvalidShaderCompilerCase::InvalidityType)invalidityType, isVertex, numLights, (LightType)lightType));
					}
				}
			}
		}
	}

	// Texture lookup shader compilation cases.

	{
		static const int texLookupCounts[] = { 1, 2, 4, 8 };

		TestCaseGroup* validTexGroup			= new TestCaseGroup(context, "texture", "Shader Compiler Texture Lookup Cases");
		TestCaseGroup* invalidCharTexGroup		= new TestCaseGroup(context, "texture", "Invalid Character Shader Compiler Texture Lookup Cases");
		TestCaseGroup* semanticErrorTexGroup	= new TestCaseGroup(context, "texture", "Semantic Error Shader Compiler Texture Lookup Cases");
		TestCaseGroup* cacheTexGroup			= new TestCaseGroup(context, "texture", "Shader Compiler Texture Lookup Cache Cases");
		validGroup->addChild(validTexGroup);
		invalidCharGroup->addChild(invalidCharTexGroup);
		semanticErrorGroup->addChild(semanticErrorTexGroup);
		cacheGroup->addChild(cacheTexGroup);

		for (int conditionalUsage = 0; conditionalUsage < (int)CONDITIONAL_USAGE_LAST; conditionalUsage++)
		{
			const char* conditionalUsageName = conditionalUsage == (int)CONDITIONAL_USAGE_NONE			? "no_conditionals"
											 : conditionalUsage == (int)CONDITIONAL_USAGE_FIRST_HALF	? "first_half"
											 : conditionalUsage == (int)CONDITIONAL_USAGE_EVERY_OTHER	? "every_other"
											 : DE_NULL;

			DE_ASSERT(conditionalUsageName != DE_NULL);

			int lastConditionalType = conditionalUsage == (int)CONDITIONAL_USAGE_NONE ? 1 : (int)CONDITIONAL_TYPE_LAST;

			for (int conditionalType = 0; conditionalType < lastConditionalType; conditionalType++)
			{
				const char* conditionalTypeName = conditionalType == (int)CONDITIONAL_TYPE_STATIC	? "static_conditionals"
												: conditionalType == (int)CONDITIONAL_TYPE_UNIFORM	? "uniform_conditionals"
												: conditionalType == (int)CONDITIONAL_TYPE_DYNAMIC	? "dynamic_conditionals"
												: DE_NULL;

				DE_ASSERT(conditionalTypeName != DE_NULL);

				for (int lookupCountNdx = 0; lookupCountNdx < DE_LENGTH_OF_ARRAY(texLookupCounts); lookupCountNdx++)
				{
					int numLookups = texLookupCounts[lookupCountNdx];

					string caseName = de::toString(numLookups) + "_lookups_" + conditionalUsageName + (conditionalUsage == (int)CONDITIONAL_USAGE_NONE ? "" : string("_") + conditionalTypeName);

					// Valid shader case, no-cache and cache versions.

					validTexGroup->addChild(new ShaderCompilerTextureCase(context, caseName.c_str(), "", caseID++, true  /* avoid cache */, false, numLookups, (ConditionalUsage)conditionalUsage, (ConditionalType)conditionalType));
					cacheTexGroup->addChild(new ShaderCompilerTextureCase(context, caseName.c_str(), "", caseID++, false /* allow cache */, false, numLookups, (ConditionalUsage)conditionalUsage, (ConditionalType)conditionalType));

					// Invalid shader cases.

					for (int invalidityType = 0; invalidityType < (int)InvalidShaderCompilerCase::INVALIDITY_LAST; invalidityType++)
					{
						TestCaseGroup* curInvalidGroup	= invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_INVALID_CHAR		? invalidCharTexGroup
														: invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_SEMANTIC_ERROR	? semanticErrorTexGroup
														: DE_NULL;

						DE_ASSERT(curInvalidGroup != DE_NULL);

						curInvalidGroup->addChild(new InvalidShaderCompilerTextureCase(context, caseName.c_str(), "", caseID++, (InvalidShaderCompilerCase::InvalidityType)invalidityType, numLookups, (ConditionalUsage)conditionalUsage, (ConditionalType)conditionalType));
					}
				}
			}
		}
	}

	// Loop shader compilation cases.

	{
		static const int loopIterCounts[]		= { 10, 100, 1000 };
		static const int maxLoopNestingDepth	= 3;
		static const int maxTotalLoopIterations	= 2000; // If <loop iteration count> ** <loop nesting depth> (where ** is exponentiation) exceeds this, don't generate the case.

		TestCaseGroup* validLoopGroup			= new TestCaseGroup(context, "loop", "Shader Compiler Loop Cases");
		TestCaseGroup* invalidCharLoopGroup		= new TestCaseGroup(context, "loop", "Invalid Character Shader Compiler Loop Cases");
		TestCaseGroup* semanticErrorLoopGroup	= new TestCaseGroup(context, "loop", "Semantic Error Shader Compiler Loop Cases");
		TestCaseGroup* cacheLoopGroup			= new TestCaseGroup(context, "loop", "Shader Compiler Loop Cache Cases");
		validGroup->addChild(validLoopGroup);
		invalidCharGroup->addChild(invalidCharLoopGroup);
		semanticErrorGroup->addChild(semanticErrorLoopGroup);
		cacheGroup->addChild(cacheLoopGroup);

		for (int loopType = 0; loopType < (int)LOOP_LAST; loopType++)
		{
			const char* loopTypeName = loopType == (int)LOOP_TYPE_STATIC	? "static"
									 : loopType == (int)LOOP_TYPE_UNIFORM	? "uniform"
									 : loopType == (int)LOOP_TYPE_DYNAMIC	? "dynamic"
									 : DE_NULL;

			DE_ASSERT(loopTypeName != DE_NULL);

			TestCaseGroup* validLoopTypeGroup			= new TestCaseGroup(context, loopTypeName, "");
			TestCaseGroup* invalidCharLoopTypeGroup		= new TestCaseGroup(context, loopTypeName, "");
			TestCaseGroup* semanticErrorLoopTypeGroup	= new TestCaseGroup(context, loopTypeName, "");
			TestCaseGroup* cacheLoopTypeGroup			= new TestCaseGroup(context, loopTypeName, "");
			validLoopGroup->addChild(validLoopTypeGroup);
			invalidCharLoopGroup->addChild(invalidCharLoopTypeGroup);
			semanticErrorLoopGroup->addChild(semanticErrorLoopTypeGroup);
			cacheLoopGroup->addChild(cacheLoopTypeGroup);

			for (int isFrag = 0; isFrag <= 1; isFrag++)
			{
				bool		isVertex	= isFrag == 0;
				const char*	vertFragStr	= isVertex ? "vertex" : "fragment";

				// \note Non-static loop cases with different iteration counts have identical shaders, so only make one of each.
				int loopIterCountMaxNdx = loopType != (int)LOOP_TYPE_STATIC ? 1 : DE_LENGTH_OF_ARRAY(loopIterCounts);

				for (int nestingDepth = 1; nestingDepth <= maxLoopNestingDepth; nestingDepth++)
				{
					for (int loopIterCountNdx = 0; loopIterCountNdx < loopIterCountMaxNdx; loopIterCountNdx++)
					{
						int numIterations = loopIterCounts[loopIterCountNdx];

						if (deFloatPow((float)numIterations, (float)nestingDepth) > (float)maxTotalLoopIterations)
							continue; // Don't generate too heavy tasks.

						string validCaseName = de::toString(numIterations) + "_iterations_" + de::toString(nestingDepth) + "_levels_" + vertFragStr;

						// Valid shader case, no-cache and cache versions.

						validLoopTypeGroup->addChild(new ShaderCompilerLoopCase(context, validCaseName.c_str(), "", caseID++, true  /* avoid cache */, false, isVertex, (LoopType)loopType, numIterations, nestingDepth));
						cacheLoopTypeGroup->addChild(new ShaderCompilerLoopCase(context, validCaseName.c_str(), "", caseID++, false /* allow cache */, false, isVertex, (LoopType)loopType, numIterations, nestingDepth));

						// Invalid shader cases.

						for (int invalidityType = 0; invalidityType < (int)InvalidShaderCompilerCase::INVALIDITY_LAST; invalidityType++)
						{
							TestCaseGroup* curInvalidGroup	= invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_INVALID_CHAR		? invalidCharLoopTypeGroup
															: invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_SEMANTIC_ERROR	? semanticErrorLoopTypeGroup
															: DE_NULL;

							DE_ASSERT(curInvalidGroup != DE_NULL);

							string invalidCaseName = de::toString(nestingDepth) + "_levels_" + vertFragStr;

							if (loopType == (int)LOOP_TYPE_STATIC)
								invalidCaseName = de::toString(numIterations) + "_iterations_" + invalidCaseName; // \note For invalid, non-static loop cases the iteration count means nothing (since no uniforms or attributes are set).

							curInvalidGroup->addChild(new InvalidShaderCompilerLoopCase(context, invalidCaseName.c_str(), "", caseID++, (InvalidShaderCompilerCase::InvalidityType)invalidityType, isVertex, (LoopType)loopType, numIterations, nestingDepth));
						}
					}
				}
			}
		}
	}

	// Multiplication shader compilation cases.

	{
		static const int multiplicationCounts[] = { 10, 100, 1000 };

		TestCaseGroup* validMulGroup			= new TestCaseGroup(context, "multiplication", "Shader Compiler Multiplication Cases");
		TestCaseGroup* invalidCharMulGroup		= new TestCaseGroup(context, "multiplication", "Invalid Character Shader Compiler Multiplication Cases");
		TestCaseGroup* semanticErrorMulGroup	= new TestCaseGroup(context, "multiplication", "Semantic Error Shader Compiler Multiplication Cases");
		TestCaseGroup* cacheMulGroup			= new TestCaseGroup(context, "multiplication", "Shader Compiler Multiplication Cache Cases");
		validGroup->addChild(validMulGroup);
		invalidCharGroup->addChild(invalidCharMulGroup);
		semanticErrorGroup->addChild(semanticErrorMulGroup);
		cacheGroup->addChild(cacheMulGroup);

		for (int isFrag = 0; isFrag <= 1; isFrag++)
		{
			bool		isVertex	= isFrag == 0;
			const char*	vertFragStr	= isVertex ? "vertex" : "fragment";

			for (int operCountNdx = 0; operCountNdx < DE_LENGTH_OF_ARRAY(multiplicationCounts); operCountNdx++)
			{
				int numOpers = multiplicationCounts[operCountNdx];

				string caseName = de::toString(numOpers) + "_operations_" + vertFragStr;

				// Valid shader case, no-cache and cache versions.

				validMulGroup->addChild(new ShaderCompilerOperCase(context, caseName.c_str(), "", caseID++, true  /* avoid cache */, false, isVertex, "*", numOpers));
				cacheMulGroup->addChild(new ShaderCompilerOperCase(context, caseName.c_str(), "", caseID++, false /* allow cache */, false, isVertex, "*", numOpers));

				// Invalid shader cases.

				for (int invalidityType = 0; invalidityType < (int)InvalidShaderCompilerCase::INVALIDITY_LAST; invalidityType++)
				{
					TestCaseGroup* curInvalidGroup	= invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_INVALID_CHAR		? invalidCharMulGroup
													: invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_SEMANTIC_ERROR	? semanticErrorMulGroup
													: DE_NULL;

					DE_ASSERT(curInvalidGroup != DE_NULL);

					curInvalidGroup->addChild(new InvalidShaderCompilerOperCase(context, caseName.c_str(), "", caseID++, (InvalidShaderCompilerCase::InvalidityType)invalidityType, isVertex, "*", numOpers));
				}
			}
		}
	}

	// Mandelbrot shader compilation cases.

	{
		static const int mandelbrotIterationCounts[] = { 32, 64, 128 };

		TestCaseGroup* validMandelbrotGroup			= new TestCaseGroup(context, "mandelbrot", "Shader Compiler Mandelbrot Fractal Cases");
		TestCaseGroup* invalidCharMandelbrotGroup	= new TestCaseGroup(context, "mandelbrot", "Invalid Character Shader Compiler Mandelbrot Fractal Cases");
		TestCaseGroup* semanticErrorMandelbrotGroup	= new TestCaseGroup(context, "mandelbrot", "Semantic Error Shader Compiler Mandelbrot Fractal Cases");
		TestCaseGroup* cacheMandelbrotGroup			= new TestCaseGroup(context, "mandelbrot", "Shader Compiler Mandelbrot Fractal Cache Cases");
		validGroup->addChild(validMandelbrotGroup);
		invalidCharGroup->addChild(invalidCharMandelbrotGroup);
		semanticErrorGroup->addChild(semanticErrorMandelbrotGroup);
		cacheGroup->addChild(cacheMandelbrotGroup);

		for (int iterCountNdx = 0; iterCountNdx < DE_LENGTH_OF_ARRAY(mandelbrotIterationCounts); iterCountNdx++)
		{
			int		numFractalIterations	= mandelbrotIterationCounts[iterCountNdx];
			string	caseName				= de::toString(numFractalIterations) + "_iterations";

			// Valid shader case, no-cache and cache versions.

			validMandelbrotGroup->addChild(new ShaderCompilerMandelbrotCase(context, caseName.c_str(), "", caseID++, true  /* avoid cache */, false, numFractalIterations));
			cacheMandelbrotGroup->addChild(new ShaderCompilerMandelbrotCase(context, caseName.c_str(), "", caseID++, false /* allow cache */, false, numFractalIterations));

			// Invalid shader cases.

			for (int invalidityType = 0; invalidityType < (int)InvalidShaderCompilerCase::INVALIDITY_LAST; invalidityType++)
			{
				TestCaseGroup* curInvalidGroup	= invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_INVALID_CHAR		? invalidCharMandelbrotGroup
												: invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_SEMANTIC_ERROR	? semanticErrorMandelbrotGroup
												: DE_NULL;

				DE_ASSERT(curInvalidGroup != DE_NULL);

				curInvalidGroup->addChild(new InvalidShaderCompilerMandelbrotCase(context, caseName.c_str(), "", caseID++, (InvalidShaderCompilerCase::InvalidityType)invalidityType, numFractalIterations));
			}
		}
	}

	// Cases testing cache behaviour when whitespace and comments are added.

	{
		TestCaseGroup* whitespaceCommentCacheGroup = new TestCaseGroup(context, "cache_whitespace_comment", "Cases testing the effect of whitespace and comments on caching");
		parentGroup.addChild(whitespaceCommentCacheGroup);

		// \note Add just a small subset of the cases that were added above for the main performance tests.

		// Cases with both vertex and fragment variants.
		for (int isFrag = 0; isFrag <= 1; isFrag++)
		{
			bool	isVertex		= isFrag == 0;
			string	vtxFragSuffix	= isVertex ? "_vertex" : "_fragment";
			string	dirLightName	= "directional_2_lights" + vtxFragSuffix;
			string	loopName		= "static_loop_100_iterations" + vtxFragSuffix;
			string	multCase		= "multiplication_100_operations" + vtxFragSuffix;

			whitespaceCommentCacheGroup->addChild(new ShaderCompilerLightCase(context, dirLightName.c_str(), "", caseID++, false, true, isVertex, 2, LIGHT_DIRECTIONAL));
			whitespaceCommentCacheGroup->addChild(new ShaderCompilerLoopCase(context, loopName.c_str(), "", caseID++, false, true, isVertex, LOOP_TYPE_STATIC, 100, 1));
			whitespaceCommentCacheGroup->addChild(new ShaderCompilerOperCase(context, multCase.c_str(), "", caseID++, false, true, isVertex, "*", 100));
		}

		// Cases that don't have vertex and fragment variants.
		whitespaceCommentCacheGroup->addChild(new ShaderCompilerTextureCase(context, "texture_4_lookups", "", caseID++, false, true, 4, CONDITIONAL_USAGE_NONE, CONDITIONAL_TYPE_STATIC));
		whitespaceCommentCacheGroup->addChild(new ShaderCompilerMandelbrotCase(context, "mandelbrot_32_operations", "", caseID++, false, true, 32));
	}
}

} // Performance
} // gles2
} // deqp
