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

#include "es3pShaderCompilationCases.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 gles3
{

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	? "" : "\tfloat 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 +=
		"#version 300 es\n"
		"in highp vec4 a_position${NAME_SPEC};\n"
		"in mediump vec3 a_normal${NAME_SPEC};\n"
		"in 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"
		"out mediump vec4 v_color${NAME_SPEC};\n"
		"out mediump vec2 v_texCoord0${NAME_SPEC};\n";

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

		if (lightType == LIGHT_POINT)
			resultTemplate +=
				"out mediump vec3 v_directionToLight${NAME_SPEC}[" + de::toString(numLights) + "];\n"
				"out 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;

	resultTemplate +=
		"#version 300 es\n"
		"layout(location = 0) out mediump vec4 o_color;\n";

	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"
		"in mediump vec4 v_color${NAME_SPEC};\n"
		"in mediump vec2 v_texCoord0${NAME_SPEC};\n";

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

		if (lightType == LIGHT_POINT)
			resultTemplate +=
				"in mediump vec3 v_directionToLight${NAME_SPEC}[" + de::toString(numLights) + "];\n"
				"in 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 *= texture(u_sampler0${NAME_SPEC}, texCoord0);\n"
		"	o_color = 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 +=
		"#version 300 es\n"
		"in highp vec4 a_position${NAME_SPEC};\n";

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

	resultTemplate +=
		"in mediump vec4 a_value${NAME_SPEC};\n"
		"out 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 +=
				"out 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 +=
		"#version 300 es\n"
		"layout(location = 0) out mediump vec4 o_color;\n"
		"in mediump vec4 v_value${NAME_SPEC};\n";

	if (!isVertexCase)
	{
		if (type == LOOP_TYPE_DYNAMIC)
			resultTemplate +=
				"in 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 +=
			"	o_color = value + ${FLOAT01};\n";
	}
	else
		resultTemplate +=
			"\n"
			"void main()\n"
			"{\n"
			"	o_color = 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 +=
		"#version 300 es\n"
		"in highp vec4 a_position${NAME_SPEC};\n"
		"in mediump vec4 a_value${NAME_SPEC};\n"
		"out 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 +=
		"#version 300 es\n"
		"layout(location = 0) out mediump vec4 o_color;\n"
		"in 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"
		"	o_color = 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 =
		"#version 300 es\n"
		"in highp vec4 a_position${NAME_SPEC};\n"
		"in mediump vec4 a_value${NAME_SPEC};\n"
		"out 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 =
		"#version 300 es\n"
		"layout(location = 0) out mediump vec4 o_color;\n"
		"in mediump vec4 v_value${NAME_SPEC};\n"
		"\n"
		"void main()\n"
		"{\n"
		"	o_color = 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 +=
		"#version 300 es\n"
		"in highp vec4 a_position${NAME_SPEC};\n"
		"in mediump vec2 a_coords${NAME_SPEC};\n"
		"out mediump vec2 v_coords${NAME_SPEC};\n";

	if (conditionVaryingNeeded)
		resultTemplate +=
			"in mediump float a_condition${NAME_SPEC};\n"
			"out 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 +=
		"#version 300 es\n"
		"layout(location = 0) out mediump vec4 o_color;\n"
		"in mediump vec2 v_coords${NAME_SPEC};\n";

	if (conditionalUsage != CONDITIONAL_USAGE_NONE && conditionalType == CONDITIONAL_TYPE_DYNAMIC)
		resultTemplate +=
			"in 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 += texture(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 +=
		"	o_color = 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 =
		"#version 300 es\n"
		"uniform highp mat4 u_mvp${NAME_SPEC};\n"
		"\n"
		"in highp vec4 a_vertex${NAME_SPEC};\n"
		"in highp vec4 a_coord${NAME_SPEC};\n"
		"\n"
		"out 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 =
		"#version 300 es\n"
		"layout(location = 0) out mediump vec4 o_color;\n"
		"in 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"
		"	o_color = 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
} // gles3
} // deqp
