es3fShaderLoopTests.js (52197B)
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.es3fShaderLoopTests'); 23 goog.require('framework.common.tcuStringTemplate'); 24 goog.require('framework.common.tcuTestCase'); 25 goog.require('framework.delibs.debase.deMath'); 26 goog.require('framework.opengl.gluShaderUtil'); 27 goog.require('framework.opengl.gluShaderProgram'); 28 goog.require('modules.shared.glsShaderRenderCase'); 29 30 goog.scope(function() { 31 var es3fShaderLoopTests = functional.gles3.es3fShaderLoopTests; 32 var tcuTestCase = framework.common.tcuTestCase; 33 var deMath = framework.delibs.debase.deMath; 34 var gluShaderUtil = framework.opengl.gluShaderUtil; 35 var gluShaderProgram = framework.opengl.gluShaderProgram; 36 var glsShaderRenderCase = modules.shared.glsShaderRenderCase; 37 var tcuStringTemplate = framework.common.tcuStringTemplate; 38 // Repeated with for, while, do-while. Examples given as 'for' loops. 39 // Repeated for const, uniform, dynamic loops. 40 41 /** 42 * @enum {number} 43 */ 44 es3fShaderLoopTests.LoopCase = { 45 LOOPCASE_EMPTY_BODY: 0, // for (...) { } 46 LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST: 1, // for (...) { break; <body>; } 47 LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST: 2, // for (...) { <body>; break; } 48 LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK: 3, // for (...) { <body>; if (cond) break; } 49 LOOPCASE_SINGLE_STATEMENT: 4, // for (...) statement; 50 LOOPCASE_COMPOUND_STATEMENT: 5, // for (...) { statement; statement; } 51 LOOPCASE_SEQUENCE_STATEMENT: 6, // for (...) statement, statement; 52 LOOPCASE_NO_ITERATIONS: 7, // for (i=0; i<0; i++) ... 53 LOOPCASE_SINGLE_ITERATION: 8, // for (i=0; i<1; i++) ... 54 LOOPCASE_SELECT_ITERATION_COUNT: 9, // for (i=0; i<a?b:c; i++) ... 55 LOOPCASE_CONDITIONAL_CONTINUE: 10, // for (...) { if (cond) continue; } 56 LOOPCASE_UNCONDITIONAL_CONTINUE: 11, // for (...) { <body>; continue; } 57 LOOPCASE_ONLY_CONTINUE: 12, // for (...) { continue; } 58 LOOPCASE_DOUBLE_CONTINUE: 13, // for (...) { if (cond) continue; <body>; continue; } 59 LOOPCASE_CONDITIONAL_BREAK: 14, // for (...) { if (cond) break; } 60 LOOPCASE_UNCONDITIONAL_BREAK: 15, // for (...) { <body>; break; } 61 LOOPCASE_PRE_INCREMENT: 16, // for (...; ++i) { <body>; } 62 LOOPCASE_POST_INCREMENT: 17, // for (...; i++) { <body>; } 63 LOOPCASE_MIXED_BREAK_CONTINUE: 18, 64 LOOPCASE_VECTOR_COUNTER: 19, // for (ivec3 ndx = ...; ndx.x < ndx.y; ndx.x += ndx.z) { ... } 65 LOOPCASE_101_ITERATIONS: 20, // loop for 101 iterations 66 LOOPCASE_SEQUENCE: 21, // two loops in sequence 67 LOOPCASE_NESTED: 22, // two nested loops 68 LOOPCASE_NESTED_SEQUENCE: 23, // two loops in sequence nested inside a third 69 LOOPCASE_NESTED_TRICKY_DATAFLOW_1: 24, // nested loops with tricky data flow 70 LOOPCASE_NESTED_TRICKY_DATAFLOW_2: 25 // nested loops with tricky data flow 71 }; 72 73 /** 74 * @param {es3fShaderLoopTests.LoopCase} loopCase 75 * @return {string} 76 */ 77 es3fShaderLoopTests.getLoopCaseName = function(loopCase) { 78 /** @type {Array<string>} */ var s_names = [ 79 'empty_body', 80 'infinite_with_unconditional_break_first', 81 'infinite_with_unconditional_break_last', 82 'infinite_with_conditional_break', 83 'single_statement', 84 'compound_statement', 85 'sequence_statement', 86 'no_iterations', 87 'single_iteration', 88 'select_iteration_count', 89 'conditional_continue', 90 'unconditional_continue', 91 'only_continue', 92 'double_continue', 93 'conditional_break', 94 'unconditional_break', 95 'pre_increment', 96 'post_increment', 97 'mixed_break_continue', 98 'vector_counter', 99 '101_iterations', 100 'sequence', 101 'nested', 102 'nested_sequence', 103 'nested_tricky_dataflow_1', 104 'nested_tricky_dataflow_2' 105 ]; 106 // DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == es3fShaderLoopTests.LoopCase.LOOPCASE_LAST); 107 // DE_ASSERT(deInBounds32((int)loopCase, 0, LOOPCASE_LAST)); 108 return s_names[loopCase]; 109 }; 110 111 // Complex loop cases. 112 113 /*enum LoopBody 114 { 115 LOOPBODY_READ_UNIFORM = 0, 116 LOOPBODY_READ_UNIFORM_ARRAY, 117 LOOPBODY_READ_ 118 };*/ 119 120 /** 121 * @enum {number} 122 */ 123 es3fShaderLoopTests.LoopType = { 124 LOOPTYPE_FOR: 0, 125 LOOPTYPE_WHILE: 1, 126 LOOPTYPE_DO_WHILE: 2 127 }; 128 129 /** 130 * @param {es3fShaderLoopTests.LoopType} loopType 131 * @return {string} 132 */ 133 es3fShaderLoopTests.getLoopTypeName = function(loopType) { 134 /** @type {Array<string>} */ var s_names = [ 135 'for', 136 'while', 137 'do_while' 138 ]; 139 140 // DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) === es3fShaderLoopTests.LoopType.LOOPTYPE_LAST); 141 // DE_ASSERT(deInBounds32((int)loopType, 0, LOOPTYPE_LAST)); 142 return s_names[loopType]; 143 }; 144 145 /** 146 * @enum {number} 147 */ 148 es3fShaderLoopTests.LoopCountType = { 149 LOOPCOUNT_CONSTANT: 0, 150 LOOPCOUNT_UNIFORM: 1, 151 LOOPCOUNT_DYNAMIC: 2 152 }; 153 154 /** 155 * @param {es3fShaderLoopTests.LoopCountType} countType 156 * @return {string} 157 */ 158 es3fShaderLoopTests.getLoopCountTypeName = function(countType) { 159 /** @type {Array<string>} */ var s_names = [ 160 'constant', 161 'uniform', 162 'dynamic' 163 ]; 164 165 // DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == es3fShaderLoopTests.LoopCountType.LOOPCOUNT_LAST); 166 // DE_ASSERT(deInBounds32((int)countType, 0, es3fShaderLoopTests.LoopCountType.LOOPCOUNT_LAST)); 167 return s_names[countType]; 168 }; 169 170 /** 171 * @param {glsShaderRenderCase.ShaderEvalContext} c 172 */ 173 es3fShaderLoopTests.evalLoop0Iters = function(c) { 174 var swizzled = deMath.swizzle(c.coords, [0, 1, 2]); 175 c.color[0] = swizzled[0]; 176 c.color[1] = swizzled[1]; 177 c.color[2] = swizzled[2]; 178 }; 179 180 /** 181 * @param {glsShaderRenderCase.ShaderEvalContext} c 182 */ 183 es3fShaderLoopTests.evalLoop1Iters = function(c) { 184 var swizzled = deMath.swizzle(c.coords, [1, 2, 3]); 185 c.color[0] = swizzled[0]; 186 c.color[1] = swizzled[1]; 187 c.color[2] = swizzled[2]; 188 }; 189 190 /** 191 * @param {glsShaderRenderCase.ShaderEvalContext} c 192 */ 193 es3fShaderLoopTests.evalLoop2Iters = function(c) { 194 var swizzled = deMath.swizzle(c.coords, [2, 3, 0]); 195 c.color[0] = swizzled[0]; 196 c.color[1] = swizzled[1]; 197 c.color[2] = swizzled[2]; 198 }; 199 200 /** 201 * @param {glsShaderRenderCase.ShaderEvalContext} c 202 */ 203 es3fShaderLoopTests.evalLoop3Iters = function(c) { 204 var swizzled = deMath.swizzle(c.coords, [3, 0, 1]); 205 c.color[0] = swizzled[0]; 206 c.color[1] = swizzled[1]; 207 c.color[2] = swizzled[2]; 208 }; 209 210 /** 211 * @param {number} numIters 212 * @return {glsShaderRenderCase.ShaderEvalFunc} 213 */ 214 es3fShaderLoopTests.getLoopEvalFunc = function(numIters) { 215 switch (numIters % 4) { 216 case 0: return es3fShaderLoopTests.evalLoop0Iters; 217 case 1: return es3fShaderLoopTests.evalLoop1Iters; 218 case 2: return es3fShaderLoopTests.evalLoop2Iters; 219 case 3: return es3fShaderLoopTests.evalLoop3Iters; 220 } 221 222 throw new Error('Invalid loop iteration count.'); 223 }; 224 225 // ShaderLoopCase 226 227 /** 228 * @constructor 229 * @extends {glsShaderRenderCase.ShaderRenderCase} 230 * @param {string} name 231 * @param {string} description 232 * @param {boolean} isVertexCase 233 * @param {glsShaderRenderCase.ShaderEvalFunc} evalFunc 234 * @param {string} vertShaderSource 235 * @param {string} fragShaderSource 236 */ 237 es3fShaderLoopTests.ShaderLoopCase = function(name, description, isVertexCase, evalFunc, vertShaderSource, fragShaderSource) { 238 glsShaderRenderCase.ShaderRenderCase.call(this, name, description, isVertexCase, evalFunc); 239 /** @type {string} */ this.m_vertShaderSource = vertShaderSource; 240 /** @type {string} */ this.m_fragShaderSource = fragShaderSource; 241 }; 242 243 es3fShaderLoopTests.ShaderLoopCase.prototype = Object.create(glsShaderRenderCase.ShaderRenderCase.prototype); 244 es3fShaderLoopTests.ShaderLoopCase.prototype.constructor = es3fShaderLoopTests.ShaderLoopCase; 245 246 // Test case creation. 247 248 /** 249 * @param {string} caseName 250 * @param {string} description 251 * @param {boolean} isVertexCase 252 * @param {es3fShaderLoopTests.LoopType} loopType 253 * @param {es3fShaderLoopTests.LoopCountType} loopCountType 254 * @param {gluShaderUtil.precision} loopCountPrecision 255 * @param {gluShaderUtil.DataType} loopCountDataType 256 * @return {es3fShaderLoopTests.ShaderLoopCase} 257 */ 258 es3fShaderLoopTests.createGenericLoopCase = function(caseName, description, isVertexCase, loopType, loopCountType, loopCountPrecision, loopCountDataType) { 259 /** @type {string} */ var vtx = ''; 260 /** @type {string} */ var frag = ''; 261 /** @type {string} */ var op = ''; 262 263 vtx += '#version 300 es\n'; 264 frag += '#version 300 es\n'; 265 266 vtx += 'in highp vec4 a_position;\n'; 267 vtx += 'in highp vec4 a_coords;\n'; 268 frag += 'layout(location = 0) out mediump vec4 o_color;\n'; 269 270 if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) 271 vtx += 'in mediump float a_one;\n'; 272 273 if (isVertexCase) { 274 vtx += 'out mediump vec3 v_color;\n'; 275 frag += 'in mediump vec3 v_color;\n'; 276 } 277 else { 278 vtx += 'out mediump vec4 v_coords;\n'; 279 frag += 'in mediump vec4 v_coords;\n'; 280 281 if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) { 282 vtx += 'out mediump float v_one;\n'; 283 frag += 'in mediump float v_one;\n'; 284 } 285 } 286 287 // \todo [petri] Pass numLoopIters from outside? 288 /** @type {number} */ var numLoopIters = 3; 289 /** @type {boolean} */ var isIntCounter = gluShaderUtil.isDataTypeIntOrIVec(loopCountDataType); 290 291 if (isIntCounter) { 292 if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM || loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) 293 op += 'uniform ${COUNTER_PRECISION} int ' + glsShaderRenderCase.getIntUniformName(numLoopIters) + ';\n'; 294 } 295 else { 296 if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM || loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) 297 op += 'uniform ${COUNTER_PRECISION} float ' + glsShaderRenderCase.getFloatFractionUniformName(numLoopIters) + ';\n'; 298 299 if (numLoopIters != 1) 300 op += 'uniform ${COUNTER_PRECISION} float uf_one;\n'; 301 } 302 303 vtx += isVertexCase ? op : ''; 304 frag += isVertexCase ? '' : op; 305 op = ''; 306 307 vtx += "\n" + 308 "void main()\n" + 309 "{\n" + 310 " gl_Position = a_position;\n"; 311 312 frag += "\n" + 313 "void main()\n" + 314 "{\n"; 315 316 if (isVertexCase) 317 vtx += ' ${PRECISION} vec4 coords = a_coords;\n'; 318 else 319 frag += ' ${PRECISION} vec4 coords = v_coords;\n'; 320 321 if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) { 322 if (isIntCounter) { 323 if (isVertexCase) 324 vtx += ' ${COUNTER_PRECISION} int one = int(a_one + 0.5);\n'; 325 else 326 frag += ' ${COUNTER_PRECISION} int one = int(v_one + 0.5);\n'; 327 } 328 else { 329 if (isVertexCase) 330 vtx += ' ${COUNTER_PRECISION} float one = a_one;\n'; 331 else 332 frag += ' ${COUNTER_PRECISION} float one = v_one;\n'; 333 } 334 } 335 336 // Read array. 337 op += ' ${PRECISION} vec4 res = coords;\n'; 338 339 // Loop iteration count. 340 /** @type {string} */ var iterMaxStr; 341 342 if (isIntCounter) { 343 if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_CONSTANT) 344 iterMaxStr = numLoopIters.toString(); 345 else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM) 346 iterMaxStr = glsShaderRenderCase.getIntUniformName(numLoopIters); 347 else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) 348 iterMaxStr = glsShaderRenderCase.getIntUniformName(numLoopIters) + '*one'; 349 else 350 throw new Error('Loop Count Type not supported: ' + loopCountType); 351 } 352 else { 353 if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_CONSTANT) 354 iterMaxStr = '1.0'; 355 else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM) 356 iterMaxStr = 'uf_one'; 357 else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) 358 iterMaxStr = 'uf_one*one'; 359 else 360 throw new Error('Loop Count Type not supported: ' + loopCountType); 361 } 362 363 // Loop operations. 364 /** @type {string} */ var initValue = isIntCounter ? '0' : '0.05'; 365 /** @type {string} */ var loopCountDeclStr = '' + gluShaderUtil.getPrecisionName(loopCountPrecision) + ' ' + gluShaderUtil.getDataTypeName(loopCountDataType) + ' ndx = ' + initValue; 366 /** @type {string} */ var loopCmpStr = 'ndx < ' + iterMaxStr; 367 /** @type {string} */ var incrementStr; 368 369 if (isIntCounter) 370 incrementStr = 'ndx++'; 371 else { 372 if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_CONSTANT) 373 incrementStr = 'ndx += ' + (1.0 / numLoopIters); 374 else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM) 375 incrementStr = 'ndx += ' + glsShaderRenderCase.getFloatFractionUniformName(numLoopIters); 376 else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) 377 incrementStr = 'ndx += ' + glsShaderRenderCase.getFloatFractionUniformName(numLoopIters) + '*one'; 378 else 379 throw new Error('Loop Count Type not supported: ' + loopCountType); 380 } 381 382 // Loop body. 383 /** @type {string} */ var loopBody = ' res = res.yzwx;\n';; 384 385 if (loopType === es3fShaderLoopTests.LoopType.LOOPTYPE_FOR) { 386 op += ' for (' + loopCountDeclStr + '; ' + loopCmpStr + '; ' + incrementStr + ')\n' + 387 ' {\n' + 388 loopBody + 389 ' }\n'; 390 } 391 else if (loopType === es3fShaderLoopTests.LoopType.LOOPTYPE_WHILE) { 392 op += '\t' + loopCountDeclStr + ';\n' + 393 ' while (' + loopCmpStr + ')\n' + 394 ' {\n' + 395 loopBody + 396 '\t\t' + incrementStr + ';\n' + 397 ' }\n'; 398 } 399 else if (loopType === es3fShaderLoopTests.LoopType.LOOPTYPE_DO_WHILE) 400 { 401 op += '\t' + loopCountDeclStr + ';\n' + 402 ' do\n' + 403 ' {\n' + 404 loopBody + 405 '\t\t' + incrementStr + ';\n' + 406 ' } while (' + loopCmpStr + ');\n'; 407 } 408 else 409 throw new Error('Loop Type not supported: ' + loopType); 410 411 vtx += isVertexCase ? op : ''; 412 frag += isVertexCase ? '' : op; 413 op = ''; 414 415 if (isVertexCase) { 416 vtx += ' v_color = res.rgb;\n'; 417 frag += ' o_color = vec4(v_color.rgb, 1.0);\n'; 418 } 419 else { 420 vtx += ' v_coords = a_coords;\n'; 421 frag += ' o_color = vec4(res.rgb, 1.0);\n'; 422 423 if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) 424 vtx += ' v_one = a_one;\n'; 425 } 426 427 vtx += '}\n'; 428 frag += '}\n'; 429 430 // Fill in shader templates. 431 /** @type {Object} */ var params = {}; 432 params['LOOP_VAR_TYPE'] = gluShaderUtil.getDataTypeName(loopCountDataType); 433 params['PRECISION'] = 'mediump'; 434 params['COUNTER_PRECISION'] = gluShaderUtil.getPrecisionName(loopCountPrecision); 435 436 /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params); 437 /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params); 438 439 // Create the case. 440 /** @type {glsShaderRenderCase.ShaderEvalFunc} */ 441 var evalFunc = es3fShaderLoopTests.getLoopEvalFunc(numLoopIters); 442 return new es3fShaderLoopTests.ShaderLoopCase(caseName, description, isVertexCase, evalFunc, vertexShaderSource, fragmentShaderSource); 443 }; 444 445 // \todo [petri] Generalize to float as well? 446 447 /** 448 * @param {string} caseName 449 * @param {string} description 450 * @param {boolean} isVertexCase 451 * @param {es3fShaderLoopTests.LoopCase} loopCase 452 * @param {es3fShaderLoopTests.LoopType} loopType 453 * @param {es3fShaderLoopTests.LoopCountType} loopCountType 454 * @return {es3fShaderLoopTests.ShaderLoopCase} 455 */ 456 es3fShaderLoopTests.createSpecialLoopCase = function(caseName, description, isVertexCase, loopCase, loopType, loopCountType) { 457 /** @type {string} */ var vtx = ''; 458 /** @type {string} */ var frag = ''; 459 /** @type {string} */ var op = ''; 460 461 vtx += '#version 300 es\n'; 462 frag += '#version 300 es\n'; 463 464 vtx += 'in highp vec4 a_position;\n'; 465 vtx += 'in highp vec4 a_coords;\n'; 466 frag += 'layout(location = 0) out mediump vec4 o_color;\n'; 467 468 if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) 469 vtx += 'in mediump float a_one;\n'; 470 471 // Attribute and varyings. 472 if (isVertexCase) { 473 vtx += 'out mediump vec3 v_color;\n'; 474 frag += 'in mediump vec3 v_color;\n'; 475 } 476 else { 477 vtx += 'out mediump vec4 v_coords;\n'; 478 frag += 'in mediump vec4 v_coords;\n'; 479 480 if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) { 481 vtx += 'out mediump float v_one;\n'; 482 frag += 'in mediump float v_one;\n'; 483 } 484 } 485 486 if (loopCase === es3fShaderLoopTests.LoopCase.LOOPCASE_SELECT_ITERATION_COUNT) 487 op += 'uniform bool ub_true;\n'; 488 489 op += 'uniform ${COUNTER_PRECISION} int ui_zero, ui_one, ui_two, ui_three, ui_four, ui_five, ui_six;\n'; 490 if (loopCase === es3fShaderLoopTests.LoopCase.LOOPCASE_101_ITERATIONS) 491 op += 'uniform ${COUNTER_PRECISION} int ui_oneHundredOne;\n'; 492 493 vtx += isVertexCase ? op : ''; 494 frag += isVertexCase ? '' : op; 495 op = ''; 496 497 /** @type {number} */ var iterCount = 3; // value to use in loop 498 /** @type {number} */ var numIters = 3; // actual number of iterations 499 500 vtx += '\n' + 501 'void main()\n' + 502 '{\n' + 503 ' gl_Position = a_position;\n'; 504 505 frag += '\n' + 506 'void main()\n' + 507 '{\n'; 508 509 if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) { 510 if (isVertexCase) 511 vtx += ' ${COUNTER_PRECISION} int one = int(a_one + 0.5);\n'; 512 else 513 frag += ' ${COUNTER_PRECISION} int one = int(v_one + 0.5);\n'; 514 } 515 516 if (isVertexCase) 517 vtx += ' ${PRECISION} vec4 coords = a_coords;\n'; 518 else 519 frag += ' ${PRECISION} vec4 coords = v_coords;\n'; 520 521 // Read array. 522 op += ' ${PRECISION} vec4 res = coords;\n'; 523 524 // Handle all loop types. 525 /** @type {string} */ var counterPrecisionStr = 'mediump'; 526 /** @type {string} */ var forLoopStr = ''; 527 /** @type {string} */ var whileLoopStr = ''; 528 /** @type {string} */ var doWhileLoopPreStr = ''; 529 /** @type {string} */ var doWhileLoopPostStr = ''; 530 531 if (loopType === es3fShaderLoopTests.LoopType.LOOPTYPE_FOR) { 532 switch (loopCase) { 533 case es3fShaderLoopTests.LoopCase.LOOPCASE_EMPTY_BODY: 534 numIters = 0; 535 op += ' ${FOR_LOOP} {}\n'; 536 break; 537 538 case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST: 539 numIters = 0; 540 op += ' for (;;) { break; res = res.yzwx; }\n'; 541 break; 542 543 case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST: 544 numIters = 1; 545 op += ' for (;;) { res = res.yzwx; break; }\n'; 546 break; 547 548 case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK: 549 numIters = 2; 550 op += ' ${COUNTER_PRECISION} int i = 0;\n' + 551 ' for (;;) { res = res.yzwx; if (i == ${ONE}) break; i++; }\n'; 552 break; 553 554 case es3fShaderLoopTests.LoopCase.LOOPCASE_SINGLE_STATEMENT: 555 op += ' ${FOR_LOOP} res = res.yzwx;\n'; 556 break; 557 558 case es3fShaderLoopTests.LoopCase.LOOPCASE_COMPOUND_STATEMENT: 559 iterCount = 2; 560 numIters = 2 * iterCount; 561 op += ' ${FOR_LOOP} { res = res.yzwx; res = res.yzwx; }\n'; 562 break; 563 564 case es3fShaderLoopTests.LoopCase.LOOPCASE_SEQUENCE_STATEMENT: 565 iterCount = 2; 566 numIters = 2 * iterCount; 567 op += ' ${FOR_LOOP} res = res.yzwx, res = res.yzwx;\n'; 568 break; 569 570 case es3fShaderLoopTests.LoopCase.LOOPCASE_NO_ITERATIONS: 571 iterCount = 0; 572 numIters = 0; 573 op += ' ${FOR_LOOP} res = res.yzwx;\n'; 574 break; 575 576 case es3fShaderLoopTests.LoopCase.LOOPCASE_SINGLE_ITERATION: 577 iterCount = 1; 578 numIters = 1; 579 op += ' ${FOR_LOOP} res = res.yzwx;\n'; 580 break; 581 582 case es3fShaderLoopTests.LoopCase.LOOPCASE_SELECT_ITERATION_COUNT: 583 op += ' for (int i = 0; i < (ub_true ? ${ITER_COUNT} : 0); i++) res = res.yzwx;\n'; 584 break; 585 586 case es3fShaderLoopTests.LoopCase.LOOPCASE_CONDITIONAL_CONTINUE: 587 numIters = iterCount - 1; 588 op += ' ${FOR_LOOP} { if (i == ${TWO}) continue; res = res.yzwx; }\n'; 589 break; 590 591 case es3fShaderLoopTests.LoopCase.LOOPCASE_UNCONDITIONAL_CONTINUE: 592 op += ' ${FOR_LOOP} { res = res.yzwx; continue; }\n'; 593 break; 594 595 case es3fShaderLoopTests.LoopCase.LOOPCASE_ONLY_CONTINUE: 596 numIters = 0; 597 op += ' ${FOR_LOOP} { continue; }\n'; 598 break; 599 600 case es3fShaderLoopTests.LoopCase.LOOPCASE_DOUBLE_CONTINUE: 601 numIters = iterCount - 1; 602 op += ' ${FOR_LOOP} { if (i == ${TWO}) continue; res = res.yzwx; continue; }\n'; 603 break; 604 605 case es3fShaderLoopTests.LoopCase.LOOPCASE_CONDITIONAL_BREAK: 606 numIters = 2; 607 op += ' ${FOR_LOOP} { if (i == ${TWO}) break; res = res.yzwx; }\n'; 608 break; 609 610 case es3fShaderLoopTests.LoopCase.LOOPCASE_UNCONDITIONAL_BREAK: 611 numIters = 1; 612 op += ' ${FOR_LOOP} { res = res.yzwx; break; }\n'; 613 break; 614 615 case es3fShaderLoopTests.LoopCase.LOOPCASE_PRE_INCREMENT: 616 op += ' for (int i = 0; i < ${ITER_COUNT}; ++i) { res = res.yzwx; }\n'; 617 break; 618 619 case es3fShaderLoopTests.LoopCase.LOOPCASE_POST_INCREMENT: 620 op += ' ${FOR_LOOP} { res = res.yzwx; }\n'; 621 break; 622 623 case es3fShaderLoopTests.LoopCase.LOOPCASE_MIXED_BREAK_CONTINUE: 624 numIters = 2; 625 iterCount = 5; 626 op += ' ${FOR_LOOP} { if (i == 0) continue; else if (i == 3) break; res = res.yzwx; }\n'; 627 break; 628 629 case es3fShaderLoopTests.LoopCase.LOOPCASE_VECTOR_COUNTER: 630 op += ' for (${COUNTER_PRECISION} ivec4 i = ivec4(0, 1, ${ITER_COUNT}, 0); i.x < i.z; i.x += i.y) { res = res.yzwx; }\n'; 631 break; 632 633 case es3fShaderLoopTests.LoopCase.LOOPCASE_101_ITERATIONS: 634 numIters = iterCount = 101; 635 op += ' ${FOR_LOOP} res = res.yzwx;\n'; 636 break; 637 638 case es3fShaderLoopTests.LoopCase.LOOPCASE_SEQUENCE: 639 iterCount = 5; 640 numIters = 5; 641 op += ' ${COUNTER_PRECISION} int i;\n' + 642 ' for (i = 0; i < ${TWO}; i++) { res = res.yzwx; }\n' + 643 ' for (; i < ${ITER_COUNT}; i++) { res = res.yzwx; }\n'; 644 break; 645 646 case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED: 647 numIters = 2 * iterCount; 648 op += ' for (${COUNTER_PRECISION} int i = 0; i < ${TWO}; i++)\n' + 649 ' {\n' + 650 ' for (${COUNTER_PRECISION} int j = 0; j < ${ITER_COUNT}; j++)\n' + 651 ' res = res.yzwx;\n' + 652 ' }\n'; 653 break; 654 655 case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_SEQUENCE: 656 numIters = 3 * iterCount; 657 op += ' for (${COUNTER_PRECISION} int i = 0; i < ${ITER_COUNT}; i++)\n' + 658 ' {\n' + 659 ' for (${COUNTER_PRECISION} int j = 0; j < ${TWO}; j++)\n' + 660 ' res = res.yzwx;\n' + 661 ' for (${COUNTER_PRECISION} int j = 0; j < ${ONE}; j++)\n' + 662 ' res = res.yzwx;\n' + 663 ' }\n'; 664 break; 665 666 case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_TRICKY_DATAFLOW_1: 667 numIters = 2; 668 op += ' ${FOR_LOOP}\n' + 669 ' {\n' + 670 ' res = coords; // ignore outer loop effect \n' + 671 ' for (${COUNTER_PRECISION} int j = 0; j < ${TWO}; j++)\n' + 672 ' res = res.yzwx;\n' + 673 ' }\n'; 674 break; 675 676 case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_TRICKY_DATAFLOW_2: 677 numIters = iterCount; 678 op += ' ${FOR_LOOP}\n' + 679 ' {\n' + 680 ' res = coords.wxyz;\n' + 681 ' for (${COUNTER_PRECISION} int j = 0; j < ${TWO}; j++)\n' + 682 ' res = res.yzwx;\n' + 683 ' coords = res;\n' + 684 ' }\n'; 685 break; 686 687 default: 688 throw new Error('Case not supported: ' + loopCase); 689 } 690 691 if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_CONSTANT) 692 forLoopStr = 'for (' + counterPrecisionStr + ' int i = 0; i < ' + iterCount + '; i++)'; 693 else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM) 694 forLoopStr = 'for (' + counterPrecisionStr + ' int i = 0; i < ' + glsShaderRenderCase.getIntUniformName(iterCount) + '; i++)'; 695 else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) 696 forLoopStr = 'for (' + counterPrecisionStr + ' int i = 0; i < one*' + glsShaderRenderCase.getIntUniformName(iterCount) + '; i++)'; 697 else 698 throw new Error('Loop Count Type not supported: ' + loopCountType); 699 } 700 else if (loopType === es3fShaderLoopTests.LoopType.LOOPTYPE_WHILE) { 701 switch (loopCase) { 702 case es3fShaderLoopTests.LoopCase.LOOPCASE_EMPTY_BODY: 703 numIters = 0; 704 op += ' ${WHILE_LOOP} {}\n'; 705 break; 706 707 case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST: 708 numIters = 0; 709 op += ' while (true) { break; res = res.yzwx; }\n'; 710 break; 711 712 case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST: 713 numIters = 1; 714 op += ' while (true) { res = res.yzwx; break; }\n'; 715 break; 716 717 case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK: 718 numIters = 2; 719 op += ' ${COUNTER_PRECISION} int i = 0;\n' + 720 ' while (true) { res = res.yzwx; if (i == ${ONE}) break; i++; }\n'; 721 break; 722 723 case es3fShaderLoopTests.LoopCase.LOOPCASE_SINGLE_STATEMENT: 724 op += ' ${WHILE_LOOP} res = res.yzwx;\n'; 725 break; 726 727 case es3fShaderLoopTests.LoopCase.LOOPCASE_COMPOUND_STATEMENT: 728 iterCount = 2; 729 numIters = 2 * iterCount; 730 op += ' ${WHILE_LOOP} { res = res.yzwx; res = res.yzwx; }\n'; 731 break; 732 733 case es3fShaderLoopTests.LoopCase.LOOPCASE_SEQUENCE_STATEMENT: 734 iterCount = 2; 735 numIters = 2 * iterCount; 736 op += ' ${WHILE_LOOP} res = res.yzwx, res = res.yzwx;\n'; 737 break; 738 739 case es3fShaderLoopTests.LoopCase.LOOPCASE_NO_ITERATIONS: 740 iterCount = 0; 741 numIters = 0; 742 op += ' ${WHILE_LOOP} res = res.yzwx;\n'; 743 break; 744 745 case es3fShaderLoopTests.LoopCase.LOOPCASE_SINGLE_ITERATION: 746 iterCount = 1; 747 numIters = 1; 748 op += ' ${WHILE_LOOP} res = res.yzwx;\n'; 749 break; 750 751 case es3fShaderLoopTests.LoopCase.LOOPCASE_SELECT_ITERATION_COUNT: 752 op += ' ${COUNTER_PRECISION} int i = 0;\n' + 753 ' while (i < (ub_true ? ${ITER_COUNT} : 0)) { res = res.yzwx; i++; }\n'; 754 break; 755 756 case es3fShaderLoopTests.LoopCase.LOOPCASE_CONDITIONAL_CONTINUE: 757 numIters = iterCount - 1; 758 op += ' ${WHILE_LOOP} { if (i == ${TWO}) continue; res = res.yzwx; }\n'; 759 break; 760 761 case es3fShaderLoopTests.LoopCase.LOOPCASE_UNCONDITIONAL_CONTINUE: 762 op += ' ${WHILE_LOOP} { res = res.yzwx; continue; }\n'; 763 break; 764 765 case es3fShaderLoopTests.LoopCase.LOOPCASE_ONLY_CONTINUE: 766 numIters = 0; 767 op += ' ${WHILE_LOOP} { continue; }\n'; 768 break; 769 770 case es3fShaderLoopTests.LoopCase.LOOPCASE_DOUBLE_CONTINUE: 771 numIters = iterCount - 1; 772 op += ' ${WHILE_LOOP} { if (i == ${ONE}) continue; res = res.yzwx; continue; }\n'; 773 break; 774 775 case es3fShaderLoopTests.LoopCase.LOOPCASE_CONDITIONAL_BREAK: 776 numIters = 2; 777 op += ' ${WHILE_LOOP} { if (i == ${THREE}) break; res = res.yzwx; }\n'; 778 break; 779 780 case es3fShaderLoopTests.LoopCase.LOOPCASE_UNCONDITIONAL_BREAK: 781 numIters = 1; 782 op += ' ${WHILE_LOOP} { res = res.yzwx; break; }\n'; 783 break; 784 785 case es3fShaderLoopTests.LoopCase.LOOPCASE_PRE_INCREMENT: 786 numIters = iterCount - 1; 787 op += ' ${COUNTER_PRECISION} int i = 0;\n' + 788 ' while (++i < ${ITER_COUNT}) { res = res.yzwx; }\n'; 789 break; 790 791 case es3fShaderLoopTests.LoopCase.LOOPCASE_POST_INCREMENT: 792 op += ' ${COUNTER_PRECISION} int i = 0;\n' + 793 ' while (i++ < ${ITER_COUNT}) { res = res.yzwx; }\n'; 794 break; 795 796 case es3fShaderLoopTests.LoopCase.LOOPCASE_MIXED_BREAK_CONTINUE: 797 numIters = 2; 798 iterCount = 5; 799 op += ' ${WHILE_LOOP} { if (i == 0) continue; else if (i == 3) break; res = res.yzwx; }\n'; 800 break; 801 802 case es3fShaderLoopTests.LoopCase.LOOPCASE_VECTOR_COUNTER: 803 op += ' ${COUNTER_PRECISION} ivec4 i = ivec4(0, 1, ${ITER_COUNT}, 0);\n' + 804 ' while (i.x < i.z) { res = res.yzwx; i.x += i.y; }\n'; 805 break; 806 807 case es3fShaderLoopTests.LoopCase.LOOPCASE_101_ITERATIONS: 808 numIters = iterCount = 101; 809 op += ' ${WHILE_LOOP} res = res.yzwx;\n'; 810 break; 811 812 case es3fShaderLoopTests.LoopCase.LOOPCASE_SEQUENCE: 813 iterCount = 6; 814 numIters = iterCount - 1; 815 op += ' ${COUNTER_PRECISION} int i = 0;\n' + 816 ' while (i++ < ${TWO}) { res = res.yzwx; }\n' + 817 ' while (i++ < ${ITER_COUNT}) { res = res.yzwx; }\n'; // \note skips one iteration 818 break; 819 820 case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED: 821 numIters = 2 * iterCount; 822 op += ' ${COUNTER_PRECISION} int i = 0;\n' + 823 ' while (i++ < ${TWO})\n' + 824 ' {\n' + 825 ' ${COUNTER_PRECISION} int j = 0;\n' + 826 ' while (j++ < ${ITER_COUNT})\n' + 827 ' res = res.yzwx;\n' + 828 ' }\n'; 829 break; 830 831 case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_SEQUENCE: 832 numIters = 2 * iterCount; 833 op += ' ${COUNTER_PRECISION} int i = 0;\n' + 834 ' while (i++ < ${ITER_COUNT})\n' + 835 ' {\n' + 836 ' ${COUNTER_PRECISION} int j = 0;\n' + 837 ' while (j++ < ${ONE})\n' + 838 ' res = res.yzwx;\n' + 839 ' while (j++ < ${THREE})\n' + // \note skips one iteration 840 ' res = res.yzwx;\n' + 841 ' }\n'; 842 break; 843 844 case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_TRICKY_DATAFLOW_1: 845 numIters = 2; 846 op += ' ${WHILE_LOOP}\n' + 847 ' {\n' + 848 ' res = coords; // ignore outer loop effect \n' + 849 ' ${COUNTER_PRECISION} int j = 0;\n' + 850 ' while (j++ < ${TWO})\n' + 851 ' res = res.yzwx;\n' + 852 ' }\n'; 853 break; 854 855 case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_TRICKY_DATAFLOW_2: 856 numIters = iterCount; 857 op += ' ${WHILE_LOOP}\n' + 858 ' {\n' + 859 ' res = coords.wxyz;\n' + 860 ' ${COUNTER_PRECISION} int j = 0;\n' + 861 ' while (j++ < ${TWO})\n' + 862 ' res = res.yzwx;\n' + 863 ' coords = res;\n' + 864 ' }\n'; 865 break; 866 867 default: 868 throw new Error('Loop Case not supported: ' + loopCase); 869 } 870 871 if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_CONSTANT) 872 whileLoopStr = '\t' + counterPrecisionStr + ' int i = 0;\n' + ' while(i++ < ' + iterCount + ')'; 873 else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM) 874 whileLoopStr = '\t' + counterPrecisionStr + ' int i = 0;\n' + ' while(i++ < ' + glsShaderRenderCase.getIntUniformName(iterCount) + ')'; 875 else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) 876 whileLoopStr = '\t' + counterPrecisionStr + ' int i = 0;\n' + ' while(i++ < one*' + glsShaderRenderCase.getIntUniformName(iterCount) + ')'; 877 else 878 throw new Error('Loop Count Type not supported: ' + loopCountType); 879 } 880 else { 881 assertMsgOptions(loopType === es3fShaderLoopTests.LoopType.LOOPTYPE_DO_WHILE, 'Expected LOOPTYPE_DO_WHILE', false, true); 882 883 switch (loopCase) { 884 case es3fShaderLoopTests.LoopCase.LOOPCASE_EMPTY_BODY: 885 numIters = 0; 886 op += ' ${DO_WHILE_PRE} {} ${DO_WHILE_POST}\n'; 887 break; 888 889 case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST: 890 numIters = 0; 891 op += ' do { break; res = res.yzwx; } while (true);\n'; 892 break; 893 894 case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST: 895 numIters = 1; 896 op += ' do { res = res.yzwx; break; } while (true);\n'; 897 break; 898 899 case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK: 900 numIters = 2; 901 op += ' ${COUNTER_PRECISION} int i = 0;\n' + 902 ' do { res = res.yzwx; if (i == ${ONE}) break; i++; } while (true);\n'; 903 break; 904 905 case es3fShaderLoopTests.LoopCase.LOOPCASE_SINGLE_STATEMENT: 906 op += ' ${DO_WHILE_PRE} res = res.yzwx; ${DO_WHILE_POST}\n'; 907 break; 908 909 case es3fShaderLoopTests.LoopCase.LOOPCASE_COMPOUND_STATEMENT: 910 iterCount = 2; 911 numIters = 2 * iterCount; 912 op += ' ${DO_WHILE_PRE} { res = res.yzwx; res = res.yzwx; } ${DO_WHILE_POST}\n'; 913 break; 914 915 case es3fShaderLoopTests.LoopCase.LOOPCASE_SEQUENCE_STATEMENT: 916 iterCount = 2; 917 numIters = 2 * iterCount; 918 op += ' ${DO_WHILE_PRE} res = res.yzwx, res = res.yzwx; ${DO_WHILE_POST}\n'; 919 break; 920 921 case es3fShaderLoopTests.LoopCase.LOOPCASE_NO_ITERATIONS: 922 //assertMsgOptions(false, 'LOOPCASE_NO_ITERATIONS', false, false); 923 break; 924 925 case es3fShaderLoopTests.LoopCase.LOOPCASE_SINGLE_ITERATION: 926 iterCount = 1; 927 numIters = 1; 928 op += ' ${DO_WHILE_PRE} res = res.yzwx; ${DO_WHILE_POST}\n'; 929 break; 930 931 case es3fShaderLoopTests.LoopCase.LOOPCASE_SELECT_ITERATION_COUNT: 932 op += ' ${COUNTER_PRECISION} int i = 0;\n' + 933 ' do { res = res.yzwx; } while (++i < (ub_true ? ${ITER_COUNT} : 0));\n'; 934 break; 935 936 case es3fShaderLoopTests.LoopCase.LOOPCASE_CONDITIONAL_CONTINUE: 937 numIters = iterCount - 1; 938 op += ' ${DO_WHILE_PRE} { if (i == ${TWO}) continue; res = res.yzwx; } ${DO_WHILE_POST}\n'; 939 break; 940 941 case es3fShaderLoopTests.LoopCase.LOOPCASE_UNCONDITIONAL_CONTINUE: 942 op += ' ${DO_WHILE_PRE} { res = res.yzwx; continue; } ${DO_WHILE_POST}\n'; 943 break; 944 945 case es3fShaderLoopTests.LoopCase.LOOPCASE_ONLY_CONTINUE: 946 numIters = 0; 947 op += ' ${DO_WHILE_PRE} { continue; } ${DO_WHILE_POST}\n'; 948 break; 949 950 case es3fShaderLoopTests.LoopCase.LOOPCASE_DOUBLE_CONTINUE: 951 numIters = iterCount - 1; 952 op += ' ${DO_WHILE_PRE} { if (i == ${TWO}) continue; res = res.yzwx; continue; } ${DO_WHILE_POST}\n'; 953 break; 954 955 case es3fShaderLoopTests.LoopCase.LOOPCASE_CONDITIONAL_BREAK: 956 numIters = 2; 957 op += ' ${DO_WHILE_PRE} { res = res.yzwx; if (i == ${ONE}) break; } ${DO_WHILE_POST}\n'; 958 break; 959 960 case es3fShaderLoopTests.LoopCase.LOOPCASE_UNCONDITIONAL_BREAK: 961 numIters = 1; 962 op += ' ${DO_WHILE_PRE} { res = res.yzwx; break; } ${DO_WHILE_POST}\n'; 963 break; 964 965 case es3fShaderLoopTests.LoopCase.LOOPCASE_PRE_INCREMENT: 966 op += ' ${COUNTER_PRECISION} int i = 0;\n' + 967 ' do { res = res.yzwx; } while (++i < ${ITER_COUNT});\n'; 968 break; 969 970 case es3fShaderLoopTests.LoopCase.LOOPCASE_POST_INCREMENT: 971 numIters = iterCount + 1; 972 op += ' ${COUNTER_PRECISION} int i = 0;\n' + 973 ' do { res = res.yzwx; } while (i++ < ${ITER_COUNT});\n'; 974 break; 975 976 case es3fShaderLoopTests.LoopCase.LOOPCASE_MIXED_BREAK_CONTINUE: 977 numIters = 2; 978 iterCount = 5; 979 op += ' ${DO_WHILE_PRE} { if (i == 0) continue; else if (i == 3) break; res = res.yzwx; } ${DO_WHILE_POST}\n'; 980 break; 981 982 case es3fShaderLoopTests.LoopCase.LOOPCASE_VECTOR_COUNTER: 983 op += ' ${COUNTER_PRECISION} ivec4 i = ivec4(0, 1, ${ITER_COUNT}, 0);\n' + 984 ' do { res = res.yzwx; } while ((i.x += i.y) < i.z);\n'; 985 break; 986 987 case es3fShaderLoopTests.LoopCase.LOOPCASE_101_ITERATIONS: 988 numIters = iterCount = 101; 989 op += ' ${DO_WHILE_PRE} res = res.yzwx; ${DO_WHILE_POST}\n'; 990 break; 991 992 case es3fShaderLoopTests.LoopCase.LOOPCASE_SEQUENCE: 993 iterCount = 5; 994 numIters = 5; 995 op += ' ${COUNTER_PRECISION} int i = 0;\n' + 996 ' do { res = res.yzwx; } while (++i < ${TWO});\n' + 997 ' do { res = res.yzwx; } while (++i < ${ITER_COUNT});\n'; 998 break; 999 1000 case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED: 1001 numIters = 2 * iterCount; 1002 op += ' ${COUNTER_PRECISION} int i = 0;\n' + 1003 ' do\n' + 1004 ' {\n' + 1005 ' ${COUNTER_PRECISION} int j = 0;\n' + 1006 ' do\n' + 1007 ' res = res.yzwx;\n' + 1008 ' while (++j < ${ITER_COUNT});\n' + 1009 ' } while (++i < ${TWO});\n'; 1010 break; 1011 1012 case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_SEQUENCE: 1013 numIters = 3 * iterCount; 1014 op += ' ${COUNTER_PRECISION} int i = 0;\n' + 1015 ' do\n' + 1016 ' {\n' + 1017 ' ${COUNTER_PRECISION} int j = 0;\n' + 1018 ' do\n' + 1019 ' res = res.yzwx;\n' + 1020 ' while (++j < ${TWO});\n' + 1021 ' do\n' + 1022 ' res = res.yzwx;\n' + 1023 ' while (++j < ${THREE});\n' + 1024 ' } while (++i < ${ITER_COUNT});\n'; 1025 break; 1026 1027 case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_TRICKY_DATAFLOW_1: 1028 numIters = 2; 1029 op += ' ${DO_WHILE_PRE}\n' + 1030 ' {\n' + 1031 ' res = coords; // ignore outer loop effect \n' + 1032 ' ${COUNTER_PRECISION} int j = 0;\n' + 1033 ' do\n' + 1034 ' res = res.yzwx;\n' + 1035 ' while (++j < ${TWO});\n' + 1036 ' } ${DO_WHILE_POST}\n'; 1037 break; 1038 1039 case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_TRICKY_DATAFLOW_2: 1040 numIters = iterCount; 1041 op += ' ${DO_WHILE_PRE}\n' + 1042 ' {\n' + 1043 ' res = coords.wxyz;\n' + 1044 ' ${COUNTER_PRECISION} int j = 0;\n' + 1045 ' while (j++ < ${TWO})\n' + 1046 ' res = res.yzwx;\n' + 1047 ' coords = res;\n' + 1048 ' } ${DO_WHILE_POST}\n'; 1049 break; 1050 1051 default: 1052 throw new Error('Loop Case not supported: ' + loopCase); 1053 } 1054 1055 doWhileLoopPreStr = '\t' + counterPrecisionStr + ' int i = 0;\n' + '\tdo '; 1056 if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_CONSTANT) 1057 doWhileLoopPostStr = ' while (++i < ' + iterCount + ');\n'; 1058 else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM) 1059 doWhileLoopPostStr = ' while (++i < ' + glsShaderRenderCase.getIntUniformName(iterCount) + ');\n'; 1060 else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) 1061 doWhileLoopPostStr = ' while (++i < one*' + glsShaderRenderCase.getIntUniformName(iterCount) + ');\n'; 1062 else 1063 throw new Error('Loop Count Type not supported: ' + loopCountType); 1064 } 1065 1066 vtx += isVertexCase ? op : ''; 1067 frag += isVertexCase ? '' : op; 1068 op = ''; 1069 1070 // Shader footers. 1071 if (isVertexCase) { 1072 vtx += ' v_color = res.rgb;\n'; 1073 frag += ' o_color = vec4(v_color.rgb, 1.0);\n'; 1074 } 1075 else { 1076 vtx += ' v_coords = a_coords;\n'; 1077 frag += ' o_color = vec4(res.rgb, 1.0);\n'; 1078 1079 if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) 1080 vtx += ' v_one = a_one;\n'; 1081 } 1082 1083 vtx += '}\n'; 1084 frag += '}\n'; 1085 1086 // Constants. 1087 /** @type {string} */ var oneStr = ''; 1088 /** @type {string} */ var twoStr = ''; 1089 /** @type {string} */ var threeStr = ''; 1090 /** @type {string} */ var iterCountStr = ''; 1091 1092 if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_CONSTANT) { 1093 oneStr = '1'; 1094 twoStr = '2'; 1095 threeStr = '3'; 1096 iterCountStr = iterCount.toString(); 1097 } 1098 else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM) { 1099 oneStr = 'ui_one'; 1100 twoStr = 'ui_two'; 1101 threeStr = 'ui_three'; 1102 iterCountStr = glsShaderRenderCase.getIntUniformName(iterCount); 1103 } 1104 else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) { 1105 oneStr = 'one*ui_one'; 1106 twoStr = 'one*ui_two'; 1107 threeStr = 'one*ui_three'; 1108 iterCountStr = 'one*' + glsShaderRenderCase.getIntUniformName(iterCount); 1109 } 1110 else throw new Error('Loop Count Type not supported: ' + loopCountType); 1111 1112 // Fill in shader templates. 1113 /** @type {Object} */ var params = {}; 1114 params["PRECISION"] = "mediump"; 1115 params["ITER_COUNT"] = iterCountStr; 1116 params["COUNTER_PRECISION"] = counterPrecisionStr; 1117 params["FOR_LOOP"] = forLoopStr; 1118 params["WHILE_LOOP"] = whileLoopStr; 1119 params["DO_WHILE_PRE"] = doWhileLoopPreStr; 1120 params["DO_WHILE_POST"] = doWhileLoopPostStr; 1121 params["ONE"] = oneStr; 1122 params["TWO"] = twoStr; 1123 params["THREE"] = threeStr; 1124 1125 /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params); 1126 /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params); 1127 1128 // Create the case. 1129 /** @type {glsShaderRenderCase.ShaderEvalFunc} */ 1130 var evalFunc = es3fShaderLoopTests.getLoopEvalFunc(numIters); 1131 return new es3fShaderLoopTests.ShaderLoopCase(caseName, description, isVertexCase, evalFunc, vertexShaderSource, fragmentShaderSource); 1132 }; 1133 1134 // ShaderLoopTests. 1135 1136 /** 1137 * @constructor 1138 * @extends {tcuTestCase.DeqpTest} 1139 */ 1140 es3fShaderLoopTests.ShaderLoopTests = function() { 1141 tcuTestCase.DeqpTest.call(this, 'loops', 'Loop Tests'); 1142 }; 1143 1144 es3fShaderLoopTests.ShaderLoopTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 1145 es3fShaderLoopTests.ShaderLoopTests.prototype.constructor = es3fShaderLoopTests.ShaderLoopTests; 1146 1147 es3fShaderLoopTests.ShaderLoopTests.prototype.init = function() { 1148 var testGroup = tcuTestCase.runner.testCases; 1149 // Loop cases. 1150 1151 /** @type {Array<gluShaderProgram.shaderType>} */ var s_shaderTypes = [ 1152 gluShaderProgram.shaderType.VERTEX, 1153 gluShaderProgram.shaderType.FRAGMENT 1154 ]; 1155 1156 /** @type {Array<gluShaderUtil.DataType>} */ var s_countDataType = [ 1157 gluShaderUtil.DataType.INT, 1158 gluShaderUtil.DataType.FLOAT 1159 ]; 1160 1161 /** @type {gluShaderProgram.shaderType} */ var shaderType; 1162 /** @type {string} */ var shaderTypeName; 1163 /** @type {boolean} */ var isVertexCase; 1164 /** @type {string} */ var name; 1165 /** @type {string} */ var desc; 1166 1167 for (var loopType in es3fShaderLoopTests.LoopType) { 1168 /** @type {string} */ var loopTypeName = es3fShaderLoopTests.getLoopTypeName(es3fShaderLoopTests.LoopType[loopType]); 1169 /** @type {tcuTestCase.DeqpTest} */ var loopTypeGroup = tcuTestCase.newTest(loopTypeName, 'Loop tests with ' + loopTypeName + ' loop type'); 1170 testGroup.addChild(loopTypeGroup); 1171 1172 for (var loopCountType in es3fShaderLoopTests.LoopCountType) { 1173 /** @type {string} */ var loopCountName = es3fShaderLoopTests.getLoopCountTypeName(es3fShaderLoopTests.LoopCountType[loopCountType]); 1174 1175 /** @type {string} */ var groupName = loopCountName + '_iterations'; 1176 /** @type {string} */ var groupDesc = 'Loop tests with ' + loopCountName + ' loop counter.'; 1177 1178 /** @type {tcuTestCase.DeqpTest} */ var group = tcuTestCase.newTest(groupName, groupDesc); 1179 loopTypeGroup.addChild(group); 1180 1181 // Generic cases. 1182 1183 for (var precision in gluShaderUtil.precision) { 1184 /** @type {string} */ var precisionName = gluShaderUtil.getPrecisionName(gluShaderUtil.precision[precision]); 1185 1186 for (var dataTypeNdx = 0; dataTypeNdx < s_countDataType.length; dataTypeNdx++) { 1187 /** @type {gluShaderUtil.DataType} */ var loopDataType = s_countDataType[dataTypeNdx]; 1188 /** @type {string} */ var dataTypeName = gluShaderUtil.getDataTypeName(loopDataType); 1189 1190 for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) { 1191 shaderType = s_shaderTypes[shaderTypeNdx]; 1192 shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType); 1193 isVertexCase = (shaderType == gluShaderProgram.shaderType.VERTEX); 1194 1195 1196 name = 'basic_' + precisionName + '_' + dataTypeName + '_' + shaderTypeName; 1197 desc = loopTypeName + ' loop with ' + precisionName + dataTypeName + ' ' + loopCountName + ' iteration count in ' + shaderTypeName + ' shader.'; 1198 group.addChild(es3fShaderLoopTests.createGenericLoopCase(name, desc, isVertexCase, es3fShaderLoopTests.LoopType[loopType], es3fShaderLoopTests.LoopCountType[loopCountType], gluShaderUtil.precision[precision], loopDataType)); 1199 } 1200 } 1201 } 1202 1203 // Special cases. 1204 1205 for (var loopCase in es3fShaderLoopTests.LoopCase) { 1206 /** @type {string} */ var loopCaseName = es3fShaderLoopTests.getLoopCaseName(es3fShaderLoopTests.LoopCase[loopCase]); 1207 1208 // no-iterations not possible with do-while. 1209 if ((es3fShaderLoopTests.LoopCase[loopCase] == es3fShaderLoopTests.LoopCase.LOOPCASE_NO_ITERATIONS) && (es3fShaderLoopTests.LoopType[loopType] == es3fShaderLoopTests.LoopType.LOOPTYPE_DO_WHILE)) 1210 continue; 1211 1212 for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) { 1213 shaderType = s_shaderTypes[shaderTypeNdx]; 1214 shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType); 1215 isVertexCase = (shaderType == gluShaderProgram.shaderType.VERTEX); 1216 1217 name = loopCaseName + '_' + shaderTypeName; 1218 desc = loopCaseName + ' loop with ' + loopTypeName + ' iteration count in ' + shaderTypeName + ' shader.'; 1219 group.addChild(es3fShaderLoopTests.createSpecialLoopCase(name, desc, isVertexCase, es3fShaderLoopTests.LoopCase[loopCase], es3fShaderLoopTests.LoopType[loopType], es3fShaderLoopTests.LoopCountType[loopCountType])); 1220 } 1221 } 1222 } 1223 } 1224 }; 1225 1226 /** 1227 * Run test 1228 * @param {WebGL2RenderingContext} context 1229 */ 1230 es3fShaderLoopTests.run = function(context, range) { 1231 gl = context; 1232 //Set up Test Root parameters 1233 var state = tcuTestCase.runner; 1234 state.setRoot(new es3fShaderLoopTests.ShaderLoopTests()); 1235 1236 //Set up name and description of this test series. 1237 setCurrentTestName(state.testCases.fullName()); 1238 description(state.testCases.getDescription()); 1239 try { 1240 if (range) 1241 state.setRange(range); 1242 //Run test cases 1243 tcuTestCase.runTestCases(); 1244 } 1245 catch (err) { 1246 testFailedOptions('Failed to es3fShaderLoopTests.run tests', false); 1247 tcuTestCase.runner.terminate(); 1248 } 1249 }; 1250 1251 });