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 control statement performance tests.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "es2pShaderControlStatementTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "glsShaderPerformanceCase.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
27*35238bceSAndroid Build Coastguard Worker
28*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
30*35238bceSAndroid Build Coastguard Worker
31*35238bceSAndroid Build Coastguard Worker #include <string>
32*35238bceSAndroid Build Coastguard Worker #include <vector>
33*35238bceSAndroid Build Coastguard Worker
34*35238bceSAndroid Build Coastguard Worker namespace deqp
35*35238bceSAndroid Build Coastguard Worker {
36*35238bceSAndroid Build Coastguard Worker namespace gles2
37*35238bceSAndroid Build Coastguard Worker {
38*35238bceSAndroid Build Coastguard Worker namespace Performance
39*35238bceSAndroid Build Coastguard Worker {
40*35238bceSAndroid Build Coastguard Worker
41*35238bceSAndroid Build Coastguard Worker using namespace gls;
42*35238bceSAndroid Build Coastguard Worker using namespace glw; // GL types
43*35238bceSAndroid Build Coastguard Worker using std::string;
44*35238bceSAndroid Build Coastguard Worker using std::vector;
45*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
46*35238bceSAndroid Build Coastguard Worker using tcu::Vec4;
47*35238bceSAndroid Build Coastguard Worker
48*35238bceSAndroid Build Coastguard Worker // Writes the workload expression used in conditional tests.
writeConditionalWorkload(std::ostringstream & stream,const char * resultName,const char * operandName)49*35238bceSAndroid Build Coastguard Worker static void writeConditionalWorkload(std::ostringstream &stream, const char *resultName, const char *operandName)
50*35238bceSAndroid Build Coastguard Worker {
51*35238bceSAndroid Build Coastguard Worker const int numMultiplications = 64;
52*35238bceSAndroid Build Coastguard Worker
53*35238bceSAndroid Build Coastguard Worker stream << resultName << " = ";
54*35238bceSAndroid Build Coastguard Worker
55*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < numMultiplications; i++)
56*35238bceSAndroid Build Coastguard Worker {
57*35238bceSAndroid Build Coastguard Worker if (i > 0)
58*35238bceSAndroid Build Coastguard Worker stream << "*";
59*35238bceSAndroid Build Coastguard Worker
60*35238bceSAndroid Build Coastguard Worker stream << operandName;
61*35238bceSAndroid Build Coastguard Worker }
62*35238bceSAndroid Build Coastguard Worker
63*35238bceSAndroid Build Coastguard Worker stream << ";";
64*35238bceSAndroid Build Coastguard Worker }
65*35238bceSAndroid Build Coastguard Worker
66*35238bceSAndroid Build Coastguard Worker // Writes the workload expression used in loop tests (one iteration).
writeLoopWorkload(std::ostringstream & stream,const char * resultName,const char * operandName)67*35238bceSAndroid Build Coastguard Worker static void writeLoopWorkload(std::ostringstream &stream, const char *resultName, const char *operandName)
68*35238bceSAndroid Build Coastguard Worker {
69*35238bceSAndroid Build Coastguard Worker const int numMultiplications = 8;
70*35238bceSAndroid Build Coastguard Worker
71*35238bceSAndroid Build Coastguard Worker stream << resultName << " = ";
72*35238bceSAndroid Build Coastguard Worker
73*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < numMultiplications; i++)
74*35238bceSAndroid Build Coastguard Worker {
75*35238bceSAndroid Build Coastguard Worker if (i > 0)
76*35238bceSAndroid Build Coastguard Worker stream << " * ";
77*35238bceSAndroid Build Coastguard Worker
78*35238bceSAndroid Build Coastguard Worker stream << "(" << resultName << " + " << operandName << ")";
79*35238bceSAndroid Build Coastguard Worker }
80*35238bceSAndroid Build Coastguard Worker
81*35238bceSAndroid Build Coastguard Worker stream << ";";
82*35238bceSAndroid Build Coastguard Worker }
83*35238bceSAndroid Build Coastguard Worker
84*35238bceSAndroid Build Coastguard Worker // The type of decision to be made in a conditional expression.
85*35238bceSAndroid Build Coastguard Worker // \note In fragment cases with DECISION_ATTRIBUTE, the value in the expression will actually be a varying.
86*35238bceSAndroid Build Coastguard Worker enum DecisionType
87*35238bceSAndroid Build Coastguard Worker {
88*35238bceSAndroid Build Coastguard Worker DECISION_STATIC = 0,
89*35238bceSAndroid Build Coastguard Worker DECISION_UNIFORM,
90*35238bceSAndroid Build Coastguard Worker DECISION_ATTRIBUTE,
91*35238bceSAndroid Build Coastguard Worker
92*35238bceSAndroid Build Coastguard Worker DECISION_LAST
93*35238bceSAndroid Build Coastguard Worker };
94*35238bceSAndroid Build Coastguard Worker
95*35238bceSAndroid Build Coastguard Worker class ControlStatementCase : public ShaderPerformanceCase
96*35238bceSAndroid Build Coastguard Worker {
97*35238bceSAndroid Build Coastguard Worker public:
ControlStatementCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,gls::PerfCaseType caseType)98*35238bceSAndroid Build Coastguard Worker ControlStatementCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
99*35238bceSAndroid Build Coastguard Worker const char *description, gls::PerfCaseType caseType)
100*35238bceSAndroid Build Coastguard Worker : ShaderPerformanceCase(testCtx, renderCtx, name, description, caseType)
101*35238bceSAndroid Build Coastguard Worker {
102*35238bceSAndroid Build Coastguard Worker }
103*35238bceSAndroid Build Coastguard Worker
init(void)104*35238bceSAndroid Build Coastguard Worker void init(void)
105*35238bceSAndroid Build Coastguard Worker {
106*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << TestLog::Message << "Using additive blending." << TestLog::EndMessage;
107*35238bceSAndroid Build Coastguard Worker ShaderPerformanceCase::init();
108*35238bceSAndroid Build Coastguard Worker }
109*35238bceSAndroid Build Coastguard Worker
setupRenderState(void)110*35238bceSAndroid Build Coastguard Worker void setupRenderState(void)
111*35238bceSAndroid Build Coastguard Worker {
112*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_renderCtx.getFunctions();
113*35238bceSAndroid Build Coastguard Worker
114*35238bceSAndroid Build Coastguard Worker gl.enable(GL_BLEND);
115*35238bceSAndroid Build Coastguard Worker gl.blendEquation(GL_FUNC_ADD);
116*35238bceSAndroid Build Coastguard Worker gl.blendFunc(GL_ONE, GL_ONE);
117*35238bceSAndroid Build Coastguard Worker }
118*35238bceSAndroid Build Coastguard Worker };
119*35238bceSAndroid Build Coastguard Worker
120*35238bceSAndroid Build Coastguard Worker class ConditionalCase : public ControlStatementCase
121*35238bceSAndroid Build Coastguard Worker {
122*35238bceSAndroid Build Coastguard Worker public:
123*35238bceSAndroid Build Coastguard Worker enum BranchResult
124*35238bceSAndroid Build Coastguard Worker {
125*35238bceSAndroid Build Coastguard Worker BRANCH_TRUE = 0,
126*35238bceSAndroid Build Coastguard Worker BRANCH_FALSE,
127*35238bceSAndroid Build Coastguard Worker BRANCH_MIXED,
128*35238bceSAndroid Build Coastguard Worker
129*35238bceSAndroid Build Coastguard Worker BRANCH_LAST
130*35238bceSAndroid Build Coastguard Worker };
131*35238bceSAndroid Build Coastguard Worker
132*35238bceSAndroid Build Coastguard Worker enum WorkloadDivision
133*35238bceSAndroid Build Coastguard Worker {
134*35238bceSAndroid Build Coastguard Worker WORKLOAD_DIVISION_EVEN = 0, //! Both true and false branches contain same amount of computation.
135*35238bceSAndroid Build Coastguard Worker WORKLOAD_DIVISION_TRUE_HEAVY, //! True branch contains more computation.
136*35238bceSAndroid Build Coastguard Worker WORKLOAD_DIVISION_FALSE_HEAVY, //! False branch contains more computation.
137*35238bceSAndroid Build Coastguard Worker
138*35238bceSAndroid Build Coastguard Worker WORKLOAD_DIVISION_LAST
139*35238bceSAndroid Build Coastguard Worker };
140*35238bceSAndroid Build Coastguard Worker
141*35238bceSAndroid Build Coastguard Worker ConditionalCase(Context &context, const char *name, const char *description, DecisionType decisionType,
142*35238bceSAndroid Build Coastguard Worker BranchResult branchType, WorkloadDivision workloadDivision, bool isVertex);
143*35238bceSAndroid Build Coastguard Worker ~ConditionalCase(void);
144*35238bceSAndroid Build Coastguard Worker
145*35238bceSAndroid Build Coastguard Worker void init(void);
146*35238bceSAndroid Build Coastguard Worker void deinit(void);
147*35238bceSAndroid Build Coastguard Worker void setupProgram(uint32_t program);
148*35238bceSAndroid Build Coastguard Worker
149*35238bceSAndroid Build Coastguard Worker private:
150*35238bceSAndroid Build Coastguard Worker DecisionType m_decisionType;
151*35238bceSAndroid Build Coastguard Worker BranchResult m_branchType;
152*35238bceSAndroid Build Coastguard Worker WorkloadDivision m_workloadDivision;
153*35238bceSAndroid Build Coastguard Worker
154*35238bceSAndroid Build Coastguard Worker vector<float>
155*35238bceSAndroid Build Coastguard Worker m_comparisonValueArray; // Will contain per-vertex comparison values if using mixed branch type in vertex case.
156*35238bceSAndroid Build Coastguard Worker uint32_t m_arrayBuffer;
157*35238bceSAndroid Build Coastguard Worker };
158*35238bceSAndroid Build Coastguard Worker
ConditionalCase(Context & context,const char * name,const char * description,DecisionType decisionType,BranchResult branchType,WorkloadDivision workloadDivision,bool isVertex)159*35238bceSAndroid Build Coastguard Worker ConditionalCase::ConditionalCase(Context &context, const char *name, const char *description, DecisionType decisionType,
160*35238bceSAndroid Build Coastguard Worker BranchResult branchType, WorkloadDivision workloadDivision, bool isVertex)
161*35238bceSAndroid Build Coastguard Worker : ControlStatementCase(context.getTestContext(), context.getRenderContext(), name, description,
162*35238bceSAndroid Build Coastguard Worker isVertex ? CASETYPE_VERTEX : CASETYPE_FRAGMENT)
163*35238bceSAndroid Build Coastguard Worker , m_decisionType(decisionType)
164*35238bceSAndroid Build Coastguard Worker , m_branchType(branchType)
165*35238bceSAndroid Build Coastguard Worker , m_workloadDivision(workloadDivision)
166*35238bceSAndroid Build Coastguard Worker , m_arrayBuffer(0)
167*35238bceSAndroid Build Coastguard Worker {
168*35238bceSAndroid Build Coastguard Worker }
169*35238bceSAndroid Build Coastguard Worker
init(void)170*35238bceSAndroid Build Coastguard Worker void ConditionalCase::init(void)
171*35238bceSAndroid Build Coastguard Worker {
172*35238bceSAndroid Build Coastguard Worker bool isVertexCase = m_caseType == CASETYPE_VERTEX;
173*35238bceSAndroid Build Coastguard Worker
174*35238bceSAndroid Build Coastguard Worker bool isStaticCase = m_decisionType == DECISION_STATIC;
175*35238bceSAndroid Build Coastguard Worker bool isUniformCase = m_decisionType == DECISION_UNIFORM;
176*35238bceSAndroid Build Coastguard Worker bool isAttributeCase = m_decisionType == DECISION_ATTRIBUTE;
177*35238bceSAndroid Build Coastguard Worker
178*35238bceSAndroid Build Coastguard Worker DE_ASSERT(isStaticCase || isUniformCase || isAttributeCase);
179*35238bceSAndroid Build Coastguard Worker
180*35238bceSAndroid Build Coastguard Worker bool isConditionTrue = m_branchType == BRANCH_TRUE;
181*35238bceSAndroid Build Coastguard Worker bool isConditionFalse = m_branchType == BRANCH_FALSE;
182*35238bceSAndroid Build Coastguard Worker bool isConditionMixed = m_branchType == BRANCH_MIXED;
183*35238bceSAndroid Build Coastguard Worker
184*35238bceSAndroid Build Coastguard Worker DE_ASSERT(isConditionTrue || isConditionFalse || isConditionMixed);
185*35238bceSAndroid Build Coastguard Worker DE_UNREF(isConditionFalse);
186*35238bceSAndroid Build Coastguard Worker
187*35238bceSAndroid Build Coastguard Worker DE_ASSERT(isAttributeCase ||
188*35238bceSAndroid Build Coastguard Worker !isConditionMixed); // The branch taken can vary between executions only if using attribute input.
189*35238bceSAndroid Build Coastguard Worker
190*35238bceSAndroid Build Coastguard Worker const char *staticCompareValueStr = isConditionTrue ? "1.0" : "-1.0";
191*35238bceSAndroid Build Coastguard Worker const char *compareValueStr = isStaticCase ? staticCompareValueStr :
192*35238bceSAndroid Build Coastguard Worker isUniformCase ? "u_compareValue" :
193*35238bceSAndroid Build Coastguard Worker isVertexCase ? "a_compareValue" :
194*35238bceSAndroid Build Coastguard Worker "v_compareValue";
195*35238bceSAndroid Build Coastguard Worker
196*35238bceSAndroid Build Coastguard Worker std::ostringstream vtx;
197*35238bceSAndroid Build Coastguard Worker std::ostringstream frag;
198*35238bceSAndroid Build Coastguard Worker std::ostringstream &op = isVertexCase ? vtx : frag;
199*35238bceSAndroid Build Coastguard Worker
200*35238bceSAndroid Build Coastguard Worker vtx << "attribute highp vec4 a_position;\n"; // Position attribute.
201*35238bceSAndroid Build Coastguard Worker vtx << "attribute mediump vec4 a_value0;\n"; // Input for workload calculations of "true" branch.
202*35238bceSAndroid Build Coastguard Worker vtx << "attribute mediump vec4 a_value1;\n"; // Input for workload calculations of "false" branch.
203*35238bceSAndroid Build Coastguard Worker
204*35238bceSAndroid Build Coastguard Worker // Value to be used in the conditional expression.
205*35238bceSAndroid Build Coastguard Worker if (isAttributeCase)
206*35238bceSAndroid Build Coastguard Worker vtx << "attribute mediump float a_compareValue;\n";
207*35238bceSAndroid Build Coastguard Worker else if (isUniformCase)
208*35238bceSAndroid Build Coastguard Worker op << "uniform mediump float u_compareValue;\n";
209*35238bceSAndroid Build Coastguard Worker
210*35238bceSAndroid Build Coastguard Worker // Varyings.
211*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
212*35238bceSAndroid Build Coastguard Worker {
213*35238bceSAndroid Build Coastguard Worker vtx << "varying mediump vec4 v_color;\n";
214*35238bceSAndroid Build Coastguard Worker frag << "varying mediump vec4 v_color;\n";
215*35238bceSAndroid Build Coastguard Worker }
216*35238bceSAndroid Build Coastguard Worker else
217*35238bceSAndroid Build Coastguard Worker {
218*35238bceSAndroid Build Coastguard Worker vtx << "varying mediump vec4 v_value0;\n";
219*35238bceSAndroid Build Coastguard Worker vtx << "varying mediump vec4 v_value1;\n";
220*35238bceSAndroid Build Coastguard Worker frag << "varying mediump vec4 v_value0;\n";
221*35238bceSAndroid Build Coastguard Worker frag << "varying mediump vec4 v_value1;\n";
222*35238bceSAndroid Build Coastguard Worker
223*35238bceSAndroid Build Coastguard Worker if (isAttributeCase)
224*35238bceSAndroid Build Coastguard Worker {
225*35238bceSAndroid Build Coastguard Worker vtx << "varying mediump float v_compareValue;\n";
226*35238bceSAndroid Build Coastguard Worker frag << "varying mediump float v_compareValue;\n";
227*35238bceSAndroid Build Coastguard Worker }
228*35238bceSAndroid Build Coastguard Worker }
229*35238bceSAndroid Build Coastguard Worker
230*35238bceSAndroid Build Coastguard Worker vtx << "\n";
231*35238bceSAndroid Build Coastguard Worker vtx << "void main()\n";
232*35238bceSAndroid Build Coastguard Worker vtx << "{\n";
233*35238bceSAndroid Build Coastguard Worker vtx << " gl_Position = a_position;\n";
234*35238bceSAndroid Build Coastguard Worker
235*35238bceSAndroid Build Coastguard Worker frag << "\n";
236*35238bceSAndroid Build Coastguard Worker frag << "void main()\n";
237*35238bceSAndroid Build Coastguard Worker frag << "{\n";
238*35238bceSAndroid Build Coastguard Worker
239*35238bceSAndroid Build Coastguard Worker op << " mediump vec4 res;\n";
240*35238bceSAndroid Build Coastguard Worker
241*35238bceSAndroid Build Coastguard Worker string condition;
242*35238bceSAndroid Build Coastguard Worker
243*35238bceSAndroid Build Coastguard Worker if (isConditionMixed && !isVertexCase)
244*35238bceSAndroid Build Coastguard Worker condition =
245*35238bceSAndroid Build Coastguard Worker string("") + "fract(" + compareValueStr + ") < 0.5"; // Comparison result varies with high frequency.
246*35238bceSAndroid Build Coastguard Worker else
247*35238bceSAndroid Build Coastguard Worker condition = string("") + compareValueStr + " > 0.0";
248*35238bceSAndroid Build Coastguard Worker
249*35238bceSAndroid Build Coastguard Worker op << " if (" << condition << ")\n";
250*35238bceSAndroid Build Coastguard Worker op << " {\n";
251*35238bceSAndroid Build Coastguard Worker
252*35238bceSAndroid Build Coastguard Worker op << "\t\t";
253*35238bceSAndroid Build Coastguard Worker if (m_workloadDivision == WORKLOAD_DIVISION_EVEN || m_workloadDivision == WORKLOAD_DIVISION_TRUE_HEAVY)
254*35238bceSAndroid Build Coastguard Worker writeConditionalWorkload(op, "res",
255*35238bceSAndroid Build Coastguard Worker isVertexCase ? "a_value0" : "v_value0"); // Workload calculation for the "true" branch.
256*35238bceSAndroid Build Coastguard Worker else
257*35238bceSAndroid Build Coastguard Worker op << "res = " << (isVertexCase ? "a_value0" : "v_value0") << ";";
258*35238bceSAndroid Build Coastguard Worker op << "\n";
259*35238bceSAndroid Build Coastguard Worker
260*35238bceSAndroid Build Coastguard Worker op << " }\n";
261*35238bceSAndroid Build Coastguard Worker op << " else\n";
262*35238bceSAndroid Build Coastguard Worker op << " {\n";
263*35238bceSAndroid Build Coastguard Worker
264*35238bceSAndroid Build Coastguard Worker op << "\t\t";
265*35238bceSAndroid Build Coastguard Worker if (m_workloadDivision == WORKLOAD_DIVISION_EVEN || m_workloadDivision == WORKLOAD_DIVISION_FALSE_HEAVY)
266*35238bceSAndroid Build Coastguard Worker writeConditionalWorkload(
267*35238bceSAndroid Build Coastguard Worker op, "res", isVertexCase ? "a_value1" : "v_value1"); // Workload calculations for the "false" branch.
268*35238bceSAndroid Build Coastguard Worker else
269*35238bceSAndroid Build Coastguard Worker op << "res = " << (isVertexCase ? "a_value1" : "v_value1") << ";";
270*35238bceSAndroid Build Coastguard Worker op << "\n";
271*35238bceSAndroid Build Coastguard Worker
272*35238bceSAndroid Build Coastguard Worker op << " }\n";
273*35238bceSAndroid Build Coastguard Worker
274*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
275*35238bceSAndroid Build Coastguard Worker {
276*35238bceSAndroid Build Coastguard Worker // Put result to color variable.
277*35238bceSAndroid Build Coastguard Worker vtx << " v_color = res;\n";
278*35238bceSAndroid Build Coastguard Worker frag << " gl_FragColor = v_color;\n";
279*35238bceSAndroid Build Coastguard Worker }
280*35238bceSAndroid Build Coastguard Worker else
281*35238bceSAndroid Build Coastguard Worker {
282*35238bceSAndroid Build Coastguard Worker // Transfer inputs to fragment shader through varyings.
283*35238bceSAndroid Build Coastguard Worker if (isAttributeCase)
284*35238bceSAndroid Build Coastguard Worker vtx << " v_compareValue = a_compareValue;\n";
285*35238bceSAndroid Build Coastguard Worker vtx << " v_value0 = a_value0;\n";
286*35238bceSAndroid Build Coastguard Worker vtx << " v_value1 = a_value1;\n";
287*35238bceSAndroid Build Coastguard Worker
288*35238bceSAndroid Build Coastguard Worker frag << " gl_FragColor = res;\n"; // Put result to color variable.
289*35238bceSAndroid Build Coastguard Worker }
290*35238bceSAndroid Build Coastguard Worker
291*35238bceSAndroid Build Coastguard Worker vtx << "}\n";
292*35238bceSAndroid Build Coastguard Worker frag << "}\n";
293*35238bceSAndroid Build Coastguard Worker
294*35238bceSAndroid Build Coastguard Worker m_vertShaderSource = vtx.str();
295*35238bceSAndroid Build Coastguard Worker m_fragShaderSource = frag.str();
296*35238bceSAndroid Build Coastguard Worker
297*35238bceSAndroid Build Coastguard Worker if (isAttributeCase)
298*35238bceSAndroid Build Coastguard Worker {
299*35238bceSAndroid Build Coastguard Worker if (!isConditionMixed)
300*35238bceSAndroid Build Coastguard Worker {
301*35238bceSAndroid Build Coastguard Worker // Every execution takes the same branch.
302*35238bceSAndroid Build Coastguard Worker
303*35238bceSAndroid Build Coastguard Worker float value = isConditionTrue ? +1.0f : -1.0f;
304*35238bceSAndroid Build Coastguard Worker m_attributes.push_back(AttribSpec("a_compareValue", Vec4(value, 0.0f, 0.0f, 0.0f),
305*35238bceSAndroid Build Coastguard Worker Vec4(value, 0.0f, 0.0f, 0.0f), Vec4(value, 0.0f, 0.0f, 0.0f),
306*35238bceSAndroid Build Coastguard Worker Vec4(value, 0.0f, 0.0f, 0.0f)));
307*35238bceSAndroid Build Coastguard Worker }
308*35238bceSAndroid Build Coastguard Worker else if (isVertexCase)
309*35238bceSAndroid Build Coastguard Worker {
310*35238bceSAndroid Build Coastguard Worker // Vertex case, not every execution takes the same branch.
311*35238bceSAndroid Build Coastguard Worker
312*35238bceSAndroid Build Coastguard Worker const int numComponents = 4;
313*35238bceSAndroid Build Coastguard Worker int numVertices = (getGridWidth() + 1) * (getGridHeight() + 1);
314*35238bceSAndroid Build Coastguard Worker
315*35238bceSAndroid Build Coastguard Worker // setupProgram() will later bind this array as an attribute.
316*35238bceSAndroid Build Coastguard Worker m_comparisonValueArray.resize(numVertices * numComponents);
317*35238bceSAndroid Build Coastguard Worker
318*35238bceSAndroid Build Coastguard Worker // Make every second vertex take the true branch, and every second the false branch.
319*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < (int)m_comparisonValueArray.size(); i++)
320*35238bceSAndroid Build Coastguard Worker {
321*35238bceSAndroid Build Coastguard Worker if (i % numComponents == 0)
322*35238bceSAndroid Build Coastguard Worker m_comparisonValueArray[i] = (i / numComponents) % 2 == 0 ? +1.0f : -1.0f;
323*35238bceSAndroid Build Coastguard Worker else
324*35238bceSAndroid Build Coastguard Worker m_comparisonValueArray[i] = 0.0f;
325*35238bceSAndroid Build Coastguard Worker }
326*35238bceSAndroid Build Coastguard Worker }
327*35238bceSAndroid Build Coastguard Worker else // isConditionMixed && !isVertexCase
328*35238bceSAndroid Build Coastguard Worker {
329*35238bceSAndroid Build Coastguard Worker // Fragment case, not every execution takes the same branch.
330*35238bceSAndroid Build Coastguard Worker // \note fract(a_compareValue) < 0.5 will be true for every second column of fragments.
331*35238bceSAndroid Build Coastguard Worker
332*35238bceSAndroid Build Coastguard Worker float minValue = 0.0f;
333*35238bceSAndroid Build Coastguard Worker float maxValue = (float)getViewportWidth() * 0.5f;
334*35238bceSAndroid Build Coastguard Worker m_attributes.push_back(AttribSpec("a_compareValue", Vec4(minValue, 0.0f, 0.0f, 0.0f),
335*35238bceSAndroid Build Coastguard Worker Vec4(maxValue, 0.0f, 0.0f, 0.0f), Vec4(minValue, 0.0f, 0.0f, 0.0f),
336*35238bceSAndroid Build Coastguard Worker Vec4(maxValue, 0.0f, 0.0f, 0.0f)));
337*35238bceSAndroid Build Coastguard Worker }
338*35238bceSAndroid Build Coastguard Worker }
339*35238bceSAndroid Build Coastguard Worker
340*35238bceSAndroid Build Coastguard Worker m_attributes.push_back(AttribSpec("a_value0", Vec4(0.0f, 0.1f, 0.2f, 0.3f), Vec4(0.4f, 0.5f, 0.6f, 0.7f),
341*35238bceSAndroid Build Coastguard Worker Vec4(0.8f, 0.9f, 1.0f, 1.1f), Vec4(1.2f, 1.3f, 1.4f, 1.5f)));
342*35238bceSAndroid Build Coastguard Worker
343*35238bceSAndroid Build Coastguard Worker m_attributes.push_back(AttribSpec("a_value1", Vec4(0.0f, 0.1f, 0.2f, 0.3f), Vec4(0.4f, 0.5f, 0.6f, 0.7f),
344*35238bceSAndroid Build Coastguard Worker Vec4(0.8f, 0.9f, 1.0f, 1.1f), Vec4(1.2f, 1.3f, 1.4f, 1.5f)));
345*35238bceSAndroid Build Coastguard Worker
346*35238bceSAndroid Build Coastguard Worker ControlStatementCase::init();
347*35238bceSAndroid Build Coastguard Worker }
348*35238bceSAndroid Build Coastguard Worker
setupProgram(uint32_t program)349*35238bceSAndroid Build Coastguard Worker void ConditionalCase::setupProgram(uint32_t program)
350*35238bceSAndroid Build Coastguard Worker {
351*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_renderCtx.getFunctions();
352*35238bceSAndroid Build Coastguard Worker
353*35238bceSAndroid Build Coastguard Worker if (m_decisionType == DECISION_UNIFORM)
354*35238bceSAndroid Build Coastguard Worker {
355*35238bceSAndroid Build Coastguard Worker int location = gl.getUniformLocation(program, "u_compareValue");
356*35238bceSAndroid Build Coastguard Worker gl.uniform1f(location, m_branchType == BRANCH_TRUE ? +1.0f : -1.0f);
357*35238bceSAndroid Build Coastguard Worker }
358*35238bceSAndroid Build Coastguard Worker else if (m_decisionType == DECISION_ATTRIBUTE && m_branchType == BRANCH_MIXED && m_caseType == CASETYPE_VERTEX)
359*35238bceSAndroid Build Coastguard Worker {
360*35238bceSAndroid Build Coastguard Worker // Setup per-vertex comparison values calculated in init().
361*35238bceSAndroid Build Coastguard Worker
362*35238bceSAndroid Build Coastguard Worker const int numComponents = 4;
363*35238bceSAndroid Build Coastguard Worker int compareAttribLocation = gl.getAttribLocation(program, "a_compareValue");
364*35238bceSAndroid Build Coastguard Worker
365*35238bceSAndroid Build Coastguard Worker DE_ASSERT((int)m_comparisonValueArray.size() == numComponents * (getGridWidth() + 1) * (getGridHeight() + 1));
366*35238bceSAndroid Build Coastguard Worker
367*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &m_arrayBuffer);
368*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, m_arrayBuffer);
369*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(m_comparisonValueArray.size() * sizeof(float)),
370*35238bceSAndroid Build Coastguard Worker &m_comparisonValueArray[0], GL_STATIC_DRAW);
371*35238bceSAndroid Build Coastguard Worker gl.enableVertexAttribArray(compareAttribLocation);
372*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(compareAttribLocation, (GLint)numComponents, GL_FLOAT, GL_FALSE, 0, DE_NULL);
373*35238bceSAndroid Build Coastguard Worker }
374*35238bceSAndroid Build Coastguard Worker
375*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Setup program state");
376*35238bceSAndroid Build Coastguard Worker }
377*35238bceSAndroid Build Coastguard Worker
~ConditionalCase(void)378*35238bceSAndroid Build Coastguard Worker ConditionalCase::~ConditionalCase(void)
379*35238bceSAndroid Build Coastguard Worker {
380*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_renderCtx.getFunctions();
381*35238bceSAndroid Build Coastguard Worker
382*35238bceSAndroid Build Coastguard Worker if (m_arrayBuffer != 0)
383*35238bceSAndroid Build Coastguard Worker {
384*35238bceSAndroid Build Coastguard Worker gl.deleteBuffers(1, &m_arrayBuffer);
385*35238bceSAndroid Build Coastguard Worker m_arrayBuffer = 0;
386*35238bceSAndroid Build Coastguard Worker }
387*35238bceSAndroid Build Coastguard Worker }
388*35238bceSAndroid Build Coastguard Worker
deinit(void)389*35238bceSAndroid Build Coastguard Worker void ConditionalCase::deinit(void)
390*35238bceSAndroid Build Coastguard Worker {
391*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_renderCtx.getFunctions();
392*35238bceSAndroid Build Coastguard Worker
393*35238bceSAndroid Build Coastguard Worker m_comparisonValueArray.clear();
394*35238bceSAndroid Build Coastguard Worker
395*35238bceSAndroid Build Coastguard Worker if (m_arrayBuffer != 0)
396*35238bceSAndroid Build Coastguard Worker {
397*35238bceSAndroid Build Coastguard Worker gl.deleteBuffers(1, &m_arrayBuffer);
398*35238bceSAndroid Build Coastguard Worker m_arrayBuffer = 0;
399*35238bceSAndroid Build Coastguard Worker }
400*35238bceSAndroid Build Coastguard Worker
401*35238bceSAndroid Build Coastguard Worker ShaderPerformanceCase::deinit();
402*35238bceSAndroid Build Coastguard Worker }
403*35238bceSAndroid Build Coastguard Worker
404*35238bceSAndroid Build Coastguard Worker class LoopCase : public ControlStatementCase
405*35238bceSAndroid Build Coastguard Worker {
406*35238bceSAndroid Build Coastguard Worker public:
407*35238bceSAndroid Build Coastguard Worker enum LoopType
408*35238bceSAndroid Build Coastguard Worker {
409*35238bceSAndroid Build Coastguard Worker LOOP_FOR = 0,
410*35238bceSAndroid Build Coastguard Worker LOOP_WHILE,
411*35238bceSAndroid Build Coastguard Worker LOOP_DO_WHILE,
412*35238bceSAndroid Build Coastguard Worker
413*35238bceSAndroid Build Coastguard Worker LOOP_LAST
414*35238bceSAndroid Build Coastguard Worker };
415*35238bceSAndroid Build Coastguard Worker LoopCase(Context &context, const char *name, const char *description, LoopType type, DecisionType decisionType,
416*35238bceSAndroid Build Coastguard Worker bool isLoopBoundStable, bool isVertex);
417*35238bceSAndroid Build Coastguard Worker ~LoopCase(void);
418*35238bceSAndroid Build Coastguard Worker
419*35238bceSAndroid Build Coastguard Worker void init(void);
420*35238bceSAndroid Build Coastguard Worker void deinit(void);
421*35238bceSAndroid Build Coastguard Worker void setupProgram(uint32_t program);
422*35238bceSAndroid Build Coastguard Worker
423*35238bceSAndroid Build Coastguard Worker private:
424*35238bceSAndroid Build Coastguard Worker DecisionType m_decisionType;
425*35238bceSAndroid Build Coastguard Worker LoopType m_type;
426*35238bceSAndroid Build Coastguard Worker
427*35238bceSAndroid Build Coastguard Worker bool m_isLoopBoundStable; // Whether loop bound is same in all executions.
428*35238bceSAndroid Build Coastguard Worker vector<float> m_boundArray; // Will contain per-vertex loop bounds if using non-stable attribute in vertex case.
429*35238bceSAndroid Build Coastguard Worker uint32_t m_arrayBuffer;
430*35238bceSAndroid Build Coastguard Worker };
431*35238bceSAndroid Build Coastguard Worker
LoopCase(Context & context,const char * name,const char * description,LoopType type,DecisionType decisionType,bool isLoopBoundStable,bool isVertex)432*35238bceSAndroid Build Coastguard Worker LoopCase::LoopCase(Context &context, const char *name, const char *description, LoopType type,
433*35238bceSAndroid Build Coastguard Worker DecisionType decisionType, bool isLoopBoundStable, bool isVertex)
434*35238bceSAndroid Build Coastguard Worker : ControlStatementCase(context.getTestContext(), context.getRenderContext(), name, description,
435*35238bceSAndroid Build Coastguard Worker isVertex ? CASETYPE_VERTEX : CASETYPE_FRAGMENT)
436*35238bceSAndroid Build Coastguard Worker , m_decisionType(decisionType)
437*35238bceSAndroid Build Coastguard Worker , m_type(type)
438*35238bceSAndroid Build Coastguard Worker , m_isLoopBoundStable(isLoopBoundStable)
439*35238bceSAndroid Build Coastguard Worker , m_arrayBuffer(0)
440*35238bceSAndroid Build Coastguard Worker {
441*35238bceSAndroid Build Coastguard Worker }
442*35238bceSAndroid Build Coastguard Worker
init(void)443*35238bceSAndroid Build Coastguard Worker void LoopCase::init(void)
444*35238bceSAndroid Build Coastguard Worker {
445*35238bceSAndroid Build Coastguard Worker bool isVertexCase = m_caseType == CASETYPE_VERTEX;
446*35238bceSAndroid Build Coastguard Worker
447*35238bceSAndroid Build Coastguard Worker bool isStaticCase = m_decisionType == DECISION_STATIC;
448*35238bceSAndroid Build Coastguard Worker bool isUniformCase = m_decisionType == DECISION_UNIFORM;
449*35238bceSAndroid Build Coastguard Worker bool isAttributeCase = m_decisionType == DECISION_ATTRIBUTE;
450*35238bceSAndroid Build Coastguard Worker
451*35238bceSAndroid Build Coastguard Worker DE_ASSERT(isStaticCase || isUniformCase || isAttributeCase);
452*35238bceSAndroid Build Coastguard Worker
453*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_type == LOOP_FOR || m_type == LOOP_WHILE || m_type == LOOP_DO_WHILE);
454*35238bceSAndroid Build Coastguard Worker
455*35238bceSAndroid Build Coastguard Worker DE_ASSERT(isAttributeCase ||
456*35238bceSAndroid Build Coastguard Worker m_isLoopBoundStable); // The loop bound count can vary between executions only if using attribute input.
457*35238bceSAndroid Build Coastguard Worker
458*35238bceSAndroid Build Coastguard Worker // \note The fractional part is .5 (instead of .0) so that these can be safely used as loop bounds.
459*35238bceSAndroid Build Coastguard Worker const float loopBound = 10.5f;
460*35238bceSAndroid Build Coastguard Worker const float unstableBoundLow = 5.5f;
461*35238bceSAndroid Build Coastguard Worker const float unstableBoundHigh = 15.5f;
462*35238bceSAndroid Build Coastguard Worker static const char *loopBoundStr = "10.5";
463*35238bceSAndroid Build Coastguard Worker static const char *unstableBoundLowStr = "5.5";
464*35238bceSAndroid Build Coastguard Worker static const char *unstableBoundHighStr = "15.5";
465*35238bceSAndroid Build Coastguard Worker
466*35238bceSAndroid Build Coastguard Worker const char *boundValueStr = isStaticCase ? loopBoundStr :
467*35238bceSAndroid Build Coastguard Worker isUniformCase ? "u_bound" :
468*35238bceSAndroid Build Coastguard Worker isVertexCase ? "a_bound" :
469*35238bceSAndroid Build Coastguard Worker m_isLoopBoundStable ? "v_bound" :
470*35238bceSAndroid Build Coastguard Worker "loopBound";
471*35238bceSAndroid Build Coastguard Worker
472*35238bceSAndroid Build Coastguard Worker std::ostringstream vtx;
473*35238bceSAndroid Build Coastguard Worker std::ostringstream frag;
474*35238bceSAndroid Build Coastguard Worker std::ostringstream &op = isVertexCase ? vtx : frag;
475*35238bceSAndroid Build Coastguard Worker
476*35238bceSAndroid Build Coastguard Worker vtx << "attribute highp vec4 a_position;\n"; // Position attribute.
477*35238bceSAndroid Build Coastguard Worker vtx << "attribute mediump vec4 a_value;\n"; // Input for workload calculations.
478*35238bceSAndroid Build Coastguard Worker
479*35238bceSAndroid Build Coastguard Worker // Value to be used as the loop iteration count.
480*35238bceSAndroid Build Coastguard Worker if (isAttributeCase)
481*35238bceSAndroid Build Coastguard Worker vtx << "attribute mediump float a_bound;\n";
482*35238bceSAndroid Build Coastguard Worker else if (isUniformCase)
483*35238bceSAndroid Build Coastguard Worker op << "uniform mediump float u_bound;\n";
484*35238bceSAndroid Build Coastguard Worker
485*35238bceSAndroid Build Coastguard Worker // Varyings.
486*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
487*35238bceSAndroid Build Coastguard Worker {
488*35238bceSAndroid Build Coastguard Worker vtx << "varying mediump vec4 v_color;\n";
489*35238bceSAndroid Build Coastguard Worker frag << "varying mediump vec4 v_color;\n";
490*35238bceSAndroid Build Coastguard Worker }
491*35238bceSAndroid Build Coastguard Worker else
492*35238bceSAndroid Build Coastguard Worker {
493*35238bceSAndroid Build Coastguard Worker vtx << "varying mediump vec4 v_value;\n";
494*35238bceSAndroid Build Coastguard Worker frag << "varying mediump vec4 v_value;\n";
495*35238bceSAndroid Build Coastguard Worker
496*35238bceSAndroid Build Coastguard Worker if (isAttributeCase)
497*35238bceSAndroid Build Coastguard Worker {
498*35238bceSAndroid Build Coastguard Worker vtx << "varying mediump float v_bound;\n";
499*35238bceSAndroid Build Coastguard Worker frag << "varying mediump float v_bound;\n";
500*35238bceSAndroid Build Coastguard Worker }
501*35238bceSAndroid Build Coastguard Worker }
502*35238bceSAndroid Build Coastguard Worker
503*35238bceSAndroid Build Coastguard Worker vtx << "\n";
504*35238bceSAndroid Build Coastguard Worker vtx << "void main()\n";
505*35238bceSAndroid Build Coastguard Worker vtx << "{\n";
506*35238bceSAndroid Build Coastguard Worker vtx << " gl_Position = a_position;\n";
507*35238bceSAndroid Build Coastguard Worker
508*35238bceSAndroid Build Coastguard Worker frag << "\n";
509*35238bceSAndroid Build Coastguard Worker frag << "void main()\n";
510*35238bceSAndroid Build Coastguard Worker frag << "{\n";
511*35238bceSAndroid Build Coastguard Worker
512*35238bceSAndroid Build Coastguard Worker op << " mediump vec4 res = vec4(0.0);\n";
513*35238bceSAndroid Build Coastguard Worker
514*35238bceSAndroid Build Coastguard Worker if (!m_isLoopBoundStable && !isVertexCase)
515*35238bceSAndroid Build Coastguard Worker {
516*35238bceSAndroid Build Coastguard Worker // Choose the actual loop bound based on v_bound.
517*35238bceSAndroid Build Coastguard Worker // \note Loop bound will vary with high frequency between fragment columns, given appropriate range for v_bound.
518*35238bceSAndroid Build Coastguard Worker op << " mediump float loopBound = fract(v_bound) < 0.5 ? " << unstableBoundLowStr << " : "
519*35238bceSAndroid Build Coastguard Worker << unstableBoundHighStr << ";\n";
520*35238bceSAndroid Build Coastguard Worker }
521*35238bceSAndroid Build Coastguard Worker
522*35238bceSAndroid Build Coastguard Worker // Start a for, while or do-while loop.
523*35238bceSAndroid Build Coastguard Worker if (m_type == LOOP_FOR)
524*35238bceSAndroid Build Coastguard Worker op << " for (mediump float i = 0.0; i < " << boundValueStr << "; i++)\n";
525*35238bceSAndroid Build Coastguard Worker else
526*35238bceSAndroid Build Coastguard Worker {
527*35238bceSAndroid Build Coastguard Worker op << " mediump float i = 0.0;\n";
528*35238bceSAndroid Build Coastguard Worker if (m_type == LOOP_WHILE)
529*35238bceSAndroid Build Coastguard Worker op << " while (i < " << boundValueStr << ")\n";
530*35238bceSAndroid Build Coastguard Worker else // LOOP_DO_WHILE
531*35238bceSAndroid Build Coastguard Worker op << " do\n";
532*35238bceSAndroid Build Coastguard Worker }
533*35238bceSAndroid Build Coastguard Worker op << " {\n";
534*35238bceSAndroid Build Coastguard Worker
535*35238bceSAndroid Build Coastguard Worker // Workload calculations inside the loop.
536*35238bceSAndroid Build Coastguard Worker op << "\t\t";
537*35238bceSAndroid Build Coastguard Worker writeLoopWorkload(op, "res", isVertexCase ? "a_value" : "v_value");
538*35238bceSAndroid Build Coastguard Worker op << "\n";
539*35238bceSAndroid Build Coastguard Worker
540*35238bceSAndroid Build Coastguard Worker // Only "for" has counter increment in the loop head.
541*35238bceSAndroid Build Coastguard Worker if (m_type != LOOP_FOR)
542*35238bceSAndroid Build Coastguard Worker op << " i++;\n";
543*35238bceSAndroid Build Coastguard Worker
544*35238bceSAndroid Build Coastguard Worker // End the loop.
545*35238bceSAndroid Build Coastguard Worker if (m_type == LOOP_DO_WHILE)
546*35238bceSAndroid Build Coastguard Worker op << " } while (i < " << boundValueStr << ");\n";
547*35238bceSAndroid Build Coastguard Worker else
548*35238bceSAndroid Build Coastguard Worker op << " }\n";
549*35238bceSAndroid Build Coastguard Worker
550*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
551*35238bceSAndroid Build Coastguard Worker {
552*35238bceSAndroid Build Coastguard Worker // Put result to color variable.
553*35238bceSAndroid Build Coastguard Worker vtx << " v_color = res;\n";
554*35238bceSAndroid Build Coastguard Worker frag << " gl_FragColor = v_color;\n";
555*35238bceSAndroid Build Coastguard Worker }
556*35238bceSAndroid Build Coastguard Worker else
557*35238bceSAndroid Build Coastguard Worker {
558*35238bceSAndroid Build Coastguard Worker // Transfer inputs to fragment shader through varyings.
559*35238bceSAndroid Build Coastguard Worker if (isAttributeCase)
560*35238bceSAndroid Build Coastguard Worker vtx << " v_bound = a_bound;\n";
561*35238bceSAndroid Build Coastguard Worker vtx << " v_value = a_value;\n";
562*35238bceSAndroid Build Coastguard Worker
563*35238bceSAndroid Build Coastguard Worker frag << " gl_FragColor = res;\n"; // Put result to color variable.
564*35238bceSAndroid Build Coastguard Worker }
565*35238bceSAndroid Build Coastguard Worker
566*35238bceSAndroid Build Coastguard Worker vtx << "}\n";
567*35238bceSAndroid Build Coastguard Worker frag << "}\n";
568*35238bceSAndroid Build Coastguard Worker
569*35238bceSAndroid Build Coastguard Worker m_vertShaderSource = vtx.str();
570*35238bceSAndroid Build Coastguard Worker m_fragShaderSource = frag.str();
571*35238bceSAndroid Build Coastguard Worker
572*35238bceSAndroid Build Coastguard Worker if (isAttributeCase)
573*35238bceSAndroid Build Coastguard Worker {
574*35238bceSAndroid Build Coastguard Worker if (m_isLoopBoundStable)
575*35238bceSAndroid Build Coastguard Worker {
576*35238bceSAndroid Build Coastguard Worker // Every execution has same number of iterations.
577*35238bceSAndroid Build Coastguard Worker
578*35238bceSAndroid Build Coastguard Worker m_attributes.push_back(AttribSpec("a_bound", Vec4(loopBound, 0.0f, 0.0f, 0.0f),
579*35238bceSAndroid Build Coastguard Worker Vec4(loopBound, 0.0f, 0.0f, 0.0f), Vec4(loopBound, 0.0f, 0.0f, 0.0f),
580*35238bceSAndroid Build Coastguard Worker Vec4(loopBound, 0.0f, 0.0f, 0.0f)));
581*35238bceSAndroid Build Coastguard Worker }
582*35238bceSAndroid Build Coastguard Worker else if (isVertexCase)
583*35238bceSAndroid Build Coastguard Worker {
584*35238bceSAndroid Build Coastguard Worker // Vertex case, with non-constant number of iterations.
585*35238bceSAndroid Build Coastguard Worker
586*35238bceSAndroid Build Coastguard Worker const int numComponents = 4;
587*35238bceSAndroid Build Coastguard Worker int numVertices = (getGridWidth() + 1) * (getGridHeight() + 1);
588*35238bceSAndroid Build Coastguard Worker
589*35238bceSAndroid Build Coastguard Worker // setupProgram() will later bind this array as an attribute.
590*35238bceSAndroid Build Coastguard Worker m_boundArray.resize(numVertices * numComponents);
591*35238bceSAndroid Build Coastguard Worker
592*35238bceSAndroid Build Coastguard Worker // Vary between low and high loop bounds; they should average to loopBound however.
593*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < (int)m_boundArray.size(); i++)
594*35238bceSAndroid Build Coastguard Worker {
595*35238bceSAndroid Build Coastguard Worker if (i % numComponents == 0)
596*35238bceSAndroid Build Coastguard Worker m_boundArray[i] = (i / numComponents) % 2 == 0 ? unstableBoundLow : unstableBoundHigh;
597*35238bceSAndroid Build Coastguard Worker else
598*35238bceSAndroid Build Coastguard Worker m_boundArray[i] = 0.0f;
599*35238bceSAndroid Build Coastguard Worker }
600*35238bceSAndroid Build Coastguard Worker }
601*35238bceSAndroid Build Coastguard Worker else // !m_isLoopBoundStable && !isVertexCase
602*35238bceSAndroid Build Coastguard Worker {
603*35238bceSAndroid Build Coastguard Worker // Fragment case, with non-constant number of iterations.
604*35238bceSAndroid Build Coastguard Worker // \note fract(a_bound) < 0.5 will be true for every second fragment.
605*35238bceSAndroid Build Coastguard Worker
606*35238bceSAndroid Build Coastguard Worker float minValue = 0.0f;
607*35238bceSAndroid Build Coastguard Worker float maxValue = (float)getViewportWidth() * 0.5f;
608*35238bceSAndroid Build Coastguard Worker m_attributes.push_back(AttribSpec("a_bound", Vec4(minValue, 0.0f, 0.0f, 0.0f),
609*35238bceSAndroid Build Coastguard Worker Vec4(maxValue, 0.0f, 0.0f, 0.0f), Vec4(minValue, 0.0f, 0.0f, 0.0f),
610*35238bceSAndroid Build Coastguard Worker Vec4(maxValue, 0.0f, 0.0f, 0.0f)));
611*35238bceSAndroid Build Coastguard Worker }
612*35238bceSAndroid Build Coastguard Worker }
613*35238bceSAndroid Build Coastguard Worker
614*35238bceSAndroid Build Coastguard Worker m_attributes.push_back(AttribSpec("a_value", Vec4(0.0f, 0.1f, 0.2f, 0.3f), Vec4(0.4f, 0.5f, 0.6f, 0.7f),
615*35238bceSAndroid Build Coastguard Worker Vec4(0.8f, 0.9f, 1.0f, 1.1f), Vec4(1.2f, 1.3f, 1.4f, 1.5f)));
616*35238bceSAndroid Build Coastguard Worker
617*35238bceSAndroid Build Coastguard Worker ControlStatementCase::init();
618*35238bceSAndroid Build Coastguard Worker }
619*35238bceSAndroid Build Coastguard Worker
setupProgram(uint32_t program)620*35238bceSAndroid Build Coastguard Worker void LoopCase::setupProgram(uint32_t program)
621*35238bceSAndroid Build Coastguard Worker {
622*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_renderCtx.getFunctions();
623*35238bceSAndroid Build Coastguard Worker
624*35238bceSAndroid Build Coastguard Worker if (m_decisionType == DECISION_UNIFORM)
625*35238bceSAndroid Build Coastguard Worker {
626*35238bceSAndroid Build Coastguard Worker const float loopBound = 10.5f;
627*35238bceSAndroid Build Coastguard Worker
628*35238bceSAndroid Build Coastguard Worker int location = gl.getUniformLocation(program, "u_bound");
629*35238bceSAndroid Build Coastguard Worker gl.uniform1f(location, loopBound);
630*35238bceSAndroid Build Coastguard Worker }
631*35238bceSAndroid Build Coastguard Worker else if (m_decisionType == DECISION_ATTRIBUTE && !m_isLoopBoundStable && m_caseType == CASETYPE_VERTEX)
632*35238bceSAndroid Build Coastguard Worker {
633*35238bceSAndroid Build Coastguard Worker // Setup per-vertex loop bounds calculated in init().
634*35238bceSAndroid Build Coastguard Worker
635*35238bceSAndroid Build Coastguard Worker const int numComponents = 4;
636*35238bceSAndroid Build Coastguard Worker int boundAttribLocation = gl.getAttribLocation(program, "a_bound");
637*35238bceSAndroid Build Coastguard Worker
638*35238bceSAndroid Build Coastguard Worker DE_ASSERT((int)m_boundArray.size() == numComponents * (getGridWidth() + 1) * (getGridHeight() + 1));
639*35238bceSAndroid Build Coastguard Worker
640*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &m_arrayBuffer);
641*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, m_arrayBuffer);
642*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(m_boundArray.size() * sizeof(float)), &m_boundArray[0],
643*35238bceSAndroid Build Coastguard Worker GL_STATIC_DRAW);
644*35238bceSAndroid Build Coastguard Worker gl.enableVertexAttribArray(boundAttribLocation);
645*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(boundAttribLocation, (GLint)numComponents, GL_FLOAT, GL_FALSE, 0, DE_NULL);
646*35238bceSAndroid Build Coastguard Worker }
647*35238bceSAndroid Build Coastguard Worker
648*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Setup program state");
649*35238bceSAndroid Build Coastguard Worker }
650*35238bceSAndroid Build Coastguard Worker
~LoopCase(void)651*35238bceSAndroid Build Coastguard Worker LoopCase::~LoopCase(void)
652*35238bceSAndroid Build Coastguard Worker {
653*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_renderCtx.getFunctions();
654*35238bceSAndroid Build Coastguard Worker
655*35238bceSAndroid Build Coastguard Worker if (m_arrayBuffer)
656*35238bceSAndroid Build Coastguard Worker {
657*35238bceSAndroid Build Coastguard Worker gl.deleteBuffers(1, &m_arrayBuffer);
658*35238bceSAndroid Build Coastguard Worker m_arrayBuffer = 0;
659*35238bceSAndroid Build Coastguard Worker }
660*35238bceSAndroid Build Coastguard Worker }
661*35238bceSAndroid Build Coastguard Worker
deinit(void)662*35238bceSAndroid Build Coastguard Worker void LoopCase::deinit(void)
663*35238bceSAndroid Build Coastguard Worker {
664*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_renderCtx.getFunctions();
665*35238bceSAndroid Build Coastguard Worker
666*35238bceSAndroid Build Coastguard Worker m_boundArray.clear();
667*35238bceSAndroid Build Coastguard Worker
668*35238bceSAndroid Build Coastguard Worker if (m_arrayBuffer)
669*35238bceSAndroid Build Coastguard Worker {
670*35238bceSAndroid Build Coastguard Worker gl.deleteBuffers(1, &m_arrayBuffer);
671*35238bceSAndroid Build Coastguard Worker m_arrayBuffer = 0;
672*35238bceSAndroid Build Coastguard Worker }
673*35238bceSAndroid Build Coastguard Worker
674*35238bceSAndroid Build Coastguard Worker ShaderPerformanceCase::deinit();
675*35238bceSAndroid Build Coastguard Worker }
676*35238bceSAndroid Build Coastguard Worker
677*35238bceSAndroid Build Coastguard Worker // A reference case, same calculations as the actual tests but without control statements.
678*35238bceSAndroid Build Coastguard Worker class WorkloadReferenceCase : public ControlStatementCase
679*35238bceSAndroid Build Coastguard Worker {
680*35238bceSAndroid Build Coastguard Worker public:
681*35238bceSAndroid Build Coastguard Worker WorkloadReferenceCase(Context &context, const char *name, const char *description, bool isVertex);
682*35238bceSAndroid Build Coastguard Worker
683*35238bceSAndroid Build Coastguard Worker void init(void);
684*35238bceSAndroid Build Coastguard Worker
685*35238bceSAndroid Build Coastguard Worker protected:
686*35238bceSAndroid Build Coastguard Worker virtual void writeWorkload(std::ostringstream &dst, const char *resultVariableName,
687*35238bceSAndroid Build Coastguard Worker const char *inputVariableName) const = 0;
688*35238bceSAndroid Build Coastguard Worker };
689*35238bceSAndroid Build Coastguard Worker
WorkloadReferenceCase(Context & context,const char * name,const char * description,bool isVertex)690*35238bceSAndroid Build Coastguard Worker WorkloadReferenceCase::WorkloadReferenceCase(Context &context, const char *name, const char *description, bool isVertex)
691*35238bceSAndroid Build Coastguard Worker : ControlStatementCase(context.getTestContext(), context.getRenderContext(), name, description,
692*35238bceSAndroid Build Coastguard Worker isVertex ? CASETYPE_VERTEX : CASETYPE_FRAGMENT)
693*35238bceSAndroid Build Coastguard Worker {
694*35238bceSAndroid Build Coastguard Worker }
695*35238bceSAndroid Build Coastguard Worker
init(void)696*35238bceSAndroid Build Coastguard Worker void WorkloadReferenceCase::init(void)
697*35238bceSAndroid Build Coastguard Worker {
698*35238bceSAndroid Build Coastguard Worker bool isVertexCase = m_caseType == CASETYPE_VERTEX;
699*35238bceSAndroid Build Coastguard Worker
700*35238bceSAndroid Build Coastguard Worker std::ostringstream vtx;
701*35238bceSAndroid Build Coastguard Worker std::ostringstream frag;
702*35238bceSAndroid Build Coastguard Worker std::ostringstream &op = isVertexCase ? vtx : frag;
703*35238bceSAndroid Build Coastguard Worker
704*35238bceSAndroid Build Coastguard Worker vtx << "attribute highp vec4 a_position;\n"; // Position attribute.
705*35238bceSAndroid Build Coastguard Worker vtx << "attribute mediump vec4 a_value;\n"; // Value for workload calculations.
706*35238bceSAndroid Build Coastguard Worker
707*35238bceSAndroid Build Coastguard Worker // Varyings.
708*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
709*35238bceSAndroid Build Coastguard Worker {
710*35238bceSAndroid Build Coastguard Worker vtx << "varying mediump vec4 v_color;\n";
711*35238bceSAndroid Build Coastguard Worker frag << "varying mediump vec4 v_color;\n";
712*35238bceSAndroid Build Coastguard Worker }
713*35238bceSAndroid Build Coastguard Worker else
714*35238bceSAndroid Build Coastguard Worker {
715*35238bceSAndroid Build Coastguard Worker vtx << "varying mediump vec4 v_value;\n";
716*35238bceSAndroid Build Coastguard Worker frag << "varying mediump vec4 v_value;\n";
717*35238bceSAndroid Build Coastguard Worker }
718*35238bceSAndroid Build Coastguard Worker
719*35238bceSAndroid Build Coastguard Worker vtx << "\n";
720*35238bceSAndroid Build Coastguard Worker vtx << "void main()\n";
721*35238bceSAndroid Build Coastguard Worker vtx << "{\n";
722*35238bceSAndroid Build Coastguard Worker vtx << " gl_Position = a_position;\n";
723*35238bceSAndroid Build Coastguard Worker
724*35238bceSAndroid Build Coastguard Worker frag << "\n";
725*35238bceSAndroid Build Coastguard Worker frag << "void main()\n";
726*35238bceSAndroid Build Coastguard Worker frag << "{\n";
727*35238bceSAndroid Build Coastguard Worker
728*35238bceSAndroid Build Coastguard Worker op << "\tmediump vec4 res;\n";
729*35238bceSAndroid Build Coastguard Worker writeWorkload(op, "res", isVertexCase ? "a_value" : "v_value");
730*35238bceSAndroid Build Coastguard Worker
731*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
732*35238bceSAndroid Build Coastguard Worker {
733*35238bceSAndroid Build Coastguard Worker // Put result to color variable.
734*35238bceSAndroid Build Coastguard Worker vtx << " v_color = res;\n";
735*35238bceSAndroid Build Coastguard Worker frag << " gl_FragColor = v_color;\n";
736*35238bceSAndroid Build Coastguard Worker }
737*35238bceSAndroid Build Coastguard Worker else
738*35238bceSAndroid Build Coastguard Worker {
739*35238bceSAndroid Build Coastguard Worker vtx << " v_value = a_value;\n"; // Transfer input to fragment shader through varying.
740*35238bceSAndroid Build Coastguard Worker frag << " gl_FragColor = res;\n"; // Put result to color variable.
741*35238bceSAndroid Build Coastguard Worker }
742*35238bceSAndroid Build Coastguard Worker
743*35238bceSAndroid Build Coastguard Worker vtx << "}\n";
744*35238bceSAndroid Build Coastguard Worker frag << "}\n";
745*35238bceSAndroid Build Coastguard Worker
746*35238bceSAndroid Build Coastguard Worker m_vertShaderSource = vtx.str();
747*35238bceSAndroid Build Coastguard Worker m_fragShaderSource = frag.str();
748*35238bceSAndroid Build Coastguard Worker
749*35238bceSAndroid Build Coastguard Worker m_attributes.push_back(AttribSpec("a_value", Vec4(0.0f, 0.1f, 0.2f, 0.3f), Vec4(0.4f, 0.5f, 0.6f, 0.7f),
750*35238bceSAndroid Build Coastguard Worker Vec4(0.8f, 0.9f, 1.0f, 1.1f), Vec4(1.2f, 1.3f, 1.4f, 1.5f)));
751*35238bceSAndroid Build Coastguard Worker
752*35238bceSAndroid Build Coastguard Worker ControlStatementCase::init();
753*35238bceSAndroid Build Coastguard Worker }
754*35238bceSAndroid Build Coastguard Worker
755*35238bceSAndroid Build Coastguard Worker class LoopWorkloadReferenceCase : public WorkloadReferenceCase
756*35238bceSAndroid Build Coastguard Worker {
757*35238bceSAndroid Build Coastguard Worker public:
LoopWorkloadReferenceCase(Context & context,const char * name,const char * description,bool isAttributeStable,bool isVertex)758*35238bceSAndroid Build Coastguard Worker LoopWorkloadReferenceCase(Context &context, const char *name, const char *description, bool isAttributeStable,
759*35238bceSAndroid Build Coastguard Worker bool isVertex)
760*35238bceSAndroid Build Coastguard Worker : WorkloadReferenceCase(context, name, description, isVertex)
761*35238bceSAndroid Build Coastguard Worker , m_isAttributeStable(isAttributeStable)
762*35238bceSAndroid Build Coastguard Worker {
763*35238bceSAndroid Build Coastguard Worker }
764*35238bceSAndroid Build Coastguard Worker
765*35238bceSAndroid Build Coastguard Worker protected:
766*35238bceSAndroid Build Coastguard Worker void writeWorkload(std::ostringstream &dst, const char *resultVariableName, const char *inputVariableName) const;
767*35238bceSAndroid Build Coastguard Worker
768*35238bceSAndroid Build Coastguard Worker private:
769*35238bceSAndroid Build Coastguard Worker bool m_isAttributeStable;
770*35238bceSAndroid Build Coastguard Worker };
771*35238bceSAndroid Build Coastguard Worker
writeWorkload(std::ostringstream & dst,const char * resultVariableName,const char * inputVariableName) const772*35238bceSAndroid Build Coastguard Worker void LoopWorkloadReferenceCase::writeWorkload(std::ostringstream &dst, const char *resultVariableName,
773*35238bceSAndroid Build Coastguard Worker const char *inputVariableName) const
774*35238bceSAndroid Build Coastguard Worker {
775*35238bceSAndroid Build Coastguard Worker const int loopIterations = 11;
776*35238bceSAndroid Build Coastguard Worker bool isVertexCase = m_caseType == CASETYPE_VERTEX;
777*35238bceSAndroid Build Coastguard Worker
778*35238bceSAndroid Build Coastguard Worker dst << "\t" << resultVariableName << " = vec4(0.0);\n";
779*35238bceSAndroid Build Coastguard Worker
780*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < loopIterations; i++)
781*35238bceSAndroid Build Coastguard Worker {
782*35238bceSAndroid Build Coastguard Worker dst << "\t";
783*35238bceSAndroid Build Coastguard Worker writeLoopWorkload(dst, resultVariableName, inputVariableName);
784*35238bceSAndroid Build Coastguard Worker dst << "\n";
785*35238bceSAndroid Build Coastguard Worker }
786*35238bceSAndroid Build Coastguard Worker
787*35238bceSAndroid Build Coastguard Worker if (!isVertexCase && !m_isAttributeStable)
788*35238bceSAndroid Build Coastguard Worker {
789*35238bceSAndroid Build Coastguard Worker // Corresponds to the fract() done in a real test's fragment case with non-stable attribute.
790*35238bceSAndroid Build Coastguard Worker dst << " res.x = fract(res.x);\n";
791*35238bceSAndroid Build Coastguard Worker }
792*35238bceSAndroid Build Coastguard Worker }
793*35238bceSAndroid Build Coastguard Worker
794*35238bceSAndroid Build Coastguard Worker class ConditionalWorkloadReferenceCase : public WorkloadReferenceCase
795*35238bceSAndroid Build Coastguard Worker {
796*35238bceSAndroid Build Coastguard Worker public:
ConditionalWorkloadReferenceCase(Context & context,const char * name,const char * description,bool isAttributeStable,bool isVertex)797*35238bceSAndroid Build Coastguard Worker ConditionalWorkloadReferenceCase(Context &context, const char *name, const char *description,
798*35238bceSAndroid Build Coastguard Worker bool isAttributeStable, bool isVertex)
799*35238bceSAndroid Build Coastguard Worker : WorkloadReferenceCase(context, name, description, isVertex)
800*35238bceSAndroid Build Coastguard Worker , m_isAttributeStable(isAttributeStable)
801*35238bceSAndroid Build Coastguard Worker {
802*35238bceSAndroid Build Coastguard Worker }
803*35238bceSAndroid Build Coastguard Worker
804*35238bceSAndroid Build Coastguard Worker protected:
805*35238bceSAndroid Build Coastguard Worker void writeWorkload(std::ostringstream &dst, const char *resultVariableName, const char *inputVariableName) const;
806*35238bceSAndroid Build Coastguard Worker
807*35238bceSAndroid Build Coastguard Worker private:
808*35238bceSAndroid Build Coastguard Worker bool m_isAttributeStable;
809*35238bceSAndroid Build Coastguard Worker };
810*35238bceSAndroid Build Coastguard Worker
writeWorkload(std::ostringstream & dst,const char * resultVariableName,const char * inputVariableName) const811*35238bceSAndroid Build Coastguard Worker void ConditionalWorkloadReferenceCase::writeWorkload(std::ostringstream &dst, const char *resultVariableName,
812*35238bceSAndroid Build Coastguard Worker const char *inputVariableName) const
813*35238bceSAndroid Build Coastguard Worker {
814*35238bceSAndroid Build Coastguard Worker bool isVertexCase = m_caseType == CASETYPE_VERTEX;
815*35238bceSAndroid Build Coastguard Worker
816*35238bceSAndroid Build Coastguard Worker dst << "\t";
817*35238bceSAndroid Build Coastguard Worker writeConditionalWorkload(dst, resultVariableName, inputVariableName);
818*35238bceSAndroid Build Coastguard Worker dst << "\n";
819*35238bceSAndroid Build Coastguard Worker
820*35238bceSAndroid Build Coastguard Worker if (!isVertexCase && !m_isAttributeStable)
821*35238bceSAndroid Build Coastguard Worker {
822*35238bceSAndroid Build Coastguard Worker // Corresponds to the fract() done in a real test's fragment case with non-stable attribute.
823*35238bceSAndroid Build Coastguard Worker dst << " res.x = fract(res.x);\n";
824*35238bceSAndroid Build Coastguard Worker }
825*35238bceSAndroid Build Coastguard Worker }
826*35238bceSAndroid Build Coastguard Worker
827*35238bceSAndroid Build Coastguard Worker // A workload reference case for e.g. a conditional case with a branch with no computation.
828*35238bceSAndroid Build Coastguard Worker class EmptyWorkloadReferenceCase : public WorkloadReferenceCase
829*35238bceSAndroid Build Coastguard Worker {
830*35238bceSAndroid Build Coastguard Worker public:
EmptyWorkloadReferenceCase(Context & context,const char * name,const char * description,bool isVertex)831*35238bceSAndroid Build Coastguard Worker EmptyWorkloadReferenceCase(Context &context, const char *name, const char *description, bool isVertex)
832*35238bceSAndroid Build Coastguard Worker : WorkloadReferenceCase(context, name, description, isVertex)
833*35238bceSAndroid Build Coastguard Worker {
834*35238bceSAndroid Build Coastguard Worker }
835*35238bceSAndroid Build Coastguard Worker
836*35238bceSAndroid Build Coastguard Worker protected:
writeWorkload(std::ostringstream & dst,const char * resultVariableName,const char * inputVariableName) const837*35238bceSAndroid Build Coastguard Worker void writeWorkload(std::ostringstream &dst, const char *resultVariableName, const char *inputVariableName) const
838*35238bceSAndroid Build Coastguard Worker {
839*35238bceSAndroid Build Coastguard Worker dst << "\t" << resultVariableName << " = " << inputVariableName << ";\n";
840*35238bceSAndroid Build Coastguard Worker }
841*35238bceSAndroid Build Coastguard Worker };
842*35238bceSAndroid Build Coastguard Worker
ShaderControlStatementTests(Context & context)843*35238bceSAndroid Build Coastguard Worker ShaderControlStatementTests::ShaderControlStatementTests(Context &context)
844*35238bceSAndroid Build Coastguard Worker : TestCaseGroup(context, "control_statement", "Control Statement Performance Tests")
845*35238bceSAndroid Build Coastguard Worker {
846*35238bceSAndroid Build Coastguard Worker }
847*35238bceSAndroid Build Coastguard Worker
~ShaderControlStatementTests(void)848*35238bceSAndroid Build Coastguard Worker ShaderControlStatementTests::~ShaderControlStatementTests(void)
849*35238bceSAndroid Build Coastguard Worker {
850*35238bceSAndroid Build Coastguard Worker }
851*35238bceSAndroid Build Coastguard Worker
init(void)852*35238bceSAndroid Build Coastguard Worker void ShaderControlStatementTests::init(void)
853*35238bceSAndroid Build Coastguard Worker {
854*35238bceSAndroid Build Coastguard Worker // Conditional cases (if-else).
855*35238bceSAndroid Build Coastguard Worker
856*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *ifElseGroup =
857*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "if_else", "if-else Conditional Performance Tests");
858*35238bceSAndroid Build Coastguard Worker addChild(ifElseGroup);
859*35238bceSAndroid Build Coastguard Worker
860*35238bceSAndroid Build Coastguard Worker for (int isFrag = 0; isFrag <= 1; isFrag++)
861*35238bceSAndroid Build Coastguard Worker {
862*35238bceSAndroid Build Coastguard Worker bool isVertex = isFrag == 0;
863*35238bceSAndroid Build Coastguard Worker ShaderPerformanceCaseGroup *vertexOrFragmentGroup =
864*35238bceSAndroid Build Coastguard Worker new ShaderPerformanceCaseGroup(m_testCtx, isVertex ? "vertex" : "fragment", "");
865*35238bceSAndroid Build Coastguard Worker ifElseGroup->addChild(vertexOrFragmentGroup);
866*35238bceSAndroid Build Coastguard Worker
867*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(DECISION_STATIC == 0);
868*35238bceSAndroid Build Coastguard Worker for (int decisionType = (int)DECISION_STATIC; decisionType < (int)DECISION_LAST; decisionType++)
869*35238bceSAndroid Build Coastguard Worker {
870*35238bceSAndroid Build Coastguard Worker const char *decisionName = decisionType == (int)DECISION_STATIC ? "static" :
871*35238bceSAndroid Build Coastguard Worker decisionType == (int)DECISION_UNIFORM ? "uniform" :
872*35238bceSAndroid Build Coastguard Worker decisionType == (int)DECISION_ATTRIBUTE ? (isVertex ? "attribute" : "varying") :
873*35238bceSAndroid Build Coastguard Worker DE_NULL;
874*35238bceSAndroid Build Coastguard Worker DE_ASSERT(decisionName != DE_NULL);
875*35238bceSAndroid Build Coastguard Worker
876*35238bceSAndroid Build Coastguard Worker for (int workloadDivision = 0; workloadDivision < ConditionalCase::WORKLOAD_DIVISION_LAST;
877*35238bceSAndroid Build Coastguard Worker workloadDivision++)
878*35238bceSAndroid Build Coastguard Worker {
879*35238bceSAndroid Build Coastguard Worker const char *workloadDivisionSuffix =
880*35238bceSAndroid Build Coastguard Worker workloadDivision == (int)ConditionalCase::WORKLOAD_DIVISION_EVEN ? "" :
881*35238bceSAndroid Build Coastguard Worker workloadDivision == (int)ConditionalCase::WORKLOAD_DIVISION_TRUE_HEAVY ? "_with_heavier_true" :
882*35238bceSAndroid Build Coastguard Worker workloadDivision == (int)ConditionalCase::WORKLOAD_DIVISION_FALSE_HEAVY ? "_with_heavier_false" :
883*35238bceSAndroid Build Coastguard Worker DE_NULL;
884*35238bceSAndroid Build Coastguard Worker DE_ASSERT(workloadDivisionSuffix != DE_NULL);
885*35238bceSAndroid Build Coastguard Worker
886*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(ConditionalCase::BRANCH_TRUE == 0);
887*35238bceSAndroid Build Coastguard Worker for (int branchResult = (int)ConditionalCase::BRANCH_TRUE;
888*35238bceSAndroid Build Coastguard Worker branchResult < (int)ConditionalCase::BRANCH_LAST; branchResult++)
889*35238bceSAndroid Build Coastguard Worker {
890*35238bceSAndroid Build Coastguard Worker if (decisionType != (int)DECISION_ATTRIBUTE && branchResult == (int)ConditionalCase::BRANCH_MIXED)
891*35238bceSAndroid Build Coastguard Worker continue;
892*35238bceSAndroid Build Coastguard Worker
893*35238bceSAndroid Build Coastguard Worker const char *branchResultName = branchResult == (int)ConditionalCase::BRANCH_TRUE ? "true" :
894*35238bceSAndroid Build Coastguard Worker branchResult == (int)ConditionalCase::BRANCH_FALSE ? "false" :
895*35238bceSAndroid Build Coastguard Worker branchResult == (int)ConditionalCase::BRANCH_MIXED ? "mixed" :
896*35238bceSAndroid Build Coastguard Worker DE_NULL;
897*35238bceSAndroid Build Coastguard Worker DE_ASSERT(branchResultName != DE_NULL);
898*35238bceSAndroid Build Coastguard Worker
899*35238bceSAndroid Build Coastguard Worker string caseName = string("") + decisionName + "_" + branchResultName + workloadDivisionSuffix;
900*35238bceSAndroid Build Coastguard Worker
901*35238bceSAndroid Build Coastguard Worker vertexOrFragmentGroup->addChild(
902*35238bceSAndroid Build Coastguard Worker new ConditionalCase(m_context, caseName.c_str(), "", (DecisionType)decisionType,
903*35238bceSAndroid Build Coastguard Worker (ConditionalCase::BranchResult)branchResult,
904*35238bceSAndroid Build Coastguard Worker (ConditionalCase::WorkloadDivision)workloadDivision, isVertex));
905*35238bceSAndroid Build Coastguard Worker }
906*35238bceSAndroid Build Coastguard Worker }
907*35238bceSAndroid Build Coastguard Worker }
908*35238bceSAndroid Build Coastguard Worker
909*35238bceSAndroid Build Coastguard Worker if (isVertex)
910*35238bceSAndroid Build Coastguard Worker vertexOrFragmentGroup->addChild(
911*35238bceSAndroid Build Coastguard Worker new ConditionalWorkloadReferenceCase(m_context, "reference", "", true, isVertex));
912*35238bceSAndroid Build Coastguard Worker else
913*35238bceSAndroid Build Coastguard Worker {
914*35238bceSAndroid Build Coastguard Worker // Only fragment case with BRANCH_MIXED has an additional fract() call.
915*35238bceSAndroid Build Coastguard Worker vertexOrFragmentGroup->addChild(
916*35238bceSAndroid Build Coastguard Worker new ConditionalWorkloadReferenceCase(m_context, "reference_unmixed", "", true, isVertex));
917*35238bceSAndroid Build Coastguard Worker vertexOrFragmentGroup->addChild(
918*35238bceSAndroid Build Coastguard Worker new ConditionalWorkloadReferenceCase(m_context, "reference_mixed", "", false, isVertex));
919*35238bceSAndroid Build Coastguard Worker }
920*35238bceSAndroid Build Coastguard Worker
921*35238bceSAndroid Build Coastguard Worker vertexOrFragmentGroup->addChild(new EmptyWorkloadReferenceCase(m_context, "reference_empty", "", isVertex));
922*35238bceSAndroid Build Coastguard Worker }
923*35238bceSAndroid Build Coastguard Worker
924*35238bceSAndroid Build Coastguard Worker // Loop cases.
925*35238bceSAndroid Build Coastguard Worker
926*35238bceSAndroid Build Coastguard Worker static const struct
927*35238bceSAndroid Build Coastguard Worker {
928*35238bceSAndroid Build Coastguard Worker LoopCase::LoopType type;
929*35238bceSAndroid Build Coastguard Worker const char *name;
930*35238bceSAndroid Build Coastguard Worker const char *description;
931*35238bceSAndroid Build Coastguard Worker } loopGroups[] = {{LoopCase::LOOP_FOR, "for", "for Loop Performance Tests"},
932*35238bceSAndroid Build Coastguard Worker {LoopCase::LOOP_WHILE, "while", "while Loop Performance Tests"},
933*35238bceSAndroid Build Coastguard Worker {LoopCase::LOOP_DO_WHILE, "do_while", "do-while Loop Performance Tests"}};
934*35238bceSAndroid Build Coastguard Worker
935*35238bceSAndroid Build Coastguard Worker for (int groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(loopGroups); groupNdx++)
936*35238bceSAndroid Build Coastguard Worker {
937*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *currentLoopGroup =
938*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, loopGroups[groupNdx].name, loopGroups[groupNdx].description);
939*35238bceSAndroid Build Coastguard Worker addChild(currentLoopGroup);
940*35238bceSAndroid Build Coastguard Worker
941*35238bceSAndroid Build Coastguard Worker for (int isFrag = 0; isFrag <= 1; isFrag++)
942*35238bceSAndroid Build Coastguard Worker {
943*35238bceSAndroid Build Coastguard Worker bool isVertex = isFrag == 0;
944*35238bceSAndroid Build Coastguard Worker ShaderPerformanceCaseGroup *vertexOrFragmentGroup =
945*35238bceSAndroid Build Coastguard Worker new ShaderPerformanceCaseGroup(m_testCtx, isVertex ? "vertex" : "fragment", "");
946*35238bceSAndroid Build Coastguard Worker currentLoopGroup->addChild(vertexOrFragmentGroup);
947*35238bceSAndroid Build Coastguard Worker
948*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(DECISION_STATIC == 0);
949*35238bceSAndroid Build Coastguard Worker for (int decisionType = (int)DECISION_STATIC; decisionType < (int)DECISION_LAST; decisionType++)
950*35238bceSAndroid Build Coastguard Worker {
951*35238bceSAndroid Build Coastguard Worker const char *decisionName =
952*35238bceSAndroid Build Coastguard Worker decisionType == (int)DECISION_STATIC ? "static" :
953*35238bceSAndroid Build Coastguard Worker decisionType == (int)DECISION_UNIFORM ? "uniform" :
954*35238bceSAndroid Build Coastguard Worker decisionType == (int)DECISION_ATTRIBUTE ? (isVertex ? "attribute" : "varying") :
955*35238bceSAndroid Build Coastguard Worker DE_NULL;
956*35238bceSAndroid Build Coastguard Worker DE_ASSERT(decisionName != DE_NULL);
957*35238bceSAndroid Build Coastguard Worker
958*35238bceSAndroid Build Coastguard Worker if (decisionType == (int)DECISION_ATTRIBUTE)
959*35238bceSAndroid Build Coastguard Worker {
960*35238bceSAndroid Build Coastguard Worker vertexOrFragmentGroup->addChild(new LoopCase(m_context, (string(decisionName) + "_stable").c_str(),
961*35238bceSAndroid Build Coastguard Worker "", loopGroups[groupNdx].type,
962*35238bceSAndroid Build Coastguard Worker (DecisionType)decisionType, true, isVertex));
963*35238bceSAndroid Build Coastguard Worker vertexOrFragmentGroup->addChild(
964*35238bceSAndroid Build Coastguard Worker new LoopCase(m_context, (string(decisionName) + "_unstable").c_str(), "",
965*35238bceSAndroid Build Coastguard Worker loopGroups[groupNdx].type, (DecisionType)decisionType, false, isVertex));
966*35238bceSAndroid Build Coastguard Worker }
967*35238bceSAndroid Build Coastguard Worker else
968*35238bceSAndroid Build Coastguard Worker vertexOrFragmentGroup->addChild(new LoopCase(m_context, decisionName, "", loopGroups[groupNdx].type,
969*35238bceSAndroid Build Coastguard Worker (DecisionType)decisionType, true, isVertex));
970*35238bceSAndroid Build Coastguard Worker }
971*35238bceSAndroid Build Coastguard Worker
972*35238bceSAndroid Build Coastguard Worker if (isVertex)
973*35238bceSAndroid Build Coastguard Worker vertexOrFragmentGroup->addChild(
974*35238bceSAndroid Build Coastguard Worker new LoopWorkloadReferenceCase(m_context, "reference", "", true, isVertex));
975*35238bceSAndroid Build Coastguard Worker else
976*35238bceSAndroid Build Coastguard Worker {
977*35238bceSAndroid Build Coastguard Worker // Only fragment case with unstable attribute has an additional fract() call.
978*35238bceSAndroid Build Coastguard Worker vertexOrFragmentGroup->addChild(
979*35238bceSAndroid Build Coastguard Worker new LoopWorkloadReferenceCase(m_context, "reference_stable", "", true, isVertex));
980*35238bceSAndroid Build Coastguard Worker vertexOrFragmentGroup->addChild(
981*35238bceSAndroid Build Coastguard Worker new LoopWorkloadReferenceCase(m_context, "reference_unstable", "", false, isVertex));
982*35238bceSAndroid Build Coastguard Worker }
983*35238bceSAndroid Build Coastguard Worker }
984*35238bceSAndroid Build Coastguard Worker }
985*35238bceSAndroid Build Coastguard Worker }
986*35238bceSAndroid Build Coastguard Worker
987*35238bceSAndroid Build Coastguard Worker } // namespace Performance
988*35238bceSAndroid Build Coastguard Worker } // namespace gles2
989*35238bceSAndroid Build Coastguard Worker } // namespace deqp
990