Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / deqp / functional / gles3 / es3fShaderStructTests.js
blob3c23545d7599e76b4f805ec6c7df2cdd8300be0b
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.es3fShaderStructTests');
23 goog.require('framework.common.tcuTestCase');
24 goog.require('framework.common.tcuTexture');
25 goog.require('framework.common.tcuTextureUtil');
26 goog.require('framework.delibs.debase.deMath');
27 // goog.require('framework.opengl.gluShaderUtil');
28 goog.require('framework.opengl.gluTexture');
29 goog.require('modules.shared.glsShaderRenderCase');
30 goog.require('framework.common.tcuStringTemplate');
32 goog.scope(function() {
33         var es3fShaderStructTests = functional.gles3.es3fShaderStructTests;
34         var tcuTestCase = framework.common.tcuTestCase;
35         var tcuTexture = framework.common.tcuTexture;
36         var tcuTextureUtil = framework.common.tcuTextureUtil;
37         var deMath = framework.delibs.debase.deMath;
38         // var gluShaderUtil = framework.opengl.gluShaderUtil;
39         var glsShaderRenderCase = modules.shared.glsShaderRenderCase;
40         var gluTexture = framework.opengl.gluTexture;
41         var tcuStringTemplate = framework.common.tcuStringTemplate;
43         /** @typedef {function(WebGLProgram, Array<number>)} */
44         es3fShaderStructTests.SetupUniformsFunc;
46         /** @const {number} */ es3fShaderStructTests.TEXTURE_BRICK = 0;
49         /**
50          * @constructor
51          * @extends {glsShaderRenderCase.ShaderRenderCase}
52          * @param  {string} name
53          * @param  {string} description
54          * @param  {boolean} isVertexCase
55          * @param  {boolean} usesTextures
56          * @param  {glsShaderRenderCase.ShaderEvalFunc} evalFunc
57          * @param  {?es3fShaderStructTests.SetupUniformsFunc} setupUniformsFunc
58          * @param  {string} vertShaderSource
59          * @param  {string} fragShaderSource
60          */
61         es3fShaderStructTests.ShaderStructCase = function(name, description, isVertexCase, usesTextures, evalFunc, setupUniformsFunc, vertShaderSource, fragShaderSource) {
62                 glsShaderRenderCase.ShaderRenderCase.call(this, name, description, isVertexCase, evalFunc);
63                 /** @type {?es3fShaderStructTests.SetupUniformsFunc} */ this.m_setupUniforms = setupUniformsFunc;
64                 /** @type {boolean} */ this.m_usesTexture = usesTextures;
65                 /** @type {gluTexture.Texture2D} */ this.m_brickTexture = null;
66                 /** @type {string} */ this.m_vertShaderSource = vertShaderSource;
67                 /** @type {string} */ this.m_fragShaderSource = fragShaderSource;
68         };
70         es3fShaderStructTests.ShaderStructCase.prototype = Object.create(glsShaderRenderCase.ShaderRenderCase.prototype);
71         es3fShaderStructTests.ShaderStructCase.prototype.constructor = es3fShaderStructTests.ShaderStructCase;
73         es3fShaderStructTests.ShaderStructCase.prototype.init = function() {
74                 if (this.m_usesTexture) {
75                         this.m_brickTexture = gluTexture.texture2DFromInternalFormat(gl, gl.RGBA8, 256, 256);
76                         var ref = this.m_brickTexture.getRefTexture();
77                         for (var i = 0 ; i < ref.getNumLevels(); i++) {
78                                 ref.allocLevel(i);
79                                 tcuTextureUtil.fillWithGrid(ref.getLevel(i), 8, [0.2, 0.7, 0.1, 1.0], [0.7, 0.1, 0.5, 0.8]);
80                         }
81                         this.m_brickTexture.upload();
83                         this.m_textures.push(new glsShaderRenderCase.TextureBinding(
84                                 this.m_brickTexture,
85                                 new tcuTexture.Sampler(
86                                         tcuTexture.WrapMode.CLAMP_TO_EDGE,
87                                         tcuTexture.WrapMode.CLAMP_TO_EDGE,
88                                         tcuTexture.WrapMode.CLAMP_TO_EDGE,
89                                         tcuTexture.FilterMode.LINEAR,
90                                         tcuTexture.FilterMode.LINEAR)));
92                         assertMsgOptions(this.m_textures.length === 1, 'Only one texture required', false, true);
93                 }
94                 this.postinit();
95         };
97         es3fShaderStructTests.ShaderStructCase.prototype.deinit = function() {
98                 glsShaderRenderCase.ShaderRenderCase.prototype.deinit.call(this);
99                 this.m_brickTexture = null;
100         };
102         /**
103          * @param  {WebGLProgram} programID
104          * @param  {Array<number>} constCoords
105          */
106         es3fShaderStructTests.ShaderStructCase.prototype.setupUniforms = function(programID, constCoords) {
107                 glsShaderRenderCase.ShaderRenderCase.prototype.setupUniforms.call(this, programID, constCoords);
108                 if (this.m_setupUniforms)
109                         this.m_setupUniforms(programID, constCoords);
110         };
112         /**
113          * @param {string} name
114          * @param {string} description
115          * @param {boolean} isVertexCase
116          * @param {boolean} usesTextures
117          * @param {glsShaderRenderCase.ShaderEvalFunc} evalFunc
118          * @param {?es3fShaderStructTests.SetupUniformsFunc} setupUniforms
119          * @param {string} shaderSrc
120          */
121         es3fShaderStructTests.ShaderStructCase.createStructCase = function(name, description, isVertexCase, usesTextures, evalFunc, setupUniforms, shaderSrc) {
122                 /** @type {string} */ var defaultVertSrc =
123                         '#version 300 es\n' +
124                         'in highp vec4 a_position;\n' +
125                         'in highp vec4 a_coords;\n' +
126                         'out mediump vec4 v_coords;\n\n' +
127                         'void main (void)\n' +
128                         '{\n' +
129                         '       v_coords = a_coords;\n' +
130                         '       gl_Position = a_position;\n' +
131                         '}\n';
132                 /** @type {string} */ var defaultFragSrc =
133                         '#version 300 es\n' +
134                         'in mediump vec4 v_color;\n' +
135                         'layout(location = 0) out mediump vec4 o_color;\n\n' +
136                         'void main (void)\n' +
137                         '{\n' +
138                         '       o_color = v_color;\n' +
139                         '}\n';
141                 // Fill in specialization parameters.
142                 var spParams = {};
143                 if (isVertexCase) {
144                         spParams["HEADER"] =
145                                 "#version 300 es\n" +
146                                 "in highp vec4 a_position;\n" +
147                                 "in highp vec4 a_coords;\n" +
148                                 "out mediump vec4 v_color;";
149                         spParams["COORDS"]              = "a_coords";
150                         spParams["DST"]                 = "v_color";
151                         spParams["ASSIGN_POS"]  = "gl_Position = a_position;";
152                 }
153                 else {
154                         spParams["HEADER"]      =
155                                 "#version 300 es\n" +
156                                 "in mediump vec4 v_coords;\n" +
157                                 "layout(location = 0) out mediump vec4 o_color;";
158                         spParams["COORDS"]                      = "v_coords";
159                         spParams["DST"]                         = "o_color";
160                         spParams["ASSIGN_POS"]          = "";
161                 }
163                 if (isVertexCase)
164                         return new es3fShaderStructTests.ShaderStructCase(name, description, isVertexCase, usesTextures, evalFunc, setupUniforms, tcuStringTemplate.specialize(shaderSrc, spParams), defaultFragSrc);
165                 else
166                         return new es3fShaderStructTests.ShaderStructCase(name, description, isVertexCase, usesTextures, evalFunc, setupUniforms, defaultVertSrc, tcuStringTemplate.specialize(shaderSrc, spParams));
167         };
169         /**
170          * @constructor
171          * @extends {tcuTestCase.DeqpTest}
172          */
173         es3fShaderStructTests.LocalStructTests = function() {
174                 tcuTestCase.DeqpTest.call(this, 'local', 'Local structs');
175                 this.makeExecutable();
176         };
178         es3fShaderStructTests.LocalStructTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
179         es3fShaderStructTests.LocalStructTests.prototype.constructor = es3fShaderStructTests.LocalStructTests;
181         es3fShaderStructTests.LocalStructTests.prototype.init = function() {
182                 var currentCtx = this;
183                 function LocalStructCase(name, description, shaderSource, evalFunction) {
184                         currentCtx.addChild(es3fShaderStructTests.ShaderStructCase.createStructCase(name + "_vertex", description, true, false, evalFunction, null, shaderSource));
185                         currentCtx.addChild(es3fShaderStructTests.ShaderStructCase.createStructCase(name + "_fragment", description, false, false, evalFunction, null, shaderSource));
186                 };
188                 LocalStructCase('basic', 'Basic struct usage',
189                         '${HEADER}\n' +
190                         'uniform int ui_one;\n' +
191                         '\n' +
192                         'struct S {\n' +
193                         '       mediump float   a;\n' +
194                         '       mediump vec3    b;\n' +
195                         '       int                             c;\n' +
196                         '};\n' +
197                         '\n' +
198                         'void main (void)\n' +
199                         '{\n' +
200                         '       S s = S(${COORDS}.x, vec3(0.0), ui_one);\n' +
201                         '       s.b = ${COORDS}.yzw;\n' +
202                         '       ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);\n' +
203                         '       ${ASSIGN_POS}\n' +
204                         '}\n',
205                         function(c) {
206                                 c.color[0] = c.coords[0];
207                                 c.color[1] = c.coords[1];
208                                 c.color[2] = c.coords[2];
209                         });
211                 LocalStructCase('nested', "Nested struct",
212                         '${HEADER}\n' +
213                         "uniform int ui_zero;\n" +
214                         "uniform int ui_one;\n" +
215                         "\n" +
216                         "struct T {\n" +
217                         "       int                             a;\n" +
218                         "       mediump vec2    b;\n" +
219                         "};\n" +
220                         "struct S {\n" +
221                         '       mediump float   a;\n' +
222                         '       T                               b;\n' +
223                         '       int                             c;\n' +
224                         '};\n' +
225                         '\n' +
226                         'void main (void)\n' +
227                         '{\n' +
228                         '       S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);\n' +
229                         '       s.b = T(ui_zero, ${COORDS}.yz);\n' +
230                         '       ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);\n' +
231                         '       ${ASSIGN_POS}\n' +
232                         '}\n',
233                         function(c) {
234                                 c.color[0] = c.coords[0];
235                                 c.color[1] = c.coords[1];
236                                 c.color[2] = c.coords[2];
237                         });
239                 LocalStructCase('array_member', "Struct with array member",
240                         '${HEADER}\n' +
241                         'uniform int ui_one;\n' +
242                         '\n' +
243                         'struct S {\n' +
244                         '       mediump float   a;\n' +
245                         '       mediump float   b[3];\n' +
246                         '       int                             c;\n' +
247                         '};\n' +
248                         '\n' +
249                         'void main (void)\n' +
250                         '{\n' +
251                         '       S s;\n' +
252                         '       s.a = ${COORDS}.w;\n' +
253                         '       s.c = ui_one;\n' +
254                         '       s.b[0] = ${COORDS}.z;\n' +
255                         '       s.b[1] = ${COORDS}.y;\n' +
256                         '       s.b[2] = ${COORDS}.x;\n' +
257                         '       ${DST} = vec4(s.a, s.b[0], s.b[1], s.c);\n' +
258                         '       ${ASSIGN_POS}\n' +
259                         '}\n',
260                         function(c) {
261                                 c.color[0] = c.coords[3];
262                                 c.color[1] = c.coords[2];
263                                 c.color[2] = c.coords[1];
264                         });
266                 LocalStructCase('array_member_dynamic_index', "Struct with array member, dynamic indexing",
267                         '${HEADER}\n' +
268                         'uniform int ui_zero;\n' +
269                         'uniform int ui_one;\n' +
270                         'uniform int ui_two;\n' +
271                         '\n' +
272                         'struct S {\n' +
273                         '       mediump float   a;\n' +
274                         '       mediump float   b[3];\n' +
275                         '       int                             c;\n' +
276                         '};\n' +
277                         '\n' +
278                         'void main (void)\n' +
279                         '{\n' +
280                         '       S s;\n' +
281                         '       s.a = ${COORDS}.w;\n' +
282                         '       s.c = ui_one;\n' +
283                         '       s.b[0] = ${COORDS}.z;\n' +
284                         '       s.b[1] = ${COORDS}.y;\n' +
285                         '       s.b[2] = ${COORDS}.x;\n' +
286                         '       ${DST} = vec4(s.b[ui_one], s.b[ui_zero], s.b[ui_two], s.c);\n' +
287                         '       ${ASSIGN_POS}\n' +
288                         '}\n',
289                         function(c) {
290                                 c.color[0] = c.coords[1];
291                                 c.color[1] = c.coords[2];
292                                 c.color[2] = c.coords[0];
293                         });
295                 LocalStructCase('struct_array', "Struct array",
296                         '${HEADER}\n' +
297                         'uniform int ui_zero;\n' +
298                         'uniform int ui_one;\n' +
299                         'uniform int ui_two;\n' +
300                         '\n' +
301                         'struct S {\n' +
302                         '       mediump float   a;\n' +
303                         '       mediump int             b;\n' +
304                         '};\n' +
305                         '\n' +
306                         'void main (void)\n' +
307                         '{\n' +
308                         '       S s[3];\n' +
309                         '       s[0] = S(${COORDS}.x, ui_zero);\n' +
310                         '       s[1].a = ${COORDS}.y;\n' +
311                         '       s[1].b = ui_one;\n' +
312                         '       s[2] = S(${COORDS}.z, ui_two);\n' +
313                         '       ${DST} = vec4(s[2].a, s[1].a, s[0].a, s[2].b - s[1].b + s[0].b);\n' +
314                         '       ${ASSIGN_POS}\n' +
315                         '}\n',
316                         function(c) {
317                                 c.color[0] = c.coords[2];
318                                 c.color[1] = c.coords[1];
319                                 c.color[2] = c.coords[0];
320                         });
322                 LocalStructCase('struct_array_dynamic_index', "Struct array with dynamic indexing",
323                         '${HEADER}\n' +
324                         'uniform int ui_zero;\n' +
325                         'uniform int ui_one;\n' +
326                         'uniform int ui_two;\n' +
327                         '\n' +
328                         'struct S {\n' +
329                         '       mediump float   a;\n' +
330                         '       mediump int             b;\n' +
331                         '};\n' +
332                         '\n' +
333                         'void main (void)\n' +
334                         '{\n' +
335                         '       S s[3];\n' +
336                         '       s[0] = S(${COORDS}.x, ui_zero);\n' +
337                         '       s[1].a = ${COORDS}.y;\n' +
338                         '       s[1].b = ui_one;\n' +
339                         '       s[2] = S(${COORDS}.z, ui_two);\n' +
340                         '       ${DST} = vec4(s[ui_two].a, s[ui_one].a, s[ui_zero].a, s[ui_two].b - s[ui_one].b + s[ui_zero].b);\n' +
341                         '       ${ASSIGN_POS}\n' +
342                         '}\n',
343                         function(c) {
344                                 c.color[0] = c.coords[2];
345                                 c.color[1] = c.coords[1];
346                                 c.color[2] = c.coords[0];
347                         });
349                 LocalStructCase('nested_struct_array', "Nested struct array",
350                         '${HEADER}\n' +
351                         'uniform int ui_zero;\n' +
352                         'uniform int ui_one;\n' +
353                         'uniform int ui_two;\n' +
354                         'uniform mediump float uf_two;\n' +
355                         'uniform mediump float uf_three;\n' +
356                         'uniform mediump float uf_four;\n' +
357                         'uniform mediump float uf_half;\n' +
358                         'uniform mediump float uf_third;\n' +
359                         'uniform mediump float uf_fourth;\n' +
360                         '\n' +
361                         'struct T {\n' +
362                         '       mediump float   a;\n' +
363                         '       mediump vec2    b[2];\n' +
364                         '};\n' +
365                         'struct S {\n' +
366                         '       mediump float   a;\n' +
367                         '       T                               b[3];\n' +
368                         '       int                             c;\n' +
369                         '};\n' +
370                         '\n' +
371                         'void main (void)\n' +
372                         '{\n' +
373                         '       S s[2];\n' +
374                         '\n' +
375                         '       // S[0]\n' +
376                         '       s[0].a         = ${COORDS}.x;\n' +
377                         '       s[0].b[0].a    = uf_half;\n' +
378                         '       s[0].b[0].b[0] = ${COORDS}.xy;\n' +
379                         '       s[0].b[0].b[1] = ${COORDS}.zw;\n' +
380                         '       s[0].b[1].a    = uf_third;\n' +
381                         '       s[0].b[1].b[0] = ${COORDS}.zw;\n' +
382                         '       s[0].b[1].b[1] = ${COORDS}.xy;\n' +
383                         '       s[0].b[2].a    = uf_fourth;\n' +
384                         '       s[0].b[2].b[0] = ${COORDS}.xz;\n' +
385                         '       s[0].b[2].b[1] = ${COORDS}.yw;\n' +
386                         '       s[0].c         = ui_zero;\n' +
387                         '\n' +
388                         '       // S[1]\n' +
389                         '       s[1].a         = ${COORDS}.w;\n' +
390                         '       s[1].b[0].a    = uf_two;\n' +
391                         '       s[1].b[0].b[0] = ${COORDS}.xx;\n' +
392                         '       s[1].b[0].b[1] = ${COORDS}.yy;\n' +
393                         '       s[1].b[1].a    = uf_three;\n' +
394                         '       s[1].b[1].b[0] = ${COORDS}.zz;\n' +
395                         '       s[1].b[1].b[1] = ${COORDS}.ww;\n' +
396                         '       s[1].b[2].a    = uf_four;\n' +
397                         '       s[1].b[2].b[0] = ${COORDS}.yx;\n' +
398                         '       s[1].b[2].b[1] = ${COORDS}.wz;\n' +
399                         '       s[1].c         = ui_one;\n' +
400                         '\n' +
401                         '       mediump float r = (s[0].b[1].b[0].x + s[1].b[2].b[1].y) * s[0].b[0].a; // (z + z) * 0.5\n' +
402                         '       mediump float g = s[1].b[0].b[0].y * s[0].b[2].a * s[1].b[2].a; // x * 0.25 * 4\n' +
403                         '       mediump float b = (s[0].b[2].b[1].y + s[0].b[1].b[0].y + s[1].a) * s[0].b[1].a; // (w + w + w) * 0.333\n' +
404                         '       mediump float a = float(s[0].c) + s[1].b[2].a - s[1].b[1].a; // 0 + 4.0 - 3.0\n' +
405                         '       ${DST} = vec4(r, g, b, a);\n' +
406                         '       ${ASSIGN_POS}\n' +
407                         '}\n',
408                         function(c) {
409                                 c.color[0] = c.coords[2];
410                                 c.color[1] = c.coords[0];
411                                 c.color[2] = c.coords[3];
412                         });
414                 LocalStructCase('nested_struct_array_dynamic_index', "Nested struct array with dynamic indexing",
415                         '${HEADER}\n' +
416                         'uniform int ui_zero;\n' +
417                         'uniform int ui_one;\n' +
418                         'uniform int ui_two;\n' +
419                         'uniform mediump float uf_two;\n' +
420                         'uniform mediump float uf_three;\n' +
421                         'uniform mediump float uf_four;\n' +
422                         'uniform mediump float uf_half;\n' +
423                         'uniform mediump float uf_third;\n' +
424                         'uniform mediump float uf_fourth;\n' +
425                         '\n' +
426                         'struct T {\n' +
427                         '       mediump float   a;\n' +
428                         '       mediump vec2    b[2];\n' +
429                         '};\n' +
430                         'struct S {\n' +
431                         '       mediump float   a;\n' +
432                         '       T                               b[3];\n' +
433                         '       int                             c;\n' +
434                         '};\n' +
435                         '\n' +
436                         'void main (void)\n' +
437                         '{\n' +
438                         '       S s[2];\n' +
439                         '\n' +
440                         '       // S[0]\n' +
441                         '       s[0].a         = ${COORDS}.x;\n' +
442                         '       s[0].b[0].a    = uf_half;\n' +
443                         '       s[0].b[0].b[0] = ${COORDS}.xy;\n' +
444                         '       s[0].b[0].b[1] = ${COORDS}.zw;\n' +
445                         '       s[0].b[1].a    = uf_third;\n' +
446                         '       s[0].b[1].b[0] = ${COORDS}.zw;\n' +
447                         '       s[0].b[1].b[1] = ${COORDS}.xy;\n' +
448                         '       s[0].b[2].a    = uf_fourth;\n' +
449                         '       s[0].b[2].b[0] = ${COORDS}.xz;\n' +
450                         '       s[0].b[2].b[1] = ${COORDS}.yw;\n' +
451                         '       s[0].c         = ui_zero;\n' +
452                         '\n' +
453                         '       // S[1]\n' +
454                         '       s[1].a         = ${COORDS}.w;\n' +
455                         '       s[1].b[0].a    = uf_two;\n' +
456                         '       s[1].b[0].b[0] = ${COORDS}.xx;\n' +
457                         '       s[1].b[0].b[1] = ${COORDS}.yy;\n' +
458                         '       s[1].b[1].a    = uf_three;\n' +
459                         '       s[1].b[1].b[0] = ${COORDS}.zz;\n' +
460                         '       s[1].b[1].b[1] = ${COORDS}.ww;\n' +
461                         '       s[1].b[2].a    = uf_four;\n' +
462                         '       s[1].b[2].b[0] = ${COORDS}.yx;\n' +
463                         '       s[1].b[2].b[1] = ${COORDS}.wz;\n' +
464                         '       s[1].c         = ui_one;\n' +
465                         '\n' +
466                         '       mediump float r = (s[0].b[ui_one].b[ui_one-1].x + s[ui_one].b[ui_two].b[ui_zero+1].y) * s[0].b[0].a; // (z + z) * 0.5\n' +
467                         '       mediump float g = s[ui_two-1].b[ui_two-2].b[ui_zero].y * s[0].b[ui_two].a * s[ui_one].b[2].a; // x * 0.25 * 4\n' +
468                         '       mediump float b = (s[ui_zero].b[ui_one+1].b[1].y + s[0].b[ui_one*ui_one].b[0].y + s[ui_one].a) * s[0].b[ui_two-ui_one].a; // (w + w + w) * 0.333\n' +
469                         '       mediump float a = float(s[ui_zero].c) + s[ui_one-ui_zero].b[ui_two].a - s[ui_zero+ui_one].b[ui_two-ui_one].a; // 0 + 4.0 - 3.0\n' +
470                         '       ${DST} = vec4(r, g, b, a);\n' +
471                         '       ${ASSIGN_POS}\n' +
472                         '}\n',
473                         function(c) {
474                                 c.color[0] = c.coords[2];
475                                 c.color[1] = c.coords[0];
476                                 c.color[2] = c.coords[3];
477                         });
479                 LocalStructCase('parameter', "Struct as a function parameter",
480                         '${HEADER}\n' +
481                         'uniform int ui_one;\n' +
482                         '\n' +
483                         'struct S {\n' +
484                         '       mediump float   a;\n' +
485                         '       mediump vec3    b;\n' +
486                         '       int                             c;\n' +
487                         '};\n' +
488                         '\n' +
489                         'mediump vec4 myFunc (S s)\n' +
490                         '{\n' +
491                         '       return vec4(s.a, s.b.x, s.b.y, s.c);\n' +
492                         '}\n' +
493                         '\n' +
494                         'void main (void)\n' +
495                         '{\n' +
496                         '       S s = S(${COORDS}.x, vec3(0.0), ui_one);\n' +
497                         '       s.b = ${COORDS}.yzw;\n' +
498                         '       ${DST} = myFunc(s);\n' +
499                         '       ${ASSIGN_POS}\n' +
500                         '}\n',
501                         function(c) {
502                                 c.color[0] = c.coords[0];
503                                 c.color[1] = c.coords[1];
504                                 c.color[2] = c.coords[2];
505                         });
507                 LocalStructCase('parameter_nested', "Nested struct as a function parameter",
508                         '${HEADER}\n' +
509                         'uniform int ui_zero;\n' +
510                         'uniform int ui_one;\n' +
511                         '\n' +
512                         'struct T {\n' +
513                         '       int                             a;\n' +
514                         '       mediump vec2    b;\n' +
515                         '};\n' +
516                         'struct S {\n' +
517                         '       mediump float   a;\n' +
518                         '       T                               b;\n' +
519                         '       int                             c;\n' +
520                         '};\n' +
521                         '\n' +
522                         'mediump vec4 myFunc (S s)\n' +
523                         '{\n' +
524                         '       return vec4(s.a, s.b.b, s.b.a + s.c);\n' +
525                         '}\n' +
526                         '\n' +
527                         'void main (void)\n' +
528                         '{\n' +
529                         '       S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);\n' +
530                         '       s.b = T(ui_zero, ${COORDS}.yz);\n' +
531                         '       ${DST} = myFunc(s);\n' +
532                         '       ${ASSIGN_POS}\n' +
533                         '}\n',
534                         function(c) {
535                                 c.color[0] = c.coords[0];
536                                 c.color[1] = c.coords[1];
537                                 c.color[2] = c.coords[2];
538                         });
540                 LocalStructCase('return', "Struct as a return value",
541                         '${HEADER}\n' +
542                         'uniform int ui_one;\n' +
543                         '\n' +
544                         'struct S {\n' +
545                         '       mediump float   a;\n' +
546                         '       mediump vec3    b;\n' +
547                         '       int                             c;\n' +
548                         '};\n' +
549                         '\n' +
550                         'S myFunc (void)\n' +
551                         '{\n' +
552                         '       S s = S(${COORDS}.x, vec3(0.0), ui_one);\n' +
553                         '       s.b = ${COORDS}.yzw;\n' +
554                         '       return s;\n' +
555                         '}\n' +
556                         '\n' +
557                         'void main (void)\n' +
558                         '{\n' +
559                         '       S s = myFunc();\n' +
560                         '       ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);\n' +
561                         '       ${ASSIGN_POS}\n' +
562                         '}\n',
563                         function(c) {
564                                 c.color[0] = c.coords[0];
565                                 c.color[1] = c.coords[1];
566                                 c.color[2] = c.coords[2];
567                         });
569                 LocalStructCase('return_nested', "Nested struct",
570                         '${HEADER}\n' +
571                         'uniform int ui_zero;\n' +
572                         'uniform int ui_one;\n' +
573                         '\n' +
574                         'struct T {\n' +
575                         '       int                             a;\n' +
576                         '       mediump vec2    b;\n' +
577                         '};\n' +
578                         'struct S {\n' +
579                         '       mediump float   a;\n' +
580                         '       T                               b;\n' +
581                         '       int                             c;\n' +
582                         '};\n' +
583                         '\n' +
584                         'S myFunc (void)\n' +
585                         '{\n' +
586                         '       S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);\n' +
587                         '       s.b = T(ui_zero, ${COORDS}.yz);\n' +
588                         '       return s;\n' +
589                         '}\n' +
590                         '\n' +
591                         'void main (void)\n' +
592                         '{\n' +
593                         '       S s = myFunc();\n' +
594                         '       ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);\n' +
595                         '       ${ASSIGN_POS}\n' +
596                         '}\n',
597                         function(c) {
598                                 c.color[0] = c.coords[0];
599                                 c.color[1] = c.coords[1];
600                                 c.color[2] = c.coords[2];
601                         });
603                 LocalStructCase('conditional_assignment', "Conditional struct assignment",
604                         '${HEADER}\n' +
605                         'uniform int ui_zero;\n' +
606                         'uniform int ui_one;\n' +
607                         'uniform mediump float uf_one;\n' +
608                         '\n' +
609                         'struct S {\n' +
610                         '       mediump float   a;\n' +
611                         '       mediump vec3    b;\n' +
612                         '       int                             c;\n' +
613                         '};\n' +
614                         '\n' +
615                         'void main (void)\n' +
616                         '{\n' +
617                         '       S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);\n' +
618                         '       if (uf_one > 0.0)\n' +
619                         '               s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);\n' +
620                         '       ${DST} = vec4(s.a, s.b.xy, s.c);\n' +
621                         '       ${ASSIGN_POS}\n' +
622                         '}\n',
623                         function(c) {
624                                 c.color[0] = c.coords[3];
625                                 c.color[1] = c.coords[2];
626                                 c.color[2] = c.coords[1];
627                         });
629                 LocalStructCase('loop_assignment', "Struct assignment in loop",
630                         '${HEADER}\n' +
631                         'uniform int ui_zero;\n' +
632                         'uniform int ui_one;\n' +
633                         '\n' +
634                         'struct S {\n' +
635                         '       mediump float   a;\n' +
636                         '       mediump vec3    b;\n' +
637                         '       int                             c;\n' +
638                         '};\n' +
639                         '\n' +
640                         'void main (void)\n' +
641                         '{\n' +
642                         '       S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);\n' +
643                         '       for (int i = 0; i < 3; i++)\n' +
644                         '       {\n' +
645                         '               if (i == 1)\n' +
646                         '                       s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);\n' +
647                         '       }\n' +
648                         '       ${DST} = vec4(s.a, s.b.xy, s.c);\n' +
649                         '       ${ASSIGN_POS}\n' +
650                         '}\n',
651                         function(c) {
652                                 c.color[0] = c.coords[3];
653                                 c.color[1] = c.coords[2];
654                                 c.color[2] = c.coords[1];
655                         });
657                 LocalStructCase('dynamic_loop_assignment', "Struct assignment in loop",
658                         '${HEADER}\n' +
659                         'uniform int ui_zero;\n' +
660                         'uniform int ui_one;\n' +
661                         'uniform int ui_three;\n' +
662                         '\n' +
663                         'struct S {\n' +
664                         '       mediump float   a;\n' +
665                         '       mediump vec3    b;\n' +
666                         '       int                             c;\n' +
667                         '};\n' +
668                         '\n' +
669                         'void main (void)\n' +
670                         '{\n' +
671                         '       S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);\n' +
672                         '       for (int i = 0; i < ui_three; i++)\n' +
673                         '       {\n' +
674                         '               if (i == ui_one)\n' +
675                         '                       s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);\n' +
676                         '       }\n' +
677                         '       ${DST} = vec4(s.a, s.b.xy, s.c);\n' +
678                         '       ${ASSIGN_POS}\n' +
679                         '}\n',
680                         function(c) {
681                                 c.color[0] = c.coords[3];
682                                 c.color[1] = c.coords[2];
683                                 c.color[2] = c.coords[1];
684                         });
686                 LocalStructCase('nested_conditional_assignment', "Conditional assignment of nested struct",
687                         '${HEADER}\n' +
688                         'uniform int ui_zero;\n' +
689                         'uniform int ui_one;\n' +
690                         'uniform mediump float uf_one;\n' +
691                         '\n' +
692                         'struct T {\n' +
693                         '       int                             a;\n' +
694                         '       mediump vec2    b;\n' +
695                         '};\n' +
696                         'struct S {\n' +
697                         '       mediump float   a;\n' +
698                         '       T                               b;\n' +
699                         '       int                             c;\n' +
700                         '};\n' +
701                         '\n' +
702                         'void main (void)\n' +
703                         '{\n' +
704                         '       S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);\n' +
705                         '       if (uf_one > 0.0)\n' +
706                         '               s.b = T(ui_zero, ${COORDS}.zw);\n' +
707                         '       ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);\n' +
708                         '       ${ASSIGN_POS}\n' +
709                         '}\n',
710                         function(c) {
711                                 c.color[0] = c.coords[0];
712                                 c.color[1] = c.coords[2];
713                                 c.color[2] = c.coords[3];
714                         });
716                 LocalStructCase('nested_loop_assignment', "Nested struct assignment in loop",
717                         '${HEADER}\n' +
718                         'uniform int ui_zero;\n' +
719                         'uniform int ui_one;\n' +
720                         'uniform mediump float uf_one;\n' +
721                         '\n' +
722                         'struct T {\n' +
723                         '       int                             a;\n' +
724                         '       mediump vec2    b;\n' +
725                         '};\n' +
726                         'struct S {\n' +
727                         '       mediump float   a;\n' +
728                         '       T                               b;\n' +
729                         '       int                             c;\n' +
730                         '};\n' +
731                         '\n' +
732                         'void main (void)\n' +
733                         '{\n' +
734                         '       S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);\n' +
735                         '       for (int i = 0; i < 3; i++)\n' +
736                         '       {\n' +
737                         '               if (i == 1)\n' +
738                         '                       s.b = T(ui_zero, ${COORDS}.zw);\n' +
739                         '       }\n' +
740                         '       ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);\n' +
741                         '       ${ASSIGN_POS}\n' +
742                         '}\n',
743                         function(c) {
744                                 c.color[0] = c.coords[0];
745                                 c.color[1] = c.coords[2];
746                                 c.color[2] = c.coords[3];
747                         });
749                 LocalStructCase('nested_dynamic_loop_assignment', "Nested struct assignment in dynamic loop",
750                         '${HEADER}\n' +
751                         'uniform int ui_zero;\n' +
752                         'uniform int ui_one;\n' +
753                         'uniform int ui_three;\n' +
754                         'uniform mediump float uf_one;\n' +
755                         '\n' +
756                         'struct T {\n' +
757                         '       int                             a;\n' +
758                         '       mediump vec2    b;\n' +
759                         '};\n' +
760                         'struct S {\n' +
761                         '       mediump float   a;\n' +
762                         '       T                               b;\n' +
763                         '       int                             c;\n' +
764                         '};\n' +
765                         '\n' +
766                         'void main (void)\n' +
767                         '{\n' +
768                         '       S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);\n' +
769                         '       for (int i = 0; i < ui_three; i++)\n' +
770                         '       {\n' +
771                         '               if (i == ui_one)\n' +
772                         '                       s.b = T(ui_zero, ${COORDS}.zw);\n' +
773                         '       }\n' +
774                         '       ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);\n' +
775                         '       ${ASSIGN_POS}\n' +
776                         '}\n',
777                         function(c) {
778                                 c.color[0] = c.coords[0];
779                                 c.color[1] = c.coords[2];
780                                 c.color[2] = c.coords[3];
781                         });
783                 LocalStructCase('loop_struct_array', "Struct array usage in loop",
784                         '${HEADER}\n' +
785                         'uniform int ui_zero;\n' +
786                         'uniform int ui_one;\n' +
787                         'uniform int ui_two;\n' +
788                         '\n' +
789                         'struct S {\n' +
790                         '       mediump float   a;\n' +
791                         '       mediump int             b;\n' +
792                         '};\n' +
793                         '\n' +
794                         'void main (void)\n' +
795                         '{\n' +
796                         '       S s[3];\n' +
797                         '       s[0] = S(${COORDS}.x, ui_zero);\n' +
798                         '       s[1].a = ${COORDS}.y;\n' +
799                         '       s[1].b = -ui_one;\n' +
800                         '       s[2] = S(${COORDS}.z, ui_two);\n' +
801                         '\n' +
802                         '       mediump float rgb[3];\n' +
803                         '       int alpha = 0;\n' +
804                         '       for (int i = 0; i < 3; i++)\n' +
805                         '       {\n' +
806                         '               rgb[i] = s[2-i].a;\n' +
807                         '               alpha += s[i].b;\n' +
808                         '       }\n' +
809                         '       ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);\n' +
810                         '       ${ASSIGN_POS}\n' +
811                         '}\n',
812                         function(c) {
813                                 c.color[0] = c.coords[2];
814                                 c.color[1] = c.coords[1];
815                                 c.color[2] = c.coords[0];
816                         });
818                 LocalStructCase('loop_nested_struct_array', "Nested struct array usage in loop",
819                         '${HEADER}\n' +
820                         'uniform int ui_zero;\n' +
821                         'uniform int ui_one;\n' +
822                         'uniform int ui_two;\n' +
823                         'uniform mediump float uf_two;\n' +
824                         'uniform mediump float uf_three;\n' +
825                         'uniform mediump float uf_four;\n' +
826                         'uniform mediump float uf_half;\n' +
827                         'uniform mediump float uf_third;\n' +
828                         'uniform mediump float uf_fourth;\n' +
829                         'uniform mediump float uf_sixth;\n' +
830                         '\n' +
831                         'struct T {\n' +
832                         '       mediump float   a;\n' +
833                         '       mediump vec2    b[2];\n' +
834                         '};\n' +
835                         'struct S {\n' +
836                         '       mediump float   a;\n' +
837                         '       T                               b[3];\n' +
838                         '       int                             c;\n' +
839                         '};\n' +
840                         '\n' +
841                         'void main (void)\n' +
842                         '{\n' +
843                         '       S s[2];\n' +
844                         '\n' +
845                         '       // S[0]\n' +
846                         '       s[0].a         = ${COORDS}.x;\n' +
847                         '       s[0].b[0].a    = uf_half;\n' +
848                         '       s[0].b[0].b[0] = ${COORDS}.yx;\n' +
849                         '       s[0].b[0].b[1] = ${COORDS}.zx;\n' +
850                         '       s[0].b[1].a    = uf_third;\n' +
851                         '       s[0].b[1].b[0] = ${COORDS}.yy;\n' +
852                         '       s[0].b[1].b[1] = ${COORDS}.wy;\n' +
853                         '       s[0].b[2].a    = uf_fourth;\n' +
854                         '       s[0].b[2].b[0] = ${COORDS}.zx;\n' +
855                         '       s[0].b[2].b[1] = ${COORDS}.zy;\n' +
856                         '       s[0].c         = ui_zero;\n' +
857                         '\n' +
858                         '       // S[1]\n' +
859                         '       s[1].a         = ${COORDS}.w;\n' +
860                         '       s[1].b[0].a    = uf_two;\n' +
861                         '       s[1].b[0].b[0] = ${COORDS}.zx;\n' +
862                         '       s[1].b[0].b[1] = ${COORDS}.zy;\n' +
863                         '       s[1].b[1].a    = uf_three;\n' +
864                         '       s[1].b[1].b[0] = ${COORDS}.zz;\n' +
865                         '       s[1].b[1].b[1] = ${COORDS}.ww;\n' +
866                         '       s[1].b[2].a    = uf_four;\n' +
867                         '       s[1].b[2].b[0] = ${COORDS}.yx;\n' +
868                         '       s[1].b[2].b[1] = ${COORDS}.wz;\n' +
869                         '       s[1].c         = ui_one;\n' +
870                         '\n' +
871                         '       mediump float r = 0.0; // (x*3 + y*3) / 6.0\n' +
872                         '       mediump float g = 0.0; // (y*3 + z*3) / 6.0\n' +
873                         '       mediump float b = 0.0; // (z*3 + w*3) / 6.0\n' +
874                         '       mediump float a = 1.0;\n' +
875                         '       for (int i = 0; i < 2; i++)\n' +
876                         '       {\n' +
877                         '               for (int j = 0; j < 3; j++)\n' +
878                         '               {\n' +
879                         '                       r += s[0].b[j].b[i].y;\n' +
880                         '                       g += s[i].b[j].b[0].x;\n' +
881                         '                       b += s[i].b[j].b[1].x;\n' +
882                         '                       a *= s[i].b[j].a;\n' +
883                         '               }\n' +
884                         '       }\n' +
885                         '       ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);\n' +
886                         '       ${ASSIGN_POS}\n' +
887                         '}\n',
888                         function(c) {
889                                 c.color[0] = (c.coords[0] + c.coords[1]) * 0.5;
890                                 c.color[1] = (c.coords[1] + c.coords[2]) * 0.5;
891                                 c.color[2] = (c.coords[2] + c.coords[3]) * 0.5;
892                         });
894                 LocalStructCase('dynamic_loop_struct_array', "Struct array usage in dynamic loop",
895                         '${HEADER}\n' +
896                         'uniform int ui_zero;\n' +
897                         'uniform int ui_one;\n' +
898                         'uniform int ui_two;\n' +
899                         'uniform int ui_three;\n' +
900                         '\n' +
901                         'struct S {\n' +
902                         '       mediump float   a;\n' +
903                         '       mediump int             b;\n' +
904                         '};\n' +
905                         '\n' +
906                         'void main (void)\n' +
907                         '{\n' +
908                         '       S s[3];\n' +
909                         '       s[0] = S(${COORDS}.x, ui_zero);\n' +
910                         '       s[1].a = ${COORDS}.y;\n' +
911                         '       s[1].b = -ui_one;\n' +
912                         '       s[2] = S(${COORDS}.z, ui_two);\n' +
913                         '\n' +
914                         '       mediump float rgb[3];\n' +
915                         '       int alpha = 0;\n' +
916                         '       for (int i = 0; i < ui_three; i++)\n' +
917                         '       {\n' +
918                         '               rgb[i] = s[2-i].a;\n' +
919                         '               alpha += s[i].b;\n' +
920                         '       }\n' +
921                         '       ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);\n' +
922                         '       ${ASSIGN_POS}\n' +
923                         '}\n',
924                         function(c) {
925                                 c.color[0] = c.coords[2];
926                                 c.color[1] = c.coords[1];
927                                 c.color[2] = c.coords[0];
928                         });
930                 LocalStructCase('dynamic_loop_nested_struct_array', "Nested struct array usage in dynamic loop",
931                         '${HEADER}\n' +
932                         'uniform int ui_zero;\n' +
933                         'uniform int ui_one;\n' +
934                         'uniform int ui_two;\n' +
935                         'uniform int ui_three;\n' +
936                         'uniform mediump float uf_two;\n' +
937                         'uniform mediump float uf_three;\n' +
938                         'uniform mediump float uf_four;\n' +
939                         'uniform mediump float uf_half;\n' +
940                         'uniform mediump float uf_third;\n' +
941                         'uniform mediump float uf_fourth;\n' +
942                         'uniform mediump float uf_sixth;\n' +
943                         '\n' +
944                         'struct T {\n' +
945                         '       mediump float   a;\n' +
946                         '       mediump vec2    b[2];\n' +
947                         '};\n' +
948                         'struct S {\n' +
949                         '       mediump float   a;\n' +
950                         '       T                               b[3];\n' +
951                         '       int                             c;\n' +
952                         '};\n' +
953                         '\n' +
954                         'void main (void)\n' +
955                         '{\n' +
956                         '       S s[2];\n' +
957                         '\n' +
958                         '       // S[0]\n' +
959                         '       s[0].a         = ${COORDS}.x;\n' +
960                         '       s[0].b[0].a    = uf_half;\n' +
961                         '       s[0].b[0].b[0] = ${COORDS}.yx;\n' +
962                         '       s[0].b[0].b[1] = ${COORDS}.zx;\n' +
963                         '       s[0].b[1].a    = uf_third;\n' +
964                         '       s[0].b[1].b[0] = ${COORDS}.yy;\n' +
965                         '       s[0].b[1].b[1] = ${COORDS}.wy;\n' +
966                         '       s[0].b[2].a    = uf_fourth;\n' +
967                         '       s[0].b[2].b[0] = ${COORDS}.zx;\n' +
968                         '       s[0].b[2].b[1] = ${COORDS}.zy;\n' +
969                         '       s[0].c         = ui_zero;\n' +
970                         '\n' +
971                         '       // S[1]\n' +
972                         '       s[1].a         = ${COORDS}.w;\n' +
973                         '       s[1].b[0].a    = uf_two;\n' +
974                         '       s[1].b[0].b[0] = ${COORDS}.zx;\n' +
975                         '       s[1].b[0].b[1] = ${COORDS}.zy;\n' +
976                         '       s[1].b[1].a    = uf_three;\n' +
977                         '       s[1].b[1].b[0] = ${COORDS}.zz;\n' +
978                         '       s[1].b[1].b[1] = ${COORDS}.ww;\n' +
979                         '       s[1].b[2].a    = uf_four;\n' +
980                         '       s[1].b[2].b[0] = ${COORDS}.yx;\n' +
981                         '       s[1].b[2].b[1] = ${COORDS}.wz;\n' +
982                         '       s[1].c         = ui_one;\n' +
983                         '\n' +
984                         '       mediump float r = 0.0; // (x*3 + y*3) / 6.0\n' +
985                         '       mediump float g = 0.0; // (y*3 + z*3) / 6.0\n' +
986                         '       mediump float b = 0.0; // (z*3 + w*3) / 6.0\n' +
987                         '       mediump float a = 1.0;\n' +
988                         '       for (int i = 0; i < ui_two; i++)\n' +
989                         '       {\n' +
990                         '               for (int j = 0; j < ui_three; j++)\n' +
991                         '               {\n' +
992                         '                       r += s[0].b[j].b[i].y;\n' +
993                         '                       g += s[i].b[j].b[0].x;\n' +
994                         '                       b += s[i].b[j].b[1].x;\n' +
995                         '                       a *= s[i].b[j].a;\n' +
996                         '               }\n' +
997                         '       }\n' +
998                         '       ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);\n' +
999                         '       ${ASSIGN_POS}\n' +
1000                         '}\n',
1001                         function(c) {
1002                                 c.color[0] = (c.coords[0] + c.coords[1]) * 0.5;
1003                                 c.color[1] = (c.coords[1] + c.coords[2]) * 0.5;
1004                                 c.color[2] = (c.coords[2] + c.coords[3]) * 0.5;
1005                         });
1007                 LocalStructCase('basic_equal', "Basic struct equality",
1008                         '${HEADER}\n' +
1009                         'uniform int ui_one;\n' +
1010                         'uniform int ui_two;\n' +
1011                         '\n' +
1012                         'struct S {\n' +
1013                         '       mediump float   a;\n' +
1014                         '       mediump vec3    b;\n' +
1015                         '       int                             c;\n' +
1016                         '};\n' +
1017                         '\n' +
1018                         'void main (void)\n' +
1019                         '{\n' +
1020                         '       S a = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);\n' +
1021                         '       S b = S(floor(${COORDS}.x+0.5), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);\n' +
1022                         '       S c = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one);\n' +
1023                         '       S d = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_two);\n' +
1024                         '       ${DST} = vec4(0.0, 0.0, 0.0, 1.0);\n' +
1025                         '       if (a == b) ${DST}.x = 1.0;\n' +
1026                         '       if (a == c) ${DST}.y = 1.0;\n' +
1027                         '       if (a == d) ${DST}.z = 1.0;\n' +
1028                         '       ${ASSIGN_POS}\n' +
1029                         '}\n',
1030                         function(c) {
1031                                 if (Math.floor(c.coords[0]) === Math.floor(c.coords[0] + 0.5))
1032                                         c.color[0] = 1.0;
1033                                 if (Math.floor(c.coords[1]) === Math.floor(c.coords[1] + 0.5))
1034                                         c.color[1] = 1.0;
1035                         });
1037                 LocalStructCase('basic_not_equal', "Basic struct equality",
1038                         '${HEADER}\n' +
1039                         'uniform int ui_one;\n' +
1040                         'uniform int ui_two;\n' +
1041                         '\n' +
1042                         'struct S {\n' +
1043                         '       mediump float   a;\n' +
1044                         '       mediump vec3    b;\n' +
1045                         '       int                             c;\n' +
1046                         '};\n' +
1047                         '\n' +
1048                         'void main (void)\n' +
1049                         '{\n' +
1050                         '       S a = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);\n' +
1051                         '       S b = S(floor(${COORDS}.x+0.5), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);\n' +
1052                         '       S c = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one);\n' +
1053                         '       S d = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_two);\n' +
1054                         '       ${DST} = vec4(0.0, 0.0, 0.0, 1.0);\n' +
1055                         '       if (a != b) ${DST}.x = 1.0;\n' +
1056                         '       if (a != c) ${DST}.y = 1.0;\n' +
1057                         '       if (a != d) ${DST}.z = 1.0;\n' +
1058                         '       ${ASSIGN_POS}\n' +
1059                         '}\n',
1060                         function(c) {
1061                                 if (Math.floor(c.coords[0]) != Math.floor(c.coords[0] + 0.5))
1062                                         c.color[0] = 1.0;
1063                                 if (Math.floor(c.coords[1]) != Math.floor(c.coords[1] + 0.5))
1064                                         c.color[1] = 1.0;
1065                                 c.color[2] = 1.0;
1066                         });
1068                 LocalStructCase('nested_equal', "Nested struct struct equality",
1069                         '${HEADER}\n' +
1070                         'uniform int ui_one;\n' +
1071                         'uniform int ui_two;\n' +
1072                         '\n' +
1073                         'struct T {\n' +
1074                         '       mediump vec3    a;\n' +
1075                         '       int                             b;\n' +
1076                         '};\n' +
1077                         'struct S {\n' +
1078                         '       mediump float   a;\n' +
1079                         '       T                               b;\n' +
1080                         '       int                             c;\n' +
1081                         '};\n' +
1082                         '\n' +
1083                         'void main (void)\n' +
1084                         '{\n' +
1085                         '       S a = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);\n' +
1086                         '       S b = S(floor(${COORDS}.x+0.5), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);\n' +
1087                         '       S c = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one), 1);\n' +
1088                         '       S d = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_two), 1);\n' +
1089                         '       ${DST} = vec4(0.0, 0.0, 0.0, 1.0);\n' +
1090                         '       if (a == b) ${DST}.x = 1.0;\n' +
1091                         '       if (a == c) ${DST}.y = 1.0;\n' +
1092                         '       if (a == d) ${DST}.z = 1.0;\n' +
1093                         '       ${ASSIGN_POS}\n' +
1094                         '}\n',
1095                         function(c) {
1096                                 if (Math.floor(c.coords[0]) == Math.floor(c.coords[0] + 0.5))
1097                                         c.color[0] = 1.0;
1098                                 if (Math.floor(c.coords[1]) == Math.floor(c.coords[1] + 0.5))
1099                                         c.color[1] = 1.0;
1100                         });
1102                 LocalStructCase('nested_not_equal', "Nested struct struct equality",
1103                         '${HEADER}\n' +
1104                         'uniform int ui_one;\n' +
1105                         'uniform int ui_two;\n' +
1106                         '\n' +
1107                         'struct T {\n' +
1108                         '       mediump vec3    a;\n' +
1109                         '       int                             b;\n' +
1110                         '};\n' +
1111                         'struct S {\n' +
1112                         '       mediump float   a;\n' +
1113                         '       T                               b;\n' +
1114                         '       int                             c;\n' +
1115                         '};\n' +
1116                         '\n' +
1117                         'void main (void)\n' +
1118                         '{\n' +
1119                         '       S a = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);\n' +
1120                         '       S b = S(floor(${COORDS}.x+0.5), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);\n' +
1121                         '       S c = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one), 1);\n' +
1122                         '       S d = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_two), 1);\n' +
1123                         '       ${DST} = vec4(0.0, 0.0, 0.0, 1.0);\n' +
1124                         '       if (a != b) ${DST}.x = 1.0;\n' +
1125                         '       if (a != c) ${DST}.y = 1.0;\n' +
1126                         '       if (a != d) ${DST}.z = 1.0;\n' +
1127                         '       ${ASSIGN_POS}\n' +
1128                         '}\n',
1129                         function(c) {
1130                                 if (Math.floor(c.coords[0]) != Math.floor(c.coords[0] + 0.5))
1131                                         c.color[0] = 1.0;
1132                                 if (Math.floor(c.coords[1]) != Math.floor(c.coords[1] + 0.5))
1133                                         c.color[1] = 1.0;
1134                                 c.color[2] = 1.0;
1135                         });
1136         };
1138         /**
1139          * @constructor
1140          * @extends {tcuTestCase.DeqpTest}
1141          */
1142         es3fShaderStructTests.UniformStructTests = function() {
1143                 tcuTestCase.DeqpTest.call(this, 'uniform', 'Uniform structs');
1144                 this.makeExecutable();
1145         };
1147         es3fShaderStructTests.UniformStructTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
1148         es3fShaderStructTests.UniformStructTests.prototype.constructor = es3fShaderStructTests.UniformStructTests;
1150         /**
1151          * @param {WebGLProgram} programID
1152          * @param {string} name
1153          * @param {Array<number>} vec
1154          */
1155         es3fShaderStructTests.setUniform2fv = function(programID, name, vec) {
1156                 /** @type {WebGLUniformLocation} */ var loc = gl.getUniformLocation(programID, name);
1157                 gl.uniform2fv(loc, vec);
1158         };
1160         /**
1161          * @param {WebGLProgram} programID
1162          * @param {string} name
1163          * @param {Array<number>} vec
1164          */
1165         es3fShaderStructTests.setUniform3fv = function(programID, name, vec) {
1166                 /** @type {WebGLUniformLocation} */ var loc = gl.getUniformLocation(programID, name);
1167                 gl.uniform3fv(loc, vec);
1168         };
1170         /**
1171         * @param {WebGLProgram} programID
1172         * @param {string} name
1173         * @param {number} value
1174         */
1175         es3fShaderStructTests.setUniform1i = function(programID, name, value) {
1176                 /** @type {WebGLUniformLocation} */ var loc = gl.getUniformLocation(programID, name);
1177                 gl.uniform1i(loc, value);
1178         };
1180         /**
1181         * @param {WebGLProgram} programID
1182         * @param {string} name
1183         * @param {number} value
1184         */
1185         es3fShaderStructTests.setUniform1f = function(programID, name, value) {
1186                 /** @type {WebGLUniformLocation} */ var loc = gl.getUniformLocation(programID, name);
1187                 gl.uniform1f(loc, value);
1188         };
1190         /**
1191         * @param {WebGLProgram} programID
1192         * @param {string} name
1193         * @param {Array<number>} vec
1194         */
1195         es3fShaderStructTests.setUniform1fv = function(programID, name, vec) {
1196                 /** @type {WebGLUniformLocation} */ var loc = gl.getUniformLocation(programID, name);
1197                 gl.uniform1fv(loc, vec);
1198         };
1200         es3fShaderStructTests.UniformStructTests.prototype.init = function() {
1201                 var currentCtx = this;
1202                 function UniformStructCase(name, description, textures, shaderSrc, setUniformsFunc, evalFunc) {
1203                         currentCtx.addChild(es3fShaderStructTests.ShaderStructCase.createStructCase(name + "_vertex", description, true, textures, evalFunc, setUniformsFunc, shaderSrc));
1204                         currentCtx.addChild(es3fShaderStructTests.ShaderStructCase.createStructCase(name + "_fragment", description, false, textures, evalFunc, setUniformsFunc, shaderSrc));
1205                 }
1207                 UniformStructCase('basic', "Basic struct usage", false,
1208                         '${HEADER}\n' +
1209                         'uniform int ui_one;\n' +
1210                         '' +
1211                         'struct S {\n' +
1212                         '       mediump float   a;\n' +
1213                         '       mediump vec3    b;\n' +
1214                         '       int                             c;\n' +
1215                         '};\n' +
1216                         'uniform S s;\n' +
1217                         '' +
1218                         'void main (void)\n' +
1219                         '{\n' +
1220                         '       ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);\n' +
1221                         '       ${ASSIGN_POS}\n' +
1222                         '}',
1223                         function(programID, constCoords) {
1224                                 es3fShaderStructTests.setUniform1f(programID, "s.a", constCoords[0]);
1225                                 es3fShaderStructTests.setUniform3fv(programID, "s.b", deMath.swizzle(constCoords, [1, 2, 3]));
1226                                 es3fShaderStructTests.setUniform1i(programID, "s.c", 1);
1227                         },
1228                         function(c) {
1229                                 c.color[0] = c.constCoords[0];
1230                                 c.color[1] = c.constCoords[1];
1231                                 c.color[2] = c.constCoords[2];
1232                         });
1234                 UniformStructCase('nested', "Nested struct", false,
1235                         '${HEADER}\n' +
1236                         'uniform int ui_zero;\n' +
1237                         'uniform int ui_one;\n' +
1238                         '' +
1239                         'struct T {\n' +
1240                         '       int                             a;\n' +
1241                         '       mediump vec2    b;\n' +
1242                         '};\n' +
1243                         'struct S {\n' +
1244                         '       mediump float   a;\n' +
1245                         '       T                               b;\n' +
1246                         '       int                             c;\n' +
1247                         '};\n' +
1248                         'uniform S s;\n' +
1249                         '' +
1250                         'void main (void)\n' +
1251                         '{\n' +
1252                         '       ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);\n' +
1253                         '       ${ASSIGN_POS}\n' +
1254                         '}',
1255                         function(programID, constCoords) {
1256                                 es3fShaderStructTests.setUniform1f(programID, "s.a", constCoords[0]);
1257                                 es3fShaderStructTests.setUniform1i(programID, "s.b.a", 0);
1258                                 es3fShaderStructTests.setUniform2fv(programID, "s.b.b", deMath.swizzle(constCoords, [1,2]));
1259                                 es3fShaderStructTests.setUniform1i(programID, "s.c", 1);
1260                         },
1261                         function(c) {
1262                                 c.color[0] = c.constCoords[0];
1263                                 c.color[1] = c.constCoords[1];
1264                                 c.color[2] = c.constCoords[2];
1265                         });
1267                 UniformStructCase('array_member', "Struct with array member", false,
1268                         '${HEADER}\n' +
1269                         'uniform int ui_one;\n' +
1270                         '' +
1271                         'struct S {\n' +
1272                         '       mediump float   a;\n' +
1273                         '       mediump float   b[3];\n' +
1274                         '       int                             c;\n' +
1275                         '};\n' +
1276                         'uniform S s;\n' +
1277                         '' +
1278                         'void main (void)\n' +
1279                         '{\n' +
1280                         '       ${DST} = vec4(s.a, s.b[0], s.b[1], s.c);\n' +
1281                         '       ${ASSIGN_POS}\n' +
1282                         '}',
1283                         function(programID, constCoords){
1284                                 es3fShaderStructTests.setUniform1f(programID, "s.a", constCoords[3]);
1285                                 es3fShaderStructTests.setUniform1i(programID, "s.c", 1);
1287                                 /** @type {Array<number>} */ var b = [];
1288                                 b[0] = constCoords[2];
1289                                 b[1] = constCoords[1];
1290                                 b[2] = constCoords[0];
1291                                 es3fShaderStructTests.setUniform1fv(programID, "s.b", b);
1292                         },
1293                         function(c) {
1294                                 c.color[0] = c.constCoords[3];
1295                                 c.color[1] = c.constCoords[2];
1296                                 c.color[2] = c.constCoords[1];
1297                         });
1299                 UniformStructCase('array_member_dynamic_index', "Struct with array member, dynamic indexing", false,
1300                         '${HEADER}\n' +
1301                         'uniform int ui_zero;\n' +
1302                         'uniform int ui_one;\n' +
1303                         'uniform int ui_two;\n' +
1304                         '' +
1305                         'struct S {\n' +
1306                         '    mediump float    a;\n' +
1307                         '    mediump float    b[3];\n' +
1308                         '    int                c;\n' +
1309                         '};\n' +
1310                         'uniform S s;\n' +
1311                         '' +
1312                         'void main (void)\n' +
1313                         '{\n' +
1314                         '    ${DST} = vec4(s.b[ui_one], s.b[ui_zero], s.b[ui_two], s.c);\n' +
1315                         '    ${ASSIGN_POS}\n' +
1316                         '}',
1317                         function(programID, constCoords) {
1318                                 es3fShaderStructTests.setUniform1f(programID, "s.a", constCoords[3]);
1319                                 es3fShaderStructTests.setUniform1i(programID, "s.c", 1);
1321                                 /** @type {Array<number>} */ var b = [];
1322                                 b[0] = constCoords[2];
1323                                 b[1] = constCoords[1];
1324                                 b[2] = constCoords[0];
1325                                 es3fShaderStructTests.setUniform1fv(programID, "s.b", b);
1326                         },
1327                         function(c) {
1328                                 c.color[0] = c.constCoords[1];
1329                                 c.color[1] = c.constCoords[2];
1330                                 c.color[2] = c.constCoords[0];
1331                         });
1333                 UniformStructCase('struct_array', "Struct array", false,
1334                         '${HEADER}\n' +
1335                         'uniform int ui_zero;\n' +
1336                         'uniform int ui_one;\n' +
1337                         'uniform int ui_two;\n' +
1338                         '' +
1339                         'struct S {\n' +
1340                         '    mediump float    a;\n' +
1341                         '    mediump int        b;\n' +
1342                         '};\n' +
1343                         'uniform S s[3];\n' +
1344                         '' +
1345                         'void main (void)\n' +
1346                         '{\n' +
1347                         '    ${DST} = vec4(s[2].a, s[1].a, s[0].a, s[2].b - s[1].b + s[0].b);\n' +
1348                         '    ${ASSIGN_POS}\n' +
1349                         '}',
1350                         function(programID, constCoords) {
1351                                 es3fShaderStructTests.setUniform1f(programID, "s[0].a", constCoords[0]);
1352                                 es3fShaderStructTests.setUniform1i(programID, "s[0].b", 0);
1353                                 es3fShaderStructTests.setUniform1f(programID, "s[1].a", constCoords[1]);
1354                                 es3fShaderStructTests.setUniform1i(programID, "s[1].b", 1);
1355                                 es3fShaderStructTests.setUniform1f(programID, "s[2].a", constCoords[2]);
1356                                 es3fShaderStructTests.setUniform1i(programID, "s[2].b", 2);
1357                         },
1358                         function(c) {
1359                                 c.color[0] = c.constCoords[2];
1360                                 c.color[1] = c.constCoords[1];
1361                                 c.color[2] = c.constCoords[0];
1362                         });
1364                 UniformStructCase('struct_array_dynamic_index', "Struct array with dynamic indexing", false,
1365                         '${HEADER}\n' +
1366                         'uniform int ui_zero;\n' +
1367                         'uniform int ui_one;\n' +
1368                         'uniform int ui_two;\n' +
1369                         '' +
1370                         'struct S {\n' +
1371                         '    mediump float    a;\n' +
1372                         '    mediump int        b;\n' +
1373                         '};\n' +
1374                         'uniform S s[3];\n' +
1375                         '' +
1376                         'void main (void)\n' +
1377                         '{\n' +
1378                         '    ${DST} = vec4(s[ui_two].a, s[ui_one].a, s[ui_zero].a, s[ui_two].b - s[ui_one].b + s[ui_zero].b);\n' +
1379                         '    ${ASSIGN_POS}\n' +
1380                         '}',
1381                         function(programID, constCoords) {
1382                                 es3fShaderStructTests.setUniform1f(programID, "s[0].a", constCoords[0]);
1383                                 es3fShaderStructTests.setUniform1i(programID, "s[0].b", 0);
1384                                 es3fShaderStructTests.setUniform1f(programID, "s[1].a", constCoords[1]);
1385                                 es3fShaderStructTests.setUniform1i(programID, "s[1].b", 1);
1386                                 es3fShaderStructTests.setUniform1f(programID, "s[2].a", constCoords[2]);
1387                                 es3fShaderStructTests.setUniform1i(programID, "s[2].b", 2);
1388                         },
1389                         function(c) {
1390                                 c.color[0] = c.constCoords[2];
1391                                 c.color[1] = c.constCoords[1];
1392                                 c.color[2] = c.constCoords[0];
1393                         });
1395                 UniformStructCase('nested_struct_array', "Nested struct array", false,
1396                         '${HEADER}\n' +
1397                         'struct T {\n' +
1398                         '    mediump float    a;\n' +
1399                         '    mediump vec2    b[2];\n' +
1400                         '};\n' +
1401                         'struct S {\n' +
1402                         '    mediump float    a;\n' +
1403                         '    T                b[3];\n' +
1404                         '    int                c;\n' +
1405                         '};\n' +
1406                         'uniform S s[2];\n' +
1407                         '' +
1408                         'void main (void)\n' +
1409                         '{\n' +
1410                         '    mediump float r = (s[0].b[1].b[0].x + s[1].b[2].b[1].y) * s[0].b[0].a; // (z + z) * 0.5\n' +
1411                         '    mediump float g = s[1].b[0].b[0].y * s[0].b[2].a * s[1].b[2].a; // x * 0.25 * 4\n' +
1412                         '    mediump float b = (s[0].b[2].b[1].y + s[0].b[1].b[0].y + s[1].a) * s[0].b[1].a; // (w + w + w) * 0.333\n' +
1413                         '    mediump float a = float(s[0].c) + s[1].b[2].a - s[1].b[1].a; // 0 + 4.0 - 3.0\n' +
1414                         '    ${DST} = vec4(r, g, b, a);\n' +
1415                         '    ${ASSIGN_POS}\n' +
1416                         '}',
1417                         function(programID, constCoords) {
1418                                 /** @type {Array<number>} */ var arr = [];
1420                                 es3fShaderStructTests.setUniform1f(programID, "s[0].a", constCoords[0]);
1421                                 arr = deMath.swizzle(constCoords, [0,1,2,3]);
1422                                 es3fShaderStructTests.setUniform1f(programID, "s[0].b[0].a", 0.5);
1423                                 es3fShaderStructTests.setUniform2fv(programID, "s[0].b[0].b", arr);
1424                                 arr = deMath.swizzle(constCoords, [2,3,0,1]);
1425                                 es3fShaderStructTests.setUniform1f(programID, "s[0].b[1].a", 1.0/3.0);
1426                                 es3fShaderStructTests.setUniform2fv(programID, "s[0].b[1].b", arr);
1427                                 arr = deMath.swizzle(constCoords, [0,2,1,3]);
1428                                 es3fShaderStructTests.setUniform1f(programID, "s[0].b[2].a", 1.0/4.0);
1429                                 es3fShaderStructTests.setUniform2fv(programID, "s[0].b[2].b", arr);
1430                                 es3fShaderStructTests.setUniform1i(programID, "s[0].c", 0);
1432                                 es3fShaderStructTests.setUniform1f(programID, "s[1].a", constCoords[3]);
1433                                 arr = deMath.swizzle(constCoords, [0,0,1,1]);
1434                                 es3fShaderStructTests.setUniform1f(programID, "s[1].b[0].a", 2.0);
1435                                 es3fShaderStructTests.setUniform2fv(programID, "s[1].b[0].b", arr);
1436                                 arr = deMath.swizzle(constCoords, [2,2,3,3]);
1437                                 es3fShaderStructTests.setUniform1f(programID, "s[1].b[1].a", 3.0);
1438                                 es3fShaderStructTests.setUniform2fv(programID, "s[1].b[1].b", arr);
1439                                 arr = deMath.swizzle(constCoords, [1,0,3,2]);
1440                                 es3fShaderStructTests.setUniform1f(programID, "s[1].b[2].a", 4.0);
1441                                 es3fShaderStructTests.setUniform2fv(programID, "s[1].b[2].b", arr);
1442                                 es3fShaderStructTests.setUniform1i(programID, "s[1].c", 1);
1443                         },
1444                         function(c) {
1445                                 c.color[0] = c.constCoords[2];
1446                                 c.color[1] = c.constCoords[0];
1447                                 c.color[2] = c.constCoords[3];
1448                         });
1450                 UniformStructCase('nested_struct_array_dynamic_index', "Nested struct array with dynamic indexing", false,
1451                         '${HEADER}\n' +
1452                         'uniform int ui_zero;\n' +
1453                         'uniform int ui_one;\n' +
1454                         'uniform int ui_two;\n' +
1455                         '' +
1456                         'struct T {\n' +
1457                         '    mediump float    a;\n' +
1458                         '    mediump vec2    b[2];\n' +
1459                         '};\n' +
1460                         'struct S {\n' +
1461                         '    mediump float    a;\n' +
1462                         '    T                b[3];\n' +
1463                         '    int                c;\n' +
1464                         '};\n' +
1465                         'uniform S s[2];\n' +
1466                         '' +
1467                         'void main (void)\n' +
1468                         '{\n' +
1469                         '    mediump float r = (s[0].b[ui_one].b[ui_one-1].x + s[ui_one].b[ui_two].b[ui_zero+1].y) * s[0].b[0].a; // (z + z) * 0.5\n' +
1470                         '    mediump float g = s[ui_two-1].b[ui_two-2].b[ui_zero].y * s[0].b[ui_two].a * s[ui_one].b[2].a; // x * 0.25 * 4\n' +
1471                         '    mediump float b = (s[ui_zero].b[ui_one+1].b[1].y + s[0].b[ui_one*ui_one].b[0].y + s[ui_one].a) * s[0].b[ui_two-ui_one].a; // (w + w + w) * 0.333\n' +
1472                         '    mediump float a = float(s[ui_zero].c) + s[ui_one-ui_zero].b[ui_two].a - s[ui_zero+ui_one].b[ui_two-ui_one].a; // 0 + 4.0 - 3.0\n' +
1473                         '    ${DST} = vec4(r, g, b, a);\n' +
1474                         '    ${ASSIGN_POS}\n' +
1475                         '}',
1476                         function(programID, constCoords){
1477                                 /** @type {Array<number>} */ var arr = [];
1479                                 es3fShaderStructTests.setUniform1f(programID, "s[0].a", constCoords[0]);
1480                                 arr = constCoords;
1481                                 es3fShaderStructTests.setUniform1f(programID, "s[0].b[0].a", 0.5);
1482                                 es3fShaderStructTests.setUniform2fv(programID, "s[0].b[0].b", arr);
1483                                 arr = deMath.swizzle(constCoords, [2,3,0,1]);
1484                                 es3fShaderStructTests.setUniform1f(programID, "s[0].b[1].a", 1.0/3.0);
1485                                 es3fShaderStructTests.setUniform2fv(programID, "s[0].b[1].b", arr);
1486                                 arr = deMath.swizzle(constCoords, [0,2,1,3]);
1487                                 es3fShaderStructTests.setUniform1f(programID, "s[0].b[2].a", 1.0/4.0);
1488                                 es3fShaderStructTests.setUniform2fv(programID, "s[0].b[2].b", arr);
1489                                 es3fShaderStructTests.setUniform1i(programID, "s[0].c", 0);
1491                                 es3fShaderStructTests.setUniform1f(programID, "s[1].a", constCoords[3]);
1492                                 arr = deMath.swizzle(constCoords, [0,0,1,1]);
1493                                 es3fShaderStructTests.setUniform1f(programID, "s[1].b[0].a", 2.0);
1494                                 es3fShaderStructTests.setUniform2fv(programID, "s[1].b[0].b", arr);
1495                                 arr = deMath.swizzle(constCoords, [2,2,3,3]);
1496                                 es3fShaderStructTests.setUniform1f(programID, "s[1].b[1].a", 3.0);
1497                                 es3fShaderStructTests.setUniform2fv(programID, "s[1].b[1].b", arr);
1498                                 arr = deMath.swizzle(constCoords, [1,0,3,2]);
1499                                 es3fShaderStructTests.setUniform1f(programID, "s[1].b[2].a", 4.0);
1500                                 es3fShaderStructTests.setUniform2fv(programID, "s[1].b[2].b", arr);
1501                                 es3fShaderStructTests.setUniform1i(programID, "s[1].c", 1);
1502                         },
1503                         function(c) {
1504                                 c.color[0] = c.constCoords[2];
1505                                 c.color[1] = c.constCoords[0];
1506                                 c.color[2] = c.constCoords[3];
1507                         });
1509                 UniformStructCase('loop_struct_array', "Struct array usage in loop", false,
1510                         '${HEADER}\n' +
1511                         'uniform int ui_zero;\n' +
1512                         'uniform int ui_one;\n' +
1513                         'uniform int ui_two;\n' +
1514                         '' +
1515                         'struct S {\n' +
1516                         '    mediump float    a;\n' +
1517                         '    mediump int        b;\n' +
1518                         '};\n' +
1519                         'uniform S s[3];\n' +
1520                         '' +
1521                         'void main (void)\n' +
1522                         '{\n' +
1523                         '    mediump float rgb[3];\n' +
1524                         '    int alpha = 0;\n' +
1525                         '    for (int i = 0; i < 3; i++)\n' +
1526                         '    {\n' +
1527                         '        rgb[i] = s[2-i].a;\n' +
1528                         '        alpha += s[i].b;\n' +
1529                         '    }\n' +
1530                         '    ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);\n' +
1531                         '    ${ASSIGN_POS}\n' +
1532                         '}',
1533                         function(programID, constCoords) {
1534                                 es3fShaderStructTests.setUniform1f(programID, "s[0].a", constCoords[0]);
1535                                 es3fShaderStructTests.setUniform1i(programID, "s[0].b", 0);
1536                                 es3fShaderStructTests.setUniform1f(programID, "s[1].a", constCoords[1]);
1537                                 es3fShaderStructTests.setUniform1i(programID, "s[1].b", -1);
1538                                 es3fShaderStructTests.setUniform1f(programID, "s[2].a", constCoords[2]);
1539                                 es3fShaderStructTests.setUniform1i(programID, "s[2].b", 2);
1540                         },
1541                         function(c) {
1542                                 c.color[0] = c.constCoords[2];
1543                                 c.color[1] = c.constCoords[1];
1544                                 c.color[2] = c.constCoords[0];
1545                         });
1547                 UniformStructCase('loop_nested_struct_array', "Nested struct array usage in loop", false,
1548                         '${HEADER}\n' +
1549                         'uniform int ui_zero;\n' +
1550                         'uniform int ui_one;\n' +
1551                         'uniform int ui_two;\n' +
1552                         'uniform mediump float uf_two;\n' +
1553                         'uniform mediump float uf_three;\n' +
1554                         'uniform mediump float uf_four;\n' +
1555                         'uniform mediump float uf_half;\n' +
1556                         'uniform mediump float uf_third;\n' +
1557                         'uniform mediump float uf_fourth;\n' +
1558                         'uniform mediump float uf_sixth;\n' +
1559                         '' +
1560                         'struct T {\n' +
1561                         '    mediump float    a;\n' +
1562                         '    mediump vec2    b[2];\n' +
1563                         '};\n' +
1564                         'struct S {\n' +
1565                         '    mediump float    a;\n' +
1566                         '    T                b[3];\n' +
1567                         '    int                c;\n' +
1568                         '};\n' +
1569                         'uniform S s[2];\n' +
1570                         '' +
1571                         'void main (void)\n' +
1572                         '{\n' +
1573                         '    mediump float r = 0.0; // (x*3 + y*3) / 6.0\n' +
1574                         '    mediump float g = 0.0; // (y*3 + z*3) / 6.0\n' +
1575                         '    mediump float b = 0.0; // (z*3 + w*3) / 6.0\n' +
1576                         '    mediump float a = 1.0;\n' +
1577                         '    for (int i = 0; i < 2; i++)\n' +
1578                         '    {\n' +
1579                         '        for (int j = 0; j < 3; j++)\n' +
1580                         '        {\n' +
1581                         '            r += s[0].b[j].b[i].y;\n' +
1582                         '            g += s[i].b[j].b[0].x;\n' +
1583                         '            b += s[i].b[j].b[1].x;\n' +
1584                         '            a *= s[i].b[j].a;\n' +
1585                         '        }\n' +
1586                         '    }\n' +
1587                         '    ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);\n' +
1588                         '    ${ASSIGN_POS}\n' +
1589                         '}',
1590                         function(programID, constCoords) {
1591                                 /** @type {Array<number>} */ var arr = [];
1593                                 es3fShaderStructTests.setUniform1f(programID, "s[0].a", constCoords[0]);
1594                                 arr = deMath.swizzle(constCoords, [1,0,2,0]);
1595                                 es3fShaderStructTests.setUniform1f(programID, "s[0].b[0].a", 0.5);
1596                                 es3fShaderStructTests.setUniform2fv(programID, "s[0].b[0].b", arr);
1597                                 arr = deMath.swizzle(constCoords, [1,1,3,1]);
1598                                 es3fShaderStructTests.setUniform1f(programID, "s[0].b[1].a", 1.0/3.0);
1599                                 es3fShaderStructTests.setUniform2fv(programID, "s[0].b[1].b", arr);
1600                                 arr = deMath.swizzle(constCoords, [2,1,2,1]);
1601                                 es3fShaderStructTests.setUniform1f(programID, "s[0].b[2].a", 1.0/4.0);
1602                                 es3fShaderStructTests.setUniform2fv(programID, "s[0].b[2].b", arr);
1603                                 es3fShaderStructTests.setUniform1i(programID, "s[0].c", 0);
1605                                 es3fShaderStructTests.setUniform1f(programID, "s[1].a", constCoords[3]);
1606                                 arr = deMath.swizzle(constCoords, [2,0,2,1]);
1607                                 es3fShaderStructTests.setUniform1f(programID, "s[1].b[0].a", 2.0);
1608                                 es3fShaderStructTests.setUniform2fv(programID, "s[1].b[0].b", arr);
1609                                 arr = deMath.swizzle(constCoords, [2,2,3,3]);
1610                                 es3fShaderStructTests.setUniform1f(programID, "s[1].b[1].a", 3.0);
1611                                 es3fShaderStructTests.setUniform2fv(programID, "s[1].b[1].b", arr);
1612                                 arr = deMath.swizzle(constCoords, [1,0,3,2]);
1613                                 es3fShaderStructTests.setUniform1f(programID, "s[1].b[2].a", 4.0);
1614                                 es3fShaderStructTests.setUniform2fv(programID, "s[1].b[2].b", arr);
1615                                 es3fShaderStructTests.setUniform1i(programID, "s[1].c", 1);
1616                         },
1617                         function(c) {
1618                                 c.color[0] = (c.constCoords[0] + c.constCoords[1]) * 0.5;
1619                                 c.color[1] = (c.constCoords[1] + c.constCoords[2]) * 0.5;
1620                                 c.color[2] = (c.constCoords[2] + c.constCoords[3]) * 0.5;
1621                         });
1623                 UniformStructCase('dynamic_loop_struct_array', "Struct array usage in dynamic loop", false,
1624                         '${HEADER}\n' +
1625                         'uniform int ui_zero;\n' +
1626                         'uniform int ui_one;\n' +
1627                         'uniform int ui_two;\n' +
1628                         'uniform int ui_three;\n' +
1629                         '' +
1630                         'struct S {\n' +
1631                         '    mediump float    a;\n' +
1632                         '    mediump int        b;\n' +
1633                         '};\n' +
1634                         'uniform S s[3];\n' +
1635                         '' +
1636                         'void main (void)\n' +
1637                         '{\n' +
1638                         '    mediump float rgb[3];\n' +
1639                         '    int alpha = 0;\n' +
1640                         '    for (int i = 0; i < ui_three; i++)\n' +
1641                         '    {\n' +
1642                         '        rgb[i] = s[2-i].a;\n' +
1643                         '        alpha += s[i].b;\n' +
1644                         '    }\n' +
1645                         '    ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);\n' +
1646                         '    ${ASSIGN_POS}\n' +
1647                         '}',
1648                         function(programID, constCoords) {
1649                                 es3fShaderStructTests.setUniform1f(programID, "s[0].a", constCoords[0]);
1650                                 es3fShaderStructTests.setUniform1i(programID, "s[0].b", 0);
1651                                 es3fShaderStructTests.setUniform1f(programID, "s[1].a", constCoords[1]);
1652                                 es3fShaderStructTests.setUniform1i(programID, "s[1].b", -1);
1653                                 es3fShaderStructTests.setUniform1f(programID, "s[2].a", constCoords[2]);
1654                                 es3fShaderStructTests.setUniform1i(programID, "s[2].b", 2);
1655                         },
1656                         function(c) {
1657                                 c.color[0] = c.constCoords[2];
1658                                 c.color[1] = c.constCoords[1];
1659                                 c.color[2] = c.constCoords[0];
1660                         });
1662                 UniformStructCase('dynamic_loop_nested_struct_array', "Nested struct array usage in dynamic loop", false,
1663                         '${HEADER}\n' +
1664                         'uniform int ui_zero;\n' +
1665                         'uniform int ui_one;\n' +
1666                         'uniform int ui_two;\n' +
1667                         'uniform int ui_three;\n' +
1668                         'uniform mediump float uf_two;\n' +
1669                         'uniform mediump float uf_three;\n' +
1670                         'uniform mediump float uf_four;\n' +
1671                         'uniform mediump float uf_half;\n' +
1672                         'uniform mediump float uf_third;\n' +
1673                         'uniform mediump float uf_fourth;\n' +
1674                         'uniform mediump float uf_sixth;\n' +
1675                         '' +
1676                         'struct T {\n' +
1677                         '    mediump float    a;\n' +
1678                         '    mediump vec2    b[2];\n' +
1679                         '};\n' +
1680                         'struct S {\n' +
1681                         '    mediump float    a;\n' +
1682                         '    T                b[3];\n' +
1683                         '    int                c;\n' +
1684                         '};\n' +
1685                         'uniform S s[2];\n' +
1686                         '' +
1687                         'void main (void)\n' +
1688                         '{\n' +
1689                         '    mediump float r = 0.0; // (x*3 + y*3) / 6.0\n' +
1690                         '    mediump float g = 0.0; // (y*3 + z*3) / 6.0\n' +
1691                         '    mediump float b = 0.0; // (z*3 + w*3) / 6.0\n' +
1692                         '    mediump float a = 1.0;\n' +
1693                         '    for (int i = 0; i < ui_two; i++)\n' +
1694                         '    {\n' +
1695                         '        for (int j = 0; j < ui_three; j++)\n' +
1696                         '        {\n' +
1697                         '            r += s[0].b[j].b[i].y;\n' +
1698                         '            g += s[i].b[j].b[0].x;\n' +
1699                         '            b += s[i].b[j].b[1].x;\n' +
1700                         '            a *= s[i].b[j].a;\n' +
1701                         '        }\n' +
1702                         '    }\n' +
1703                         '    ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);\n' +
1704                         '    ${ASSIGN_POS}\n' +
1705                         '}',
1706                         function(programID, constCoords) {
1707                                 /** @type {Array<number>} */ var arr = [];
1709                                 es3fShaderStructTests.setUniform1f(programID, "s[0].a", constCoords[0]);
1710                                 arr = deMath.swizzle(constCoords, [1,0,2,0]);
1711                                 es3fShaderStructTests.setUniform1f(programID, "s[0].b[0].a", 0.5);
1712                                 es3fShaderStructTests.setUniform2fv(programID, "s[0].b[0].b", arr);
1713                                 arr = deMath.swizzle(constCoords, [1,1,3,1]);
1714                                 es3fShaderStructTests.setUniform1f(programID, "s[0].b[1].a", 1.0/3.0);
1715                                 es3fShaderStructTests.setUniform2fv(programID, "s[0].b[1].b", arr);
1716                                 arr = deMath.swizzle(constCoords, [2,1,2,1]);
1717                                 es3fShaderStructTests.setUniform1f(programID, "s[0].b[2].a",    1.0/4.0);
1718                                 es3fShaderStructTests.setUniform2fv(programID, "s[0].b[2].b", arr);
1719                                 es3fShaderStructTests.setUniform1i(programID, "s[0].c", 0);
1721                                 es3fShaderStructTests.setUniform1f(programID, "s[1].a", constCoords[3]);
1722                                 arr = deMath.swizzle(constCoords, [2,0,2,1]);
1723                                 es3fShaderStructTests.setUniform1f(programID, "s[1].b[0].a", 2.0);
1724                                 es3fShaderStructTests.setUniform2fv(programID, "s[1].b[0].b", arr);
1725                                 arr = deMath.swizzle(constCoords, [2,2,3,3]);
1726                                 es3fShaderStructTests.setUniform1f(programID, "s[1].b[1].a", 3.0);
1727                                 es3fShaderStructTests.setUniform2fv(programID, "s[1].b[1].b", arr);
1728                                 arr = deMath.swizzle(constCoords, [1,0,3,2]);
1729                                 es3fShaderStructTests.setUniform1f(programID, "s[1].b[2].a", 4.0);
1730                                 es3fShaderStructTests.setUniform2fv(programID, "s[1].b[2].b", arr);
1731                                 es3fShaderStructTests.setUniform1i(programID, "s[1].c", 1);
1732                         },
1733                         function(c) {
1734                                 c.color[0] = (c.constCoords[0] + c.constCoords[1]) * 0.5;
1735                                 c.color[1] = (c.constCoords[1] + c.constCoords[2]) * 0.5;
1736                                 c.color[2] = (c.constCoords[2] + c.constCoords[3]) * 0.5;
1737                         });
1739                 UniformStructCase('sampler', "Sampler in struct", true,
1740                         '${HEADER}\n' +
1741                         'uniform int ui_one;\n' +
1742                         '' +
1743                         'struct S {\n' +
1744                         '    mediump float    a;\n' +
1745                         '    mediump vec3    b;\n' +
1746                         '    sampler2D        c;\n' +
1747                         '};\n' +
1748                         'uniform S s;\n' +
1749                         '' +
1750                         'void main (void)\n' +
1751                         '{\n' +
1752                         '    ${DST} = vec4(texture(s.c, ${COORDS}.xy * s.b.xy + s.b.z).rgb, s.a);\n' +
1753                         '    ${ASSIGN_POS}\n' +
1754                         '}',
1755                         function(programID, constCoords) {
1756                                 es3fShaderStructTests.setUniform1f(programID, "s.a", 1.0);
1757                                 es3fShaderStructTests.setUniform3fv(programID, "s.b", [0.25, 0.25, 0.5]);
1758                                 es3fShaderStructTests.setUniform1i(programID, "s.c", 0);
1759                         },
1760                         function(c) {
1761                                 var tex2d = c.texture2D(es3fShaderStructTests.TEXTURE_BRICK, deMath.addScalar(deMath.scale(deMath.swizzle(c.coords, [0,1]), 0.25), 0.5))
1763                                 c.color[0] = tex2d[0];
1764                                 c.color[1] = tex2d[1];
1765                                 c.color[2] = tex2d[2];
1766                         });
1768                 UniformStructCase('sampler_nested', "Sampler in nested struct", true,
1769                         '${HEADER}\n' +
1770                         'uniform int ui_zero;\n' +
1771                         'uniform int ui_one;\n' +
1772                         '' +
1773                         'struct T {\n' +
1774                         '    sampler2D        a;\n' +
1775                         '    mediump vec2    b;\n' +
1776                         '};\n' +
1777                         'struct S {\n' +
1778                         '    mediump float    a;\n' +
1779                         '    T                b;\n' +
1780                         '    int                c;\n' +
1781                         '};\n' +
1782                         'uniform S s;\n' +
1783                         '' +
1784                         'void main (void)\n' +
1785                         '{\n' +
1786                         '    ${DST} = vec4(texture(s.b.a, ${COORDS}.xy * s.b.b + s.a).rgb, s.c);\n' +
1787                         '    ${ASSIGN_POS}\n' +
1788                         '}',
1789                         function(programID, constCoords) {
1790                                 es3fShaderStructTests.setUniform1f(programID, "s.a", 0.5);
1791                                 es3fShaderStructTests.setUniform1i(programID, "s.b.a", 0);
1792                                 es3fShaderStructTests.setUniform2fv(programID, "s.b.b", [0.25, 0.25]);
1793                                 es3fShaderStructTests.setUniform1i(programID, "s.c", 1);
1794                         },
1795                         function(c) {
1796                                 var tex2d = c.texture2D(es3fShaderStructTests.TEXTURE_BRICK, deMath.addScalar(deMath.scale(deMath.swizzle(c.coords, [0,1]), 0.25), 0.5));
1797                                 c.color[0] = tex2d[0];
1798                                 c.color[1] = tex2d[1];
1799                                 c.color[2] = tex2d[2];
1800                         });
1802                 UniformStructCase('sampler_array', "Sampler in struct array", true,
1803                         '${HEADER}\n' +
1804                         'uniform int ui_one;\n' +
1805                         '' +
1806                         'struct S {\n' +
1807                         '    mediump float    a;\n' +
1808                         '    mediump vec3    b;\n' +
1809                         '    sampler2D        c;\n' +
1810                         '};\n' +
1811                         'uniform S s[2];\n' +
1812                         '' +
1813                         'void main (void)\n' +
1814                         '{\n' +
1815                         '    ${DST} = vec4(texture(s[1].c, ${COORDS}.xy * s[0].b.xy + s[1].b.z).rgb, s[0].a);\n' +
1816                         '    ${ASSIGN_POS}\n' +
1817                         '}',
1818                         function(programID, constCoords) {
1819                                 es3fShaderStructTests.setUniform1f(programID, "s[0].a", 1.0);
1820                                 es3fShaderStructTests.setUniform3fv(programID, "s[0].b", [0.25, 0.25, 0.25]);
1821                                 es3fShaderStructTests.setUniform1i(programID, "s[0].c", 1);
1822                                 es3fShaderStructTests.setUniform1f(programID, "s[1].a", 0.0);
1823                                 es3fShaderStructTests.setUniform3fv(programID, "s[1].b", [0.5, 0.5, 0.5]);
1824                                 es3fShaderStructTests.setUniform1i(programID, "s[1].c", 0);
1825                         },
1826                         function(c) {
1827                                 var tex2d = c.texture2D(es3fShaderStructTests.TEXTURE_BRICK, deMath.addScalar(deMath.scale(deMath.swizzle(c.coords, [0,1]), 0.25), 0.5));
1828                                 c.color[0] = tex2d[0];
1829                                 c.color[1] = tex2d[1];
1830                                 c.color[2] = tex2d[2];
1831                         });
1833                 UniformStructCase('equal', "Struct equality", false,
1834                         '${HEADER}\n' +
1835                         'uniform mediump float uf_one;\n' +
1836                         'uniform int ui_two;\n' +
1837                         '' +
1838                         'struct S {\n' +
1839                         '    mediump float    a;\n' +
1840                         '    mediump vec3    b;\n' +
1841                         '    int                c;\n' +
1842                         '};\n' +
1843                         'uniform S a;\n' +
1844                         'uniform S b;\n' +
1845                         'uniform S c;\n' +
1846                         '' +
1847                         'void main (void)\n' +
1848                         '{\n' +
1849                         '    S d = S(uf_one, vec3(0.0, floor(${COORDS}.y+1.0), 2.0), ui_two);\n' +
1850                         '    ${DST} = vec4(0.0, 0.0, 0.0, 1.0);\n' +
1851                         '    if (a == b) ${DST}.x = 1.0;\n' +
1852                         '    if (a == c) ${DST}.y = 1.0;\n' +
1853                         '    if (a == d) ${DST}.z = 1.0;\n' +
1854                         '    ${ASSIGN_POS}\n' +
1855                         '}',
1856                         function(programID, constCoords) {
1857                                 es3fShaderStructTests.setUniform1f(programID, "a.a", 1.0);
1858                                 es3fShaderStructTests.setUniform3fv(programID, "a.b", [0.0, 1.0, 2.0]);
1859                                 es3fShaderStructTests.setUniform1i(programID, "a.c", 2);
1860                                 es3fShaderStructTests.setUniform1f(programID, "b.a", 1.0);
1861                                 es3fShaderStructTests.setUniform3fv(programID, "b.b", [0.0, 1.0, 2.0]);
1862                                 es3fShaderStructTests.setUniform1i(programID, "b.c", 2);
1863                                 es3fShaderStructTests.setUniform1f(programID, "c.a", 1.0);
1864                                 es3fShaderStructTests.setUniform3fv(programID, "c.b", [0.0, 1.1, 2.0]);
1865                                 es3fShaderStructTests.setUniform1i(programID, "c.c", 2);
1866                         },
1867                         function(c) {
1868                                 c.color[0] = 1.0;
1869                                 c.color[1] = 0.0;
1870                                 if (Math.floor(c.coords[1] + 1.0) == Math.floor(1.1))
1871                                         c.color[2] = 1.0;
1872                         });
1874                 UniformStructCase('not_equal', "Struct equality", false,
1875                         '${HEADER}\n' +
1876                         'uniform mediump float uf_one;\n' +
1877                         'uniform int ui_two;\n' +
1878                         '' +
1879                         'struct S {\n' +
1880                         '    mediump float    a;\n' +
1881                         '    mediump vec3    b;\n' +
1882                         '    int                c;\n' +
1883                         '};\n' +
1884                         'uniform S a;\n' +
1885                         'uniform S b;\n' +
1886                         'uniform S c;\n' +
1887                         '' +
1888                         'void main (void)\n' +
1889                         '{\n' +
1890                         '    S d = S(uf_one, vec3(0.0, floor(${COORDS}.y+1.0), 2.0), ui_two);\n' +
1891                         '    ${DST} = vec4(0.0, 0.0, 0.0, 1.0);\n' +
1892                         '    if (a != b) ${DST}.x = 1.0;\n' +
1893                         '    if (a != c) ${DST}.y = 1.0;\n' +
1894                         '    if (a != d) ${DST}.z = 1.0;\n' +
1895                         '    ${ASSIGN_POS}\n' +
1896                         '}',
1897                         function(programID, constCoords) {
1898                                 es3fShaderStructTests.setUniform1f(programID, "a.a", 1.0);
1899                                 es3fShaderStructTests.setUniform3fv(programID, "a.b", [0.0, 1.0, 2.0]);
1900                                 es3fShaderStructTests.setUniform1i(programID, "a.c", 2);
1901                                 es3fShaderStructTests.setUniform1f(programID, "b.a", 1.0);
1902                                 es3fShaderStructTests.setUniform3fv(programID, "b.b", [0.0, 1.0, 2.0]);
1903                                 es3fShaderStructTests.setUniform1i(programID, "b.c", 2);
1904                                 es3fShaderStructTests.setUniform1f(programID, "c.a", 1.0);
1905                                 es3fShaderStructTests.setUniform3fv(programID, "c.b", [0.0, 1.1, 2.0]);
1906                                 es3fShaderStructTests.setUniform1i(programID, "c.c", 2);
1907                         },
1908                         function(c) {
1909                                 c.color[0] = 0.0;
1910                                 c.color[1] = 1.0;
1911                                 if (Math.floor(c.coords[1] + 1.0) != Math.floor(1.1))
1912                                         c.color[2] = 1.0;
1913                         });
1915         };
1917         /**
1918          * @constructor
1919          * @extends {tcuTestCase.DeqpTest}
1920          */
1921         es3fShaderStructTests.ShaderStructTests = function() {
1922                 tcuTestCase.DeqpTest.call(this, 'struct', 'Struct Tests');
1923         };
1925         es3fShaderStructTests.ShaderStructTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
1926         es3fShaderStructTests.ShaderStructTests.prototype.constructor = es3fShaderStructTests.ShaderStructTests;
1928         es3fShaderStructTests.ShaderStructTests.prototype.init = function() {
1929                 this.addChild(new es3fShaderStructTests.LocalStructTests());
1930                 this.addChild(new es3fShaderStructTests.UniformStructTests());
1931         };
1933         /**
1934      * Run test
1935      * @param {WebGL2RenderingContext} context
1936      */
1937     es3fShaderStructTests.run = function(context) {
1938         gl = context;
1939         //Set up Test Root parameters
1940         var state = tcuTestCase.runner;
1941         state.setRoot(new es3fShaderStructTests.ShaderStructTests());
1943         //Set up name and description of this test series.
1944         setCurrentTestName(state.testCases.fullName());
1945         description(state.testCases.getDescription());
1946         try {
1947             //Run test cases
1948             tcuTestCase.runTestCases();
1949         }
1950         catch (err) {
1951             testFailedOptions('Failed to es3fShaderStructTests.run tests', false);
1952             tcuTestCase.runner.terminate();
1953         }
1954     };