xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fShaderSwitchTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 3.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 switch statement tests.
22*35238bceSAndroid Build Coastguard Worker  *
23*35238bceSAndroid Build Coastguard Worker  * Variables:
24*35238bceSAndroid Build Coastguard Worker  *  + Selection expression type: static, uniform, dynamic
25*35238bceSAndroid Build Coastguard Worker  *  + Switch layout - fall-through or use of default label
26*35238bceSAndroid Build Coastguard Worker  *  + Switch nested in loop/conditional statement
27*35238bceSAndroid Build Coastguard Worker  *  + Loop/conditional statement nested in switch
28*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
29*35238bceSAndroid Build Coastguard Worker 
30*35238bceSAndroid Build Coastguard Worker #include "es3fShaderSwitchTests.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "glsShaderRenderCase.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "glsShaderLibrary.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
35*35238bceSAndroid Build Coastguard Worker 
36*35238bceSAndroid Build Coastguard Worker namespace deqp
37*35238bceSAndroid Build Coastguard Worker {
38*35238bceSAndroid Build Coastguard Worker namespace gles3
39*35238bceSAndroid Build Coastguard Worker {
40*35238bceSAndroid Build Coastguard Worker namespace Functional
41*35238bceSAndroid Build Coastguard Worker {
42*35238bceSAndroid Build Coastguard Worker 
43*35238bceSAndroid Build Coastguard Worker using namespace deqp::gls;
44*35238bceSAndroid Build Coastguard Worker using std::map;
45*35238bceSAndroid Build Coastguard Worker using std::string;
46*35238bceSAndroid Build Coastguard Worker using std::vector;
47*35238bceSAndroid Build Coastguard Worker 
48*35238bceSAndroid Build Coastguard Worker class ShaderSwitchCase : public ShaderRenderCase
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker public:
51*35238bceSAndroid Build Coastguard Worker     ShaderSwitchCase(Context &context, const char *name, const char *description, bool isVertexCase,
52*35238bceSAndroid Build Coastguard Worker                      const char *vtxSource, const char *fragSource, ShaderEvalFunc evalFunc);
53*35238bceSAndroid Build Coastguard Worker     virtual ~ShaderSwitchCase(void);
54*35238bceSAndroid Build Coastguard Worker };
55*35238bceSAndroid Build Coastguard Worker 
ShaderSwitchCase(Context & context,const char * name,const char * description,bool isVertexCase,const char * vtxSource,const char * fragSource,ShaderEvalFunc evalFunc)56*35238bceSAndroid Build Coastguard Worker ShaderSwitchCase::ShaderSwitchCase(Context &context, const char *name, const char *description, bool isVertexCase,
57*35238bceSAndroid Build Coastguard Worker                                    const char *vtxSource, const char *fragSource, ShaderEvalFunc evalFunc)
58*35238bceSAndroid Build Coastguard Worker     : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name,
59*35238bceSAndroid Build Coastguard Worker                        description, isVertexCase, evalFunc)
60*35238bceSAndroid Build Coastguard Worker {
61*35238bceSAndroid Build Coastguard Worker     m_vertShaderSource = vtxSource;
62*35238bceSAndroid Build Coastguard Worker     m_fragShaderSource = fragSource;
63*35238bceSAndroid Build Coastguard Worker }
64*35238bceSAndroid Build Coastguard Worker 
~ShaderSwitchCase(void)65*35238bceSAndroid Build Coastguard Worker ShaderSwitchCase::~ShaderSwitchCase(void)
66*35238bceSAndroid Build Coastguard Worker {
67*35238bceSAndroid Build Coastguard Worker }
68*35238bceSAndroid Build Coastguard Worker 
69*35238bceSAndroid Build Coastguard Worker enum SwitchType
70*35238bceSAndroid Build Coastguard Worker {
71*35238bceSAndroid Build Coastguard Worker     SWITCHTYPE_STATIC = 0,
72*35238bceSAndroid Build Coastguard Worker     SWITCHTYPE_UNIFORM,
73*35238bceSAndroid Build Coastguard Worker     SWITCHTYPE_DYNAMIC,
74*35238bceSAndroid Build Coastguard Worker 
75*35238bceSAndroid Build Coastguard Worker     SWITCHTYPE_LAST
76*35238bceSAndroid Build Coastguard Worker };
77*35238bceSAndroid Build Coastguard Worker 
evalSwitchStatic(ShaderEvalContext & evalCtx)78*35238bceSAndroid Build Coastguard Worker static void evalSwitchStatic(ShaderEvalContext &evalCtx)
79*35238bceSAndroid Build Coastguard Worker {
80*35238bceSAndroid Build Coastguard Worker     evalCtx.color.xyz() = evalCtx.coords.swizzle(1, 2, 3);
81*35238bceSAndroid Build Coastguard Worker }
evalSwitchUniform(ShaderEvalContext & evalCtx)82*35238bceSAndroid Build Coastguard Worker static void evalSwitchUniform(ShaderEvalContext &evalCtx)
83*35238bceSAndroid Build Coastguard Worker {
84*35238bceSAndroid Build Coastguard Worker     evalCtx.color.xyz() = evalCtx.coords.swizzle(1, 2, 3);
85*35238bceSAndroid Build Coastguard Worker }
evalSwitchDynamic(ShaderEvalContext & evalCtx)86*35238bceSAndroid Build Coastguard Worker static void evalSwitchDynamic(ShaderEvalContext &evalCtx)
87*35238bceSAndroid Build Coastguard Worker {
88*35238bceSAndroid Build Coastguard Worker     switch (int(deFloatFloor(evalCtx.coords.z() * 1.5f + 2.0f)))
89*35238bceSAndroid Build Coastguard Worker     {
90*35238bceSAndroid Build Coastguard Worker     case 0:
91*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = evalCtx.coords.swizzle(0, 1, 2);
92*35238bceSAndroid Build Coastguard Worker         break;
93*35238bceSAndroid Build Coastguard Worker     case 1:
94*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = evalCtx.coords.swizzle(3, 2, 1);
95*35238bceSAndroid Build Coastguard Worker         break;
96*35238bceSAndroid Build Coastguard Worker     case 2:
97*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = evalCtx.coords.swizzle(1, 2, 3);
98*35238bceSAndroid Build Coastguard Worker         break;
99*35238bceSAndroid Build Coastguard Worker     case 3:
100*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = evalCtx.coords.swizzle(2, 1, 0);
101*35238bceSAndroid Build Coastguard Worker         break;
102*35238bceSAndroid Build Coastguard Worker     default:
103*35238bceSAndroid Build Coastguard Worker         evalCtx.color.xyz() = evalCtx.coords.swizzle(0, 0, 0);
104*35238bceSAndroid Build Coastguard Worker         break;
105*35238bceSAndroid Build Coastguard Worker     }
106*35238bceSAndroid Build Coastguard Worker }
107*35238bceSAndroid Build Coastguard Worker 
makeSwitchCase(Context & context,const char * name,const char * desc,SwitchType type,bool isVertex,const LineStream & switchBody)108*35238bceSAndroid Build Coastguard Worker static tcu::TestCase *makeSwitchCase(Context &context, const char *name, const char *desc, SwitchType type,
109*35238bceSAndroid Build Coastguard Worker                                      bool isVertex, const LineStream &switchBody)
110*35238bceSAndroid Build Coastguard Worker {
111*35238bceSAndroid Build Coastguard Worker     std::ostringstream vtx;
112*35238bceSAndroid Build Coastguard Worker     std::ostringstream frag;
113*35238bceSAndroid Build Coastguard Worker     std::ostringstream &op = isVertex ? vtx : frag;
114*35238bceSAndroid Build Coastguard Worker 
115*35238bceSAndroid Build Coastguard Worker     vtx << "#version 300 es\n"
116*35238bceSAndroid Build Coastguard Worker         << "in highp vec4 a_position;\n"
117*35238bceSAndroid Build Coastguard Worker         << "in highp vec4 a_coords;\n";
118*35238bceSAndroid Build Coastguard Worker     frag << "#version 300 es\n"
119*35238bceSAndroid Build Coastguard Worker          << "layout(location = 0) out mediump vec4 o_color;\n";
120*35238bceSAndroid Build Coastguard Worker 
121*35238bceSAndroid Build Coastguard Worker     if (isVertex)
122*35238bceSAndroid Build Coastguard Worker     {
123*35238bceSAndroid Build Coastguard Worker         vtx << "out mediump vec4 v_color;\n";
124*35238bceSAndroid Build Coastguard Worker         frag << "in mediump vec4 v_color;\n";
125*35238bceSAndroid Build Coastguard Worker     }
126*35238bceSAndroid Build Coastguard Worker     else
127*35238bceSAndroid Build Coastguard Worker     {
128*35238bceSAndroid Build Coastguard Worker         vtx << "out highp vec4 v_coords;\n";
129*35238bceSAndroid Build Coastguard Worker         frag << "in highp vec4 v_coords;\n";
130*35238bceSAndroid Build Coastguard Worker     }
131*35238bceSAndroid Build Coastguard Worker 
132*35238bceSAndroid Build Coastguard Worker     if (type == SWITCHTYPE_UNIFORM)
133*35238bceSAndroid Build Coastguard Worker         op << "uniform highp int ui_two;\n";
134*35238bceSAndroid Build Coastguard Worker 
135*35238bceSAndroid Build Coastguard Worker     vtx << "\n"
136*35238bceSAndroid Build Coastguard Worker         << "void main (void)\n"
137*35238bceSAndroid Build Coastguard Worker         << "{\n"
138*35238bceSAndroid Build Coastguard Worker         << "    gl_Position = a_position;\n";
139*35238bceSAndroid Build Coastguard Worker     frag << "\n"
140*35238bceSAndroid Build Coastguard Worker          << "void main (void)\n"
141*35238bceSAndroid Build Coastguard Worker          << "{\n";
142*35238bceSAndroid Build Coastguard Worker 
143*35238bceSAndroid Build Coastguard Worker     // Setup.
144*35238bceSAndroid Build Coastguard Worker     op << "    highp vec4 coords = " << (isVertex ? "a_coords" : "v_coords") << ";\n";
145*35238bceSAndroid Build Coastguard Worker     op << "    mediump vec3 res = vec3(0.0);\n\n";
146*35238bceSAndroid Build Coastguard Worker 
147*35238bceSAndroid Build Coastguard Worker     // Switch body.
148*35238bceSAndroid Build Coastguard Worker     map<string, string> params;
149*35238bceSAndroid Build Coastguard Worker     params["CONDITION"] = type == SWITCHTYPE_STATIC  ? "2" :
150*35238bceSAndroid Build Coastguard Worker                           type == SWITCHTYPE_UNIFORM ? "ui_two" :
151*35238bceSAndroid Build Coastguard Worker                           type == SWITCHTYPE_DYNAMIC ? "int(floor(coords.z*1.5 + 2.0))" :
152*35238bceSAndroid Build Coastguard Worker                                                        "???";
153*35238bceSAndroid Build Coastguard Worker 
154*35238bceSAndroid Build Coastguard Worker     op << tcu::StringTemplate(switchBody.str()).specialize(params).c_str();
155*35238bceSAndroid Build Coastguard Worker     op << "\n";
156*35238bceSAndroid Build Coastguard Worker 
157*35238bceSAndroid Build Coastguard Worker     if (isVertex)
158*35238bceSAndroid Build Coastguard Worker     {
159*35238bceSAndroid Build Coastguard Worker         vtx << "    v_color = vec4(res, 1.0);\n";
160*35238bceSAndroid Build Coastguard Worker         frag << "    o_color = v_color;\n";
161*35238bceSAndroid Build Coastguard Worker     }
162*35238bceSAndroid Build Coastguard Worker     else
163*35238bceSAndroid Build Coastguard Worker     {
164*35238bceSAndroid Build Coastguard Worker         vtx << "    v_coords = a_coords;\n";
165*35238bceSAndroid Build Coastguard Worker         frag << "    o_color = vec4(res, 1.0);\n";
166*35238bceSAndroid Build Coastguard Worker     }
167*35238bceSAndroid Build Coastguard Worker 
168*35238bceSAndroid Build Coastguard Worker     vtx << "}\n";
169*35238bceSAndroid Build Coastguard Worker     frag << "}\n";
170*35238bceSAndroid Build Coastguard Worker 
171*35238bceSAndroid Build Coastguard Worker     return new ShaderSwitchCase(context, name, desc, isVertex, vtx.str().c_str(), frag.str().c_str(),
172*35238bceSAndroid Build Coastguard Worker                                 type == SWITCHTYPE_STATIC  ? evalSwitchStatic :
173*35238bceSAndroid Build Coastguard Worker                                 type == SWITCHTYPE_UNIFORM ? evalSwitchUniform :
174*35238bceSAndroid Build Coastguard Worker                                 type == SWITCHTYPE_DYNAMIC ? evalSwitchDynamic :
175*35238bceSAndroid Build Coastguard Worker                                                              (ShaderEvalFunc)DE_NULL);
176*35238bceSAndroid Build Coastguard Worker }
177*35238bceSAndroid Build Coastguard Worker 
makeSwitchCases(TestCaseGroup * group,const char * name,const char * desc,const LineStream & switchBody,const bool skipDynamicType=false)178*35238bceSAndroid Build Coastguard Worker static void makeSwitchCases(TestCaseGroup *group, const char *name, const char *desc, const LineStream &switchBody,
179*35238bceSAndroid Build Coastguard Worker                             const bool skipDynamicType = false)
180*35238bceSAndroid Build Coastguard Worker {
181*35238bceSAndroid Build Coastguard Worker     static const char *switchTypeNames[] = {"static", "uniform", "dynamic"};
182*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(switchTypeNames) == SWITCHTYPE_LAST);
183*35238bceSAndroid Build Coastguard Worker 
184*35238bceSAndroid Build Coastguard Worker     for (int type = 0; type < SWITCHTYPE_LAST; type++)
185*35238bceSAndroid Build Coastguard Worker     {
186*35238bceSAndroid Build Coastguard Worker         if (skipDynamicType && (type == SWITCHTYPE_DYNAMIC))
187*35238bceSAndroid Build Coastguard Worker             continue;
188*35238bceSAndroid Build Coastguard Worker 
189*35238bceSAndroid Build Coastguard Worker         group->addChild(makeSwitchCase(group->getContext(),
190*35238bceSAndroid Build Coastguard Worker                                        (string(name) + "_" + switchTypeNames[type] + "_vertex").c_str(), desc,
191*35238bceSAndroid Build Coastguard Worker                                        (SwitchType)type, true, switchBody));
192*35238bceSAndroid Build Coastguard Worker         group->addChild(makeSwitchCase(group->getContext(),
193*35238bceSAndroid Build Coastguard Worker                                        (string(name) + "_" + switchTypeNames[type] + "_fragment").c_str(), desc,
194*35238bceSAndroid Build Coastguard Worker                                        (SwitchType)type, false, switchBody));
195*35238bceSAndroid Build Coastguard Worker     }
196*35238bceSAndroid Build Coastguard Worker }
197*35238bceSAndroid Build Coastguard Worker 
ShaderSwitchTests(Context & context)198*35238bceSAndroid Build Coastguard Worker ShaderSwitchTests::ShaderSwitchTests(Context &context) : TestCaseGroup(context, "switch", "Switch statement tests")
199*35238bceSAndroid Build Coastguard Worker {
200*35238bceSAndroid Build Coastguard Worker }
201*35238bceSAndroid Build Coastguard Worker 
~ShaderSwitchTests(void)202*35238bceSAndroid Build Coastguard Worker ShaderSwitchTests::~ShaderSwitchTests(void)
203*35238bceSAndroid Build Coastguard Worker {
204*35238bceSAndroid Build Coastguard Worker }
205*35238bceSAndroid Build Coastguard Worker 
init(void)206*35238bceSAndroid Build Coastguard Worker void ShaderSwitchTests::init(void)
207*35238bceSAndroid Build Coastguard Worker {
208*35238bceSAndroid Build Coastguard Worker     // Expected swizzles:
209*35238bceSAndroid Build Coastguard Worker     // 0: xyz
210*35238bceSAndroid Build Coastguard Worker     // 1: wzy
211*35238bceSAndroid Build Coastguard Worker     // 2: yzw
212*35238bceSAndroid Build Coastguard Worker     // 3: zyx
213*35238bceSAndroid Build Coastguard Worker 
214*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "basic", "Basic switch statement usage",
215*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "switch (${CONDITION})"
216*35238bceSAndroid Build Coastguard Worker                                   << "{"
217*35238bceSAndroid Build Coastguard Worker                                   << "    case 0: res = coords.xyz;    break;"
218*35238bceSAndroid Build Coastguard Worker                                   << "    case 1: res = coords.wzy;    break;"
219*35238bceSAndroid Build Coastguard Worker                                   << "    case 2: res = coords.yzw;    break;"
220*35238bceSAndroid Build Coastguard Worker                                   << "    case 3: res = coords.zyx;    break;"
221*35238bceSAndroid Build Coastguard Worker                                   << "}");
222*35238bceSAndroid Build Coastguard Worker 
223*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "const_expr_in_label", "Constant expression in label",
224*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "const int t = 2;"
225*35238bceSAndroid Build Coastguard Worker                                   << "switch (${CONDITION})"
226*35238bceSAndroid Build Coastguard Worker                                   << "{"
227*35238bceSAndroid Build Coastguard Worker                                   << "    case int(0.0): res = coords.xyz;    break;"
228*35238bceSAndroid Build Coastguard Worker                                   << "    case 2-1: res = coords.wzy;    break;"
229*35238bceSAndroid Build Coastguard Worker                                   << "    case 3&(1<<1): res = coords.yzw;    break;"
230*35238bceSAndroid Build Coastguard Worker                                   << "    case t+1: res = coords.zyx;    break;"
231*35238bceSAndroid Build Coastguard Worker                                   << "}");
232*35238bceSAndroid Build Coastguard Worker 
233*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "default_label", "Default label usage",
234*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "switch (${CONDITION})"
235*35238bceSAndroid Build Coastguard Worker                                   << "{"
236*35238bceSAndroid Build Coastguard Worker                                   << "    case 0: res = coords.xyz;    break;"
237*35238bceSAndroid Build Coastguard Worker                                   << "    case 1: res = coords.wzy;    break;"
238*35238bceSAndroid Build Coastguard Worker                                   << "    case 3: res = coords.zyx;    break;"
239*35238bceSAndroid Build Coastguard Worker                                   << "    default: res = coords.yzw;"
240*35238bceSAndroid Build Coastguard Worker                                   << "}");
241*35238bceSAndroid Build Coastguard Worker 
242*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "default_not_last", "Default label usage",
243*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "switch (${CONDITION})"
244*35238bceSAndroid Build Coastguard Worker                                   << "{"
245*35238bceSAndroid Build Coastguard Worker                                   << "    case 0: res = coords.xyz;    break;"
246*35238bceSAndroid Build Coastguard Worker                                   << "    default: res = coords.yzw;    break;"
247*35238bceSAndroid Build Coastguard Worker                                   << "    case 1: res = coords.wzy;    break;"
248*35238bceSAndroid Build Coastguard Worker                                   << "    case 3: res = coords.zyx;    break;"
249*35238bceSAndroid Build Coastguard Worker                                   << "}");
250*35238bceSAndroid Build Coastguard Worker 
251*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "no_default_label", "No match in switch without default label",
252*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "res = coords.yzw;\n"
253*35238bceSAndroid Build Coastguard Worker                                   << "switch (${CONDITION})"
254*35238bceSAndroid Build Coastguard Worker                                   << "{"
255*35238bceSAndroid Build Coastguard Worker                                   << "    case 0: res = coords.xyz;    break;"
256*35238bceSAndroid Build Coastguard Worker                                   << "    case 1: res = coords.wzy;    break;"
257*35238bceSAndroid Build Coastguard Worker                                   << "    case 3: res = coords.zyx;    break;"
258*35238bceSAndroid Build Coastguard Worker                                   << "}");
259*35238bceSAndroid Build Coastguard Worker 
260*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "default_only", "Default case only",
261*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "switch (${CONDITION})"
262*35238bceSAndroid Build Coastguard Worker                                   << "{"
263*35238bceSAndroid Build Coastguard Worker                                   << "    default:"
264*35238bceSAndroid Build Coastguard Worker                                   << "        res = coords.yzw;"
265*35238bceSAndroid Build Coastguard Worker                                   << "}",
266*35238bceSAndroid Build Coastguard Worker                     true);
267*35238bceSAndroid Build Coastguard Worker 
268*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "empty_case_default", "Empty case and default",
269*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "switch (${CONDITION})"
270*35238bceSAndroid Build Coastguard Worker                                   << "{"
271*35238bceSAndroid Build Coastguard Worker                                   << "    case 2:"
272*35238bceSAndroid Build Coastguard Worker                                   << "    default:"
273*35238bceSAndroid Build Coastguard Worker                                   << "        res = coords.yzw;"
274*35238bceSAndroid Build Coastguard Worker                                   << "}",
275*35238bceSAndroid Build Coastguard Worker                     true);
276*35238bceSAndroid Build Coastguard Worker 
277*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "fall_through", "Fall-through",
278*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "switch (${CONDITION})"
279*35238bceSAndroid Build Coastguard Worker                                   << "{"
280*35238bceSAndroid Build Coastguard Worker                                   << "    case 0: res = coords.xyz;    break;"
281*35238bceSAndroid Build Coastguard Worker                                   << "    case 1: res = coords.wzy;    break;"
282*35238bceSAndroid Build Coastguard Worker                                   << "    case 2: coords = coords.yzwx;"
283*35238bceSAndroid Build Coastguard Worker                                   << "    case 4: res = vec3(coords);    break;"
284*35238bceSAndroid Build Coastguard Worker                                   << "    case 3: res = coords.zyx;    break;"
285*35238bceSAndroid Build Coastguard Worker                                   << "}");
286*35238bceSAndroid Build Coastguard Worker 
287*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "fall_through_default", "Fall-through",
288*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "switch (${CONDITION})"
289*35238bceSAndroid Build Coastguard Worker                                   << "{"
290*35238bceSAndroid Build Coastguard Worker                                   << "    case 0: res = coords.xyz;    break;"
291*35238bceSAndroid Build Coastguard Worker                                   << "    case 1: res = coords.wzy;    break;"
292*35238bceSAndroid Build Coastguard Worker                                   << "    case 3: res = coords.zyx;    break;"
293*35238bceSAndroid Build Coastguard Worker                                   << "    case 2: coords = coords.yzwx;"
294*35238bceSAndroid Build Coastguard Worker                                   << "    default: res = vec3(coords);"
295*35238bceSAndroid Build Coastguard Worker                                   << "}");
296*35238bceSAndroid Build Coastguard Worker 
297*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "conditional_fall_through", "Fall-through",
298*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "highp vec4 tmp = coords;"
299*35238bceSAndroid Build Coastguard Worker                                   << "switch (${CONDITION})"
300*35238bceSAndroid Build Coastguard Worker                                   << "{"
301*35238bceSAndroid Build Coastguard Worker                                   << "    case 0: res = coords.xyz;    break;"
302*35238bceSAndroid Build Coastguard Worker                                   << "    case 1: res = coords.wzy;    break;"
303*35238bceSAndroid Build Coastguard Worker                                   << "    case 2:"
304*35238bceSAndroid Build Coastguard Worker                                   << "        tmp = coords.yzwx;"
305*35238bceSAndroid Build Coastguard Worker                                   << "    case 3:"
306*35238bceSAndroid Build Coastguard Worker                                   << "        res = vec3(tmp);"
307*35238bceSAndroid Build Coastguard Worker                                   << "        if (${CONDITION} != 3)"
308*35238bceSAndroid Build Coastguard Worker                                   << "            break;"
309*35238bceSAndroid Build Coastguard Worker                                   << "    default: res = tmp.zyx;        break;"
310*35238bceSAndroid Build Coastguard Worker                                   << "}");
311*35238bceSAndroid Build Coastguard Worker 
312*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "conditional_fall_through_2", "Fall-through",
313*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "highp vec4 tmp = coords;"
314*35238bceSAndroid Build Coastguard Worker                                   << "mediump int c = ${CONDITION};"
315*35238bceSAndroid Build Coastguard Worker                                   << "switch (c)"
316*35238bceSAndroid Build Coastguard Worker                                   << "{"
317*35238bceSAndroid Build Coastguard Worker                                   << "    case 0: res = coords.xyz;    break;"
318*35238bceSAndroid Build Coastguard Worker                                   << "    case 1: res = coords.wzy;    break;"
319*35238bceSAndroid Build Coastguard Worker                                   << "    case 2:"
320*35238bceSAndroid Build Coastguard Worker                                   << "        c += ${CONDITION};"
321*35238bceSAndroid Build Coastguard Worker                                   << "        tmp = coords.yzwx;"
322*35238bceSAndroid Build Coastguard Worker                                   << "    case 3:"
323*35238bceSAndroid Build Coastguard Worker                                   << "        res = vec3(tmp);"
324*35238bceSAndroid Build Coastguard Worker                                   << "        if (c == 4)"
325*35238bceSAndroid Build Coastguard Worker                                   << "            break;"
326*35238bceSAndroid Build Coastguard Worker                                   << "    default: res = tmp.zyx;        break;"
327*35238bceSAndroid Build Coastguard Worker                                   << "}");
328*35238bceSAndroid Build Coastguard Worker 
329*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "scope", "Basic switch statement usage",
330*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "switch (${CONDITION})"
331*35238bceSAndroid Build Coastguard Worker                                   << "{"
332*35238bceSAndroid Build Coastguard Worker                                   << "    case 0: res = coords.xyz;    break;"
333*35238bceSAndroid Build Coastguard Worker                                   << "    case 1: res = coords.wzy;    break;"
334*35238bceSAndroid Build Coastguard Worker                                   << "    case 2:"
335*35238bceSAndroid Build Coastguard Worker                                   << "    {"
336*35238bceSAndroid Build Coastguard Worker                                   << "        mediump vec3 t = coords.yzw;"
337*35238bceSAndroid Build Coastguard Worker                                   << "        res = t;"
338*35238bceSAndroid Build Coastguard Worker                                   << "        break;"
339*35238bceSAndroid Build Coastguard Worker                                   << "    }"
340*35238bceSAndroid Build Coastguard Worker                                   << "    case 3: res = coords.zyx;    break;"
341*35238bceSAndroid Build Coastguard Worker                                   << "}");
342*35238bceSAndroid Build Coastguard Worker 
343*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "switch_in_if", "Switch in for loop",
344*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "if (${CONDITION} >= 0)"
345*35238bceSAndroid Build Coastguard Worker                                   << "{"
346*35238bceSAndroid Build Coastguard Worker                                   << "    switch (${CONDITION})"
347*35238bceSAndroid Build Coastguard Worker                                   << "    {"
348*35238bceSAndroid Build Coastguard Worker                                   << "        case 0: res = coords.xyz;    break;"
349*35238bceSAndroid Build Coastguard Worker                                   << "        case 1: res = coords.wzy;    break;"
350*35238bceSAndroid Build Coastguard Worker                                   << "        case 2: res = coords.yzw;    break;"
351*35238bceSAndroid Build Coastguard Worker                                   << "        case 3: res = coords.zyx;    break;"
352*35238bceSAndroid Build Coastguard Worker                                   << "    }"
353*35238bceSAndroid Build Coastguard Worker                                   << "}");
354*35238bceSAndroid Build Coastguard Worker 
355*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "switch_in_for_loop", "Switch in for loop",
356*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "for (int i = 0; i <= ${CONDITION}; i++)"
357*35238bceSAndroid Build Coastguard Worker                                   << "{"
358*35238bceSAndroid Build Coastguard Worker                                   << "    switch (i)"
359*35238bceSAndroid Build Coastguard Worker                                   << "    {"
360*35238bceSAndroid Build Coastguard Worker                                   << "        case 0: res = coords.xyz;    break;"
361*35238bceSAndroid Build Coastguard Worker                                   << "        case 1: res = coords.wzy;    break;"
362*35238bceSAndroid Build Coastguard Worker                                   << "        case 2: res = coords.yzw;    break;"
363*35238bceSAndroid Build Coastguard Worker                                   << "        case 3: res = coords.zyx;    break;"
364*35238bceSAndroid Build Coastguard Worker                                   << "    }"
365*35238bceSAndroid Build Coastguard Worker                                   << "}");
366*35238bceSAndroid Build Coastguard Worker 
367*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "switch_in_while_loop", "Switch in while loop",
368*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "int i = 0;"
369*35238bceSAndroid Build Coastguard Worker                                   << "while (i <= ${CONDITION})"
370*35238bceSAndroid Build Coastguard Worker                                   << "{"
371*35238bceSAndroid Build Coastguard Worker                                   << "    switch (i)"
372*35238bceSAndroid Build Coastguard Worker                                   << "    {"
373*35238bceSAndroid Build Coastguard Worker                                   << "        case 0: res = coords.xyz;    break;"
374*35238bceSAndroid Build Coastguard Worker                                   << "        case 1: res = coords.wzy;    break;"
375*35238bceSAndroid Build Coastguard Worker                                   << "        case 2: res = coords.yzw;    break;"
376*35238bceSAndroid Build Coastguard Worker                                   << "        case 3: res = coords.zyx;    break;"
377*35238bceSAndroid Build Coastguard Worker                                   << "    }"
378*35238bceSAndroid Build Coastguard Worker                                   << "    i += 1;"
379*35238bceSAndroid Build Coastguard Worker                                   << "}");
380*35238bceSAndroid Build Coastguard Worker 
381*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "switch_in_do_while_loop", "Switch in do-while loop",
382*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "int i = 0;"
383*35238bceSAndroid Build Coastguard Worker                                   << "do"
384*35238bceSAndroid Build Coastguard Worker                                   << "{"
385*35238bceSAndroid Build Coastguard Worker                                   << "    switch (i)"
386*35238bceSAndroid Build Coastguard Worker                                   << "    {"
387*35238bceSAndroid Build Coastguard Worker                                   << "        case 0: res = coords.xyz;    break;"
388*35238bceSAndroid Build Coastguard Worker                                   << "        case 1: res = coords.wzy;    break;"
389*35238bceSAndroid Build Coastguard Worker                                   << "        case 2: res = coords.yzw;    break;"
390*35238bceSAndroid Build Coastguard Worker                                   << "        case 3: res = coords.zyx;    break;"
391*35238bceSAndroid Build Coastguard Worker                                   << "    }"
392*35238bceSAndroid Build Coastguard Worker                                   << "    i += 1;"
393*35238bceSAndroid Build Coastguard Worker                                   << "} while (i <= ${CONDITION});");
394*35238bceSAndroid Build Coastguard Worker 
395*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "if_in_switch", "Basic switch statement usage",
396*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "switch (${CONDITION})"
397*35238bceSAndroid Build Coastguard Worker                                   << "{"
398*35238bceSAndroid Build Coastguard Worker                                   << "    case 0: res = coords.xyz;    break;"
399*35238bceSAndroid Build Coastguard Worker                                   << "    case 1: res = coords.wzy;    break;"
400*35238bceSAndroid Build Coastguard Worker                                   << "    default:"
401*35238bceSAndroid Build Coastguard Worker                                   << "        if (${CONDITION} == 2)"
402*35238bceSAndroid Build Coastguard Worker                                   << "            res = coords.yzw;"
403*35238bceSAndroid Build Coastguard Worker                                   << "        else"
404*35238bceSAndroid Build Coastguard Worker                                   << "            res = coords.zyx;"
405*35238bceSAndroid Build Coastguard Worker                                   << "        break;"
406*35238bceSAndroid Build Coastguard Worker                                   << "}");
407*35238bceSAndroid Build Coastguard Worker 
408*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "for_loop_in_switch", "Basic switch statement usage",
409*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "switch (${CONDITION})"
410*35238bceSAndroid Build Coastguard Worker                                   << "{"
411*35238bceSAndroid Build Coastguard Worker                                   << "    case 0: res = coords.xyz;    break;"
412*35238bceSAndroid Build Coastguard Worker                                   << "    case 1:"
413*35238bceSAndroid Build Coastguard Worker                                   << "    case 2:"
414*35238bceSAndroid Build Coastguard Worker                                   << "    {"
415*35238bceSAndroid Build Coastguard Worker                                   << "        highp vec3 t = coords.yzw;"
416*35238bceSAndroid Build Coastguard Worker                                   << "        for (int i = 0; i < ${CONDITION}; i++)"
417*35238bceSAndroid Build Coastguard Worker                                   << "            t = t.zyx;"
418*35238bceSAndroid Build Coastguard Worker                                   << "        res = t;"
419*35238bceSAndroid Build Coastguard Worker                                   << "        break;"
420*35238bceSAndroid Build Coastguard Worker                                   << "    }"
421*35238bceSAndroid Build Coastguard Worker                                   << "    default: res = coords.zyx;    break;"
422*35238bceSAndroid Build Coastguard Worker                                   << "}");
423*35238bceSAndroid Build Coastguard Worker 
424*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "while_loop_in_switch", "Basic switch statement usage",
425*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "switch (${CONDITION})"
426*35238bceSAndroid Build Coastguard Worker                                   << "{"
427*35238bceSAndroid Build Coastguard Worker                                   << "    case 0: res = coords.xyz;    break;"
428*35238bceSAndroid Build Coastguard Worker                                   << "    case 1:"
429*35238bceSAndroid Build Coastguard Worker                                   << "    case 2:"
430*35238bceSAndroid Build Coastguard Worker                                   << "    {"
431*35238bceSAndroid Build Coastguard Worker                                   << "        highp vec3 t = coords.yzw;"
432*35238bceSAndroid Build Coastguard Worker                                   << "        int i = 0;"
433*35238bceSAndroid Build Coastguard Worker                                   << "        while (i < ${CONDITION})"
434*35238bceSAndroid Build Coastguard Worker                                   << "        {"
435*35238bceSAndroid Build Coastguard Worker                                   << "            t = t.zyx;"
436*35238bceSAndroid Build Coastguard Worker                                   << "            i += 1;"
437*35238bceSAndroid Build Coastguard Worker                                   << "        }"
438*35238bceSAndroid Build Coastguard Worker                                   << "        res = t;"
439*35238bceSAndroid Build Coastguard Worker                                   << "        break;"
440*35238bceSAndroid Build Coastguard Worker                                   << "    }"
441*35238bceSAndroid Build Coastguard Worker                                   << "    default: res = coords.zyx;    break;"
442*35238bceSAndroid Build Coastguard Worker                                   << "}");
443*35238bceSAndroid Build Coastguard Worker 
444*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "do_while_loop_in_switch", "Basic switch statement usage",
445*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "switch (${CONDITION})"
446*35238bceSAndroid Build Coastguard Worker                                   << "{"
447*35238bceSAndroid Build Coastguard Worker                                   << "    case 0: res = coords.xyz;    break;"
448*35238bceSAndroid Build Coastguard Worker                                   << "    case 1:"
449*35238bceSAndroid Build Coastguard Worker                                   << "    case 2:"
450*35238bceSAndroid Build Coastguard Worker                                   << "    {"
451*35238bceSAndroid Build Coastguard Worker                                   << "        highp vec3 t = coords.yzw;"
452*35238bceSAndroid Build Coastguard Worker                                   << "        int i = 0;"
453*35238bceSAndroid Build Coastguard Worker                                   << "        do"
454*35238bceSAndroid Build Coastguard Worker                                   << "        {"
455*35238bceSAndroid Build Coastguard Worker                                   << "            t = t.zyx;"
456*35238bceSAndroid Build Coastguard Worker                                   << "            i += 1;"
457*35238bceSAndroid Build Coastguard Worker                                   << "        } while (i < ${CONDITION});"
458*35238bceSAndroid Build Coastguard Worker                                   << "        res = t;"
459*35238bceSAndroid Build Coastguard Worker                                   << "        break;"
460*35238bceSAndroid Build Coastguard Worker                                   << "    }"
461*35238bceSAndroid Build Coastguard Worker                                   << "    default: res = coords.zyx;    break;"
462*35238bceSAndroid Build Coastguard Worker                                   << "}");
463*35238bceSAndroid Build Coastguard Worker 
464*35238bceSAndroid Build Coastguard Worker     makeSwitchCases(this, "switch_in_switch", "Basic switch statement usage",
465*35238bceSAndroid Build Coastguard Worker                     LineStream(1) << "switch (${CONDITION})"
466*35238bceSAndroid Build Coastguard Worker                                   << "{"
467*35238bceSAndroid Build Coastguard Worker                                   << "    case 0: res = coords.xyz;    break;"
468*35238bceSAndroid Build Coastguard Worker                                   << "    case 1:"
469*35238bceSAndroid Build Coastguard Worker                                   << "    case 2:"
470*35238bceSAndroid Build Coastguard Worker                                   << "        switch (${CONDITION} - 1)"
471*35238bceSAndroid Build Coastguard Worker                                   << "        {"
472*35238bceSAndroid Build Coastguard Worker                                   << "            case 0: res = coords.wzy;    break;"
473*35238bceSAndroid Build Coastguard Worker                                   << "            case 1: res = coords.yzw;    break;"
474*35238bceSAndroid Build Coastguard Worker                                   << "        }"
475*35238bceSAndroid Build Coastguard Worker                                   << "        break;"
476*35238bceSAndroid Build Coastguard Worker                                   << "    default: res = coords.zyx;    break;"
477*35238bceSAndroid Build Coastguard Worker                                   << "}");
478*35238bceSAndroid Build Coastguard Worker 
479*35238bceSAndroid Build Coastguard Worker     // Negative cases.
480*35238bceSAndroid Build Coastguard Worker     ShaderLibrary library(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo());
481*35238bceSAndroid Build Coastguard Worker     vector<tcu::TestNode *> negativeCases = library.loadShaderFile("shaders/switch.test");
482*35238bceSAndroid Build Coastguard Worker 
483*35238bceSAndroid Build Coastguard Worker     for (vector<tcu::TestNode *>::iterator i = negativeCases.begin(); i != negativeCases.end(); i++)
484*35238bceSAndroid Build Coastguard Worker         addChild(*i);
485*35238bceSAndroid Build Coastguard Worker }
486*35238bceSAndroid Build Coastguard Worker 
487*35238bceSAndroid Build Coastguard Worker } // namespace Functional
488*35238bceSAndroid Build Coastguard Worker } // namespace gles3
489*35238bceSAndroid Build Coastguard Worker } // namespace deqp
490