es3fShaderStructTests.js (64670B)
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 */ 20 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'); 31 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; 42 43 /** @typedef {function(WebGLProgram, Array<number>)} */ 44 es3fShaderStructTests.SetupUniformsFunc; 45 46 /** @const {number} */ es3fShaderStructTests.TEXTURE_BRICK = 0; 47 48 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 }; 69 70 es3fShaderStructTests.ShaderStructCase.prototype = Object.create(glsShaderRenderCase.ShaderRenderCase.prototype); 71 es3fShaderStructTests.ShaderStructCase.prototype.constructor = es3fShaderStructTests.ShaderStructCase; 72 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(); 82 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))); 91 92 assertMsgOptions(this.m_textures.length === 1, 'Only one texture required', false, true); 93 } 94 this.postinit(); 95 }; 96 97 es3fShaderStructTests.ShaderStructCase.prototype.deinit = function() { 98 glsShaderRenderCase.ShaderRenderCase.prototype.deinit.call(this); 99 this.m_brickTexture = null; 100 }; 101 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 }; 111 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'; 140 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 } 162 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 }; 168 169 /** 170 * @constructor 171 * @extends {tcuTestCase.DeqpTest} 172 */ 173 es3fShaderStructTests.LocalStructTests = function() { 174 tcuTestCase.DeqpTest.call(this, 'local', 'Local structs'); 175 this.makeExecutable(); 176 }; 177 178 es3fShaderStructTests.LocalStructTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 179 es3fShaderStructTests.LocalStructTests.prototype.constructor = es3fShaderStructTests.LocalStructTests; 180 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 }; 187 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 }); 210 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 }); 238 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 }); 265 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 }); 294 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 }); 321 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 }); 348 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 }); 413 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 }); 478 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 }); 506 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 }); 539 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 }); 568 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 }); 602 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 }); 628 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 }); 656 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 }); 685 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 }); 715 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 }); 748 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 }); 782 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 }); 817 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 }); 893 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 }); 929 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 }); 1006 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 }); 1036 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 }); 1067 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 }); 1101 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 }; 1137 1138 /** 1139 * @constructor 1140 * @extends {tcuTestCase.DeqpTest} 1141 */ 1142 es3fShaderStructTests.UniformStructTests = function() { 1143 tcuTestCase.DeqpTest.call(this, 'uniform', 'Uniform structs'); 1144 this.makeExecutable(); 1145 }; 1146 1147 es3fShaderStructTests.UniformStructTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 1148 es3fShaderStructTests.UniformStructTests.prototype.constructor = es3fShaderStructTests.UniformStructTests; 1149 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 }; 1159 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 }; 1169 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 }; 1179 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 }; 1189 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 }; 1199 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 } 1206 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 }); 1233 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 }); 1266 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); 1286 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 }); 1298 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); 1320 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 }); 1332 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 }); 1363 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 }); 1394 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 = []; 1419 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); 1431 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 }); 1449 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 = []; 1478 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); 1490 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 }); 1508 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 }); 1546 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 = []; 1592 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); 1604 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 }); 1622 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 }); 1661 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 = []; 1708 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); 1720 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 }); 1738 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)) 1762 1763 c.color[0] = tex2d[0]; 1764 c.color[1] = tex2d[1]; 1765 c.color[2] = tex2d[2]; 1766 }); 1767 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 }); 1801 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 }); 1832 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 }); 1873 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 }); 1914 1915 }; 1916 1917 /** 1918 * @constructor 1919 * @extends {tcuTestCase.DeqpTest} 1920 */ 1921 es3fShaderStructTests.ShaderStructTests = function() { 1922 tcuTestCase.DeqpTest.call(this, 'struct', 'Struct Tests'); 1923 }; 1924 1925 es3fShaderStructTests.ShaderStructTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 1926 es3fShaderStructTests.ShaderStructTests.prototype.constructor = es3fShaderStructTests.ShaderStructTests; 1927 1928 es3fShaderStructTests.ShaderStructTests.prototype.init = function() { 1929 this.addChild(new es3fShaderStructTests.LocalStructTests()); 1930 this.addChild(new es3fShaderStructTests.UniformStructTests()); 1931 }; 1932 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()); 1942 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 }; 1955 1956 1957 });