13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 2.0 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Shader loop tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \todo [petri]
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * - loop body cases (do different operations inside the loops)
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * - more complex nested loops
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *   * random generated?
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *   * dataflow variations
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *   * mixed loop types
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es2fShaderLoopTests.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsShaderRenderCase.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderUtil.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuStringTemplate.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deInt32.h"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <map>
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace std;
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace tcu;
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glu;
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace deqp::gls;
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles2
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Repeated with for, while, do-while. Examples given as 'for' loops.
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Repeated for const, uniform, dynamic loops.
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum LoopCase
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_EMPTY_BODY = 0,								// for (...) { }
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST,		// for (...) { break; <body>; }
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST,		// for (...) { <body>; break; }
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK,				// for (...) { <body>; if (cond) break; }
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_SINGLE_STATEMENT,								// for (...) statement;
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_COMPOUND_STATEMENT,							// for (...) { statement; statement; }
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_SEQUENCE_STATEMENT,							// for (...) statement, statement;
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_NO_ITERATIONS,									// for (i=0; i<0; i++) ...
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_SINGLE_ITERATION,								// for (i=0; i<1; i++) ...
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_SELECT_ITERATION_COUNT,						// for (i=0; i<a?b:c; i++) ...
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_CONDITIONAL_CONTINUE,							// for (...) { if (cond) continue; }
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_UNCONDITIONAL_CONTINUE,						// for (...) { <body>; continue; }
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_ONLY_CONTINUE,									// for (...) { continue; }
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_DOUBLE_CONTINUE,								// for (...) { if (cond) continue; <body>; continue; }
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_CONDITIONAL_BREAK,								// for (...) { if (cond) break; }
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_UNCONDITIONAL_BREAK,							// for (...) { <body>; break; }
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_PRE_INCREMENT,									// for (...; ++i) { <body>; }
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_POST_INCREMENT,								// for (...; i++) { <body>; }
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_MIXED_BREAK_CONTINUE,
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_VECTOR_COUNTER,								// for (ivec3 ndx = ...; ndx.x < ndx.y; ndx.x += ndx.z) { ... }
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_101_ITERATIONS,								// loop for 101 iterations
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_SEQUENCE,										// two loops in sequence
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_NESTED,										// two nested loops
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_NESTED_SEQUENCE,								// two loops in sequence nested inside a third
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_NESTED_TRICKY_DATAFLOW_1,						// nested loops with tricky data flow
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_NESTED_TRICKY_DATAFLOW_2,						// nested loops with tricky data flow
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_CONDITIONAL_BODY,								// conditional body in loop
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_FUNCTION_CALL_RETURN,							// function call in loop with return value usage
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_FUNCTION_CALL_INOUT,							// function call with inout parameter usage
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_LAST
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum LoopRequirement
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPREQUIREMENT_STANDARD = 0,		//!< Minimum requirements by standard (constant for loop with simple iterator).
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPREQUIREMENT_UNIFORM,
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPREQUIREMENT_DYNAMIC,
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPREQUIREMENT_LAST
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getLoopCaseName (LoopCase loopCase)
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* s_names[] =
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"empty_body",
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"infinite_with_unconditional_break_first",
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"infinite_with_unconditional_break_last",
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"infinite_with_conditional_break",
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"single_statement",
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"compound_statement",
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"sequence_statement",
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"no_iterations",
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"single_iteration",
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"select_iteration_count",
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"conditional_continue",
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"unconditional_continue",
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"only_continue",
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"double_continue",
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"conditional_break",
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"unconditional_break",
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"pre_increment",
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"post_increment",
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"mixed_break_continue",
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"vector_counter",
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"101_iterations",
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"sequence",
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"nested",
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"nested_sequence",
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"nested_tricky_dataflow_1",
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"nested_tricky_dataflow_2",
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"conditional_body",
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"function_call_return",
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"function_call_inout"
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == LOOPCASE_LAST);
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(deInBounds32((int)loopCase, 0, LOOPCASE_LAST));
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return s_names[(int)loopCase];
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum LoopType
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPTYPE_FOR = 0,
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPTYPE_WHILE,
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPTYPE_DO_WHILE,
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPTYPE_LAST
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getLoopTypeName (LoopType loopType)
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* s_names[] =
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"for",
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"while",
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"do_while"
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == LOOPTYPE_LAST);
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(deInBounds32((int)loopType, 0, LOOPTYPE_LAST));
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return s_names[(int)loopType];
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum LoopCountType
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCOUNT_CONSTANT = 0,
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCOUNT_UNIFORM,
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCOUNT_DYNAMIC,
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCOUNT_LAST
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getLoopCountTypeName (LoopCountType countType)
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* s_names[] =
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"constant",
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform",
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"dynamic"
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == LOOPCOUNT_LAST);
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(deInBounds32((int)countType, 0, LOOPCOUNT_LAST));
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return s_names[(int)countType];
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void evalLoop0Iters	(ShaderEvalContext& c) { c.color.xyz()	= c.coords.swizzle(0,1,2); }
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void evalLoop1Iters	(ShaderEvalContext& c) { c.color.xyz()	= c.coords.swizzle(1,2,3); }
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void evalLoop2Iters	(ShaderEvalContext& c) { c.color.xyz()	= c.coords.swizzle(2,3,0); }
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void evalLoop3Iters	(ShaderEvalContext& c) { c.color.xyz()	= c.coords.swizzle(3,0,1); }
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic ShaderEvalFunc getLoopEvalFunc (int numIters)
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (numIters % 4)
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 0: return evalLoop0Iters;
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 1:	return evalLoop1Iters;
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 2:	return evalLoop2Iters;
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 3:	return evalLoop3Iters;
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!"Invalid loop iteration count.");
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return NULL;
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// ShaderLoopCase
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderLoopCase : public ShaderRenderCase
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								ShaderLoopCase			(Context& context, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, LoopRequirement requirement, const char* vertShaderSource, const char* fragShaderSource);
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual						~ShaderLoopCase			(void);
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						init					(void);
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								ShaderLoopCase			(const ShaderLoopCase&);	// not allowed!
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderLoopCase&				operator=				(const ShaderLoopCase&);	// not allowed!
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				setup					(int programID);
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				setupUniforms			(int programID, const Vec4& constCoords);
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LoopRequirement				m_requirement;
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2263c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderLoopCase::ShaderLoopCase (Context& context, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, LoopRequirement requirement, const char* vertShaderSource, const char* fragShaderSource)
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ShaderRenderCase	(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, description, isVertexCase, evalFunc)
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_requirement		(requirement)
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_vertShaderSource	= vertShaderSource;
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fragShaderSource	= fragShaderSource;
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2343c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderLoopCase::~ShaderLoopCase (void)
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderLoopCase::init (void)
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool isSupported = true;
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_requirement == LOOPREQUIREMENT_UNIFORM)
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		isSupported = m_isVertexCase ? m_ctxInfo.isVertexUniformLoopSupported()
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 : m_ctxInfo.isFragmentUniformLoopSupported();
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_requirement == LOOPREQUIREMENT_DYNAMIC)
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		isSupported = m_isVertexCase ? m_ctxInfo.isVertexDynamicLoopSupported()
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 : m_ctxInfo.isFragmentDynamicLoopSupported();
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ShaderRenderCase::init();
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const CompileFailed&)
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!isSupported)
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("Loop type is not supported");
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw;
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderLoopCase::setup (int programID)
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(programID);
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderLoopCase::setupUniforms (int programID, const Vec4& constCoords)
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(programID);
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(constCoords);
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Test case creation.
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic ShaderLoopCase* createGenericLoopCase (Context& context, const char* caseName, const char* description, bool isVertexCase, LoopType loopType, LoopCountType loopCountType, Precision loopCountPrecision, DataType loopCountDataType)
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream vtx;
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream frag;
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream& op = isVertexCase ? vtx : frag;
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "attribute highp vec4 a_position;\n";
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "attribute highp vec4 a_coords;\n";
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopCountType == LOOPCOUNT_DYNAMIC)
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "attribute mediump float a_one;\n";
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "varying mediump vec3 v_color;\n";
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "varying mediump vec3 v_color;\n";
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "varying mediump vec4 v_coords;\n";
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "varying mediump vec4 v_coords;\n";
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_DYNAMIC)
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vtx << "varying mediump float v_one;\n";
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			frag << "varying mediump float v_one;\n";
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [petri] Pass numLoopIters from outside?
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		numLoopIters = 3;
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	isIntCounter = isDataTypeIntOrIVec(loopCountDataType);
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isIntCounter)
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_UNIFORM || loopCountType == LOOPCOUNT_DYNAMIC)
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "uniform ${COUNTER_PRECISION} int " << getIntUniformName(numLoopIters) << ";\n";
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_UNIFORM || loopCountType == LOOPCOUNT_DYNAMIC)
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "uniform ${COUNTER_PRECISION} float " << getFloatFractionUniformName(numLoopIters) << ";\n";
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numLoopIters != 1)
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "uniform ${COUNTER_PRECISION} float uf_one;\n";
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "\n";
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "void main()\n";
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "{\n";
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "	gl_Position = a_position;\n";
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "\n";
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "void main()\n";
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "{\n";
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	${PRECISION} vec4 coords = a_coords;\n";
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	${PRECISION} vec4 coords = v_coords;\n";
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopCountType == LOOPCOUNT_DYNAMIC)
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isIntCounter)
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isVertexCase)
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vtx << "	${COUNTER_PRECISION} int one = int(a_one + 0.5);\n";
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				frag << "	${COUNTER_PRECISION} int one = int(v_one + 0.5);\n";
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isVertexCase)
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vtx << "	${COUNTER_PRECISION} float one = a_one;\n";
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				frag << "	${COUNTER_PRECISION} float one = v_one;\n";
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read array.
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	op << "	${PRECISION} vec4 res = coords;\n";
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Loop iteration count.
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string	iterMaxStr;
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isIntCounter)
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_CONSTANT)
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			iterMaxStr = de::toString(numLoopIters);
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_UNIFORM)
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			iterMaxStr = getIntUniformName(numLoopIters);
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_DYNAMIC)
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			iterMaxStr = string(getIntUniformName(numLoopIters)) + "*one";
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_CONSTANT)
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			iterMaxStr = "1.0";
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_UNIFORM)
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			iterMaxStr = "uf_one";
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_DYNAMIC)
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			iterMaxStr = "uf_one*one";
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Loop operations.
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string initValue		= isIntCounter ? "0" : "0.05";
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string loopCountDeclStr	= "${COUNTER_PRECISION} ${LOOP_VAR_TYPE} ndx = " + initValue;
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string loopCmpStr		= ("ndx < " + iterMaxStr);
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string incrementStr;
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isIntCounter)
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		incrementStr = "ndx++";
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_CONSTANT)
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			incrementStr = string("ndx += ") + de::toString(1.0f / numLoopIters);
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_UNIFORM)
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			incrementStr = string("ndx += ") + getFloatFractionUniformName(numLoopIters);
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_DYNAMIC)
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			incrementStr = string("ndx += ") + getFloatFractionUniformName(numLoopIters) + "*one";
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Loop body.
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string loopBody;
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	loopBody = "		res = res.yzwx;\n";
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopType == LOOPTYPE_FOR)
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	for (" + loopCountDeclStr + "; " + loopCmpStr + "; " + incrementStr + ")\n";
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	{\n";
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << loopBody;
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	}\n";
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (loopType == LOOPTYPE_WHILE)
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "\t" << loopCountDeclStr + ";\n";
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	while (" + loopCmpStr + ")\n";
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	{\n";
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << loopBody;
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "\t\t" + incrementStr + ";\n";
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	}\n";
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (loopType == LOOPTYPE_DO_WHILE)
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "\t" << loopCountDeclStr + ";\n";
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	do\n";
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	{\n";
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << loopBody;
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "\t\t" + incrementStr + ";\n";
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	} while (" + loopCmpStr + ");\n";
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	v_color = res.rgb;\n";
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	gl_FragColor = vec4(v_color.rgb, 1.0);\n";
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	v_coords = a_coords;\n";
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	gl_FragColor = vec4(res.rgb, 1.0);\n";
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_DYNAMIC)
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vtx << "	v_one = a_one;\n";
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "}\n";
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "}\n";
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fill in shader templates.
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	map<string, string> params;
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("LOOP_VAR_TYPE", getDataTypeName(loopCountDataType)));
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("PRECISION", "mediump"));
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("COUNTER_PRECISION", getPrecisionName(loopCountPrecision)));
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate vertTemplate(vtx.str().c_str());
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate fragTemplate(frag.str().c_str());
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string vertexShaderSource = vertTemplate.specialize(params);
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string fragmentShaderSource = fragTemplate.specialize(params);
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create the case.
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderEvalFunc evalFunc = getLoopEvalFunc(numLoopIters);
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LoopRequirement requirement;
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopType == LOOPTYPE_FOR)
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_CONSTANT)
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			requirement = LOOPREQUIREMENT_STANDARD;
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_UNIFORM)
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			requirement = LOOPREQUIREMENT_UNIFORM;
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			requirement = LOOPREQUIREMENT_DYNAMIC;
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		requirement = LOOPREQUIREMENT_DYNAMIC;
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new ShaderLoopCase(context, caseName, description, isVertexCase, evalFunc, requirement, vertexShaderSource.c_str(), fragmentShaderSource.c_str());
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [petri] Generalize to float as well?
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic ShaderLoopCase* createSpecialLoopCase (Context& context, const char* caseName, const char* description, bool isVertexCase, LoopCase loopCase, LoopType loopType, LoopCountType loopCountType)
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream vtx;
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream frag;
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream& op = isVertexCase ? vtx : frag;
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "attribute highp vec4 a_position;\n";
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "attribute highp vec4 a_coords;\n";
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopCountType == LOOPCOUNT_DYNAMIC)
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "attribute mediump float a_one;\n";
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Attribute and varyings.
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "varying mediump vec3 v_color;\n";
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "varying mediump vec3 v_color;\n";
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "varying mediump vec4 v_coords;\n";
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "varying mediump vec4 v_coords;\n";
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_DYNAMIC)
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vtx << "varying mediump float v_one;\n";
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			frag << "varying mediump float v_one;\n";
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopCase == LOOPCASE_SELECT_ITERATION_COUNT)
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "uniform bool ub_true;\n";
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	op << "uniform ${COUNTER_PRECISION} int ui_zero, ui_one, ui_two, ui_three, ui_four, ui_five, ui_six;\n";
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopCase == LOOPCASE_101_ITERATIONS)
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "uniform ${COUNTER_PRECISION} int ui_oneHundredOne;\n";
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int iterCount	= 3;	// value to use in loop
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numIters	= 3;	// actual number of iterations
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate helpers if necessary.
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopCase == LOOPCASE_FUNCTION_CALL_RETURN)
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "\n${PRECISION} vec4 func (in ${PRECISION} vec4 coords) { return coords.yzwx; }\n";
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (loopCase == LOOPCASE_FUNCTION_CALL_INOUT)
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "\nvoid func (inout ${PRECISION} vec4 coords) { coords = coords.yzwx; }\n";
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "\n";
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "void main()\n";
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "{\n";
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "	gl_Position = a_position;\n";
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "\n";
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "void main()\n";
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "{\n";
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopCountType == LOOPCOUNT_DYNAMIC)
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isVertexCase)
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vtx << "	${COUNTER_PRECISION} int one = int(a_one + 0.5);\n";
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			frag << "	${COUNTER_PRECISION} int one = int(v_one + 0.5);\n";
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	${PRECISION} vec4 coords = a_coords;\n";
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	${PRECISION} vec4 coords = v_coords;\n";
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read array.
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	op << "	${PRECISION} vec4 res = coords;\n";
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Handle all loop types.
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string counterPrecisionStr = "mediump";
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string forLoopStr;
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string whileLoopStr;
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string doWhileLoopPreStr;
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string doWhileLoopPostStr;
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopType == LOOPTYPE_FOR)
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (loopCase)
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_EMPTY_BODY:
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} {}\n";
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST:
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (;;) { break; res = res.yzwx; }\n";
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST:
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 1;
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (;;) { res = res.yzwx; break; }\n";
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK:
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (;;) { res = res.yzwx; if (i == ${ONE}) break; i++; }\n";
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SINGLE_STATEMENT:
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} res = res.yzwx;\n";
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_COMPOUND_STATEMENT:
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 2;
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2 * iterCount;
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { res = res.yzwx; res = res.yzwx; }\n";
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SEQUENCE_STATEMENT:
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 2;
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2 * iterCount;
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} res = res.yzwx, res = res.yzwx;\n";
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NO_ITERATIONS:
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 0;
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 0;
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} res = res.yzwx;\n";
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SINGLE_ITERATION:
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 1;
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 1;
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} res = res.yzwx;\n";
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SELECT_ITERATION_COUNT:
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (int i = 0; i < (ub_true ? ${ITER_COUNT} : 0); i++) res = res.yzwx;\n";
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_CONDITIONAL_CONTINUE:
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount - 1;
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { if (i == ${TWO}) continue; res = res.yzwx; }\n";
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_UNCONDITIONAL_CONTINUE:
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { res = res.yzwx; continue; }\n";
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_ONLY_CONTINUE:
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { continue; }\n";
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_DOUBLE_CONTINUE:
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount - 1;
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { if (i == ${TWO}) continue; res = res.yzwx; continue; }\n";
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_CONDITIONAL_BREAK:
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { if (i == ${TWO}) break; res = res.yzwx; }\n";
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_UNCONDITIONAL_BREAK:
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 1;
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { res = res.yzwx; break; }\n";
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_PRE_INCREMENT:
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (int i = 0; i < ${ITER_COUNT}; ++i) { res = res.yzwx; }\n";
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_POST_INCREMENT:
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { res = res.yzwx; }\n";
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_MIXED_BREAK_CONTINUE:
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2;
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 5;
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { if (i == 0) continue; else if (i == 3) break; res = res.yzwx; }\n";
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_VECTOR_COUNTER:
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (${COUNTER_PRECISION} ivec4 i = ivec4(0, 1, ${ITER_COUNT}, 0); i.x < i.z; i.x += i.y) { res = res.yzwx; }\n";
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_101_ITERATIONS:
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount = 101;
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} res = res.yzwx;\n";
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SEQUENCE:
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 5;
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 5;
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i;\n";
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (i = 0; i < ${TWO}; i++) { res = res.yzwx; }\n";
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (; i < ${ITER_COUNT}; i++) { res = res.yzwx; }\n";
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED:
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2 * iterCount;
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (${COUNTER_PRECISION} int i = 0; i < ${TWO}; i++)\n";
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		for (${COUNTER_PRECISION} int j = 0; j < ${ITER_COUNT}; j++)\n";
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_SEQUENCE:
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 3 * iterCount;
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (${COUNTER_PRECISION} int i = 0; i < ${ITER_COUNT}; i++)\n";
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		for (${COUNTER_PRECISION} int j = 0; j < ${TWO}; j++)\n";
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		for (${COUNTER_PRECISION} int j = 0; j < ${ONE}; j++)\n";
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_TRICKY_DATAFLOW_1:
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP}\n";
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		res = coords; // ignore outer loop effect \n";
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		for (${COUNTER_PRECISION} int j = 0; j < ${TWO}; j++)\n";
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_TRICKY_DATAFLOW_2:
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount;
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP}\n";
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		res = coords.wxyz;\n";
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		for (${COUNTER_PRECISION} int j = 0; j < ${TWO}; j++)\n";
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		coords = res;\n";
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_CONDITIONAL_BODY:
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = de::min(2, iterCount);
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} if (i < 2) res = res.yzwx;\n";
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_FUNCTION_CALL_RETURN:
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount;
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP}\n";
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		res = func(res);\n";
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_FUNCTION_CALL_INOUT:
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount;
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP}\n";
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		func(res);\n";
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_CONSTANT)
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			forLoopStr = string("for (") + counterPrecisionStr + " int i = 0; i < " + de::toString(iterCount) + "; i++)";
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_UNIFORM)
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			forLoopStr = string("for (") + counterPrecisionStr + " int i = 0; i < " + getIntUniformName(iterCount) + "; i++)";
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_DYNAMIC)
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			forLoopStr = string("for (") + counterPrecisionStr + " int i = 0; i < one*" + getIntUniformName(iterCount) + "; i++)";
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (loopType == LOOPTYPE_WHILE)
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (loopCase)
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_EMPTY_BODY:
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} {}\n";
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST:
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (true) { break; res = res.yzwx; }\n";
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST:
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 1;
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (true) { res = res.yzwx; break; }\n";
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK:
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (true) { res = res.yzwx; if (i == ${ONE}) break; i++; }\n";
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SINGLE_STATEMENT:
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} res = res.yzwx;\n";
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_COMPOUND_STATEMENT:
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 2;
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2 * iterCount;
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} { res = res.yzwx; res = res.yzwx; }\n";
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SEQUENCE_STATEMENT:
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 2;
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2 * iterCount;
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} res = res.yzwx, res = res.yzwx;\n";
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NO_ITERATIONS:
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 0;
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 0;
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} res = res.yzwx;\n";
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SINGLE_ITERATION:
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 1;
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 1;
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} res = res.yzwx;\n";
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SELECT_ITERATION_COUNT:
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (i < (ub_true ? ${ITER_COUNT} : 0)) { res = res.yzwx; i++; }\n";
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_CONDITIONAL_CONTINUE:
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount - 1;
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} { if (i == ${TWO}) continue; res = res.yzwx; }\n";
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_UNCONDITIONAL_CONTINUE:
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} { res = res.yzwx; continue; }\n";
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_ONLY_CONTINUE:
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} { continue; }\n";
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_DOUBLE_CONTINUE:
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount - 1;
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} { if (i == ${ONE}) continue; res = res.yzwx; continue; }\n";
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_CONDITIONAL_BREAK:
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} { if (i == ${THREE}) break; res = res.yzwx; }\n";
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_UNCONDITIONAL_BREAK:
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 1;
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} { res = res.yzwx; break; }\n";
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_PRE_INCREMENT:
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount - 1;
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (++i < ${ITER_COUNT}) { res = res.yzwx; }\n";
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_POST_INCREMENT:
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (i++ < ${ITER_COUNT}) { res = res.yzwx; }\n";
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_MIXED_BREAK_CONTINUE:
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2;
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 5;
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} { if (i == 0) continue; else if (i == 3) break; res = res.yzwx; }\n";
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_VECTOR_COUNTER:
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} ivec4 i = ivec4(0, 1, ${ITER_COUNT}, 0);\n";
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (i.x < i.z) { res = res.yzwx; i.x += i.y; }\n";
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_101_ITERATIONS:
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount = 101;
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} res = res.yzwx;\n";
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SEQUENCE:
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 6;
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= iterCount - 1;
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (i++ < ${TWO}) { res = res.yzwx; }\n";
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (i++ < ${ITER_COUNT}) { res = res.yzwx; }\n"; // \note skips one iteration
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED:
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2 * iterCount;
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (i++ < ${TWO})\n";
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		${COUNTER_PRECISION} int j = 0;\n";
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (j++ < ${ITER_COUNT})\n";
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_SEQUENCE:
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2 * iterCount;
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (i++ < ${ITER_COUNT})\n";
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		${COUNTER_PRECISION} int j = 0;\n";
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (j++ < ${ONE})\n";
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (j++ < ${THREE})\n"; // \note skips one iteration
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_TRICKY_DATAFLOW_1:
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP}\n";
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		res = coords; // ignore outer loop effect \n";
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		${COUNTER_PRECISION} int j = 0;\n";
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (j++ < ${TWO})\n";
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_TRICKY_DATAFLOW_2:
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount;
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP}\n";
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		res = coords.wxyz;\n";
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		${COUNTER_PRECISION} int j = 0;\n";
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (j++ < ${TWO})\n";
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		coords = res;\n";
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_CONDITIONAL_BODY:
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = de::min(1, iterCount);
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} if (i < 2) res = res.yzwx;\n";
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_FUNCTION_CALL_RETURN:
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount;
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP}\n";
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		res = func(res);\n";
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_FUNCTION_CALL_INOUT:
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount;
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP}\n";
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		func(res);\n";
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_CONSTANT)
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			whileLoopStr = string("\t") + counterPrecisionStr + " int i = 0;\n" + "	while(i++ < " + de::toString(iterCount) + ")";
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_UNIFORM)
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			whileLoopStr = string("\t") + counterPrecisionStr + " int i = 0;\n" + "	while(i++ < " + getIntUniformName(iterCount) + ")";
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_DYNAMIC)
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			whileLoopStr = string("\t") + counterPrecisionStr + " int i = 0;\n" + "	while(i++ < one*" + getIntUniformName(iterCount) + ")";
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(loopType == LOOPTYPE_DO_WHILE);
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (loopCase)
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_EMPTY_BODY:
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} {} ${DO_WHILE_POST}\n";
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST:
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { break; res = res.yzwx; } while (true);\n";
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST:
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 1;
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { res = res.yzwx; break; } while (true);\n";
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK:
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { res = res.yzwx; if (i == ${ONE}) break; i++; } while (true);\n";
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SINGLE_STATEMENT:
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} res = res.yzwx; ${DO_WHILE_POST}\n";
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_COMPOUND_STATEMENT:
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 2;
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2 * iterCount;
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} { res = res.yzwx; res = res.yzwx; } ${DO_WHILE_POST}\n";
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SEQUENCE_STATEMENT:
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 2;
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2 * iterCount;
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} res = res.yzwx, res = res.yzwx; ${DO_WHILE_POST}\n";
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NO_ITERATIONS:
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SINGLE_ITERATION:
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 1;
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 1;
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} res = res.yzwx; ${DO_WHILE_POST}\n";
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SELECT_ITERATION_COUNT:
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { res = res.yzwx; } while (++i < (ub_true ? ${ITER_COUNT} : 0));\n";
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_CONDITIONAL_CONTINUE:
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount - 1;
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} { if (i == ${TWO}) continue; res = res.yzwx; } ${DO_WHILE_POST}\n";
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_UNCONDITIONAL_CONTINUE:
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} { res = res.yzwx; continue; } ${DO_WHILE_POST}\n";
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_ONLY_CONTINUE:
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} { continue; } ${DO_WHILE_POST}\n";
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_DOUBLE_CONTINUE:
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount - 1;
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} { if (i == ${TWO}) continue; res = res.yzwx; continue; } ${DO_WHILE_POST}\n";
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_CONDITIONAL_BREAK:
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} { res = res.yzwx; if (i == ${ONE}) break; } ${DO_WHILE_POST}\n";
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_UNCONDITIONAL_BREAK:
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 1;
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} { res = res.yzwx; break; } ${DO_WHILE_POST}\n";
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_PRE_INCREMENT:
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { res = res.yzwx; } while (++i < ${ITER_COUNT});\n";
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_POST_INCREMENT:
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount + 1;
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { res = res.yzwx; } while (i++ < ${ITER_COUNT});\n";
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_MIXED_BREAK_CONTINUE:
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2;
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 5;
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} { if (i == 0) continue; else if (i == 3) break; res = res.yzwx; } ${DO_WHILE_POST}\n";
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_VECTOR_COUNTER:
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} ivec4 i = ivec4(0, 1, ${ITER_COUNT}, 0);\n";
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { res = res.yzwx; } while ((i.x += i.y) < i.z);\n";
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_101_ITERATIONS:
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount = 101;
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} res = res.yzwx; ${DO_WHILE_POST}\n";
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SEQUENCE:
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 5;
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 5;
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { res = res.yzwx; } while (++i < ${TWO});\n";
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { res = res.yzwx; } while (++i < ${ITER_COUNT});\n";
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED:
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2 * iterCount;
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do\n";
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		${COUNTER_PRECISION} int j = 0;\n";
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		do\n";
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (++j < ${ITER_COUNT});\n";
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	} while (++i < ${TWO});\n";
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_SEQUENCE:
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 3 * iterCount;
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do\n";
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		${COUNTER_PRECISION} int j = 0;\n";
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		do\n";
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (++j < ${TWO});\n";
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		do\n";
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (++j < ${THREE});\n";
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	} while (++i < ${ITER_COUNT});\n";
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_TRICKY_DATAFLOW_1:
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE}\n";
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		res = coords; // ignore outer loop effect \n";
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		${COUNTER_PRECISION} int j = 0;\n";
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		do\n";
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (++j < ${TWO});\n";
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	} ${DO_WHILE_POST}\n";
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_TRICKY_DATAFLOW_2:
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount;
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE}\n";
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		res = coords.wxyz;\n";
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		${COUNTER_PRECISION} int j = 0;\n";
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (j++ < ${TWO})\n";
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		coords = res;\n";
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	} ${DO_WHILE_POST}\n";
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_CONDITIONAL_BODY:
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = de::min(2, iterCount);
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} if (i < 2) res = res.yzwx; ${DO_WHILE_POST}\n";
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_FUNCTION_CALL_RETURN:
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount;
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE}\n";
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		res = func(res);\n";
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	} ${DO_WHILE_POST}\n";
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_FUNCTION_CALL_INOUT:
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount;
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE}\n";
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		func(res);\n";
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	} ${DO_WHILE_POST}\n";
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		doWhileLoopPreStr = string("\t") + counterPrecisionStr + " int i = 0;\n" + "\tdo ";
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_CONSTANT)
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			doWhileLoopPostStr = string(" while (++i < ") + de::toString(iterCount) + ");\n";
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_UNIFORM)
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			doWhileLoopPostStr = string(" while (++i < ") + getIntUniformName(iterCount) + ");\n";
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_DYNAMIC)
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			doWhileLoopPostStr = string(" while (++i < one*") + getIntUniformName(iterCount) + ");\n";
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Shader footers.
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	v_color = res.rgb;\n";
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	gl_FragColor = vec4(v_color.rgb, 1.0);\n";
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	v_coords = a_coords;\n";
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	gl_FragColor = vec4(res.rgb, 1.0);\n";
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_DYNAMIC)
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vtx << "	v_one = a_one;\n";
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "}\n";
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "}\n";
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Constants.
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string oneStr;
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string twoStr;
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string threeStr;
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string iterCountStr;
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopCountType == LOOPCOUNT_CONSTANT)
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		oneStr			= "1";
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		twoStr			= "2";
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		threeStr		= "3";
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		iterCountStr	= de::toString(iterCount);
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (loopCountType == LOOPCOUNT_UNIFORM)
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		oneStr			= "ui_one";
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		twoStr			= "ui_two";
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		threeStr		= "ui_three";
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		iterCountStr	= getIntUniformName(iterCount);
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (loopCountType == LOOPCOUNT_DYNAMIC)
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		oneStr			= "one*ui_one";
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		twoStr			= "one*ui_two";
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		threeStr		= "one*ui_three";
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		iterCountStr	= string("one*") + getIntUniformName(iterCount);
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else DE_ASSERT(false);
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fill in shader templates.
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	map<string, string> params;
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("PRECISION", "mediump"));
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("ITER_COUNT", iterCountStr));
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("COUNTER_PRECISION", counterPrecisionStr));
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("FOR_LOOP", forLoopStr));
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("WHILE_LOOP", whileLoopStr));
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("DO_WHILE_PRE", doWhileLoopPreStr));
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("DO_WHILE_POST", doWhileLoopPostStr));
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("ONE", oneStr));
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("TWO", twoStr));
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("THREE", threeStr));
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate vertTemplate(vtx.str().c_str());
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate fragTemplate(frag.str().c_str());
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string vertexShaderSource = vertTemplate.specialize(params);
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string fragmentShaderSource = fragTemplate.specialize(params);
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create the case.
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderEvalFunc evalFunc = getLoopEvalFunc(numIters);
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LoopRequirement requirement;
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopType == LOOPTYPE_FOR && loopCountType == LOOPCOUNT_CONSTANT)
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCase == LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK			||
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			loopCase == LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST	||
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			loopCase == LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST		||
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			loopCase == LOOPCASE_SELECT_ITERATION_COUNT						||
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			loopCase == LOOPCASE_VECTOR_COUNTER								||
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			loopCase == LOOPCASE_SEQUENCE)
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			requirement = LOOPREQUIREMENT_DYNAMIC;
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			requirement = LOOPREQUIREMENT_STANDARD;
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		requirement = LOOPREQUIREMENT_DYNAMIC;
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new ShaderLoopCase(context, caseName, description, isVertexCase, evalFunc, requirement, vertexShaderSource.c_str(), fragmentShaderSource.c_str());
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// ShaderLoopTests.
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderLoopTests::ShaderLoopTests(Context& context)
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "loops", "Loop Tests")
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderLoopTests::~ShaderLoopTests (void)
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderLoopTests::init (void)
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Loop cases.
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const ShaderType s_shaderTypes[] =
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		SHADERTYPE_VERTEX,
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		SHADERTYPE_FRAGMENT
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const DataType s_countDataType[] =
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_INT,
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int loopType = 0; loopType < LOOPTYPE_LAST; loopType++)
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* loopTypeName = getLoopTypeName((LoopType)loopType);
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int loopCountType = 0; loopCountType < LOOPCOUNT_LAST; loopCountType++)
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char* loopCountName = getLoopCountTypeName((LoopCountType)loopCountType);
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string groupName = string(loopTypeName) + "_" + string(loopCountName) + "_iterations";
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string groupDesc = string("Loop tests with ") + loopCountName + " loop counter.";
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* group = new TestCaseGroup(m_context, groupName.c_str(), groupDesc.c_str());
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			addChild(group);
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Generic cases.
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int precision = 0; precision < PRECISION_LAST; precision++)
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char* precisionName = getPrecisionName((Precision)precision);
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_countDataType); dataTypeNdx++)
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DataType loopDataType = s_countDataType[dataTypeNdx];
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char* dataTypeName = getDataTypeName(loopDataType);
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ShaderType	shaderType		= s_shaderTypes[shaderTypeNdx];
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const char*	shaderTypeName	= getShaderTypeName(shaderType);
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						bool		isVertexCase	= (shaderType == SHADERTYPE_VERTEX);
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						string name = string("basic_") + precisionName + "_" + dataTypeName + "_" + shaderTypeName;
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						string desc = string(loopTypeName) + " loop with " + precisionName + dataTypeName + " " + loopCountName + " iteration count in " + shaderTypeName + " shader.";
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						group->addChild(createGenericLoopCase(m_context, name.c_str(), desc.c_str(), isVertexCase, (LoopType)loopType, (LoopCountType)loopCountType, (Precision)precision, loopDataType));
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Special cases.
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int loopCase = 0; loopCase < LOOPCASE_LAST; loopCase++)
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char* loopCaseName = getLoopCaseName((LoopCase)loopCase);
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// no-iterations not possible with do-while.
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if ((loopCase == LOOPCASE_NO_ITERATIONS) && (loopType == LOOPTYPE_DO_WHILE))
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					ShaderType	shaderType		= s_shaderTypes[shaderTypeNdx];
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char*	shaderTypeName	= getShaderTypeName(shaderType);
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					bool		isVertexCase	= (shaderType == SHADERTYPE_VERTEX);
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					string name = string(loopCaseName) + "_" + shaderTypeName;
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					string desc = string(loopCaseName) + " loop with " + loopTypeName + " iteration count in " + shaderTypeName + " shader.";
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					group->addChild(createSpecialLoopCase(m_context, name.c_str(), desc.c_str(), isVertexCase, (LoopCase)loopCase, (LoopType)loopType, (LoopCountType)loopCountType));
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles2
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1344