Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / deqp / functional / gles3 / es3fShaderSwitchTests.js
blob27670f9d644a861fa5411766c05e06a0fdec53fb
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES Utilities
3  * ------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
21 'use strict';
22 goog.provide('functional.gles3.es3fShaderSwitchTests');
23 goog.require('framework.common.tcuStringTemplate');
24 goog.require('framework.common.tcuTestCase');
25 goog.require('modules.shared.glsShaderRenderCase');
28 goog.scope(function() {
29     var es3fShaderSwitchTests = functional.gles3.es3fShaderSwitchTests;
30     var glsShaderRenderCase = modules.shared.glsShaderRenderCase;
31     var tcuTestCase = framework.common.tcuTestCase;
32     var tcuStringTemplate = framework.common.tcuStringTemplate;
34     /**
35      * @constructor
36      * @extends {glsShaderRenderCase.ShaderRenderCase}
37      * @param {string} name
38      * @param {string} description
39      * @param {boolean} isVertexCase
40      * @param {string} vtxSource
41      * @param {string} fragSource
42      * @param {glsShaderRenderCase.ShaderEvalFunc=} evalFunc
43      */
44     es3fShaderSwitchTests.ShaderSwitchCase = function(name, description, isVertexCase, vtxSource, fragSource, evalFunc) {
45         glsShaderRenderCase.ShaderRenderCase.call(this, name, description, isVertexCase, evalFunc);
46         /** @type {string} */ this.m_vertShaderSource = vtxSource;
47         /** @type {string} */ this.m_fragShaderSource = fragSource;
48     };
50     es3fShaderSwitchTests.ShaderSwitchCase.prototype = Object.create(glsShaderRenderCase.ShaderRenderCase.prototype);
51     es3fShaderSwitchTests.ShaderSwitchCase.prototype.constructor = es3fShaderSwitchTests.ShaderSwitchCase;
53     /**
54      * @enum {number}
55      */
56     es3fShaderSwitchTests.SwitchType = {
57         STATIC: 0,
58         UNIFORM: 1,
59         DYNAMIC: 2
60     };
62     /** @param {glsShaderRenderCase.ShaderEvalContext} evalCtx */
63     es3fShaderSwitchTests.evalSwitchStatic = function(evalCtx) {
64         evalCtx.color[0] = evalCtx.coords[1];
65         evalCtx.color[1] = evalCtx.coords[2];
66         evalCtx.color[2] = evalCtx.coords[3];
67     };
69     /** @param {glsShaderRenderCase.ShaderEvalContext} evalCtx */
70     es3fShaderSwitchTests.evalSwitchUniform = function(evalCtx) {
71         evalCtx.color[0] = evalCtx.coords[1];
72         evalCtx.color[1] = evalCtx.coords[2];
73         evalCtx.color[2] = evalCtx.coords[3];
74     };
76     /** @param {glsShaderRenderCase.ShaderEvalContext} evalCtx */
77     es3fShaderSwitchTests.evalSwitchDynamic = function(evalCtx) {
78         switch (Math.floor(evalCtx.coords[2]*1.5 + 2.0)) {
79             case 0:
80                 evalCtx.color[0] = evalCtx.coords[0];
81                 evalCtx.color[1] = evalCtx.coords[1];
82                 evalCtx.color[2] = evalCtx.coords[2];
83                 break;
84             case 1:
85                 evalCtx.color[0] = evalCtx.coords[3];
86                 evalCtx.color[1] = evalCtx.coords[2];
87                 evalCtx.color[2] = evalCtx.coords[1];
88                 break;
89             case 2:
90                 evalCtx.color[0] = evalCtx.coords[1];
91                 evalCtx.color[1] = evalCtx.coords[2];
92                 evalCtx.color[2] = evalCtx.coords[3];
93                 break;
94             case 3:
95                 evalCtx.color[0] = evalCtx.coords[2];
96                 evalCtx.color[1] = evalCtx.coords[1];
97                 evalCtx.color[2] = evalCtx.coords[0];
98                 break;
99             default:
100                 evalCtx.color[0] = evalCtx.coords[0];
101                 evalCtx.color[1] = evalCtx.coords[0];
102                 evalCtx.color[2] = evalCtx.coords[0];
103                 break;
104         }
105     };
107     /**
108      * @param  {string} name
109      * @param  {string} desc
110      * @param  {es3fShaderSwitchTests.SwitchType} type
111      * @param  {boolean} isVertex
112      * @param  {string} switchBody
113      * @return {es3fShaderSwitchTests.ShaderSwitchCase}
114      */
115     es3fShaderSwitchTests.makeSwitchCase = function(name, desc, type, isVertex, switchBody) {
116         /** @type {string} */ var vtx = '';
117         /** @type {string} */ var frag = '';
118         /** @type {string} */ var op = '';
120         vtx += "#version 300 es\n" +
121                "in highp vec4 a_position;\n" +
122                "in highp vec4 a_coords;\n";
123         frag += "#version 300 es\n" +
124                 "layout(location = 0) out mediump vec4 o_color;\n";
126         if (isVertex) {
127             vtx += "out mediump vec4 v_color;\n";
128             frag += "in mediump vec4 v_color;\n";
129         } else {
130             vtx += "out highp vec4 v_coords;\n";
131             frag += "in highp vec4 v_coords;\n";
132         }
134         if (type === es3fShaderSwitchTests.SwitchType.UNIFORM)
135             op += "uniform highp int ui_two;\n";
137         vtx += isVertex ? op : '';
138         frag += isVertex ? '' : op;
139         op = '';
141         vtx += "\n" +
142             "void main (void)\n" +
143             "{\n" +
144             "    gl_Position = a_position;\n";
145         frag += "\n" +
146                 "void main (void)\n" +
147                 "{\n";
149         // Setup.
150         op += "    highp vec4 coords = " + (isVertex ? "a_coords" : "v_coords") + ";\n";
151         op += "    mediump vec3 res = vec3(0.0);\n\n";
152         vtx += isVertex ? op : '';
153         frag += isVertex ? '' : op;
154         op = '';
156         // Switch body.
157         var params = {};
158         params["CONDITION"] = type == es3fShaderSwitchTests.SwitchType.STATIC ? "2"     :
159                               type == es3fShaderSwitchTests.SwitchType.UNIFORM ? "ui_two" :
160                               type == es3fShaderSwitchTests.SwitchType.DYNAMIC ? "int(floor(coords.z*1.5 + 2.0))" : "???";
162         op += tcuStringTemplate.specialize(switchBody, params);
163         op += "\n";
165         vtx += isVertex ? op : '';
166         frag += isVertex ? '' : op;
167         op = '';
169         if (isVertex) {
170             vtx += "    v_color = vec4(res, 1.0);\n";
171             frag += "    o_color = v_color;\n";
172         } else {
173             vtx += "    v_coords = a_coords;\n";
174             frag += "    o_color = vec4(res, 1.0);\n";
175         }
177         vtx += "}\n";
178         frag += "}\n";
180         return new es3fShaderSwitchTests.ShaderSwitchCase(name, desc, isVertex, vtx, frag,
181                                     type === es3fShaderSwitchTests.SwitchType.STATIC ? es3fShaderSwitchTests.evalSwitchStatic :
182                                     type === es3fShaderSwitchTests.SwitchType.UNIFORM ? es3fShaderSwitchTests.evalSwitchUniform :
183                                     type === es3fShaderSwitchTests.SwitchType.DYNAMIC ? es3fShaderSwitchTests.evalSwitchDynamic : undefined);
184     };
186     /**
187      * @param {tcuTestCase.DeqpTest} group
188      * @param {string} name
189      * @param {string} desc
190      * @param {string} switchBody
191      */
192     es3fShaderSwitchTests.makeSwitchCases = function(group, name, desc, switchBody) {
193         /** @type {Array<string>} */ var switchTypeNames = ["static", "uniform", "dynamic"];
194         for (var type in es3fShaderSwitchTests.SwitchType) {
195             group.addChild(es3fShaderSwitchTests.makeSwitchCase(name + "_" + switchTypeNames[es3fShaderSwitchTests.SwitchType[type]] + "_vertex", desc, es3fShaderSwitchTests.SwitchType[type], true, switchBody));
196             group.addChild(es3fShaderSwitchTests.makeSwitchCase(name + "_" + switchTypeNames[es3fShaderSwitchTests.SwitchType[type]] + "_fragment", desc, es3fShaderSwitchTests.SwitchType[type], false, switchBody));
197         }
198     };
200     /**
201      * @constructor
202      * @extends {tcuTestCase.DeqpTest}
203      */
204     es3fShaderSwitchTests.ShaderSwitchTests = function() {
205         tcuTestCase.DeqpTest.call(this, 'switch', 'Switch statement tests');
206     };
208     es3fShaderSwitchTests.ShaderSwitchTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
209     es3fShaderSwitchTests.ShaderSwitchTests.prototype.constructor = es3fShaderSwitchTests.ShaderSwitchTests;
211     es3fShaderSwitchTests.ShaderSwitchTests.prototype.init = function() {
212         // Expected swizzles:
213         // 0: xyz
214         // 1: wzy
215         // 2: yzw
216         // 3: zyx
217         es3fShaderSwitchTests.makeSwitchCases(this, "basic", "Basic switch statement usage",
218             '   switch (${CONDITION})\n' +
219             '    {\n' +
220             '        case 0:        res = coords.xyz;    break;\n' +
221             '        case 1:        res = coords.wzy;    break;\n' +
222             '        case 2:        res = coords.yzw;    break;\n' +
223             '        case 3:        res = coords.zyx;    break;\n' +
224             '    }\n');
226         es3fShaderSwitchTests.makeSwitchCases(this, "const_expr_in_label", "Constant expression in label",
227             '    const int t = 2;\n' +
228             '    switch (${CONDITION})\n' +
229             '    {\n' +
230             '        case int(0.0):    res = coords.xyz;    break;\n' +
231             '        case 2-1:        res = coords.wzy;    break;\n' +
232             '        case 3&(1<<1):    res = coords.yzw;    break;\n' +
233             '        case t+1:        res = coords.zyx;    break;\n' +
234             '    }\n');
236         es3fShaderSwitchTests.makeSwitchCases(this, "default_label", "Default label usage",
237             '    switch (${CONDITION})\n' +
238             '    {\n' +
239             '        case 0:        res = coords.xyz;    break;\n' +
240             '        case 1:        res = coords.wzy;    break;\n' +
241             '        case 3:        res = coords.zyx;    break;\n' +
242             '        default:    res = coords.yzw;\n' +
243             '    }\n');
245         es3fShaderSwitchTests.makeSwitchCases(this, "default_not_last", "Default label usage",
246             '    switch (${CONDITION})\n' +
247             '    {\n' +
248             '        case 0:        res = coords.xyz;    break;\n' +
249             '        default:    res = coords.yzw;    break;\n' +
250             '        case 1:        res = coords.wzy;    break;\n' +
251             '        case 3:        res = coords.zyx;    break;\n' +
252             '    }\n');
254         es3fShaderSwitchTests.makeSwitchCases(this, "no_default_label", "No match in switch without default label",
255             '    res = coords.yzw;\n\n' +
256             '    switch (${CONDITION})\n' +
257             '    {\n' +
258             '        case 0:        res = coords.xyz;    break;\n' +
259             '        case 1:        res = coords.wzy;    break;\n' +
260             '        case 3:        res = coords.zyx;    break;\n' +
261             '    }\n');
263         es3fShaderSwitchTests.makeSwitchCases(this, "fall_through", "Fall-through",
264             '    switch (${CONDITION})\n' +
265             '    {\n' +
266             '        case 0:        res = coords.xyz;    break;\n' +
267             '        case 1:        res = coords.wzy;    break;\n' +
268             '        case 2:        coords = coords.yzwx;\n' +
269             '        case 4:        res = vec3(coords);    break;\n' +
270             '        case 3:        res = coords.zyx;    break;\n' +
271             '    }\n');
273         es3fShaderSwitchTests.makeSwitchCases(this, "fall_through_default", "Fall-through",
274             '    switch (${CONDITION})\n' +
275             '    {\n' +
276             '        case 0:        res = coords.xyz;    break;\n' +
277             '        case 1:        res = coords.wzy;    break;\n' +
278             '        case 3:        res = coords.zyx;    break;\n' +
279             '        case 2:        coords = coords.yzwx;\n' +
280             '        default:    res = vec3(coords);\n' +
281             '    }\n');
283         es3fShaderSwitchTests.makeSwitchCases(this, "conditional_fall_through", "Fall-through",
284             '    highp vec4 tmp = coords;\n' +
285             '    switch (${CONDITION})\n' +
286             '    {\n' +
287             '        case 0:        res = coords.xyz;    break;\n' +
288             '        case 1:        res = coords.wzy;    break;\n' +
289             '        case 2:\n' +
290             '            tmp = coords.yzwx;\n' +
291             '        case 3:\n' +
292             '            res = vec3(tmp);\n' +
293             '            if (${CONDITION} != 3)\n' +
294             '                break;\n' +
295             '        default:    res = tmp.zyx;        break;\n' +
296             '    }\n');
298         es3fShaderSwitchTests.makeSwitchCases(this, "conditional_fall_through_2", "Fall-through",
299             '    highp vec4 tmp = coords;\n' +
300             '    mediump int c = ${CONDITION};\n' +
301             '    switch (c)\n' +
302             '    {\n' +
303             '        case 0:        res = coords.xyz;    break;\n' +
304             '        case 1:        res = coords.wzy;    break;\n' +
305             '        case 2:\n' +
306             '            c += ${CONDITION};\n' +
307             '            tmp = coords.yzwx;\n' +
308             '        case 3:\n' +
309             '            res = vec3(tmp);\n' +
310             '            if (c == 4)\n' +
311             '                break;\n' +
312             '        default:    res = tmp.zyx;        break;\n' +
313             '    }\n');
315         es3fShaderSwitchTests.makeSwitchCases(this, "scope", "Basic switch statement usage",
316             '    switch (${CONDITION})\n' +
317             '    {\n' +
318             '        case 0:        res = coords.xyz;    break;\n' +
319             '        case 1:        res = coords.wzy;    break;\n' +
320             '        case 2:\n' +
321             '        {\n' +
322             '            mediump vec3 t = coords.yzw;\n' +
323             '            res = t;\n' +
324             '            break;\n' +
325             '        }\n' +
326             '        case 3:        res = coords.zyx;    break;\n' +
327             '    }\n');
329         es3fShaderSwitchTests.makeSwitchCases(this, "switch_in_if", "Switch in for loop",
330             '    if (${CONDITION} >= 0)\n' +
331             '    {\n' +
332             '        switch (${CONDITION})\n' +
333             '        {\n' +
334             '            case 0:        res = coords.xyz;    break;\n' +
335             '            case 1:        res = coords.wzy;    break;\n' +
336             '            case 2:        res = coords.yzw;    break;\n' +
337             '            case 3:        res = coords.zyx;    break;\n' +
338             '        }\n' +
339             '    }\n');
341         es3fShaderSwitchTests.makeSwitchCases(this, "switch_in_for_loop", "Switch in for loop",
342             '    for (int i = 0; i <= ${CONDITION}; i++)\n' +
343             '    {\n' +
344             '        switch (i)\n' +
345             '        {\n' +
346             '            case 0:        res = coords.xyz;    break;\n' +
347             '            case 1:        res = coords.wzy;    break;\n' +
348             '            case 2:        res = coords.yzw;    break;\n' +
349             '            case 3:        res = coords.zyx;    break;\n' +
350             '        }\n' +
351             '    }\n');
353         es3fShaderSwitchTests.makeSwitchCases(this, "switch_in_while_loop", "Switch in while loop",
354             '    int i = 0;\n' +
355             '    while (i <= ${CONDITION})\n' +
356             '    {\n' +
357             '        switch (i)\n' +
358             '        {\n' +
359             '            case 0:        res = coords.xyz;    break;\n' +
360             '            case 1:        res = coords.wzy;    break;\n' +
361             '            case 2:        res = coords.yzw;    break;\n' +
362             '            case 3:        res = coords.zyx;    break;\n' +
363             '        }\n' +
364             '        i += 1;\n' +
365             '    }\n');
367         es3fShaderSwitchTests.makeSwitchCases(this, "switch_in_do_while_loop", "Switch in do-while loop",
368             '    int i = 0;\n' +
369             '    do\n' +
370             '    {\n' +
371             '        switch (i)\n' +
372             '        {\n' +
373             '            case 0:        res = coords.xyz;    break;\n' +
374             '            case 1:        res = coords.wzy;    break;\n' +
375             '            case 2:        res = coords.yzw;    break;\n' +
376             '            case 3:        res = coords.zyx;    break;\n' +
377             '        }\n' +
378             '        i += 1;\n' +
379             '    } while (i <= ${CONDITION});\n');
381         es3fShaderSwitchTests.makeSwitchCases(this, "if_in_switch", "Basic switch statement usage",
382             '    switch (${CONDITION})\n' +
383             '    {\n' +
384             '        case 0:        res = coords.xyz;    break;\n' +
385             '        case 1:        res = coords.wzy;    break;\n' +
386             '        default:\n' +
387             '            if (${CONDITION} == 2)\n' +
388             '                res = coords.yzw;\n' +
389             '            else\n' +
390             '                res = coords.zyx;\n' +
391             '            break;\n' +
392             '    }\n');
394         es3fShaderSwitchTests.makeSwitchCases(this, "for_loop_in_switch", "Basic switch statement usage",
395             '    switch (${CONDITION})\n' +
396             '    {\n' +
397             '        case 0:        res = coords.xyz;    break;\n' +
398             '        case 1:\n' +
399             '        case 2:\n' +
400             '        {\n' +
401             '            highp vec3 t = coords.yzw;\n' +
402             '            for (int i = 0; i < ${CONDITION}; i++)\n' +
403             '                t = t.zyx;\n' +
404             '            res = t;\n' +
405             '            break;\n' +
406             '        }\n' +
407             '        default:    res = coords.zyx;    break;\n' +
408             '    }\n');
410         es3fShaderSwitchTests.makeSwitchCases(this, "while_loop_in_switch", "Basic switch statement usage",
411             '    switch (${CONDITION})\n' +
412             '    {\n' +
413             '        case 0:        res = coords.xyz;    break;\n' +
414             '        case 1:\n' +
415             '        case 2:\n' +
416             '        {\n' +
417             '            highp vec3 t = coords.yzw;\n' +
418             '            int i = 0;\n' +
419             '            while (i < ${CONDITION})\n' +
420             '            {\n' +
421             '                t = t.zyx;\n' +
422             '                i += 1;\n' +
423             '            }\n' +
424             '            res = t;\n' +
425             '            break;\n' +
426             '        }\n' +
427             '        default:    res = coords.zyx;    break;\n' +
428             '    }\n');
430         es3fShaderSwitchTests.makeSwitchCases(this, "do_while_loop_in_switch", "Basic switch statement usage",
431             '    switch (${CONDITION})\n' +
432             '    {\n' +
433             '        case 0:        res = coords.xyz;    break;\n' +
434             '        case 1:\n' +
435             '        case 2:\n' +
436             '        {\n' +
437             '            highp vec3 t = coords.yzw;\n' +
438             '            int i = 0;\n' +
439             '            do\n' +
440             '            {\n' +
441             '                t = t.zyx;\n' +
442             '                i += 1;\n' +
443             '            } while (i < ${CONDITION});\n' +
444             '            res = t;\n' +
445             '            break;\n' +
446             '        }\n' +
447             '        default:    res = coords.zyx;    break;\n' +
448             '    }\n');
450         es3fShaderSwitchTests.makeSwitchCases(this, "switch_in_switch", "Basic switch statement usage",
451             '    switch (${CONDITION})\n' +
452             '    {\n' +
453             '        case 0:        res = coords.xyz;    break;\n' +
454             '        case 1:\n' +
455             '        case 2:\n' +
456             '            switch (${CONDITION} - 1)\n' +
457             '            {\n' +
458             '                case 0:        res = coords.wzy;    break;\n' +
459             '                case 1:        res = coords.yzw;    break;\n' +
460             '            }\n' +
461             '            break;\n' +
462             '        default:    res = coords.zyx;    break;\n' +
463             '}\n');
465         // Negative cases.
466         // This is being tested somwhere else: data/gles3/shaders/switch.html
467     };
469     /**
470      * Run test
471      * @param {WebGL2RenderingContext} context
472      */
473     es3fShaderSwitchTests.run = function(context) {
474         gl = context;
475         //Set up Test Root parameters
476         var state = tcuTestCase.runner;
477         state.setRoot(new es3fShaderSwitchTests.ShaderSwitchTests());
479         //Set up name and description of this test series.
480         setCurrentTestName(state.testCases.fullName());
481         description(state.testCases.getDescription());
482         try {
483             //Run test cases
484             tcuTestCase.runTestCases();
485         }
486         catch (err) {
487             testFailedOptions('Failed to es3fShaderSwitchTests.run tests', false);
488             tcuTestCase.runner.terminate();
489         }
490     };