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

#include "es2pShaderControlStatementTests.hpp"
#include "glsShaderPerformanceCase.hpp"
#include "tcuTestLog.hpp"

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

#include <string>
#include <vector>

namespace deqp
{
namespace gles2
{
namespace Performance
{

using namespace gls;
using namespace glw; // GL types
using tcu::Vec4;
using tcu::TestLog;
using std::string;
using std::vector;

// Writes the workload expression used in conditional tests.
static void writeConditionalWorkload (std::ostringstream& stream, const char* resultName, const char* operandName)
{
	const int numMultiplications = 64;

	stream << resultName << " = ";

	for (int i = 0; i < numMultiplications; i++)
	{
		if (i > 0)
			stream << "*";

		stream << operandName;
	}

	stream << ";";
}

// Writes the workload expression used in loop tests (one iteration).
static void writeLoopWorkload (std::ostringstream& stream, const char* resultName, const char* operandName)
{
	const int numMultiplications = 8;

	stream << resultName << " = ";

	for (int i = 0; i < numMultiplications; i++)
	{
		if (i > 0)
			stream << " * ";

		stream << "(" << resultName << " + " << operandName << ")";
	}

	stream << ";";
}

// The type of decision to be made in a conditional expression.
// \note In fragment cases with DECISION_ATTRIBUTE, the value in the expression will actually be a varying.
enum DecisionType
{
	DECISION_STATIC = 0,
	DECISION_UNIFORM,
	DECISION_ATTRIBUTE,

	DECISION_LAST
};

class ControlStatementCase :  public ShaderPerformanceCase
{
public:
	ControlStatementCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, gls::PerfCaseType caseType)
		: ShaderPerformanceCase(testCtx, renderCtx, name, description, caseType)
	{
	}

	void init (void)
	{
		m_testCtx.getLog() << TestLog::Message << "Using additive blending." << TestLog::EndMessage;
		ShaderPerformanceCase::init();
	}

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

		gl.enable(GL_BLEND);
		gl.blendEquation(GL_FUNC_ADD);
		gl.blendFunc(GL_ONE, GL_ONE);
	}
};

class ConditionalCase : public ControlStatementCase
{
public:
	enum BranchResult
	{
		BRANCH_TRUE = 0,
		BRANCH_FALSE,
		BRANCH_MIXED,

		BRANCH_LAST
	};

	enum WorkloadDivision
	{
		WORKLOAD_DIVISION_EVEN = 0,		//! Both true and false branches contain same amount of computation.
		WORKLOAD_DIVISION_TRUE_HEAVY,	//! True branch contains more computation.
		WORKLOAD_DIVISION_FALSE_HEAVY,	//! False branch contains more computation.

		WORKLOAD_DIVISION_LAST
	};

						ConditionalCase		(Context& context, const char* name, const char* description, DecisionType decisionType, BranchResult branchType, WorkloadDivision workloadDivision, bool isVertex);
						~ConditionalCase	(void);

	void				init				(void);
	void				deinit				(void);
	void				setupProgram		(deUint32 program);

private:
	DecisionType		m_decisionType;
	BranchResult		m_branchType;
	WorkloadDivision	m_workloadDivision;

	vector<float>		m_comparisonValueArray; // Will contain per-vertex comparison values if using mixed branch type in vertex case.
	deUint32			m_arrayBuffer;
};

ConditionalCase::ConditionalCase (Context& context, const char* name, const char* description, DecisionType decisionType, BranchResult branchType, WorkloadDivision workloadDivision, bool isVertex)
	: ControlStatementCase			(context.getTestContext(), context.getRenderContext(), name, description, isVertex ? CASETYPE_VERTEX : CASETYPE_FRAGMENT)
	, m_decisionType				(decisionType)
	, m_branchType					(branchType)
	, m_workloadDivision			(workloadDivision)
	, m_arrayBuffer					(0)
{
}

void ConditionalCase::init (void)
{
	bool			isVertexCase		= m_caseType == CASETYPE_VERTEX;

	bool			isStaticCase		= m_decisionType == DECISION_STATIC;
	bool			isUniformCase		= m_decisionType == DECISION_UNIFORM;
	bool			isAttributeCase		= m_decisionType == DECISION_ATTRIBUTE;

	DE_ASSERT(isStaticCase || isUniformCase || isAttributeCase);

	bool			isConditionTrue		= m_branchType == BRANCH_TRUE;
	bool			isConditionFalse	= m_branchType == BRANCH_FALSE;
	bool			isConditionMixed	= m_branchType == BRANCH_MIXED;

	DE_ASSERT(isConditionTrue || isConditionFalse || isConditionMixed);
	DE_UNREF(isConditionFalse);

	DE_ASSERT(isAttributeCase || !isConditionMixed); // The branch taken can vary between executions only if using attribute input.

	const char*		staticCompareValueStr	= isConditionTrue	? "1.0" : "-1.0";
	const char*		compareValueStr			= isStaticCase		? staticCompareValueStr :
											  isUniformCase		? "u_compareValue" :
											  isVertexCase		? "a_compareValue" :
																  "v_compareValue";

	std::ostringstream	vtx;
	std::ostringstream	frag;
	std::ostringstream&	op		= isVertexCase ? vtx : frag;

	vtx << "attribute highp vec4 a_position;\n";	// Position attribute.
	vtx << "attribute mediump vec4 a_value0;\n";	// Input for workload calculations of "true" branch.
	vtx << "attribute mediump vec4 a_value1;\n";	// Input for workload calculations of "false" branch.

	// Value to be used in the conditional expression.
	if (isAttributeCase)
		vtx << "attribute mediump float a_compareValue;\n";
	else if (isUniformCase)
		op << "uniform mediump float u_compareValue;\n";

	// Varyings.
	if (isVertexCase)
	{
		vtx << "varying mediump vec4 v_color;\n";
		frag << "varying mediump vec4 v_color;\n";
	}
	else
	{
		vtx << "varying mediump vec4 v_value0;\n";
		vtx << "varying mediump vec4 v_value1;\n";
		frag << "varying mediump vec4 v_value0;\n";
		frag << "varying mediump vec4 v_value1;\n";

		if (isAttributeCase)
		{
			vtx << "varying mediump float v_compareValue;\n";
			frag << "varying mediump float v_compareValue;\n";
		}
	}

	vtx << "\n";
	vtx << "void main()\n";
	vtx << "{\n";
	vtx << "	gl_Position = a_position;\n";

	frag << "\n";
	frag << "void main()\n";
	frag << "{\n";

	op << "	mediump vec4 res;\n";

	string condition;

	if (isConditionMixed && !isVertexCase)
		condition = string("") + "fract(" + compareValueStr + ") < 0.5"; // Comparison result varies with high frequency.
	else
		condition = string("") + compareValueStr + " > 0.0";

	op << "	if (" << condition << ")\n";
	op << "	{\n";

	op << "\t\t";
	if (m_workloadDivision == WORKLOAD_DIVISION_EVEN || m_workloadDivision == WORKLOAD_DIVISION_TRUE_HEAVY)
		writeConditionalWorkload(op, "res", isVertexCase ? "a_value0" : "v_value0"); // Workload calculation for the "true" branch.
	else
		op << "res = " << (isVertexCase ? "a_value0" : "v_value0") << ";";
	op << "\n";

	op << "	}\n";
	op << "	else\n";
	op << "	{\n";

	op << "\t\t";
	if (m_workloadDivision == WORKLOAD_DIVISION_EVEN || m_workloadDivision == WORKLOAD_DIVISION_FALSE_HEAVY)
		writeConditionalWorkload(op, "res", isVertexCase ? "a_value1" : "v_value1"); // Workload calculations for the "false" branch.
	else
		op << "res = " << (isVertexCase ? "a_value1" : "v_value1") << ";";
	op << "\n";

	op << "	}\n";

	if (isVertexCase)
	{
		// Put result to color variable.
		vtx << "	v_color = res;\n";
		frag << "	gl_FragColor = v_color;\n";
	}
	else
	{
		// Transfer inputs to fragment shader through varyings.
		if (isAttributeCase)
			vtx << "	v_compareValue = a_compareValue;\n";
		vtx << "	v_value0 = a_value0;\n";
		vtx << "	v_value1 = a_value1;\n";

		frag << "	gl_FragColor = res;\n"; // Put result to color variable.
	}

	vtx << "}\n";
	frag << "}\n";

	m_vertShaderSource = vtx.str();
	m_fragShaderSource = frag.str();

	if (isAttributeCase)
	{
		if (!isConditionMixed)
		{
			// Every execution takes the same branch.

			float value = isConditionTrue ? +1.0f : -1.0f;
			m_attributes.push_back(AttribSpec("a_compareValue",	Vec4(value, 0.0f, 0.0f, 0.0f),
																Vec4(value, 0.0f, 0.0f, 0.0f),
																Vec4(value, 0.0f, 0.0f, 0.0f),
																Vec4(value, 0.0f, 0.0f, 0.0f)));
		}
		else if (isVertexCase)
		{
			// Vertex case, not every execution takes the same branch.

			const int	numComponents	= 4;
			int			numVertices		= (getGridWidth() + 1) * (getGridHeight() + 1);

			// setupProgram() will later bind this array as an attribute.
			m_comparisonValueArray.resize(numVertices * numComponents);

			// Make every second vertex take the true branch, and every second the false branch.
			for (int i = 0; i < (int)m_comparisonValueArray.size(); i++)
			{
				if (i % numComponents == 0)
					m_comparisonValueArray[i] = (i / numComponents) % 2 == 0 ? +1.0f : -1.0f;
				else
					m_comparisonValueArray[i] = 0.0f;
			}
		}
		else // isConditionMixed && !isVertexCase
		{
			// Fragment case, not every execution takes the same branch.
			// \note fract(a_compareValue) < 0.5 will be true for every second column of fragments.

			float minValue = 0.0f;
			float maxValue = (float)getViewportWidth()*0.5f;
			m_attributes.push_back(AttribSpec("a_compareValue",	Vec4(minValue, 0.0f, 0.0f, 0.0f),
																Vec4(maxValue, 0.0f, 0.0f, 0.0f),
																Vec4(minValue, 0.0f, 0.0f, 0.0f),
																Vec4(maxValue, 0.0f, 0.0f, 0.0f)));
		}
	}

	m_attributes.push_back(AttribSpec("a_value0",	Vec4(0.0f, 0.1f, 0.2f, 0.3f),
													Vec4(0.4f, 0.5f, 0.6f, 0.7f),
													Vec4(0.8f, 0.9f, 1.0f, 1.1f),
													Vec4(1.2f, 1.3f, 1.4f, 1.5f)));

	m_attributes.push_back(AttribSpec("a_value1",	Vec4(0.0f, 0.1f, 0.2f, 0.3f),
													Vec4(0.4f, 0.5f, 0.6f, 0.7f),
													Vec4(0.8f, 0.9f, 1.0f, 1.1f),
													Vec4(1.2f, 1.3f, 1.4f, 1.5f)));

	ControlStatementCase::init();
}

void ConditionalCase::setupProgram (deUint32 program)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	if (m_decisionType == DECISION_UNIFORM)
	{
		int location = gl.getUniformLocation(program, "u_compareValue");
		gl.uniform1f(location, m_branchType == BRANCH_TRUE ? +1.0f : -1.0f);
	}
	else if (m_decisionType == DECISION_ATTRIBUTE && m_branchType == BRANCH_MIXED && m_caseType == CASETYPE_VERTEX)
	{
		// Setup per-vertex comparison values calculated in init().

		const int	numComponents			= 4;
		int			compareAttribLocation	= gl.getAttribLocation(program, "a_compareValue");

		DE_ASSERT((int)m_comparisonValueArray.size() == numComponents * (getGridWidth() + 1) * (getGridHeight() + 1));

		gl.genBuffers(1, &m_arrayBuffer);
		gl.bindBuffer(GL_ARRAY_BUFFER, m_arrayBuffer);
		gl.bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(m_comparisonValueArray.size()*sizeof(float)), &m_comparisonValueArray[0], GL_STATIC_DRAW);
		gl.enableVertexAttribArray(compareAttribLocation);
		gl.vertexAttribPointer(compareAttribLocation, (GLint)numComponents, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "Setup program state");
}

ConditionalCase::~ConditionalCase (void)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	if (m_arrayBuffer != 0)
	{
		gl.deleteBuffers(1, &m_arrayBuffer);
		m_arrayBuffer = 0;
	}
}

void ConditionalCase::deinit (void)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	m_comparisonValueArray.clear();

	if (m_arrayBuffer != 0)
	{
		gl.deleteBuffers(1, &m_arrayBuffer);
		m_arrayBuffer = 0;
	}

	ShaderPerformanceCase::deinit();
}

class LoopCase : public ControlStatementCase
{
public:
	enum LoopType
	{
		LOOP_FOR = 0,
		LOOP_WHILE,
		LOOP_DO_WHILE,

		LOOP_LAST
	};
					LoopCase			(Context& context, const char* name, const char* description, LoopType type, DecisionType decisionType, bool isLoopBoundStable, bool isVertex);
					~LoopCase			(void);

	void			init				(void);
	void			deinit				(void);
	void			setupProgram		(deUint32 program);

private:
	DecisionType	m_decisionType;
	LoopType		m_type;

	bool			m_isLoopBoundStable;	// Whether loop bound is same in all executions.
	vector<float>	m_boundArray;			// Will contain per-vertex loop bounds if using non-stable attribute in vertex case.
	deUint32		m_arrayBuffer;
};

LoopCase::LoopCase (Context& context, const char* name, const char* description, LoopType type, DecisionType decisionType, bool isLoopBoundStable, bool isVertex)
	: ControlStatementCase	(context.getTestContext(), context.getRenderContext(), name, description, isVertex ? CASETYPE_VERTEX : CASETYPE_FRAGMENT)
	, m_decisionType		(decisionType)
	, m_type				(type)
	, m_isLoopBoundStable	(isLoopBoundStable)
	, m_arrayBuffer			(0)
{
}

void LoopCase::init (void)
{
	bool				isVertexCase	= m_caseType == CASETYPE_VERTEX;

	bool				isStaticCase	= m_decisionType == DECISION_STATIC;
	bool				isUniformCase	= m_decisionType == DECISION_UNIFORM;
	bool				isAttributeCase	= m_decisionType == DECISION_ATTRIBUTE;

	DE_ASSERT(isStaticCase || isUniformCase || isAttributeCase);

	DE_ASSERT(m_type == LOOP_FOR		||
			  m_type == LOOP_WHILE		||
			  m_type == LOOP_DO_WHILE);

	DE_ASSERT(isAttributeCase || m_isLoopBoundStable); // The loop bound count can vary between executions only if using attribute input.

	// \note The fractional part is .5 (instead of .0) so that these can be safely used as loop bounds.
	const float			loopBound				= 10.5f;
	const float			unstableBoundLow		= 5.5f;
	const float			unstableBoundHigh		= 15.5f;
	static const char*	loopBoundStr			= "10.5";
	static const char*	unstableBoundLowStr		= "5.5";
	static const char*	unstableBoundHighStr	= "15.5";

	const char*			boundValueStr		= isStaticCase			? loopBoundStr :
											  isUniformCase			? "u_bound" :
											  isVertexCase			? "a_bound" :
											  m_isLoopBoundStable	? "v_bound" :
																	  "loopBound";

	std::ostringstream	vtx;
	std::ostringstream	frag;
	std::ostringstream&	op		= isVertexCase ? vtx : frag;

	vtx << "attribute highp vec4 a_position;\n";	// Position attribute.
	vtx << "attribute mediump vec4 a_value;\n";		// Input for workload calculations.

	// Value to be used as the loop iteration count.
	if (isAttributeCase)
		vtx << "attribute mediump float a_bound;\n";
	else if (isUniformCase)
		op << "uniform mediump float u_bound;\n";

	// Varyings.
	if (isVertexCase)
	{
		vtx << "varying mediump vec4 v_color;\n";
		frag << "varying mediump vec4 v_color;\n";
	}
	else
	{
		vtx << "varying mediump vec4 v_value;\n";
		frag << "varying mediump vec4 v_value;\n";

		if (isAttributeCase)
		{
			vtx << "varying mediump float v_bound;\n";
			frag << "varying mediump float v_bound;\n";
		}
	}

	vtx << "\n";
	vtx << "void main()\n";
	vtx << "{\n";
	vtx << "	gl_Position = a_position;\n";

	frag << "\n";
	frag << "void main()\n";
	frag << "{\n";

	op << "	mediump vec4 res = vec4(0.0);\n";

	if (!m_isLoopBoundStable && !isVertexCase)
	{
		// Choose the actual loop bound based on v_bound.
		// \note Loop bound will vary with high frequency between fragment columns, given appropriate range for v_bound.
		op << "	mediump float loopBound = fract(v_bound) < 0.5 ? " << unstableBoundLowStr << " : " << unstableBoundHighStr << ";\n";
	}

	// Start a for, while or do-while loop.
	if (m_type == LOOP_FOR)
		op << "	for (mediump float i = 0.0; i < " << boundValueStr << "; i++)\n";
	else
	{
		op << "	mediump float i = 0.0;\n";
		if (m_type == LOOP_WHILE)
			op << "	while (i < " << boundValueStr << ")\n";
		else // LOOP_DO_WHILE
			op << "	do\n";
	}
	op << "	{\n";

	// Workload calculations inside the loop.
	op << "\t\t";
	writeLoopWorkload(op, "res", isVertexCase ? "a_value" : "v_value");
	op << "\n";

	// Only "for" has counter increment in the loop head.
	if (m_type != LOOP_FOR)
		op << "		i++;\n";

	// End the loop.
	if (m_type == LOOP_DO_WHILE)
		op << "	} while (i < " << boundValueStr << ");\n";
	else
		op << "	}\n";

	if (isVertexCase)
	{
		// Put result to color variable.
		vtx << "	v_color = res;\n";
		frag << "	gl_FragColor = v_color;\n";
	}
	else
	{
		// Transfer inputs to fragment shader through varyings.
		if (isAttributeCase)
			vtx << "	v_bound = a_bound;\n";
		vtx << "	v_value = a_value;\n";

		frag << "	gl_FragColor = res;\n"; // Put result to color variable.
	}

	vtx << "}\n";
	frag << "}\n";

	m_vertShaderSource = vtx.str();
	m_fragShaderSource = frag.str();

	if (isAttributeCase)
	{
		if (m_isLoopBoundStable)
		{
			// Every execution has same number of iterations.

			m_attributes.push_back(AttribSpec("a_bound",	Vec4(loopBound, 0.0f, 0.0f, 0.0f),
															Vec4(loopBound, 0.0f, 0.0f, 0.0f),
															Vec4(loopBound, 0.0f, 0.0f, 0.0f),
															Vec4(loopBound, 0.0f, 0.0f, 0.0f)));
		}
		else if (isVertexCase)
		{
			// Vertex case, with non-constant number of iterations.

			const int	numComponents	= 4;
			int			numVertices		= (getGridWidth() + 1) * (getGridHeight() + 1);

			// setupProgram() will later bind this array as an attribute.
			m_boundArray.resize(numVertices * numComponents);

			// Vary between low and high loop bounds; they should average to loopBound however.
			for (int i = 0; i < (int)m_boundArray.size(); i++)
			{
				if (i % numComponents == 0)
					m_boundArray[i] = (i / numComponents) % 2 == 0 ? unstableBoundLow : unstableBoundHigh;
				else
					m_boundArray[i] = 0.0f;
			}
		}
		else // !m_isLoopBoundStable && !isVertexCase
		{
			// Fragment case, with non-constant number of iterations.
			// \note fract(a_bound) < 0.5 will be true for every second fragment.

			float minValue = 0.0f;
			float maxValue = (float)getViewportWidth()*0.5f;
			m_attributes.push_back(AttribSpec("a_bound",	Vec4(minValue, 0.0f, 0.0f, 0.0f),
															Vec4(maxValue, 0.0f, 0.0f, 0.0f),
															Vec4(minValue, 0.0f, 0.0f, 0.0f),
															Vec4(maxValue, 0.0f, 0.0f, 0.0f)));
		}
	}

	m_attributes.push_back(AttribSpec("a_value",	Vec4(0.0f, 0.1f, 0.2f, 0.3f),
													Vec4(0.4f, 0.5f, 0.6f, 0.7f),
													Vec4(0.8f, 0.9f, 1.0f, 1.1f),
													Vec4(1.2f, 1.3f, 1.4f, 1.5f)));

	ControlStatementCase::init();
}

void LoopCase::setupProgram (deUint32 program)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	if (m_decisionType == DECISION_UNIFORM)
	{
		const float loopBound = 10.5f;

		int location = gl.getUniformLocation(program, "u_bound");
		gl.uniform1f(location, loopBound);
	}
	else if (m_decisionType == DECISION_ATTRIBUTE && !m_isLoopBoundStable && m_caseType == CASETYPE_VERTEX)
	{
		// Setup per-vertex loop bounds calculated in init().

		const int	numComponents		= 4;
		int			boundAttribLocation	= gl.getAttribLocation(program, "a_bound");

		DE_ASSERT((int)m_boundArray.size() == numComponents * (getGridWidth() + 1) * (getGridHeight() + 1));

		gl.genBuffers(1, &m_arrayBuffer);
		gl.bindBuffer(GL_ARRAY_BUFFER, m_arrayBuffer);
		gl.bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(m_boundArray.size()*sizeof(float)), &m_boundArray[0], GL_STATIC_DRAW);
		gl.enableVertexAttribArray(boundAttribLocation);
		gl.vertexAttribPointer(boundAttribLocation, (GLint)numComponents, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "Setup program state");
}

LoopCase::~LoopCase (void)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	if (m_arrayBuffer)
	{
		gl.deleteBuffers(1, &m_arrayBuffer);
		m_arrayBuffer = 0;
	}
}

void LoopCase::deinit (void)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	m_boundArray.clear();

	if (m_arrayBuffer)
	{
		gl.deleteBuffers(1, &m_arrayBuffer);
		m_arrayBuffer = 0;
	}

	ShaderPerformanceCase::deinit();
}

// A reference case, same calculations as the actual tests but without control statements.
class WorkloadReferenceCase : public ControlStatementCase
{
public:
							WorkloadReferenceCase		(Context& context, const char* name, const char* description, bool isVertex);

	void					init						(void);

protected:
	virtual void			writeWorkload				(std::ostringstream& dst, const char* resultVariableName, const char* inputVariableName) const = 0;
};

WorkloadReferenceCase::WorkloadReferenceCase (Context& context, const char* name, const char* description, bool isVertex)
	: ControlStatementCase(context.getTestContext(), context.getRenderContext(), name, description, isVertex ? CASETYPE_VERTEX : CASETYPE_FRAGMENT)
{
}

void WorkloadReferenceCase::init (void)
{
	bool isVertexCase = m_caseType == CASETYPE_VERTEX;

	std::ostringstream	vtx;
	std::ostringstream	frag;
	std::ostringstream&	op			= isVertexCase ? vtx : frag;

	vtx << "attribute highp vec4 a_position;\n";	// Position attribute.
	vtx << "attribute mediump vec4 a_value;\n";		// Value for workload calculations.

	// Varyings.
	if (isVertexCase)
	{
		vtx << "varying mediump vec4 v_color;\n";
		frag << "varying mediump vec4 v_color;\n";
	}
	else
	{
		vtx << "varying mediump vec4 v_value;\n";
		frag << "varying mediump vec4 v_value;\n";
	}

	vtx << "\n";
	vtx << "void main()\n";
	vtx << "{\n";
	vtx << "	gl_Position = a_position;\n";

	frag << "\n";
	frag << "void main()\n";
	frag << "{\n";

	op << "\tmediump vec4 res;\n";
	writeWorkload(op, "res", isVertexCase ? "a_value" : "v_value");

	if (isVertexCase)
	{
		// Put result to color variable.
		vtx << "	v_color = res;\n";
		frag << "	gl_FragColor = v_color;\n";
	}
	else
	{
		vtx << "	v_value = a_value;\n";	// Transfer input to fragment shader through varying.
		frag << "	gl_FragColor = res;\n";	// Put result to color variable.
	}

	vtx << "}\n";
	frag << "}\n";

	m_vertShaderSource = vtx.str();
	m_fragShaderSource = frag.str();

	m_attributes.push_back(AttribSpec("a_value",	Vec4(0.0f, 0.1f, 0.2f, 0.3f),
													Vec4(0.4f, 0.5f, 0.6f, 0.7f),
													Vec4(0.8f, 0.9f, 1.0f, 1.1f),
													Vec4(1.2f, 1.3f, 1.4f, 1.5f)));

	ControlStatementCase::init();
}

class LoopWorkloadReferenceCase : public WorkloadReferenceCase
{
public:
	LoopWorkloadReferenceCase (Context& context, const char* name, const char* description, bool isAttributeStable, bool isVertex)
		: WorkloadReferenceCase		(context, name, description, isVertex)
		, m_isAttributeStable		(isAttributeStable)
	{
	}

protected:
	void writeWorkload (std::ostringstream& dst, const char* resultVariableName, const char* inputVariableName) const;

private:
	bool m_isAttributeStable;
};

void LoopWorkloadReferenceCase::writeWorkload (std::ostringstream& dst, const char* resultVariableName, const char* inputVariableName) const
{
	const int	loopIterations	= 11;
	bool		isVertexCase	= m_caseType == CASETYPE_VERTEX;

	dst << "\t" << resultVariableName << " = vec4(0.0);\n";

	for (int i = 0; i < loopIterations; i++)
	{
		dst << "\t";
		writeLoopWorkload(dst, resultVariableName, inputVariableName);
		dst << "\n";
	}

	if (!isVertexCase && !m_isAttributeStable)
	{
		// Corresponds to the fract() done in a real test's fragment case with non-stable attribute.
		dst << "	res.x = fract(res.x);\n";
	}
}

class ConditionalWorkloadReferenceCase : public WorkloadReferenceCase
{
public:
	ConditionalWorkloadReferenceCase (Context& context, const char* name, const char* description, bool isAttributeStable, bool isVertex)
		: WorkloadReferenceCase		(context, name, description, isVertex)
		, m_isAttributeStable		(isAttributeStable)
	{
	}

protected:
	void writeWorkload (std::ostringstream& dst, const char* resultVariableName, const char* inputVariableName) const;

private:
	bool m_isAttributeStable;
};

void ConditionalWorkloadReferenceCase::writeWorkload (std::ostringstream& dst, const char* resultVariableName, const char* inputVariableName) const
{
	bool isVertexCase = m_caseType == CASETYPE_VERTEX;

	dst << "\t";
	writeConditionalWorkload(dst, resultVariableName, inputVariableName);
	dst << "\n";

	if (!isVertexCase && !m_isAttributeStable)
	{
		// Corresponds to the fract() done in a real test's fragment case with non-stable attribute.
		dst << "	res.x = fract(res.x);\n";
	}
}

// A workload reference case for e.g. a conditional case with a branch with no computation.
class EmptyWorkloadReferenceCase : public WorkloadReferenceCase
{
public:
	EmptyWorkloadReferenceCase	(Context& context, const char* name, const char* description, bool isVertex)
		: WorkloadReferenceCase (context, name, description, isVertex)
	{
	}

protected:
	void writeWorkload (std::ostringstream& dst, const char* resultVariableName, const char* inputVariableName) const
	{
		dst << "\t" << resultVariableName << " = " << inputVariableName << ";\n";
	}
};

ShaderControlStatementTests::ShaderControlStatementTests (Context& context)
	: TestCaseGroup(context, "control_statement", "Control Statement Performance Tests")
{
}

ShaderControlStatementTests::~ShaderControlStatementTests (void)
{
}

void ShaderControlStatementTests::init (void)
{
	// Conditional cases (if-else).

	tcu::TestCaseGroup* ifElseGroup = new tcu::TestCaseGroup(m_testCtx, "if_else", "if-else Conditional Performance Tests");
	addChild(ifElseGroup);

	for (int isFrag = 0; isFrag <= 1; isFrag++)
	{
		bool isVertex = isFrag == 0;
		ShaderPerformanceCaseGroup* vertexOrFragmentGroup = new ShaderPerformanceCaseGroup(m_testCtx, isVertex ? "vertex" : "fragment", "");
		ifElseGroup->addChild(vertexOrFragmentGroup);

		DE_STATIC_ASSERT(DECISION_STATIC == 0);
		for (int decisionType = (int)DECISION_STATIC; decisionType < (int)DECISION_LAST; decisionType++)
		{
			const char* decisionName = decisionType == (int)DECISION_STATIC		? "static" :
										decisionType == (int)DECISION_UNIFORM	? "uniform" :
										decisionType == (int)DECISION_ATTRIBUTE	? (isVertex ? "attribute" : "varying") :
																					DE_NULL;
			DE_ASSERT(decisionName != DE_NULL);

			for (int workloadDivision = 0; workloadDivision < ConditionalCase::WORKLOAD_DIVISION_LAST; workloadDivision++)
			{
				const char* workloadDivisionSuffix = workloadDivision == (int)ConditionalCase::WORKLOAD_DIVISION_EVEN			? "" :
													 workloadDivision == (int)ConditionalCase::WORKLOAD_DIVISION_TRUE_HEAVY		? "_with_heavier_true" :
													 workloadDivision == (int)ConditionalCase::WORKLOAD_DIVISION_FALSE_HEAVY	? "_with_heavier_false" :
																																  DE_NULL;
				DE_ASSERT(workloadDivisionSuffix != DE_NULL);

				DE_STATIC_ASSERT(ConditionalCase::BRANCH_TRUE == 0);
				for (int branchResult = (int)ConditionalCase::BRANCH_TRUE; branchResult < (int)ConditionalCase::BRANCH_LAST; branchResult++)
				{
					if (decisionType != (int)DECISION_ATTRIBUTE && branchResult == (int)ConditionalCase::BRANCH_MIXED)
						continue;

					const char* branchResultName = branchResult == (int)ConditionalCase::BRANCH_TRUE	? "true" :
												   branchResult == (int)ConditionalCase::BRANCH_FALSE	? "false" :
												   branchResult == (int)ConditionalCase::BRANCH_MIXED	? "mixed" :
																										  DE_NULL;
					DE_ASSERT(branchResultName != DE_NULL);

					string caseName = string("") + decisionName + "_" + branchResultName + workloadDivisionSuffix;

					vertexOrFragmentGroup->addChild(new ConditionalCase(m_context, caseName.c_str(), "",
																		(DecisionType)decisionType, (ConditionalCase::BranchResult)branchResult,
																		(ConditionalCase::WorkloadDivision)workloadDivision, isVertex));
				}
			}
		}

		if (isVertex)
			vertexOrFragmentGroup->addChild(new ConditionalWorkloadReferenceCase(m_context, "reference", "", true, isVertex));
		else
		{
			// Only fragment case with BRANCH_MIXED has an additional fract() call.
			vertexOrFragmentGroup->addChild(new ConditionalWorkloadReferenceCase(m_context, "reference_unmixed", "", true, isVertex));
			vertexOrFragmentGroup->addChild(new ConditionalWorkloadReferenceCase(m_context, "reference_mixed", "", false, isVertex));
		}

		vertexOrFragmentGroup->addChild(new EmptyWorkloadReferenceCase(m_context, "reference_empty", "", isVertex));
	}

	// Loop cases.

	static const struct
	{
		LoopCase::LoopType	type;
		const char*			name;
		const char*			description;
	} loopGroups[] =
	{
		{LoopCase::LOOP_FOR,		"for",		"for Loop Performance Tests"},
		{LoopCase::LOOP_WHILE,		"while",	"while Loop Performance Tests"},
		{LoopCase::LOOP_DO_WHILE,	"do_while",	"do-while Loop Performance Tests"}
	};

	for (int groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(loopGroups); groupNdx++)
	{
		tcu::TestCaseGroup* currentLoopGroup = new tcu::TestCaseGroup(m_testCtx, loopGroups[groupNdx].name, loopGroups[groupNdx].description);
		addChild(currentLoopGroup);

		for (int isFrag = 0; isFrag <= 1; isFrag++)
		{
			bool isVertex = isFrag == 0;
			ShaderPerformanceCaseGroup* vertexOrFragmentGroup = new ShaderPerformanceCaseGroup(m_testCtx, isVertex ? "vertex" : "fragment", "");
			currentLoopGroup->addChild(vertexOrFragmentGroup);

			DE_STATIC_ASSERT(DECISION_STATIC == 0);
			for (int decisionType = (int)DECISION_STATIC; decisionType < (int)DECISION_LAST; decisionType++)
			{
				const char* decisionName = decisionType == (int)DECISION_STATIC		? "static" :
										   decisionType == (int)DECISION_UNIFORM	? "uniform" :
										   decisionType == (int)DECISION_ATTRIBUTE	? (isVertex ? "attribute" : "varying") :
																					  DE_NULL;
				DE_ASSERT(decisionName != DE_NULL);

				if (decisionType == (int)DECISION_ATTRIBUTE)
				{
					vertexOrFragmentGroup->addChild(new LoopCase(m_context, (string(decisionName) + "_stable").c_str(), "", loopGroups[groupNdx].type, (DecisionType)decisionType, true, isVertex));
					vertexOrFragmentGroup->addChild(new LoopCase(m_context, (string(decisionName) + "_unstable").c_str(), "", loopGroups[groupNdx].type, (DecisionType)decisionType, false, isVertex));
				}
				else
					vertexOrFragmentGroup->addChild(new LoopCase(m_context, decisionName, "", loopGroups[groupNdx].type, (DecisionType)decisionType, true, isVertex));

			}

			if (isVertex)
				vertexOrFragmentGroup->addChild(new LoopWorkloadReferenceCase(m_context, "reference", "", true, isVertex));
			else
			{
				// Only fragment case with unstable attribute has an additional fract() call.
				vertexOrFragmentGroup->addChild(new LoopWorkloadReferenceCase(m_context, "reference_stable", "", true, isVertex));
				vertexOrFragmentGroup->addChild(new LoopWorkloadReferenceCase(m_context, "reference_unstable", "", false, isVertex));
			}
		}
	}
}

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