13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.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 Texture wrap mode test case
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 "es3fShaderLoopTests.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 gles3
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
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//LOOPCASE_MULTI_DECLARATION,							// for (int i,j,k; ...) ...  -- illegal?
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCASE_LAST
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getLoopCaseName (LoopCase loopCase)
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* s_names[] =
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"empty_body",
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"infinite_with_unconditional_break_first",
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"infinite_with_unconditional_break_last",
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"infinite_with_conditional_break",
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"single_statement",
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"compound_statement",
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"sequence_statement",
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"no_iterations",
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"single_iteration",
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"select_iteration_count",
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"conditional_continue",
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"unconditional_continue",
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"only_continue",
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"double_continue",
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"conditional_break",
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"unconditional_break",
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"pre_increment",
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"post_increment",
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"mixed_break_continue",
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"vector_counter",
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"101_iterations",
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"sequence",
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"nested",
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"nested_sequence",
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"nested_tricky_dataflow_1",
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"nested_tricky_dataflow_2"
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//"multi_declaration",
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == LOOPCASE_LAST);
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(deInBounds32((int)loopCase, 0, LOOPCASE_LAST));
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return s_names[(int)loopCase];
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Complex loop cases.
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*enum LoopBody
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPBODY_READ_UNIFORM = 0,
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPBODY_READ_UNIFORM_ARRAY,
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPBODY_READ_
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};*/
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum LoopType
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPTYPE_FOR = 0,
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPTYPE_WHILE,
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPTYPE_DO_WHILE,
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPTYPE_LAST
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getLoopTypeName (LoopType loopType)
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* s_names[] =
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"for",
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"while",
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"do_while"
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == LOOPTYPE_LAST);
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(deInBounds32((int)loopType, 0, LOOPTYPE_LAST));
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return s_names[(int)loopType];
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum LoopCountType
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCOUNT_CONSTANT = 0,
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCOUNT_UNIFORM,
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCOUNT_DYNAMIC,
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOPCOUNT_LAST
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getLoopCountTypeName (LoopCountType countType)
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* s_names[] =
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"constant",
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform",
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"dynamic"
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == LOOPCOUNT_LAST);
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(deInBounds32((int)countType, 0, LOOPCOUNT_LAST));
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return s_names[(int)countType];
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void evalLoop0Iters	(ShaderEvalContext& c) { c.color.xyz()	= c.coords.swizzle(0,1,2); }
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void evalLoop1Iters	(ShaderEvalContext& c) { c.color.xyz()	= c.coords.swizzle(1,2,3); }
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void evalLoop2Iters	(ShaderEvalContext& c) { c.color.xyz()	= c.coords.swizzle(2,3,0); }
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void evalLoop3Iters	(ShaderEvalContext& c) { c.color.xyz()	= c.coords.swizzle(3,0,1); }
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic ShaderEvalFunc getLoopEvalFunc (int numIters)
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (numIters % 4)
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 0: return evalLoop0Iters;
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 1:	return evalLoop1Iters;
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 2:	return evalLoop2Iters;
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 3:	return evalLoop3Iters;
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!"Invalid loop iteration count.");
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return NULL;
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// ShaderLoopCase
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderLoopCase : public ShaderRenderCase
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								ShaderLoopCase			(Context& context, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, const char* vertShaderSource, const char* fragShaderSource);
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual						~ShaderLoopCase			(void);
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								ShaderLoopCase			(const ShaderLoopCase&);	// not allowed!
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderLoopCase&				operator=				(const ShaderLoopCase&);	// not allowed!
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				setup					(int programID);
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				setupUniforms			(int programID, const Vec4& constCoords);
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2193c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderLoopCase::ShaderLoopCase (Context& context, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, const char* vertShaderSource, const char* fragShaderSource)
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, description, isVertexCase, evalFunc)
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_vertShaderSource	= vertShaderSource;
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fragShaderSource	= fragShaderSource;
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2263c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderLoopCase::~ShaderLoopCase (void)
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderLoopCase::setup (int programID)
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(programID);
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderLoopCase::setupUniforms (int programID, const Vec4& constCoords)
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(programID);
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(constCoords);
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Test case creation.
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic ShaderLoopCase* createGenericLoopCase (Context& context, const char* caseName, const char* description, bool isVertexCase, LoopType loopType, LoopCountType loopCountType, Precision loopCountPrecision, DataType loopCountDataType)
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream vtx;
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream frag;
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream& op = isVertexCase ? vtx : frag;
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "#version 300 es\n";
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "#version 300 es\n";
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "in highp vec4 a_position;\n";
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "in highp vec4 a_coords;\n";
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "layout(location = 0) out mediump vec4 o_color;\n";
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopCountType == LOOPCOUNT_DYNAMIC)
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "in mediump float a_one;\n";
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "out mediump vec3 v_color;\n";
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "in mediump vec3 v_color;\n";
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "out mediump vec4 v_coords;\n";
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "in mediump vec4 v_coords;\n";
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_DYNAMIC)
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vtx << "out mediump float v_one;\n";
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			frag << "in mediump float v_one;\n";
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [petri] Pass numLoopIters from outside?
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		numLoopIters = 3;
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	isIntCounter = isDataTypeIntOrIVec(loopCountDataType);
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isIntCounter)
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_UNIFORM || loopCountType == LOOPCOUNT_DYNAMIC)
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "uniform ${COUNTER_PRECISION} int " << getIntUniformName(numLoopIters) << ";\n";
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_UNIFORM || loopCountType == LOOPCOUNT_DYNAMIC)
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "uniform ${COUNTER_PRECISION} float " << getFloatFractionUniformName(numLoopIters) << ";\n";
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numLoopIters != 1)
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "uniform ${COUNTER_PRECISION} float uf_one;\n";
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "\n";
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "void main()\n";
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "{\n";
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "	gl_Position = a_position;\n";
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "\n";
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "void main()\n";
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "{\n";
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	${PRECISION} vec4 coords = a_coords;\n";
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	${PRECISION} vec4 coords = v_coords;\n";
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopCountType == LOOPCOUNT_DYNAMIC)
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isIntCounter)
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isVertexCase)
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vtx << "	${COUNTER_PRECISION} int one = int(a_one + 0.5);\n";
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				frag << "	${COUNTER_PRECISION} int one = int(v_one + 0.5);\n";
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isVertexCase)
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vtx << "	${COUNTER_PRECISION} float one = a_one;\n";
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				frag << "	${COUNTER_PRECISION} float one = v_one;\n";
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read array.
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	op << "	${PRECISION} vec4 res = coords;\n";
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Loop iteration count.
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string	iterMaxStr;
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isIntCounter)
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_CONSTANT)
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			iterMaxStr = de::toString(numLoopIters);
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_UNIFORM)
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			iterMaxStr = getIntUniformName(numLoopIters);
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_DYNAMIC)
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			iterMaxStr = string(getIntUniformName(numLoopIters)) + "*one";
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_CONSTANT)
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			iterMaxStr = "1.0";
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_UNIFORM)
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			iterMaxStr = "uf_one";
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_DYNAMIC)
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			iterMaxStr = "uf_one*one";
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Loop operations.
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string initValue		= isIntCounter ? "0" : "0.05";
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string loopCountDeclStr	= "${COUNTER_PRECISION} ${LOOP_VAR_TYPE} ndx = " + initValue;
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string loopCmpStr		= ("ndx < " + iterMaxStr);
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string incrementStr;
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isIntCounter)
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		incrementStr = "ndx++";
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_CONSTANT)
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			incrementStr = string("ndx += ") + de::toString(1.0f / numLoopIters);
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_UNIFORM)
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			incrementStr = string("ndx += ") + getFloatFractionUniformName(numLoopIters);
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_DYNAMIC)
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			incrementStr = string("ndx += ") + getFloatFractionUniformName(numLoopIters) + "*one";
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Loop body.
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string loopBody;
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	loopBody = "		res = res.yzwx;\n";
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopType == LOOPTYPE_FOR)
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	for (" + loopCountDeclStr + "; " + loopCmpStr + "; " + incrementStr + ")\n";
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	{\n";
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << loopBody;
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	}\n";
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (loopType == LOOPTYPE_WHILE)
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "\t" << loopCountDeclStr + ";\n";
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	while (" + loopCmpStr + ")\n";
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	{\n";
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << loopBody;
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "\t\t" + incrementStr + ";\n";
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	}\n";
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (loopType == LOOPTYPE_DO_WHILE)
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "\t" << loopCountDeclStr + ";\n";
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	do\n";
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	{\n";
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << loopBody;
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "\t\t" + incrementStr + ";\n";
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	} while (" + loopCmpStr + ");\n";
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	v_color = res.rgb;\n";
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	o_color = vec4(v_color.rgb, 1.0);\n";
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	v_coords = a_coords;\n";
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	o_color = vec4(res.rgb, 1.0);\n";
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_DYNAMIC)
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vtx << "	v_one = a_one;\n";
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "}\n";
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "}\n";
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fill in shader templates.
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	map<string, string> params;
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("LOOP_VAR_TYPE", getDataTypeName(loopCountDataType)));
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("PRECISION", "mediump"));
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("COUNTER_PRECISION", getPrecisionName(loopCountPrecision)));
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate vertTemplate(vtx.str().c_str());
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate fragTemplate(frag.str().c_str());
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string vertexShaderSource = vertTemplate.specialize(params);
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string fragmentShaderSource = fragTemplate.specialize(params);
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create the case.
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderEvalFunc evalFunc = getLoopEvalFunc(numLoopIters);
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new ShaderLoopCase(context, caseName, description, isVertexCase, evalFunc, vertexShaderSource.c_str(), fragmentShaderSource.c_str());
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [petri] Generalize to float as well?
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic ShaderLoopCase* createSpecialLoopCase (Context& context, const char* caseName, const char* description, bool isVertexCase, LoopCase loopCase, LoopType loopType, LoopCountType loopCountType)
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream vtx;
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream frag;
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream& op = isVertexCase ? vtx : frag;
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "#version 300 es\n";
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "#version 300 es\n";
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "in highp vec4 a_position;\n";
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "in highp vec4 a_coords;\n";
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "layout(location = 0) out mediump vec4 o_color;\n";
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopCountType == LOOPCOUNT_DYNAMIC)
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "in mediump float a_one;\n";
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Attribute and varyings.
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "out mediump vec3 v_color;\n";
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "in mediump vec3 v_color;\n";
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "out mediump vec4 v_coords;\n";
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "in mediump vec4 v_coords;\n";
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_DYNAMIC)
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vtx << "out mediump float v_one;\n";
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			frag << "in mediump float v_one;\n";
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopCase == LOOPCASE_SELECT_ITERATION_COUNT)
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "uniform bool ub_true;\n";
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	op << "uniform ${COUNTER_PRECISION} int ui_zero, ui_one, ui_two, ui_three, ui_four, ui_five, ui_six;\n";
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopCase == LOOPCASE_101_ITERATIONS)
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "uniform ${COUNTER_PRECISION} int ui_oneHundredOne;\n";
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int iterCount	= 3;	// value to use in loop
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numIters	= 3;	// actual number of iterations
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "\n";
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "void main()\n";
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "{\n";
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "	gl_Position = a_position;\n";
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "\n";
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "void main()\n";
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "{\n";
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopCountType == LOOPCOUNT_DYNAMIC)
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isVertexCase)
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vtx << "	${COUNTER_PRECISION} int one = int(a_one + 0.5);\n";
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			frag << "	${COUNTER_PRECISION} int one = int(v_one + 0.5);\n";
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	${PRECISION} vec4 coords = a_coords;\n";
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	${PRECISION} vec4 coords = v_coords;\n";
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read array.
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	op << "	${PRECISION} vec4 res = coords;\n";
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Handle all loop types.
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string counterPrecisionStr = "mediump";
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string forLoopStr;
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string whileLoopStr;
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string doWhileLoopPreStr;
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string doWhileLoopPostStr;
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopType == LOOPTYPE_FOR)
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (loopCase)
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_EMPTY_BODY:
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} {}\n";
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST:
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (;;) { break; res = res.yzwx; }\n";
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST:
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 1;
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (;;) { res = res.yzwx; break; }\n";
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK:
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (;;) { res = res.yzwx; if (i == ${ONE}) break; i++; }\n";
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SINGLE_STATEMENT:
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} res = res.yzwx;\n";
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_COMPOUND_STATEMENT:
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 2;
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2 * iterCount;
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { res = res.yzwx; res = res.yzwx; }\n";
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SEQUENCE_STATEMENT:
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 2;
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2 * iterCount;
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} res = res.yzwx, res = res.yzwx;\n";
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NO_ITERATIONS:
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 0;
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 0;
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} res = res.yzwx;\n";
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SINGLE_ITERATION:
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 1;
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 1;
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} res = res.yzwx;\n";
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SELECT_ITERATION_COUNT:
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (int i = 0; i < (ub_true ? ${ITER_COUNT} : 0); i++) res = res.yzwx;\n";
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_CONDITIONAL_CONTINUE:
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount - 1;
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { if (i == ${TWO}) continue; res = res.yzwx; }\n";
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_UNCONDITIONAL_CONTINUE:
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { res = res.yzwx; continue; }\n";
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_ONLY_CONTINUE:
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { continue; }\n";
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_DOUBLE_CONTINUE:
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount - 1;
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { if (i == ${TWO}) continue; res = res.yzwx; continue; }\n";
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_CONDITIONAL_BREAK:
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { if (i == ${TWO}) break; res = res.yzwx; }\n";
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_UNCONDITIONAL_BREAK:
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 1;
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { res = res.yzwx; break; }\n";
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_PRE_INCREMENT:
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (int i = 0; i < ${ITER_COUNT}; ++i) { res = res.yzwx; }\n";
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_POST_INCREMENT:
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { res = res.yzwx; }\n";
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_MIXED_BREAK_CONTINUE:
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2;
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 5;
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} { if (i == 0) continue; else if (i == 3) break; res = res.yzwx; }\n";
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_VECTOR_COUNTER:
6183c827367444ee418f129b2c238299f49d3264554Jarkko 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";
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_101_ITERATIONS:
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount = 101;
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP} res = res.yzwx;\n";
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SEQUENCE:
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 5;
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 5;
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i;\n";
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (i = 0; i < ${TWO}; i++) { res = res.yzwx; }\n";
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (; i < ${ITER_COUNT}; i++) { res = res.yzwx; }\n";
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED:
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2 * iterCount;
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (${COUNTER_PRECISION} int i = 0; i < ${TWO}; i++)\n";
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		for (${COUNTER_PRECISION} int j = 0; j < ${ITER_COUNT}; j++)\n";
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_SEQUENCE:
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 3 * iterCount;
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	for (${COUNTER_PRECISION} int i = 0; i < ${ITER_COUNT}; i++)\n";
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		for (${COUNTER_PRECISION} int j = 0; j < ${TWO}; j++)\n";
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		for (${COUNTER_PRECISION} int j = 0; j < ${ONE}; j++)\n";
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_TRICKY_DATAFLOW_1:
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP}\n";
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		res = coords; // ignore outer loop effect \n";
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		for (${COUNTER_PRECISION} int j = 0; j < ${TWO}; j++)\n";
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_TRICKY_DATAFLOW_2:
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount;
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${FOR_LOOP}\n";
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		res = coords.wxyz;\n";
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		for (${COUNTER_PRECISION} int j = 0; j < ${TWO}; j++)\n";
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		coords = res;\n";
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_CONSTANT)
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			forLoopStr = string("for (") + counterPrecisionStr + " int i = 0; i < " + de::toString(iterCount) + "; i++)";
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_UNIFORM)
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			forLoopStr = string("for (") + counterPrecisionStr + " int i = 0; i < " + getIntUniformName(iterCount) + "; i++)";
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_DYNAMIC)
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			forLoopStr = string("for (") + counterPrecisionStr + " int i = 0; i < one*" + getIntUniformName(iterCount) + "; i++)";
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (loopType == LOOPTYPE_WHILE)
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (loopCase)
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_EMPTY_BODY:
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} {}\n";
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST:
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (true) { break; res = res.yzwx; }\n";
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST:
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 1;
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (true) { res = res.yzwx; break; }\n";
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK:
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (true) { res = res.yzwx; if (i == ${ONE}) break; i++; }\n";
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SINGLE_STATEMENT:
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} res = res.yzwx;\n";
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_COMPOUND_STATEMENT:
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 2;
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2 * iterCount;
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} { res = res.yzwx; res = res.yzwx; }\n";
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SEQUENCE_STATEMENT:
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 2;
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2 * iterCount;
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} res = res.yzwx, res = res.yzwx;\n";
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NO_ITERATIONS:
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 0;
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 0;
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} res = res.yzwx;\n";
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SINGLE_ITERATION:
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 1;
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 1;
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} res = res.yzwx;\n";
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SELECT_ITERATION_COUNT:
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (i < (ub_true ? ${ITER_COUNT} : 0)) { res = res.yzwx; i++; }\n";
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_CONDITIONAL_CONTINUE:
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount - 1;
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} { if (i == ${TWO}) continue; res = res.yzwx; }\n";
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_UNCONDITIONAL_CONTINUE:
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} { res = res.yzwx; continue; }\n";
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_ONLY_CONTINUE:
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} { continue; }\n";
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_DOUBLE_CONTINUE:
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount - 1;
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} { if (i == ${ONE}) continue; res = res.yzwx; continue; }\n";
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_CONDITIONAL_BREAK:
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} { if (i == ${THREE}) break; res = res.yzwx; }\n";
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_UNCONDITIONAL_BREAK:
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 1;
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} { res = res.yzwx; break; }\n";
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_PRE_INCREMENT:
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount - 1;
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (++i < ${ITER_COUNT}) { res = res.yzwx; }\n";
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_POST_INCREMENT:
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (i++ < ${ITER_COUNT}) { res = res.yzwx; }\n";
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_MIXED_BREAK_CONTINUE:
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2;
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 5;
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} { if (i == 0) continue; else if (i == 3) break; res = res.yzwx; }\n";
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_VECTOR_COUNTER:
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} ivec4 i = ivec4(0, 1, ${ITER_COUNT}, 0);\n";
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (i.x < i.z) { res = res.yzwx; i.x += i.y; }\n";
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_101_ITERATIONS:
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount = 101;
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP} res = res.yzwx;\n";
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SEQUENCE:
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 6;
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= iterCount - 1;
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (i++ < ${TWO}) { res = res.yzwx; }\n";
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (i++ < ${ITER_COUNT}) { res = res.yzwx; }\n"; // \note skips one iteration
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED:
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2 * iterCount;
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (i++ < ${TWO})\n";
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		${COUNTER_PRECISION} int j = 0;\n";
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (j++ < ${ITER_COUNT})\n";
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_SEQUENCE:
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2 * iterCount;
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	while (i++ < ${ITER_COUNT})\n";
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		${COUNTER_PRECISION} int j = 0;\n";
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (j++ < ${ONE})\n";
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (j++ < ${THREE})\n"; // \note skips one iteration
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_TRICKY_DATAFLOW_1:
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP}\n";
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		res = coords; // ignore outer loop effect \n";
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		${COUNTER_PRECISION} int j = 0;\n";
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (j++ < ${TWO})\n";
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_TRICKY_DATAFLOW_2:
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount;
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${WHILE_LOOP}\n";
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		res = coords.wxyz;\n";
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		${COUNTER_PRECISION} int j = 0;\n";
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (j++ < ${TWO})\n";
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		coords = res;\n";
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	}\n";
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_CONSTANT)
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			whileLoopStr = string("\t") + counterPrecisionStr + " int i = 0;\n" + "	while(i++ < " + de::toString(iterCount) + ")";
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_UNIFORM)
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			whileLoopStr = string("\t") + counterPrecisionStr + " int i = 0;\n" + "	while(i++ < " + getIntUniformName(iterCount) + ")";
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_DYNAMIC)
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			whileLoopStr = string("\t") + counterPrecisionStr + " int i = 0;\n" + "	while(i++ < one*" + getIntUniformName(iterCount) + ")";
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(loopType == LOOPTYPE_DO_WHILE);
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (loopCase)
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_EMPTY_BODY:
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} {} ${DO_WHILE_POST}\n";
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST:
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { break; res = res.yzwx; } while (true);\n";
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST:
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 1;
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { res = res.yzwx; break; } while (true);\n";
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK:
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { res = res.yzwx; if (i == ${ONE}) break; i++; } while (true);\n";
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SINGLE_STATEMENT:
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} res = res.yzwx; ${DO_WHILE_POST}\n";
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_COMPOUND_STATEMENT:
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 2;
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2 * iterCount;
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} { res = res.yzwx; res = res.yzwx; } ${DO_WHILE_POST}\n";
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SEQUENCE_STATEMENT:
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 2;
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2 * iterCount;
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} res = res.yzwx, res = res.yzwx; ${DO_WHILE_POST}\n";
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NO_ITERATIONS:
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SINGLE_ITERATION:
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 1;
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 1;
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} res = res.yzwx; ${DO_WHILE_POST}\n";
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SELECT_ITERATION_COUNT:
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { res = res.yzwx; } while (++i < (ub_true ? ${ITER_COUNT} : 0));\n";
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_CONDITIONAL_CONTINUE:
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount - 1;
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} { if (i == ${TWO}) continue; res = res.yzwx; } ${DO_WHILE_POST}\n";
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_UNCONDITIONAL_CONTINUE:
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} { res = res.yzwx; continue; } ${DO_WHILE_POST}\n";
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_ONLY_CONTINUE:
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 0;
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} { continue; } ${DO_WHILE_POST}\n";
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_DOUBLE_CONTINUE:
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount - 1;
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} { if (i == ${TWO}) continue; res = res.yzwx; continue; } ${DO_WHILE_POST}\n";
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_CONDITIONAL_BREAK:
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} { res = res.yzwx; if (i == ${ONE}) break; } ${DO_WHILE_POST}\n";
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_UNCONDITIONAL_BREAK:
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 1;
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} { res = res.yzwx; break; } ${DO_WHILE_POST}\n";
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_PRE_INCREMENT:
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { res = res.yzwx; } while (++i < ${ITER_COUNT});\n";
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_POST_INCREMENT:
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount + 1;
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { res = res.yzwx; } while (i++ < ${ITER_COUNT});\n";
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_MIXED_BREAK_CONTINUE:
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 2;
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 5;
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} { if (i == 0) continue; else if (i == 3) break; res = res.yzwx; } ${DO_WHILE_POST}\n";
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_VECTOR_COUNTER:
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} ivec4 i = ivec4(0, 1, ${ITER_COUNT}, 0);\n";
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { res = res.yzwx; } while ((i.x += i.y) < i.z);\n";
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_101_ITERATIONS:
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount = 101;
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE} res = res.yzwx; ${DO_WHILE_POST}\n";
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_SEQUENCE:
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				iterCount	= 5;
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters	= 5;
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { res = res.yzwx; } while (++i < ${TWO});\n";
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do { res = res.yzwx; } while (++i < ${ITER_COUNT});\n";
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED:
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2 * iterCount;
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do\n";
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		${COUNTER_PRECISION} int j = 0;\n";
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		do\n";
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (++j < ${ITER_COUNT});\n";
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	} while (++i < ${TWO});\n";
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_SEQUENCE:
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 3 * iterCount;
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${COUNTER_PRECISION} int i = 0;\n";
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	do\n";
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		${COUNTER_PRECISION} int j = 0;\n";
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		do\n";
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (++j < ${TWO});\n";
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		do\n";
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (++j < ${THREE});\n";
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	} while (++i < ${ITER_COUNT});\n";
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_TRICKY_DATAFLOW_1:
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = 2;
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE}\n";
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		res = coords; // ignore outer loop effect \n";
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		${COUNTER_PRECISION} int j = 0;\n";
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		do\n";
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (++j < ${TWO});\n";
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	} ${DO_WHILE_POST}\n";
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case LOOPCASE_NESTED_TRICKY_DATAFLOW_2:
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numIters = iterCount;
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	${DO_WHILE_PRE}\n";
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	{\n";
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		res = coords.wxyz;\n";
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		${COUNTER_PRECISION} int j = 0;\n";
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		while (j++ < ${TWO})\n";
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "			res = res.yzwx;\n";
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "		coords = res;\n";
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				op << "	} ${DO_WHILE_POST}\n";
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		doWhileLoopPreStr = string("\t") + counterPrecisionStr + " int i = 0;\n" + "\tdo ";
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_CONSTANT)
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			doWhileLoopPostStr = string(" while (++i < ") + de::toString(iterCount) + ");\n";
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_UNIFORM)
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			doWhileLoopPostStr = string(" while (++i < ") + getIntUniformName(iterCount) + ");\n";
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (loopCountType == LOOPCOUNT_DYNAMIC)
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			doWhileLoopPostStr = string(" while (++i < one*") + getIntUniformName(iterCount) + ");\n";
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Shader footers.
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	v_color = res.rgb;\n";
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	o_color = vec4(v_color.rgb, 1.0);\n";
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	v_coords = a_coords;\n";
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	o_color = vec4(res.rgb, 1.0);\n";
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loopCountType == LOOPCOUNT_DYNAMIC)
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vtx << "	v_one = a_one;\n";
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "}\n";
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "}\n";
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Constants.
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string oneStr;
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string twoStr;
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string threeStr;
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string iterCountStr;
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (loopCountType == LOOPCOUNT_CONSTANT)
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		oneStr			= "1";
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		twoStr			= "2";
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		threeStr		= "3";
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		iterCountStr	= de::toString(iterCount);
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (loopCountType == LOOPCOUNT_UNIFORM)
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		oneStr			= "ui_one";
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		twoStr			= "ui_two";
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		threeStr		= "ui_three";
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		iterCountStr	= getIntUniformName(iterCount);
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (loopCountType == LOOPCOUNT_DYNAMIC)
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		oneStr			= "one*ui_one";
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		twoStr			= "one*ui_two";
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		threeStr		= "one*ui_three";
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		iterCountStr	= string("one*") + getIntUniformName(iterCount);
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else DE_ASSERT(false);
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fill in shader templates.
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	map<string, string> params;
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("PRECISION", "mediump"));
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("ITER_COUNT", iterCountStr));
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("COUNTER_PRECISION", counterPrecisionStr));
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("FOR_LOOP", forLoopStr));
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("WHILE_LOOP", whileLoopStr));
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("DO_WHILE_PRE", doWhileLoopPreStr));
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("DO_WHILE_POST", doWhileLoopPostStr));
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("ONE", oneStr));
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("TWO", twoStr));
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("THREE", threeStr));
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate vertTemplate(vtx.str().c_str());
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate fragTemplate(frag.str().c_str());
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string vertexShaderSource = vertTemplate.specialize(params);
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string fragmentShaderSource = fragTemplate.specialize(params);
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create the case.
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderEvalFunc evalFunc = getLoopEvalFunc(numIters);
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new ShaderLoopCase(context, caseName, description, isVertexCase, evalFunc, vertexShaderSource.c_str(), fragmentShaderSource.c_str());
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// ShaderLoopTests.
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11303c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderLoopTests::ShaderLoopTests(Context& context)
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "loops", "Loop Tests")
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderLoopTests::~ShaderLoopTests (void)
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderLoopTests::init (void)
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Loop cases.
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const ShaderType s_shaderTypes[] =
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		SHADERTYPE_VERTEX,
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		SHADERTYPE_FRAGMENT
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const DataType s_countDataType[] =
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_INT,
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int loopType = 0; loopType < LOOPTYPE_LAST; loopType++)
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* loopTypeName = getLoopTypeName((LoopType)loopType);
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int loopCountType = 0; loopCountType < LOOPCOUNT_LAST; loopCountType++)
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char* loopCountName = getLoopCountTypeName((LoopCountType)loopCountType);
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string groupName = string(loopTypeName) + "_" + string(loopCountName) + "_iterations";
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string groupDesc = string("Loop tests with ") + loopCountName + " loop counter.";
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* group = new TestCaseGroup(m_context, groupName.c_str(), groupDesc.c_str());
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			addChild(group);
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Generic cases.
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int precision = 0; precision < PRECISION_LAST; precision++)
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char* precisionName = getPrecisionName((Precision)precision);
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_countDataType); dataTypeNdx++)
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DataType loopDataType = s_countDataType[dataTypeNdx];
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char* dataTypeName = getDataTypeName(loopDataType);
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ShaderType	shaderType		= s_shaderTypes[shaderTypeNdx];
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const char*	shaderTypeName	= getShaderTypeName(shaderType);
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						bool		isVertexCase	= (shaderType == SHADERTYPE_VERTEX);
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						string name = string("basic_") + precisionName + "_" + dataTypeName + "_" + shaderTypeName;
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						string desc = string(loopTypeName) + " loop with " + precisionName + dataTypeName + " " + loopCountName + " iteration count in " + shaderTypeName + " shader.";
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						group->addChild(createGenericLoopCase(m_context, name.c_str(), desc.c_str(), isVertexCase, (LoopType)loopType, (LoopCountType)loopCountType, (Precision)precision, loopDataType));
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Special cases.
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int loopCase = 0; loopCase < LOOPCASE_LAST; loopCase++)
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char* loopCaseName = getLoopCaseName((LoopCase)loopCase);
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// no-iterations not possible with do-while.
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if ((loopCase == LOOPCASE_NO_ITERATIONS) && (loopType == LOOPTYPE_DO_WHILE))
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					ShaderType	shaderType		= s_shaderTypes[shaderTypeNdx];
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char*	shaderTypeName	= getShaderTypeName(shaderType);
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					bool		isVertexCase	= (shaderType == SHADERTYPE_VERTEX);
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					string name = string(loopCaseName) + "_" + shaderTypeName;
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					string desc = string(loopCaseName) + " loop with " + loopTypeName + " iteration count in " + shaderTypeName + " shader.";
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					group->addChild(createSpecialLoopCase(m_context, name.c_str(), desc.c_str(), isVertexCase, (LoopCase)loopCase, (LoopType)loopType, (LoopCountType)loopCountType));
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles3
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1220