1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program OpenGL ES 2.0 Module
3*35238bceSAndroid Build Coastguard Worker * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker *
5*35238bceSAndroid Build Coastguard Worker * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker *
7*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker *
11*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker *
13*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker *
19*35238bceSAndroid Build Coastguard Worker *//*!
20*35238bceSAndroid Build Coastguard Worker * \file
21*35238bceSAndroid Build Coastguard Worker * \brief Shader loop tests.
22*35238bceSAndroid Build Coastguard Worker *
23*35238bceSAndroid Build Coastguard Worker * \todo [petri]
24*35238bceSAndroid Build Coastguard Worker * - loop body cases (do different operations inside the loops)
25*35238bceSAndroid Build Coastguard Worker * - more complex nested loops
26*35238bceSAndroid Build Coastguard Worker * * random generated?
27*35238bceSAndroid Build Coastguard Worker * * dataflow variations
28*35238bceSAndroid Build Coastguard Worker * * mixed loop types
29*35238bceSAndroid Build Coastguard Worker * -
30*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
31*35238bceSAndroid Build Coastguard Worker
32*35238bceSAndroid Build Coastguard Worker #include "es2fShaderLoopTests.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "glsShaderLibrary.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "glsShaderRenderCase.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "gluShaderUtil.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
37*35238bceSAndroid Build Coastguard Worker
38*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "deInt32.h"
40*35238bceSAndroid Build Coastguard Worker #include "deMemory.h"
41*35238bceSAndroid Build Coastguard Worker
42*35238bceSAndroid Build Coastguard Worker #include <map>
43*35238bceSAndroid Build Coastguard Worker
44*35238bceSAndroid Build Coastguard Worker using namespace std;
45*35238bceSAndroid Build Coastguard Worker using namespace tcu;
46*35238bceSAndroid Build Coastguard Worker using namespace glu;
47*35238bceSAndroid Build Coastguard Worker using namespace deqp::gls;
48*35238bceSAndroid Build Coastguard Worker
49*35238bceSAndroid Build Coastguard Worker namespace deqp
50*35238bceSAndroid Build Coastguard Worker {
51*35238bceSAndroid Build Coastguard Worker namespace gles2
52*35238bceSAndroid Build Coastguard Worker {
53*35238bceSAndroid Build Coastguard Worker namespace Functional
54*35238bceSAndroid Build Coastguard Worker {
55*35238bceSAndroid Build Coastguard Worker
56*35238bceSAndroid Build Coastguard Worker // Repeated with for, while, do-while. Examples given as 'for' loops.
57*35238bceSAndroid Build Coastguard Worker // Repeated for const, uniform, dynamic loops.
58*35238bceSAndroid Build Coastguard Worker enum LoopCase
59*35238bceSAndroid Build Coastguard Worker {
60*35238bceSAndroid Build Coastguard Worker LOOPCASE_EMPTY_BODY = 0, // for (...) { }
61*35238bceSAndroid Build Coastguard Worker LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST, // for (...) { break; <body>; }
62*35238bceSAndroid Build Coastguard Worker LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST, // for (...) { <body>; break; }
63*35238bceSAndroid Build Coastguard Worker LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK, // for (...) { <body>; if (cond) break; }
64*35238bceSAndroid Build Coastguard Worker LOOPCASE_SINGLE_STATEMENT, // for (...) statement;
65*35238bceSAndroid Build Coastguard Worker LOOPCASE_COMPOUND_STATEMENT, // for (...) { statement; statement; }
66*35238bceSAndroid Build Coastguard Worker LOOPCASE_SEQUENCE_STATEMENT, // for (...) statement, statement;
67*35238bceSAndroid Build Coastguard Worker LOOPCASE_NO_ITERATIONS, // for (i=0; i<0; i++) ...
68*35238bceSAndroid Build Coastguard Worker LOOPCASE_SINGLE_ITERATION, // for (i=0; i<1; i++) ...
69*35238bceSAndroid Build Coastguard Worker LOOPCASE_SELECT_ITERATION_COUNT, // for (i=0; i<a?b:c; i++) ...
70*35238bceSAndroid Build Coastguard Worker LOOPCASE_CONDITIONAL_CONTINUE, // for (...) { if (cond) continue; }
71*35238bceSAndroid Build Coastguard Worker LOOPCASE_UNCONDITIONAL_CONTINUE, // for (...) { <body>; continue; }
72*35238bceSAndroid Build Coastguard Worker LOOPCASE_ONLY_CONTINUE, // for (...) { continue; }
73*35238bceSAndroid Build Coastguard Worker LOOPCASE_DOUBLE_CONTINUE, // for (...) { if (cond) continue; <body>; continue; }
74*35238bceSAndroid Build Coastguard Worker LOOPCASE_CONDITIONAL_BREAK, // for (...) { if (cond) break; }
75*35238bceSAndroid Build Coastguard Worker LOOPCASE_UNCONDITIONAL_BREAK, // for (...) { <body>; break; }
76*35238bceSAndroid Build Coastguard Worker LOOPCASE_PRE_INCREMENT, // for (...; ++i) { <body>; }
77*35238bceSAndroid Build Coastguard Worker LOOPCASE_POST_INCREMENT, // for (...; i++) { <body>; }
78*35238bceSAndroid Build Coastguard Worker LOOPCASE_MIXED_BREAK_CONTINUE,
79*35238bceSAndroid Build Coastguard Worker LOOPCASE_VECTOR_COUNTER, // for (ivec3 ndx = ...; ndx.x < ndx.y; ndx.x += ndx.z) { ... }
80*35238bceSAndroid Build Coastguard Worker LOOPCASE_101_ITERATIONS, // loop for 101 iterations
81*35238bceSAndroid Build Coastguard Worker LOOPCASE_SEQUENCE, // two loops in sequence
82*35238bceSAndroid Build Coastguard Worker LOOPCASE_NESTED, // two nested loops
83*35238bceSAndroid Build Coastguard Worker LOOPCASE_NESTED_SEQUENCE, // two loops in sequence nested inside a third
84*35238bceSAndroid Build Coastguard Worker LOOPCASE_NESTED_TRICKY_DATAFLOW_1, // nested loops with tricky data flow
85*35238bceSAndroid Build Coastguard Worker LOOPCASE_NESTED_TRICKY_DATAFLOW_2, // nested loops with tricky data flow
86*35238bceSAndroid Build Coastguard Worker LOOPCASE_CONDITIONAL_BODY, // conditional body in loop
87*35238bceSAndroid Build Coastguard Worker LOOPCASE_FUNCTION_CALL_RETURN, // function call in loop with return value usage
88*35238bceSAndroid Build Coastguard Worker LOOPCASE_FUNCTION_CALL_INOUT, // function call with inout parameter usage
89*35238bceSAndroid Build Coastguard Worker
90*35238bceSAndroid Build Coastguard Worker LOOPCASE_LAST
91*35238bceSAndroid Build Coastguard Worker };
92*35238bceSAndroid Build Coastguard Worker
93*35238bceSAndroid Build Coastguard Worker enum LoopRequirement
94*35238bceSAndroid Build Coastguard Worker {
95*35238bceSAndroid Build Coastguard Worker LOOPREQUIREMENT_STANDARD = 0, //!< Minimum requirements by standard (constant for loop with simple iterator).
96*35238bceSAndroid Build Coastguard Worker LOOPREQUIREMENT_UNIFORM,
97*35238bceSAndroid Build Coastguard Worker LOOPREQUIREMENT_DYNAMIC,
98*35238bceSAndroid Build Coastguard Worker
99*35238bceSAndroid Build Coastguard Worker LOOPREQUIREMENT_LAST
100*35238bceSAndroid Build Coastguard Worker };
101*35238bceSAndroid Build Coastguard Worker
getLoopCaseName(LoopCase loopCase)102*35238bceSAndroid Build Coastguard Worker static const char *getLoopCaseName(LoopCase loopCase)
103*35238bceSAndroid Build Coastguard Worker {
104*35238bceSAndroid Build Coastguard Worker static const char *s_names[] = {"empty_body",
105*35238bceSAndroid Build Coastguard Worker "infinite_with_unconditional_break_first",
106*35238bceSAndroid Build Coastguard Worker "infinite_with_unconditional_break_last",
107*35238bceSAndroid Build Coastguard Worker "infinite_with_conditional_break",
108*35238bceSAndroid Build Coastguard Worker "single_statement",
109*35238bceSAndroid Build Coastguard Worker "compound_statement",
110*35238bceSAndroid Build Coastguard Worker "sequence_statement",
111*35238bceSAndroid Build Coastguard Worker "no_iterations",
112*35238bceSAndroid Build Coastguard Worker "single_iteration",
113*35238bceSAndroid Build Coastguard Worker "select_iteration_count",
114*35238bceSAndroid Build Coastguard Worker "conditional_continue",
115*35238bceSAndroid Build Coastguard Worker "unconditional_continue",
116*35238bceSAndroid Build Coastguard Worker "only_continue",
117*35238bceSAndroid Build Coastguard Worker "double_continue",
118*35238bceSAndroid Build Coastguard Worker "conditional_break",
119*35238bceSAndroid Build Coastguard Worker "unconditional_break",
120*35238bceSAndroid Build Coastguard Worker "pre_increment",
121*35238bceSAndroid Build Coastguard Worker "post_increment",
122*35238bceSAndroid Build Coastguard Worker "mixed_break_continue",
123*35238bceSAndroid Build Coastguard Worker "vector_counter",
124*35238bceSAndroid Build Coastguard Worker "101_iterations",
125*35238bceSAndroid Build Coastguard Worker "sequence",
126*35238bceSAndroid Build Coastguard Worker "nested",
127*35238bceSAndroid Build Coastguard Worker "nested_sequence",
128*35238bceSAndroid Build Coastguard Worker "nested_tricky_dataflow_1",
129*35238bceSAndroid Build Coastguard Worker "nested_tricky_dataflow_2",
130*35238bceSAndroid Build Coastguard Worker "conditional_body",
131*35238bceSAndroid Build Coastguard Worker "function_call_return",
132*35238bceSAndroid Build Coastguard Worker "function_call_inout"};
133*35238bceSAndroid Build Coastguard Worker
134*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == LOOPCASE_LAST);
135*35238bceSAndroid Build Coastguard Worker DE_ASSERT(deInBounds32((int)loopCase, 0, LOOPCASE_LAST));
136*35238bceSAndroid Build Coastguard Worker return s_names[(int)loopCase];
137*35238bceSAndroid Build Coastguard Worker }
138*35238bceSAndroid Build Coastguard Worker
139*35238bceSAndroid Build Coastguard Worker enum LoopType
140*35238bceSAndroid Build Coastguard Worker {
141*35238bceSAndroid Build Coastguard Worker LOOPTYPE_FOR = 0,
142*35238bceSAndroid Build Coastguard Worker LOOPTYPE_WHILE,
143*35238bceSAndroid Build Coastguard Worker LOOPTYPE_DO_WHILE,
144*35238bceSAndroid Build Coastguard Worker
145*35238bceSAndroid Build Coastguard Worker LOOPTYPE_LAST
146*35238bceSAndroid Build Coastguard Worker };
147*35238bceSAndroid Build Coastguard Worker
getLoopTypeName(LoopType loopType)148*35238bceSAndroid Build Coastguard Worker static const char *getLoopTypeName(LoopType loopType)
149*35238bceSAndroid Build Coastguard Worker {
150*35238bceSAndroid Build Coastguard Worker static const char *s_names[] = {"for", "while", "do_while"};
151*35238bceSAndroid Build Coastguard Worker
152*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == LOOPTYPE_LAST);
153*35238bceSAndroid Build Coastguard Worker DE_ASSERT(deInBounds32((int)loopType, 0, LOOPTYPE_LAST));
154*35238bceSAndroid Build Coastguard Worker return s_names[(int)loopType];
155*35238bceSAndroid Build Coastguard Worker }
156*35238bceSAndroid Build Coastguard Worker
157*35238bceSAndroid Build Coastguard Worker enum LoopCountType
158*35238bceSAndroid Build Coastguard Worker {
159*35238bceSAndroid Build Coastguard Worker LOOPCOUNT_CONSTANT = 0,
160*35238bceSAndroid Build Coastguard Worker LOOPCOUNT_UNIFORM,
161*35238bceSAndroid Build Coastguard Worker LOOPCOUNT_DYNAMIC,
162*35238bceSAndroid Build Coastguard Worker
163*35238bceSAndroid Build Coastguard Worker LOOPCOUNT_LAST
164*35238bceSAndroid Build Coastguard Worker };
165*35238bceSAndroid Build Coastguard Worker
getLoopCountTypeName(LoopCountType countType)166*35238bceSAndroid Build Coastguard Worker static const char *getLoopCountTypeName(LoopCountType countType)
167*35238bceSAndroid Build Coastguard Worker {
168*35238bceSAndroid Build Coastguard Worker static const char *s_names[] = {"constant", "uniform", "dynamic"};
169*35238bceSAndroid Build Coastguard Worker
170*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == LOOPCOUNT_LAST);
171*35238bceSAndroid Build Coastguard Worker DE_ASSERT(deInBounds32((int)countType, 0, LOOPCOUNT_LAST));
172*35238bceSAndroid Build Coastguard Worker return s_names[(int)countType];
173*35238bceSAndroid Build Coastguard Worker }
174*35238bceSAndroid Build Coastguard Worker
evalLoop0Iters(ShaderEvalContext & c)175*35238bceSAndroid Build Coastguard Worker static void evalLoop0Iters(ShaderEvalContext &c)
176*35238bceSAndroid Build Coastguard Worker {
177*35238bceSAndroid Build Coastguard Worker c.color.xyz() = c.coords.swizzle(0, 1, 2);
178*35238bceSAndroid Build Coastguard Worker }
evalLoop1Iters(ShaderEvalContext & c)179*35238bceSAndroid Build Coastguard Worker static void evalLoop1Iters(ShaderEvalContext &c)
180*35238bceSAndroid Build Coastguard Worker {
181*35238bceSAndroid Build Coastguard Worker c.color.xyz() = c.coords.swizzle(1, 2, 3);
182*35238bceSAndroid Build Coastguard Worker }
evalLoop2Iters(ShaderEvalContext & c)183*35238bceSAndroid Build Coastguard Worker static void evalLoop2Iters(ShaderEvalContext &c)
184*35238bceSAndroid Build Coastguard Worker {
185*35238bceSAndroid Build Coastguard Worker c.color.xyz() = c.coords.swizzle(2, 3, 0);
186*35238bceSAndroid Build Coastguard Worker }
evalLoop3Iters(ShaderEvalContext & c)187*35238bceSAndroid Build Coastguard Worker static void evalLoop3Iters(ShaderEvalContext &c)
188*35238bceSAndroid Build Coastguard Worker {
189*35238bceSAndroid Build Coastguard Worker c.color.xyz() = c.coords.swizzle(3, 0, 1);
190*35238bceSAndroid Build Coastguard Worker }
191*35238bceSAndroid Build Coastguard Worker
getLoopEvalFunc(int numIters)192*35238bceSAndroid Build Coastguard Worker static ShaderEvalFunc getLoopEvalFunc(int numIters)
193*35238bceSAndroid Build Coastguard Worker {
194*35238bceSAndroid Build Coastguard Worker switch (numIters % 4)
195*35238bceSAndroid Build Coastguard Worker {
196*35238bceSAndroid Build Coastguard Worker case 0:
197*35238bceSAndroid Build Coastguard Worker return evalLoop0Iters;
198*35238bceSAndroid Build Coastguard Worker case 1:
199*35238bceSAndroid Build Coastguard Worker return evalLoop1Iters;
200*35238bceSAndroid Build Coastguard Worker case 2:
201*35238bceSAndroid Build Coastguard Worker return evalLoop2Iters;
202*35238bceSAndroid Build Coastguard Worker case 3:
203*35238bceSAndroid Build Coastguard Worker return evalLoop3Iters;
204*35238bceSAndroid Build Coastguard Worker }
205*35238bceSAndroid Build Coastguard Worker
206*35238bceSAndroid Build Coastguard Worker DE_FATAL("Invalid loop iteration count.");
207*35238bceSAndroid Build Coastguard Worker return NULL;
208*35238bceSAndroid Build Coastguard Worker }
209*35238bceSAndroid Build Coastguard Worker
210*35238bceSAndroid Build Coastguard Worker // ShaderLoopCase
211*35238bceSAndroid Build Coastguard Worker
212*35238bceSAndroid Build Coastguard Worker class ShaderLoopCase : public ShaderRenderCase
213*35238bceSAndroid Build Coastguard Worker {
214*35238bceSAndroid Build Coastguard Worker public:
215*35238bceSAndroid Build Coastguard Worker ShaderLoopCase(Context &context, const char *name, const char *description, bool isVertexCase,
216*35238bceSAndroid Build Coastguard Worker ShaderEvalFunc evalFunc, LoopRequirement requirement, const char *vertShaderSource,
217*35238bceSAndroid Build Coastguard Worker const char *fragShaderSource);
218*35238bceSAndroid Build Coastguard Worker virtual ~ShaderLoopCase(void);
219*35238bceSAndroid Build Coastguard Worker
220*35238bceSAndroid Build Coastguard Worker void init(void);
221*35238bceSAndroid Build Coastguard Worker
222*35238bceSAndroid Build Coastguard Worker private:
223*35238bceSAndroid Build Coastguard Worker ShaderLoopCase(const ShaderLoopCase &); // not allowed!
224*35238bceSAndroid Build Coastguard Worker ShaderLoopCase &operator=(const ShaderLoopCase &); // not allowed!
225*35238bceSAndroid Build Coastguard Worker
226*35238bceSAndroid Build Coastguard Worker virtual void setup(int programID);
227*35238bceSAndroid Build Coastguard Worker virtual void setupUniforms(int programID, const Vec4 &constCoords);
228*35238bceSAndroid Build Coastguard Worker
229*35238bceSAndroid Build Coastguard Worker LoopRequirement m_requirement;
230*35238bceSAndroid Build Coastguard Worker };
231*35238bceSAndroid Build Coastguard Worker
ShaderLoopCase(Context & context,const char * name,const char * description,bool isVertexCase,ShaderEvalFunc evalFunc,LoopRequirement requirement,const char * vertShaderSource,const char * fragShaderSource)232*35238bceSAndroid Build Coastguard Worker ShaderLoopCase::ShaderLoopCase(Context &context, const char *name, const char *description, bool isVertexCase,
233*35238bceSAndroid Build Coastguard Worker ShaderEvalFunc evalFunc, LoopRequirement requirement, const char *vertShaderSource,
234*35238bceSAndroid Build Coastguard Worker const char *fragShaderSource)
235*35238bceSAndroid Build Coastguard Worker : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name,
236*35238bceSAndroid Build Coastguard Worker description, isVertexCase, evalFunc)
237*35238bceSAndroid Build Coastguard Worker , m_requirement(requirement)
238*35238bceSAndroid Build Coastguard Worker {
239*35238bceSAndroid Build Coastguard Worker m_vertShaderSource = vertShaderSource;
240*35238bceSAndroid Build Coastguard Worker m_fragShaderSource = fragShaderSource;
241*35238bceSAndroid Build Coastguard Worker }
242*35238bceSAndroid Build Coastguard Worker
~ShaderLoopCase(void)243*35238bceSAndroid Build Coastguard Worker ShaderLoopCase::~ShaderLoopCase(void)
244*35238bceSAndroid Build Coastguard Worker {
245*35238bceSAndroid Build Coastguard Worker }
246*35238bceSAndroid Build Coastguard Worker
init(void)247*35238bceSAndroid Build Coastguard Worker void ShaderLoopCase::init(void)
248*35238bceSAndroid Build Coastguard Worker {
249*35238bceSAndroid Build Coastguard Worker bool isSupported = true;
250*35238bceSAndroid Build Coastguard Worker
251*35238bceSAndroid Build Coastguard Worker if (m_requirement == LOOPREQUIREMENT_UNIFORM)
252*35238bceSAndroid Build Coastguard Worker isSupported =
253*35238bceSAndroid Build Coastguard Worker m_isVertexCase ? m_ctxInfo.isVertexUniformLoopSupported() : m_ctxInfo.isFragmentUniformLoopSupported();
254*35238bceSAndroid Build Coastguard Worker else if (m_requirement == LOOPREQUIREMENT_DYNAMIC)
255*35238bceSAndroid Build Coastguard Worker isSupported =
256*35238bceSAndroid Build Coastguard Worker m_isVertexCase ? m_ctxInfo.isVertexDynamicLoopSupported() : m_ctxInfo.isFragmentDynamicLoopSupported();
257*35238bceSAndroid Build Coastguard Worker
258*35238bceSAndroid Build Coastguard Worker try
259*35238bceSAndroid Build Coastguard Worker {
260*35238bceSAndroid Build Coastguard Worker ShaderRenderCase::init();
261*35238bceSAndroid Build Coastguard Worker }
262*35238bceSAndroid Build Coastguard Worker catch (const CompileFailed &)
263*35238bceSAndroid Build Coastguard Worker {
264*35238bceSAndroid Build Coastguard Worker if (!isSupported)
265*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Loop type is not supported");
266*35238bceSAndroid Build Coastguard Worker else
267*35238bceSAndroid Build Coastguard Worker throw;
268*35238bceSAndroid Build Coastguard Worker }
269*35238bceSAndroid Build Coastguard Worker }
270*35238bceSAndroid Build Coastguard Worker
setup(int programID)271*35238bceSAndroid Build Coastguard Worker void ShaderLoopCase::setup(int programID)
272*35238bceSAndroid Build Coastguard Worker {
273*35238bceSAndroid Build Coastguard Worker DE_UNREF(programID);
274*35238bceSAndroid Build Coastguard Worker }
275*35238bceSAndroid Build Coastguard Worker
setupUniforms(int programID,const Vec4 & constCoords)276*35238bceSAndroid Build Coastguard Worker void ShaderLoopCase::setupUniforms(int programID, const Vec4 &constCoords)
277*35238bceSAndroid Build Coastguard Worker {
278*35238bceSAndroid Build Coastguard Worker DE_UNREF(programID);
279*35238bceSAndroid Build Coastguard Worker DE_UNREF(constCoords);
280*35238bceSAndroid Build Coastguard Worker }
281*35238bceSAndroid Build Coastguard Worker
282*35238bceSAndroid Build Coastguard Worker // Test case creation.
283*35238bceSAndroid Build Coastguard Worker
createGenericLoopCase(Context & context,const char * caseName,const char * description,bool isVertexCase,LoopType loopType,LoopCountType loopCountType,Precision loopCountPrecision,DataType loopCountDataType)284*35238bceSAndroid Build Coastguard Worker static ShaderLoopCase *createGenericLoopCase(Context &context, const char *caseName, const char *description,
285*35238bceSAndroid Build Coastguard Worker bool isVertexCase, LoopType loopType, LoopCountType loopCountType,
286*35238bceSAndroid Build Coastguard Worker Precision loopCountPrecision, DataType loopCountDataType)
287*35238bceSAndroid Build Coastguard Worker {
288*35238bceSAndroid Build Coastguard Worker std::ostringstream vtx;
289*35238bceSAndroid Build Coastguard Worker std::ostringstream frag;
290*35238bceSAndroid Build Coastguard Worker std::ostringstream &op = isVertexCase ? vtx : frag;
291*35238bceSAndroid Build Coastguard Worker
292*35238bceSAndroid Build Coastguard Worker vtx << "attribute highp vec4 a_position;\n";
293*35238bceSAndroid Build Coastguard Worker vtx << "attribute highp vec4 a_coords;\n";
294*35238bceSAndroid Build Coastguard Worker
295*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_DYNAMIC)
296*35238bceSAndroid Build Coastguard Worker vtx << "attribute mediump float a_one;\n";
297*35238bceSAndroid Build Coastguard Worker
298*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
299*35238bceSAndroid Build Coastguard Worker {
300*35238bceSAndroid Build Coastguard Worker vtx << "varying mediump vec3 v_color;\n";
301*35238bceSAndroid Build Coastguard Worker frag << "varying mediump vec3 v_color;\n";
302*35238bceSAndroid Build Coastguard Worker }
303*35238bceSAndroid Build Coastguard Worker else
304*35238bceSAndroid Build Coastguard Worker {
305*35238bceSAndroid Build Coastguard Worker vtx << "varying mediump vec4 v_coords;\n";
306*35238bceSAndroid Build Coastguard Worker frag << "varying mediump vec4 v_coords;\n";
307*35238bceSAndroid Build Coastguard Worker
308*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_DYNAMIC)
309*35238bceSAndroid Build Coastguard Worker {
310*35238bceSAndroid Build Coastguard Worker vtx << "varying mediump float v_one;\n";
311*35238bceSAndroid Build Coastguard Worker frag << "varying mediump float v_one;\n";
312*35238bceSAndroid Build Coastguard Worker }
313*35238bceSAndroid Build Coastguard Worker }
314*35238bceSAndroid Build Coastguard Worker
315*35238bceSAndroid Build Coastguard Worker // \todo [petri] Pass numLoopIters from outside?
316*35238bceSAndroid Build Coastguard Worker int numLoopIters = 3;
317*35238bceSAndroid Build Coastguard Worker bool isIntCounter = isDataTypeIntOrIVec(loopCountDataType);
318*35238bceSAndroid Build Coastguard Worker
319*35238bceSAndroid Build Coastguard Worker if (isIntCounter)
320*35238bceSAndroid Build Coastguard Worker {
321*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_UNIFORM || loopCountType == LOOPCOUNT_DYNAMIC)
322*35238bceSAndroid Build Coastguard Worker op << "uniform ${COUNTER_PRECISION} int " << getIntUniformName(numLoopIters) << ";\n";
323*35238bceSAndroid Build Coastguard Worker }
324*35238bceSAndroid Build Coastguard Worker else
325*35238bceSAndroid Build Coastguard Worker {
326*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_UNIFORM || loopCountType == LOOPCOUNT_DYNAMIC)
327*35238bceSAndroid Build Coastguard Worker op << "uniform ${COUNTER_PRECISION} float " << getFloatFractionUniformName(numLoopIters) << ";\n";
328*35238bceSAndroid Build Coastguard Worker
329*35238bceSAndroid Build Coastguard Worker if (numLoopIters != 1)
330*35238bceSAndroid Build Coastguard Worker op << "uniform ${COUNTER_PRECISION} float uf_one;\n";
331*35238bceSAndroid Build Coastguard Worker }
332*35238bceSAndroid Build Coastguard Worker
333*35238bceSAndroid Build Coastguard Worker vtx << "\n";
334*35238bceSAndroid Build Coastguard Worker vtx << "void main()\n";
335*35238bceSAndroid Build Coastguard Worker vtx << "{\n";
336*35238bceSAndroid Build Coastguard Worker vtx << " gl_Position = a_position;\n";
337*35238bceSAndroid Build Coastguard Worker
338*35238bceSAndroid Build Coastguard Worker frag << "\n";
339*35238bceSAndroid Build Coastguard Worker frag << "void main()\n";
340*35238bceSAndroid Build Coastguard Worker frag << "{\n";
341*35238bceSAndroid Build Coastguard Worker
342*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
343*35238bceSAndroid Build Coastguard Worker vtx << " ${PRECISION} vec4 coords = a_coords;\n";
344*35238bceSAndroid Build Coastguard Worker else
345*35238bceSAndroid Build Coastguard Worker frag << " ${PRECISION} vec4 coords = v_coords;\n";
346*35238bceSAndroid Build Coastguard Worker
347*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_DYNAMIC)
348*35238bceSAndroid Build Coastguard Worker {
349*35238bceSAndroid Build Coastguard Worker if (isIntCounter)
350*35238bceSAndroid Build Coastguard Worker {
351*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
352*35238bceSAndroid Build Coastguard Worker vtx << " ${COUNTER_PRECISION} int one = int(a_one + 0.5);\n";
353*35238bceSAndroid Build Coastguard Worker else
354*35238bceSAndroid Build Coastguard Worker frag << " ${COUNTER_PRECISION} int one = int(v_one + 0.5);\n";
355*35238bceSAndroid Build Coastguard Worker }
356*35238bceSAndroid Build Coastguard Worker else
357*35238bceSAndroid Build Coastguard Worker {
358*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
359*35238bceSAndroid Build Coastguard Worker vtx << " ${COUNTER_PRECISION} float one = a_one;\n";
360*35238bceSAndroid Build Coastguard Worker else
361*35238bceSAndroid Build Coastguard Worker frag << " ${COUNTER_PRECISION} float one = v_one;\n";
362*35238bceSAndroid Build Coastguard Worker }
363*35238bceSAndroid Build Coastguard Worker }
364*35238bceSAndroid Build Coastguard Worker
365*35238bceSAndroid Build Coastguard Worker // Read array.
366*35238bceSAndroid Build Coastguard Worker op << " ${PRECISION} vec4 res = coords;\n";
367*35238bceSAndroid Build Coastguard Worker
368*35238bceSAndroid Build Coastguard Worker // Loop iteration count.
369*35238bceSAndroid Build Coastguard Worker string iterMaxStr;
370*35238bceSAndroid Build Coastguard Worker
371*35238bceSAndroid Build Coastguard Worker if (isIntCounter)
372*35238bceSAndroid Build Coastguard Worker {
373*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_CONSTANT)
374*35238bceSAndroid Build Coastguard Worker iterMaxStr = de::toString(numLoopIters);
375*35238bceSAndroid Build Coastguard Worker else if (loopCountType == LOOPCOUNT_UNIFORM)
376*35238bceSAndroid Build Coastguard Worker iterMaxStr = getIntUniformName(numLoopIters);
377*35238bceSAndroid Build Coastguard Worker else if (loopCountType == LOOPCOUNT_DYNAMIC)
378*35238bceSAndroid Build Coastguard Worker iterMaxStr = string(getIntUniformName(numLoopIters)) + "*one";
379*35238bceSAndroid Build Coastguard Worker else
380*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
381*35238bceSAndroid Build Coastguard Worker }
382*35238bceSAndroid Build Coastguard Worker else
383*35238bceSAndroid Build Coastguard Worker {
384*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_CONSTANT)
385*35238bceSAndroid Build Coastguard Worker iterMaxStr = "1.0";
386*35238bceSAndroid Build Coastguard Worker else if (loopCountType == LOOPCOUNT_UNIFORM)
387*35238bceSAndroid Build Coastguard Worker iterMaxStr = "uf_one";
388*35238bceSAndroid Build Coastguard Worker else if (loopCountType == LOOPCOUNT_DYNAMIC)
389*35238bceSAndroid Build Coastguard Worker iterMaxStr = "uf_one*one";
390*35238bceSAndroid Build Coastguard Worker else
391*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
392*35238bceSAndroid Build Coastguard Worker }
393*35238bceSAndroid Build Coastguard Worker
394*35238bceSAndroid Build Coastguard Worker // Loop operations.
395*35238bceSAndroid Build Coastguard Worker string initValue = isIntCounter ? "0" : "0.05";
396*35238bceSAndroid Build Coastguard Worker string loopCountDeclStr = "${COUNTER_PRECISION} ${LOOP_VAR_TYPE} ndx = " + initValue;
397*35238bceSAndroid Build Coastguard Worker string loopCmpStr = ("ndx < " + iterMaxStr);
398*35238bceSAndroid Build Coastguard Worker string incrementStr;
399*35238bceSAndroid Build Coastguard Worker if (isIntCounter)
400*35238bceSAndroid Build Coastguard Worker incrementStr = "ndx++";
401*35238bceSAndroid Build Coastguard Worker else
402*35238bceSAndroid Build Coastguard Worker {
403*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_CONSTANT)
404*35238bceSAndroid Build Coastguard Worker incrementStr = string("ndx += ") + de::toString(1.0f / (float)numLoopIters);
405*35238bceSAndroid Build Coastguard Worker else if (loopCountType == LOOPCOUNT_UNIFORM)
406*35238bceSAndroid Build Coastguard Worker incrementStr = string("ndx += ") + getFloatFractionUniformName(numLoopIters);
407*35238bceSAndroid Build Coastguard Worker else if (loopCountType == LOOPCOUNT_DYNAMIC)
408*35238bceSAndroid Build Coastguard Worker incrementStr = string("ndx += ") + getFloatFractionUniformName(numLoopIters) + "*one";
409*35238bceSAndroid Build Coastguard Worker else
410*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
411*35238bceSAndroid Build Coastguard Worker }
412*35238bceSAndroid Build Coastguard Worker
413*35238bceSAndroid Build Coastguard Worker // Loop body.
414*35238bceSAndroid Build Coastguard Worker string loopBody;
415*35238bceSAndroid Build Coastguard Worker
416*35238bceSAndroid Build Coastguard Worker loopBody = " res = res.yzwx;\n";
417*35238bceSAndroid Build Coastguard Worker
418*35238bceSAndroid Build Coastguard Worker if (loopType == LOOPTYPE_FOR)
419*35238bceSAndroid Build Coastguard Worker {
420*35238bceSAndroid Build Coastguard Worker op << " for (" + loopCountDeclStr + "; " + loopCmpStr + "; " + incrementStr + ")\n";
421*35238bceSAndroid Build Coastguard Worker op << " {\n";
422*35238bceSAndroid Build Coastguard Worker op << loopBody;
423*35238bceSAndroid Build Coastguard Worker op << " }\n";
424*35238bceSAndroid Build Coastguard Worker }
425*35238bceSAndroid Build Coastguard Worker else if (loopType == LOOPTYPE_WHILE)
426*35238bceSAndroid Build Coastguard Worker {
427*35238bceSAndroid Build Coastguard Worker op << "\t" << loopCountDeclStr + ";\n";
428*35238bceSAndroid Build Coastguard Worker op << " while (" + loopCmpStr + ")\n";
429*35238bceSAndroid Build Coastguard Worker op << " {\n";
430*35238bceSAndroid Build Coastguard Worker op << loopBody;
431*35238bceSAndroid Build Coastguard Worker op << "\t\t" + incrementStr + ";\n";
432*35238bceSAndroid Build Coastguard Worker op << " }\n";
433*35238bceSAndroid Build Coastguard Worker }
434*35238bceSAndroid Build Coastguard Worker else if (loopType == LOOPTYPE_DO_WHILE)
435*35238bceSAndroid Build Coastguard Worker {
436*35238bceSAndroid Build Coastguard Worker op << "\t" << loopCountDeclStr + ";\n";
437*35238bceSAndroid Build Coastguard Worker op << " do\n";
438*35238bceSAndroid Build Coastguard Worker op << " {\n";
439*35238bceSAndroid Build Coastguard Worker op << loopBody;
440*35238bceSAndroid Build Coastguard Worker op << "\t\t" + incrementStr + ";\n";
441*35238bceSAndroid Build Coastguard Worker op << " } while (" + loopCmpStr + ");\n";
442*35238bceSAndroid Build Coastguard Worker }
443*35238bceSAndroid Build Coastguard Worker else
444*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
445*35238bceSAndroid Build Coastguard Worker
446*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
447*35238bceSAndroid Build Coastguard Worker {
448*35238bceSAndroid Build Coastguard Worker vtx << " v_color = res.rgb;\n";
449*35238bceSAndroid Build Coastguard Worker frag << " gl_FragColor = vec4(v_color.rgb, 1.0);\n";
450*35238bceSAndroid Build Coastguard Worker }
451*35238bceSAndroid Build Coastguard Worker else
452*35238bceSAndroid Build Coastguard Worker {
453*35238bceSAndroid Build Coastguard Worker vtx << " v_coords = a_coords;\n";
454*35238bceSAndroid Build Coastguard Worker frag << " gl_FragColor = vec4(res.rgb, 1.0);\n";
455*35238bceSAndroid Build Coastguard Worker
456*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_DYNAMIC)
457*35238bceSAndroid Build Coastguard Worker vtx << " v_one = a_one;\n";
458*35238bceSAndroid Build Coastguard Worker }
459*35238bceSAndroid Build Coastguard Worker
460*35238bceSAndroid Build Coastguard Worker vtx << "}\n";
461*35238bceSAndroid Build Coastguard Worker frag << "}\n";
462*35238bceSAndroid Build Coastguard Worker
463*35238bceSAndroid Build Coastguard Worker // Fill in shader templates.
464*35238bceSAndroid Build Coastguard Worker map<string, string> params;
465*35238bceSAndroid Build Coastguard Worker params.insert(pair<string, string>("LOOP_VAR_TYPE", getDataTypeName(loopCountDataType)));
466*35238bceSAndroid Build Coastguard Worker params.insert(pair<string, string>("PRECISION", "mediump"));
467*35238bceSAndroid Build Coastguard Worker params.insert(pair<string, string>("COUNTER_PRECISION", getPrecisionName(loopCountPrecision)));
468*35238bceSAndroid Build Coastguard Worker
469*35238bceSAndroid Build Coastguard Worker StringTemplate vertTemplate(vtx.str().c_str());
470*35238bceSAndroid Build Coastguard Worker StringTemplate fragTemplate(frag.str().c_str());
471*35238bceSAndroid Build Coastguard Worker string vertexShaderSource = vertTemplate.specialize(params);
472*35238bceSAndroid Build Coastguard Worker string fragmentShaderSource = fragTemplate.specialize(params);
473*35238bceSAndroid Build Coastguard Worker
474*35238bceSAndroid Build Coastguard Worker // Create the case.
475*35238bceSAndroid Build Coastguard Worker ShaderEvalFunc evalFunc = getLoopEvalFunc(numLoopIters);
476*35238bceSAndroid Build Coastguard Worker LoopRequirement requirement;
477*35238bceSAndroid Build Coastguard Worker
478*35238bceSAndroid Build Coastguard Worker if (loopType == LOOPTYPE_FOR)
479*35238bceSAndroid Build Coastguard Worker {
480*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_CONSTANT)
481*35238bceSAndroid Build Coastguard Worker requirement = LOOPREQUIREMENT_STANDARD;
482*35238bceSAndroid Build Coastguard Worker else if (loopCountType == LOOPCOUNT_UNIFORM)
483*35238bceSAndroid Build Coastguard Worker requirement = LOOPREQUIREMENT_UNIFORM;
484*35238bceSAndroid Build Coastguard Worker else
485*35238bceSAndroid Build Coastguard Worker requirement = LOOPREQUIREMENT_DYNAMIC;
486*35238bceSAndroid Build Coastguard Worker }
487*35238bceSAndroid Build Coastguard Worker else
488*35238bceSAndroid Build Coastguard Worker requirement = LOOPREQUIREMENT_DYNAMIC;
489*35238bceSAndroid Build Coastguard Worker
490*35238bceSAndroid Build Coastguard Worker return new ShaderLoopCase(context, caseName, description, isVertexCase, evalFunc, requirement,
491*35238bceSAndroid Build Coastguard Worker vertexShaderSource.c_str(), fragmentShaderSource.c_str());
492*35238bceSAndroid Build Coastguard Worker }
493*35238bceSAndroid Build Coastguard Worker
494*35238bceSAndroid Build Coastguard Worker // \todo [petri] Generalize to float as well?
createSpecialLoopCase(Context & context,const char * caseName,const char * description,bool isVertexCase,LoopCase loopCase,LoopType loopType,LoopCountType loopCountType)495*35238bceSAndroid Build Coastguard Worker static ShaderLoopCase *createSpecialLoopCase(Context &context, const char *caseName, const char *description,
496*35238bceSAndroid Build Coastguard Worker bool isVertexCase, LoopCase loopCase, LoopType loopType,
497*35238bceSAndroid Build Coastguard Worker LoopCountType loopCountType)
498*35238bceSAndroid Build Coastguard Worker {
499*35238bceSAndroid Build Coastguard Worker std::ostringstream vtx;
500*35238bceSAndroid Build Coastguard Worker std::ostringstream frag;
501*35238bceSAndroid Build Coastguard Worker std::ostringstream &op = isVertexCase ? vtx : frag;
502*35238bceSAndroid Build Coastguard Worker
503*35238bceSAndroid Build Coastguard Worker vtx << "attribute highp vec4 a_position;\n";
504*35238bceSAndroid Build Coastguard Worker vtx << "attribute highp vec4 a_coords;\n";
505*35238bceSAndroid Build Coastguard Worker
506*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_DYNAMIC)
507*35238bceSAndroid Build Coastguard Worker vtx << "attribute mediump float a_one;\n";
508*35238bceSAndroid Build Coastguard Worker
509*35238bceSAndroid Build Coastguard Worker // Attribute and varyings.
510*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
511*35238bceSAndroid Build Coastguard Worker {
512*35238bceSAndroid Build Coastguard Worker vtx << "varying mediump vec3 v_color;\n";
513*35238bceSAndroid Build Coastguard Worker frag << "varying mediump vec3 v_color;\n";
514*35238bceSAndroid Build Coastguard Worker }
515*35238bceSAndroid Build Coastguard Worker else
516*35238bceSAndroid Build Coastguard Worker {
517*35238bceSAndroid Build Coastguard Worker vtx << "varying mediump vec4 v_coords;\n";
518*35238bceSAndroid Build Coastguard Worker frag << "varying mediump vec4 v_coords;\n";
519*35238bceSAndroid Build Coastguard Worker
520*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_DYNAMIC)
521*35238bceSAndroid Build Coastguard Worker {
522*35238bceSAndroid Build Coastguard Worker vtx << "varying mediump float v_one;\n";
523*35238bceSAndroid Build Coastguard Worker frag << "varying mediump float v_one;\n";
524*35238bceSAndroid Build Coastguard Worker }
525*35238bceSAndroid Build Coastguard Worker }
526*35238bceSAndroid Build Coastguard Worker
527*35238bceSAndroid Build Coastguard Worker if (loopCase == LOOPCASE_SELECT_ITERATION_COUNT)
528*35238bceSAndroid Build Coastguard Worker op << "uniform bool ub_true;\n";
529*35238bceSAndroid Build Coastguard Worker
530*35238bceSAndroid Build Coastguard Worker op << "uniform ${COUNTER_PRECISION} int ui_zero, ui_one, ui_two, ui_three, ui_four, ui_five, ui_six;\n";
531*35238bceSAndroid Build Coastguard Worker if (loopCase == LOOPCASE_101_ITERATIONS)
532*35238bceSAndroid Build Coastguard Worker op << "uniform ${COUNTER_PRECISION} int ui_oneHundredOne;\n";
533*35238bceSAndroid Build Coastguard Worker
534*35238bceSAndroid Build Coastguard Worker int iterCount = 3; // value to use in loop
535*35238bceSAndroid Build Coastguard Worker int numIters = 3; // actual number of iterations
536*35238bceSAndroid Build Coastguard Worker
537*35238bceSAndroid Build Coastguard Worker // Generate helpers if necessary.
538*35238bceSAndroid Build Coastguard Worker if (loopCase == LOOPCASE_FUNCTION_CALL_RETURN)
539*35238bceSAndroid Build Coastguard Worker op << "\n${PRECISION} vec4 func (in ${PRECISION} vec4 coords) { return coords.yzwx; }\n";
540*35238bceSAndroid Build Coastguard Worker else if (loopCase == LOOPCASE_FUNCTION_CALL_INOUT)
541*35238bceSAndroid Build Coastguard Worker op << "\nvoid func (inout ${PRECISION} vec4 coords) { coords = coords.yzwx; }\n";
542*35238bceSAndroid Build Coastguard Worker
543*35238bceSAndroid Build Coastguard Worker vtx << "\n";
544*35238bceSAndroid Build Coastguard Worker vtx << "void main()\n";
545*35238bceSAndroid Build Coastguard Worker vtx << "{\n";
546*35238bceSAndroid Build Coastguard Worker vtx << " gl_Position = a_position;\n";
547*35238bceSAndroid Build Coastguard Worker
548*35238bceSAndroid Build Coastguard Worker frag << "\n";
549*35238bceSAndroid Build Coastguard Worker frag << "void main()\n";
550*35238bceSAndroid Build Coastguard Worker frag << "{\n";
551*35238bceSAndroid Build Coastguard Worker
552*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_DYNAMIC)
553*35238bceSAndroid Build Coastguard Worker {
554*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
555*35238bceSAndroid Build Coastguard Worker vtx << " ${COUNTER_PRECISION} int one = int(a_one + 0.5);\n";
556*35238bceSAndroid Build Coastguard Worker else
557*35238bceSAndroid Build Coastguard Worker frag << " ${COUNTER_PRECISION} int one = int(v_one + 0.5);\n";
558*35238bceSAndroid Build Coastguard Worker }
559*35238bceSAndroid Build Coastguard Worker
560*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
561*35238bceSAndroid Build Coastguard Worker vtx << " ${PRECISION} vec4 coords = a_coords;\n";
562*35238bceSAndroid Build Coastguard Worker else
563*35238bceSAndroid Build Coastguard Worker frag << " ${PRECISION} vec4 coords = v_coords;\n";
564*35238bceSAndroid Build Coastguard Worker
565*35238bceSAndroid Build Coastguard Worker // Read array.
566*35238bceSAndroid Build Coastguard Worker op << " ${PRECISION} vec4 res = coords;\n";
567*35238bceSAndroid Build Coastguard Worker
568*35238bceSAndroid Build Coastguard Worker // Handle all loop types.
569*35238bceSAndroid Build Coastguard Worker string counterPrecisionStr = "mediump";
570*35238bceSAndroid Build Coastguard Worker string forLoopStr;
571*35238bceSAndroid Build Coastguard Worker string whileLoopStr;
572*35238bceSAndroid Build Coastguard Worker string doWhileLoopPreStr;
573*35238bceSAndroid Build Coastguard Worker string doWhileLoopPostStr;
574*35238bceSAndroid Build Coastguard Worker
575*35238bceSAndroid Build Coastguard Worker if (loopType == LOOPTYPE_FOR)
576*35238bceSAndroid Build Coastguard Worker {
577*35238bceSAndroid Build Coastguard Worker switch (loopCase)
578*35238bceSAndroid Build Coastguard Worker {
579*35238bceSAndroid Build Coastguard Worker case LOOPCASE_EMPTY_BODY:
580*35238bceSAndroid Build Coastguard Worker numIters = 0;
581*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP} {}\n";
582*35238bceSAndroid Build Coastguard Worker break;
583*35238bceSAndroid Build Coastguard Worker
584*35238bceSAndroid Build Coastguard Worker case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST:
585*35238bceSAndroid Build Coastguard Worker numIters = 0;
586*35238bceSAndroid Build Coastguard Worker op << " for (;;) { break; res = res.yzwx; }\n";
587*35238bceSAndroid Build Coastguard Worker break;
588*35238bceSAndroid Build Coastguard Worker
589*35238bceSAndroid Build Coastguard Worker case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST:
590*35238bceSAndroid Build Coastguard Worker numIters = 1;
591*35238bceSAndroid Build Coastguard Worker op << " for (;;) { res = res.yzwx; break; }\n";
592*35238bceSAndroid Build Coastguard Worker break;
593*35238bceSAndroid Build Coastguard Worker
594*35238bceSAndroid Build Coastguard Worker case LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK:
595*35238bceSAndroid Build Coastguard Worker numIters = 2;
596*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int i = 0;\n";
597*35238bceSAndroid Build Coastguard Worker op << " for (;;) { res = res.yzwx; if (i == ${ONE}) break; i++; }\n";
598*35238bceSAndroid Build Coastguard Worker break;
599*35238bceSAndroid Build Coastguard Worker
600*35238bceSAndroid Build Coastguard Worker case LOOPCASE_SINGLE_STATEMENT:
601*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP} res = res.yzwx;\n";
602*35238bceSAndroid Build Coastguard Worker break;
603*35238bceSAndroid Build Coastguard Worker
604*35238bceSAndroid Build Coastguard Worker case LOOPCASE_COMPOUND_STATEMENT:
605*35238bceSAndroid Build Coastguard Worker iterCount = 2;
606*35238bceSAndroid Build Coastguard Worker numIters = 2 * iterCount;
607*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP} { res = res.yzwx; res = res.yzwx; }\n";
608*35238bceSAndroid Build Coastguard Worker break;
609*35238bceSAndroid Build Coastguard Worker
610*35238bceSAndroid Build Coastguard Worker case LOOPCASE_SEQUENCE_STATEMENT:
611*35238bceSAndroid Build Coastguard Worker iterCount = 2;
612*35238bceSAndroid Build Coastguard Worker numIters = 2 * iterCount;
613*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP} res = res.yzwx, res = res.yzwx;\n";
614*35238bceSAndroid Build Coastguard Worker break;
615*35238bceSAndroid Build Coastguard Worker
616*35238bceSAndroid Build Coastguard Worker case LOOPCASE_NO_ITERATIONS:
617*35238bceSAndroid Build Coastguard Worker iterCount = 0;
618*35238bceSAndroid Build Coastguard Worker numIters = 0;
619*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP} res = res.yzwx;\n";
620*35238bceSAndroid Build Coastguard Worker break;
621*35238bceSAndroid Build Coastguard Worker
622*35238bceSAndroid Build Coastguard Worker case LOOPCASE_SINGLE_ITERATION:
623*35238bceSAndroid Build Coastguard Worker iterCount = 1;
624*35238bceSAndroid Build Coastguard Worker numIters = 1;
625*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP} res = res.yzwx;\n";
626*35238bceSAndroid Build Coastguard Worker break;
627*35238bceSAndroid Build Coastguard Worker
628*35238bceSAndroid Build Coastguard Worker case LOOPCASE_SELECT_ITERATION_COUNT:
629*35238bceSAndroid Build Coastguard Worker op << " for (int i = 0; i < (ub_true ? ${ITER_COUNT} : 0); i++) res = res.yzwx;\n";
630*35238bceSAndroid Build Coastguard Worker break;
631*35238bceSAndroid Build Coastguard Worker
632*35238bceSAndroid Build Coastguard Worker case LOOPCASE_CONDITIONAL_CONTINUE:
633*35238bceSAndroid Build Coastguard Worker numIters = iterCount - 1;
634*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP} { if (i == ${TWO}) continue; res = res.yzwx; }\n";
635*35238bceSAndroid Build Coastguard Worker break;
636*35238bceSAndroid Build Coastguard Worker
637*35238bceSAndroid Build Coastguard Worker case LOOPCASE_UNCONDITIONAL_CONTINUE:
638*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP} { res = res.yzwx; continue; }\n";
639*35238bceSAndroid Build Coastguard Worker break;
640*35238bceSAndroid Build Coastguard Worker
641*35238bceSAndroid Build Coastguard Worker case LOOPCASE_ONLY_CONTINUE:
642*35238bceSAndroid Build Coastguard Worker numIters = 0;
643*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP} { continue; }\n";
644*35238bceSAndroid Build Coastguard Worker break;
645*35238bceSAndroid Build Coastguard Worker
646*35238bceSAndroid Build Coastguard Worker case LOOPCASE_DOUBLE_CONTINUE:
647*35238bceSAndroid Build Coastguard Worker numIters = iterCount - 1;
648*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP} { if (i == ${TWO}) continue; res = res.yzwx; continue; }\n";
649*35238bceSAndroid Build Coastguard Worker break;
650*35238bceSAndroid Build Coastguard Worker
651*35238bceSAndroid Build Coastguard Worker case LOOPCASE_CONDITIONAL_BREAK:
652*35238bceSAndroid Build Coastguard Worker numIters = 2;
653*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP} { if (i == ${TWO}) break; res = res.yzwx; }\n";
654*35238bceSAndroid Build Coastguard Worker break;
655*35238bceSAndroid Build Coastguard Worker
656*35238bceSAndroid Build Coastguard Worker case LOOPCASE_UNCONDITIONAL_BREAK:
657*35238bceSAndroid Build Coastguard Worker numIters = 1;
658*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP} { res = res.yzwx; break; }\n";
659*35238bceSAndroid Build Coastguard Worker break;
660*35238bceSAndroid Build Coastguard Worker
661*35238bceSAndroid Build Coastguard Worker case LOOPCASE_PRE_INCREMENT:
662*35238bceSAndroid Build Coastguard Worker op << " for (int i = 0; i < ${ITER_COUNT}; ++i) { res = res.yzwx; }\n";
663*35238bceSAndroid Build Coastguard Worker break;
664*35238bceSAndroid Build Coastguard Worker
665*35238bceSAndroid Build Coastguard Worker case LOOPCASE_POST_INCREMENT:
666*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP} { res = res.yzwx; }\n";
667*35238bceSAndroid Build Coastguard Worker break;
668*35238bceSAndroid Build Coastguard Worker
669*35238bceSAndroid Build Coastguard Worker case LOOPCASE_MIXED_BREAK_CONTINUE:
670*35238bceSAndroid Build Coastguard Worker numIters = 2;
671*35238bceSAndroid Build Coastguard Worker iterCount = 5;
672*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP} { if (i == 0) continue; else if (i == 3) break; res = res.yzwx; }\n";
673*35238bceSAndroid Build Coastguard Worker break;
674*35238bceSAndroid Build Coastguard Worker
675*35238bceSAndroid Build Coastguard Worker case LOOPCASE_VECTOR_COUNTER:
676*35238bceSAndroid Build Coastguard Worker op << " for (${COUNTER_PRECISION} ivec4 i = ivec4(0, 1, ${ITER_COUNT}, 0); i.x < i.z; i.x += i.y) { res "
677*35238bceSAndroid Build Coastguard Worker "= "
678*35238bceSAndroid Build Coastguard Worker "res.yzwx; }\n";
679*35238bceSAndroid Build Coastguard Worker break;
680*35238bceSAndroid Build Coastguard Worker
681*35238bceSAndroid Build Coastguard Worker case LOOPCASE_101_ITERATIONS:
682*35238bceSAndroid Build Coastguard Worker numIters = iterCount = 101;
683*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP} res = res.yzwx;\n";
684*35238bceSAndroid Build Coastguard Worker break;
685*35238bceSAndroid Build Coastguard Worker
686*35238bceSAndroid Build Coastguard Worker case LOOPCASE_SEQUENCE:
687*35238bceSAndroid Build Coastguard Worker iterCount = 5;
688*35238bceSAndroid Build Coastguard Worker numIters = 5;
689*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int i;\n";
690*35238bceSAndroid Build Coastguard Worker op << " for (i = 0; i < ${TWO}; i++) { res = res.yzwx; }\n";
691*35238bceSAndroid Build Coastguard Worker op << " for (; i < ${ITER_COUNT}; i++) { res = res.yzwx; }\n";
692*35238bceSAndroid Build Coastguard Worker break;
693*35238bceSAndroid Build Coastguard Worker
694*35238bceSAndroid Build Coastguard Worker case LOOPCASE_NESTED:
695*35238bceSAndroid Build Coastguard Worker numIters = 2 * iterCount;
696*35238bceSAndroid Build Coastguard Worker op << " for (${COUNTER_PRECISION} int i = 0; i < ${TWO}; i++)\n";
697*35238bceSAndroid Build Coastguard Worker op << " {\n";
698*35238bceSAndroid Build Coastguard Worker op << " for (${COUNTER_PRECISION} int j = 0; j < ${ITER_COUNT}; j++)\n";
699*35238bceSAndroid Build Coastguard Worker op << " res = res.yzwx;\n";
700*35238bceSAndroid Build Coastguard Worker op << " }\n";
701*35238bceSAndroid Build Coastguard Worker break;
702*35238bceSAndroid Build Coastguard Worker
703*35238bceSAndroid Build Coastguard Worker case LOOPCASE_NESTED_SEQUENCE:
704*35238bceSAndroid Build Coastguard Worker numIters = 3 * iterCount;
705*35238bceSAndroid Build Coastguard Worker op << " for (${COUNTER_PRECISION} int i = 0; i < ${ITER_COUNT}; i++)\n";
706*35238bceSAndroid Build Coastguard Worker op << " {\n";
707*35238bceSAndroid Build Coastguard Worker op << " for (${COUNTER_PRECISION} int j = 0; j < ${TWO}; j++)\n";
708*35238bceSAndroid Build Coastguard Worker op << " res = res.yzwx;\n";
709*35238bceSAndroid Build Coastguard Worker op << " for (${COUNTER_PRECISION} int j = 0; j < ${ONE}; j++)\n";
710*35238bceSAndroid Build Coastguard Worker op << " res = res.yzwx;\n";
711*35238bceSAndroid Build Coastguard Worker op << " }\n";
712*35238bceSAndroid Build Coastguard Worker break;
713*35238bceSAndroid Build Coastguard Worker
714*35238bceSAndroid Build Coastguard Worker case LOOPCASE_NESTED_TRICKY_DATAFLOW_1:
715*35238bceSAndroid Build Coastguard Worker numIters = 2;
716*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP}\n";
717*35238bceSAndroid Build Coastguard Worker op << " {\n";
718*35238bceSAndroid Build Coastguard Worker op << " res = coords; // ignore outer loop effect \n";
719*35238bceSAndroid Build Coastguard Worker op << " for (${COUNTER_PRECISION} int j = 0; j < ${TWO}; j++)\n";
720*35238bceSAndroid Build Coastguard Worker op << " res = res.yzwx;\n";
721*35238bceSAndroid Build Coastguard Worker op << " }\n";
722*35238bceSAndroid Build Coastguard Worker break;
723*35238bceSAndroid Build Coastguard Worker
724*35238bceSAndroid Build Coastguard Worker case LOOPCASE_NESTED_TRICKY_DATAFLOW_2:
725*35238bceSAndroid Build Coastguard Worker numIters = iterCount;
726*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP}\n";
727*35238bceSAndroid Build Coastguard Worker op << " {\n";
728*35238bceSAndroid Build Coastguard Worker op << " res = coords.wxyz;\n";
729*35238bceSAndroid Build Coastguard Worker op << " for (${COUNTER_PRECISION} int j = 0; j < ${TWO}; j++)\n";
730*35238bceSAndroid Build Coastguard Worker op << " res = res.yzwx;\n";
731*35238bceSAndroid Build Coastguard Worker op << " coords = res;\n";
732*35238bceSAndroid Build Coastguard Worker op << " }\n";
733*35238bceSAndroid Build Coastguard Worker break;
734*35238bceSAndroid Build Coastguard Worker
735*35238bceSAndroid Build Coastguard Worker case LOOPCASE_CONDITIONAL_BODY:
736*35238bceSAndroid Build Coastguard Worker numIters = de::min(2, iterCount);
737*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP} if (i < 2) res = res.yzwx;\n";
738*35238bceSAndroid Build Coastguard Worker break;
739*35238bceSAndroid Build Coastguard Worker
740*35238bceSAndroid Build Coastguard Worker case LOOPCASE_FUNCTION_CALL_RETURN:
741*35238bceSAndroid Build Coastguard Worker numIters = iterCount;
742*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP}\n";
743*35238bceSAndroid Build Coastguard Worker op << " {\n";
744*35238bceSAndroid Build Coastguard Worker op << " res = func(res);\n";
745*35238bceSAndroid Build Coastguard Worker op << " }\n";
746*35238bceSAndroid Build Coastguard Worker break;
747*35238bceSAndroid Build Coastguard Worker
748*35238bceSAndroid Build Coastguard Worker case LOOPCASE_FUNCTION_CALL_INOUT:
749*35238bceSAndroid Build Coastguard Worker numIters = iterCount;
750*35238bceSAndroid Build Coastguard Worker op << " ${FOR_LOOP}\n";
751*35238bceSAndroid Build Coastguard Worker op << " {\n";
752*35238bceSAndroid Build Coastguard Worker op << " func(res);\n";
753*35238bceSAndroid Build Coastguard Worker op << " }\n";
754*35238bceSAndroid Build Coastguard Worker break;
755*35238bceSAndroid Build Coastguard Worker
756*35238bceSAndroid Build Coastguard Worker default:
757*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
758*35238bceSAndroid Build Coastguard Worker }
759*35238bceSAndroid Build Coastguard Worker
760*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_CONSTANT)
761*35238bceSAndroid Build Coastguard Worker forLoopStr =
762*35238bceSAndroid Build Coastguard Worker string("for (") + counterPrecisionStr + " int i = 0; i < " + de::toString(iterCount) + "; i++)";
763*35238bceSAndroid Build Coastguard Worker else if (loopCountType == LOOPCOUNT_UNIFORM)
764*35238bceSAndroid Build Coastguard Worker forLoopStr =
765*35238bceSAndroid Build Coastguard Worker string("for (") + counterPrecisionStr + " int i = 0; i < " + getIntUniformName(iterCount) + "; i++)";
766*35238bceSAndroid Build Coastguard Worker else if (loopCountType == LOOPCOUNT_DYNAMIC)
767*35238bceSAndroid Build Coastguard Worker forLoopStr = string("for (") + counterPrecisionStr + " int i = 0; i < one*" + getIntUniformName(iterCount) +
768*35238bceSAndroid Build Coastguard Worker "; i++)";
769*35238bceSAndroid Build Coastguard Worker else
770*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
771*35238bceSAndroid Build Coastguard Worker }
772*35238bceSAndroid Build Coastguard Worker else if (loopType == LOOPTYPE_WHILE)
773*35238bceSAndroid Build Coastguard Worker {
774*35238bceSAndroid Build Coastguard Worker switch (loopCase)
775*35238bceSAndroid Build Coastguard Worker {
776*35238bceSAndroid Build Coastguard Worker case LOOPCASE_EMPTY_BODY:
777*35238bceSAndroid Build Coastguard Worker numIters = 0;
778*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP} {}\n";
779*35238bceSAndroid Build Coastguard Worker break;
780*35238bceSAndroid Build Coastguard Worker
781*35238bceSAndroid Build Coastguard Worker case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST:
782*35238bceSAndroid Build Coastguard Worker numIters = 0;
783*35238bceSAndroid Build Coastguard Worker op << " while (true) { break; res = res.yzwx; }\n";
784*35238bceSAndroid Build Coastguard Worker break;
785*35238bceSAndroid Build Coastguard Worker
786*35238bceSAndroid Build Coastguard Worker case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST:
787*35238bceSAndroid Build Coastguard Worker numIters = 1;
788*35238bceSAndroid Build Coastguard Worker op << " while (true) { res = res.yzwx; break; }\n";
789*35238bceSAndroid Build Coastguard Worker break;
790*35238bceSAndroid Build Coastguard Worker
791*35238bceSAndroid Build Coastguard Worker case LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK:
792*35238bceSAndroid Build Coastguard Worker numIters = 2;
793*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int i = 0;\n";
794*35238bceSAndroid Build Coastguard Worker op << " while (true) { res = res.yzwx; if (i == ${ONE}) break; i++; }\n";
795*35238bceSAndroid Build Coastguard Worker break;
796*35238bceSAndroid Build Coastguard Worker
797*35238bceSAndroid Build Coastguard Worker case LOOPCASE_SINGLE_STATEMENT:
798*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP} res = res.yzwx;\n";
799*35238bceSAndroid Build Coastguard Worker break;
800*35238bceSAndroid Build Coastguard Worker
801*35238bceSAndroid Build Coastguard Worker case LOOPCASE_COMPOUND_STATEMENT:
802*35238bceSAndroid Build Coastguard Worker iterCount = 2;
803*35238bceSAndroid Build Coastguard Worker numIters = 2 * iterCount;
804*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP} { res = res.yzwx; res = res.yzwx; }\n";
805*35238bceSAndroid Build Coastguard Worker break;
806*35238bceSAndroid Build Coastguard Worker
807*35238bceSAndroid Build Coastguard Worker case LOOPCASE_SEQUENCE_STATEMENT:
808*35238bceSAndroid Build Coastguard Worker iterCount = 2;
809*35238bceSAndroid Build Coastguard Worker numIters = 2 * iterCount;
810*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP} res = res.yzwx, res = res.yzwx;\n";
811*35238bceSAndroid Build Coastguard Worker break;
812*35238bceSAndroid Build Coastguard Worker
813*35238bceSAndroid Build Coastguard Worker case LOOPCASE_NO_ITERATIONS:
814*35238bceSAndroid Build Coastguard Worker iterCount = 0;
815*35238bceSAndroid Build Coastguard Worker numIters = 0;
816*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP} res = res.yzwx;\n";
817*35238bceSAndroid Build Coastguard Worker break;
818*35238bceSAndroid Build Coastguard Worker
819*35238bceSAndroid Build Coastguard Worker case LOOPCASE_SINGLE_ITERATION:
820*35238bceSAndroid Build Coastguard Worker iterCount = 1;
821*35238bceSAndroid Build Coastguard Worker numIters = 1;
822*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP} res = res.yzwx;\n";
823*35238bceSAndroid Build Coastguard Worker break;
824*35238bceSAndroid Build Coastguard Worker
825*35238bceSAndroid Build Coastguard Worker case LOOPCASE_SELECT_ITERATION_COUNT:
826*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int i = 0;\n";
827*35238bceSAndroid Build Coastguard Worker op << " while (i < (ub_true ? ${ITER_COUNT} : 0)) { res = res.yzwx; i++; }\n";
828*35238bceSAndroid Build Coastguard Worker break;
829*35238bceSAndroid Build Coastguard Worker
830*35238bceSAndroid Build Coastguard Worker case LOOPCASE_CONDITIONAL_CONTINUE:
831*35238bceSAndroid Build Coastguard Worker numIters = iterCount - 1;
832*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP} { if (i == ${TWO}) continue; res = res.yzwx; }\n";
833*35238bceSAndroid Build Coastguard Worker break;
834*35238bceSAndroid Build Coastguard Worker
835*35238bceSAndroid Build Coastguard Worker case LOOPCASE_UNCONDITIONAL_CONTINUE:
836*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP} { res = res.yzwx; continue; }\n";
837*35238bceSAndroid Build Coastguard Worker break;
838*35238bceSAndroid Build Coastguard Worker
839*35238bceSAndroid Build Coastguard Worker case LOOPCASE_ONLY_CONTINUE:
840*35238bceSAndroid Build Coastguard Worker numIters = 0;
841*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP} { continue; }\n";
842*35238bceSAndroid Build Coastguard Worker break;
843*35238bceSAndroid Build Coastguard Worker
844*35238bceSAndroid Build Coastguard Worker case LOOPCASE_DOUBLE_CONTINUE:
845*35238bceSAndroid Build Coastguard Worker numIters = iterCount - 1;
846*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP} { if (i == ${ONE}) continue; res = res.yzwx; continue; }\n";
847*35238bceSAndroid Build Coastguard Worker break;
848*35238bceSAndroid Build Coastguard Worker
849*35238bceSAndroid Build Coastguard Worker case LOOPCASE_CONDITIONAL_BREAK:
850*35238bceSAndroid Build Coastguard Worker numIters = 2;
851*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP} { if (i == ${THREE}) break; res = res.yzwx; }\n";
852*35238bceSAndroid Build Coastguard Worker break;
853*35238bceSAndroid Build Coastguard Worker
854*35238bceSAndroid Build Coastguard Worker case LOOPCASE_UNCONDITIONAL_BREAK:
855*35238bceSAndroid Build Coastguard Worker numIters = 1;
856*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP} { res = res.yzwx; break; }\n";
857*35238bceSAndroid Build Coastguard Worker break;
858*35238bceSAndroid Build Coastguard Worker
859*35238bceSAndroid Build Coastguard Worker case LOOPCASE_PRE_INCREMENT:
860*35238bceSAndroid Build Coastguard Worker numIters = iterCount - 1;
861*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int i = 0;\n";
862*35238bceSAndroid Build Coastguard Worker op << " while (++i < ${ITER_COUNT}) { res = res.yzwx; }\n";
863*35238bceSAndroid Build Coastguard Worker break;
864*35238bceSAndroid Build Coastguard Worker
865*35238bceSAndroid Build Coastguard Worker case LOOPCASE_POST_INCREMENT:
866*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int i = 0;\n";
867*35238bceSAndroid Build Coastguard Worker op << " while (i++ < ${ITER_COUNT}) { res = res.yzwx; }\n";
868*35238bceSAndroid Build Coastguard Worker break;
869*35238bceSAndroid Build Coastguard Worker
870*35238bceSAndroid Build Coastguard Worker case LOOPCASE_MIXED_BREAK_CONTINUE:
871*35238bceSAndroid Build Coastguard Worker numIters = 2;
872*35238bceSAndroid Build Coastguard Worker iterCount = 5;
873*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP} { if (i == 0) continue; else if (i == 3) break; res = res.yzwx; }\n";
874*35238bceSAndroid Build Coastguard Worker break;
875*35238bceSAndroid Build Coastguard Worker
876*35238bceSAndroid Build Coastguard Worker case LOOPCASE_VECTOR_COUNTER:
877*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} ivec4 i = ivec4(0, 1, ${ITER_COUNT}, 0);\n";
878*35238bceSAndroid Build Coastguard Worker op << " while (i.x < i.z) { res = res.yzwx; i.x += i.y; }\n";
879*35238bceSAndroid Build Coastguard Worker break;
880*35238bceSAndroid Build Coastguard Worker
881*35238bceSAndroid Build Coastguard Worker case LOOPCASE_101_ITERATIONS:
882*35238bceSAndroid Build Coastguard Worker numIters = iterCount = 101;
883*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP} res = res.yzwx;\n";
884*35238bceSAndroid Build Coastguard Worker break;
885*35238bceSAndroid Build Coastguard Worker
886*35238bceSAndroid Build Coastguard Worker case LOOPCASE_SEQUENCE:
887*35238bceSAndroid Build Coastguard Worker iterCount = 6;
888*35238bceSAndroid Build Coastguard Worker numIters = iterCount - 1;
889*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int i = 0;\n";
890*35238bceSAndroid Build Coastguard Worker op << " while (i++ < ${TWO}) { res = res.yzwx; }\n";
891*35238bceSAndroid Build Coastguard Worker op << " while (i++ < ${ITER_COUNT}) { res = res.yzwx; }\n"; // \note skips one iteration
892*35238bceSAndroid Build Coastguard Worker break;
893*35238bceSAndroid Build Coastguard Worker
894*35238bceSAndroid Build Coastguard Worker case LOOPCASE_NESTED:
895*35238bceSAndroid Build Coastguard Worker numIters = 2 * iterCount;
896*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int i = 0;\n";
897*35238bceSAndroid Build Coastguard Worker op << " while (i++ < ${TWO})\n";
898*35238bceSAndroid Build Coastguard Worker op << " {\n";
899*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int j = 0;\n";
900*35238bceSAndroid Build Coastguard Worker op << " while (j++ < ${ITER_COUNT})\n";
901*35238bceSAndroid Build Coastguard Worker op << " res = res.yzwx;\n";
902*35238bceSAndroid Build Coastguard Worker op << " }\n";
903*35238bceSAndroid Build Coastguard Worker break;
904*35238bceSAndroid Build Coastguard Worker
905*35238bceSAndroid Build Coastguard Worker case LOOPCASE_NESTED_SEQUENCE:
906*35238bceSAndroid Build Coastguard Worker numIters = 2 * iterCount;
907*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int i = 0;\n";
908*35238bceSAndroid Build Coastguard Worker op << " while (i++ < ${ITER_COUNT})\n";
909*35238bceSAndroid Build Coastguard Worker op << " {\n";
910*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int j = 0;\n";
911*35238bceSAndroid Build Coastguard Worker op << " while (j++ < ${ONE})\n";
912*35238bceSAndroid Build Coastguard Worker op << " res = res.yzwx;\n";
913*35238bceSAndroid Build Coastguard Worker op << " while (j++ < ${THREE})\n"; // \note skips one iteration
914*35238bceSAndroid Build Coastguard Worker op << " res = res.yzwx;\n";
915*35238bceSAndroid Build Coastguard Worker op << " }\n";
916*35238bceSAndroid Build Coastguard Worker break;
917*35238bceSAndroid Build Coastguard Worker
918*35238bceSAndroid Build Coastguard Worker case LOOPCASE_NESTED_TRICKY_DATAFLOW_1:
919*35238bceSAndroid Build Coastguard Worker numIters = 2;
920*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP}\n";
921*35238bceSAndroid Build Coastguard Worker op << " {\n";
922*35238bceSAndroid Build Coastguard Worker op << " res = coords; // ignore outer loop effect \n";
923*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int j = 0;\n";
924*35238bceSAndroid Build Coastguard Worker op << " while (j++ < ${TWO})\n";
925*35238bceSAndroid Build Coastguard Worker op << " res = res.yzwx;\n";
926*35238bceSAndroid Build Coastguard Worker op << " }\n";
927*35238bceSAndroid Build Coastguard Worker break;
928*35238bceSAndroid Build Coastguard Worker
929*35238bceSAndroid Build Coastguard Worker case LOOPCASE_NESTED_TRICKY_DATAFLOW_2:
930*35238bceSAndroid Build Coastguard Worker numIters = iterCount;
931*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP}\n";
932*35238bceSAndroid Build Coastguard Worker op << " {\n";
933*35238bceSAndroid Build Coastguard Worker op << " res = coords.wxyz;\n";
934*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int j = 0;\n";
935*35238bceSAndroid Build Coastguard Worker op << " while (j++ < ${TWO})\n";
936*35238bceSAndroid Build Coastguard Worker op << " res = res.yzwx;\n";
937*35238bceSAndroid Build Coastguard Worker op << " coords = res;\n";
938*35238bceSAndroid Build Coastguard Worker op << " }\n";
939*35238bceSAndroid Build Coastguard Worker break;
940*35238bceSAndroid Build Coastguard Worker
941*35238bceSAndroid Build Coastguard Worker case LOOPCASE_CONDITIONAL_BODY:
942*35238bceSAndroid Build Coastguard Worker numIters = de::min(1, iterCount);
943*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP} if (i < 2) res = res.yzwx;\n";
944*35238bceSAndroid Build Coastguard Worker break;
945*35238bceSAndroid Build Coastguard Worker
946*35238bceSAndroid Build Coastguard Worker case LOOPCASE_FUNCTION_CALL_RETURN:
947*35238bceSAndroid Build Coastguard Worker numIters = iterCount;
948*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP}\n";
949*35238bceSAndroid Build Coastguard Worker op << " {\n";
950*35238bceSAndroid Build Coastguard Worker op << " res = func(res);\n";
951*35238bceSAndroid Build Coastguard Worker op << " }\n";
952*35238bceSAndroid Build Coastguard Worker break;
953*35238bceSAndroid Build Coastguard Worker
954*35238bceSAndroid Build Coastguard Worker case LOOPCASE_FUNCTION_CALL_INOUT:
955*35238bceSAndroid Build Coastguard Worker numIters = iterCount;
956*35238bceSAndroid Build Coastguard Worker op << " ${WHILE_LOOP}\n";
957*35238bceSAndroid Build Coastguard Worker op << " {\n";
958*35238bceSAndroid Build Coastguard Worker op << " func(res);\n";
959*35238bceSAndroid Build Coastguard Worker op << " }\n";
960*35238bceSAndroid Build Coastguard Worker break;
961*35238bceSAndroid Build Coastguard Worker
962*35238bceSAndroid Build Coastguard Worker default:
963*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
964*35238bceSAndroid Build Coastguard Worker }
965*35238bceSAndroid Build Coastguard Worker
966*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_CONSTANT)
967*35238bceSAndroid Build Coastguard Worker whileLoopStr = string("\t") + counterPrecisionStr + " int i = 0;\n" + " while(i++ < " +
968*35238bceSAndroid Build Coastguard Worker de::toString(iterCount) + ")";
969*35238bceSAndroid Build Coastguard Worker else if (loopCountType == LOOPCOUNT_UNIFORM)
970*35238bceSAndroid Build Coastguard Worker whileLoopStr = string("\t") + counterPrecisionStr + " int i = 0;\n" + " while(i++ < " +
971*35238bceSAndroid Build Coastguard Worker getIntUniformName(iterCount) + ")";
972*35238bceSAndroid Build Coastguard Worker else if (loopCountType == LOOPCOUNT_DYNAMIC)
973*35238bceSAndroid Build Coastguard Worker whileLoopStr = string("\t") + counterPrecisionStr + " int i = 0;\n" + " while(i++ < one*" +
974*35238bceSAndroid Build Coastguard Worker getIntUniformName(iterCount) + ")";
975*35238bceSAndroid Build Coastguard Worker else
976*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
977*35238bceSAndroid Build Coastguard Worker }
978*35238bceSAndroid Build Coastguard Worker else
979*35238bceSAndroid Build Coastguard Worker {
980*35238bceSAndroid Build Coastguard Worker DE_ASSERT(loopType == LOOPTYPE_DO_WHILE);
981*35238bceSAndroid Build Coastguard Worker
982*35238bceSAndroid Build Coastguard Worker switch (loopCase)
983*35238bceSAndroid Build Coastguard Worker {
984*35238bceSAndroid Build Coastguard Worker case LOOPCASE_EMPTY_BODY:
985*35238bceSAndroid Build Coastguard Worker numIters = 0;
986*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE} {} ${DO_WHILE_POST}\n";
987*35238bceSAndroid Build Coastguard Worker break;
988*35238bceSAndroid Build Coastguard Worker
989*35238bceSAndroid Build Coastguard Worker case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST:
990*35238bceSAndroid Build Coastguard Worker numIters = 0;
991*35238bceSAndroid Build Coastguard Worker op << " do { break; res = res.yzwx; } while (true);\n";
992*35238bceSAndroid Build Coastguard Worker break;
993*35238bceSAndroid Build Coastguard Worker
994*35238bceSAndroid Build Coastguard Worker case LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST:
995*35238bceSAndroid Build Coastguard Worker numIters = 1;
996*35238bceSAndroid Build Coastguard Worker op << " do { res = res.yzwx; break; } while (true);\n";
997*35238bceSAndroid Build Coastguard Worker break;
998*35238bceSAndroid Build Coastguard Worker
999*35238bceSAndroid Build Coastguard Worker case LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK:
1000*35238bceSAndroid Build Coastguard Worker numIters = 2;
1001*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int i = 0;\n";
1002*35238bceSAndroid Build Coastguard Worker op << " do { res = res.yzwx; if (i == ${ONE}) break; i++; } while (true);\n";
1003*35238bceSAndroid Build Coastguard Worker break;
1004*35238bceSAndroid Build Coastguard Worker
1005*35238bceSAndroid Build Coastguard Worker case LOOPCASE_SINGLE_STATEMENT:
1006*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE} res = res.yzwx; ${DO_WHILE_POST}\n";
1007*35238bceSAndroid Build Coastguard Worker break;
1008*35238bceSAndroid Build Coastguard Worker
1009*35238bceSAndroid Build Coastguard Worker case LOOPCASE_COMPOUND_STATEMENT:
1010*35238bceSAndroid Build Coastguard Worker iterCount = 2;
1011*35238bceSAndroid Build Coastguard Worker numIters = 2 * iterCount;
1012*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE} { res = res.yzwx; res = res.yzwx; } ${DO_WHILE_POST}\n";
1013*35238bceSAndroid Build Coastguard Worker break;
1014*35238bceSAndroid Build Coastguard Worker
1015*35238bceSAndroid Build Coastguard Worker case LOOPCASE_SEQUENCE_STATEMENT:
1016*35238bceSAndroid Build Coastguard Worker iterCount = 2;
1017*35238bceSAndroid Build Coastguard Worker numIters = 2 * iterCount;
1018*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE} res = res.yzwx, res = res.yzwx; ${DO_WHILE_POST}\n";
1019*35238bceSAndroid Build Coastguard Worker break;
1020*35238bceSAndroid Build Coastguard Worker
1021*35238bceSAndroid Build Coastguard Worker case LOOPCASE_NO_ITERATIONS:
1022*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1023*35238bceSAndroid Build Coastguard Worker break;
1024*35238bceSAndroid Build Coastguard Worker
1025*35238bceSAndroid Build Coastguard Worker case LOOPCASE_SINGLE_ITERATION:
1026*35238bceSAndroid Build Coastguard Worker iterCount = 1;
1027*35238bceSAndroid Build Coastguard Worker numIters = 1;
1028*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE} res = res.yzwx; ${DO_WHILE_POST}\n";
1029*35238bceSAndroid Build Coastguard Worker break;
1030*35238bceSAndroid Build Coastguard Worker
1031*35238bceSAndroid Build Coastguard Worker case LOOPCASE_SELECT_ITERATION_COUNT:
1032*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int i = 0;\n";
1033*35238bceSAndroid Build Coastguard Worker op << " do { res = res.yzwx; } while (++i < (ub_true ? ${ITER_COUNT} : 0));\n";
1034*35238bceSAndroid Build Coastguard Worker break;
1035*35238bceSAndroid Build Coastguard Worker
1036*35238bceSAndroid Build Coastguard Worker case LOOPCASE_CONDITIONAL_CONTINUE:
1037*35238bceSAndroid Build Coastguard Worker numIters = iterCount - 1;
1038*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE} { if (i == ${TWO}) continue; res = res.yzwx; } ${DO_WHILE_POST}\n";
1039*35238bceSAndroid Build Coastguard Worker break;
1040*35238bceSAndroid Build Coastguard Worker
1041*35238bceSAndroid Build Coastguard Worker case LOOPCASE_UNCONDITIONAL_CONTINUE:
1042*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE} { res = res.yzwx; continue; } ${DO_WHILE_POST}\n";
1043*35238bceSAndroid Build Coastguard Worker break;
1044*35238bceSAndroid Build Coastguard Worker
1045*35238bceSAndroid Build Coastguard Worker case LOOPCASE_ONLY_CONTINUE:
1046*35238bceSAndroid Build Coastguard Worker numIters = 0;
1047*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE} { continue; } ${DO_WHILE_POST}\n";
1048*35238bceSAndroid Build Coastguard Worker break;
1049*35238bceSAndroid Build Coastguard Worker
1050*35238bceSAndroid Build Coastguard Worker case LOOPCASE_DOUBLE_CONTINUE:
1051*35238bceSAndroid Build Coastguard Worker numIters = iterCount - 1;
1052*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE} { if (i == ${TWO}) continue; res = res.yzwx; continue; } ${DO_WHILE_POST}\n";
1053*35238bceSAndroid Build Coastguard Worker break;
1054*35238bceSAndroid Build Coastguard Worker
1055*35238bceSAndroid Build Coastguard Worker case LOOPCASE_CONDITIONAL_BREAK:
1056*35238bceSAndroid Build Coastguard Worker numIters = 2;
1057*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE} { res = res.yzwx; if (i == ${ONE}) break; } ${DO_WHILE_POST}\n";
1058*35238bceSAndroid Build Coastguard Worker break;
1059*35238bceSAndroid Build Coastguard Worker
1060*35238bceSAndroid Build Coastguard Worker case LOOPCASE_UNCONDITIONAL_BREAK:
1061*35238bceSAndroid Build Coastguard Worker numIters = 1;
1062*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE} { res = res.yzwx; break; } ${DO_WHILE_POST}\n";
1063*35238bceSAndroid Build Coastguard Worker break;
1064*35238bceSAndroid Build Coastguard Worker
1065*35238bceSAndroid Build Coastguard Worker case LOOPCASE_PRE_INCREMENT:
1066*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int i = 0;\n";
1067*35238bceSAndroid Build Coastguard Worker op << " do { res = res.yzwx; } while (++i < ${ITER_COUNT});\n";
1068*35238bceSAndroid Build Coastguard Worker break;
1069*35238bceSAndroid Build Coastguard Worker
1070*35238bceSAndroid Build Coastguard Worker case LOOPCASE_POST_INCREMENT:
1071*35238bceSAndroid Build Coastguard Worker numIters = iterCount + 1;
1072*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int i = 0;\n";
1073*35238bceSAndroid Build Coastguard Worker op << " do { res = res.yzwx; } while (i++ < ${ITER_COUNT});\n";
1074*35238bceSAndroid Build Coastguard Worker break;
1075*35238bceSAndroid Build Coastguard Worker
1076*35238bceSAndroid Build Coastguard Worker case LOOPCASE_MIXED_BREAK_CONTINUE:
1077*35238bceSAndroid Build Coastguard Worker numIters = 2;
1078*35238bceSAndroid Build Coastguard Worker iterCount = 5;
1079*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE} { if (i == 0) continue; else if (i == 3) break; res = res.yzwx; } "
1080*35238bceSAndroid Build Coastguard Worker "${DO_WHILE_POST}\n";
1081*35238bceSAndroid Build Coastguard Worker break;
1082*35238bceSAndroid Build Coastguard Worker
1083*35238bceSAndroid Build Coastguard Worker case LOOPCASE_VECTOR_COUNTER:
1084*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} ivec4 i = ivec4(0, 1, ${ITER_COUNT}, 0);\n";
1085*35238bceSAndroid Build Coastguard Worker op << " do { res = res.yzwx; } while ((i.x += i.y) < i.z);\n";
1086*35238bceSAndroid Build Coastguard Worker break;
1087*35238bceSAndroid Build Coastguard Worker
1088*35238bceSAndroid Build Coastguard Worker case LOOPCASE_101_ITERATIONS:
1089*35238bceSAndroid Build Coastguard Worker numIters = iterCount = 101;
1090*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE} res = res.yzwx; ${DO_WHILE_POST}\n";
1091*35238bceSAndroid Build Coastguard Worker break;
1092*35238bceSAndroid Build Coastguard Worker
1093*35238bceSAndroid Build Coastguard Worker case LOOPCASE_SEQUENCE:
1094*35238bceSAndroid Build Coastguard Worker iterCount = 5;
1095*35238bceSAndroid Build Coastguard Worker numIters = 5;
1096*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int i = 0;\n";
1097*35238bceSAndroid Build Coastguard Worker op << " do { res = res.yzwx; } while (++i < ${TWO});\n";
1098*35238bceSAndroid Build Coastguard Worker op << " do { res = res.yzwx; } while (++i < ${ITER_COUNT});\n";
1099*35238bceSAndroid Build Coastguard Worker break;
1100*35238bceSAndroid Build Coastguard Worker
1101*35238bceSAndroid Build Coastguard Worker case LOOPCASE_NESTED:
1102*35238bceSAndroid Build Coastguard Worker numIters = 2 * iterCount;
1103*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int i = 0;\n";
1104*35238bceSAndroid Build Coastguard Worker op << " do\n";
1105*35238bceSAndroid Build Coastguard Worker op << " {\n";
1106*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int j = 0;\n";
1107*35238bceSAndroid Build Coastguard Worker op << " do\n";
1108*35238bceSAndroid Build Coastguard Worker op << " res = res.yzwx;\n";
1109*35238bceSAndroid Build Coastguard Worker op << " while (++j < ${ITER_COUNT});\n";
1110*35238bceSAndroid Build Coastguard Worker op << " } while (++i < ${TWO});\n";
1111*35238bceSAndroid Build Coastguard Worker break;
1112*35238bceSAndroid Build Coastguard Worker
1113*35238bceSAndroid Build Coastguard Worker case LOOPCASE_NESTED_SEQUENCE:
1114*35238bceSAndroid Build Coastguard Worker numIters = 3 * iterCount;
1115*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int i = 0;\n";
1116*35238bceSAndroid Build Coastguard Worker op << " do\n";
1117*35238bceSAndroid Build Coastguard Worker op << " {\n";
1118*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int j = 0;\n";
1119*35238bceSAndroid Build Coastguard Worker op << " do\n";
1120*35238bceSAndroid Build Coastguard Worker op << " res = res.yzwx;\n";
1121*35238bceSAndroid Build Coastguard Worker op << " while (++j < ${TWO});\n";
1122*35238bceSAndroid Build Coastguard Worker op << " do\n";
1123*35238bceSAndroid Build Coastguard Worker op << " res = res.yzwx;\n";
1124*35238bceSAndroid Build Coastguard Worker op << " while (++j < ${THREE});\n";
1125*35238bceSAndroid Build Coastguard Worker op << " } while (++i < ${ITER_COUNT});\n";
1126*35238bceSAndroid Build Coastguard Worker break;
1127*35238bceSAndroid Build Coastguard Worker
1128*35238bceSAndroid Build Coastguard Worker case LOOPCASE_NESTED_TRICKY_DATAFLOW_1:
1129*35238bceSAndroid Build Coastguard Worker numIters = 2;
1130*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE}\n";
1131*35238bceSAndroid Build Coastguard Worker op << " {\n";
1132*35238bceSAndroid Build Coastguard Worker op << " res = coords; // ignore outer loop effect \n";
1133*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int j = 0;\n";
1134*35238bceSAndroid Build Coastguard Worker op << " do\n";
1135*35238bceSAndroid Build Coastguard Worker op << " res = res.yzwx;\n";
1136*35238bceSAndroid Build Coastguard Worker op << " while (++j < ${TWO});\n";
1137*35238bceSAndroid Build Coastguard Worker op << " } ${DO_WHILE_POST}\n";
1138*35238bceSAndroid Build Coastguard Worker break;
1139*35238bceSAndroid Build Coastguard Worker
1140*35238bceSAndroid Build Coastguard Worker case LOOPCASE_NESTED_TRICKY_DATAFLOW_2:
1141*35238bceSAndroid Build Coastguard Worker numIters = iterCount;
1142*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE}\n";
1143*35238bceSAndroid Build Coastguard Worker op << " {\n";
1144*35238bceSAndroid Build Coastguard Worker op << " res = coords.wxyz;\n";
1145*35238bceSAndroid Build Coastguard Worker op << " ${COUNTER_PRECISION} int j = 0;\n";
1146*35238bceSAndroid Build Coastguard Worker op << " while (j++ < ${TWO})\n";
1147*35238bceSAndroid Build Coastguard Worker op << " res = res.yzwx;\n";
1148*35238bceSAndroid Build Coastguard Worker op << " coords = res;\n";
1149*35238bceSAndroid Build Coastguard Worker op << " } ${DO_WHILE_POST}\n";
1150*35238bceSAndroid Build Coastguard Worker break;
1151*35238bceSAndroid Build Coastguard Worker
1152*35238bceSAndroid Build Coastguard Worker case LOOPCASE_CONDITIONAL_BODY:
1153*35238bceSAndroid Build Coastguard Worker numIters = de::min(2, iterCount);
1154*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE} if (i < 2) res = res.yzwx; ${DO_WHILE_POST}\n";
1155*35238bceSAndroid Build Coastguard Worker break;
1156*35238bceSAndroid Build Coastguard Worker
1157*35238bceSAndroid Build Coastguard Worker case LOOPCASE_FUNCTION_CALL_RETURN:
1158*35238bceSAndroid Build Coastguard Worker numIters = iterCount;
1159*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE}\n";
1160*35238bceSAndroid Build Coastguard Worker op << " {\n";
1161*35238bceSAndroid Build Coastguard Worker op << " res = func(res);\n";
1162*35238bceSAndroid Build Coastguard Worker op << " } ${DO_WHILE_POST}\n";
1163*35238bceSAndroid Build Coastguard Worker break;
1164*35238bceSAndroid Build Coastguard Worker
1165*35238bceSAndroid Build Coastguard Worker case LOOPCASE_FUNCTION_CALL_INOUT:
1166*35238bceSAndroid Build Coastguard Worker numIters = iterCount;
1167*35238bceSAndroid Build Coastguard Worker op << " ${DO_WHILE_PRE}\n";
1168*35238bceSAndroid Build Coastguard Worker op << " {\n";
1169*35238bceSAndroid Build Coastguard Worker op << " func(res);\n";
1170*35238bceSAndroid Build Coastguard Worker op << " } ${DO_WHILE_POST}\n";
1171*35238bceSAndroid Build Coastguard Worker break;
1172*35238bceSAndroid Build Coastguard Worker
1173*35238bceSAndroid Build Coastguard Worker default:
1174*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1175*35238bceSAndroid Build Coastguard Worker }
1176*35238bceSAndroid Build Coastguard Worker
1177*35238bceSAndroid Build Coastguard Worker doWhileLoopPreStr = string("\t") + counterPrecisionStr + " int i = 0;\n" + "\tdo ";
1178*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_CONSTANT)
1179*35238bceSAndroid Build Coastguard Worker doWhileLoopPostStr = string(" while (++i < ") + de::toString(iterCount) + ");\n";
1180*35238bceSAndroid Build Coastguard Worker else if (loopCountType == LOOPCOUNT_UNIFORM)
1181*35238bceSAndroid Build Coastguard Worker doWhileLoopPostStr = string(" while (++i < ") + getIntUniformName(iterCount) + ");\n";
1182*35238bceSAndroid Build Coastguard Worker else if (loopCountType == LOOPCOUNT_DYNAMIC)
1183*35238bceSAndroid Build Coastguard Worker doWhileLoopPostStr = string(" while (++i < one*") + getIntUniformName(iterCount) + ");\n";
1184*35238bceSAndroid Build Coastguard Worker else
1185*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1186*35238bceSAndroid Build Coastguard Worker }
1187*35238bceSAndroid Build Coastguard Worker
1188*35238bceSAndroid Build Coastguard Worker // Shader footers.
1189*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
1190*35238bceSAndroid Build Coastguard Worker {
1191*35238bceSAndroid Build Coastguard Worker vtx << " v_color = res.rgb;\n";
1192*35238bceSAndroid Build Coastguard Worker frag << " gl_FragColor = vec4(v_color.rgb, 1.0);\n";
1193*35238bceSAndroid Build Coastguard Worker }
1194*35238bceSAndroid Build Coastguard Worker else
1195*35238bceSAndroid Build Coastguard Worker {
1196*35238bceSAndroid Build Coastguard Worker vtx << " v_coords = a_coords;\n";
1197*35238bceSAndroid Build Coastguard Worker frag << " gl_FragColor = vec4(res.rgb, 1.0);\n";
1198*35238bceSAndroid Build Coastguard Worker
1199*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_DYNAMIC)
1200*35238bceSAndroid Build Coastguard Worker vtx << " v_one = a_one;\n";
1201*35238bceSAndroid Build Coastguard Worker }
1202*35238bceSAndroid Build Coastguard Worker
1203*35238bceSAndroid Build Coastguard Worker vtx << "}\n";
1204*35238bceSAndroid Build Coastguard Worker frag << "}\n";
1205*35238bceSAndroid Build Coastguard Worker
1206*35238bceSAndroid Build Coastguard Worker // Constants.
1207*35238bceSAndroid Build Coastguard Worker string oneStr;
1208*35238bceSAndroid Build Coastguard Worker string twoStr;
1209*35238bceSAndroid Build Coastguard Worker string threeStr;
1210*35238bceSAndroid Build Coastguard Worker string iterCountStr;
1211*35238bceSAndroid Build Coastguard Worker
1212*35238bceSAndroid Build Coastguard Worker if (loopCountType == LOOPCOUNT_CONSTANT)
1213*35238bceSAndroid Build Coastguard Worker {
1214*35238bceSAndroid Build Coastguard Worker oneStr = "1";
1215*35238bceSAndroid Build Coastguard Worker twoStr = "2";
1216*35238bceSAndroid Build Coastguard Worker threeStr = "3";
1217*35238bceSAndroid Build Coastguard Worker iterCountStr = de::toString(iterCount);
1218*35238bceSAndroid Build Coastguard Worker }
1219*35238bceSAndroid Build Coastguard Worker else if (loopCountType == LOOPCOUNT_UNIFORM)
1220*35238bceSAndroid Build Coastguard Worker {
1221*35238bceSAndroid Build Coastguard Worker oneStr = "ui_one";
1222*35238bceSAndroid Build Coastguard Worker twoStr = "ui_two";
1223*35238bceSAndroid Build Coastguard Worker threeStr = "ui_three";
1224*35238bceSAndroid Build Coastguard Worker iterCountStr = getIntUniformName(iterCount);
1225*35238bceSAndroid Build Coastguard Worker }
1226*35238bceSAndroid Build Coastguard Worker else if (loopCountType == LOOPCOUNT_DYNAMIC)
1227*35238bceSAndroid Build Coastguard Worker {
1228*35238bceSAndroid Build Coastguard Worker oneStr = "one*ui_one";
1229*35238bceSAndroid Build Coastguard Worker twoStr = "one*ui_two";
1230*35238bceSAndroid Build Coastguard Worker threeStr = "one*ui_three";
1231*35238bceSAndroid Build Coastguard Worker iterCountStr = string("one*") + getIntUniformName(iterCount);
1232*35238bceSAndroid Build Coastguard Worker }
1233*35238bceSAndroid Build Coastguard Worker else
1234*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1235*35238bceSAndroid Build Coastguard Worker
1236*35238bceSAndroid Build Coastguard Worker // Fill in shader templates.
1237*35238bceSAndroid Build Coastguard Worker map<string, string> params;
1238*35238bceSAndroid Build Coastguard Worker params.insert(pair<string, string>("PRECISION", "mediump"));
1239*35238bceSAndroid Build Coastguard Worker params.insert(pair<string, string>("ITER_COUNT", iterCountStr));
1240*35238bceSAndroid Build Coastguard Worker params.insert(pair<string, string>("COUNTER_PRECISION", counterPrecisionStr));
1241*35238bceSAndroid Build Coastguard Worker params.insert(pair<string, string>("FOR_LOOP", forLoopStr));
1242*35238bceSAndroid Build Coastguard Worker params.insert(pair<string, string>("WHILE_LOOP", whileLoopStr));
1243*35238bceSAndroid Build Coastguard Worker params.insert(pair<string, string>("DO_WHILE_PRE", doWhileLoopPreStr));
1244*35238bceSAndroid Build Coastguard Worker params.insert(pair<string, string>("DO_WHILE_POST", doWhileLoopPostStr));
1245*35238bceSAndroid Build Coastguard Worker params.insert(pair<string, string>("ONE", oneStr));
1246*35238bceSAndroid Build Coastguard Worker params.insert(pair<string, string>("TWO", twoStr));
1247*35238bceSAndroid Build Coastguard Worker params.insert(pair<string, string>("THREE", threeStr));
1248*35238bceSAndroid Build Coastguard Worker
1249*35238bceSAndroid Build Coastguard Worker StringTemplate vertTemplate(vtx.str().c_str());
1250*35238bceSAndroid Build Coastguard Worker StringTemplate fragTemplate(frag.str().c_str());
1251*35238bceSAndroid Build Coastguard Worker string vertexShaderSource = vertTemplate.specialize(params);
1252*35238bceSAndroid Build Coastguard Worker string fragmentShaderSource = fragTemplate.specialize(params);
1253*35238bceSAndroid Build Coastguard Worker
1254*35238bceSAndroid Build Coastguard Worker // Create the case.
1255*35238bceSAndroid Build Coastguard Worker ShaderEvalFunc evalFunc = getLoopEvalFunc(numIters);
1256*35238bceSAndroid Build Coastguard Worker LoopRequirement requirement;
1257*35238bceSAndroid Build Coastguard Worker
1258*35238bceSAndroid Build Coastguard Worker if (loopType == LOOPTYPE_FOR && loopCountType == LOOPCOUNT_CONSTANT)
1259*35238bceSAndroid Build Coastguard Worker {
1260*35238bceSAndroid Build Coastguard Worker if (loopCase == LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK ||
1261*35238bceSAndroid Build Coastguard Worker loopCase == LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST ||
1262*35238bceSAndroid Build Coastguard Worker loopCase == LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST ||
1263*35238bceSAndroid Build Coastguard Worker loopCase == LOOPCASE_SELECT_ITERATION_COUNT || loopCase == LOOPCASE_VECTOR_COUNTER ||
1264*35238bceSAndroid Build Coastguard Worker loopCase == LOOPCASE_SEQUENCE)
1265*35238bceSAndroid Build Coastguard Worker requirement = LOOPREQUIREMENT_DYNAMIC;
1266*35238bceSAndroid Build Coastguard Worker else
1267*35238bceSAndroid Build Coastguard Worker requirement = LOOPREQUIREMENT_STANDARD;
1268*35238bceSAndroid Build Coastguard Worker }
1269*35238bceSAndroid Build Coastguard Worker else
1270*35238bceSAndroid Build Coastguard Worker requirement = LOOPREQUIREMENT_DYNAMIC;
1271*35238bceSAndroid Build Coastguard Worker
1272*35238bceSAndroid Build Coastguard Worker return new ShaderLoopCase(context, caseName, description, isVertexCase, evalFunc, requirement,
1273*35238bceSAndroid Build Coastguard Worker vertexShaderSource.c_str(), fragmentShaderSource.c_str());
1274*35238bceSAndroid Build Coastguard Worker }
1275*35238bceSAndroid Build Coastguard Worker
1276*35238bceSAndroid Build Coastguard Worker // ShaderLoopTests.
1277*35238bceSAndroid Build Coastguard Worker
ShaderLoopTests(Context & context)1278*35238bceSAndroid Build Coastguard Worker ShaderLoopTests::ShaderLoopTests(Context &context) : TestCaseGroup(context, "loops", "Loop Tests")
1279*35238bceSAndroid Build Coastguard Worker {
1280*35238bceSAndroid Build Coastguard Worker }
1281*35238bceSAndroid Build Coastguard Worker
~ShaderLoopTests(void)1282*35238bceSAndroid Build Coastguard Worker ShaderLoopTests::~ShaderLoopTests(void)
1283*35238bceSAndroid Build Coastguard Worker {
1284*35238bceSAndroid Build Coastguard Worker }
1285*35238bceSAndroid Build Coastguard Worker
init(void)1286*35238bceSAndroid Build Coastguard Worker void ShaderLoopTests::init(void)
1287*35238bceSAndroid Build Coastguard Worker {
1288*35238bceSAndroid Build Coastguard Worker // Loop cases.
1289*35238bceSAndroid Build Coastguard Worker
1290*35238bceSAndroid Build Coastguard Worker static const ShaderType s_shaderTypes[] = {SHADERTYPE_VERTEX, SHADERTYPE_FRAGMENT};
1291*35238bceSAndroid Build Coastguard Worker
1292*35238bceSAndroid Build Coastguard Worker static const DataType s_countDataType[] = {TYPE_INT, TYPE_FLOAT};
1293*35238bceSAndroid Build Coastguard Worker
1294*35238bceSAndroid Build Coastguard Worker for (int loopType = 0; loopType < LOOPTYPE_LAST; loopType++)
1295*35238bceSAndroid Build Coastguard Worker {
1296*35238bceSAndroid Build Coastguard Worker const char *loopTypeName = getLoopTypeName((LoopType)loopType);
1297*35238bceSAndroid Build Coastguard Worker
1298*35238bceSAndroid Build Coastguard Worker for (int loopCountType = 0; loopCountType < LOOPCOUNT_LAST; loopCountType++)
1299*35238bceSAndroid Build Coastguard Worker {
1300*35238bceSAndroid Build Coastguard Worker const char *loopCountName = getLoopCountTypeName((LoopCountType)loopCountType);
1301*35238bceSAndroid Build Coastguard Worker
1302*35238bceSAndroid Build Coastguard Worker string groupName = string(loopTypeName) + "_" + string(loopCountName) + "_iterations";
1303*35238bceSAndroid Build Coastguard Worker string groupDesc = string("Loop tests with ") + loopCountName + " loop counter.";
1304*35238bceSAndroid Build Coastguard Worker TestCaseGroup *group = new TestCaseGroup(m_context, groupName.c_str(), groupDesc.c_str());
1305*35238bceSAndroid Build Coastguard Worker addChild(group);
1306*35238bceSAndroid Build Coastguard Worker
1307*35238bceSAndroid Build Coastguard Worker // Generic cases.
1308*35238bceSAndroid Build Coastguard Worker
1309*35238bceSAndroid Build Coastguard Worker for (int precision = 0; precision < PRECISION_LAST; precision++)
1310*35238bceSAndroid Build Coastguard Worker {
1311*35238bceSAndroid Build Coastguard Worker const char *precisionName = getPrecisionName((Precision)precision);
1312*35238bceSAndroid Build Coastguard Worker
1313*35238bceSAndroid Build Coastguard Worker for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_countDataType); dataTypeNdx++)
1314*35238bceSAndroid Build Coastguard Worker {
1315*35238bceSAndroid Build Coastguard Worker DataType loopDataType = s_countDataType[dataTypeNdx];
1316*35238bceSAndroid Build Coastguard Worker const char *dataTypeName = getDataTypeName(loopDataType);
1317*35238bceSAndroid Build Coastguard Worker
1318*35238bceSAndroid Build Coastguard Worker for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
1319*35238bceSAndroid Build Coastguard Worker {
1320*35238bceSAndroid Build Coastguard Worker ShaderType shaderType = s_shaderTypes[shaderTypeNdx];
1321*35238bceSAndroid Build Coastguard Worker const char *shaderTypeName = getShaderTypeName(shaderType);
1322*35238bceSAndroid Build Coastguard Worker bool isVertexCase = (shaderType == SHADERTYPE_VERTEX);
1323*35238bceSAndroid Build Coastguard Worker
1324*35238bceSAndroid Build Coastguard Worker string name = string("basic_") + precisionName + "_" + dataTypeName + "_" + shaderTypeName;
1325*35238bceSAndroid Build Coastguard Worker string desc = string(loopTypeName) + " loop with " + precisionName + dataTypeName + " " +
1326*35238bceSAndroid Build Coastguard Worker loopCountName + " iteration count in " + shaderTypeName + " shader.";
1327*35238bceSAndroid Build Coastguard Worker group->addChild(createGenericLoopCase(m_context, name.c_str(), desc.c_str(), isVertexCase,
1328*35238bceSAndroid Build Coastguard Worker (LoopType)loopType, (LoopCountType)loopCountType,
1329*35238bceSAndroid Build Coastguard Worker (Precision)precision, loopDataType));
1330*35238bceSAndroid Build Coastguard Worker }
1331*35238bceSAndroid Build Coastguard Worker }
1332*35238bceSAndroid Build Coastguard Worker }
1333*35238bceSAndroid Build Coastguard Worker
1334*35238bceSAndroid Build Coastguard Worker // Special cases.
1335*35238bceSAndroid Build Coastguard Worker
1336*35238bceSAndroid Build Coastguard Worker for (int loopCase = 0; loopCase < LOOPCASE_LAST; loopCase++)
1337*35238bceSAndroid Build Coastguard Worker {
1338*35238bceSAndroid Build Coastguard Worker const char *loopCaseName = getLoopCaseName((LoopCase)loopCase);
1339*35238bceSAndroid Build Coastguard Worker
1340*35238bceSAndroid Build Coastguard Worker // no-iterations not possible with do-while.
1341*35238bceSAndroid Build Coastguard Worker if ((loopCase == LOOPCASE_NO_ITERATIONS) && (loopType == LOOPTYPE_DO_WHILE))
1342*35238bceSAndroid Build Coastguard Worker continue;
1343*35238bceSAndroid Build Coastguard Worker
1344*35238bceSAndroid Build Coastguard Worker for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
1345*35238bceSAndroid Build Coastguard Worker {
1346*35238bceSAndroid Build Coastguard Worker ShaderType shaderType = s_shaderTypes[shaderTypeNdx];
1347*35238bceSAndroid Build Coastguard Worker const char *shaderTypeName = getShaderTypeName(shaderType);
1348*35238bceSAndroid Build Coastguard Worker bool isVertexCase = (shaderType == SHADERTYPE_VERTEX);
1349*35238bceSAndroid Build Coastguard Worker
1350*35238bceSAndroid Build Coastguard Worker string name = string(loopCaseName) + "_" + shaderTypeName;
1351*35238bceSAndroid Build Coastguard Worker string desc = string(loopCaseName) + " loop with " + loopTypeName + " iteration count in " +
1352*35238bceSAndroid Build Coastguard Worker shaderTypeName + " shader.";
1353*35238bceSAndroid Build Coastguard Worker group->addChild(createSpecialLoopCase(m_context, name.c_str(), desc.c_str(), isVertexCase,
1354*35238bceSAndroid Build Coastguard Worker (LoopCase)loopCase, (LoopType)loopType,
1355*35238bceSAndroid Build Coastguard Worker (LoopCountType)loopCountType));
1356*35238bceSAndroid Build Coastguard Worker }
1357*35238bceSAndroid Build Coastguard Worker }
1358*35238bceSAndroid Build Coastguard Worker }
1359*35238bceSAndroid Build Coastguard Worker }
1360*35238bceSAndroid Build Coastguard Worker
1361*35238bceSAndroid Build Coastguard Worker // Additional smaller handwritten tests.
1362*35238bceSAndroid Build Coastguard Worker const std::vector<tcu::TestNode *> children =
1363*35238bceSAndroid Build Coastguard Worker gls::ShaderLibrary(m_context.getTestContext(), m_context.getRenderContext(), m_context.getContextInfo())
1364*35238bceSAndroid Build Coastguard Worker .loadShaderFile("shaders/loops.test");
1365*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < (int)children.size(); i++)
1366*35238bceSAndroid Build Coastguard Worker addChild(children[i]);
1367*35238bceSAndroid Build Coastguard Worker }
1368*35238bceSAndroid Build Coastguard Worker
1369*35238bceSAndroid Build Coastguard Worker } // namespace Functional
1370*35238bceSAndroid Build Coastguard Worker } // namespace gles2
1371*35238bceSAndroid Build Coastguard Worker } // namespace deqp
1372