tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

es3fShaderOperatorTests.js (157630B)


      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.es3fShaderOperatorTests');
     23 goog.require('framework.common.tcuTestCase');
     24 goog.require('framework.opengl.gluShaderUtil');
     25 goog.require('framework.opengl.gluShaderProgram');
     26 goog.require('framework.delibs.debase.deMath');
     27 goog.require('modules.shared.glsShaderRenderCase');
     28 goog.require('framework.common.tcuMatrix');
     29 
     30 goog.scope(function() {
     31 var es3fShaderOperatorTests = functional.gles3.es3fShaderOperatorTests;
     32 var tcuTestCase = framework.common.tcuTestCase;
     33 var gluShaderUtil = framework.opengl.gluShaderUtil;
     34 var gluShaderProgram = framework.opengl.gluShaderProgram;
     35 var deMath = framework.delibs.debase.deMath;
     36 var glsShaderRenderCase = modules.shared.glsShaderRenderCase;
     37 var tcuMatrix = framework.common.tcuMatrix;
     38 
     39 /** @const */ es3fShaderOperatorTests.MAX_INPUTS = 3;
     40 
     41 let canvasWH = 256;
     42 if (tcuTestCase.isQuickMode()) {
     43    canvasWH = 32;
     44 }
     45 
     46 es3fShaderOperatorTests.stringJoin = function(elems, delim) {
     47    var result = '';
     48    for (var i = 0; i < elems.length; i++)
     49        result += (i > 0 ? delim : '') + elems[i];
     50    return result;
     51 };
     52 
     53 es3fShaderOperatorTests.twoValuedVec4 = function(first, second, firstMask) {
     54    var elems = [];
     55    for (var i = 0; i < 4; i++)
     56        elems[i] = firstMask[i] ? first : second;
     57 
     58    return 'vec4(' + es3fShaderOperatorTests.stringJoin(elems, ', ') + ')';
     59 };
     60 
     61 var setParentClass = function(child, parent) {
     62    child.prototype = Object.create(parent.prototype);
     63    child.prototype.constructor = child;
     64 };
     65 
     66 var negate = function(x) {
     67    return -x;
     68 };
     69 
     70 var addOne = function(x) {
     71    return x + 1;
     72 };
     73 
     74 var subOne = function(x) {
     75    return x - 1;
     76 };
     77 
     78 /**
     79 * @param {number} a
     80 * @param {number} b
     81 */
     82 var add = function(a, b) {
     83    return a + b;
     84 };
     85 
     86 /**
     87 * @param {number} a
     88 * @param {number} b
     89 */
     90 var sub = function(a, b) {
     91    return a - b;
     92 };
     93 
     94 /**
     95 * @param {number} a
     96 * @param {number} b
     97 */
     98 var mul = function(a, b) {
     99    return a * b;
    100 };
    101 
    102 /**
    103 * @param {number} a
    104 * @param {number} b
    105 */
    106 var div = function(a, b) {
    107    return a / b;
    108 };
    109 
    110 /**
    111 * @param {number} a
    112 * @param {number} b
    113 * @return {number}
    114 */
    115 var lessThan = function(a, b) {
    116    return a < b ? 1 : 0;
    117 };
    118 
    119 /**
    120 * @param {Array<number>} a
    121 * @param {Array<number>} b
    122 * @return {Array<number>}
    123 */
    124 var lessThanVec = function(a, b) {
    125    var res = [];
    126    for (var i = 0; i < a.length; i++)
    127        res[i] = a[i] < b[i];
    128    return res
    129 };
    130 
    131 /**
    132 * @param {number} a
    133 * @param {number} b
    134 * @return {number}
    135 */
    136 var lessThanEqual = function(a, b) {
    137    return a <= b ? 1 : 0;
    138 };
    139 
    140 /**
    141 * @param {Array<number>} a
    142 * @param {Array<number>} b
    143 * @return {Array<number>}
    144 */
    145 var lessThanEqualVec = function(a, b) {
    146    var res = [];
    147    for (var i = 0; i < a.length; i++)
    148        res[i] = a[i] <= b[i];
    149    return res;
    150 };
    151 
    152 /**
    153 * @param {number} a
    154 * @param {number} b
    155 */
    156 var greaterThan = function(a, b) {
    157    return a > b ? 1 : 0;
    158 };
    159 
    160 /**
    161 * @param {Array<number>} a
    162 * @param {Array<number>} b
    163 * @return {Array<number>}
    164 */
    165 var greaterThanVec = function(a, b) {
    166    var res = [];
    167    for (var i = 0; i < a.length; i++)
    168        res[i] = a[i] > b[i];
    169    return res;
    170 };
    171 
    172 /**
    173 * @param {number} a
    174 * @param {number} b
    175 */
    176 var greaterThanEqual = function(a, b) {
    177    return a >= b ? 1 : 0;
    178 };
    179 
    180 /**
    181 * @param {Array<number>} a
    182 * @param {Array<number>} b
    183 * @return {Array<number>}
    184 */
    185 var greaterThanEqualVec = function(a, b) {
    186    var res = [];
    187    for (var i = 0; i < a.length; i++)
    188        res[i] = a[i] >= b[i];
    189    return res;
    190 };
    191 
    192 /**
    193 * @param {Array<number>} a
    194 * @param {Array<number>} b
    195 * @return {number}
    196 */
    197 var allEqual = function(a, b) {
    198    return deMath.equal(a, b) ? 1 : 0;
    199 };
    200 
    201 /**
    202 * @param {Array<number>} a
    203 * @param {Array<number>} b
    204 * @return {Array<number>}
    205 */
    206 var allEqualVec = function(a, b) {
    207    var res = [];
    208    for (var i = 0; i < a.length; i++)
    209        res[i] = a[i] == b[i];
    210    return res;
    211 };
    212 
    213 /**
    214 * @param {Array<number>} a
    215 * @param {Array<number>} b
    216 * @return {number}
    217 */
    218 var anyNotEqual = function(a, b) {
    219    return !deMath.equal(a, b) ? 1 : 0;
    220 };
    221 
    222 /**
    223 * @param {Array<number>} a
    224 * @param {Array<number>} b
    225 * @return {Array<number>}
    226 */
    227 var anyNotEqualVec = function(a, b) {
    228    var res = [];
    229    for (var i = 0; i < a.length; i++)
    230        res[i] = a[i] != b[i];
    231    return res;
    232 };
    233 
    234 /**
    235 * @param {Array<number>} a
    236 * @return {Array<number>}
    237 */
    238 var boolNotVec = function(a) {
    239    var res = [];
    240    for (var i = 0; i < a.length; i++)
    241        res[i] = !a[i];
    242    return res;
    243 }
    244 
    245 /**
    246 * @param {Array<number>} a
    247 * @return {boolean}
    248 */
    249 var boolAny = function(a) {
    250    for (var i = 0; i < a.length; i++)
    251        if (a[i] == true)
    252            return true;
    253    return false;
    254 }
    255 
    256 /**
    257 * @param {Array<number>} a
    258 * @return {boolean}
    259 */
    260 var boolAll = function(a) {
    261    for (var i = 0; i < a.length; i++)
    262        if (a[i] == false)
    263            return false;
    264    return true;
    265 }
    266 
    267 /**
    268 * @param {number} a
    269 * @param {number} b
    270 */
    271 var logicalAnd = function(a, b) {
    272    return a && b ? 1 : 0;
    273 };
    274 
    275 /**
    276 * @param {number} a
    277 * @param {number} b
    278 */
    279 var logicalOr = function(a, b) {
    280    return a || b ? 1 : 0;
    281 };
    282 
    283 /**
    284 * @param {number} a
    285 * @param {number} b
    286 */
    287 var logicalXor = function(a, b) {
    288    return a != b ? 1 : 0;
    289 };
    290 
    291 /**
    292 * @param {number} a
    293 */
    294 var exp2 = function(a) {
    295    return deFloatExp2(a);
    296 };
    297 
    298 /**
    299 * @param {number} a
    300 */
    301 var inverseSqrt = function(a) {
    302    return deFloatRsq(a);
    303 };
    304 
    305 /**
    306 * @param {Array<number>} a
    307 * @param {number} b
    308 * @return {Array<number>}
    309 */
    310 var minVecScalar = function(a, b) {
    311    var res = [];
    312    for (var i = 0; i < a.length; i++)
    313        res[i] = Math.min(a[i], b);
    314    return res;
    315 };
    316 
    317 /**
    318 * @param {Array<number>} a
    319 * @param {number} b
    320 * @return {Array<number>}
    321 */
    322 var maxVecScalar = function(a, b) {
    323    var res = [];
    324    for (var i = 0; i < a.length; i++)
    325        res[i] = Math.max(a[i], b);
    326    return res;
    327 };
    328 
    329 /**
    330 * @param {number} a
    331 * @param {number} b
    332 * @param {number} c
    333 * @return {number}
    334 */
    335 var mix = function(a, b, c) {
    336    return a * (1.0 - c) + b * c;
    337 };
    338 /**
    339 * @param {Array<number>} a
    340 * @param {Array<number>} b
    341 * @param {number} c
    342 * @return {Array<number>}
    343 */
    344 var mixVecVecScalar = function(a, b, c) {
    345    var res = [];
    346    for (var i = 0; i < a.length; i++)
    347        res[i] = mix(a[i], b[i], c);
    348    return res;
    349 };
    350 
    351 /**
    352 * @param {Array<number>} a
    353 * @param {number} b
    354 * @param {number} c
    355 * @return {Array<number>}
    356 */
    357 var clampVecScalarScalar = function(a, b, c) {
    358    var res = [];
    359    for (var i = 0; i < a.length; i++)
    360        res[i] = deMath.clamp(a[i], b, c);
    361    return res;
    362 };
    363 
    364 /**
    365 * @param {number} a
    366 * @param {number} b
    367 * @return {number}
    368 */
    369 var step = function(a, b) {
    370    return b < a ? 0.0 : 1.0;
    371 };
    372 
    373 /**
    374 * @param {number} a
    375 * @param {Array<number>} b
    376 * @return {Array<number>}
    377 */
    378 var stepScalarVec = function(a, b) {
    379    var res = [];
    380    for (var i = 0; i < b.length; i++)
    381        res[i] = step(a, b[i]);
    382    return res;
    383 };
    384 
    385 /**
    386 * @param {number} a
    387 * @param {number} b
    388 * @param {number} c
    389 * @return {number}
    390 */
    391 var smoothStep = function(a, b, c) {
    392    if (c <= a) return 0.0;
    393    if (c >= b) return 1.0;
    394    var t = deMath.clamp((c - a) / (b - a), 0.0, 1.0);
    395    return t * t * (3.0 - 2.0 * t);
    396 };
    397 
    398 /**
    399 * @param {number} a
    400 * @param {number} b
    401 * @param {Array<number>} c
    402 * @return {Array<number>}
    403 */
    404 var smoothStepScalarScalarVec = function(a, b, c) {
    405    var res = [];
    406    for (var i = 0; i < c.length; i++)
    407        res[i] = smoothStep(a, b, c[i]);
    408    return res;
    409 };
    410 
    411 /**
    412 * @param {number} a
    413 * @return {number}
    414 */
    415 var roundToEven = function(a) {
    416    var q = deMath.deFloatFrac(a);
    417    var r = a - q;
    418 
    419    if (q > 0.5)
    420        r += 1.0;
    421    else if (q == 0.5 && r % 2 != 0)
    422        r += 1.0;
    423 
    424    return r;
    425 };
    426 
    427 /**
    428 * @param {number} a
    429 * @return {number}
    430 */
    431 var fract = function(a) {
    432    return a - Math.floor(a);
    433 };
    434 
    435 /**
    436 * @param {number} a
    437 * @return {number}
    438 */
    439 var radians = function(a) {
    440    return deFloatRadians(a);
    441 }
    442 
    443 /**
    444 * @param {number} a
    445 * @return {number}
    446 */
    447 var degrees = function(a) {
    448    return deFloatDegrees(a);
    449 }
    450 
    451 /**
    452 * @param {number} a
    453 * @param {Array<number>} b
    454 */
    455 var addScalarVec = function(a, b) {
    456    return deMath.addScalar(b, a);
    457 };
    458 
    459 /**
    460 * @param {number} a
    461 * @param {Array<number>} b
    462 */
    463 var subScalarVec = function(a, b) {
    464    var dst = [];
    465    for (var i = 0; i < b.length; i++)
    466        dst.push(a - b[i]);
    467    return dst;
    468 };
    469 
    470 /**
    471 * @param {number} a
    472 * @param {Array<number>} b
    473 */
    474 var mulScalarVec = function(a, b) {
    475    var dst = [];
    476    for (var i = 0; i < b.length; i++)
    477        dst.push(a * b[i]);
    478    return dst;
    479 };
    480 
    481 /**
    482 * @param {number} a
    483 * @param {Array<number>} b
    484 */
    485 var divScalarVec = function(a, b) {
    486    var dst = [];
    487    for (var i = 0; i < b.length; i++)
    488        dst.push(a / b[i]);
    489    return dst;
    490 };
    491 
    492 /**
    493 * @param {number} a
    494 * @param {Array<number>} b
    495 */
    496 var modScalarVec = function(a, b) {
    497    var dst = [];
    498    for (var i = 0; i < b.length; i++)
    499        dst.push(a % b[i]);
    500    return dst;
    501 };
    502 
    503 var bitwiseAndScalarVec = function(a, b) {
    504    var dst = [];
    505    for (var i = 0; i < b.length; i++)
    506        dst.push(deMath.binaryOp(a, b[i], deMath.BinaryOp.AND));
    507    return dst;
    508 };
    509 
    510 var bitwiseOrScalarVec = function(a, b) {
    511    var dst = [];
    512    for (var i = 0; i < b.length; i++)
    513        dst.push(deMath.binaryOp(a, b[i], deMath.BinaryOp.OR));
    514    return dst;
    515 };
    516 
    517 var bitwiseXorScalarVec = function(a, b) {
    518    var dst = [];
    519    for (var i = 0; i < b.length; i++)
    520        dst.push(deMath.binaryOp(a, b[i], deMath.BinaryOp.XOR));
    521    return dst;
    522 };
    523 
    524 /**
    525 * @param {Array<number>} a
    526 * @return {number}
    527 */
    528 var length = function(a) {
    529    var squareSum = 0;
    530    for (var i = 0; i < a.length; i++)
    531        squareSum += a[i] * a[i];
    532    return Math.sqrt(squareSum);
    533 };
    534 
    535 /**
    536 * @param {Array<number>} a
    537 * @param {Array<number>} b
    538 * @return {number}
    539 */
    540 var distance = function(a, b) {
    541    var res = deMath.subtract(a, b)
    542    return length(res);
    543 };
    544 
    545 /**
    546 * @param {Array<number>} a
    547 * @param {Array<number>} b
    548 * @return {number}
    549 */
    550 var dot = function(a, b) {
    551    var res = deMath.multiply(a, b);
    552    var sum = 0;
    553    for (var i = 0; i < res.length; i++)
    554        sum += res[i];
    555    return sum;
    556 };
    557 
    558 /**
    559 * @param {Array<number>} a
    560 * @return {Array<number>}
    561 */
    562 var normalize = function(a) {
    563    var ooLen = 1 / length(a);
    564    var res = [];
    565    for (var i = 0; i < a.length; i++)
    566        res[i] = ooLen * a[i];
    567    return res;
    568 };
    569 
    570 /**
    571 * @param {Array<number>} a
    572 * @param {Array<number>} b
    573 * @param {Array<number>} c
    574 * @return {Array<number>}
    575 */
    576 var faceforward = function(a, b, c) {
    577    return dot(c, b) < 0 ? a : deMath.scale(a, -1);
    578 };
    579 
    580 /**
    581 * @param {Array<number>} a
    582 * @param {Array<number>} b
    583 * @return {Array<number>}
    584 */
    585 var reflect = function(a, b) {
    586    return deMath.subtract(a, deMath.scale(deMath.scale(b, dot(b, a)), 2));
    587 };
    588 
    589 /**
    590 * @param {Array<number>} a
    591 * @param {Array<number>} b
    592 * @param {number} c
    593 * @return {Array<number>}
    594 */
    595 var refract = function(a, b, c) {
    596    var cosAngle = dot(b, a);
    597    var k = 1 - c * c * (1 - cosAngle * cosAngle);
    598    if (k < 0) {
    599        var res = new Array(a.length);
    600        return res.fill(0)
    601    } else
    602        return deMath.subtract(deMath.scale(a, c), deMath.scale(b, c * cosAngle + Math.sqrt(k)));
    603 };
    604 
    605 /**
    606 * @param {Array<number>} a
    607 * @param {Array<number>} b
    608 * @return {Array<number>}
    609 */
    610 var cross = function(a, b) {
    611    if (a.length != 3 || b.length != 3)
    612        throw new Error('Arrays must have the size of 3');
    613    return [
    614        a[1] * b[2] - b[1] * a[2],
    615        a[2] * b[0] - b[2] * a[0],
    616        a[0] * b[1] - b[0] * a[1]];
    617 };
    618 
    619 var nop = function(v) {
    620    return v;
    621 };
    622 
    623 var selection = function(cond, a, b) {
    624    return cond ? a : b;
    625 };
    626 
    627 var boolNot = function(a) {
    628    return !a;
    629 };
    630 
    631 var bitwiseNot = function(a) {
    632    return ~a;
    633 };
    634 
    635 /**
    636 * @param {number} x
    637 * @return {number}
    638 */
    639 var deFloatRadians = function(x) {
    640    return x * (Math.PI / 180.0);
    641 };
    642 
    643 /**
    644 * @param {number} x
    645 * @return {number}
    646 */
    647 var deFloatDegrees = function(x) {
    648    return x * (180.0 / Math.PI);
    649 };
    650 
    651 /**
    652 * @param {number} x
    653 * @return {number}
    654 */
    655 var deFloatExp2 = function(x) {
    656    return Math.exp(x * Math.LN2);
    657 };
    658 
    659 /**
    660 * @param {number} x
    661 * @return {number}
    662 */
    663 var deFloatLog2 = function(x) {
    664    return Math.log(x) * Math.LOG2E;
    665 };
    666 
    667 /**
    668 * @param {number} x
    669 * @return {number}
    670 */
    671 var deFloatRsq = function(x) {
    672    var s = Math.sqrt(x);
    673    return s == 0.0 ? 0.0 : (1.0 / s);
    674 };
    675 
    676 /**
    677 * @constructor
    678 * @param {boolean} low
    679 * @param {boolean} medium
    680 * @param {boolean} high
    681 */
    682 es3fShaderOperatorTests.Precision = function(low, medium, high) {
    683    this.low = low;
    684    this.medium = medium;
    685    this.high = high;
    686 };
    687 
    688 /** @const */ es3fShaderOperatorTests.Precision.Low = new es3fShaderOperatorTests.Precision(true, false, false);
    689 /** @const */ es3fShaderOperatorTests.Precision.Medium = new es3fShaderOperatorTests.Precision(false, true, false);
    690 /** @const */ es3fShaderOperatorTests.Precision.High = new es3fShaderOperatorTests.Precision(false, false, true);
    691 /** @const */ es3fShaderOperatorTests.Precision.LowMedium = new es3fShaderOperatorTests.Precision(true, true, false);
    692 /** @const */ es3fShaderOperatorTests.Precision.MediumHigh = new es3fShaderOperatorTests.Precision(false, true, true);
    693 /** @const */ es3fShaderOperatorTests.Precision.All = new es3fShaderOperatorTests.Precision(true, true, true);
    694 /** @const */ es3fShaderOperatorTests.Precision.None = new es3fShaderOperatorTests.Precision(false, false, false);
    695 
    696 /**
    697 * @enum
    698 */
    699 es3fShaderOperatorTests.ValueType = {
    700    NONE: 0,
    701    FLOAT: (1 << 0), // float scalar
    702    FLOAT_VEC: (1 << 1), // float vector
    703    FLOAT_GENTYPE: (1 << 2), // float scalar/vector
    704    VEC3: (1 << 3), // vec3 only
    705    MATRIX: (1 << 4), // matrix
    706    BOOL: (1 << 5), // boolean scalar
    707    BOOL_VEC: (1 << 6), // boolean vector
    708    BOOL_GENTYPE: (1 << 7), // boolean scalar/vector
    709    INT: (1 << 8), // int scalar
    710    INT_VEC: (1 << 9), // int vector
    711    INT_GENTYPE: (1 << 10), // int scalar/vector
    712    UINT: (1 << 11), // uint scalar
    713    UINT_VEC: (1 << 12), // uint vector
    714    UINT_GENTYPE: (1 << 13) // uint scalar/vector
    715 };
    716 
    717 /**
    718 * @param {es3fShaderOperatorTests.ValueType} type
    719 * @return {boolean}
    720 */
    721 es3fShaderOperatorTests.isBoolType = function(type) {
    722    return (type & (es3fShaderOperatorTests.ValueType.BOOL | es3fShaderOperatorTests.ValueType.BOOL_VEC | es3fShaderOperatorTests.ValueType.BOOL_GENTYPE)) != 0;
    723 };
    724 
    725 /**
    726 * @param {es3fShaderOperatorTests.ValueType} type
    727 * @return {boolean}
    728 */
    729 es3fShaderOperatorTests.isIntType = function(type) {
    730    return (type & (es3fShaderOperatorTests.ValueType.INT | es3fShaderOperatorTests.ValueType.INT_VEC | es3fShaderOperatorTests.ValueType.INT_GENTYPE)) != 0;
    731 };
    732 
    733 /**
    734 * @param {es3fShaderOperatorTests.ValueType} type
    735 * @return {boolean}
    736 */
    737 es3fShaderOperatorTests.isUintType = function(type) {
    738    return (type & (es3fShaderOperatorTests.ValueType.UINT | es3fShaderOperatorTests.ValueType.UINT_VEC | es3fShaderOperatorTests.ValueType.UINT_GENTYPE)) != 0;
    739 };
    740 
    741 /**
    742 * @param {es3fShaderOperatorTests.ValueType} type
    743 * @return {boolean}
    744 */
    745 es3fShaderOperatorTests.isScalarType = function(type) {
    746    return type == es3fShaderOperatorTests.ValueType.FLOAT || type == es3fShaderOperatorTests.ValueType.BOOL || type == es3fShaderOperatorTests.ValueType.INT || type == es3fShaderOperatorTests.ValueType.UINT;
    747 };
    748 
    749 /**
    750 * @param {es3fShaderOperatorTests.ValueType} type
    751 * @return {boolean}
    752 */
    753 es3fShaderOperatorTests.isFloatType = function(type) {
    754    return (type & (es3fShaderOperatorTests.ValueType.FLOAT | es3fShaderOperatorTests.ValueType.FLOAT_VEC | es3fShaderOperatorTests.ValueType.FLOAT_GENTYPE)) != 0;
    755 };
    756 
    757 /**
    758 * @param {gluShaderProgram.shaderType} shaderType
    759 * @param {gluShaderUtil.precision} uintPrecision
    760 * @return {number}
    761 */
    762 es3fShaderOperatorTests.getGLSLUintMaxAsFloat = function(shaderType, uintPrecision) {
    763    switch (uintPrecision) {
    764        case gluShaderUtil.precision.PRECISION_LOWP:
    765            var intPrecisionGL = gl.LOW_INT;
    766            break;
    767        case gluShaderUtil.precision.PRECISION_MEDIUMP:
    768            var intPrecisionGL = gl.MEDIUM_INT;
    769            break;
    770        case gluShaderUtil.precision.PRECISION_HIGHP:
    771            var intPrecisionGL = gl.HIGH_INT;
    772            break;
    773        default:
    774            assertMsgOptions(false, 'Invalid shader type', false, false);
    775            var intPrecisionGL = 0;
    776    }
    777 
    778    switch (shaderType) {
    779        case gluShaderProgram.shaderType.VERTEX:
    780            var shaderTypeGL = gl.VERTEX_SHADER;
    781            break;
    782        case gluShaderProgram.shaderType.FRAGMENT:
    783            var shaderTypeGL = gl.FRAGMENT_SHADER;
    784            break;
    785        default:
    786            assertMsgOptions(false, 'Invalid shader type', false, false);
    787            var shaderTypeGL = 0;
    788    }
    789 
    790    /** @type {WebGLShaderPrecisionFormat } */ var sPrecision = gl.getShaderPrecisionFormat(shaderTypeGL, intPrecisionGL);
    791    assertMsgOptions(gl.getError() === gl.NO_ERROR, 'glGetShaderPrecisionFormat failed', false, true);
    792 
    793    if (!deMath.deInBounds32(sPrecision.rangeMin, 8, 32))
    794        throw new Error('Out of range');
    795 
    796    var numBitsInType = sPrecision.rangeMin + 1;
    797    return Math.pow(2, numBitsInType) - 1;
    798 };
    799 
    800 /**
    801 * @enum
    802 */
    803 es3fShaderOperatorTests.OperationType = {
    804    FUNCTION: 0,
    805    OPERATOR: 1,
    806    SIDE_EFFECT_OPERATOR: 2 // Test the side-effect (as opposed to the result) of a side-effect operator.
    807 };
    808 
    809 /**
    810 * swizzling indices for assigning the tested function output to the correct color channel
    811 */
    812 es3fShaderOperatorTests.outIndices = [];
    813 es3fShaderOperatorTests.outIndices[1] = [0];
    814 es3fShaderOperatorTests.outIndices[2] = [1, 2];
    815 es3fShaderOperatorTests.outIndices[3] = [0, 1, 2];
    816 es3fShaderOperatorTests.outIndices[4] = [0, 1, 2, 3];
    817 
    818 var convert = function(input, dataType) {
    819    switch (dataType) {
    820        case gluShaderUtil.DataType.INT:
    821            if (input instanceof Array) {
    822                var ret = [];
    823                for (var i = 0; i < input.length; i++)
    824                    ret[i] = deMath.intCast(input[i]);
    825                return ret;
    826            }
    827            return deMath.intCast(input);
    828        case gluShaderUtil.DataType.UINT:
    829            if (input instanceof Array) {
    830                var ret = [];
    831                for (var i = 0; i < input.length; i++)
    832                    ret[i] = deMath.uintCast(input[i]);
    833                return ret;
    834            }
    835            return deMath.uintCast(input);
    836        case gluShaderUtil.DataType.BOOL:
    837            if (input instanceof Array) {
    838                var ret = [];
    839                for (var i = 0; i < input.length; i++)
    840                    ret[i] = input[i] > 0 ? 1 : 0;
    841                return ret;
    842            }
    843            return input > 0 ? 1 : 0;
    844 
    845    }
    846    return input;
    847 };
    848 
    849 /**
    850 * Generate unary functions which have the same input and return type
    851 * @param {function(number): number} func
    852 * @param {gluShaderUtil.DataType=} dataTypeIn
    853 * @param {gluShaderUtil.DataType=} dataTypeOut
    854 */
    855 es3fShaderOperatorTests.unaryGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) {
    856    var run = function(output, func, input) {
    857        if (input instanceof Array) {
    858            var len = input.length;
    859            var indices = es3fShaderOperatorTests.outIndices[len];
    860            for (var i = 0; i < input.length; i++)
    861                 output[indices[i]] = convert(func(convert(input[i], dataTypeIn)), dataTypeOut);
    862        } else
    863            output[0] = convert(func(convert(input, dataTypeIn)), dataTypeOut);
    864    };
    865 
    866    var functions = {};
    867    functions.scalar = function(c) { run(c.color, func, c.in_[0][2]); };
    868    functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1])); };
    869    functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1])); };
    870    functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0])); };
    871    return functions;
    872 };
    873 
    874 /**
    875 * Generate unary functions which have the same input and return type
    876 * @param {function(Array<number>): Array<number>} func
    877 * @param {gluShaderUtil.DataType=} dataTypeIn
    878 * @param {gluShaderUtil.DataType=} dataTypeOut
    879 */
    880 es3fShaderOperatorTests.unaryArrayFuncs = function(func, dataTypeOut, dataTypeIn) {
    881    var run = function(output, func, input) {
    882        var len = input.length;
    883        var indices = es3fShaderOperatorTests.outIndices[len];
    884        var value = convert(func(convert(input, dataTypeIn)), dataTypeOut);
    885        for (var i = 0; i < input.length; i++)
    886             output[indices[i]] = value[i];
    887    };
    888 
    889    var functions = {};
    890    functions.scalar = function(c) { run(c.color, func, [c.in_[0][2]]); };
    891    functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1])); };
    892    functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1])); };
    893    functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0])); };
    894    return functions;
    895 };
    896 
    897 /**
    898 * Generate unary functions which always have scalar return type
    899 * @param {function(Array<number>): number} func
    900 * @param {gluShaderUtil.DataType=} dataTypeIn
    901 * @param {gluShaderUtil.DataType=} dataTypeOut
    902 */
    903 es3fShaderOperatorTests.unaryScalarGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) {
    904    var run = function(output, func, input) {
    905        output[0] = convert(func(convert(input, dataTypeIn)), dataTypeOut);
    906    };
    907 
    908    var functions = {};
    909    functions.scalar = function(c) { run(c.color, func, [c.in_[0][2]]); };
    910    functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1])); };
    911    functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1])); };
    912    functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0])); };
    913    return functions;
    914 };
    915 
    916 /**
    917 * Generate unary functions which always have bolean return type
    918 * @param {function(Array<number>): boolean} func
    919 * @param {gluShaderUtil.DataType=} dataTypeIn
    920 * @param {gluShaderUtil.DataType=} dataTypeOut
    921 */
    922 es3fShaderOperatorTests.unaryBooleanGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) {
    923    var run = function(output, func, input) {
    924        output[0] = convert(func(convert(input, dataTypeIn)), dataTypeOut);
    925    };
    926 
    927    var functions = {};
    928    functions.scalar = function(c) { run(c.color, func, [c.in_[0][2] > 0.0]); };
    929    functions.vec2 = function(c) { run(c.color, func, greaterThanVec(deMath.swizzle(c.in_[0], [3, 1]), [0, 0])); };
    930    functions.vec3 = function(c) { run(c.color, func, greaterThanVec(deMath.swizzle(c.in_[0], [2, 0, 1]), [0, 0, 0])); };
    931    functions.vec4 = function(c) { run(c.color, func, greaterThanVec(deMath.swizzle(c.in_[0], [1, 2, 3, 0]), [0, 0, 0, 0])); };
    932    return functions;
    933 };
    934 
    935 /**
    936 * Generate binary functions which have the same input and return type
    937 * @param {function(number, number): number} func
    938 * @param {gluShaderUtil.DataType=} dataTypeIn
    939 * @param {gluShaderUtil.DataType=} dataTypeOut
    940 */
    941 es3fShaderOperatorTests.binaryGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) {
    942    var run = function(output, func, input1, input2) {
    943        if (input1 instanceof Array) {
    944            var len = input1.length;
    945            var indices = es3fShaderOperatorTests.outIndices[len];
    946            for (var i = 0; i < input1.length; i++)
    947                 output[indices[i]] = convert(func(convert(input1[i], dataTypeIn), convert(input2[i], dataTypeIn)), dataTypeOut);
    948        } else {
    949            var value = convert(func(convert(input1, dataTypeIn), convert(input2, dataTypeIn)), dataTypeOut);
    950            output[0] = value;
    951        }
    952    };
    953 
    954    var functions = {};
    955    functions.scalar = function(c) { run(c.color, func, c.in_[0][2], c.in_[1][0]); };
    956    functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), deMath.swizzle(c.in_[1], [1, 0])); };
    957    functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), deMath.swizzle(c.in_[1], [1, 2, 0])); };
    958    functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0]), deMath.swizzle(c.in_[1], [3, 2, 1, 0])); };
    959    return functions;
    960 };
    961 
    962 /**
    963 * Generate binary functions which have the same input and return type
    964 * @param {function(number, number, number): number} func
    965 * @param {gluShaderUtil.DataType=} dataTypeIn
    966 * @param {gluShaderUtil.DataType=} dataTypeOut
    967 */
    968 es3fShaderOperatorTests.ternaryGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) {
    969    var run = function(output, func, input1, input2, input3) {
    970        if (input1 instanceof Array) {
    971            var len = input1.length;
    972            var indices = es3fShaderOperatorTests.outIndices[len];
    973            for (var i = 0; i < input1.length; i++)
    974                 output[indices[i]] = convert(func(convert(input1[i], dataTypeIn), convert(input2[i], dataTypeIn), convert(input3[i], dataTypeIn)), dataTypeOut);
    975        } else {
    976            var value = convert(func(convert(input1, dataTypeIn), convert(input2, dataTypeIn), convert(input3, dataTypeIn)), dataTypeOut);
    977            output[0] = value;
    978        }
    979    };
    980 
    981    var functions = {};
    982    functions.scalar = function(c) { run(c.color, func, c.in_[0][2], c.in_[1][0], c.in_[2][1]); };
    983    functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), deMath.swizzle(c.in_[1], [1, 0]), deMath.swizzle(c.in_[2], [2, 1])); };
    984    functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), deMath.swizzle(c.in_[1], [1, 2, 0]), deMath.swizzle(c.in_[2], [3, 1, 2])); };
    985    functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0]), deMath.swizzle(c.in_[1], [3, 2, 1, 0]), deMath.swizzle(c.in_[2], [0, 3, 2, 1])); };
    986    return functions;
    987 };
    988 
    989 /**
    990 * Generate binary functions which have the same input and return type
    991 * @param {function(Array<number>, Array<number>): number} func
    992 * @param {gluShaderUtil.DataType=} dataTypeIn
    993 * @param {gluShaderUtil.DataType=} dataTypeOut
    994 */
    995 es3fShaderOperatorTests.binaryScalarGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) {
    996    var run = function(output, func, input1, input2) {
    997        var value = convert(func(convert(input1, dataTypeIn), convert(input2, dataTypeIn)), dataTypeOut);
    998        output[0] = value;
    999    };
   1000 
   1001    var functions = {};
   1002    functions.scalar = function(c) { run(c.color, func, [c.in_[0][2]], [c.in_[1][0]]); };
   1003    functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), deMath.swizzle(c.in_[1], [1, 0])); };
   1004    functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), deMath.swizzle(c.in_[1], [1, 2, 0])); };
   1005    functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0]), deMath.swizzle(c.in_[1], [3, 2, 1, 0])); };
   1006    return functions;
   1007 };
   1008 
   1009 /**
   1010 * Generate (cond ? a : b) functions
   1011 * @param {gluShaderUtil.DataType} dataType
   1012 * Returns an array of functions, indexed by datatype size
   1013 */
   1014 es3fShaderOperatorTests.selectionFuncs = function(dataType) {
   1015    var run = function(output, input0, input1, input2) {
   1016        var value = selection(input0, input1, input2);
   1017        value = convert(value, dataType);
   1018        if (value instanceof Array) {
   1019            var len = value.length;
   1020            var indices = es3fShaderOperatorTests.outIndices[len];
   1021            for (var i = 0; i < len; i++)
   1022                output[indices[i]] = value[i];
   1023        } else
   1024            output[0] = value;
   1025    };
   1026 
   1027    var functions = [];
   1028    functions[1] = function(c) { run(c.color, c.in_[0][2] > 0, c.in_[1][0], c.in_[2][1]); };
   1029    functions[2] = function(c) { run(c.color, c.in_[0][2] > 0, deMath.swizzle(c.in_[1], [1, 0]), deMath.swizzle(c.in_[2], [2, 1])); };
   1030    functions[3] = function(c) { run(c.color, c.in_[0][2] > 0, deMath.swizzle(c.in_[1], [1, 2, 0]), deMath.swizzle(c.in_[2], [3, 1, 2])); };
   1031    functions[4] = function(c) { run(c.color, c.in_[0][2] > 0, deMath.swizzle(c.in_[1], [3, 2, 1, 0]), deMath.swizzle(c.in_[2], [0, 3, 2, 1])); };
   1032    return functions;
   1033 };
   1034 
   1035 var cp = function(dst, src) {
   1036    var len = src.length;
   1037    var indices = es3fShaderOperatorTests.outIndices[len];
   1038    for (var i = 0; i < len; i++)
   1039        dst[indices[i]] = src[i];
   1040 };
   1041 
   1042 /**
   1043 * Generate binary functions of form: vec = func(scalar, vec)
   1044 * @param {function(number, Array<number>): Array<number>} func
   1045 * @param {gluShaderUtil.DataType=} dataTypeIn
   1046 * @param {gluShaderUtil.DataType=} dataTypeOut
   1047 */
   1048 es3fShaderOperatorTests.binaryScalarVecFuncs = function(func, dataTypeOut, dataTypeIn) {
   1049    /**
   1050     * @param {function(number, Array<number>): Array<number>} func
   1051     * @param {number} input1
   1052     * @param {Array<number>} input2
   1053     */
   1054    var run = function(output, func, input1, input2) {
   1055        var in1 = convert(input1, dataTypeIn);
   1056        var in2 = convert(input2, dataTypeIn);
   1057        var value = func(in1, in2);
   1058        value = convert(value, dataTypeOut);
   1059        cp(output, value);
   1060    };
   1061    var functions = {};
   1062    functions.vec2 = function(c) { run(c.color, func, c.in_[0][2], deMath.swizzle(c.in_[1], [1, 0])); };
   1063    functions.vec3 = function(c) { run(c.color, func, c.in_[0][2], deMath.swizzle(c.in_[1], [1, 2, 0])); };
   1064    functions.vec4 = function(c) { run(c.color, func, c.in_[0][2], deMath.swizzle(c.in_[1], [3, 2, 1, 0])); };
   1065    return functions;
   1066 };
   1067 
   1068 /**
   1069 * Generate binary functions of form: vec = func(vec, scalar)
   1070 * @param {function(Array<number>, number): Array<number>} func
   1071 * @param {gluShaderUtil.DataType=} dataTypeIn
   1072 * @param {gluShaderUtil.DataType=} dataTypeOut
   1073 */
   1074 es3fShaderOperatorTests.binaryVecScalarFuncs = function(func, dataTypeOut, dataTypeIn) {
   1075    /**
   1076     * @param {function(Array<number>, number): Array<number>} func
   1077     * @param {Array<number>} input1
   1078     * @param {number} input2
   1079     */
   1080    var run = function(output, func, input1, input2) {
   1081        var in1 = convert(input1, dataTypeIn);
   1082        var in2 = convert(input2, dataTypeIn);
   1083        var value = func(in1, in2);
   1084        value = convert(value, dataTypeOut);
   1085        cp(output, value);
   1086    };
   1087    var functions = {};
   1088    functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), c.in_[1][0]); };
   1089    functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), c.in_[1][0]); };
   1090    functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0]), c.in_[1][0]); };
   1091    return functions;
   1092 };
   1093 
   1094 /**
   1095 * Generate binary functions of form: vec = func(vec, vec, scalar)
   1096 * @param {function(Array<number>, Array<number>, number): Array<number>} func
   1097 * @param {gluShaderUtil.DataType=} dataTypeIn
   1098 * @param {gluShaderUtil.DataType=} dataTypeOut
   1099 */
   1100 es3fShaderOperatorTests.ternaryVecVecScalarFuncs = function(func, dataTypeOut, dataTypeIn) {
   1101    /**
   1102     * @param {function(Array<number>, Array<number>, number): Array<number>} func
   1103     * @param {Array<number>} input1
   1104     * @param {Array<number>} input2
   1105     * @param {number} input3
   1106     */
   1107    var run = function(output, func, input1, input2, input3) {
   1108        var in1 = convert(input1, dataTypeIn);
   1109        var in2 = convert(input2, dataTypeIn);
   1110        var in3 = convert(input3, dataTypeIn);
   1111        var value = func(in1, in2, in3);
   1112        value = convert(value, dataTypeOut);
   1113        cp(output, value);
   1114    };
   1115    var functions = {};
   1116    functions.scalar = function(c) { run(c.color, func, [c.in_[0][2]], [c.in_[1][0]], c.in_[2][1]); };
   1117    functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), deMath.swizzle(c.in_[1], [1, 0]), c.in_[2][1]); };
   1118    functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), deMath.swizzle(c.in_[1], [1, 2, 0]), c.in_[2][1]); };
   1119    functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0]), deMath.swizzle(c.in_[1], [3, 2, 1, 0]), c.in_[2][1]); };
   1120    return functions;
   1121 };
   1122 
   1123 /**
   1124 * Generate binary functions of form: vec = func(vec, scalar, scalar)
   1125 * @param {function(Array<number>, number, number): Array<number>} func
   1126 * @param {gluShaderUtil.DataType=} dataTypeIn
   1127 * @param {gluShaderUtil.DataType=} dataTypeOut
   1128 */
   1129 es3fShaderOperatorTests.ternaryVecScalarScalarFuncs = function(func, dataTypeOut, dataTypeIn) {
   1130    /**
   1131     * @param {function(Array<number>, number, number): Array<number>} func
   1132     * @param {Array<number>} input1
   1133     * @param {number} input2
   1134     * @param {number} input3
   1135     */
   1136    var run = function(output, func, input1, input2, input3) {
   1137        var in1 = convert(input1, dataTypeIn);
   1138        var in2 = convert(input2, dataTypeIn);
   1139        var in3 = convert(input3, dataTypeIn);
   1140        var value = func(in1, in2, in3);
   1141        value = convert(value, dataTypeOut);
   1142        cp(output, value);
   1143    };
   1144    var functions = {};
   1145    functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), c.in_[1][0], c.in_[2][1]); };
   1146    functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), c.in_[1][0], c.in_[2][1]); };
   1147    functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0]), c.in_[1][0], c.in_[2][1]); };
   1148    return functions;
   1149 };
   1150 
   1151 /**
   1152 * Generate binary functions of form: vec = func(scalar, scalar, vec)
   1153 * @param {function(number, number, Array<number>): Array<number>} func
   1154 * @param {gluShaderUtil.DataType=} dataTypeIn
   1155 * @param {gluShaderUtil.DataType=} dataTypeOut
   1156 */
   1157 es3fShaderOperatorTests.ternaryScalarScalarVecFuncs = function(func, dataTypeOut, dataTypeIn) {
   1158    /**
   1159     * @param {function(number, number, Array<number>): Array<number>} func
   1160     * @param {number} input1
   1161     * @param {number} input2
   1162     * @param {Array<number>} input3
   1163     */
   1164    var run = function(output, func, input1, input2, input3) {
   1165        var in1 = convert(input1, dataTypeIn);
   1166        var in2 = convert(input2, dataTypeIn);
   1167        var in3 = convert(input3, dataTypeIn);
   1168        var value = func(in1, in2, in3);
   1169        value = convert(value, dataTypeOut);
   1170        cp(output, value);
   1171    };
   1172    var functions = {};
   1173    functions.vec2 = function(c) { run(c.color, func, c.in_[0][2], c.in_[1][0], deMath.swizzle(c.in_[2], [2, 1])); };
   1174    functions.vec3 = function(c) { run(c.color, func, c.in_[0][2], c.in_[1][0], deMath.swizzle(c.in_[2], [3, 1, 2])); };
   1175    functions.vec4 = function(c) { run(c.color, func, c.in_[0][2], c.in_[1][0], deMath.swizzle(c.in_[2], [0, 3, 2, 1])); };
   1176    return functions;
   1177 };
   1178 
   1179 /**
   1180 * Generate binary functions of form: vec = func(vec, vec, vec)
   1181 * @param {function(Array<number>, Array<number>, Array<number>): Array<number>} func
   1182 * @param {gluShaderUtil.DataType=} dataTypeIn
   1183 * @param {gluShaderUtil.DataType=} dataTypeOut
   1184 */
   1185 es3fShaderOperatorTests.ternaryVecVecVecFuncs = function(func, dataTypeOut, dataTypeIn) {
   1186    /**
   1187     * @param {function(Array<number>, Array<number>, Array<number>): Array<number>} func
   1188     * @param {Array<number>} input1
   1189     * @param {Array<number>} input2
   1190     * @param {Array<number>} input3
   1191     */
   1192    var run = function(output, func, input1, input2, input3) {
   1193        var in1 = convert(input1, dataTypeIn);
   1194        var in2 = convert(input2, dataTypeIn);
   1195        var in3 = convert(input3, dataTypeIn);
   1196        var value = func(in1, in2, in3);
   1197        value = convert(value, dataTypeOut);
   1198        cp(output, value);
   1199    };
   1200    var functions = {};
   1201    functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), deMath.swizzle(c.in_[1], [1, 0]), deMath.swizzle(c.in_[2], [2, 1])); };
   1202    functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), deMath.swizzle(c.in_[1], [1, 2, 0]), deMath.swizzle(c.in_[2], [3, 1, 2])); };
   1203    functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0]), deMath.swizzle(c.in_[1], [3, 2, 1, 0]), deMath.swizzle(c.in_[2], [0, 3, 2, 1])); };
   1204    return functions;
   1205 };
   1206 
   1207 /**
   1208 * Generate binary functions of form: vec = func(vec, vec)
   1209 * @param {function(Array<number>, Array<number>): Array<number>} func
   1210 * @param {gluShaderUtil.DataType=} dataTypeIn
   1211 * @param {gluShaderUtil.DataType=} dataTypeOut
   1212 */
   1213 es3fShaderOperatorTests.binaryVecVecFuncs = function(func, dataTypeOut, dataTypeIn) {
   1214    /**
   1215     * @param {function(Array<number>, Array<number>): Array<number>} func
   1216     * @param {Array<number>} input1
   1217     * @param {Array<number>} input2
   1218     */
   1219    var run = function(output, func, input1, input2) {
   1220        var in1 = convert(input1, dataTypeIn);
   1221        var in2 = convert(input2, dataTypeIn);
   1222        var value = func(in1, in2);
   1223        value = convert(value, dataTypeOut);
   1224        cp(output, value);
   1225    };
   1226    var functions = {};
   1227    functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), deMath.swizzle(c.in_[1], [1, 0])); };
   1228    functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), deMath.swizzle(c.in_[1], [1, 2, 0])); };
   1229    functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0]), deMath.swizzle(c.in_[1], [3, 2, 1, 0])); };
   1230    return functions;
   1231 };
   1232 
   1233 /**
   1234 * @constructor
   1235 * @param {es3fShaderOperatorTests.ValueType} valueType
   1236 * @param {es3fShaderOperatorTests.FloatScalar} rangeMin
   1237 * @param {es3fShaderOperatorTests.FloatScalar} rangeMax
   1238 */
   1239 es3fShaderOperatorTests.Value = function(valueType, rangeMin, rangeMax) {
   1240    this.valueType = valueType;
   1241    this.rangeMin = rangeMin;
   1242    this.rangeMax = rangeMax;
   1243 };
   1244 
   1245 /**
   1246 * @enum
   1247 */
   1248 es3fShaderOperatorTests.Symbol = {
   1249    SYMBOL_LOWP_UINT_MAX: 0,
   1250    SYMBOL_MEDIUMP_UINT_MAX: 1,
   1251 
   1252    SYMBOL_LOWP_UINT_MAX_RECIPROCAL: 2,
   1253    SYMBOL_MEDIUMP_UINT_MAX_RECIPROCAL: 3,
   1254 
   1255    SYMBOL_ONE_MINUS_UINT32MAX_DIV_LOWP_UINT_MAX: 4,
   1256    SYMBOL_ONE_MINUS_UINT32MAX_DIV_MEDIUMP_UINT_MAX: 5
   1257 
   1258 };
   1259 
   1260 /**
   1261 * @constructor
   1262 * @param {number|es3fShaderOperatorTests.Symbol} value
   1263 * @param {boolean=} isSymbol
   1264 */
   1265 es3fShaderOperatorTests.FloatScalar = function(value, isSymbol) {
   1266    if (isSymbol)
   1267        this.symbol = /** @type {es3fShaderOperatorTests.Symbol} */ (value);
   1268    else
   1269        this.constant = /** @type {number} */ (value);
   1270 };
   1271 
   1272 /**
   1273 * @param {gluShaderProgram.shaderType} shaderType
   1274 * @return {number}
   1275 */
   1276 es3fShaderOperatorTests.FloatScalar.prototype.getValue = function(shaderType) {
   1277    if (this.constant !== undefined)
   1278        return this.constant;
   1279    else
   1280        switch (this.symbol) {
   1281            case es3fShaderOperatorTests.Symbol.SYMBOL_LOWP_UINT_MAX:
   1282                return es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_LOWP);
   1283            case es3fShaderOperatorTests.Symbol.SYMBOL_MEDIUMP_UINT_MAX:
   1284                return es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_MEDIUMP);
   1285 
   1286            case es3fShaderOperatorTests.Symbol.SYMBOL_LOWP_UINT_MAX_RECIPROCAL:
   1287                return 1.0 / es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_LOWP);
   1288            case es3fShaderOperatorTests.Symbol.SYMBOL_MEDIUMP_UINT_MAX_RECIPROCAL:
   1289                return 1.0 / es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_MEDIUMP);
   1290 
   1291            case es3fShaderOperatorTests.Symbol.SYMBOL_ONE_MINUS_UINT32MAX_DIV_LOWP_UINT_MAX:
   1292                return 1.0 - 0xFFFFFFFF / es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_LOWP);
   1293            case es3fShaderOperatorTests.Symbol.SYMBOL_ONE_MINUS_UINT32MAX_DIV_MEDIUMP_UINT_MAX:
   1294                return 1.0 - 0xFFFFFFFF / es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_MEDIUMP);
   1295 
   1296            default:
   1297                assertMsgOptions(false, 'Invalid shader type', false, false);
   1298                return 0.0;
   1299        }
   1300 };
   1301 
   1302 /**
   1303 * @constructor
   1304 * @param {gluShaderUtil.DataType=} type
   1305 * @param {es3fShaderOperatorTests.FloatScalar=} rangeMin
   1306 * @param {es3fShaderOperatorTests.FloatScalar=} rangeMax
   1307 */
   1308 es3fShaderOperatorTests.ShaderValue = function(type, rangeMin, rangeMax) {
   1309    this.type = type || gluShaderUtil.DataType.INVALID;
   1310    this.rangeMin = rangeMin || new es3fShaderOperatorTests.FloatScalar(0);
   1311    this.rangeMax = rangeMax || new es3fShaderOperatorTests.FloatScalar(0);
   1312 };
   1313 
   1314 /**
   1315 * @constructor
   1316 */
   1317 es3fShaderOperatorTests.ShaderDataSpec = function() {
   1318    /** @type {es3fShaderOperatorTests.FloatScalar} */ this.resultScale = new es3fShaderOperatorTests.FloatScalar(1);
   1319    /** @type {es3fShaderOperatorTests.FloatScalar} */ this.resultBias = new es3fShaderOperatorTests.FloatScalar(0);
   1320    /** @type {es3fShaderOperatorTests.FloatScalar} */ this.referenceScale = new es3fShaderOperatorTests.FloatScalar(1);
   1321    /** @type {es3fShaderOperatorTests.FloatScalar} */ this.referenceBias = new es3fShaderOperatorTests.FloatScalar(0);
   1322    /** @type {es3fShaderOperatorTests.Precision} */ this.precision = es3fShaderOperatorTests.Precision.None;
   1323    /** @type {gluShaderUtil.DataType} */ this.output;
   1324    /** @type {number} */ this.numInputs = 0;
   1325    /** @type {Array<es3fShaderOperatorTests.ShaderValue>}*/ this.inputs = [];
   1326    for (var i = 0; i < es3fShaderOperatorTests.MAX_INPUTS; i++)
   1327        this.inputs[i] = new es3fShaderOperatorTests.ShaderValue();
   1328 };
   1329 
   1330 /**
   1331 * @constructor
   1332 * @struct
   1333 * @param {string} caseName
   1334 * @param {string} shaderFuncName
   1335 * @param {es3fShaderOperatorTests.ValueType} outValue
   1336 * @param {Array<es3fShaderOperatorTests.Value>} inputs
   1337 * @param {es3fShaderOperatorTests.FloatScalar} resultScale
   1338 * @param {es3fShaderOperatorTests.FloatScalar} resultBias
   1339 * @param {es3fShaderOperatorTests.FloatScalar} referenceScale
   1340 * @param {es3fShaderOperatorTests.FloatScalar} referenceBias
   1341 * @param {gluShaderUtil.precision} precision
   1342 * @param {*} functions
   1343 * @param {es3fShaderOperatorTests.OperationType=} type
   1344 * @param {boolean=} isUnaryPrefix
   1345 */
   1346 es3fShaderOperatorTests.BuiltinFuncInfo = function(caseName, shaderFuncName, outValue, inputs, resultScale, resultBias, referenceScale, referenceBias, precision, functions, type, isUnaryPrefix) {
   1347    this.caseName = caseName;
   1348    this.shaderFuncName = shaderFuncName;
   1349    this.outValue = outValue;
   1350    this.inputs = inputs;
   1351    this.resultScale = resultScale;
   1352    this.resultBias = resultBias;
   1353    this.referenceScale = referenceScale;
   1354    this.referenceBias = referenceBias;
   1355    this.precision = precision;
   1356    this.evalFunctions = functions;
   1357    this.type = type || es3fShaderOperatorTests.OperationType.FUNCTION;
   1358    this.isUnaryPrefix = isUnaryPrefix === undefined ? true : isUnaryPrefix;
   1359 };
   1360 
   1361 es3fShaderOperatorTests.builtinOperInfo = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions) {
   1362    return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName,
   1363                                                   shaderFuncName,
   1364                                                   outValue,
   1365                                                   inputs,
   1366                                                   scale,
   1367                                                   bias,
   1368                                                   scale,
   1369                                                   bias,
   1370                                                   precision,
   1371                                                   functions,
   1372                                                   es3fShaderOperatorTests.OperationType.OPERATOR);
   1373 };
   1374 
   1375 es3fShaderOperatorTests.builtinFunctionInfo = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions) {
   1376    return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName,
   1377                                                   shaderFuncName,
   1378                                                   outValue,
   1379                                                   inputs,
   1380                                                   scale,
   1381                                                   bias,
   1382                                                   scale,
   1383                                                   bias,
   1384                                                   precision,
   1385                                                   functions,
   1386                                                   es3fShaderOperatorTests.OperationType.FUNCTION);
   1387 };
   1388 
   1389 es3fShaderOperatorTests.builtinSideEffOperInfo = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions) {
   1390    return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName,
   1391                                                   shaderFuncName,
   1392                                                   outValue,
   1393                                                   inputs,
   1394                                                   scale,
   1395                                                   bias,
   1396                                                   scale,
   1397                                                   bias,
   1398                                                   precision,
   1399                                                   functions,
   1400                                                   es3fShaderOperatorTests.OperationType.SIDE_EFFECT_OPERATOR);
   1401 };
   1402 
   1403 es3fShaderOperatorTests.builtinOperInfoSeparateRefScaleBias = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions, referenceScale, referenceBias) {
   1404    return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName,
   1405                                                    shaderFuncName,
   1406                                                    outValue,
   1407                                                    inputs,
   1408                                                    scale,
   1409                                                    bias,
   1410                                                    referenceScale,
   1411                                                    referenceBias,
   1412                                                    precision,
   1413                                                    functions,
   1414                                                    es3fShaderOperatorTests.OperationType.OPERATOR);
   1415 };
   1416 
   1417 es3fShaderOperatorTests.BuiltinPostSideEffOperInfo = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions) {
   1418    return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName,
   1419                                                    shaderFuncName,
   1420                                                    outValue,
   1421                                                    inputs,
   1422                                                    scale,
   1423                                                    bias,
   1424                                                    scale,
   1425                                                    bias,
   1426                                                    precision,
   1427                                                    functions,
   1428                                                    es3fShaderOperatorTests.OperationType.SIDE_EFFECT_OPERATOR,
   1429                                                    false);
   1430 };
   1431 es3fShaderOperatorTests.BuiltinPostOperInfo = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions) {
   1432    return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName,
   1433                                                    shaderFuncName,
   1434                                                    outValue,
   1435                                                    inputs,
   1436                                                    scale,
   1437                                                    bias,
   1438                                                    scale,
   1439                                                    bias,
   1440                                                    precision,
   1441                                                    functions,
   1442                                                    es3fShaderOperatorTests.OperationType.OPERATOR,
   1443                                                    false);
   1444 };
   1445 
   1446 /**
   1447 * @constructor
   1448 * @param {string} name
   1449 * @param {string} description
   1450 */
   1451 es3fShaderOperatorTests.BuiltinFuncGroup = function(name, description) {
   1452    this.name = name;
   1453    this.description = description;
   1454    this.funcInfos = [];
   1455 };
   1456 
   1457 es3fShaderOperatorTests.BuiltinFuncGroup.prototype.push = function(a) { this.funcInfos.push(a); };
   1458 
   1459 var s_inSwizzles = [
   1460 
   1461    ['z', 'wy', 'zxy', 'yzwx'],
   1462    ['x', 'yx', 'yzx', 'wzyx'],
   1463    ['y', 'zy', 'wyz', 'xwzy']
   1464 ];
   1465 
   1466 var s_outSwizzles = ['x', 'yz', 'xyz', 'xyzw'];
   1467 
   1468 var s_outSwizzleChannelMasks = [
   1469    [true, false, false, false],
   1470    [false, true, true, false],
   1471    [true, true, true, false],
   1472    [true, true, true, true]
   1473 ];
   1474 
   1475 /**
   1476 * @constructor
   1477 * @extends {glsShaderRenderCase.ShaderEvaluator}
   1478 * @param {gluShaderProgram.shaderType} shaderType
   1479 * @param {glsShaderRenderCase.ShaderEvalFunc} evalFunc
   1480 * @param {es3fShaderOperatorTests.FloatScalar} scale
   1481 * @param {es3fShaderOperatorTests.FloatScalar} bias
   1482 * @param {number} resultScalarSize
   1483 */
   1484 es3fShaderOperatorTests.OperatorShaderEvaluator = function(shaderType, evalFunc, scale, bias, resultScalarSize) {
   1485    glsShaderRenderCase.ShaderEvaluator.call(this, evalFunc);
   1486    this.m_shaderType = shaderType;
   1487    this.m_scale = scale;
   1488    this.m_bias = bias;
   1489    this.m_resultScalarSize = resultScalarSize;
   1490    this.m_areScaleAndBiasEvaluated = false;
   1491 };
   1492 
   1493 setParentClass(es3fShaderOperatorTests.OperatorShaderEvaluator, glsShaderRenderCase.ShaderEvaluator);
   1494 
   1495 es3fShaderOperatorTests.OperatorShaderEvaluator.prototype.evaluate = function(ctx) {
   1496    this.m_evalFunc(ctx);
   1497 
   1498    if (!this.m_areScaleAndBiasEvaluated) {
   1499        this.m_evaluatedScale = this.m_scale.getValue(this.m_shaderType);
   1500        this.m_evaluatedBias = this.m_bias.getValue(this.m_shaderType);
   1501        this.m_areScaleAndBiasEvaluated = true;
   1502    }
   1503 
   1504    for (var i = 0; i < 4; i++)
   1505        if (s_outSwizzleChannelMasks[this.m_resultScalarSize - 1][i])
   1506            ctx.color[i] = ctx.color[i] * this.m_evaluatedScale + this.m_evaluatedBias;
   1507 };
   1508 
   1509 /**
   1510 * @constructor
   1511 * @extends {glsShaderRenderCase.ShaderRenderCase}
   1512 * @param {string} caseName
   1513 * @param {string} description
   1514 * @param {boolean} isVertexCase
   1515 * @param {glsShaderRenderCase.ShaderEvalFunc} evalFunc
   1516 * @param {string} shaderOp
   1517 * @param {es3fShaderOperatorTests.ShaderDataSpec} spec
   1518 */
   1519 es3fShaderOperatorTests.ShaderOperatorCase = function(caseName, description, isVertexCase, evalFunc, shaderOp, spec) {
   1520    glsShaderRenderCase.ShaderRenderCase.call(this, caseName, description, isVertexCase, evalFunc);
   1521    this.m_spec = spec;
   1522    this.m_shaderOp = shaderOp;
   1523    var shaderType = isVertexCase ? gluShaderProgram.shaderType.VERTEX : gluShaderProgram.shaderType.FRAGMENT;
   1524    this.m_evaluator = new es3fShaderOperatorTests.OperatorShaderEvaluator(shaderType,
   1525                                                                           evalFunc,
   1526                                                                           spec.referenceScale,
   1527                                                                           spec.referenceBias,
   1528                                                                           gluShaderUtil.getDataTypeScalarSize(spec.output));
   1529 };
   1530 
   1531 setParentClass(es3fShaderOperatorTests.ShaderOperatorCase, glsShaderRenderCase.ShaderRenderCase);
   1532 
   1533 es3fShaderOperatorTests.ShaderOperatorCase.prototype.setupShaderData = function() {
   1534    var shaderType = this.m_isVertexCase ? gluShaderProgram.shaderType.VERTEX : gluShaderProgram.shaderType.FRAGMENT;
   1535    var precision = this.m_spec.precision !== undefined ? gluShaderUtil.getPrecisionName(this.m_spec.precision) : null;
   1536    var inputPrecision = [];
   1537    var sources = [];
   1538    sources[0] = ''; //vertex
   1539    sources[1] = ''; //fragment
   1540    var vtx = 0;
   1541    var frag = 1;
   1542    var op = this.m_isVertexCase ? vtx : frag;
   1543 
   1544    sources[vtx] += '#version 300 es\n';
   1545    sources[frag] += '#version 300 es\n';
   1546 
   1547    // Compute precision for inputs.
   1548    for (var i = 0; i < this.m_spec.numInputs; i++) {
   1549        var isBoolVal = gluShaderUtil.isDataTypeBoolOrBVec(this.m_spec.inputs[i].type);
   1550        var isIntVal = gluShaderUtil.isDataTypeIntOrIVec(this.m_spec.inputs[i].type);
   1551        var isUintVal = gluShaderUtil.isDataTypeUintOrUVec(this.m_spec.inputs[i].type);
   1552        // \note Mediump interpolators are used for booleans, and highp for integers.
   1553        var prec = isBoolVal ? gluShaderUtil.precision.PRECISION_MEDIUMP :
   1554                                isIntVal || isUintVal ? gluShaderUtil.precision.PRECISION_HIGHP :
   1555                                this.m_spec.precision;
   1556        inputPrecision[i] = gluShaderUtil.getPrecisionName(prec);
   1557    }
   1558 
   1559    // Attributes.
   1560    sources[vtx] += 'in highp vec4 a_position;\n';
   1561    for (var i = 0; i < this.m_spec.numInputs; i++)
   1562        sources[vtx] += 'in ' + inputPrecision[i] + ' vec4 a_in' + i + ';\n';
   1563 
   1564    // Color output.
   1565    sources[frag] += 'layout(location = 0) out mediump vec4 o_color;\n';
   1566 
   1567    if (this.m_isVertexCase) {
   1568        sources[vtx] += 'out mediump vec4 v_color;\n';
   1569        sources[frag] += 'in mediump vec4 v_color;\n';
   1570    } else{
   1571        for (var i = 0; i < this.m_spec.numInputs; i++) {
   1572            sources[vtx] += 'out ' + inputPrecision[i] + ' vec4 v_in' + i + ';\n';
   1573            sources[frag] += 'in ' + inputPrecision[i] + ' vec4 v_in' + i + ';\n';
   1574        }
   1575    }
   1576 
   1577    sources[vtx] += '\n';
   1578    sources[vtx] += 'void main()\n';
   1579    sources[vtx] += '{\n';
   1580    sources[vtx] += ' gl_Position = a_position;\n';
   1581 
   1582    sources[frag] += '\n';
   1583    sources[frag] += 'void main()\n';
   1584    sources[frag] += '{\n';
   1585 
   1586    // Expression inputs.
   1587    var prefix = this.m_isVertexCase ? 'a_' : 'v_';
   1588    for (var i = 0; i < this.m_spec.numInputs; i++) {
   1589        var inType = this.m_spec.inputs[i].type;
   1590        var inSize = gluShaderUtil.getDataTypeScalarSize(inType);
   1591        var isInt = gluShaderUtil.isDataTypeIntOrIVec(inType);
   1592        var isUint = gluShaderUtil.isDataTypeUintOrUVec(inType);
   1593        var isBool = gluShaderUtil.isDataTypeBoolOrBVec(inType);
   1594        var typeName = gluShaderUtil.getDataTypeName(inType);
   1595        var swizzle = s_inSwizzles[i][inSize - 1];
   1596 
   1597        sources[op] += '\t';
   1598        if (precision && !isBool) sources[op] += precision + ' ';
   1599 
   1600        sources[op] += typeName + ' in' + i + ' = ';
   1601 
   1602        if (isBool) {
   1603            if (inSize == 1) sources[op] += '(';
   1604            else sources[op] += 'greaterThan(';
   1605        } else if (isInt || isUint)
   1606            sources[op] += typeName + '(';
   1607 
   1608        sources[op] += prefix + 'in' + i + '.' + swizzle;
   1609 
   1610        if (isBool) {
   1611            if (inSize == 1) sources[op] += ' > 0.0)';
   1612            else sources[op] += ', vec' + inSize + '(0.0))';
   1613        } else if (isInt || isUint)
   1614            sources[op] += ')';
   1615 
   1616        sources[op] += ';\n';
   1617    }
   1618 
   1619    // Result variable.
   1620    var outTypeName = gluShaderUtil.getDataTypeName(this.m_spec.output);
   1621    var isBoolOut = gluShaderUtil.isDataTypeBoolOrBVec(this.m_spec.output);
   1622 
   1623    sources[op] += '\t';
   1624    if (precision && !isBoolOut) sources[op] += precision + ' ';
   1625    sources[op] += outTypeName + ' res = ' + outTypeName + '(0.0);\n\n';
   1626 
   1627 
   1628    // Expression.
   1629    sources[op] += '\t' + this.m_shaderOp + '\n\n';
   1630 
   1631    // Convert to color.
   1632    var isResFloatVec = gluShaderUtil.isDataTypeFloatOrVec(this.m_spec.output);
   1633    var outScalarSize = gluShaderUtil.getDataTypeScalarSize(this.m_spec.output);
   1634 
   1635    sources[op] += '\thighp vec4 color = vec4(0.0, 0.0, 0.0, 1.0);\n';
   1636    sources[op] += '\tcolor.' + s_outSwizzles[outScalarSize - 1] + ' = ';
   1637 
   1638    if (!isResFloatVec && outScalarSize == 1)
   1639        sources[op] += 'float(res)';
   1640    else if (!isResFloatVec)
   1641        sources[op] += 'vec' + outScalarSize + '(res)';
   1642    else
   1643        sources[op] += 'res';
   1644 
   1645    sources[op] += ';\n';
   1646 
   1647    // Scale & bias.
   1648    var resultScale = this.m_spec.resultScale.getValue(shaderType);
   1649    var resultBias = this.m_spec.resultBias.getValue(shaderType);
   1650    if ((resultScale != 1.0) || (resultBias != 0.0)) {
   1651        sources[op] += '\tcolor = color';
   1652        if (resultScale != 1.0) sources[op] += ' * ' + es3fShaderOperatorTests.twoValuedVec4(resultScale.toString(10), '1.0', s_outSwizzleChannelMasks[outScalarSize - 1]);
   1653        if (resultBias != 0.0) sources[op] += ' + ' + es3fShaderOperatorTests.twoValuedVec4(resultBias.toString(10), '0.0', s_outSwizzleChannelMasks[outScalarSize - 1]);
   1654        sources[op] += ';\n';
   1655    }
   1656 
   1657    // ..
   1658    if (this.m_isVertexCase) {
   1659        sources[vtx] += ' v_color = color;\n';
   1660        sources[frag] += ' o_color = v_color;\n';
   1661    } else{
   1662        for (var i = 0; i < this.m_spec.numInputs; i++)
   1663        sources[vtx] += ' v_in' + i + ' = a_in' + i + ';\n';
   1664        sources[frag] += ' o_color = color;\n';
   1665    }
   1666 
   1667    sources[vtx] += '}\n';
   1668    sources[frag] += '}\n';
   1669 
   1670    this.m_vertShaderSource = sources[vtx];
   1671    this.m_fragShaderSource = sources[frag];
   1672 
   1673    // Setup the user attributes.
   1674    this.m_userAttribTransforms = [];
   1675    for (var inputNdx = 0; inputNdx < this.m_spec.numInputs; inputNdx++) {
   1676        var v = this.m_spec.inputs[inputNdx];
   1677 
   1678        var rangeMin = v.rangeMin.getValue(shaderType);
   1679        var rangeMax = v.rangeMax.getValue(shaderType);
   1680        var scale = rangeMax - rangeMin;
   1681        var minBias = rangeMin;
   1682        var maxBias = rangeMax;
   1683        var attribMatrix = new tcuMatrix.Matrix(4, 4);
   1684 
   1685        for (var rowNdx = 0; rowNdx < 4; rowNdx++) {
   1686            var row;
   1687 
   1688            switch ((rowNdx + inputNdx) % 4) {
   1689                case 0: row = [scale, 0.0, 0.0, minBias]; break;
   1690                case 1: row = [0.0, scale, 0.0, minBias]; break;
   1691                case 2: row = [-scale, 0.0, 0.0, maxBias]; break;
   1692                case 3: row = [0.0, -scale, 0.0, maxBias]; break;
   1693                default: throw new Error('Invalid row index');
   1694            }
   1695 
   1696            attribMatrix.setRow(rowNdx, row);
   1697        }
   1698 
   1699        this.m_userAttribTransforms[inputNdx] = attribMatrix;
   1700    }
   1701 
   1702 };
   1703 
   1704 // Reference functions for specific sequence operations for the sequence operator tests.
   1705 /**
   1706 * Reference for expression "in0, in2 + in1, in1 + in0"
   1707 * @param {Array<number>} in0 Vec4
   1708 * @param {Array<number>} in1 Vec4
   1709 * @param {Array<number>} in2 Vec4
   1710 * @return {Array<number>} Vec4
   1711 */
   1712 es3fShaderOperatorTests.sequenceNoSideEffCase0 = function(in0, in1, in2) {
   1713    return deMath.add(in1, in0);
   1714 };
   1715 
   1716 /**
   1717 * Reference for expression "in0, in2 + in1, in1 + in0"
   1718 * @param {number} in0 float
   1719 * @param {number} in1 deUint32
   1720 * @param {number} in2 float
   1721 * @return {number} deUint32
   1722 */
   1723 es3fShaderOperatorTests.sequenceNoSideEffCase1 = function(in0, in1, in2) {
   1724    in1 = convert(in1, gluShaderUtil.DataType.UINT);
   1725    return convert(in1 + in1, gluShaderUtil.DataType.UINT);
   1726 };
   1727 
   1728 /**
   1729 * Reference for expression "in0 && in1, in0, ivec2(vec2(in0) + in2)"
   1730 * @param {boolean} in0
   1731 * @param {boolean} in1
   1732 * @param {Array<number>} in2 Vec2
   1733 * @return {Array<number>} IVec2
   1734 */
   1735 es3fShaderOperatorTests.sequenceNoSideEffCase2 = function(in0, in1, in2) {
   1736    in0 = convert(in0, gluShaderUtil.DataType.BOOL);
   1737    return convert([in0 + in2[0], in0 + in2[1]], gluShaderUtil.DataType.INT);
   1738 };
   1739 
   1740 /**
   1741 * Reference for expression "in0 + vec4(in1), in2, in1"
   1742 * @param {Array<number>} in0 Vec4
   1743 * @param {Array<number>} in1 IVec4
   1744 * @param {Array<boolean>} in2 BVec4
   1745 * @return {Array<number>} IVec4
   1746 */
   1747 es3fShaderOperatorTests.sequenceNoSideEffCase3 = function(in0, in1, in2) {
   1748    return convert(in1, gluShaderUtil.DataType.INT);
   1749 };
   1750 
   1751 /**
   1752 * Reference for expression "in0++, in1 = in0 + in2, in2 = in1"
   1753 * @param {Array<number>} in0 Vec4
   1754 * @param {Array<number>} in1 Vec4
   1755 * @param {Array<number>} in2 Vec4
   1756 * @return {Array<number>} Vec4
   1757 */
   1758 es3fShaderOperatorTests.sequenceSideEffCase0 = function(in0, in1, in2) {
   1759    return deMath.add(deMath.add(in0, [1.0, 1.0, 1.0, 1.0]), in2);
   1760 };
   1761 
   1762 /**
   1763 * Reference for expression "in1++, in0 = float(in1), in1 = uint(in0 + in2)"
   1764 * @param {number} in0 float
   1765 * @param {number} in1 deUint32
   1766 * @param {number} in2 float
   1767 * @return {number} deUint32
   1768 */
   1769 es3fShaderOperatorTests.sequenceSideEffCase1 = function(in0, in1, in2) {
   1770    in1 = convert(in1, gluShaderUtil.DataType.UINT);
   1771    return convert(in1 + 1.0 + in2, gluShaderUtil.DataType.UINT);
   1772 };
   1773 
   1774 /**
   1775 * Reference for expression "in1 = in0, in2++, in2 = in2 + vec2(in1), ivec2(in2)"
   1776 * @param {boolean} in0
   1777 * @param {boolean} in1
   1778 * @param {Array<number>} in2 Vec2
   1779 * @return {Array<number>} IVec2
   1780 */
   1781 es3fShaderOperatorTests.sequenceSideEffCase2 = function(in0, in1, in2) {
   1782    in0 = convert(in0, gluShaderUtil.DataType.BOOL);
   1783    return convert(deMath.add(deMath.add(in2, [1.0, 1.0]), [in0, in0]), gluShaderUtil.DataType.INT);
   1784 };
   1785 
   1786 /**
   1787 * Reference for expression "in0 = in0 + vec4(in2), in1 = in1 + ivec4(in0), in1++"
   1788 * @param {Array<number>} in0 Vec4
   1789 * @param {Array<number>} in1 IVec4
   1790 * @param {Array<boolean>} in2 BVec4
   1791 * @return {Array<number>} IVec4
   1792 */
   1793 es3fShaderOperatorTests.sequenceSideEffCase3 = function(in0, in1, in2) {
   1794    in1 = convert(in1, gluShaderUtil.DataType.INT);
   1795    in2 = convert(in2, gluShaderUtil.DataType.BOOL);
   1796    in0 = deMath.add(in0, in2);
   1797    in1 = deMath.add(in1, convert(in0, gluShaderUtil.DataType.INT));
   1798    return in1;
   1799 };
   1800 
   1801 // ShaderEvalFunc-type wrappers for the above functions.
   1802 
   1803 /** @param {glsShaderRenderCase.ShaderEvalContext} ctx */
   1804 es3fShaderOperatorTests.evalSequenceNoSideEffCase0 = function(ctx) {
   1805    ctx.color = es3fShaderOperatorTests.sequenceNoSideEffCase0(
   1806        deMath.swizzle(ctx.in_[0], [1, 2, 3, 0]),
   1807        deMath.swizzle(ctx.in_[1], [3, 2, 1, 0]),
   1808        deMath.swizzle(ctx.in_[2], [0, 3, 2, 1])
   1809    );
   1810 };
   1811 
   1812 /** @param {glsShaderRenderCase.ShaderEvalContext} ctx */
   1813 es3fShaderOperatorTests.evalSequenceNoSideEffCase1 = function(ctx) {
   1814    ctx.color[0] = es3fShaderOperatorTests.sequenceNoSideEffCase1(
   1815        ctx.in_[0][2],
   1816        ctx.in_[1][0],
   1817        ctx.in_[2][1]
   1818    );
   1819 };
   1820 
   1821 /** @param {glsShaderRenderCase.ShaderEvalContext} ctx */
   1822 es3fShaderOperatorTests.evalSequenceNoSideEffCase2 = function(ctx) {
   1823    /** @type {Array<number>} */ var result = es3fShaderOperatorTests.sequenceNoSideEffCase2(
   1824        ctx.in_[0][2] > 0.0,
   1825        ctx.in_[1][0] > 0.0,
   1826        deMath.swizzle(ctx.in_[2], [2, 1])
   1827    );
   1828    ctx.color[1] = result[0];
   1829    ctx.color[2] = result[1];
   1830 };
   1831 
   1832 /** @param {glsShaderRenderCase.ShaderEvalContext} ctx */
   1833 es3fShaderOperatorTests.evalSequenceNoSideEffCase3 = function(ctx) {
   1834    ctx.color = es3fShaderOperatorTests.sequenceNoSideEffCase3(
   1835        deMath.swizzle(ctx.in_[0], [1, 2, 3, 0]),
   1836        deMath.swizzle(ctx.in_[1], [3, 2, 1, 0]),
   1837        deMath.greaterThan(deMath.swizzle(ctx.in_[2], [0, 3, 2, 1]), [0.0, 0.0, 0.0, 0.0])
   1838    );
   1839 };
   1840 
   1841 /** @param {glsShaderRenderCase.ShaderEvalContext} ctx */
   1842 es3fShaderOperatorTests.evalSequenceSideEffCase0 = function(ctx) {
   1843    ctx.color = es3fShaderOperatorTests.sequenceSideEffCase0(
   1844        deMath.swizzle(ctx.in_[0], [1, 2, 3, 0]),
   1845        deMath.swizzle(ctx.in_[1], [3, 2, 1, 0]),
   1846        deMath.swizzle(ctx.in_[2], [0, 3, 2, 1])
   1847    );
   1848 };
   1849 
   1850 /** @param {glsShaderRenderCase.ShaderEvalContext} ctx */
   1851 es3fShaderOperatorTests.evalSequenceSideEffCase1 = function(ctx) {
   1852    ctx.color[0] = es3fShaderOperatorTests.sequenceSideEffCase1(
   1853        ctx.in_[0][2],
   1854        ctx.in_[1][0],
   1855        ctx.in_[2][1]
   1856    );
   1857 };
   1858 
   1859 /** @param {glsShaderRenderCase.ShaderEvalContext} ctx */
   1860 es3fShaderOperatorTests.evalSequenceSideEffCase2 = function(ctx) {
   1861    /** @type {Array<number>} */ var result = es3fShaderOperatorTests.sequenceSideEffCase2(
   1862        ctx.in_[0][2] > 0.0,
   1863        ctx.in_[1][0] > 0.0,
   1864        deMath.swizzle(ctx.in_[2], [2, 1])
   1865    );
   1866    ctx.color[1] = result[0];
   1867    ctx.color[2] = result[1];
   1868 };
   1869 
   1870 /** @param {glsShaderRenderCase.ShaderEvalContext} ctx */
   1871 es3fShaderOperatorTests.evalSequenceSideEffCase3 = function(ctx) {
   1872    ctx.color = es3fShaderOperatorTests.sequenceSideEffCase3(
   1873        deMath.swizzle(ctx.in_[0], [1, 2, 3, 0]),
   1874        deMath.swizzle(ctx.in_[1], [3, 2, 1, 0]),
   1875        deMath.greaterThan(deMath.swizzle(ctx.in_[2], [0, 3, 2, 1]), [0.0, 0.0, 0.0, 0.0])
   1876    );
   1877 };
   1878 
   1879 /**
   1880 * @constructor
   1881 * @extends {tcuTestCase.DeqpTest}
   1882 */
   1883 es3fShaderOperatorTests.ShaderOperatorTests = function() {
   1884    tcuTestCase.DeqpTest.call(this, 'shaderop', 'Shader operators tests');
   1885 };
   1886 
   1887 setParentClass(es3fShaderOperatorTests.ShaderOperatorTests, tcuTestCase.DeqpTest);
   1888 
   1889 es3fShaderOperatorTests.ShaderOperatorTests.prototype.init = function() {
   1890    var op = es3fShaderOperatorTests.builtinOperInfo;
   1891    var side = es3fShaderOperatorTests.builtinSideEffOperInfo;
   1892    var separate = es3fShaderOperatorTests.builtinOperInfoSeparateRefScaleBias;
   1893    var postSide = es3fShaderOperatorTests.BuiltinPostSideEffOperInfo;
   1894    var postOp = es3fShaderOperatorTests.BuiltinPostOperInfo;
   1895    var all = es3fShaderOperatorTests.Precision.All;
   1896    var highp = es3fShaderOperatorTests.Precision.High;
   1897    var mediump = es3fShaderOperatorTests.Precision.Medium;
   1898    var mediumhighp = es3fShaderOperatorTests.Precision.MediumHigh;
   1899    var lowp = es3fShaderOperatorTests.Precision.Low;
   1900    var na = es3fShaderOperatorTests.Precision.None;
   1901    var GT = es3fShaderOperatorTests.ValueType.FLOAT_GENTYPE;
   1902    var UGT = es3fShaderOperatorTests.ValueType.UINT_GENTYPE;
   1903    var IGT = es3fShaderOperatorTests.ValueType.INT_GENTYPE;
   1904    var BGT = es3fShaderOperatorTests.ValueType.BOOL_GENTYPE;
   1905    var F = es3fShaderOperatorTests.ValueType.FLOAT;
   1906    var I = es3fShaderOperatorTests.ValueType.INT;
   1907    var U = es3fShaderOperatorTests.ValueType.UINT;
   1908    var BV = es3fShaderOperatorTests.ValueType.BOOL_VEC;
   1909    var FV = es3fShaderOperatorTests.ValueType.FLOAT_VEC;
   1910    var IV = es3fShaderOperatorTests.ValueType.INT_VEC;
   1911    var UV = es3fShaderOperatorTests.ValueType.UINT_VEC;
   1912    var B = es3fShaderOperatorTests.ValueType.BOOL;
   1913    var V3 = es3fShaderOperatorTests.ValueType.VEC3;
   1914    var lUMax = es3fShaderOperatorTests.Symbol.SYMBOL_LOWP_UINT_MAX;
   1915    var mUMax = es3fShaderOperatorTests.Symbol.SYMBOL_MEDIUMP_UINT_MAX;
   1916    var lUMaxR = es3fShaderOperatorTests.Symbol.SYMBOL_LOWP_UINT_MAX_RECIPROCAL;
   1917    var mUMaxR = es3fShaderOperatorTests.Symbol.SYMBOL_MEDIUMP_UINT_MAX_RECIPROCAL;
   1918    var f = function(value) {
   1919        return new es3fShaderOperatorTests.FloatScalar(value);
   1920    };
   1921    var s = function(value) {
   1922        return new es3fShaderOperatorTests.FloatScalar(value, true);
   1923    };
   1924    var v = function(type, a, b) {
   1925        return new es3fShaderOperatorTests.Value(type, f(a), f(b));
   1926    };
   1927    var v2 = function(type, a, b) {
   1928        return new es3fShaderOperatorTests.Value(type, f(a), s(b));
   1929    };
   1930    var funcInfoGroups = [];
   1931    var unary = new es3fShaderOperatorTests.BuiltinFuncGroup('unary_operator', 'Unary operator tests');
   1932    funcInfoGroups.push(unary);
   1933 
   1934    unary.push(op('plus', '+', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.5), all,
   1935        es3fShaderOperatorTests.unaryGenTypeFuncs(nop)));
   1936    unary.push(op('plus', '+', IGT, [v(IGT, -5.0, 5.0)], f(0.1), f(0.5), all,
   1937        es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.INT,
   1938        gluShaderUtil.DataType.INT)));
   1939    unary.push(op('plus', '+', UGT, [v(UGT, 0.0, 2e2)], f(5e-3), f(0.0), all,
   1940        es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.UINT,
   1941        gluShaderUtil.DataType.UINT)));
   1942    unary.push(op('minus', '-', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.5), all,
   1943        es3fShaderOperatorTests.unaryGenTypeFuncs(negate)));
   1944    unary.push(op('minus', '-', IGT, [v(IGT, -5.0, 5.0)], f(0.1), f(0.5), all,
   1945        es3fShaderOperatorTests.unaryGenTypeFuncs(negate, gluShaderUtil.DataType.INT,
   1946        gluShaderUtil.DataType.INT)));
   1947    unary.push(separate('minus', '-', UGT, [v2(UGT, 0.0, lUMax)], s(lUMaxR), f(0.0), lowp,
   1948        es3fShaderOperatorTests.unaryGenTypeFuncs(negate, gluShaderUtil.DataType.UINT,
   1949        gluShaderUtil.DataType.UINT), s(lUMaxR),
   1950        s(es3fShaderOperatorTests.Symbol.SYMBOL_ONE_MINUS_UINT32MAX_DIV_LOWP_UINT_MAX)));
   1951    unary.push(separate('minus', '-', UGT, [v2(UGT, 0.0, mUMax)], s(mUMaxR), f(0.0), mediump,
   1952        es3fShaderOperatorTests.unaryGenTypeFuncs(negate, gluShaderUtil.DataType.UINT,
   1953        gluShaderUtil.DataType.UINT), s(mUMaxR),
   1954        s(es3fShaderOperatorTests.Symbol.SYMBOL_ONE_MINUS_UINT32MAX_DIV_MEDIUMP_UINT_MAX)));
   1955    unary.push(op('minus', '-', UGT, [v(UGT, 0.0, 4e9)], f(2e-10), f(0.0), highp,
   1956        es3fShaderOperatorTests.unaryGenTypeFuncs(negate, gluShaderUtil.DataType.UINT,
   1957        gluShaderUtil.DataType.UINT)));
   1958    unary.push(op('not', '!', B, [v(B, -1.0, 1.0)], f(1.0), f(0.0), na,{'scalar': es3fShaderOperatorTests.unaryGenTypeFuncs(boolNot, gluShaderUtil.DataType.BOOL,
   1959        gluShaderUtil.DataType.BOOL).scalar}));
   1960    unary.push(op('bitwise_not', '~', IGT, [v(IGT, -1e5, 1e5)], f(5e-5), f(0.5), highp,
   1961        es3fShaderOperatorTests.unaryGenTypeFuncs(bitwiseNot, gluShaderUtil.DataType.INT,
   1962        gluShaderUtil.DataType.INT)));
   1963    unary.push(op('bitwise_not', '~', UGT, [v(UGT, 0.0, 2e9)], f(2e-10), f(0.0), highp,
   1964        es3fShaderOperatorTests.unaryGenTypeFuncs(bitwiseNot, gluShaderUtil.DataType.UINT,
   1965        gluShaderUtil.DataType.UINT)));
   1966 
   1967    // Pre/post incr/decr side effect cases.
   1968    unary = new es3fShaderOperatorTests.BuiltinFuncGroup('unary_operator', 'Unary operator tests');
   1969    funcInfoGroups.push(unary);
   1970 
   1971    unary.push(side('pre_increment_effect', '++', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.0), all,
   1972        es3fShaderOperatorTests.unaryGenTypeFuncs(addOne)));
   1973    unary.push(side('pre_increment_effect', '++', IGT, [v(IGT, -6.0, 4.0)], f(0.1), f(0.5), all,
   1974        es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.INT,
   1975        gluShaderUtil.DataType.INT)));
   1976    unary.push(side('pre_increment_effect', '++', UGT, [v(UGT, 0.0, 9.0)], f(0.1), f(0.5), all,
   1977        es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.UINT,
   1978        gluShaderUtil.DataType.UINT)));
   1979    unary.push(side('pre_decrement_effect', '--', GT, [v(GT, -1.0, 1.0)], f(0.5), f(1.0), all,
   1980        es3fShaderOperatorTests.unaryGenTypeFuncs(subOne)));
   1981    unary.push(side('pre_decrement_effect', '--', IGT, [v(IGT, -4.0, 6.0)], f(0.1), f(0.5), all,
   1982        es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.INT,
   1983        gluShaderUtil.DataType.INT)));
   1984    unary.push(side('pre_decrement_effect', '--', UGT, [v(UGT, 0.0, 10.0)], f(0.1), f(0.0), all,
   1985        es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.UINT,
   1986        gluShaderUtil.DataType.UINT)));
   1987    unary.push(postSide('post_increment_result', '++', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.0), all,
   1988        es3fShaderOperatorTests.unaryGenTypeFuncs(addOne)));
   1989    unary.push(postSide('post_increment_result', '++', IGT, [v(IGT, -6.0, 4.0)], f(0.1), f(0.5), all,
   1990        es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.INT,
   1991        gluShaderUtil.DataType.INT)));
   1992    unary.push(postSide('post_increment_result', '++', UGT, [v(UGT, 0.0, 9.0)], f(0.1), f(0.0), all,
   1993        es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.UINT,
   1994        gluShaderUtil.DataType.UINT)));
   1995    unary.push(postSide('post_decrement_result', '--', GT, [v(GT, -1.0, 1.0)], f(0.5), f(1.0), all,
   1996        es3fShaderOperatorTests.unaryGenTypeFuncs(subOne)));
   1997    unary.push(postSide('post_decrement_result', '--', IGT, [v(IGT, -4.0, 6.0)], f(0.1), f(0.5), all,
   1998        es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.INT,
   1999        gluShaderUtil.DataType.INT)));
   2000    unary.push(postSide('post_decrement_result', '--', UGT, [v(UGT, 1.0, 10.0)], f(0.1), f(0.0), all,
   2001        es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.UINT,
   2002        gluShaderUtil.DataType.UINT)));
   2003 
   2004    // Pre/post incr/decr result cases.
   2005    unary = new es3fShaderOperatorTests.BuiltinFuncGroup('unary_operator', 'Unary operator tests');
   2006    funcInfoGroups.push(unary);
   2007 
   2008    unary.push(op('pre_increment_result', '++', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.0), all,
   2009        es3fShaderOperatorTests.unaryGenTypeFuncs(addOne)));
   2010    unary.push(op('pre_increment_result', '++', IGT, [v(IGT, -6.0, 4.0)], f(0.1), f(0.5), all,
   2011        es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.INT,
   2012        gluShaderUtil.DataType.INT)));
   2013    unary.push(op('pre_increment_result', '++', UGT, [v(UGT, 0.0, 9.0)], f(0.1), f(0.0), all,
   2014        es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.UINT,
   2015        gluShaderUtil.DataType.UINT)));
   2016    unary.push(op('pre_dencrement_result', '--', GT, [v(GT, -1.0, 1.0)], f(0.5), f(1.0), all,
   2017        es3fShaderOperatorTests.unaryGenTypeFuncs(subOne)));
   2018    unary.push(op('pre_decrement_result', '--', IGT, [v(IGT, -4.0, 6.0)], f(0.1), f(0.5), all,
   2019        es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.INT,
   2020        gluShaderUtil.DataType.INT)));
   2021    unary.push(op('pre_decrement_result', '--', UGT, [v(UGT, 0.0, 10.0)], f(0.1), f(0.0), all,
   2022        es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.UINT,
   2023        gluShaderUtil.DataType.UINT)));
   2024    unary.push(postOp('post_increment_result', '++', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.5), all,
   2025        es3fShaderOperatorTests.unaryGenTypeFuncs(nop)));
   2026    unary.push(postOp('post_increment_result', '++', IGT, [v(IGT, -5.0, 5.0)], f(0.1), f(0.5), all,
   2027        es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.INT,
   2028        gluShaderUtil.DataType.INT)));
   2029    unary.push(postOp('post_increment_result', '++', UGT, [v(UGT, 0.0, 9.0)], f(0.1), f(0.0), all,
   2030        es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.UINT,
   2031        gluShaderUtil.DataType.UINT)));
   2032    unary.push(postOp('post_decrement_result', '--', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.5), all,
   2033        es3fShaderOperatorTests.unaryGenTypeFuncs(nop)));
   2034    unary.push(postOp('post_decrement_result', '--', IGT, [v(IGT, -5.0, 5.0)], f(0.1), f(0.5), all,
   2035        es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.INT,
   2036        gluShaderUtil.DataType.INT)));
   2037    unary.push(postOp('post_decrement_result', '--', UGT, [v(UGT, 1.0, 10.0)], f(0.1), f(0.0), all,
   2038        es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.UINT,
   2039        gluShaderUtil.DataType.UINT)));
   2040 
   2041    var binary;
   2042 
   2043    // Normal binary operations and their corresponding assignment operations have lots in common; generate both in the following loop.
   2044    // 0: normal op test, 1: assignment op side-effect test, 2: assignment op result test
   2045    for (var binaryOperatorType = 0; binaryOperatorType <= 2; binaryOperatorType++) {
   2046        var isNormalOp = binaryOperatorType == 0;
   2047        var isAssignEff = binaryOperatorType == 1;
   2048        var isAssignRes = binaryOperatorType == 2;
   2049 
   2050        var addName = isNormalOp ? 'add' : isAssignEff ? 'add_assign_effect' : 'add_assign_result';
   2051        var subName = isNormalOp ? 'sub' : isAssignEff ? 'sub_assign_effect' : 'sub_assign_result';
   2052        var mulName = isNormalOp ? 'mul' : isAssignEff ? 'mul_assign_effect' : 'mul_assign_result';
   2053        var divName = isNormalOp ? 'div' : isAssignEff ? 'div_assign_effect' : 'div_assign_result';
   2054        var modName = isNormalOp ? 'mod' : isAssignEff ? 'mod_assign_effect' : 'mod_assign_result';
   2055        var andName = isNormalOp ? 'bitwise_and' : isAssignEff ? 'bitwise_and_assign_effect' : 'bitwise_and_assign_result';
   2056        var orName = isNormalOp ? 'bitwise_or' : isAssignEff ? 'bitwise_or_assign_effect' : 'bitwise_or_assign_result';
   2057        var xorName = isNormalOp ? 'bitwise_xor' : isAssignEff ? 'bitwise_xor_assign_effect' : 'bitwise_xor_assign_result';
   2058        var leftShiftName = isNormalOp ? 'left_shift' : isAssignEff ? 'left_shift_assign_effect' : 'left_shift_assign_result';
   2059        var rightShiftName = isNormalOp ? 'right_shift' : isAssignEff ? 'right_shift_assign_effect' : 'right_shift_assign_result';
   2060        var addOp = isNormalOp ? '+' : '+=';
   2061        var subOp = isNormalOp ? '-' : '-=';
   2062        var mulOp = isNormalOp ? '*' : '*=';
   2063        var divOp = isNormalOp ? '/' : '/=';
   2064        var modOp = isNormalOp ? '%' : '%=';
   2065        var andOp = isNormalOp ? '&' : '&=';
   2066        var orOp = isNormalOp ? '|' : '|=';
   2067        var xorOp = isNormalOp ? '^' : '^=';
   2068        var leftShiftOp = isNormalOp ? '<<' : '<<=';
   2069        var rightShiftOp = isNormalOp ? '>>' : '>>=';
   2070 
   2071        op = isAssignEff ? es3fShaderOperatorTests.builtinSideEffOperInfo : es3fShaderOperatorTests.builtinOperInfo;
   2072 
   2073        binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests');
   2074        funcInfoGroups.push(binary);
   2075 
   2076        // The add operator.
   2077 
   2078        binary.push(op(addName, addOp, GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(1.0), f(0.0),
   2079            all, es3fShaderOperatorTests.binaryGenTypeFuncs(add)));
   2080        binary.push(op(addName, addOp, IGT, [v(IGT, -4.0, 6.0), v(IGT, -6.0, 5.0)], f(0.1), f(0.5),
   2081            mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(add, gluShaderUtil.DataType.INT,
   2082            gluShaderUtil.DataType.INT)));
   2083        binary.push(op(addName, addOp, IGT, [v(IGT, -2e9, 2e9), v(IGT, -2e9, 2e9)], f(4e-10), f(0.5),
   2084            highp, es3fShaderOperatorTests.binaryGenTypeFuncs(add, gluShaderUtil.DataType.INT,
   2085            gluShaderUtil.DataType.INT)));
   2086        binary.push(op(addName, addOp, UGT, [v(UGT, 0.0, 1e2), v(UGT, 0.0, 1e2)], f(5e-3), f(0.0),
   2087            mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(add, gluShaderUtil.DataType.UINT,
   2088            gluShaderUtil.DataType.UINT)));
   2089        binary.push(op(addName, addOp, UGT, [v(UGT, 0.0, 4e9), v(UGT, 0.0, 4e9)], f(2e-10), f(0.0),
   2090            highp, es3fShaderOperatorTests.binaryGenTypeFuncs(add, gluShaderUtil.DataType.UINT,
   2091            gluShaderUtil.DataType.UINT)));
   2092 
   2093        binary.push(op(addName, addOp, FV, [v(FV, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0),
   2094            all, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.addScalar)));
   2095        binary.push(op(addName, addOp, IV, [v(IV, -4.0, 6.0), v(I, -6.0, 5.0)], f(0.1), f(0.5),
   2096            mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.addScalar, gluShaderUtil.DataType.INT,
   2097            gluShaderUtil.DataType.INT)));
   2098        binary.push(op(addName, addOp, IV, [v(IV, -2e9, 2e9), v(I, -2e9, 2e9)], f(4e-10), f(0.5),
   2099            highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.addScalar, gluShaderUtil.DataType.INT,
   2100            gluShaderUtil.DataType.INT)));
   2101        binary.push(op(addName, addOp, UV, [v(UV, 0.0, 1e2), v(U, 0.0, 1e2)], f(5e-3), f(0.0),
   2102            mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.addScalar, gluShaderUtil.DataType.UINT,
   2103            gluShaderUtil.DataType.UINT)));
   2104        binary.push(op(addName, addOp, UV, [v(UV, 0.0, 4e9), v(U, 0.0, 4e9)], f(2e-10), f(0.0),
   2105            highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.addScalar, gluShaderUtil.DataType.UINT,
   2106            gluShaderUtil.DataType.UINT)));
   2107 
   2108        if (isNormalOp) {
   2109            binary.push(op(addName, addOp, FV, [v(F, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
   2110                all, es3fShaderOperatorTests.binaryScalarVecFuncs(addScalarVec)));
   2111            binary.push(op(addName, addOp, IV, [v(I, -4.0, 6.0), v(IV, -6.0, 5.0)], f(0.1), f(0.5),
   2112                mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(addScalarVec, gluShaderUtil.DataType.INT,
   2113                gluShaderUtil.DataType.INT)));
   2114            binary.push(op(addName, addOp, IV, [v(I, -2e9, 2e9), v(IV, -2e9, 2e9)], f(4e-10), f(0.5),
   2115                highp, es3fShaderOperatorTests.binaryScalarVecFuncs(addScalarVec, gluShaderUtil.DataType.INT,
   2116                gluShaderUtil.DataType.INT)));
   2117            binary.push(op(addName, addOp, UV, [v(U, 0.0, 1e2), v(UV, 0.0, 1e2)], f(5e-3), f(0.0),
   2118                mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(addScalarVec, gluShaderUtil.DataType.UINT,
   2119                gluShaderUtil.DataType.UINT)));
   2120            binary.push(op(addName, addOp, UV, [v(U, 0.0, 4e9), v(UV, 0.0, 4e9)], f(2e-10), f(0.0),
   2121                highp, es3fShaderOperatorTests.binaryScalarVecFuncs(addScalarVec, gluShaderUtil.DataType.UINT,
   2122                gluShaderUtil.DataType.UINT)));
   2123        }
   2124 
   2125        // The subtract operator.
   2126 
   2127        binary.push(op(subName, subOp, GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(1.0), f(0.0),
   2128            all, es3fShaderOperatorTests.binaryGenTypeFuncs(sub)));
   2129        binary.push(op(subName, subOp, IGT, [v(IGT, -4.0, 6.0), v(IGT, -6.0, 5.0)], f(0.1), f(0.5),
   2130            mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(sub, gluShaderUtil.DataType.INT,
   2131            gluShaderUtil.DataType.INT)));
   2132        binary.push(op(subName, subOp, IGT, [v(IGT, -2e9, 2e9), v(IGT, -2e9, 2e9)], f(4e-10), f(0.5),
   2133            highp, es3fShaderOperatorTests.binaryGenTypeFuncs(sub, gluShaderUtil.DataType.INT,
   2134            gluShaderUtil.DataType.INT)));
   2135        binary.push(op(subName, subOp, UGT, [v(UGT, 1e2, 2e2), v(UGT, 0.0, 1e2)], f(5e-3), f(0.0),
   2136            mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(sub, gluShaderUtil.DataType.UINT,
   2137            gluShaderUtil.DataType.UINT)));
   2138        binary.push(op(subName, subOp, UGT, [v(UGT, .5e9, 3.7e9), v(UGT, 0.0, 3.9e9)], f(2e-10), f(0.0),
   2139            highp, es3fShaderOperatorTests.binaryGenTypeFuncs(sub, gluShaderUtil.DataType.UINT,
   2140            gluShaderUtil.DataType.UINT)));
   2141        binary.push(op(subName, subOp, FV, [v(FV, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0),
   2142            all, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.subScalar)));
   2143        binary.push(op(subName, subOp, IV, [v(IV, -4.0, 6.0), v(I, -6.0, 5.0)], f(0.1), f(0.5),
   2144            mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.subScalar, gluShaderUtil.DataType.INT,
   2145            gluShaderUtil.DataType.INT)));
   2146        binary.push(op(subName, subOp, IV, [v(IV, -2e9, 2e9), v(I, -2e9, 2e9)], f(4e-10), f(0.5),
   2147            highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.subScalar, gluShaderUtil.DataType.INT,
   2148            gluShaderUtil.DataType.INT)));
   2149        binary.push(op(subName, subOp, UV, [v(UV, 1e2, 2e2), v(U, 0.0, 1e2)], f(5e-3), f(0.0),
   2150            mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.subScalar, gluShaderUtil.DataType.UINT,
   2151            gluShaderUtil.DataType.UINT)));
   2152        binary.push(op(subName, subOp, UV, [v(UV, 0.0, 4e9), v(U, 0.0, 4e9)], f(2e-10), f(0.0),
   2153            highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.subScalar, gluShaderUtil.DataType.UINT,
   2154            gluShaderUtil.DataType.UINT)));
   2155 
   2156        if (isNormalOp) {
   2157            binary.push(op(subName, subOp, FV, [v(F, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
   2158                all, es3fShaderOperatorTests.binaryScalarVecFuncs(subScalarVec)));
   2159            binary.push(op(subName, subOp, IV, [v(I, -4.0, 6.0), v(IV, -6.0, 5.0)], f(0.1), f(0.5),
   2160                mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(subScalarVec, gluShaderUtil.DataType.INT,
   2161                gluShaderUtil.DataType.INT)));
   2162            binary.push(op(subName, subOp, IV, [v(I, -2e9, 2e9), v(IV, -2e9, 2e9)], f(4e-10), f(0.5),
   2163                highp, es3fShaderOperatorTests.binaryScalarVecFuncs(subScalarVec, gluShaderUtil.DataType.INT,
   2164                gluShaderUtil.DataType.INT)));
   2165            binary.push(op(subName, subOp, UV, [v(U, 1e2, 2e2), v(UV, 0.0, 1e2)], f(5e-3), f(0.0),
   2166                mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(subScalarVec, gluShaderUtil.DataType.UINT,
   2167                gluShaderUtil.DataType.UINT)));
   2168            binary.push(op(subName, subOp, UV, [v(U, 0.0, 4e9), v(UV, 0.0, 4e9)], f(2e-10), f(0.0),
   2169                highp, es3fShaderOperatorTests.binaryScalarVecFuncs(subScalarVec, gluShaderUtil.DataType.UINT,
   2170                gluShaderUtil.DataType.UINT)));
   2171        }
   2172 
   2173        binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests');
   2174        funcInfoGroups.push(binary);
   2175 
   2176        // The multiply operator.
   2177 
   2178        binary.push(op(mulName, mulOp, GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(1.0), f(0.0),
   2179            all, es3fShaderOperatorTests.binaryGenTypeFuncs(mul)));
   2180        binary.push(op(mulName, mulOp, IGT, [v(IGT, -4.0, 6.0), v(IGT, -6.0, 5.0)], f(0.1), f(0.5),
   2181            mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(mul, gluShaderUtil.DataType.INT,
   2182            gluShaderUtil.DataType.INT)));
   2183        binary.push(op(mulName, mulOp, IGT, [v(IGT, -3e5, 3e5), v(IGT, -3e4, 3e4)], f(4e-10), f(0.5),
   2184            highp, es3fShaderOperatorTests.binaryGenTypeFuncs(mul, gluShaderUtil.DataType.INT,
   2185            gluShaderUtil.DataType.INT)));
   2186        binary.push(op(mulName, mulOp, UGT, [v(UGT, 0.0, 16.0), v(UGT, 0.0, 16.0)], f(4e-3), f(0.0),
   2187            mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(mul, gluShaderUtil.DataType.UINT,
   2188            gluShaderUtil.DataType.UINT)));
   2189        binary.push(op(mulName, mulOp, UGT, [v(UGT, 0.0, 6e5), v(UGT, 0.0, 6e4)], f(2e-10), f(0.0),
   2190            highp, es3fShaderOperatorTests.binaryGenTypeFuncs(mul, gluShaderUtil.DataType.UINT,
   2191            gluShaderUtil.DataType.UINT)));
   2192        binary.push(op(mulName, mulOp, FV, [v(FV, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0),
   2193            all, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.scale)));
   2194        binary.push(op(mulName, mulOp, IV, [v(IV, -4.0, 6.0), v(I, -6.0, 5.0)], f(0.1), f(0.5),
   2195            mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.scale, gluShaderUtil.DataType.INT,
   2196            gluShaderUtil.DataType.INT)));
   2197        binary.push(op(mulName, mulOp, IV, [v(IV, -3e5, 3e5), v(I, -3e4, 3e4)], f(4e-10), f(0.5),
   2198            highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.scale, gluShaderUtil.DataType.INT,
   2199            gluShaderUtil.DataType.INT)));
   2200        binary.push(op(mulName, mulOp, UV, [v(UV, 0.0, 16.0), v(U, 0.0, 16.0)], f(4e-3), f(0.0),
   2201            mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.scale, gluShaderUtil.DataType.UINT,
   2202            gluShaderUtil.DataType.UINT)));
   2203        binary.push(op(mulName, mulOp, UV, [v(UV, 0.0, 6e5), v(U, 0.0, 6e4)], f(2e-10), f(0.0),
   2204            highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.scale, gluShaderUtil.DataType.UINT,
   2205            gluShaderUtil.DataType.UINT)));
   2206 
   2207        if (isNormalOp) {
   2208            binary.push(op(mulName, mulOp, FV, [v(F, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
   2209                all, es3fShaderOperatorTests.binaryScalarVecFuncs(mulScalarVec)));
   2210            binary.push(op(mulName, mulOp, IV, [v(I, -4.0, 6.0), v(IV, -6.0, 5.0)], f(0.1), f(0.5),
   2211                mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(mulScalarVec, gluShaderUtil.DataType.INT,
   2212                gluShaderUtil.DataType.INT)));
   2213            binary.push(op(mulName, mulOp, IV, [v(I, -3e5, 3e5), v(IV, -3e4, 3e4)], f(4e-10), f(0.5),
   2214                highp, es3fShaderOperatorTests.binaryScalarVecFuncs(mulScalarVec, gluShaderUtil.DataType.INT,
   2215                gluShaderUtil.DataType.INT)));
   2216            binary.push(op(mulName, mulOp, UV, [v(U, 0.0, 16.0), v(UV, 0.0, 16.0)], f(4e-3), f(0.0),
   2217                mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(mulScalarVec, gluShaderUtil.DataType.UINT,
   2218                gluShaderUtil.DataType.UINT)));
   2219            binary.push(op(mulName, mulOp, UV, [v(U, 0.0, 6e5), v(UV, 0.0, 6e4)], f(2e-10), f(0.0),
   2220                highp, es3fShaderOperatorTests.binaryScalarVecFuncs(mulScalarVec, gluShaderUtil.DataType.UINT,
   2221                gluShaderUtil.DataType.UINT)));
   2222        }
   2223 
   2224        // The divide operator.
   2225 
   2226        binary.push(op(divName, divOp, GT, [v(GT, -1.0, 1.0), v(GT, -2.0, -0.5)], f(1.0), f(0.0),
   2227            all, es3fShaderOperatorTests.binaryGenTypeFuncs(div)));
   2228        binary.push(op(divName, divOp, IGT, [v(IGT, 24.0, 24.0), v(IGT, -4.0, -1.0)], f(0.04), f(1.0),
   2229            mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(div, gluShaderUtil.DataType.INT,
   2230            gluShaderUtil.DataType.INT)));
   2231        binary.push(op(divName, divOp, IGT, [v(IGT, 40320.0, 40320.0), v(IGT, -8.0, -1.0)], f(1e-5), f(0.5),
   2232            highp, es3fShaderOperatorTests.binaryGenTypeFuncs(div, gluShaderUtil.DataType.INT,
   2233            gluShaderUtil.DataType.INT)));
   2234        binary.push(op(divName, divOp, UGT, [v(UGT, 0.0, 24.0), v(UGT, 1.0, 4.0)], f(0.04), f(0.0),
   2235            mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(div, gluShaderUtil.DataType.UINT,
   2236            gluShaderUtil.DataType.UINT)));
   2237        binary.push(op(divName, divOp, UGT, [v(UGT, 0.0, 40320.0), v(UGT, 1.0, 8.0)], f(1e-5), f(0.0),
   2238            highp, es3fShaderOperatorTests.binaryGenTypeFuncs(div, gluShaderUtil.DataType.UINT,
   2239            gluShaderUtil.DataType.UINT)));
   2240        binary.push(op(divName, divOp, FV, [v(FV, -1.0, 1.0), v(F, -2.0, -0.5)], f(1.0), f(0.0),
   2241            all, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.divideScale)));
   2242        binary.push(op(divName, divOp, IV, [v(IV, 24.0, 24.0), v(I, -4.0, -1.0)], f(0.04), f(1.0),
   2243            mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.divideScale, gluShaderUtil.DataType.INT,
   2244            gluShaderUtil.DataType.INT)));
   2245        binary.push(op(divName, divOp, IV, [v(IV, 40320.0, 40320.0), v(I, -8.0, -1.0)], f(1e-5), f(0.5),
   2246            highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.divideScale, gluShaderUtil.DataType.INT,
   2247            gluShaderUtil.DataType.INT)));
   2248        binary.push(op(divName, divOp, UV, [v(UV, 0.0, 24.0), v(U, 1.0, 4.0)], f(0.04), f(0.0),
   2249            mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.divideScale, gluShaderUtil.DataType.UINT,
   2250            gluShaderUtil.DataType.UINT)));
   2251        binary.push(op(divName, divOp, UV, [v(UV, 0.0, 40320.0), v(U, 1.0, 8.0)], f(1e-5), f(0.0),
   2252            highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.divideScale, gluShaderUtil.DataType.UINT,
   2253            gluShaderUtil.DataType.UINT)));
   2254 
   2255        if (isNormalOp) {
   2256            binary.push(op(divName, divOp, FV, [v(F, -1.0, 1.0), v(FV, -2.0, -0.5)], f(1.0), f(0.0),
   2257                all, es3fShaderOperatorTests.binaryScalarVecFuncs(divScalarVec)));
   2258            binary.push(op(divName, divOp, IV, [v(I, 24.0, 24.0), v(IV, -4.0, -1.0)], f(0.04), f(1.0),
   2259                mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(divScalarVec, gluShaderUtil.DataType.INT,
   2260                gluShaderUtil.DataType.INT)));
   2261            binary.push(op(divName, divOp, IV, [v(I, 40320.0, 40320.0), v(IV, -8.0, -1.0)], f(1e-5), f(0.5),
   2262                highp, es3fShaderOperatorTests.binaryScalarVecFuncs(divScalarVec, gluShaderUtil.DataType.INT,
   2263                gluShaderUtil.DataType.INT)));
   2264            binary.push(op(divName, divOp, UV, [v(U, 0.0, 24.0), v(UV, 1.0, 4.0)], f(0.04), f(0.0),
   2265                mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(divScalarVec, gluShaderUtil.DataType.UINT,
   2266                gluShaderUtil.DataType.UINT)));
   2267            binary.push(op(divName, divOp, UV, [v(U, 0.0, 40320.0), v(UV, 1.0, 8.0)], f(1e-5), f(0.0),
   2268                highp, es3fShaderOperatorTests.binaryScalarVecFuncs(divScalarVec, gluShaderUtil.DataType.UINT,
   2269                gluShaderUtil.DataType.UINT)));
   2270        }
   2271 
   2272        binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests');
   2273        funcInfoGroups.push(binary);
   2274 
   2275        // The modulus operator.
   2276 
   2277        binary.push(op(modName, modOp, IGT, [v(IGT, 0.0, 6.0), v(IGT, 1.1, 6.1)], f(0.25), f(0.5),
   2278            mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.mod, gluShaderUtil.DataType.INT,
   2279            gluShaderUtil.DataType.INT)));
   2280        binary.push(op(modName, modOp, IGT, [v(IGT, 0.0, 14.0), v(IGT, 1.1, 11.1)], f(0.1), f(0.5),
   2281            highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.mod, gluShaderUtil.DataType.INT,
   2282            gluShaderUtil.DataType.INT)));
   2283        binary.push(op(modName, modOp, UGT, [v(UGT, 0.0, 6.0), v(UGT, 1.1, 6.1)], f(0.25), f(0.0),
   2284            mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.mod, gluShaderUtil.DataType.INT,
   2285            gluShaderUtil.DataType.INT)));
   2286        binary.push(op(modName, modOp, UGT, [v(UGT, 0.0, 24.0), v(UGT, 1.1, 11.1)], f(0.1), f(0.0),
   2287            highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.mod, gluShaderUtil.DataType.UINT,
   2288            gluShaderUtil.DataType.UINT)));
   2289        binary.push(op(modName, modOp, IV, [v(IV, 0.0, 6.0), v(I, 1.1, 6.1)], f(0.25), f(0.5),
   2290            mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.modScale, gluShaderUtil.DataType.INT,
   2291            gluShaderUtil.DataType.INT)));
   2292        binary.push(op(modName, modOp, IV, [v(IV, 0.0, 6.0), v(I, 1.1, 11.1)], f(0.1), f(0.5),
   2293            highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.modScale, gluShaderUtil.DataType.INT,
   2294            gluShaderUtil.DataType.INT)));
   2295        binary.push(op(modName, modOp, UV, [v(UV, 0.0, 6.0), v(U, 1.1, 6.1)], f(0.25), f(0.0),
   2296            mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.modScale, gluShaderUtil.DataType.UINT,
   2297            gluShaderUtil.DataType.UINT)));
   2298        binary.push(op(modName, modOp, UV, [v(UV, 0.0, 24.0), v(U, 1.1, 11.1)], f(0.1), f(0.0),
   2299            highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.modScale, gluShaderUtil.DataType.UINT,
   2300            gluShaderUtil.DataType.UINT)));
   2301 
   2302        if (isNormalOp) {
   2303            binary.push(op(modName, modOp, IV, [v(I, 0.0, 6.0), v(IV, 1.1, 6.1)], f(0.25), f(0.5),
   2304                mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(modScalarVec, gluShaderUtil.DataType.INT,
   2305                gluShaderUtil.DataType.INT)));
   2306            binary.push(op(modName, modOp, IV, [v(I, 0.0, 6.0), v(IV, 1.1, 11.1)], f(0.1), f(0.5),
   2307                highp, es3fShaderOperatorTests.binaryScalarVecFuncs(modScalarVec, gluShaderUtil.DataType.INT,
   2308                gluShaderUtil.DataType.INT)));
   2309            binary.push(op(modName, modOp, UV, [v(U, 0.0, 6.0), v(UV, 1.1, 6.1)], f(0.25), f(0.0),
   2310                mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(modScalarVec, gluShaderUtil.DataType.UINT,
   2311                gluShaderUtil.DataType.UINT)));
   2312            binary.push(op(modName, modOp, UV, [v(U, 0.0, 24.0), v(UV, 1.1, 11.1)], f(0.1), f(0.0),
   2313                highp, es3fShaderOperatorTests.binaryScalarVecFuncs(modScalarVec, gluShaderUtil.DataType.UINT,
   2314                gluShaderUtil.DataType.UINT)));
   2315        }
   2316 
   2317        // The bitwise and operator.
   2318 
   2319        binary.push(op(andName, andOp, IGT, [v(IGT, -16.0, 16.0), v(IGT, -16.0, 16.0)], f(0.03), f(0.5),
   2320            mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryAnd, gluShaderUtil.DataType.INT,
   2321            gluShaderUtil.DataType.INT)));
   2322        binary.push(op(andName, andOp, IGT, [v(IGT, -2e9, 2e9), v(IGT, -2e9, 2e9)], f(4e-10), f(0.5),
   2323            highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryAnd, gluShaderUtil.DataType.INT,
   2324            gluShaderUtil.DataType.INT)));
   2325        binary.push(op(andName, andOp, UGT, [v(UGT, 0.0, 32.0), v(UGT, 0.0, 32.0)], f(0.03), f(0.0),
   2326            mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryAnd, gluShaderUtil.DataType.UINT,
   2327            gluShaderUtil.DataType.UINT)));
   2328        binary.push(op(andName, andOp, UGT, [v(UGT, 0.0, 4e9), v(UGT, 0.0, 4e9)], f(2e-10), f(0.0),
   2329            highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryAnd, gluShaderUtil.DataType.UINT,
   2330            gluShaderUtil.DataType.UINT)));
   2331        binary.push(op(andName, andOp, IV, [v(IV, -16.0, 16.0), v(I, -16.0, 16.0)], f(0.03), f(0.5),
   2332            mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryAndVecScalar, gluShaderUtil.DataType.INT,
   2333            gluShaderUtil.DataType.INT)));
   2334        binary.push(op(andName, andOp, IV, [v(IV, -2e9, 2e9), v(I, -2e9, 2e9)], f(4e-10), f(0.5),
   2335            highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryAndVecScalar, gluShaderUtil.DataType.INT,
   2336            gluShaderUtil.DataType.INT)));
   2337        binary.push(op(andName, andOp, UV, [v(UV, 0.0, 32.0), v(U, 0.0, 32.0)], f(0.03), f(0.0),
   2338            mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryAndVecScalar, gluShaderUtil.DataType.UINT,
   2339            gluShaderUtil.DataType.UINT)));
   2340        binary.push(op(andName, andOp, UV, [v(UV, 0.0, 4e9), v(U, 0.0, 4e9)], f(2e-10), f(0.0),
   2341            highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryAndVecScalar, gluShaderUtil.DataType.UINT,
   2342            gluShaderUtil.DataType.UINT)));
   2343 
   2344        if (isNormalOp) {
   2345            binary.push(op(andName, andOp, IV, [v(I, -16.0, 16.0), v(IV, -16.0, 16.0)], f(0.03), f(0.5),
   2346                mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseAndScalarVec, gluShaderUtil.DataType.INT,
   2347                gluShaderUtil.DataType.INT)));
   2348            binary.push(op(andName, andOp, IV, [v(I, -2e9, 2e9), v(IV, -2e9, 2e9)], f(4e-10), f(0.5),
   2349                highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseAndScalarVec, gluShaderUtil.DataType.INT,
   2350                gluShaderUtil.DataType.INT)));
   2351            binary.push(op(andName, andOp, UV, [v(U, 0.0, 32.0), v(UV, 0.0, 32.0)], f(0.03), f(0.0),
   2352                mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseAndScalarVec, gluShaderUtil.DataType.UINT,
   2353                gluShaderUtil.DataType.UINT)));
   2354            binary.push(op(andName, andOp, UV, [v(U, 0.0, 4e9), v(UV, 0.0, 4e9)], f(2e-10), f(0.0),
   2355                highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseAndScalarVec, gluShaderUtil.DataType.UINT,
   2356                gluShaderUtil.DataType.UINT)));
   2357        }
   2358 
   2359        binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests');
   2360        funcInfoGroups.push(binary);
   2361 
   2362        // The bitwise or operator.
   2363 
   2364        binary.push(op(orName, orOp, IGT, [v(IGT, -16.0, 16.0), v(IGT, -16.0, 16.0)], f(0.03), f(0.5),
   2365            mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryOr, gluShaderUtil.DataType.INT,
   2366            gluShaderUtil.DataType.INT)));
   2367        binary.push(op(orName, orOp, IGT, [v(IGT, -2e9, 2e9), v(IGT, -2e9, 2e9)], f(4e-10), f(0.5),
   2368            highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryOr, gluShaderUtil.DataType.INT,
   2369            gluShaderUtil.DataType.INT)));
   2370        binary.push(op(orName, orOp, UGT, [v(UGT, 0.0, 32.0), v(UGT, 0.0, 32.0)], f(0.03), f(0.0),
   2371            mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryOr, gluShaderUtil.DataType.UINT,
   2372            gluShaderUtil.DataType.UINT)));
   2373        binary.push(op(orName, orOp, UGT, [v(UGT, 0.0, 4e9), v(UGT, 0.0, 4e9)], f(2e-10), f(0.0),
   2374            highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryOr, gluShaderUtil.DataType.UINT,
   2375            gluShaderUtil.DataType.UINT)));
   2376        binary.push(op(orName, orOp, IV, [v(IV, -16.0, 16.0), v(I, -16.0, 16.0)], f(0.03), f(0.5),
   2377            mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryOrVecScalar, gluShaderUtil.DataType.INT,
   2378            gluShaderUtil.DataType.INT)));
   2379        binary.push(op(orName, orOp, IV, [v(IV, -2e9, 2e9), v(I, -2e9, 2e9)], f(4e-10), f(0.5),
   2380            highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryOrVecScalar, gluShaderUtil.DataType.INT,
   2381            gluShaderUtil.DataType.INT)));
   2382        binary.push(op(orName, orOp, UV, [v(UV, 0.0, 32.0), v(U, 0.0, 32.0)], f(0.03), f(0.0),
   2383            mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryOrVecScalar, gluShaderUtil.DataType.UINT,
   2384            gluShaderUtil.DataType.UINT)));
   2385        binary.push(op(orName, orOp, UV, [v(UV, 0.0, 4e9), v(U, 0.0, 4e9)], f(2e-10), f(0.0),
   2386            highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryOrVecScalar, gluShaderUtil.DataType.UINT,
   2387            gluShaderUtil.DataType.UINT)));
   2388 
   2389        if (isNormalOp) {
   2390            binary.push(op(orName, orOp, IV, [v(I, -16.0, 16.0), v(IV, -16.0, 16.0)], f(0.03), f(0.5),
   2391                mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseOrScalarVec, gluShaderUtil.DataType.INT,
   2392                gluShaderUtil.DataType.INT)));
   2393            binary.push(op(orName, orOp, IV, [v(I, -2e9, 2e9), v(IV, -2e9, 2e9)], f(4e-10), f(0.5),
   2394                highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseOrScalarVec, gluShaderUtil.DataType.INT,
   2395                gluShaderUtil.DataType.INT)));
   2396            binary.push(op(orName, orOp, UV, [v(U, 0.0, 32.0), v(UV, 0.0, 32.0)], f(0.03), f(0.0),
   2397                mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseOrScalarVec, gluShaderUtil.DataType.UINT,
   2398                gluShaderUtil.DataType.UINT)));
   2399            binary.push(op(orName, orOp, UV, [v(U, 0.0, 4e9), v(UV, 0.0, 4e9)], f(2e-10), f(0.0),
   2400                highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseOrScalarVec, gluShaderUtil.DataType.UINT,
   2401                gluShaderUtil.DataType.UINT)));
   2402        }
   2403 
   2404        // The bitwise xor operator.
   2405 
   2406        binary.push(op(xorName, xorOp, IGT, [v(IGT, -16.0, 16.0), v(IGT, -16.0, 16.0)], f(0.03), f(0.5),
   2407            mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryXor, gluShaderUtil.DataType.INT,
   2408            gluShaderUtil.DataType.INT)));
   2409        binary.push(op(xorName, xorOp, IGT, [v(IGT, -2e9, 2e9), v(IGT, -2e9, 2e9)], f(4e-10), f(0.5),
   2410            highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryXor, gluShaderUtil.DataType.INT,
   2411            gluShaderUtil.DataType.INT)));
   2412        binary.push(op(xorName, xorOp, UGT, [v(UGT, 0.0, 32.0), v(UGT, 0.0, 32.0)], f(0.03), f(0.0),
   2413            mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryXor, gluShaderUtil.DataType.UINT,
   2414            gluShaderUtil.DataType.UINT)));
   2415        binary.push(op(xorName, xorOp, UGT, [v(UGT, 0.0, 4e9), v(UGT, 0.0, 4e9)], f(2e-10), f(0.0),
   2416            highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryXor, gluShaderUtil.DataType.UINT,
   2417            gluShaderUtil.DataType.UINT)));
   2418        binary.push(op(xorName, xorOp, IV, [v(IV, -16.0, 16.0), v(I, -16.0, 16.0)], f(0.03), f(0.5),
   2419            mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryXorVecScalar, gluShaderUtil.DataType.INT,
   2420            gluShaderUtil.DataType.INT)));
   2421        binary.push(op(xorName, xorOp, IV, [v(IV, -2e9, 2e9), v(I, -2e9, 2e9)], f(4e-10), f(0.5),
   2422            highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryXorVecScalar, gluShaderUtil.DataType.INT,
   2423            gluShaderUtil.DataType.INT)));
   2424        binary.push(op(xorName, xorOp, UV, [v(UV, 0.0, 32.0), v(U, 0.0, 32.0)], f(0.03), f(0.0),
   2425            mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryXorVecScalar, gluShaderUtil.DataType.UINT,
   2426            gluShaderUtil.DataType.UINT)));
   2427        binary.push(op(xorName, xorOp, UV, [v(UV, 0.0, 4e9), v(U, 0.0, 4e9)], f(2e-10), f(0.0),
   2428            highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryXorVecScalar, gluShaderUtil.DataType.UINT,
   2429            gluShaderUtil.DataType.UINT)));
   2430 
   2431        if (isNormalOp) {
   2432            binary.push(op(xorName, xorOp, IV, [v(I, -16.0, 16.0), v(IV, -16.0, 16.0)], f(0.03), f(0.5),
   2433                mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseXorScalarVec, gluShaderUtil.DataType.INT,
   2434                gluShaderUtil.DataType.INT)));
   2435            binary.push(op(xorName, xorOp, IV, [v(I, -2e9, 2e9), v(IV, -2e9, 2e9)], f(4e-10), f(0.5),
   2436                highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseXorScalarVec, gluShaderUtil.DataType.INT,
   2437                gluShaderUtil.DataType.INT)));
   2438            binary.push(op(xorName, xorOp, UV, [v(U, 0.0, 32.0), v(UV, 0.0, 32.0)], f(0.03), f(0.0),
   2439                mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseXorScalarVec, gluShaderUtil.DataType.UINT,
   2440                gluShaderUtil.DataType.UINT)));
   2441            binary.push(op(xorName, xorOp, UV, [v(U, 0.0, 4e9), v(UV, 0.0, 4e9)], f(2e-10), f(0.0),
   2442                highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseXorScalarVec, gluShaderUtil.DataType.UINT,
   2443                gluShaderUtil.DataType.UINT)));
   2444        }
   2445 
   2446        binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests');
   2447        funcInfoGroups.push(binary);
   2448 
   2449        // The left shift operator. Second operand (shift amount) can be either int or uint, even for uint and int first operand, respectively.
   2450        for (var isSignedAmount = 0; isSignedAmount <= 1; isSignedAmount++) {
   2451            var gType = isSignedAmount == 0 ? UGT : IGT;
   2452            var sType = isSignedAmount == 0 ? U : I;
   2453            binary.push(op(leftShiftName, leftShiftOp, IGT, [v(IGT, -7.0, 7.0), v(gType, 0.0, 4.0)], f(4e-3), f(0.5),
   2454                mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftLeft, gluShaderUtil.DataType.INT,
   2455                gluShaderUtil.DataType.INT)));
   2456            binary.push(op(leftShiftName, leftShiftOp, IGT, [v(IGT, -7.0, 7.0), v(gType, 0.0, 27.0)], f(5e-10), f(0.5),
   2457                highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftLeft, gluShaderUtil.DataType.INT,
   2458                gluShaderUtil.DataType.INT)));
   2459            binary.push(op(leftShiftName, leftShiftOp, UGT, [v(UGT, 0.0, 7.0), v(gType, 0.0, 5.0)], f(4e-3), f(0.0),
   2460                mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftLeft, gluShaderUtil.DataType.UINT,
   2461                gluShaderUtil.DataType.UINT)));
   2462            binary.push(op(leftShiftName, leftShiftOp, UGT, [v(UGT, 0.0, 7.0), v(gType, 0.0, 28.0)], f(5e-10), f(0.0),
   2463                highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftLeft, gluShaderUtil.DataType.UINT,
   2464                gluShaderUtil.DataType.UINT)));
   2465            binary.push(op(leftShiftName, leftShiftOp, IV, [v(IV, -7.0, 7.0), v(sType, 0.0, 4.0)], f(4e-3), f(0.5),
   2466                mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftLeftVecScalar, gluShaderUtil.DataType.INT,
   2467                gluShaderUtil.DataType.INT)));
   2468            binary.push(op(leftShiftName, leftShiftOp, IV, [v(IV, -7.0, 7.0), v(sType, 0.0, 27.0)], f(5e-10), f(0.5),
   2469                highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftLeftVecScalar, gluShaderUtil.DataType.INT,
   2470                gluShaderUtil.DataType.INT)));
   2471            binary.push(op(leftShiftName, leftShiftOp, UV, [v(UV, 0.0, 7.0), v(sType, 0.0, 5.0)], f(4e-3), f(0.0),
   2472                mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftLeftVecScalar, gluShaderUtil.DataType.UINT,
   2473                gluShaderUtil.DataType.UINT)));
   2474            binary.push(op(leftShiftName, leftShiftOp, UV, [v(UV, 0.0, 7.0), v(sType, 0.0, 28.0)], f(5e-10), f(0.0),
   2475                highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftLeftVecScalar, gluShaderUtil.DataType.UINT,
   2476                gluShaderUtil.DataType.UINT)));
   2477        }
   2478 
   2479        // The right shift operator. Second operand (shift amount) can be either int or uint, even for uint and int first operand, respectively.
   2480 
   2481        for (var isSignedAmount = 0; isSignedAmount <= 1; isSignedAmount++) {
   2482            gType = isSignedAmount == 0 ? UGT : IGT;
   2483            sType = isSignedAmount == 0 ? U : I;
   2484            binary.push(op(rightShiftName, rightShiftOp, IGT, [v(IGT, -127.0, 127.0), v(gType, 0.0, 8.0)], f(4e-3), f(0.5),
   2485                mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftRight, gluShaderUtil.DataType.INT,
   2486                gluShaderUtil.DataType.INT)));
   2487            binary.push(op(rightShiftName, rightShiftOp, IGT, [v(IGT, -2e9, 2e9), v(gType, 0.0, 31.0)], f(5e-10), f(0.5),
   2488                highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftRight, gluShaderUtil.DataType.INT,
   2489                gluShaderUtil.DataType.INT)));
   2490            binary.push(op(rightShiftName, rightShiftOp, UGT, [v(UGT, 0.0, 255.0), v(gType, 0.0, 8.0)], f(4e-3), f(0.0),
   2491                mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftRight, gluShaderUtil.DataType.UINT,
   2492                gluShaderUtil.DataType.UINT)));
   2493            binary.push(op(rightShiftName, rightShiftOp, UGT, [v(UGT, 0.0, 4e9), v(gType, 0.0, 31.0)], f(5e-10), f(0.0),
   2494                highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftRight, gluShaderUtil.DataType.UINT,
   2495                gluShaderUtil.DataType.UINT)));
   2496            binary.push(op(rightShiftName, rightShiftOp, IV, [v(IV, -127.0, 127.0), v(sType, 0.0, 8.0)], f(4e-3), f(0.5),
   2497                mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftRightVecScalar, gluShaderUtil.DataType.INT,
   2498                gluShaderUtil.DataType.INT)));
   2499            binary.push(op(rightShiftName, rightShiftOp, IV, [v(IV, -2e9, 2e9), v(sType, 0.0, 31.0)], f(5e-10), f(0.5),
   2500                highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftRightVecScalar, gluShaderUtil.DataType.INT,
   2501                gluShaderUtil.DataType.INT)));
   2502            binary.push(op(rightShiftName, rightShiftOp, UV, [v(UV, 0.0, 255.0), v(sType, 0.0, 8.0)], f(4e-3), f(0.0),
   2503                mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftRightVecScalar, gluShaderUtil.DataType.UINT,
   2504                gluShaderUtil.DataType.UINT)));
   2505            binary.push(op(rightShiftName, rightShiftOp, UV, [v(UV, 0.0, 4e9), v(sType, 0.0, 31.0)], f(5e-10), f(0.0),
   2506                highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftRightVecScalar, gluShaderUtil.DataType.UINT,
   2507                gluShaderUtil.DataType.UINT)));
   2508        }
   2509    }
   2510 
   2511    // Rest of binary operators.
   2512    // Scalar relational operators.
   2513    binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests');
   2514    funcInfoGroups.push(binary);
   2515 
   2516    binary.push(op('less', '<', B, [v(F, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0),
   2517        all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThan).scalar}));
   2518    binary.push(op('less', '<', B, [v(I, -5.0, 5.0), v(I, -5.0, 5.0)], f(1.0), f(0.0),
   2519        all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThan, gluShaderUtil.DataType.INT,
   2520        gluShaderUtil.DataType.INT).scalar}));
   2521    binary.push(op('less', '<', B, [v(U, 0.0, 16.0), v(U, 0.0, 16.0)], f(1.0), f(0.0),
   2522        all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThan, gluShaderUtil.DataType.UINT,
   2523        gluShaderUtil.DataType.UINT).scalar}));
   2524    binary.push(op('less_or_equal', '<=', B, [v(F, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0),
   2525        all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThanEqual).scalar}));
   2526    binary.push(op('less_or_equal', '<=', B, [v(I, -5.0, 5.0), v(I, -5.0, 5.0)], f(1.0), f(0.0),
   2527        all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThanEqual, gluShaderUtil.DataType.INT,
   2528        gluShaderUtil.DataType.INT).scalar}));
   2529    binary.push(op('less_or_equal', '<=', B, [v(U, 0.0, 16.0), v(U, 0.0, 16.0)], f(1.0), f(0.0),
   2530        all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThanEqual, gluShaderUtil.DataType.UINT,
   2531        gluShaderUtil.DataType.UINT).scalar}));
   2532    binary.push(op('greater', '>', B, [v(F, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0),
   2533        all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThan).scalar}));
   2534    binary.push(op('greater', '>', B, [v(I, -5.0, 5.0), v(I, -5.0, 5.0)], f(1.0), f(0.0),
   2535        all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThan, gluShaderUtil.DataType.INT,
   2536        gluShaderUtil.DataType.INT).scalar}));
   2537    binary.push(op('greater', '>', B, [v(U, 0.0, 16.0), v(U, 0.0, 16.0)], f(1.0), f(0.0),
   2538        all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThan, gluShaderUtil.DataType.UINT,
   2539        gluShaderUtil.DataType.UINT).scalar}));
   2540    binary.push(op('greater_or_equal', '>=', B, [v(F, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0),
   2541        all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThanEqual).scalar}));
   2542    binary.push(op('greater_or_equal', '>=', B, [v(I, -5.0, 5.0), v(I, -5.0, 5.0)], f(1.0), f(0.0),
   2543        all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThanEqual, gluShaderUtil.DataType.INT,
   2544        gluShaderUtil.DataType.INT).scalar}));
   2545    binary.push(op('greater_or_equal', '>=', B, [v(U, 0.0, 16.0), v(U, 0.0, 16.0)], f(1.0), f(0.0),
   2546        all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThanEqual, gluShaderUtil.DataType.UINT,
   2547        gluShaderUtil.DataType.UINT).scalar}));
   2548 
   2549    binary.push(op('equal', '==', B, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(1.0), f(0.0),
   2550        all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(allEqual)));
   2551    binary.push(op('equal', '==', B, [v(IGT, -5.5, 4.7), v(IGT, -2.1, 0.1)], f(1.0), f(0.0),
   2552        all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(allEqual, gluShaderUtil.DataType.INT,
   2553        gluShaderUtil.DataType.INT)));
   2554    binary.push(op('equal', '==', B, [v(UGT, 0.0, 8.0), v(UGT, 3.5, 4.5)], f(1.0), f(0.0),
   2555        all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(allEqual, gluShaderUtil.DataType.UINT,
   2556        gluShaderUtil.DataType.UINT)));
   2557    binary.push(op('equal', '==', B, [v(BGT, -2.1, 2.1), v(BGT, -1.1, 3.0)], f(1.0), f(0.0),
   2558        na, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(allEqual, gluShaderUtil.DataType.BOOL,
   2559        gluShaderUtil.DataType.BOOL)));
   2560    binary.push(op('not_equal', '!=', B, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(1.0), f(0.0),
   2561        all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(anyNotEqual)));
   2562    binary.push(op('not_equal', '!=', B, [v(IGT, -5.5, 4.7), v(IGT, -2.1, 0.1)], f(1.0), f(0.0),
   2563        all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(anyNotEqual, gluShaderUtil.DataType.INT,
   2564        gluShaderUtil.DataType.INT)));
   2565    binary.push(op('not_equal', '!=', B, [v(UGT, 0.0, 8.0), v(UGT, 3.5, 4.5)], f(1.0), f(0.0),
   2566        all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(anyNotEqual, gluShaderUtil.DataType.UINT,
   2567        gluShaderUtil.DataType.UINT)));
   2568    binary.push(op('not_equal', '!=', B, [v(BGT, -2.1, 2.1), v(BGT, -1.1, 3.0)], f(1.0), f(0.0),
   2569        na, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(anyNotEqual, gluShaderUtil.DataType.BOOL,
   2570        gluShaderUtil.DataType.BOOL)));
   2571 
   2572    // Logical operators.
   2573    binary.push(op('logical_and', '&&', B, [v(B, -1.0, 1.0), v(B, -1.0, 1.0)], f(1.0), f(0.0),
   2574        na, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(logicalAnd, gluShaderUtil.DataType.BOOL,
   2575        gluShaderUtil.DataType.BOOL).scalar}));
   2576    binary.push(op('logical_or', '||', B, [v(B, -1.0, 1.0), v(B, -1.0, 1.0)], f(1.0), f(0.0),
   2577        na, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(logicalOr, gluShaderUtil.DataType.BOOL,
   2578        gluShaderUtil.DataType.BOOL).scalar}));
   2579    binary.push(op('logical_xor', '^^', B, [v(B, -1.0, 1.0), v(B, -1.0, 1.0)], f(1.0), f(0.0),
   2580        na, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(logicalXor, gluShaderUtil.DataType.BOOL,
   2581        gluShaderUtil.DataType.BOOL).scalar}));
   2582 
   2583    // 8.1 Angle and Trigonometry Functions.
   2584    var trig = new es3fShaderOperatorTests.BuiltinFuncGroup("angle_and_trigonometry", "Angle and trigonometry function tests.");
   2585    funcInfoGroups.push(trig);
   2586    op = es3fShaderOperatorTests.builtinFunctionInfo;
   2587    trig.push(op("radians", "radians", GT, [v(GT, -1.0, 1.0)], f(25.0), f(0.5),
   2588        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(radians)));
   2589    trig.push(op("degrees", "degrees", GT, [v(GT, -1.0, 1.0)], f(0.04), f(0.5),
   2590        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(degrees)));
   2591    trig.push(op("sin", "sin", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5),
   2592        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sin)));
   2593    trig.push(op("sin", "sin", GT, [v(GT, -1.5, 1.5)], f(0.5), f(0.5),
   2594        lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sin)));
   2595    trig.push(op("cos", "cos", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5),
   2596        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.cos)));
   2597    trig.push(op("cos", "cos", GT, [v(GT, -1.5, 1.5)], f(0.5), f(0.5),
   2598        lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.cos)));
   2599    trig.push(op("tan", "tan", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5),
   2600        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.tan)));
   2601    trig.push(op("tan", "tan", GT, [v(GT, -1.5, 5.5)], f(0.5), f(0.5),
   2602        lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.tan)));
   2603 
   2604    trig = new es3fShaderOperatorTests.BuiltinFuncGroup("angle_and_trigonometry", "Angle and trigonometry function tests.");
   2605    funcInfoGroups.push(trig);
   2606    trig.push(op("asin", "asin", GT, [v(GT, -1.0, 1.0)], f(1.0), f(0.0),
   2607        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.asin)));
   2608    trig.push(op("acos", "acos", GT, [v(GT, -1.0, 1.0)], f(1.0), f(0.0),
   2609        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.acos)));
   2610    trig.push(op("atan", "atan", GT, [v(GT, -4.0, 4.0)], f(0.5), f(0.5),
   2611        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.atan)));
   2612    trig.push(op("atan2", "atan", GT, [v(GT, -4.0, 4.0), v(GT, 0.5, 2.0)], f(0.5), f(0.5),
   2613        mediumhighp, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.atan2)));
   2614 
   2615    trig = new es3fShaderOperatorTests.BuiltinFuncGroup("angle_and_trigonometry", "Angle and trigonometry function tests.");
   2616    funcInfoGroups.push(trig);
   2617    trig.push(op("sinh", "sinh", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5),
   2618        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sinh)));
   2619    trig.push(op("sinh", "sinh", GT, [v(GT, -1.5, 1.5)], f(0.5), f(0.5),
   2620        lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sinh)));
   2621    trig.push(op("cosh", "cosh", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5),
   2622        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.cosh)));
   2623    trig.push(op("cosh", "cosh", GT, [v(GT, -1.5, 1.5)], f(0.5), f(0.5),
   2624        lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.cosh)));
   2625    trig.push(op("tanh", "tanh", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5),
   2626        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.tanh)));
   2627    trig.push(op("tanh", "tanh", GT, [v(GT, -1.5, 5.5)], f(0.5), f(0.5),
   2628        lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.tanh)));
   2629 
   2630    trig = new es3fShaderOperatorTests.BuiltinFuncGroup("angle_and_trigonometry", "Angle and trigonometry function tests.");
   2631    funcInfoGroups.push(trig);
   2632    trig.push(op("asinh", "asinh", GT, [v(GT, -1.0, 1.0)], f(1.0), f(0.0),
   2633        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.asinh)));
   2634    trig.push(op("acosh", "acosh", GT, [v(GT, 1.0, 2.2)], f(1.0), f(0.0),
   2635        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.acosh)));
   2636    // Results are undefined if |x| >= 1, so it diverses from C++ version here.
   2637    trig.push(op("atanh", "atanh", GT, [v(GT, -0.99, 0.99)], f(1.0), f(0.0),
   2638        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.atanh)));
   2639 
   2640    // 8.2 Exponential Functions.
   2641    var exps = new es3fShaderOperatorTests.BuiltinFuncGroup("exponential", "Exponential function tests");
   2642    exps.push(op("pow", "pow", GT, [v(GT, 0.1, 8.0), v(GT, -4.0, 2.0)], f(1.0), f(0.0),
   2643        mediumhighp, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.pow)));
   2644    exps.push(op("exp", "exp", GT, [v(GT, -6.0, 3.0)], f(0.5), f(0.0),
   2645        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.exp)));
   2646    exps.push(op("log", "log", GT, [v(GT, 0.1, 10.0)], f(0.5), f(0.3),
   2647        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.log)));
   2648    exps.push(op("exp2", "exp2", GT, [v(GT, -7.0, 2.0)], f(1.0), f(0.0),
   2649        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(exp2)));
   2650    exps.push(op("log2", "log2", GT, [v(GT, 0.1, 10.0)], f(1.0), f(0.0),
   2651        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.log2)));
   2652    exps.push(op("sqrt", "sqrt", GT, [v(GT, 0.0, 10.0)], f(0.3), f(0.0),
   2653        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sqrt)));
   2654    exps.push(op("inversesqrt", "inversesqrt", GT, [v(GT, 0.5, 10.0)], f(1.0), f(0.0),
   2655        mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(inverseSqrt)));
   2656 
   2657    funcInfoGroups.push(exps);
   2658 
   2659    // 8.3 Common Functions.
   2660    var comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
   2661    funcInfoGroups.push(comm);
   2662    comm.push(op("abs", "abs", GT, [v(GT, -2.0, 2.0)], f(0.5), f(0.5),
   2663        all, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.abs)));
   2664    comm.push(op("sign", "sign", GT, [v(GT, -1.5, 1.5)], f(0.3), f(0.5),
   2665        all, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sign)));
   2666    comm.push(op("floor", "floor", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.7),
   2667        all, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.floor)));
   2668    comm.push(op("trunc", "trunc", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.7),
   2669        all, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.trunc)));
   2670    comm.push(op("round", "round", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.7),
   2671        all, es3fShaderOperatorTests.unaryGenTypeFuncs(roundToEven)));
   2672 
   2673    comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
   2674    funcInfoGroups.push(comm);
   2675 
   2676    comm.push(op("roundEven", "roundEven", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.7),
   2677        all, es3fShaderOperatorTests.unaryGenTypeFuncs(roundToEven)));
   2678    comm.push(op("ceil", "ceil", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.5),
   2679        all, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.ceil)));
   2680    comm.push(op("fract", "fract", GT, [v(GT, -1.5, 1.5)], f(0.8), f(0.1),
   2681        all, es3fShaderOperatorTests.unaryGenTypeFuncs(fract)));
   2682    comm.push(op("mod", "mod", GT, [v(GT, -2.0, 2.0), v(GT, 0.9, 6.0)], f(0.5), f(0.5),
   2683        mediumhighp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.mod)));
   2684    comm.push(op("mod", "mod", GT, [v(FV, -2.0, 2.0), v(F, 0.9, 6.0)], f(0.5), f(0.5),
   2685        mediumhighp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.modScale)));
   2686 
   2687    comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
   2688    funcInfoGroups.push(comm);
   2689 
   2690    comm.push(op("min", "min", GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(0.5), f(0.5),
   2691        all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.min)));
   2692    comm.push(op("min", "min", GT, [v(FV, -1.0, 1.0), v(F, -1.0, 1.0)], f(0.5), f(0.5),
   2693        all, es3fShaderOperatorTests.binaryVecScalarFuncs(minVecScalar)));
   2694    comm.push(op("min", "min", IGT, [v(IGT, -4.0, 4.0), v(IGT, -4.0, 4.0)], f(0.125), f(0.5),
   2695        all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.min, gluShaderUtil.DataType.INT,
   2696        gluShaderUtil.DataType.INT)));
   2697    comm.push(op("min", "min", IGT, [v(IV, -4.0, 4.0), v(I, -4.0, 4.0)], f(0.125), f(0.5),
   2698        all, es3fShaderOperatorTests.binaryVecScalarFuncs(minVecScalar, gluShaderUtil.DataType.INT,
   2699        gluShaderUtil.DataType.INT)));
   2700    comm.push(op("min", "min", UGT, [v(UGT, 0.0, 8.0), v(UGT, 0.0, 8.0)], f(0.125), f(0.0),
   2701        all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.min, gluShaderUtil.DataType.INT,
   2702        gluShaderUtil.DataType.INT)));
   2703 
   2704    comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
   2705    funcInfoGroups.push(comm);
   2706 
   2707    comm.push(op("min", "min", UGT, [v(UV, 0.0, 8.0), v(U, 0.0, 8.0)], f(0.125), f(0.0),
   2708        all, es3fShaderOperatorTests.binaryVecScalarFuncs(minVecScalar, gluShaderUtil.DataType.UINT,
   2709        gluShaderUtil.DataType.UINT)));
   2710    comm.push(op("max", "max", GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(0.5), f(0.5),
   2711        all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.max)));
   2712    comm.push(op("max", "max", GT, [v(FV, -1.0, 1.0), v(F, -1.0, 1.0)], f(0.5), f(0.5),
   2713        all, es3fShaderOperatorTests.binaryVecScalarFuncs(maxVecScalar)));
   2714    comm.push(op("max", "max", IGT, [v(IGT, -4.0, 4.0), v(IGT, -4.0, 4.0)], f(0.125), f(0.5),
   2715        all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.max, gluShaderUtil.DataType.INT,
   2716        gluShaderUtil.DataType.INT)));
   2717    comm.push(op("max", "max", IGT, [v(IV, -4.0, 4.0), v(I, -4.0, 4.0)], f(0.125), f(0.5),
   2718        all, es3fShaderOperatorTests.binaryVecScalarFuncs(maxVecScalar, gluShaderUtil.DataType.INT,
   2719        gluShaderUtil.DataType.INT)));
   2720 
   2721    comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
   2722    funcInfoGroups.push(comm);
   2723 
   2724    comm.push(op("max", "max", UGT, [v(UGT, 0.0, 8.0), v(UGT, 0.0, 8.0)], f(0.125), f(0.0),
   2725        all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.max, gluShaderUtil.DataType.INT,
   2726        gluShaderUtil.DataType.INT)));
   2727    comm.push(op("max", "max", UGT, [v(UV, 0.0, 8.0), v(U, 0.0, 8.0)], f(0.125), f(0.0),
   2728        all, es3fShaderOperatorTests.binaryVecScalarFuncs(maxVecScalar, gluShaderUtil.DataType.UINT,
   2729        gluShaderUtil.DataType.UINT)));
   2730    comm.push(op("clamp", "clamp", GT, [v(GT, -1.0, 1.0), v(GT, -0.5, 0.5), v(GT, 0.5, 1.0)], f(0.5), f(0.5),
   2731        all, es3fShaderOperatorTests.ternaryGenTypeFuncs(deMath.clamp)));
   2732    comm.push(op("clamp", "clamp", GT, [v(FV, -1.0, 1.0), v(F, -0.5, 0.5), v(F, 0.5, 1.0)], f(0.5), f(0.5),
   2733        all, es3fShaderOperatorTests.ternaryVecScalarScalarFuncs(clampVecScalarScalar)));
   2734    comm.push(op("clamp", "clamp", IGT, [v(IGT, -4.0, 4.0), v(IGT, -2.0, 2.0), v(IGT, 2.0, 4.0)], f(0.125), f(0.5),
   2735        all, es3fShaderOperatorTests.ternaryGenTypeFuncs(deMath.clamp, gluShaderUtil.DataType.INT,
   2736        gluShaderUtil.DataType.INT)));
   2737 
   2738    comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
   2739    funcInfoGroups.push(comm);
   2740 
   2741    comm.push(op("clamp", "clamp", IGT, [v(IGT, -4.0, 4.0), v(I, -2.0, 2.0), v(I, 2.0, 4.0)], f(0.125), f(0.5),
   2742        all, es3fShaderOperatorTests.ternaryVecScalarScalarFuncs(clampVecScalarScalar, gluShaderUtil.DataType.INT,
   2743        gluShaderUtil.DataType.INT)));
   2744    comm.push(op("clamp", "clamp", UGT, [v(UGT, 0.0, 8.0), v(UGT, 2.0, 6.0), v(UGT, 6.0, 8.0)], f(0.125), f(0.0),
   2745        all, es3fShaderOperatorTests.ternaryGenTypeFuncs(deMath.clamp, gluShaderUtil.DataType.UINT,
   2746        gluShaderUtil.DataType.UINT)));
   2747    comm.push(op("clamp", "clamp", UGT, [v(UV, 0.0, 8.0), v(U, 2.0, 6.0), v(U, 6.0, 8.0)], f(0.125), f(0.0),
   2748        all, es3fShaderOperatorTests.ternaryVecScalarScalarFuncs(clampVecScalarScalar, gluShaderUtil.DataType.UINT,
   2749        gluShaderUtil.DataType.UINT)));
   2750    comm.push(op("mix", "mix", GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0), v(GT, 0.0, 1.0)], f(0.5), f(0.5),
   2751        all, es3fShaderOperatorTests.ternaryGenTypeFuncs(mix)));
   2752    comm.push(op("mix", "mix", GT, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0), v(F, 0.0, 1.0)], f(0.5), f(0.5),
   2753        all, es3fShaderOperatorTests.ternaryVecVecScalarFuncs(mixVecVecScalar)));
   2754 
   2755    comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
   2756    funcInfoGroups.push(comm);
   2757 
   2758    comm.push(op("step", "step", GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 0.0)], f(0.5), f(0.25),
   2759        all, es3fShaderOperatorTests.binaryGenTypeFuncs(step)));
   2760    comm.push(op("step", "step", GT, [v(F, -1.0, 1.0), v(FV, -1.0, 0.0)], f(0.5), f(0.25),
   2761        all, es3fShaderOperatorTests.binaryScalarVecFuncs(stepScalarVec)));
   2762    comm.push(op("smoothstep", "smoothstep", GT, [v(GT, -0.5, 0.0), v(GT, 0.1, 1.0), v(GT, -1.0, 1.0)], f(0.5), f(0.5),
   2763        all, es3fShaderOperatorTests.ternaryGenTypeFuncs(smoothStep)));
   2764    comm.push(op("smoothstep", "smoothstep", GT, [v(F, -0.5, 0.0), v(F, 0.1, 1.0), v(FV, -1.0, 1.0)], f(0.5), f(0.5),
   2765        all, es3fShaderOperatorTests.ternaryScalarScalarVecFuncs(smoothStepScalarScalarVec)));
   2766 
   2767    // 8.4 Geometric Functions.
   2768    var geom = new es3fShaderOperatorTests.BuiltinFuncGroup("geometric", "Geometric function tests.");
   2769    geom.push(op("length", "length", F, [v(GT, -5.0, 5.0)], f(0.1), f(0.5),
   2770        mediumhighp, es3fShaderOperatorTests.unaryScalarGenTypeFuncs(length)));
   2771    geom.push(op("distance", "distance", F, [v(GT, -5.0, 5.0), v(GT, -5.0, 5.0)], f(0.1), f(0.5),
   2772        mediumhighp, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(distance)));
   2773    geom.push(op("dot", "dot", F, [v(GT, -5.0, 5.0), v(GT, -5.0, 5.0)], f(0.1), f(0.5),
   2774        mediumhighp, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(dot)));
   2775    geom.push(op("cross", "cross", V3, [v(GT, -5.0, 5.0), v(GT, -5.0, 5.0)], f(0.1), f(0.5),
   2776        mediumhighp, {vec3: es3fShaderOperatorTests.binaryVecVecFuncs(cross).vec3}));
   2777    geom.push(op("normalize", "normalize", GT, [v(GT, 0.1, 4.0)], f(0.5), f(0.5),
   2778        mediumhighp, es3fShaderOperatorTests.unaryArrayFuncs(normalize)));
   2779    geom.push(op("faceforward", "faceforward", GT, [v(GT, -5.0, 5.0), v(GT, -5.0, 5.0), v(GT, -1.0, 1.0)], f(0.5), f(0.5),
   2780        mediumhighp, es3fShaderOperatorTests.ternaryVecVecVecFuncs(faceforward)));
   2781    geom.push(op("reflect", "reflect", GT, [v(GT, -0.8, -0.5), v(GT, 0.5, 0.8)], f(0.5), f(0.5),
   2782        mediumhighp, es3fShaderOperatorTests.binaryVecVecFuncs(reflect)));
   2783    geom.push(op("refract", "refract", GT, [v(GT, -0.8, 1.2), v(GT, -1.1, 0.5), v(F, 0.2, 1.5)], f(0.5), f(0.5),
   2784        mediumhighp, es3fShaderOperatorTests.ternaryVecVecScalarFuncs(refract)));
   2785 
   2786    funcInfoGroups.push(geom);
   2787 
   2788    // 8.6 Vector Relational Functions.
   2789    var floatComp = new es3fShaderOperatorTests.BuiltinFuncGroup("float_compare", "Floating point comparison tests.");
   2790    floatComp.push(op("lessThan", "lessThan", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
   2791        all, es3fShaderOperatorTests.binaryVecVecFuncs(lessThanVec)));
   2792    floatComp.push(op("lessThanEqual", "lessThanEqual", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
   2793        all, es3fShaderOperatorTests.binaryVecVecFuncs(lessThanEqualVec)));
   2794    floatComp.push(op("greaterThan", "greaterThan", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
   2795        all, es3fShaderOperatorTests.binaryVecVecFuncs(greaterThanVec)));
   2796    floatComp.push(op("greaterThanEqual", "greaterThanEqual", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
   2797        all, es3fShaderOperatorTests.binaryVecVecFuncs(greaterThanEqualVec)));
   2798    floatComp.push(op("equal", "equal", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
   2799        all, es3fShaderOperatorTests.binaryVecVecFuncs(allEqualVec)));
   2800    floatComp.push(op("notEqual", "notEqual", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
   2801        all, es3fShaderOperatorTests.binaryVecVecFuncs(anyNotEqualVec)));
   2802 
   2803    funcInfoGroups.push(floatComp);
   2804 
   2805    var intComp = new es3fShaderOperatorTests.BuiltinFuncGroup("int_compare", "Integer comparison tests.");
   2806    intComp.push(op("lessThan", "lessThan", BV, [v(IV, 5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0),
   2807        all, es3fShaderOperatorTests.binaryVecVecFuncs(lessThanVec, gluShaderUtil.DataType.INT,
   2808        gluShaderUtil.DataType.INT)));
   2809    intComp.push(op("lessThanEqual", "lessThanEqual", BV, [v(IV, -5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0),
   2810        all, es3fShaderOperatorTests.binaryVecVecFuncs(lessThanEqualVec, gluShaderUtil.DataType.INT,
   2811        gluShaderUtil.DataType.INT)));
   2812    intComp.push(op("greaterThan", "greaterThan", BV, [v(IV, -5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0),
   2813        all, es3fShaderOperatorTests.binaryVecVecFuncs(greaterThanVec, gluShaderUtil.DataType.INT,
   2814        gluShaderUtil.DataType.INT)));
   2815    intComp.push(op("greaterThanEqual", "greaterThanEqual", BV, [v(IV, -5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0),
   2816        all, es3fShaderOperatorTests.binaryVecVecFuncs(greaterThanEqualVec, gluShaderUtil.DataType.INT,
   2817        gluShaderUtil.DataType.INT)));
   2818    intComp.push(op("equal", "equal", BV, [v(IV, -5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0),
   2819        all, es3fShaderOperatorTests.binaryVecVecFuncs(allEqualVec, gluShaderUtil.DataType.INT,
   2820        gluShaderUtil.DataType.INT)));
   2821    intComp.push(op("notEqual", "notEqual", BV, [v(IV, -5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0),
   2822        all, es3fShaderOperatorTests.binaryVecVecFuncs(anyNotEqualVec, gluShaderUtil.DataType.INT,
   2823        gluShaderUtil.DataType.INT)));
   2824 
   2825    funcInfoGroups.push(intComp);
   2826 
   2827    var boolComp = new es3fShaderOperatorTests.BuiltinFuncGroup("bool_compare", "Boolean comparison tests.");
   2828    var evalBoolEqual = es3fShaderOperatorTests.binaryVecVecFuncs(allEqualVec, gluShaderUtil.DataType.BOOL,
   2829        gluShaderUtil.DataType.BOOL);
   2830    var evalBoolNotEqual = es3fShaderOperatorTests.binaryVecVecFuncs(anyNotEqualVec, gluShaderUtil.DataType.BOOL,
   2831        gluShaderUtil.DataType.BOOL);
   2832    var evalBoolAny = es3fShaderOperatorTests.unaryBooleanGenTypeFuncs(boolAny, gluShaderUtil.DataType.BOOL,
   2833        gluShaderUtil.DataType.BOOL);
   2834    evalBoolAny.scalar = null;
   2835    var evalBoolAll = es3fShaderOperatorTests.unaryBooleanGenTypeFuncs(boolAll, gluShaderUtil.DataType.BOOL,
   2836        gluShaderUtil.DataType.BOOL);
   2837    evalBoolAll.scalar = null;
   2838    var evalBoolNot = es3fShaderOperatorTests.unaryArrayFuncs(boolNotVec, gluShaderUtil.DataType.BOOL,
   2839        gluShaderUtil.DataType.BOOL);
   2840    evalBoolNot.scalar = null;
   2841 
   2842    boolComp.push(op("equal", "equal", BV, [v(BV, -5.2, 4.9), v(BV, -5.0, 5.0)], f(1.0), f(0.0),
   2843        na, evalBoolEqual));
   2844    boolComp.push(op("notEqual", "notEqual", BV, [v(BV, -5.2, 4.9), v(BV, -5.0, 5.0)], f(1.0), f(0.0),
   2845        na, evalBoolNotEqual));
   2846    boolComp.push(op("any", "any", B, [v(BV, -1.0, 0.3)], f(1.0), f(0.0),
   2847        na, evalBoolAny));
   2848    boolComp.push(op("all", "all", B, [v(BV, -0.3, 1.0)], f(1.0), f(0.0),
   2849        na, evalBoolAll));
   2850    boolComp.push(op("not", "not", BV, [v(BV, -1.0, 1.0)], f(1.0), f(0.0),
   2851        na, evalBoolNot));
   2852 
   2853    funcInfoGroups.push(boolComp);
   2854 
   2855    var s_shaderTypes = [
   2856        gluShaderProgram.shaderType.VERTEX,
   2857        gluShaderProgram.shaderType.FRAGMENT
   2858    ];
   2859 
   2860    var s_floatTypes = [
   2861        gluShaderUtil.DataType.FLOAT,
   2862        gluShaderUtil.DataType.FLOAT_VEC2,
   2863        gluShaderUtil.DataType.FLOAT_VEC3,
   2864        gluShaderUtil.DataType.FLOAT_VEC4
   2865    ];
   2866 
   2867    var s_intTypes = [
   2868        gluShaderUtil.DataType.INT,
   2869        gluShaderUtil.DataType.INT_VEC2,
   2870        gluShaderUtil.DataType.INT_VEC3,
   2871        gluShaderUtil.DataType.INT_VEC4
   2872    ];
   2873 
   2874    var s_uintTypes = [
   2875        gluShaderUtil.DataType.UINT,
   2876        gluShaderUtil.DataType.UINT_VEC2,
   2877        gluShaderUtil.DataType.UINT_VEC3,
   2878        gluShaderUtil.DataType.UINT_VEC4
   2879    ];
   2880 
   2881    var s_boolTypes = [
   2882        gluShaderUtil.DataType.BOOL,
   2883        gluShaderUtil.DataType.BOOL_VEC2,
   2884        gluShaderUtil.DataType.BOOL_VEC3,
   2885        gluShaderUtil.DataType.BOOL_VEC4
   2886    ];
   2887 
   2888    for (var outerGroupNdx = 0; outerGroupNdx < funcInfoGroups.length; outerGroupNdx++) {
   2889        // Create outer group.
   2890        var outerGroupInfo = funcInfoGroups[outerGroupNdx];
   2891        var outerGroup = new tcuTestCase.DeqpTest(outerGroupInfo.name, outerGroupInfo.description);
   2892        this.addChild(outerGroup);
   2893 
   2894        // Only create new group if name differs from previous one.
   2895        var innerGroup = null;
   2896 
   2897        for (var funcInfoNdx = 0; funcInfoNdx < outerGroupInfo.funcInfos.length; funcInfoNdx++) {
   2898            var funcInfo = outerGroupInfo.funcInfos[funcInfoNdx];
   2899            var shaderFuncName = funcInfo.shaderFuncName;
   2900            var isBoolCase = (funcInfo.precision == es3fShaderOperatorTests.Precision.None);
   2901            var isBoolOut = es3fShaderOperatorTests.isBoolType(funcInfo.outValue);
   2902            var isIntOut = es3fShaderOperatorTests.isIntType(funcInfo.outValue);
   2903            var isUintOut = es3fShaderOperatorTests.isUintType(funcInfo.outValue);
   2904            var isFloatOut = !isBoolOut && !isIntOut && !isUintOut;
   2905 
   2906            if (!innerGroup || (innerGroup.name != funcInfo.caseName)) {
   2907                var groupDesc = 'Built-in function ' + shaderFuncName + '() tests.';
   2908                innerGroup = new tcuTestCase.DeqpTest(funcInfo.caseName, groupDesc);
   2909                outerGroup.addChild(innerGroup);
   2910            }
   2911 
   2912            for (var inScalarSize = 1; inScalarSize <= 4; inScalarSize++) {
   2913                var outScalarSize = ((funcInfo.outValue == es3fShaderOperatorTests.ValueType.FLOAT) || (funcInfo.outValue == es3fShaderOperatorTests.ValueType.BOOL)) ? 1 : inScalarSize; // \todo [petri] Int.
   2914                var outDataType = isFloatOut ? s_floatTypes[outScalarSize - 1] :
   2915                                            isIntOut ? s_intTypes[outScalarSize - 1] :
   2916                                            isUintOut ? s_uintTypes[outScalarSize - 1] :
   2917                                            isBoolOut ? s_boolTypes[outScalarSize - 1] :
   2918                                            undefined;
   2919 
   2920                var evalFunc = null;
   2921                if (inScalarSize == 1) evalFunc = funcInfo.evalFunctions.scalar;
   2922                else if (inScalarSize == 2) evalFunc = funcInfo.evalFunctions.vec2;
   2923                else if (inScalarSize == 3) evalFunc = funcInfo.evalFunctions.vec3;
   2924                else if (inScalarSize == 4) evalFunc = funcInfo.evalFunctions.vec4;
   2925                else throw new Error('Invalid scalar size ' + inScalarSize);
   2926 
   2927                // Skip if no valid eval func.
   2928                // \todo [petri] Better check for V3 only etc. cases?
   2929                if (evalFunc == null)
   2930                    continue;
   2931 
   2932                var precisions = ['low', 'medium', 'high'];
   2933                for (var precId = 0; precId < precisions.length; precId++) {
   2934                    var precision = precisions[precId];
   2935                    if ((funcInfo.precision[precision]) ||
   2936                        (funcInfo.precision == es3fShaderOperatorTests.Precision.None && precision === 'medium')) { // use mediump interpolators for booleans
   2937                        var precisionPrefix = isBoolCase ? '' : precision + 'p_';
   2938 
   2939                        for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
   2940                            var shaderType = s_shaderTypes[shaderTypeNdx];
   2941                            var shaderSpec = new es3fShaderOperatorTests.ShaderDataSpec();
   2942                            var shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
   2943                            var isVertexCase = shaderType == gluShaderProgram.shaderType.VERTEX;
   2944                            var isUnaryOp = (funcInfo.inputs.length == 1);
   2945 
   2946                            // \note Data type names will be added to description and name in a following loop.
   2947                            var desc = 'Built-in function ' + shaderFuncName + '(';
   2948                            var name = precisionPrefix;
   2949 
   2950                            // Generate shader op.
   2951                            var shaderOp = 'res = ';
   2952 
   2953                            var precNames = [gluShaderUtil.precision.PRECISION_LOWP,
   2954                                             gluShaderUtil.precision.PRECISION_MEDIUMP,
   2955                                             gluShaderUtil.precision.PRECISION_HIGHP];
   2956                            // Setup shader data info.
   2957                            shaderSpec.numInputs = 0;
   2958                            shaderSpec.precision = isBoolCase ? undefined : precNames[precId];
   2959                            shaderSpec.output = outDataType;
   2960                            shaderSpec.resultScale = funcInfo.resultScale;
   2961                            shaderSpec.resultBias = funcInfo.resultBias;
   2962                            shaderSpec.referenceScale = funcInfo.referenceScale;
   2963                            shaderSpec.referenceBias = funcInfo.referenceBias;
   2964 
   2965                            if (funcInfo.type == es3fShaderOperatorTests.OperationType.OPERATOR) {
   2966                                if (isUnaryOp && funcInfo.isUnaryPrefix)
   2967                                    shaderOp += shaderFuncName;
   2968                            } else if (funcInfo.type == es3fShaderOperatorTests.OperationType.FUNCTION)
   2969                                shaderOp += shaderFuncName + '(';
   2970                            else // SIDE_EFFECT_OPERATOR
   2971                                shaderOp += 'in0;\n\t';
   2972 
   2973                            for (var inputNdx = 0; inputNdx < funcInfo.inputs.length; inputNdx++) {
   2974                                var prevNdx = inputNdx > 0 ? inputNdx - 1 : funcInfo.inputs.length - 1;
   2975                                var prevValue = funcInfo.inputs[prevNdx];
   2976                                var value = funcInfo.inputs[inputNdx];
   2977 
   2978                                if (value.valueType == es3fShaderOperatorTests.ValueType.NONE)
   2979                                    continue; // Skip unused input.
   2980 
   2981                                var prevInScalarSize = es3fShaderOperatorTests.isScalarType(prevValue.valueType) ? 1 : inScalarSize;
   2982                                var prevInDataType = es3fShaderOperatorTests.isFloatType(prevValue.valueType) ? s_floatTypes[prevInScalarSize - 1] :
   2983                                                                    es3fShaderOperatorTests.isIntType(prevValue.valueType) ? s_intTypes[prevInScalarSize - 1] :
   2984                                                                    es3fShaderOperatorTests.isUintType(prevValue.valueType) ? s_uintTypes[prevInScalarSize - 1] :
   2985                                                                    es3fShaderOperatorTests.isBoolType(prevValue.valueType) ? s_boolTypes[prevInScalarSize - 1] :
   2986                                                                    undefined;
   2987 
   2988                                var curInScalarSize = es3fShaderOperatorTests.isScalarType(value.valueType) ? 1 : inScalarSize;
   2989                                var curInDataType = es3fShaderOperatorTests.isFloatType(value.valueType) ? s_floatTypes[curInScalarSize - 1] :
   2990                                                                    es3fShaderOperatorTests.isIntType(value.valueType) ? s_intTypes[curInScalarSize - 1] :
   2991                                                                    es3fShaderOperatorTests.isUintType(value.valueType) ? s_uintTypes[curInScalarSize - 1] :
   2992                                                                    es3fShaderOperatorTests.isBoolType(value.valueType) ? s_boolTypes[curInScalarSize - 1] :
   2993                                                                    undefined;
   2994 
   2995                                // Write input type(s) to case description and name.
   2996 
   2997                                if (inputNdx > 0)
   2998                                    desc += ', ';
   2999 
   3000                                desc += gluShaderUtil.getDataTypeName(curInDataType);
   3001 
   3002                                if (inputNdx == 0 || prevInDataType != curInDataType) // \note Only write input type to case name if different from previous input type (avoid overly long names).
   3003                                    name += gluShaderUtil.getDataTypeName(curInDataType) + '_';
   3004 
   3005                                // Generate op input source.
   3006 
   3007                                if (funcInfo.type == es3fShaderOperatorTests.OperationType.OPERATOR || funcInfo.type == es3fShaderOperatorTests.OperationType.FUNCTION) {
   3008                                    if (inputNdx != 0) {
   3009                                        if (funcInfo.type == es3fShaderOperatorTests.OperationType.OPERATOR && !isUnaryOp)
   3010                                            shaderOp += ' ' + shaderFuncName + ' ';
   3011                                        else
   3012                                            shaderOp += ', ';
   3013                                    }
   3014 
   3015                                    shaderOp += 'in' + inputNdx.toString(10);
   3016 
   3017                                    if (funcInfo.type == es3fShaderOperatorTests.OperationType.OPERATOR && isUnaryOp && !funcInfo.isUnaryPrefix)
   3018                                        shaderOp += shaderFuncName;
   3019                                } else{
   3020                                    if (inputNdx != 0 || (isUnaryOp && funcInfo.isUnaryPrefix))
   3021                                        shaderOp += (isUnaryOp ? '' : ' ') + shaderFuncName + (isUnaryOp ? '' : ' ');
   3022 
   3023                                    shaderOp += inputNdx == 0 ? 'res' : 'in' + inputNdx.toString(10); // \note in0 has already been assigned to res, so start from in1.
   3024 
   3025                                    if (isUnaryOp && !funcInfo.isUnaryPrefix)
   3026                                        shaderOp += shaderFuncName;
   3027                                }
   3028 
   3029                                // Fill in shader info.
   3030                                shaderSpec.inputs[shaderSpec.numInputs++] = new es3fShaderOperatorTests.ShaderValue(curInDataType, value.rangeMin, value.rangeMax);
   3031                            }
   3032 
   3033                            if (funcInfo.type == es3fShaderOperatorTests.OperationType.FUNCTION)
   3034                                shaderOp += ')';
   3035 
   3036                            shaderOp += ';';
   3037 
   3038                            desc += ').';
   3039                            name += shaderTypeName;
   3040 
   3041                            // Create the test case.
   3042                            innerGroup.addChild(new es3fShaderOperatorTests.ShaderOperatorCase(name, desc, isVertexCase, evalFunc, shaderOp, shaderSpec));
   3043                        }
   3044                    }
   3045                }
   3046            }
   3047        }
   3048    }
   3049 
   3050    // The ?: selection operator.
   3051 
   3052    var s_selectionInfo = [
   3053        gluShaderUtil.DataType.FLOAT,
   3054        gluShaderUtil.DataType.FLOAT_VEC2,
   3055        gluShaderUtil.DataType.FLOAT_VEC3,
   3056        gluShaderUtil.DataType.FLOAT_VEC4,
   3057        gluShaderUtil.DataType.INT,
   3058        gluShaderUtil.DataType.INT_VEC2,
   3059        gluShaderUtil.DataType.INT_VEC3,
   3060        gluShaderUtil.DataType.INT_VEC4,
   3061        gluShaderUtil.DataType.UINT,
   3062        gluShaderUtil.DataType.UINT_VEC2,
   3063        gluShaderUtil.DataType.UINT_VEC3,
   3064        gluShaderUtil.DataType.UINT_VEC4,
   3065        gluShaderUtil.DataType.BOOL,
   3066        gluShaderUtil.DataType.BOOL_VEC2,
   3067        gluShaderUtil.DataType.BOOL_VEC3,
   3068        gluShaderUtil.DataType.BOOL_VEC4
   3069    ];
   3070 
   3071    var selectionEvalFuncsFloat = es3fShaderOperatorTests.selectionFuncs(gluShaderUtil.DataType.FLOAT);
   3072    var selectionEvalFuncsInt = es3fShaderOperatorTests.selectionFuncs(gluShaderUtil.DataType.INT);
   3073    var selectionEvalFuncsUint = es3fShaderOperatorTests.selectionFuncs(gluShaderUtil.DataType.UINT);
   3074    var selectionEvalFuncsBool = es3fShaderOperatorTests.selectionFuncs(gluShaderUtil.DataType.BOOL);
   3075 
   3076    var selectionGroup = new tcuTestCase.DeqpTest('selection', 'Selection operator tests');
   3077    this.addChild(selectionGroup);
   3078 
   3079    for (var typeNdx = 0; typeNdx < s_selectionInfo.length; typeNdx++) {
   3080        var curType = s_selectionInfo[typeNdx];
   3081        var scalarSize = gluShaderUtil.getDataTypeScalarSize(curType);
   3082        var isBoolCase = gluShaderUtil.isDataTypeBoolOrBVec(curType);
   3083        var isFloatCase = gluShaderUtil.isDataTypeFloatOrVec(curType);
   3084        var isIntCase = gluShaderUtil.isDataTypeIntOrIVec(curType);
   3085        var isUintCase = gluShaderUtil.isDataTypeUintOrUVec(curType);
   3086        var dataTypeStr = gluShaderUtil.getDataTypeName(curType);
   3087 
   3088        var evalFuncs = selectionEvalFuncsFloat;
   3089        if (isBoolCase)
   3090            evalFuncs = selectionEvalFuncsBool;
   3091        else if (isIntCase)
   3092            evalFuncs = selectionEvalFuncsInt;
   3093        else if (isUintCase)
   3094            evalFuncs = selectionEvalFuncsUint;
   3095 
   3096        var evalFunc = evalFuncs[scalarSize];
   3097 
   3098        for (var prec in gluShaderUtil.precision) {
   3099            var precision = gluShaderUtil.precision[prec];
   3100            if (isBoolCase && precision != gluShaderUtil.precision.PRECISION_MEDIUMP) // Use mediump interpolators for booleans.
   3101                continue;
   3102 
   3103            var precisionStr = gluShaderUtil.getPrecisionName(precision);
   3104            var precisionPrefix = isBoolCase ? '' : (precisionStr + '_');
   3105 
   3106            for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
   3107                var shaderType = s_shaderTypes[shaderTypeNdx];
   3108                var shaderSpec = new es3fShaderOperatorTests.ShaderDataSpec();
   3109                var shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
   3110                var isVertexCase = shaderType == gluShaderProgram.shaderType.VERTEX;
   3111 
   3112                var name = precisionPrefix + dataTypeStr + '_' + shaderTypeName;
   3113 
   3114                shaderSpec.numInputs = 3;
   3115                shaderSpec.precision = isBoolCase ? undefined : precision;
   3116                shaderSpec.output = curType;
   3117                shaderSpec.resultScale = isBoolCase ? f(1.0) : isFloatCase ? f(0.5) : isUintCase ? f(0.5) : f(0.1);
   3118                shaderSpec.resultBias = isBoolCase ? f(0.0) : isFloatCase ? f(0.5) : isUintCase ? f(0.0) : f(0.5);
   3119                shaderSpec.referenceScale = shaderSpec.resultScale;
   3120                shaderSpec.referenceBias = shaderSpec.resultBias;
   3121 
   3122                var rangeMin = isBoolCase ? -1.0 : isFloatCase ? -1.0 : isUintCase ? 0.0 : -5.0;
   3123                var rangeMax = isBoolCase ? 1.0 : isFloatCase ? 1.0 : isUintCase ? 2.0 : 5.0;
   3124 
   3125                shaderSpec.inputs[0] = new es3fShaderOperatorTests.ShaderValue(gluShaderUtil.DataType.BOOL, f(-1.0), f(1.0));
   3126                shaderSpec.inputs[1] = new es3fShaderOperatorTests.ShaderValue(curType, f(rangeMin), f(rangeMax));
   3127                shaderSpec.inputs[2] = new es3fShaderOperatorTests.ShaderValue(curType, f(rangeMin), f(rangeMax));
   3128 
   3129                selectionGroup.addChild(new es3fShaderOperatorTests.ShaderOperatorCase(name, '', isVertexCase, evalFunc, 'res = in0 ? in1 : in2;', shaderSpec));
   3130            }
   3131        }
   3132    }
   3133 
   3134    // The sequence operator (comma).
   3135    /** @type {tcuTestCase.DeqpTest} */ var sequenceGroup = new tcuTestCase.DeqpTest('sequence', 'sequence');
   3136    this.addChild(sequenceGroup);
   3137 
   3138    /** @type {tcuTestCase.DeqpTest} */ var sequenceNoSideEffGroup = new tcuTestCase.DeqpTest('no_side_effects', 'Sequence tests without side-effects');
   3139    /** @type {tcuTestCase.DeqpTest} */ var sequenceSideEffGroup = new tcuTestCase.DeqpTest('side_effects', 'Sequence tests with side-effects');
   3140    sequenceGroup.addChild(sequenceNoSideEffGroup);
   3141    sequenceGroup.addChild(sequenceSideEffGroup);
   3142 
   3143    /**
   3144     * @struct
   3145     * @constructor
   3146     * @param {boolean} containsSideEffects
   3147     * @param {string} caseName
   3148     * @param {string} expressionStr
   3149     * @param {number} numInputs
   3150     * @param {Array<gluShaderUtil.DataType>} inputTypes
   3151     * @param {gluShaderUtil.DataType} resultType
   3152     * @param {glsShaderRenderCase.ShaderEvalFunc} evalFunc
   3153     */
   3154     var SequenceCase = function(containsSideEffects, caseName, expressionStr, numInputs, inputTypes, resultType, evalFunc) {
   3155         /** @type {boolean} */ this.containsSideEffects = containsSideEffects;
   3156         /** @type {string} */ this.caseName = caseName;
   3157         /** @type {string} */ this.expressionStr = expressionStr;
   3158         /** @type {number} */ this.numInputs = numInputs;
   3159         /** @type {Array<gluShaderUtil.DataType>} */ this.inputTypes = inputTypes;
   3160         /** @type {gluShaderUtil.DataType} */ this.resultType = resultType;
   3161         /** @type {glsShaderRenderCase.ShaderEvalFunc} */ this.evalFunc = evalFunc;
   3162    };
   3163 
   3164    /** @type {Array<SequenceCase>} */ var s_sequenceCases = [
   3165        new SequenceCase(false, 'vec4', 'in0, in2 + in1, in1 + in0', 3, [gluShaderUtil.DataType.FLOAT_VEC4, gluShaderUtil.DataType.FLOAT_VEC4, gluShaderUtil.DataType.FLOAT_VEC4], gluShaderUtil.DataType.FLOAT_VEC4, es3fShaderOperatorTests.evalSequenceNoSideEffCase0),
   3166        new SequenceCase(false, 'float_uint', 'in0 + in2, in1 + in1', 3, [gluShaderUtil.DataType.FLOAT, gluShaderUtil.DataType.UINT, gluShaderUtil.DataType.FLOAT], gluShaderUtil.DataType.UINT, es3fShaderOperatorTests.evalSequenceNoSideEffCase1),
   3167        new SequenceCase(false, 'bool_vec2', 'in0 && in1, in0, ivec2(vec2(in0) + in2)', 3, [gluShaderUtil.DataType.BOOL, gluShaderUtil.DataType.BOOL, gluShaderUtil.DataType.FLOAT_VEC2], gluShaderUtil.DataType.INT_VEC2, es3fShaderOperatorTests.evalSequenceNoSideEffCase2),
   3168        new SequenceCase(false, 'vec4_ivec4_bvec4', 'in0 + vec4(in1), in2, in1', 3, [gluShaderUtil.DataType.FLOAT_VEC4, gluShaderUtil.DataType.INT_VEC4, gluShaderUtil.DataType.BOOL_VEC4], gluShaderUtil.DataType.INT_VEC4, es3fShaderOperatorTests.evalSequenceNoSideEffCase3),
   3169 
   3170        new SequenceCase(true, 'vec4', 'in0++, in1 = in0 + in2, in2 = in1', 3, [gluShaderUtil.DataType.FLOAT_VEC4, gluShaderUtil.DataType.FLOAT_VEC4, gluShaderUtil.DataType.FLOAT_VEC4], gluShaderUtil.DataType.FLOAT_VEC4, es3fShaderOperatorTests.evalSequenceSideEffCase0),
   3171        new SequenceCase(true, 'float_uint', 'in1++, in0 = float(in1), in1 = uint(in0 + in2)', 3, [gluShaderUtil.DataType.FLOAT, gluShaderUtil.DataType.UINT, gluShaderUtil.DataType.FLOAT], gluShaderUtil.DataType.UINT, es3fShaderOperatorTests.evalSequenceSideEffCase1),
   3172        new SequenceCase(true, 'bool_vec2', 'in1 = in0, in2++, in2 = in2 + vec2(in1), ivec2(in2)', 3, [gluShaderUtil.DataType.BOOL, gluShaderUtil.DataType.BOOL, gluShaderUtil.DataType.FLOAT_VEC2], gluShaderUtil.DataType.INT_VEC2, es3fShaderOperatorTests.evalSequenceSideEffCase2),
   3173        new SequenceCase(true, 'vec4_ivec4_bvec4', 'in0 = in0 + vec4(in2), in1 = in1 + ivec4(in0), in1++', 3, [gluShaderUtil.DataType.FLOAT_VEC4, gluShaderUtil.DataType.INT_VEC4, gluShaderUtil.DataType.BOOL_VEC4], gluShaderUtil.DataType.INT_VEC4, es3fShaderOperatorTests.evalSequenceSideEffCase3)
   3174    ];
   3175 
   3176    for (var caseNdx = 0; caseNdx < s_sequenceCases.length; caseNdx++) {
   3177        for (var precision in gluShaderUtil.precision) {
   3178            for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
   3179                /** @type {gluShaderProgram.shaderType} */ var shaderType = s_shaderTypes[shaderTypeNdx];
   3180                /** @type {es3fShaderOperatorTests.ShaderDataSpec} */ var shaderSpec = new es3fShaderOperatorTests.ShaderDataSpec();
   3181                /** @type {string} */ var shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
   3182                /** @type {boolean} */ var isVertexCase = shaderType === gluShaderProgram.shaderType.VERTEX;
   3183 
   3184                /** @type {string} */ var name = gluShaderUtil.getPrecisionName(gluShaderUtil.precision[precision]) + '_' + s_sequenceCases[caseNdx].caseName + '_' + shaderTypeName;
   3185 
   3186                shaderSpec.numInputs = s_sequenceCases[caseNdx].numInputs;
   3187                shaderSpec.precision = gluShaderUtil.precision[precision];
   3188                shaderSpec.output = s_sequenceCases[caseNdx].resultType;
   3189                shaderSpec.resultScale = f(0.5);
   3190                shaderSpec.resultBias = f(0.0);
   3191                shaderSpec.referenceScale = shaderSpec.resultScale;
   3192                shaderSpec.referenceBias = shaderSpec.resultBias;
   3193 
   3194                for (var inputNdx = 0; inputNdx < s_sequenceCases[caseNdx].numInputs; inputNdx++) {
   3195                    /** @type {gluShaderUtil.DataType} */ var type = s_sequenceCases[caseNdx].inputTypes[inputNdx];
   3196                    /** @type {es3fShaderOperatorTests.FloatScalar} */ var rangeMin = gluShaderUtil.isDataTypeFloatOrVec(type) ?
   3197                        f(-0.5) : gluShaderUtil.isDataTypeIntOrIVec(type) ?
   3198                        f(-2.0) : gluShaderUtil.isDataTypeUintOrUVec(type) ?
   3199                        f(0.0) : f(-1.0);
   3200 
   3201                    /** @type {es3fShaderOperatorTests.FloatScalar} */ var rangeMax = gluShaderUtil.isDataTypeFloatOrVec(type) ?
   3202                        f(0.5) : gluShaderUtil.isDataTypeIntOrIVec(type) ?
   3203                        f(2.0) : gluShaderUtil.isDataTypeUintOrUVec(type) ?
   3204                        f(2.0) : f(1.0);
   3205 
   3206                    shaderSpec.inputs[inputNdx] = new es3fShaderOperatorTests.ShaderValue(type, rangeMin, rangeMax);
   3207                }
   3208 
   3209                /** @type {string} */ var expression = 'res = (' + s_sequenceCases[caseNdx].expressionStr + ');';
   3210 
   3211                if (s_sequenceCases[caseNdx].containsSideEffects)
   3212                    sequenceSideEffGroup.addChild(new es3fShaderOperatorTests.ShaderOperatorCase(name, '', isVertexCase, s_sequenceCases[caseNdx].evalFunc, expression, shaderSpec));
   3213                else
   3214                    sequenceNoSideEffGroup.addChild(new es3fShaderOperatorTests.ShaderOperatorCase(name, '', isVertexCase, s_sequenceCases[caseNdx].evalFunc, expression, shaderSpec));
   3215            }
   3216        }
   3217    }
   3218 
   3219 };
   3220 
   3221 /**
   3222 * Run test
   3223 * @param {WebGL2RenderingContext} context
   3224 */
   3225 es3fShaderOperatorTests.run = function(context, range) {
   3226    gl = context;
   3227 
   3228    const canvas = gl.canvas;
   3229    canvas.width = canvasWH;
   3230    canvas.height = canvasWH;
   3231 
   3232    //Set up Test Root parameters
   3233    var state = tcuTestCase.runner;
   3234    state.setRoot(new es3fShaderOperatorTests.ShaderOperatorTests());
   3235 
   3236    //Set up name and description of this test series.
   3237    setCurrentTestName(state.testCases.fullName());
   3238    description(state.testCases.getDescription());
   3239 
   3240    try {
   3241        if (range)
   3242            state.setRange(range);
   3243        //Run test cases
   3244        tcuTestCase.runTestCases();
   3245    }
   3246    catch (err) {
   3247        testFailedOptions('Failed to es3fShaderOperatorTests.run tests', false);
   3248        tcuTestCase.runner.terminate();
   3249    }
   3250 };
   3251 
   3252 });