diff options
Diffstat (limited to '')
-rw-r--r-- | dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderOperatorTests.js | 3252 |
1 files changed, 3252 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderOperatorTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderOperatorTests.js new file mode 100644 index 0000000000..5dfd0311d3 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderOperatorTests.js @@ -0,0 +1,3252 @@ +/*------------------------------------------------------------------------- + * drawElements Quality Program OpenGL ES Utilities + * ------------------------------------------------ + * + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +'use strict'; +goog.provide('functional.gles3.es3fShaderOperatorTests'); +goog.require('framework.common.tcuTestCase'); +goog.require('framework.opengl.gluShaderUtil'); +goog.require('framework.opengl.gluShaderProgram'); +goog.require('framework.delibs.debase.deMath'); +goog.require('modules.shared.glsShaderRenderCase'); +goog.require('framework.common.tcuMatrix'); + +goog.scope(function() { +var es3fShaderOperatorTests = functional.gles3.es3fShaderOperatorTests; +var tcuTestCase = framework.common.tcuTestCase; +var gluShaderUtil = framework.opengl.gluShaderUtil; +var gluShaderProgram = framework.opengl.gluShaderProgram; +var deMath = framework.delibs.debase.deMath; +var glsShaderRenderCase = modules.shared.glsShaderRenderCase; +var tcuMatrix = framework.common.tcuMatrix; + +/** @const */ es3fShaderOperatorTests.MAX_INPUTS = 3; + +let canvasWH = 256; +if (tcuTestCase.isQuickMode()) { + canvasWH = 32; +} + +es3fShaderOperatorTests.stringJoin = function(elems, delim) { + var result = ''; + for (var i = 0; i < elems.length; i++) + result += (i > 0 ? delim : '') + elems[i]; + return result; +}; + +es3fShaderOperatorTests.twoValuedVec4 = function(first, second, firstMask) { + var elems = []; + for (var i = 0; i < 4; i++) + elems[i] = firstMask[i] ? first : second; + + return 'vec4(' + es3fShaderOperatorTests.stringJoin(elems, ', ') + ')'; +}; + +var setParentClass = function(child, parent) { + child.prototype = Object.create(parent.prototype); + child.prototype.constructor = child; +}; + +var negate = function(x) { + return -x; +}; + +var addOne = function(x) { + return x + 1; +}; + +var subOne = function(x) { + return x - 1; +}; + +/** + * @param {number} a + * @param {number} b + */ +var add = function(a, b) { + return a + b; +}; + +/** + * @param {number} a + * @param {number} b + */ +var sub = function(a, b) { + return a - b; +}; + +/** + * @param {number} a + * @param {number} b + */ +var mul = function(a, b) { + return a * b; +}; + +/** + * @param {number} a + * @param {number} b + */ +var div = function(a, b) { + return a / b; +}; + +/** + * @param {number} a + * @param {number} b + * @return {number} + */ +var lessThan = function(a, b) { + return a < b ? 1 : 0; +}; + +/** + * @param {Array<number>} a + * @param {Array<number>} b + * @return {Array<number>} + */ +var lessThanVec = function(a, b) { + var res = []; + for (var i = 0; i < a.length; i++) + res[i] = a[i] < b[i]; + return res +}; + +/** + * @param {number} a + * @param {number} b + * @return {number} + */ +var lessThanEqual = function(a, b) { + return a <= b ? 1 : 0; +}; + +/** + * @param {Array<number>} a + * @param {Array<number>} b + * @return {Array<number>} + */ +var lessThanEqualVec = function(a, b) { + var res = []; + for (var i = 0; i < a.length; i++) + res[i] = a[i] <= b[i]; + return res; +}; + +/** + * @param {number} a + * @param {number} b + */ +var greaterThan = function(a, b) { + return a > b ? 1 : 0; +}; + +/** + * @param {Array<number>} a + * @param {Array<number>} b + * @return {Array<number>} + */ +var greaterThanVec = function(a, b) { + var res = []; + for (var i = 0; i < a.length; i++) + res[i] = a[i] > b[i]; + return res; +}; + +/** + * @param {number} a + * @param {number} b + */ +var greaterThanEqual = function(a, b) { + return a >= b ? 1 : 0; +}; + +/** + * @param {Array<number>} a + * @param {Array<number>} b + * @return {Array<number>} + */ +var greaterThanEqualVec = function(a, b) { + var res = []; + for (var i = 0; i < a.length; i++) + res[i] = a[i] >= b[i]; + return res; +}; + +/** + * @param {Array<number>} a + * @param {Array<number>} b + * @return {number} + */ +var allEqual = function(a, b) { + return deMath.equal(a, b) ? 1 : 0; +}; + +/** + * @param {Array<number>} a + * @param {Array<number>} b + * @return {Array<number>} + */ +var allEqualVec = function(a, b) { + var res = []; + for (var i = 0; i < a.length; i++) + res[i] = a[i] == b[i]; + return res; +}; + +/** + * @param {Array<number>} a + * @param {Array<number>} b + * @return {number} + */ +var anyNotEqual = function(a, b) { + return !deMath.equal(a, b) ? 1 : 0; +}; + +/** + * @param {Array<number>} a + * @param {Array<number>} b + * @return {Array<number>} + */ +var anyNotEqualVec = function(a, b) { + var res = []; + for (var i = 0; i < a.length; i++) + res[i] = a[i] != b[i]; + return res; +}; + +/** + * @param {Array<number>} a + * @return {Array<number>} + */ +var boolNotVec = function(a) { + var res = []; + for (var i = 0; i < a.length; i++) + res[i] = !a[i]; + return res; +} + +/** + * @param {Array<number>} a + * @return {boolean} + */ +var boolAny = function(a) { + for (var i = 0; i < a.length; i++) + if (a[i] == true) + return true; + return false; +} + +/** + * @param {Array<number>} a + * @return {boolean} + */ +var boolAll = function(a) { + for (var i = 0; i < a.length; i++) + if (a[i] == false) + return false; + return true; +} + +/** + * @param {number} a + * @param {number} b + */ +var logicalAnd = function(a, b) { + return a && b ? 1 : 0; +}; + +/** + * @param {number} a + * @param {number} b + */ +var logicalOr = function(a, b) { + return a || b ? 1 : 0; +}; + +/** + * @param {number} a + * @param {number} b + */ +var logicalXor = function(a, b) { + return a != b ? 1 : 0; +}; + +/** + * @param {number} a + */ +var exp2 = function(a) { + return deFloatExp2(a); +}; + +/** + * @param {number} a + */ +var inverseSqrt = function(a) { + return deFloatRsq(a); +}; + +/** + * @param {Array<number>} a + * @param {number} b + * @return {Array<number>} + */ +var minVecScalar = function(a, b) { + var res = []; + for (var i = 0; i < a.length; i++) + res[i] = Math.min(a[i], b); + return res; +}; + +/** + * @param {Array<number>} a + * @param {number} b + * @return {Array<number>} + */ +var maxVecScalar = function(a, b) { + var res = []; + for (var i = 0; i < a.length; i++) + res[i] = Math.max(a[i], b); + return res; +}; + +/** + * @param {number} a + * @param {number} b + * @param {number} c + * @return {number} + */ +var mix = function(a, b, c) { + return a * (1.0 - c) + b * c; +}; +/** + * @param {Array<number>} a + * @param {Array<number>} b + * @param {number} c + * @return {Array<number>} + */ +var mixVecVecScalar = function(a, b, c) { + var res = []; + for (var i = 0; i < a.length; i++) + res[i] = mix(a[i], b[i], c); + return res; +}; + +/** + * @param {Array<number>} a + * @param {number} b + * @param {number} c + * @return {Array<number>} + */ +var clampVecScalarScalar = function(a, b, c) { + var res = []; + for (var i = 0; i < a.length; i++) + res[i] = deMath.clamp(a[i], b, c); + return res; +}; + +/** + * @param {number} a + * @param {number} b + * @return {number} + */ +var step = function(a, b) { + return b < a ? 0.0 : 1.0; +}; + +/** + * @param {number} a + * @param {Array<number>} b + * @return {Array<number>} + */ +var stepScalarVec = function(a, b) { + var res = []; + for (var i = 0; i < b.length; i++) + res[i] = step(a, b[i]); + return res; +}; + +/** + * @param {number} a + * @param {number} b + * @param {number} c + * @return {number} + */ +var smoothStep = function(a, b, c) { + if (c <= a) return 0.0; + if (c >= b) return 1.0; + var t = deMath.clamp((c - a) / (b - a), 0.0, 1.0); + return t * t * (3.0 - 2.0 * t); +}; + +/** + * @param {number} a + * @param {number} b + * @param {Array<number>} c + * @return {Array<number>} + */ +var smoothStepScalarScalarVec = function(a, b, c) { + var res = []; + for (var i = 0; i < c.length; i++) + res[i] = smoothStep(a, b, c[i]); + return res; +}; + +/** + * @param {number} a + * @return {number} + */ +var roundToEven = function(a) { + var q = deMath.deFloatFrac(a); + var r = a - q; + + if (q > 0.5) + r += 1.0; + else if (q == 0.5 && r % 2 != 0) + r += 1.0; + + return r; +}; + +/** + * @param {number} a + * @return {number} + */ +var fract = function(a) { + return a - Math.floor(a); +}; + +/** + * @param {number} a + * @return {number} + */ +var radians = function(a) { + return deFloatRadians(a); +} + +/** + * @param {number} a + * @return {number} + */ +var degrees = function(a) { + return deFloatDegrees(a); +} + +/** + * @param {number} a + * @param {Array<number>} b + */ +var addScalarVec = function(a, b) { + return deMath.addScalar(b, a); +}; + +/** + * @param {number} a + * @param {Array<number>} b + */ +var subScalarVec = function(a, b) { + var dst = []; + for (var i = 0; i < b.length; i++) + dst.push(a - b[i]); + return dst; +}; + +/** + * @param {number} a + * @param {Array<number>} b + */ +var mulScalarVec = function(a, b) { + var dst = []; + for (var i = 0; i < b.length; i++) + dst.push(a * b[i]); + return dst; +}; + +/** + * @param {number} a + * @param {Array<number>} b + */ +var divScalarVec = function(a, b) { + var dst = []; + for (var i = 0; i < b.length; i++) + dst.push(a / b[i]); + return dst; +}; + +/** + * @param {number} a + * @param {Array<number>} b + */ +var modScalarVec = function(a, b) { + var dst = []; + for (var i = 0; i < b.length; i++) + dst.push(a % b[i]); + return dst; +}; + +var bitwiseAndScalarVec = function(a, b) { + var dst = []; + for (var i = 0; i < b.length; i++) + dst.push(deMath.binaryOp(a, b[i], deMath.BinaryOp.AND)); + return dst; +}; + +var bitwiseOrScalarVec = function(a, b) { + var dst = []; + for (var i = 0; i < b.length; i++) + dst.push(deMath.binaryOp(a, b[i], deMath.BinaryOp.OR)); + return dst; +}; + +var bitwiseXorScalarVec = function(a, b) { + var dst = []; + for (var i = 0; i < b.length; i++) + dst.push(deMath.binaryOp(a, b[i], deMath.BinaryOp.XOR)); + return dst; +}; + +/** + * @param {Array<number>} a + * @return {number} + */ +var length = function(a) { + var squareSum = 0; + for (var i = 0; i < a.length; i++) + squareSum += a[i] * a[i]; + return Math.sqrt(squareSum); +}; + +/** + * @param {Array<number>} a + * @param {Array<number>} b + * @return {number} + */ +var distance = function(a, b) { + var res = deMath.subtract(a, b) + return length(res); +}; + +/** + * @param {Array<number>} a + * @param {Array<number>} b + * @return {number} + */ +var dot = function(a, b) { + var res = deMath.multiply(a, b); + var sum = 0; + for (var i = 0; i < res.length; i++) + sum += res[i]; + return sum; +}; + +/** + * @param {Array<number>} a + * @return {Array<number>} + */ +var normalize = function(a) { + var ooLen = 1 / length(a); + var res = []; + for (var i = 0; i < a.length; i++) + res[i] = ooLen * a[i]; + return res; +}; + +/** + * @param {Array<number>} a + * @param {Array<number>} b + * @param {Array<number>} c + * @return {Array<number>} + */ +var faceforward = function(a, b, c) { + return dot(c, b) < 0 ? a : deMath.scale(a, -1); +}; + +/** + * @param {Array<number>} a + * @param {Array<number>} b + * @return {Array<number>} + */ +var reflect = function(a, b) { + return deMath.subtract(a, deMath.scale(deMath.scale(b, dot(b, a)), 2)); +}; + +/** + * @param {Array<number>} a + * @param {Array<number>} b + * @param {number} c + * @return {Array<number>} + */ +var refract = function(a, b, c) { + var cosAngle = dot(b, a); + var k = 1 - c * c * (1 - cosAngle * cosAngle); + if (k < 0) { + var res = new Array(a.length); + return res.fill(0) + } else + return deMath.subtract(deMath.scale(a, c), deMath.scale(b, c * cosAngle + Math.sqrt(k))); +}; + +/** + * @param {Array<number>} a + * @param {Array<number>} b + * @return {Array<number>} + */ +var cross = function(a, b) { + if (a.length != 3 || b.length != 3) + throw new Error('Arrays must have the size of 3'); + return [ + a[1] * b[2] - b[1] * a[2], + a[2] * b[0] - b[2] * a[0], + a[0] * b[1] - b[0] * a[1]]; +}; + +var nop = function(v) { + return v; +}; + +var selection = function(cond, a, b) { + return cond ? a : b; +}; + +var boolNot = function(a) { + return !a; +}; + +var bitwiseNot = function(a) { + return ~a; +}; + +/** + * @param {number} x + * @return {number} + */ +var deFloatRadians = function(x) { + return x * (Math.PI / 180.0); +}; + +/** + * @param {number} x + * @return {number} + */ +var deFloatDegrees = function(x) { + return x * (180.0 / Math.PI); +}; + +/** + * @param {number} x + * @return {number} + */ +var deFloatExp2 = function(x) { + return Math.exp(x * Math.LN2); +}; + +/** + * @param {number} x + * @return {number} + */ +var deFloatLog2 = function(x) { + return Math.log(x) * Math.LOG2E; +}; + +/** + * @param {number} x + * @return {number} + */ +var deFloatRsq = function(x) { + var s = Math.sqrt(x); + return s == 0.0 ? 0.0 : (1.0 / s); +}; + +/** + * @constructor + * @param {boolean} low + * @param {boolean} medium + * @param {boolean} high + */ +es3fShaderOperatorTests.Precision = function(low, medium, high) { + this.low = low; + this.medium = medium; + this.high = high; +}; + +/** @const */ es3fShaderOperatorTests.Precision.Low = new es3fShaderOperatorTests.Precision(true, false, false); +/** @const */ es3fShaderOperatorTests.Precision.Medium = new es3fShaderOperatorTests.Precision(false, true, false); +/** @const */ es3fShaderOperatorTests.Precision.High = new es3fShaderOperatorTests.Precision(false, false, true); +/** @const */ es3fShaderOperatorTests.Precision.LowMedium = new es3fShaderOperatorTests.Precision(true, true, false); +/** @const */ es3fShaderOperatorTests.Precision.MediumHigh = new es3fShaderOperatorTests.Precision(false, true, true); +/** @const */ es3fShaderOperatorTests.Precision.All = new es3fShaderOperatorTests.Precision(true, true, true); +/** @const */ es3fShaderOperatorTests.Precision.None = new es3fShaderOperatorTests.Precision(false, false, false); + +/** + * @enum + */ +es3fShaderOperatorTests.ValueType = { + NONE: 0, + FLOAT: (1 << 0), // float scalar + FLOAT_VEC: (1 << 1), // float vector + FLOAT_GENTYPE: (1 << 2), // float scalar/vector + VEC3: (1 << 3), // vec3 only + MATRIX: (1 << 4), // matrix + BOOL: (1 << 5), // boolean scalar + BOOL_VEC: (1 << 6), // boolean vector + BOOL_GENTYPE: (1 << 7), // boolean scalar/vector + INT: (1 << 8), // int scalar + INT_VEC: (1 << 9), // int vector + INT_GENTYPE: (1 << 10), // int scalar/vector + UINT: (1 << 11), // uint scalar + UINT_VEC: (1 << 12), // uint vector + UINT_GENTYPE: (1 << 13) // uint scalar/vector +}; + +/** + * @param {es3fShaderOperatorTests.ValueType} type + * @return {boolean} + */ +es3fShaderOperatorTests.isBoolType = function(type) { + return (type & (es3fShaderOperatorTests.ValueType.BOOL | es3fShaderOperatorTests.ValueType.BOOL_VEC | es3fShaderOperatorTests.ValueType.BOOL_GENTYPE)) != 0; +}; + +/** + * @param {es3fShaderOperatorTests.ValueType} type + * @return {boolean} + */ +es3fShaderOperatorTests.isIntType = function(type) { + return (type & (es3fShaderOperatorTests.ValueType.INT | es3fShaderOperatorTests.ValueType.INT_VEC | es3fShaderOperatorTests.ValueType.INT_GENTYPE)) != 0; +}; + +/** + * @param {es3fShaderOperatorTests.ValueType} type + * @return {boolean} + */ +es3fShaderOperatorTests.isUintType = function(type) { + return (type & (es3fShaderOperatorTests.ValueType.UINT | es3fShaderOperatorTests.ValueType.UINT_VEC | es3fShaderOperatorTests.ValueType.UINT_GENTYPE)) != 0; +}; + +/** + * @param {es3fShaderOperatorTests.ValueType} type + * @return {boolean} + */ +es3fShaderOperatorTests.isScalarType = function(type) { + return type == es3fShaderOperatorTests.ValueType.FLOAT || type == es3fShaderOperatorTests.ValueType.BOOL || type == es3fShaderOperatorTests.ValueType.INT || type == es3fShaderOperatorTests.ValueType.UINT; +}; + +/** + * @param {es3fShaderOperatorTests.ValueType} type + * @return {boolean} + */ +es3fShaderOperatorTests.isFloatType = function(type) { + return (type & (es3fShaderOperatorTests.ValueType.FLOAT | es3fShaderOperatorTests.ValueType.FLOAT_VEC | es3fShaderOperatorTests.ValueType.FLOAT_GENTYPE)) != 0; +}; + +/** + * @param {gluShaderProgram.shaderType} shaderType + * @param {gluShaderUtil.precision} uintPrecision + * @return {number} + */ +es3fShaderOperatorTests.getGLSLUintMaxAsFloat = function(shaderType, uintPrecision) { + switch (uintPrecision) { + case gluShaderUtil.precision.PRECISION_LOWP: + var intPrecisionGL = gl.LOW_INT; + break; + case gluShaderUtil.precision.PRECISION_MEDIUMP: + var intPrecisionGL = gl.MEDIUM_INT; + break; + case gluShaderUtil.precision.PRECISION_HIGHP: + var intPrecisionGL = gl.HIGH_INT; + break; + default: + assertMsgOptions(false, 'Invalid shader type', false, false); + var intPrecisionGL = 0; + } + + switch (shaderType) { + case gluShaderProgram.shaderType.VERTEX: + var shaderTypeGL = gl.VERTEX_SHADER; + break; + case gluShaderProgram.shaderType.FRAGMENT: + var shaderTypeGL = gl.FRAGMENT_SHADER; + break; + default: + assertMsgOptions(false, 'Invalid shader type', false, false); + var shaderTypeGL = 0; + } + + /** @type {WebGLShaderPrecisionFormat } */ var sPrecision = gl.getShaderPrecisionFormat(shaderTypeGL, intPrecisionGL); + assertMsgOptions(gl.getError() === gl.NO_ERROR, 'glGetShaderPrecisionFormat failed', false, true); + + if (!deMath.deInBounds32(sPrecision.rangeMin, 8, 32)) + throw new Error('Out of range'); + + var numBitsInType = sPrecision.rangeMin + 1; + return Math.pow(2, numBitsInType) - 1; +}; + +/** + * @enum + */ +es3fShaderOperatorTests.OperationType = { + FUNCTION: 0, + OPERATOR: 1, + SIDE_EFFECT_OPERATOR: 2 // Test the side-effect (as opposed to the result) of a side-effect operator. +}; + +/** + * swizzling indices for assigning the tested function output to the correct color channel + */ +es3fShaderOperatorTests.outIndices = []; +es3fShaderOperatorTests.outIndices[1] = [0]; +es3fShaderOperatorTests.outIndices[2] = [1, 2]; +es3fShaderOperatorTests.outIndices[3] = [0, 1, 2]; +es3fShaderOperatorTests.outIndices[4] = [0, 1, 2, 3]; + +var convert = function(input, dataType) { + switch (dataType) { + case gluShaderUtil.DataType.INT: + if (input instanceof Array) { + var ret = []; + for (var i = 0; i < input.length; i++) + ret[i] = deMath.intCast(input[i]); + return ret; + } + return deMath.intCast(input); + case gluShaderUtil.DataType.UINT: + if (input instanceof Array) { + var ret = []; + for (var i = 0; i < input.length; i++) + ret[i] = deMath.uintCast(input[i]); + return ret; + } + return deMath.uintCast(input); + case gluShaderUtil.DataType.BOOL: + if (input instanceof Array) { + var ret = []; + for (var i = 0; i < input.length; i++) + ret[i] = input[i] > 0 ? 1 : 0; + return ret; + } + return input > 0 ? 1 : 0; + + } + return input; +}; + +/** + * Generate unary functions which have the same input and return type + * @param {function(number): number} func + * @param {gluShaderUtil.DataType=} dataTypeIn + * @param {gluShaderUtil.DataType=} dataTypeOut + */ +es3fShaderOperatorTests.unaryGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) { + var run = function(output, func, input) { + if (input instanceof Array) { + var len = input.length; + var indices = es3fShaderOperatorTests.outIndices[len]; + for (var i = 0; i < input.length; i++) + output[indices[i]] = convert(func(convert(input[i], dataTypeIn)), dataTypeOut); + } else + output[0] = convert(func(convert(input, dataTypeIn)), dataTypeOut); + }; + + var functions = {}; + functions.scalar = function(c) { run(c.color, func, c.in_[0][2]); }; + functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1])); }; + functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1])); }; + functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0])); }; + return functions; +}; + +/** + * Generate unary functions which have the same input and return type + * @param {function(Array<number>): Array<number>} func + * @param {gluShaderUtil.DataType=} dataTypeIn + * @param {gluShaderUtil.DataType=} dataTypeOut + */ +es3fShaderOperatorTests.unaryArrayFuncs = function(func, dataTypeOut, dataTypeIn) { + var run = function(output, func, input) { + var len = input.length; + var indices = es3fShaderOperatorTests.outIndices[len]; + var value = convert(func(convert(input, dataTypeIn)), dataTypeOut); + for (var i = 0; i < input.length; i++) + output[indices[i]] = value[i]; + }; + + var functions = {}; + functions.scalar = function(c) { run(c.color, func, [c.in_[0][2]]); }; + functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1])); }; + functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1])); }; + functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0])); }; + return functions; +}; + +/** + * Generate unary functions which always have scalar return type + * @param {function(Array<number>): number} func + * @param {gluShaderUtil.DataType=} dataTypeIn + * @param {gluShaderUtil.DataType=} dataTypeOut + */ +es3fShaderOperatorTests.unaryScalarGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) { + var run = function(output, func, input) { + output[0] = convert(func(convert(input, dataTypeIn)), dataTypeOut); + }; + + var functions = {}; + functions.scalar = function(c) { run(c.color, func, [c.in_[0][2]]); }; + functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1])); }; + functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1])); }; + functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0])); }; + return functions; +}; + +/** + * Generate unary functions which always have bolean return type + * @param {function(Array<number>): boolean} func + * @param {gluShaderUtil.DataType=} dataTypeIn + * @param {gluShaderUtil.DataType=} dataTypeOut + */ +es3fShaderOperatorTests.unaryBooleanGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) { + var run = function(output, func, input) { + output[0] = convert(func(convert(input, dataTypeIn)), dataTypeOut); + }; + + var functions = {}; + functions.scalar = function(c) { run(c.color, func, [c.in_[0][2] > 0.0]); }; + functions.vec2 = function(c) { run(c.color, func, greaterThanVec(deMath.swizzle(c.in_[0], [3, 1]), [0, 0])); }; + functions.vec3 = function(c) { run(c.color, func, greaterThanVec(deMath.swizzle(c.in_[0], [2, 0, 1]), [0, 0, 0])); }; + functions.vec4 = function(c) { run(c.color, func, greaterThanVec(deMath.swizzle(c.in_[0], [1, 2, 3, 0]), [0, 0, 0, 0])); }; + return functions; +}; + +/** + * Generate binary functions which have the same input and return type + * @param {function(number, number): number} func + * @param {gluShaderUtil.DataType=} dataTypeIn + * @param {gluShaderUtil.DataType=} dataTypeOut + */ +es3fShaderOperatorTests.binaryGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) { + var run = function(output, func, input1, input2) { + if (input1 instanceof Array) { + var len = input1.length; + var indices = es3fShaderOperatorTests.outIndices[len]; + for (var i = 0; i < input1.length; i++) + output[indices[i]] = convert(func(convert(input1[i], dataTypeIn), convert(input2[i], dataTypeIn)), dataTypeOut); + } else { + var value = convert(func(convert(input1, dataTypeIn), convert(input2, dataTypeIn)), dataTypeOut); + output[0] = value; + } + }; + + var functions = {}; + functions.scalar = function(c) { run(c.color, func, c.in_[0][2], c.in_[1][0]); }; + functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), deMath.swizzle(c.in_[1], [1, 0])); }; + functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), deMath.swizzle(c.in_[1], [1, 2, 0])); }; + 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])); }; + return functions; +}; + +/** + * Generate binary functions which have the same input and return type + * @param {function(number, number, number): number} func + * @param {gluShaderUtil.DataType=} dataTypeIn + * @param {gluShaderUtil.DataType=} dataTypeOut + */ +es3fShaderOperatorTests.ternaryGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) { + var run = function(output, func, input1, input2, input3) { + if (input1 instanceof Array) { + var len = input1.length; + var indices = es3fShaderOperatorTests.outIndices[len]; + for (var i = 0; i < input1.length; i++) + output[indices[i]] = convert(func(convert(input1[i], dataTypeIn), convert(input2[i], dataTypeIn), convert(input3[i], dataTypeIn)), dataTypeOut); + } else { + var value = convert(func(convert(input1, dataTypeIn), convert(input2, dataTypeIn), convert(input3, dataTypeIn)), dataTypeOut); + output[0] = value; + } + }; + + var functions = {}; + functions.scalar = function(c) { run(c.color, func, c.in_[0][2], c.in_[1][0], c.in_[2][1]); }; + 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])); }; + 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])); }; + 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])); }; + return functions; +}; + +/** + * Generate binary functions which have the same input and return type + * @param {function(Array<number>, Array<number>): number} func + * @param {gluShaderUtil.DataType=} dataTypeIn + * @param {gluShaderUtil.DataType=} dataTypeOut + */ +es3fShaderOperatorTests.binaryScalarGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) { + var run = function(output, func, input1, input2) { + var value = convert(func(convert(input1, dataTypeIn), convert(input2, dataTypeIn)), dataTypeOut); + output[0] = value; + }; + + var functions = {}; + functions.scalar = function(c) { run(c.color, func, [c.in_[0][2]], [c.in_[1][0]]); }; + functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), deMath.swizzle(c.in_[1], [1, 0])); }; + functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), deMath.swizzle(c.in_[1], [1, 2, 0])); }; + 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])); }; + return functions; +}; + +/** + * Generate (cond ? a : b) functions + * @param {gluShaderUtil.DataType} dataType + * Returns an array of functions, indexed by datatype size + */ +es3fShaderOperatorTests.selectionFuncs = function(dataType) { + var run = function(output, input0, input1, input2) { + var value = selection(input0, input1, input2); + value = convert(value, dataType); + if (value instanceof Array) { + var len = value.length; + var indices = es3fShaderOperatorTests.outIndices[len]; + for (var i = 0; i < len; i++) + output[indices[i]] = value[i]; + } else + output[0] = value; + }; + + var functions = []; + functions[1] = function(c) { run(c.color, c.in_[0][2] > 0, c.in_[1][0], c.in_[2][1]); }; + 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])); }; + 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])); }; + 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])); }; + return functions; +}; + +var cp = function(dst, src) { + var len = src.length; + var indices = es3fShaderOperatorTests.outIndices[len]; + for (var i = 0; i < len; i++) + dst[indices[i]] = src[i]; +}; + +/** + * Generate binary functions of form: vec = func(scalar, vec) + * @param {function(number, Array<number>): Array<number>} func + * @param {gluShaderUtil.DataType=} dataTypeIn + * @param {gluShaderUtil.DataType=} dataTypeOut + */ +es3fShaderOperatorTests.binaryScalarVecFuncs = function(func, dataTypeOut, dataTypeIn) { + /** + * @param {function(number, Array<number>): Array<number>} func + * @param {number} input1 + * @param {Array<number>} input2 + */ + var run = function(output, func, input1, input2) { + var in1 = convert(input1, dataTypeIn); + var in2 = convert(input2, dataTypeIn); + var value = func(in1, in2); + value = convert(value, dataTypeOut); + cp(output, value); + }; + var functions = {}; + functions.vec2 = function(c) { run(c.color, func, c.in_[0][2], deMath.swizzle(c.in_[1], [1, 0])); }; + functions.vec3 = function(c) { run(c.color, func, c.in_[0][2], deMath.swizzle(c.in_[1], [1, 2, 0])); }; + functions.vec4 = function(c) { run(c.color, func, c.in_[0][2], deMath.swizzle(c.in_[1], [3, 2, 1, 0])); }; + return functions; +}; + +/** + * Generate binary functions of form: vec = func(vec, scalar) + * @param {function(Array<number>, number): Array<number>} func + * @param {gluShaderUtil.DataType=} dataTypeIn + * @param {gluShaderUtil.DataType=} dataTypeOut + */ +es3fShaderOperatorTests.binaryVecScalarFuncs = function(func, dataTypeOut, dataTypeIn) { + /** + * @param {function(Array<number>, number): Array<number>} func + * @param {Array<number>} input1 + * @param {number} input2 + */ + var run = function(output, func, input1, input2) { + var in1 = convert(input1, dataTypeIn); + var in2 = convert(input2, dataTypeIn); + var value = func(in1, in2); + value = convert(value, dataTypeOut); + cp(output, value); + }; + var functions = {}; + functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), c.in_[1][0]); }; + functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), c.in_[1][0]); }; + functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0]), c.in_[1][0]); }; + return functions; +}; + +/** + * Generate binary functions of form: vec = func(vec, vec, scalar) + * @param {function(Array<number>, Array<number>, number): Array<number>} func + * @param {gluShaderUtil.DataType=} dataTypeIn + * @param {gluShaderUtil.DataType=} dataTypeOut + */ +es3fShaderOperatorTests.ternaryVecVecScalarFuncs = function(func, dataTypeOut, dataTypeIn) { + /** + * @param {function(Array<number>, Array<number>, number): Array<number>} func + * @param {Array<number>} input1 + * @param {Array<number>} input2 + * @param {number} input3 + */ + var run = function(output, func, input1, input2, input3) { + var in1 = convert(input1, dataTypeIn); + var in2 = convert(input2, dataTypeIn); + var in3 = convert(input3, dataTypeIn); + var value = func(in1, in2, in3); + value = convert(value, dataTypeOut); + cp(output, value); + }; + var functions = {}; + functions.scalar = function(c) { run(c.color, func, [c.in_[0][2]], [c.in_[1][0]], c.in_[2][1]); }; + 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]); }; + 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]); }; + 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]); }; + return functions; +}; + +/** + * Generate binary functions of form: vec = func(vec, scalar, scalar) + * @param {function(Array<number>, number, number): Array<number>} func + * @param {gluShaderUtil.DataType=} dataTypeIn + * @param {gluShaderUtil.DataType=} dataTypeOut + */ +es3fShaderOperatorTests.ternaryVecScalarScalarFuncs = function(func, dataTypeOut, dataTypeIn) { + /** + * @param {function(Array<number>, number, number): Array<number>} func + * @param {Array<number>} input1 + * @param {number} input2 + * @param {number} input3 + */ + var run = function(output, func, input1, input2, input3) { + var in1 = convert(input1, dataTypeIn); + var in2 = convert(input2, dataTypeIn); + var in3 = convert(input3, dataTypeIn); + var value = func(in1, in2, in3); + value = convert(value, dataTypeOut); + cp(output, value); + }; + var functions = {}; + functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), c.in_[1][0], c.in_[2][1]); }; + functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), c.in_[1][0], c.in_[2][1]); }; + 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]); }; + return functions; +}; + +/** + * Generate binary functions of form: vec = func(scalar, scalar, vec) + * @param {function(number, number, Array<number>): Array<number>} func + * @param {gluShaderUtil.DataType=} dataTypeIn + * @param {gluShaderUtil.DataType=} dataTypeOut + */ +es3fShaderOperatorTests.ternaryScalarScalarVecFuncs = function(func, dataTypeOut, dataTypeIn) { + /** + * @param {function(number, number, Array<number>): Array<number>} func + * @param {number} input1 + * @param {number} input2 + * @param {Array<number>} input3 + */ + var run = function(output, func, input1, input2, input3) { + var in1 = convert(input1, dataTypeIn); + var in2 = convert(input2, dataTypeIn); + var in3 = convert(input3, dataTypeIn); + var value = func(in1, in2, in3); + value = convert(value, dataTypeOut); + cp(output, value); + }; + var functions = {}; + functions.vec2 = function(c) { run(c.color, func, c.in_[0][2], c.in_[1][0], deMath.swizzle(c.in_[2], [2, 1])); }; + functions.vec3 = function(c) { run(c.color, func, c.in_[0][2], c.in_[1][0], deMath.swizzle(c.in_[2], [3, 1, 2])); }; + 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])); }; + return functions; +}; + +/** + * Generate binary functions of form: vec = func(vec, vec, vec) + * @param {function(Array<number>, Array<number>, Array<number>): Array<number>} func + * @param {gluShaderUtil.DataType=} dataTypeIn + * @param {gluShaderUtil.DataType=} dataTypeOut + */ +es3fShaderOperatorTests.ternaryVecVecVecFuncs = function(func, dataTypeOut, dataTypeIn) { + /** + * @param {function(Array<number>, Array<number>, Array<number>): Array<number>} func + * @param {Array<number>} input1 + * @param {Array<number>} input2 + * @param {Array<number>} input3 + */ + var run = function(output, func, input1, input2, input3) { + var in1 = convert(input1, dataTypeIn); + var in2 = convert(input2, dataTypeIn); + var in3 = convert(input3, dataTypeIn); + var value = func(in1, in2, in3); + value = convert(value, dataTypeOut); + cp(output, value); + }; + var functions = {}; + 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])); }; + 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])); }; + 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])); }; + return functions; +}; + +/** + * Generate binary functions of form: vec = func(vec, vec) + * @param {function(Array<number>, Array<number>): Array<number>} func + * @param {gluShaderUtil.DataType=} dataTypeIn + * @param {gluShaderUtil.DataType=} dataTypeOut + */ +es3fShaderOperatorTests.binaryVecVecFuncs = function(func, dataTypeOut, dataTypeIn) { + /** + * @param {function(Array<number>, Array<number>): Array<number>} func + * @param {Array<number>} input1 + * @param {Array<number>} input2 + */ + var run = function(output, func, input1, input2) { + var in1 = convert(input1, dataTypeIn); + var in2 = convert(input2, dataTypeIn); + var value = func(in1, in2); + value = convert(value, dataTypeOut); + cp(output, value); + }; + var functions = {}; + functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), deMath.swizzle(c.in_[1], [1, 0])); }; + functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), deMath.swizzle(c.in_[1], [1, 2, 0])); }; + 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])); }; + return functions; +}; + +/** + * @constructor + * @param {es3fShaderOperatorTests.ValueType} valueType + * @param {es3fShaderOperatorTests.FloatScalar} rangeMin + * @param {es3fShaderOperatorTests.FloatScalar} rangeMax + */ +es3fShaderOperatorTests.Value = function(valueType, rangeMin, rangeMax) { + this.valueType = valueType; + this.rangeMin = rangeMin; + this.rangeMax = rangeMax; +}; + +/** + * @enum + */ +es3fShaderOperatorTests.Symbol = { + SYMBOL_LOWP_UINT_MAX: 0, + SYMBOL_MEDIUMP_UINT_MAX: 1, + + SYMBOL_LOWP_UINT_MAX_RECIPROCAL: 2, + SYMBOL_MEDIUMP_UINT_MAX_RECIPROCAL: 3, + + SYMBOL_ONE_MINUS_UINT32MAX_DIV_LOWP_UINT_MAX: 4, + SYMBOL_ONE_MINUS_UINT32MAX_DIV_MEDIUMP_UINT_MAX: 5 + +}; + +/** + * @constructor + * @param {number|es3fShaderOperatorTests.Symbol} value + * @param {boolean=} isSymbol + */ +es3fShaderOperatorTests.FloatScalar = function(value, isSymbol) { + if (isSymbol) + this.symbol = /** @type {es3fShaderOperatorTests.Symbol} */ (value); + else + this.constant = /** @type {number} */ (value); +}; + +/** + * @param {gluShaderProgram.shaderType} shaderType + * @return {number} + */ +es3fShaderOperatorTests.FloatScalar.prototype.getValue = function(shaderType) { + if (this.constant !== undefined) + return this.constant; + else + switch (this.symbol) { + case es3fShaderOperatorTests.Symbol.SYMBOL_LOWP_UINT_MAX: + return es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_LOWP); + case es3fShaderOperatorTests.Symbol.SYMBOL_MEDIUMP_UINT_MAX: + return es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_MEDIUMP); + + case es3fShaderOperatorTests.Symbol.SYMBOL_LOWP_UINT_MAX_RECIPROCAL: + return 1.0 / es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_LOWP); + case es3fShaderOperatorTests.Symbol.SYMBOL_MEDIUMP_UINT_MAX_RECIPROCAL: + return 1.0 / es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_MEDIUMP); + + case es3fShaderOperatorTests.Symbol.SYMBOL_ONE_MINUS_UINT32MAX_DIV_LOWP_UINT_MAX: + return 1.0 - 0xFFFFFFFF / es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_LOWP); + case es3fShaderOperatorTests.Symbol.SYMBOL_ONE_MINUS_UINT32MAX_DIV_MEDIUMP_UINT_MAX: + return 1.0 - 0xFFFFFFFF / es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_MEDIUMP); + + default: + assertMsgOptions(false, 'Invalid shader type', false, false); + return 0.0; + } +}; + +/** + * @constructor + * @param {gluShaderUtil.DataType=} type + * @param {es3fShaderOperatorTests.FloatScalar=} rangeMin + * @param {es3fShaderOperatorTests.FloatScalar=} rangeMax + */ +es3fShaderOperatorTests.ShaderValue = function(type, rangeMin, rangeMax) { + this.type = type || gluShaderUtil.DataType.INVALID; + this.rangeMin = rangeMin || new es3fShaderOperatorTests.FloatScalar(0); + this.rangeMax = rangeMax || new es3fShaderOperatorTests.FloatScalar(0); +}; + +/** + * @constructor + */ +es3fShaderOperatorTests.ShaderDataSpec = function() { + /** @type {es3fShaderOperatorTests.FloatScalar} */ this.resultScale = new es3fShaderOperatorTests.FloatScalar(1); + /** @type {es3fShaderOperatorTests.FloatScalar} */ this.resultBias = new es3fShaderOperatorTests.FloatScalar(0); + /** @type {es3fShaderOperatorTests.FloatScalar} */ this.referenceScale = new es3fShaderOperatorTests.FloatScalar(1); + /** @type {es3fShaderOperatorTests.FloatScalar} */ this.referenceBias = new es3fShaderOperatorTests.FloatScalar(0); + /** @type {es3fShaderOperatorTests.Precision} */ this.precision = es3fShaderOperatorTests.Precision.None; + /** @type {gluShaderUtil.DataType} */ this.output; + /** @type {number} */ this.numInputs = 0; + /** @type {Array<es3fShaderOperatorTests.ShaderValue>}*/ this.inputs = []; + for (var i = 0; i < es3fShaderOperatorTests.MAX_INPUTS; i++) + this.inputs[i] = new es3fShaderOperatorTests.ShaderValue(); +}; + +/** + * @constructor + * @struct + * @param {string} caseName + * @param {string} shaderFuncName + * @param {es3fShaderOperatorTests.ValueType} outValue + * @param {Array<es3fShaderOperatorTests.Value>} inputs + * @param {es3fShaderOperatorTests.FloatScalar} resultScale + * @param {es3fShaderOperatorTests.FloatScalar} resultBias + * @param {es3fShaderOperatorTests.FloatScalar} referenceScale + * @param {es3fShaderOperatorTests.FloatScalar} referenceBias + * @param {gluShaderUtil.precision} precision + * @param {*} functions + * @param {es3fShaderOperatorTests.OperationType=} type + * @param {boolean=} isUnaryPrefix + */ +es3fShaderOperatorTests.BuiltinFuncInfo = function(caseName, shaderFuncName, outValue, inputs, resultScale, resultBias, referenceScale, referenceBias, precision, functions, type, isUnaryPrefix) { + this.caseName = caseName; + this.shaderFuncName = shaderFuncName; + this.outValue = outValue; + this.inputs = inputs; + this.resultScale = resultScale; + this.resultBias = resultBias; + this.referenceScale = referenceScale; + this.referenceBias = referenceBias; + this.precision = precision; + this.evalFunctions = functions; + this.type = type || es3fShaderOperatorTests.OperationType.FUNCTION; + this.isUnaryPrefix = isUnaryPrefix === undefined ? true : isUnaryPrefix; +}; + +es3fShaderOperatorTests.builtinOperInfo = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions) { + return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName, + shaderFuncName, + outValue, + inputs, + scale, + bias, + scale, + bias, + precision, + functions, + es3fShaderOperatorTests.OperationType.OPERATOR); +}; + +es3fShaderOperatorTests.builtinFunctionInfo = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions) { + return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName, + shaderFuncName, + outValue, + inputs, + scale, + bias, + scale, + bias, + precision, + functions, + es3fShaderOperatorTests.OperationType.FUNCTION); +}; + +es3fShaderOperatorTests.builtinSideEffOperInfo = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions) { + return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName, + shaderFuncName, + outValue, + inputs, + scale, + bias, + scale, + bias, + precision, + functions, + es3fShaderOperatorTests.OperationType.SIDE_EFFECT_OPERATOR); +}; + +es3fShaderOperatorTests.builtinOperInfoSeparateRefScaleBias = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions, referenceScale, referenceBias) { + return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName, + shaderFuncName, + outValue, + inputs, + scale, + bias, + referenceScale, + referenceBias, + precision, + functions, + es3fShaderOperatorTests.OperationType.OPERATOR); +}; + +es3fShaderOperatorTests.BuiltinPostSideEffOperInfo = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions) { + return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName, + shaderFuncName, + outValue, + inputs, + scale, + bias, + scale, + bias, + precision, + functions, + es3fShaderOperatorTests.OperationType.SIDE_EFFECT_OPERATOR, + false); +}; +es3fShaderOperatorTests.BuiltinPostOperInfo = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions) { + return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName, + shaderFuncName, + outValue, + inputs, + scale, + bias, + scale, + bias, + precision, + functions, + es3fShaderOperatorTests.OperationType.OPERATOR, + false); +}; + +/** + * @constructor + * @param {string} name + * @param {string} description + */ +es3fShaderOperatorTests.BuiltinFuncGroup = function(name, description) { + this.name = name; + this.description = description; + this.funcInfos = []; +}; + +es3fShaderOperatorTests.BuiltinFuncGroup.prototype.push = function(a) { this.funcInfos.push(a); }; + +var s_inSwizzles = [ + + ['z', 'wy', 'zxy', 'yzwx'], + ['x', 'yx', 'yzx', 'wzyx'], + ['y', 'zy', 'wyz', 'xwzy'] +]; + +var s_outSwizzles = ['x', 'yz', 'xyz', 'xyzw']; + +var s_outSwizzleChannelMasks = [ + [true, false, false, false], + [false, true, true, false], + [true, true, true, false], + [true, true, true, true] +]; + +/** + * @constructor + * @extends {glsShaderRenderCase.ShaderEvaluator} + * @param {gluShaderProgram.shaderType} shaderType + * @param {glsShaderRenderCase.ShaderEvalFunc} evalFunc + * @param {es3fShaderOperatorTests.FloatScalar} scale + * @param {es3fShaderOperatorTests.FloatScalar} bias + * @param {number} resultScalarSize + */ +es3fShaderOperatorTests.OperatorShaderEvaluator = function(shaderType, evalFunc, scale, bias, resultScalarSize) { + glsShaderRenderCase.ShaderEvaluator.call(this, evalFunc); + this.m_shaderType = shaderType; + this.m_scale = scale; + this.m_bias = bias; + this.m_resultScalarSize = resultScalarSize; + this.m_areScaleAndBiasEvaluated = false; +}; + +setParentClass(es3fShaderOperatorTests.OperatorShaderEvaluator, glsShaderRenderCase.ShaderEvaluator); + +es3fShaderOperatorTests.OperatorShaderEvaluator.prototype.evaluate = function(ctx) { + this.m_evalFunc(ctx); + + if (!this.m_areScaleAndBiasEvaluated) { + this.m_evaluatedScale = this.m_scale.getValue(this.m_shaderType); + this.m_evaluatedBias = this.m_bias.getValue(this.m_shaderType); + this.m_areScaleAndBiasEvaluated = true; + } + + for (var i = 0; i < 4; i++) + if (s_outSwizzleChannelMasks[this.m_resultScalarSize - 1][i]) + ctx.color[i] = ctx.color[i] * this.m_evaluatedScale + this.m_evaluatedBias; +}; + +/** + * @constructor + * @extends {glsShaderRenderCase.ShaderRenderCase} + * @param {string} caseName + * @param {string} description + * @param {boolean} isVertexCase + * @param {glsShaderRenderCase.ShaderEvalFunc} evalFunc + * @param {string} shaderOp + * @param {es3fShaderOperatorTests.ShaderDataSpec} spec + */ +es3fShaderOperatorTests.ShaderOperatorCase = function(caseName, description, isVertexCase, evalFunc, shaderOp, spec) { + glsShaderRenderCase.ShaderRenderCase.call(this, caseName, description, isVertexCase, evalFunc); + this.m_spec = spec; + this.m_shaderOp = shaderOp; + var shaderType = isVertexCase ? gluShaderProgram.shaderType.VERTEX : gluShaderProgram.shaderType.FRAGMENT; + this.m_evaluator = new es3fShaderOperatorTests.OperatorShaderEvaluator(shaderType, + evalFunc, + spec.referenceScale, + spec.referenceBias, + gluShaderUtil.getDataTypeScalarSize(spec.output)); +}; + +setParentClass(es3fShaderOperatorTests.ShaderOperatorCase, glsShaderRenderCase.ShaderRenderCase); + +es3fShaderOperatorTests.ShaderOperatorCase.prototype.setupShaderData = function() { + var shaderType = this.m_isVertexCase ? gluShaderProgram.shaderType.VERTEX : gluShaderProgram.shaderType.FRAGMENT; + var precision = this.m_spec.precision !== undefined ? gluShaderUtil.getPrecisionName(this.m_spec.precision) : null; + var inputPrecision = []; + var sources = []; + sources[0] = ''; //vertex + sources[1] = ''; //fragment + var vtx = 0; + var frag = 1; + var op = this.m_isVertexCase ? vtx : frag; + + sources[vtx] += '#version 300 es\n'; + sources[frag] += '#version 300 es\n'; + + // Compute precision for inputs. + for (var i = 0; i < this.m_spec.numInputs; i++) { + var isBoolVal = gluShaderUtil.isDataTypeBoolOrBVec(this.m_spec.inputs[i].type); + var isIntVal = gluShaderUtil.isDataTypeIntOrIVec(this.m_spec.inputs[i].type); + var isUintVal = gluShaderUtil.isDataTypeUintOrUVec(this.m_spec.inputs[i].type); + // \note Mediump interpolators are used for booleans, and highp for integers. + var prec = isBoolVal ? gluShaderUtil.precision.PRECISION_MEDIUMP : + isIntVal || isUintVal ? gluShaderUtil.precision.PRECISION_HIGHP : + this.m_spec.precision; + inputPrecision[i] = gluShaderUtil.getPrecisionName(prec); + } + + // Attributes. + sources[vtx] += 'in highp vec4 a_position;\n'; + for (var i = 0; i < this.m_spec.numInputs; i++) + sources[vtx] += 'in ' + inputPrecision[i] + ' vec4 a_in' + i + ';\n'; + + // Color output. + sources[frag] += 'layout(location = 0) out mediump vec4 o_color;\n'; + + if (this.m_isVertexCase) { + sources[vtx] += 'out mediump vec4 v_color;\n'; + sources[frag] += 'in mediump vec4 v_color;\n'; + } else{ + for (var i = 0; i < this.m_spec.numInputs; i++) { + sources[vtx] += 'out ' + inputPrecision[i] + ' vec4 v_in' + i + ';\n'; + sources[frag] += 'in ' + inputPrecision[i] + ' vec4 v_in' + i + ';\n'; + } + } + + sources[vtx] += '\n'; + sources[vtx] += 'void main()\n'; + sources[vtx] += '{\n'; + sources[vtx] += ' gl_Position = a_position;\n'; + + sources[frag] += '\n'; + sources[frag] += 'void main()\n'; + sources[frag] += '{\n'; + + // Expression inputs. + var prefix = this.m_isVertexCase ? 'a_' : 'v_'; + for (var i = 0; i < this.m_spec.numInputs; i++) { + var inType = this.m_spec.inputs[i].type; + var inSize = gluShaderUtil.getDataTypeScalarSize(inType); + var isInt = gluShaderUtil.isDataTypeIntOrIVec(inType); + var isUint = gluShaderUtil.isDataTypeUintOrUVec(inType); + var isBool = gluShaderUtil.isDataTypeBoolOrBVec(inType); + var typeName = gluShaderUtil.getDataTypeName(inType); + var swizzle = s_inSwizzles[i][inSize - 1]; + + sources[op] += '\t'; + if (precision && !isBool) sources[op] += precision + ' '; + + sources[op] += typeName + ' in' + i + ' = '; + + if (isBool) { + if (inSize == 1) sources[op] += '('; + else sources[op] += 'greaterThan('; + } else if (isInt || isUint) + sources[op] += typeName + '('; + + sources[op] += prefix + 'in' + i + '.' + swizzle; + + if (isBool) { + if (inSize == 1) sources[op] += ' > 0.0)'; + else sources[op] += ', vec' + inSize + '(0.0))'; + } else if (isInt || isUint) + sources[op] += ')'; + + sources[op] += ';\n'; + } + + // Result variable. + var outTypeName = gluShaderUtil.getDataTypeName(this.m_spec.output); + var isBoolOut = gluShaderUtil.isDataTypeBoolOrBVec(this.m_spec.output); + + sources[op] += '\t'; + if (precision && !isBoolOut) sources[op] += precision + ' '; + sources[op] += outTypeName + ' res = ' + outTypeName + '(0.0);\n\n'; + + + // Expression. + sources[op] += '\t' + this.m_shaderOp + '\n\n'; + + // Convert to color. + var isResFloatVec = gluShaderUtil.isDataTypeFloatOrVec(this.m_spec.output); + var outScalarSize = gluShaderUtil.getDataTypeScalarSize(this.m_spec.output); + + sources[op] += '\thighp vec4 color = vec4(0.0, 0.0, 0.0, 1.0);\n'; + sources[op] += '\tcolor.' + s_outSwizzles[outScalarSize - 1] + ' = '; + + if (!isResFloatVec && outScalarSize == 1) + sources[op] += 'float(res)'; + else if (!isResFloatVec) + sources[op] += 'vec' + outScalarSize + '(res)'; + else + sources[op] += 'res'; + + sources[op] += ';\n'; + + // Scale & bias. + var resultScale = this.m_spec.resultScale.getValue(shaderType); + var resultBias = this.m_spec.resultBias.getValue(shaderType); + if ((resultScale != 1.0) || (resultBias != 0.0)) { + sources[op] += '\tcolor = color'; + if (resultScale != 1.0) sources[op] += ' * ' + es3fShaderOperatorTests.twoValuedVec4(resultScale.toString(10), '1.0', s_outSwizzleChannelMasks[outScalarSize - 1]); + if (resultBias != 0.0) sources[op] += ' + ' + es3fShaderOperatorTests.twoValuedVec4(resultBias.toString(10), '0.0', s_outSwizzleChannelMasks[outScalarSize - 1]); + sources[op] += ';\n'; + } + + // .. + if (this.m_isVertexCase) { + sources[vtx] += ' v_color = color;\n'; + sources[frag] += ' o_color = v_color;\n'; + } else{ + for (var i = 0; i < this.m_spec.numInputs; i++) + sources[vtx] += ' v_in' + i + ' = a_in' + i + ';\n'; + sources[frag] += ' o_color = color;\n'; + } + + sources[vtx] += '}\n'; + sources[frag] += '}\n'; + + this.m_vertShaderSource = sources[vtx]; + this.m_fragShaderSource = sources[frag]; + + // Setup the user attributes. + this.m_userAttribTransforms = []; + for (var inputNdx = 0; inputNdx < this.m_spec.numInputs; inputNdx++) { + var v = this.m_spec.inputs[inputNdx]; + + var rangeMin = v.rangeMin.getValue(shaderType); + var rangeMax = v.rangeMax.getValue(shaderType); + var scale = rangeMax - rangeMin; + var minBias = rangeMin; + var maxBias = rangeMax; + var attribMatrix = new tcuMatrix.Matrix(4, 4); + + for (var rowNdx = 0; rowNdx < 4; rowNdx++) { + var row; + + switch ((rowNdx + inputNdx) % 4) { + case 0: row = [scale, 0.0, 0.0, minBias]; break; + case 1: row = [0.0, scale, 0.0, minBias]; break; + case 2: row = [-scale, 0.0, 0.0, maxBias]; break; + case 3: row = [0.0, -scale, 0.0, maxBias]; break; + default: throw new Error('Invalid row index'); + } + + attribMatrix.setRow(rowNdx, row); + } + + this.m_userAttribTransforms[inputNdx] = attribMatrix; + } + +}; + +// Reference functions for specific sequence operations for the sequence operator tests. +/** + * Reference for expression "in0, in2 + in1, in1 + in0" + * @param {Array<number>} in0 Vec4 + * @param {Array<number>} in1 Vec4 + * @param {Array<number>} in2 Vec4 + * @return {Array<number>} Vec4 + */ +es3fShaderOperatorTests.sequenceNoSideEffCase0 = function(in0, in1, in2) { + return deMath.add(in1, in0); +}; + +/** + * Reference for expression "in0, in2 + in1, in1 + in0" + * @param {number} in0 float + * @param {number} in1 deUint32 + * @param {number} in2 float + * @return {number} deUint32 + */ +es3fShaderOperatorTests.sequenceNoSideEffCase1 = function(in0, in1, in2) { + in1 = convert(in1, gluShaderUtil.DataType.UINT); + return convert(in1 + in1, gluShaderUtil.DataType.UINT); +}; + +/** + * Reference for expression "in0 && in1, in0, ivec2(vec2(in0) + in2)" + * @param {boolean} in0 + * @param {boolean} in1 + * @param {Array<number>} in2 Vec2 + * @return {Array<number>} IVec2 + */ +es3fShaderOperatorTests.sequenceNoSideEffCase2 = function(in0, in1, in2) { + in0 = convert(in0, gluShaderUtil.DataType.BOOL); + return convert([in0 + in2[0], in0 + in2[1]], gluShaderUtil.DataType.INT); +}; + +/** + * Reference for expression "in0 + vec4(in1), in2, in1" + * @param {Array<number>} in0 Vec4 + * @param {Array<number>} in1 IVec4 + * @param {Array<boolean>} in2 BVec4 + * @return {Array<number>} IVec4 + */ +es3fShaderOperatorTests.sequenceNoSideEffCase3 = function(in0, in1, in2) { + return convert(in1, gluShaderUtil.DataType.INT); +}; + +/** + * Reference for expression "in0++, in1 = in0 + in2, in2 = in1" + * @param {Array<number>} in0 Vec4 + * @param {Array<number>} in1 Vec4 + * @param {Array<number>} in2 Vec4 + * @return {Array<number>} Vec4 + */ +es3fShaderOperatorTests.sequenceSideEffCase0 = function(in0, in1, in2) { + return deMath.add(deMath.add(in0, [1.0, 1.0, 1.0, 1.0]), in2); +}; + +/** + * Reference for expression "in1++, in0 = float(in1), in1 = uint(in0 + in2)" + * @param {number} in0 float + * @param {number} in1 deUint32 + * @param {number} in2 float + * @return {number} deUint32 + */ +es3fShaderOperatorTests.sequenceSideEffCase1 = function(in0, in1, in2) { + in1 = convert(in1, gluShaderUtil.DataType.UINT); + return convert(in1 + 1.0 + in2, gluShaderUtil.DataType.UINT); +}; + +/** + * Reference for expression "in1 = in0, in2++, in2 = in2 + vec2(in1), ivec2(in2)" + * @param {boolean} in0 + * @param {boolean} in1 + * @param {Array<number>} in2 Vec2 + * @return {Array<number>} IVec2 + */ +es3fShaderOperatorTests.sequenceSideEffCase2 = function(in0, in1, in2) { + in0 = convert(in0, gluShaderUtil.DataType.BOOL); + return convert(deMath.add(deMath.add(in2, [1.0, 1.0]), [in0, in0]), gluShaderUtil.DataType.INT); +}; + +/** + * Reference for expression "in0 = in0 + vec4(in2), in1 = in1 + ivec4(in0), in1++" + * @param {Array<number>} in0 Vec4 + * @param {Array<number>} in1 IVec4 + * @param {Array<boolean>} in2 BVec4 + * @return {Array<number>} IVec4 + */ +es3fShaderOperatorTests.sequenceSideEffCase3 = function(in0, in1, in2) { + in1 = convert(in1, gluShaderUtil.DataType.INT); + in2 = convert(in2, gluShaderUtil.DataType.BOOL); + in0 = deMath.add(in0, in2); + in1 = deMath.add(in1, convert(in0, gluShaderUtil.DataType.INT)); + return in1; +}; + +// ShaderEvalFunc-type wrappers for the above functions. + +/** @param {glsShaderRenderCase.ShaderEvalContext} ctx */ +es3fShaderOperatorTests.evalSequenceNoSideEffCase0 = function(ctx) { + ctx.color = es3fShaderOperatorTests.sequenceNoSideEffCase0( + deMath.swizzle(ctx.in_[0], [1, 2, 3, 0]), + deMath.swizzle(ctx.in_[1], [3, 2, 1, 0]), + deMath.swizzle(ctx.in_[2], [0, 3, 2, 1]) + ); +}; + +/** @param {glsShaderRenderCase.ShaderEvalContext} ctx */ +es3fShaderOperatorTests.evalSequenceNoSideEffCase1 = function(ctx) { + ctx.color[0] = es3fShaderOperatorTests.sequenceNoSideEffCase1( + ctx.in_[0][2], + ctx.in_[1][0], + ctx.in_[2][1] + ); +}; + +/** @param {glsShaderRenderCase.ShaderEvalContext} ctx */ +es3fShaderOperatorTests.evalSequenceNoSideEffCase2 = function(ctx) { + /** @type {Array<number>} */ var result = es3fShaderOperatorTests.sequenceNoSideEffCase2( + ctx.in_[0][2] > 0.0, + ctx.in_[1][0] > 0.0, + deMath.swizzle(ctx.in_[2], [2, 1]) + ); + ctx.color[1] = result[0]; + ctx.color[2] = result[1]; +}; + +/** @param {glsShaderRenderCase.ShaderEvalContext} ctx */ +es3fShaderOperatorTests.evalSequenceNoSideEffCase3 = function(ctx) { + ctx.color = es3fShaderOperatorTests.sequenceNoSideEffCase3( + deMath.swizzle(ctx.in_[0], [1, 2, 3, 0]), + deMath.swizzle(ctx.in_[1], [3, 2, 1, 0]), + deMath.greaterThan(deMath.swizzle(ctx.in_[2], [0, 3, 2, 1]), [0.0, 0.0, 0.0, 0.0]) + ); +}; + +/** @param {glsShaderRenderCase.ShaderEvalContext} ctx */ +es3fShaderOperatorTests.evalSequenceSideEffCase0 = function(ctx) { + ctx.color = es3fShaderOperatorTests.sequenceSideEffCase0( + deMath.swizzle(ctx.in_[0], [1, 2, 3, 0]), + deMath.swizzle(ctx.in_[1], [3, 2, 1, 0]), + deMath.swizzle(ctx.in_[2], [0, 3, 2, 1]) + ); +}; + +/** @param {glsShaderRenderCase.ShaderEvalContext} ctx */ +es3fShaderOperatorTests.evalSequenceSideEffCase1 = function(ctx) { + ctx.color[0] = es3fShaderOperatorTests.sequenceSideEffCase1( + ctx.in_[0][2], + ctx.in_[1][0], + ctx.in_[2][1] + ); +}; + +/** @param {glsShaderRenderCase.ShaderEvalContext} ctx */ +es3fShaderOperatorTests.evalSequenceSideEffCase2 = function(ctx) { + /** @type {Array<number>} */ var result = es3fShaderOperatorTests.sequenceSideEffCase2( + ctx.in_[0][2] > 0.0, + ctx.in_[1][0] > 0.0, + deMath.swizzle(ctx.in_[2], [2, 1]) + ); + ctx.color[1] = result[0]; + ctx.color[2] = result[1]; +}; + +/** @param {glsShaderRenderCase.ShaderEvalContext} ctx */ +es3fShaderOperatorTests.evalSequenceSideEffCase3 = function(ctx) { + ctx.color = es3fShaderOperatorTests.sequenceSideEffCase3( + deMath.swizzle(ctx.in_[0], [1, 2, 3, 0]), + deMath.swizzle(ctx.in_[1], [3, 2, 1, 0]), + deMath.greaterThan(deMath.swizzle(ctx.in_[2], [0, 3, 2, 1]), [0.0, 0.0, 0.0, 0.0]) + ); +}; + +/** + * @constructor + * @extends {tcuTestCase.DeqpTest} + */ +es3fShaderOperatorTests.ShaderOperatorTests = function() { + tcuTestCase.DeqpTest.call(this, 'shaderop', 'Shader operators tests'); +}; + +setParentClass(es3fShaderOperatorTests.ShaderOperatorTests, tcuTestCase.DeqpTest); + +es3fShaderOperatorTests.ShaderOperatorTests.prototype.init = function() { + var op = es3fShaderOperatorTests.builtinOperInfo; + var side = es3fShaderOperatorTests.builtinSideEffOperInfo; + var separate = es3fShaderOperatorTests.builtinOperInfoSeparateRefScaleBias; + var postSide = es3fShaderOperatorTests.BuiltinPostSideEffOperInfo; + var postOp = es3fShaderOperatorTests.BuiltinPostOperInfo; + var all = es3fShaderOperatorTests.Precision.All; + var highp = es3fShaderOperatorTests.Precision.High; + var mediump = es3fShaderOperatorTests.Precision.Medium; + var mediumhighp = es3fShaderOperatorTests.Precision.MediumHigh; + var lowp = es3fShaderOperatorTests.Precision.Low; + var na = es3fShaderOperatorTests.Precision.None; + var GT = es3fShaderOperatorTests.ValueType.FLOAT_GENTYPE; + var UGT = es3fShaderOperatorTests.ValueType.UINT_GENTYPE; + var IGT = es3fShaderOperatorTests.ValueType.INT_GENTYPE; + var BGT = es3fShaderOperatorTests.ValueType.BOOL_GENTYPE; + var F = es3fShaderOperatorTests.ValueType.FLOAT; + var I = es3fShaderOperatorTests.ValueType.INT; + var U = es3fShaderOperatorTests.ValueType.UINT; + var BV = es3fShaderOperatorTests.ValueType.BOOL_VEC; + var FV = es3fShaderOperatorTests.ValueType.FLOAT_VEC; + var IV = es3fShaderOperatorTests.ValueType.INT_VEC; + var UV = es3fShaderOperatorTests.ValueType.UINT_VEC; + var B = es3fShaderOperatorTests.ValueType.BOOL; + var V3 = es3fShaderOperatorTests.ValueType.VEC3; + var lUMax = es3fShaderOperatorTests.Symbol.SYMBOL_LOWP_UINT_MAX; + var mUMax = es3fShaderOperatorTests.Symbol.SYMBOL_MEDIUMP_UINT_MAX; + var lUMaxR = es3fShaderOperatorTests.Symbol.SYMBOL_LOWP_UINT_MAX_RECIPROCAL; + var mUMaxR = es3fShaderOperatorTests.Symbol.SYMBOL_MEDIUMP_UINT_MAX_RECIPROCAL; + var f = function(value) { + return new es3fShaderOperatorTests.FloatScalar(value); + }; + var s = function(value) { + return new es3fShaderOperatorTests.FloatScalar(value, true); + }; + var v = function(type, a, b) { + return new es3fShaderOperatorTests.Value(type, f(a), f(b)); + }; + var v2 = function(type, a, b) { + return new es3fShaderOperatorTests.Value(type, f(a), s(b)); + }; + var funcInfoGroups = []; + var unary = new es3fShaderOperatorTests.BuiltinFuncGroup('unary_operator', 'Unary operator tests'); + funcInfoGroups.push(unary); + + unary.push(op('plus', '+', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.5), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(nop))); + unary.push(op('plus', '+', IGT, [v(IGT, -5.0, 5.0)], f(0.1), f(0.5), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + unary.push(op('plus', '+', UGT, [v(UGT, 0.0, 2e2)], f(5e-3), f(0.0), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + unary.push(op('minus', '-', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.5), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(negate))); + unary.push(op('minus', '-', IGT, [v(IGT, -5.0, 5.0)], f(0.1), f(0.5), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(negate, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + unary.push(separate('minus', '-', UGT, [v2(UGT, 0.0, lUMax)], s(lUMaxR), f(0.0), lowp, + es3fShaderOperatorTests.unaryGenTypeFuncs(negate, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT), s(lUMaxR), + s(es3fShaderOperatorTests.Symbol.SYMBOL_ONE_MINUS_UINT32MAX_DIV_LOWP_UINT_MAX))); + unary.push(separate('minus', '-', UGT, [v2(UGT, 0.0, mUMax)], s(mUMaxR), f(0.0), mediump, + es3fShaderOperatorTests.unaryGenTypeFuncs(negate, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT), s(mUMaxR), + s(es3fShaderOperatorTests.Symbol.SYMBOL_ONE_MINUS_UINT32MAX_DIV_MEDIUMP_UINT_MAX))); + unary.push(op('minus', '-', UGT, [v(UGT, 0.0, 4e9)], f(2e-10), f(0.0), highp, + es3fShaderOperatorTests.unaryGenTypeFuncs(negate, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + 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, + gluShaderUtil.DataType.BOOL).scalar})); + unary.push(op('bitwise_not', '~', IGT, [v(IGT, -1e5, 1e5)], f(5e-5), f(0.5), highp, + es3fShaderOperatorTests.unaryGenTypeFuncs(bitwiseNot, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + unary.push(op('bitwise_not', '~', UGT, [v(UGT, 0.0, 2e9)], f(2e-10), f(0.0), highp, + es3fShaderOperatorTests.unaryGenTypeFuncs(bitwiseNot, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + + // Pre/post incr/decr side effect cases. + unary = new es3fShaderOperatorTests.BuiltinFuncGroup('unary_operator', 'Unary operator tests'); + funcInfoGroups.push(unary); + + unary.push(side('pre_increment_effect', '++', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.0), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(addOne))); + unary.push(side('pre_increment_effect', '++', IGT, [v(IGT, -6.0, 4.0)], f(0.1), f(0.5), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + unary.push(side('pre_increment_effect', '++', UGT, [v(UGT, 0.0, 9.0)], f(0.1), f(0.5), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + unary.push(side('pre_decrement_effect', '--', GT, [v(GT, -1.0, 1.0)], f(0.5), f(1.0), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(subOne))); + unary.push(side('pre_decrement_effect', '--', IGT, [v(IGT, -4.0, 6.0)], f(0.1), f(0.5), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + unary.push(side('pre_decrement_effect', '--', UGT, [v(UGT, 0.0, 10.0)], f(0.1), f(0.0), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + unary.push(postSide('post_increment_result', '++', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.0), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(addOne))); + unary.push(postSide('post_increment_result', '++', IGT, [v(IGT, -6.0, 4.0)], f(0.1), f(0.5), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + unary.push(postSide('post_increment_result', '++', UGT, [v(UGT, 0.0, 9.0)], f(0.1), f(0.0), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + unary.push(postSide('post_decrement_result', '--', GT, [v(GT, -1.0, 1.0)], f(0.5), f(1.0), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(subOne))); + unary.push(postSide('post_decrement_result', '--', IGT, [v(IGT, -4.0, 6.0)], f(0.1), f(0.5), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + unary.push(postSide('post_decrement_result', '--', UGT, [v(UGT, 1.0, 10.0)], f(0.1), f(0.0), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + + // Pre/post incr/decr result cases. + unary = new es3fShaderOperatorTests.BuiltinFuncGroup('unary_operator', 'Unary operator tests'); + funcInfoGroups.push(unary); + + unary.push(op('pre_increment_result', '++', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.0), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(addOne))); + unary.push(op('pre_increment_result', '++', IGT, [v(IGT, -6.0, 4.0)], f(0.1), f(0.5), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + unary.push(op('pre_increment_result', '++', UGT, [v(UGT, 0.0, 9.0)], f(0.1), f(0.0), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + unary.push(op('pre_dencrement_result', '--', GT, [v(GT, -1.0, 1.0)], f(0.5), f(1.0), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(subOne))); + unary.push(op('pre_decrement_result', '--', IGT, [v(IGT, -4.0, 6.0)], f(0.1), f(0.5), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + unary.push(op('pre_decrement_result', '--', UGT, [v(UGT, 0.0, 10.0)], f(0.1), f(0.0), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + unary.push(postOp('post_increment_result', '++', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.5), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(nop))); + unary.push(postOp('post_increment_result', '++', IGT, [v(IGT, -5.0, 5.0)], f(0.1), f(0.5), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + unary.push(postOp('post_increment_result', '++', UGT, [v(UGT, 0.0, 9.0)], f(0.1), f(0.0), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + unary.push(postOp('post_decrement_result', '--', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.5), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(nop))); + unary.push(postOp('post_decrement_result', '--', IGT, [v(IGT, -5.0, 5.0)], f(0.1), f(0.5), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + unary.push(postOp('post_decrement_result', '--', UGT, [v(UGT, 1.0, 10.0)], f(0.1), f(0.0), all, + es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + + var binary; + + // Normal binary operations and their corresponding assignment operations have lots in common; generate both in the following loop. + // 0: normal op test, 1: assignment op side-effect test, 2: assignment op result test + for (var binaryOperatorType = 0; binaryOperatorType <= 2; binaryOperatorType++) { + var isNormalOp = binaryOperatorType == 0; + var isAssignEff = binaryOperatorType == 1; + var isAssignRes = binaryOperatorType == 2; + + var addName = isNormalOp ? 'add' : isAssignEff ? 'add_assign_effect' : 'add_assign_result'; + var subName = isNormalOp ? 'sub' : isAssignEff ? 'sub_assign_effect' : 'sub_assign_result'; + var mulName = isNormalOp ? 'mul' : isAssignEff ? 'mul_assign_effect' : 'mul_assign_result'; + var divName = isNormalOp ? 'div' : isAssignEff ? 'div_assign_effect' : 'div_assign_result'; + var modName = isNormalOp ? 'mod' : isAssignEff ? 'mod_assign_effect' : 'mod_assign_result'; + var andName = isNormalOp ? 'bitwise_and' : isAssignEff ? 'bitwise_and_assign_effect' : 'bitwise_and_assign_result'; + var orName = isNormalOp ? 'bitwise_or' : isAssignEff ? 'bitwise_or_assign_effect' : 'bitwise_or_assign_result'; + var xorName = isNormalOp ? 'bitwise_xor' : isAssignEff ? 'bitwise_xor_assign_effect' : 'bitwise_xor_assign_result'; + var leftShiftName = isNormalOp ? 'left_shift' : isAssignEff ? 'left_shift_assign_effect' : 'left_shift_assign_result'; + var rightShiftName = isNormalOp ? 'right_shift' : isAssignEff ? 'right_shift_assign_effect' : 'right_shift_assign_result'; + var addOp = isNormalOp ? '+' : '+='; + var subOp = isNormalOp ? '-' : '-='; + var mulOp = isNormalOp ? '*' : '*='; + var divOp = isNormalOp ? '/' : '/='; + var modOp = isNormalOp ? '%' : '%='; + var andOp = isNormalOp ? '&' : '&='; + var orOp = isNormalOp ? '|' : '|='; + var xorOp = isNormalOp ? '^' : '^='; + var leftShiftOp = isNormalOp ? '<<' : '<<='; + var rightShiftOp = isNormalOp ? '>>' : '>>='; + + op = isAssignEff ? es3fShaderOperatorTests.builtinSideEffOperInfo : es3fShaderOperatorTests.builtinOperInfo; + + binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests'); + funcInfoGroups.push(binary); + + // The add operator. + + binary.push(op(addName, addOp, GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryGenTypeFuncs(add))); + binary.push(op(addName, addOp, IGT, [v(IGT, -4.0, 6.0), v(IGT, -6.0, 5.0)], f(0.1), f(0.5), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(add, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(addName, addOp, IGT, [v(IGT, -2e9, 2e9), v(IGT, -2e9, 2e9)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(add, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(addName, addOp, UGT, [v(UGT, 0.0, 1e2), v(UGT, 0.0, 1e2)], f(5e-3), f(0.0), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(add, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(addName, addOp, UGT, [v(UGT, 0.0, 4e9), v(UGT, 0.0, 4e9)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(add, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + + binary.push(op(addName, addOp, FV, [v(FV, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.addScalar))); + binary.push(op(addName, addOp, IV, [v(IV, -4.0, 6.0), v(I, -6.0, 5.0)], f(0.1), f(0.5), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.addScalar, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(addName, addOp, IV, [v(IV, -2e9, 2e9), v(I, -2e9, 2e9)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.addScalar, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(addName, addOp, UV, [v(UV, 0.0, 1e2), v(U, 0.0, 1e2)], f(5e-3), f(0.0), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.addScalar, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(addName, addOp, UV, [v(UV, 0.0, 4e9), v(U, 0.0, 4e9)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.addScalar, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + + if (isNormalOp) { + binary.push(op(addName, addOp, FV, [v(F, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryScalarVecFuncs(addScalarVec))); + binary.push(op(addName, addOp, IV, [v(I, -4.0, 6.0), v(IV, -6.0, 5.0)], f(0.1), f(0.5), + mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(addScalarVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(addName, addOp, IV, [v(I, -2e9, 2e9), v(IV, -2e9, 2e9)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryScalarVecFuncs(addScalarVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(addName, addOp, UV, [v(U, 0.0, 1e2), v(UV, 0.0, 1e2)], f(5e-3), f(0.0), + mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(addScalarVec, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(addName, addOp, UV, [v(U, 0.0, 4e9), v(UV, 0.0, 4e9)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryScalarVecFuncs(addScalarVec, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + } + + // The subtract operator. + + binary.push(op(subName, subOp, GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryGenTypeFuncs(sub))); + binary.push(op(subName, subOp, IGT, [v(IGT, -4.0, 6.0), v(IGT, -6.0, 5.0)], f(0.1), f(0.5), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(sub, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(subName, subOp, IGT, [v(IGT, -2e9, 2e9), v(IGT, -2e9, 2e9)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(sub, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(subName, subOp, UGT, [v(UGT, 1e2, 2e2), v(UGT, 0.0, 1e2)], f(5e-3), f(0.0), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(sub, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(subName, subOp, UGT, [v(UGT, .5e9, 3.7e9), v(UGT, 0.0, 3.9e9)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(sub, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(subName, subOp, FV, [v(FV, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.subScalar))); + binary.push(op(subName, subOp, IV, [v(IV, -4.0, 6.0), v(I, -6.0, 5.0)], f(0.1), f(0.5), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.subScalar, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(subName, subOp, IV, [v(IV, -2e9, 2e9), v(I, -2e9, 2e9)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.subScalar, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(subName, subOp, UV, [v(UV, 1e2, 2e2), v(U, 0.0, 1e2)], f(5e-3), f(0.0), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.subScalar, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(subName, subOp, UV, [v(UV, 0.0, 4e9), v(U, 0.0, 4e9)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.subScalar, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + + if (isNormalOp) { + binary.push(op(subName, subOp, FV, [v(F, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryScalarVecFuncs(subScalarVec))); + binary.push(op(subName, subOp, IV, [v(I, -4.0, 6.0), v(IV, -6.0, 5.0)], f(0.1), f(0.5), + mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(subScalarVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(subName, subOp, IV, [v(I, -2e9, 2e9), v(IV, -2e9, 2e9)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryScalarVecFuncs(subScalarVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(subName, subOp, UV, [v(U, 1e2, 2e2), v(UV, 0.0, 1e2)], f(5e-3), f(0.0), + mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(subScalarVec, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(subName, subOp, UV, [v(U, 0.0, 4e9), v(UV, 0.0, 4e9)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryScalarVecFuncs(subScalarVec, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + } + + binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests'); + funcInfoGroups.push(binary); + + // The multiply operator. + + binary.push(op(mulName, mulOp, GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryGenTypeFuncs(mul))); + binary.push(op(mulName, mulOp, IGT, [v(IGT, -4.0, 6.0), v(IGT, -6.0, 5.0)], f(0.1), f(0.5), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(mul, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(mulName, mulOp, IGT, [v(IGT, -3e5, 3e5), v(IGT, -3e4, 3e4)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(mul, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(mulName, mulOp, UGT, [v(UGT, 0.0, 16.0), v(UGT, 0.0, 16.0)], f(4e-3), f(0.0), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(mul, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(mulName, mulOp, UGT, [v(UGT, 0.0, 6e5), v(UGT, 0.0, 6e4)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(mul, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(mulName, mulOp, FV, [v(FV, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.scale))); + binary.push(op(mulName, mulOp, IV, [v(IV, -4.0, 6.0), v(I, -6.0, 5.0)], f(0.1), f(0.5), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.scale, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(mulName, mulOp, IV, [v(IV, -3e5, 3e5), v(I, -3e4, 3e4)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.scale, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(mulName, mulOp, UV, [v(UV, 0.0, 16.0), v(U, 0.0, 16.0)], f(4e-3), f(0.0), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.scale, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(mulName, mulOp, UV, [v(UV, 0.0, 6e5), v(U, 0.0, 6e4)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.scale, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + + if (isNormalOp) { + binary.push(op(mulName, mulOp, FV, [v(F, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryScalarVecFuncs(mulScalarVec))); + binary.push(op(mulName, mulOp, IV, [v(I, -4.0, 6.0), v(IV, -6.0, 5.0)], f(0.1), f(0.5), + mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(mulScalarVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(mulName, mulOp, IV, [v(I, -3e5, 3e5), v(IV, -3e4, 3e4)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryScalarVecFuncs(mulScalarVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(mulName, mulOp, UV, [v(U, 0.0, 16.0), v(UV, 0.0, 16.0)], f(4e-3), f(0.0), + mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(mulScalarVec, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(mulName, mulOp, UV, [v(U, 0.0, 6e5), v(UV, 0.0, 6e4)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryScalarVecFuncs(mulScalarVec, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + } + + // The divide operator. + + binary.push(op(divName, divOp, GT, [v(GT, -1.0, 1.0), v(GT, -2.0, -0.5)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryGenTypeFuncs(div))); + binary.push(op(divName, divOp, IGT, [v(IGT, 24.0, 24.0), v(IGT, -4.0, -1.0)], f(0.04), f(1.0), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(div, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(divName, divOp, IGT, [v(IGT, 40320.0, 40320.0), v(IGT, -8.0, -1.0)], f(1e-5), f(0.5), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(div, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(divName, divOp, UGT, [v(UGT, 0.0, 24.0), v(UGT, 1.0, 4.0)], f(0.04), f(0.0), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(div, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(divName, divOp, UGT, [v(UGT, 0.0, 40320.0), v(UGT, 1.0, 8.0)], f(1e-5), f(0.0), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(div, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(divName, divOp, FV, [v(FV, -1.0, 1.0), v(F, -2.0, -0.5)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.divideScale))); + binary.push(op(divName, divOp, IV, [v(IV, 24.0, 24.0), v(I, -4.0, -1.0)], f(0.04), f(1.0), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.divideScale, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(divName, divOp, IV, [v(IV, 40320.0, 40320.0), v(I, -8.0, -1.0)], f(1e-5), f(0.5), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.divideScale, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(divName, divOp, UV, [v(UV, 0.0, 24.0), v(U, 1.0, 4.0)], f(0.04), f(0.0), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.divideScale, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(divName, divOp, UV, [v(UV, 0.0, 40320.0), v(U, 1.0, 8.0)], f(1e-5), f(0.0), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.divideScale, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + + if (isNormalOp) { + binary.push(op(divName, divOp, FV, [v(F, -1.0, 1.0), v(FV, -2.0, -0.5)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryScalarVecFuncs(divScalarVec))); + binary.push(op(divName, divOp, IV, [v(I, 24.0, 24.0), v(IV, -4.0, -1.0)], f(0.04), f(1.0), + mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(divScalarVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(divName, divOp, IV, [v(I, 40320.0, 40320.0), v(IV, -8.0, -1.0)], f(1e-5), f(0.5), + highp, es3fShaderOperatorTests.binaryScalarVecFuncs(divScalarVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(divName, divOp, UV, [v(U, 0.0, 24.0), v(UV, 1.0, 4.0)], f(0.04), f(0.0), + mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(divScalarVec, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(divName, divOp, UV, [v(U, 0.0, 40320.0), v(UV, 1.0, 8.0)], f(1e-5), f(0.0), + highp, es3fShaderOperatorTests.binaryScalarVecFuncs(divScalarVec, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + } + + binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests'); + funcInfoGroups.push(binary); + + // The modulus operator. + + binary.push(op(modName, modOp, IGT, [v(IGT, 0.0, 6.0), v(IGT, 1.1, 6.1)], f(0.25), f(0.5), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.mod, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(modName, modOp, IGT, [v(IGT, 0.0, 14.0), v(IGT, 1.1, 11.1)], f(0.1), f(0.5), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.mod, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(modName, modOp, UGT, [v(UGT, 0.0, 6.0), v(UGT, 1.1, 6.1)], f(0.25), f(0.0), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.mod, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(modName, modOp, UGT, [v(UGT, 0.0, 24.0), v(UGT, 1.1, 11.1)], f(0.1), f(0.0), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.mod, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(modName, modOp, IV, [v(IV, 0.0, 6.0), v(I, 1.1, 6.1)], f(0.25), f(0.5), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.modScale, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(modName, modOp, IV, [v(IV, 0.0, 6.0), v(I, 1.1, 11.1)], f(0.1), f(0.5), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.modScale, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(modName, modOp, UV, [v(UV, 0.0, 6.0), v(U, 1.1, 6.1)], f(0.25), f(0.0), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.modScale, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(modName, modOp, UV, [v(UV, 0.0, 24.0), v(U, 1.1, 11.1)], f(0.1), f(0.0), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.modScale, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + + if (isNormalOp) { + binary.push(op(modName, modOp, IV, [v(I, 0.0, 6.0), v(IV, 1.1, 6.1)], f(0.25), f(0.5), + mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(modScalarVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(modName, modOp, IV, [v(I, 0.0, 6.0), v(IV, 1.1, 11.1)], f(0.1), f(0.5), + highp, es3fShaderOperatorTests.binaryScalarVecFuncs(modScalarVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(modName, modOp, UV, [v(U, 0.0, 6.0), v(UV, 1.1, 6.1)], f(0.25), f(0.0), + mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(modScalarVec, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(modName, modOp, UV, [v(U, 0.0, 24.0), v(UV, 1.1, 11.1)], f(0.1), f(0.0), + highp, es3fShaderOperatorTests.binaryScalarVecFuncs(modScalarVec, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + } + + // The bitwise and operator. + + binary.push(op(andName, andOp, IGT, [v(IGT, -16.0, 16.0), v(IGT, -16.0, 16.0)], f(0.03), f(0.5), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryAnd, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(andName, andOp, IGT, [v(IGT, -2e9, 2e9), v(IGT, -2e9, 2e9)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryAnd, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(andName, andOp, UGT, [v(UGT, 0.0, 32.0), v(UGT, 0.0, 32.0)], f(0.03), f(0.0), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryAnd, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(andName, andOp, UGT, [v(UGT, 0.0, 4e9), v(UGT, 0.0, 4e9)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryAnd, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(andName, andOp, IV, [v(IV, -16.0, 16.0), v(I, -16.0, 16.0)], f(0.03), f(0.5), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryAndVecScalar, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(andName, andOp, IV, [v(IV, -2e9, 2e9), v(I, -2e9, 2e9)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryAndVecScalar, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(andName, andOp, UV, [v(UV, 0.0, 32.0), v(U, 0.0, 32.0)], f(0.03), f(0.0), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryAndVecScalar, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(andName, andOp, UV, [v(UV, 0.0, 4e9), v(U, 0.0, 4e9)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryAndVecScalar, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + + if (isNormalOp) { + binary.push(op(andName, andOp, IV, [v(I, -16.0, 16.0), v(IV, -16.0, 16.0)], f(0.03), f(0.5), + mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseAndScalarVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(andName, andOp, IV, [v(I, -2e9, 2e9), v(IV, -2e9, 2e9)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseAndScalarVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(andName, andOp, UV, [v(U, 0.0, 32.0), v(UV, 0.0, 32.0)], f(0.03), f(0.0), + mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseAndScalarVec, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(andName, andOp, UV, [v(U, 0.0, 4e9), v(UV, 0.0, 4e9)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseAndScalarVec, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + } + + binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests'); + funcInfoGroups.push(binary); + + // The bitwise or operator. + + binary.push(op(orName, orOp, IGT, [v(IGT, -16.0, 16.0), v(IGT, -16.0, 16.0)], f(0.03), f(0.5), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryOr, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(orName, orOp, IGT, [v(IGT, -2e9, 2e9), v(IGT, -2e9, 2e9)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryOr, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(orName, orOp, UGT, [v(UGT, 0.0, 32.0), v(UGT, 0.0, 32.0)], f(0.03), f(0.0), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryOr, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(orName, orOp, UGT, [v(UGT, 0.0, 4e9), v(UGT, 0.0, 4e9)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryOr, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(orName, orOp, IV, [v(IV, -16.0, 16.0), v(I, -16.0, 16.0)], f(0.03), f(0.5), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryOrVecScalar, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(orName, orOp, IV, [v(IV, -2e9, 2e9), v(I, -2e9, 2e9)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryOrVecScalar, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(orName, orOp, UV, [v(UV, 0.0, 32.0), v(U, 0.0, 32.0)], f(0.03), f(0.0), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryOrVecScalar, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(orName, orOp, UV, [v(UV, 0.0, 4e9), v(U, 0.0, 4e9)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryOrVecScalar, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + + if (isNormalOp) { + binary.push(op(orName, orOp, IV, [v(I, -16.0, 16.0), v(IV, -16.0, 16.0)], f(0.03), f(0.5), + mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseOrScalarVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(orName, orOp, IV, [v(I, -2e9, 2e9), v(IV, -2e9, 2e9)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseOrScalarVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(orName, orOp, UV, [v(U, 0.0, 32.0), v(UV, 0.0, 32.0)], f(0.03), f(0.0), + mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseOrScalarVec, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(orName, orOp, UV, [v(U, 0.0, 4e9), v(UV, 0.0, 4e9)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseOrScalarVec, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + } + + // The bitwise xor operator. + + binary.push(op(xorName, xorOp, IGT, [v(IGT, -16.0, 16.0), v(IGT, -16.0, 16.0)], f(0.03), f(0.5), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryXor, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(xorName, xorOp, IGT, [v(IGT, -2e9, 2e9), v(IGT, -2e9, 2e9)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryXor, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(xorName, xorOp, UGT, [v(UGT, 0.0, 32.0), v(UGT, 0.0, 32.0)], f(0.03), f(0.0), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryXor, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(xorName, xorOp, UGT, [v(UGT, 0.0, 4e9), v(UGT, 0.0, 4e9)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryXor, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(xorName, xorOp, IV, [v(IV, -16.0, 16.0), v(I, -16.0, 16.0)], f(0.03), f(0.5), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryXorVecScalar, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(xorName, xorOp, IV, [v(IV, -2e9, 2e9), v(I, -2e9, 2e9)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryXorVecScalar, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(xorName, xorOp, UV, [v(UV, 0.0, 32.0), v(U, 0.0, 32.0)], f(0.03), f(0.0), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryXorVecScalar, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(xorName, xorOp, UV, [v(UV, 0.0, 4e9), v(U, 0.0, 4e9)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryXorVecScalar, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + + if (isNormalOp) { + binary.push(op(xorName, xorOp, IV, [v(I, -16.0, 16.0), v(IV, -16.0, 16.0)], f(0.03), f(0.5), + mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseXorScalarVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(xorName, xorOp, IV, [v(I, -2e9, 2e9), v(IV, -2e9, 2e9)], f(4e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseXorScalarVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(xorName, xorOp, UV, [v(U, 0.0, 32.0), v(UV, 0.0, 32.0)], f(0.03), f(0.0), + mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseXorScalarVec, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(xorName, xorOp, UV, [v(U, 0.0, 4e9), v(UV, 0.0, 4e9)], f(2e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseXorScalarVec, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + } + + binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests'); + funcInfoGroups.push(binary); + + // The left shift operator. Second operand (shift amount) can be either int or uint, even for uint and int first operand, respectively. + for (var isSignedAmount = 0; isSignedAmount <= 1; isSignedAmount++) { + var gType = isSignedAmount == 0 ? UGT : IGT; + var sType = isSignedAmount == 0 ? U : I; + binary.push(op(leftShiftName, leftShiftOp, IGT, [v(IGT, -7.0, 7.0), v(gType, 0.0, 4.0)], f(4e-3), f(0.5), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftLeft, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(leftShiftName, leftShiftOp, IGT, [v(IGT, -7.0, 7.0), v(gType, 0.0, 27.0)], f(5e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftLeft, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(leftShiftName, leftShiftOp, UGT, [v(UGT, 0.0, 7.0), v(gType, 0.0, 5.0)], f(4e-3), f(0.0), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftLeft, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(leftShiftName, leftShiftOp, UGT, [v(UGT, 0.0, 7.0), v(gType, 0.0, 28.0)], f(5e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftLeft, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(leftShiftName, leftShiftOp, IV, [v(IV, -7.0, 7.0), v(sType, 0.0, 4.0)], f(4e-3), f(0.5), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftLeftVecScalar, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(leftShiftName, leftShiftOp, IV, [v(IV, -7.0, 7.0), v(sType, 0.0, 27.0)], f(5e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftLeftVecScalar, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(leftShiftName, leftShiftOp, UV, [v(UV, 0.0, 7.0), v(sType, 0.0, 5.0)], f(4e-3), f(0.0), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftLeftVecScalar, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(leftShiftName, leftShiftOp, UV, [v(UV, 0.0, 7.0), v(sType, 0.0, 28.0)], f(5e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftLeftVecScalar, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + } + + // The right shift operator. Second operand (shift amount) can be either int or uint, even for uint and int first operand, respectively. + + for (var isSignedAmount = 0; isSignedAmount <= 1; isSignedAmount++) { + gType = isSignedAmount == 0 ? UGT : IGT; + sType = isSignedAmount == 0 ? U : I; + binary.push(op(rightShiftName, rightShiftOp, IGT, [v(IGT, -127.0, 127.0), v(gType, 0.0, 8.0)], f(4e-3), f(0.5), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftRight, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(rightShiftName, rightShiftOp, IGT, [v(IGT, -2e9, 2e9), v(gType, 0.0, 31.0)], f(5e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftRight, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(rightShiftName, rightShiftOp, UGT, [v(UGT, 0.0, 255.0), v(gType, 0.0, 8.0)], f(4e-3), f(0.0), + mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftRight, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(rightShiftName, rightShiftOp, UGT, [v(UGT, 0.0, 4e9), v(gType, 0.0, 31.0)], f(5e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftRight, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(rightShiftName, rightShiftOp, IV, [v(IV, -127.0, 127.0), v(sType, 0.0, 8.0)], f(4e-3), f(0.5), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftRightVecScalar, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(rightShiftName, rightShiftOp, IV, [v(IV, -2e9, 2e9), v(sType, 0.0, 31.0)], f(5e-10), f(0.5), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftRightVecScalar, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op(rightShiftName, rightShiftOp, UV, [v(UV, 0.0, 255.0), v(sType, 0.0, 8.0)], f(4e-3), f(0.0), + mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftRightVecScalar, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op(rightShiftName, rightShiftOp, UV, [v(UV, 0.0, 4e9), v(sType, 0.0, 31.0)], f(5e-10), f(0.0), + highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftRightVecScalar, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + } + } + + // Rest of binary operators. + // Scalar relational operators. + binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests'); + funcInfoGroups.push(binary); + + binary.push(op('less', '<', B, [v(F, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0), + all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThan).scalar})); + binary.push(op('less', '<', B, [v(I, -5.0, 5.0), v(I, -5.0, 5.0)], f(1.0), f(0.0), + all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThan, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT).scalar})); + binary.push(op('less', '<', B, [v(U, 0.0, 16.0), v(U, 0.0, 16.0)], f(1.0), f(0.0), + all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThan, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT).scalar})); + 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), + all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThanEqual).scalar})); + 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), + all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThanEqual, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT).scalar})); + 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), + all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThanEqual, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT).scalar})); + binary.push(op('greater', '>', B, [v(F, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0), + all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThan).scalar})); + binary.push(op('greater', '>', B, [v(I, -5.0, 5.0), v(I, -5.0, 5.0)], f(1.0), f(0.0), + all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThan, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT).scalar})); + binary.push(op('greater', '>', B, [v(U, 0.0, 16.0), v(U, 0.0, 16.0)], f(1.0), f(0.0), + all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThan, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT).scalar})); + 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), + all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThanEqual).scalar})); + 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), + all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThanEqual, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT).scalar})); + 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), + all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThanEqual, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT).scalar})); + + binary.push(op('equal', '==', B, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(allEqual))); + binary.push(op('equal', '==', B, [v(IGT, -5.5, 4.7), v(IGT, -2.1, 0.1)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(allEqual, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op('equal', '==', B, [v(UGT, 0.0, 8.0), v(UGT, 3.5, 4.5)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(allEqual, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op('equal', '==', B, [v(BGT, -2.1, 2.1), v(BGT, -1.1, 3.0)], f(1.0), f(0.0), + na, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(allEqual, gluShaderUtil.DataType.BOOL, + gluShaderUtil.DataType.BOOL))); + binary.push(op('not_equal', '!=', B, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(anyNotEqual))); + binary.push(op('not_equal', '!=', B, [v(IGT, -5.5, 4.7), v(IGT, -2.1, 0.1)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(anyNotEqual, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + binary.push(op('not_equal', '!=', B, [v(UGT, 0.0, 8.0), v(UGT, 3.5, 4.5)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(anyNotEqual, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + binary.push(op('not_equal', '!=', B, [v(BGT, -2.1, 2.1), v(BGT, -1.1, 3.0)], f(1.0), f(0.0), + na, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(anyNotEqual, gluShaderUtil.DataType.BOOL, + gluShaderUtil.DataType.BOOL))); + + // Logical operators. + binary.push(op('logical_and', '&&', B, [v(B, -1.0, 1.0), v(B, -1.0, 1.0)], f(1.0), f(0.0), + na, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(logicalAnd, gluShaderUtil.DataType.BOOL, + gluShaderUtil.DataType.BOOL).scalar})); + binary.push(op('logical_or', '||', B, [v(B, -1.0, 1.0), v(B, -1.0, 1.0)], f(1.0), f(0.0), + na, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(logicalOr, gluShaderUtil.DataType.BOOL, + gluShaderUtil.DataType.BOOL).scalar})); + binary.push(op('logical_xor', '^^', B, [v(B, -1.0, 1.0), v(B, -1.0, 1.0)], f(1.0), f(0.0), + na, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(logicalXor, gluShaderUtil.DataType.BOOL, + gluShaderUtil.DataType.BOOL).scalar})); + + // 8.1 Angle and Trigonometry Functions. + var trig = new es3fShaderOperatorTests.BuiltinFuncGroup("angle_and_trigonometry", "Angle and trigonometry function tests."); + funcInfoGroups.push(trig); + op = es3fShaderOperatorTests.builtinFunctionInfo; + trig.push(op("radians", "radians", GT, [v(GT, -1.0, 1.0)], f(25.0), f(0.5), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(radians))); + trig.push(op("degrees", "degrees", GT, [v(GT, -1.0, 1.0)], f(0.04), f(0.5), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(degrees))); + trig.push(op("sin", "sin", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sin))); + trig.push(op("sin", "sin", GT, [v(GT, -1.5, 1.5)], f(0.5), f(0.5), + lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sin))); + trig.push(op("cos", "cos", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.cos))); + trig.push(op("cos", "cos", GT, [v(GT, -1.5, 1.5)], f(0.5), f(0.5), + lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.cos))); + trig.push(op("tan", "tan", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.tan))); + trig.push(op("tan", "tan", GT, [v(GT, -1.5, 5.5)], f(0.5), f(0.5), + lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.tan))); + + trig = new es3fShaderOperatorTests.BuiltinFuncGroup("angle_and_trigonometry", "Angle and trigonometry function tests."); + funcInfoGroups.push(trig); + trig.push(op("asin", "asin", GT, [v(GT, -1.0, 1.0)], f(1.0), f(0.0), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.asin))); + trig.push(op("acos", "acos", GT, [v(GT, -1.0, 1.0)], f(1.0), f(0.0), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.acos))); + trig.push(op("atan", "atan", GT, [v(GT, -4.0, 4.0)], f(0.5), f(0.5), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.atan))); + trig.push(op("atan2", "atan", GT, [v(GT, -4.0, 4.0), v(GT, 0.5, 2.0)], f(0.5), f(0.5), + mediumhighp, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.atan2))); + + trig = new es3fShaderOperatorTests.BuiltinFuncGroup("angle_and_trigonometry", "Angle and trigonometry function tests."); + funcInfoGroups.push(trig); + trig.push(op("sinh", "sinh", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sinh))); + trig.push(op("sinh", "sinh", GT, [v(GT, -1.5, 1.5)], f(0.5), f(0.5), + lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sinh))); + trig.push(op("cosh", "cosh", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.cosh))); + trig.push(op("cosh", "cosh", GT, [v(GT, -1.5, 1.5)], f(0.5), f(0.5), + lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.cosh))); + trig.push(op("tanh", "tanh", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.tanh))); + trig.push(op("tanh", "tanh", GT, [v(GT, -1.5, 5.5)], f(0.5), f(0.5), + lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.tanh))); + + trig = new es3fShaderOperatorTests.BuiltinFuncGroup("angle_and_trigonometry", "Angle and trigonometry function tests."); + funcInfoGroups.push(trig); + trig.push(op("asinh", "asinh", GT, [v(GT, -1.0, 1.0)], f(1.0), f(0.0), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.asinh))); + trig.push(op("acosh", "acosh", GT, [v(GT, 1.0, 2.2)], f(1.0), f(0.0), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.acosh))); + // Results are undefined if |x| >= 1, so it diverses from C++ version here. + trig.push(op("atanh", "atanh", GT, [v(GT, -0.99, 0.99)], f(1.0), f(0.0), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.atanh))); + + // 8.2 Exponential Functions. + var exps = new es3fShaderOperatorTests.BuiltinFuncGroup("exponential", "Exponential function tests"); + exps.push(op("pow", "pow", GT, [v(GT, 0.1, 8.0), v(GT, -4.0, 2.0)], f(1.0), f(0.0), + mediumhighp, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.pow))); + exps.push(op("exp", "exp", GT, [v(GT, -6.0, 3.0)], f(0.5), f(0.0), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.exp))); + exps.push(op("log", "log", GT, [v(GT, 0.1, 10.0)], f(0.5), f(0.3), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.log))); + exps.push(op("exp2", "exp2", GT, [v(GT, -7.0, 2.0)], f(1.0), f(0.0), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(exp2))); + exps.push(op("log2", "log2", GT, [v(GT, 0.1, 10.0)], f(1.0), f(0.0), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.log2))); + exps.push(op("sqrt", "sqrt", GT, [v(GT, 0.0, 10.0)], f(0.3), f(0.0), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sqrt))); + exps.push(op("inversesqrt", "inversesqrt", GT, [v(GT, 0.5, 10.0)], f(1.0), f(0.0), + mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(inverseSqrt))); + + funcInfoGroups.push(exps); + + // 8.3 Common Functions. + var comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests."); + funcInfoGroups.push(comm); + comm.push(op("abs", "abs", GT, [v(GT, -2.0, 2.0)], f(0.5), f(0.5), + all, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.abs))); + comm.push(op("sign", "sign", GT, [v(GT, -1.5, 1.5)], f(0.3), f(0.5), + all, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sign))); + comm.push(op("floor", "floor", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.7), + all, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.floor))); + comm.push(op("trunc", "trunc", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.7), + all, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.trunc))); + comm.push(op("round", "round", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.7), + all, es3fShaderOperatorTests.unaryGenTypeFuncs(roundToEven))); + + comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests."); + funcInfoGroups.push(comm); + + comm.push(op("roundEven", "roundEven", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.7), + all, es3fShaderOperatorTests.unaryGenTypeFuncs(roundToEven))); + comm.push(op("ceil", "ceil", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.5), + all, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.ceil))); + comm.push(op("fract", "fract", GT, [v(GT, -1.5, 1.5)], f(0.8), f(0.1), + all, es3fShaderOperatorTests.unaryGenTypeFuncs(fract))); + comm.push(op("mod", "mod", GT, [v(GT, -2.0, 2.0), v(GT, 0.9, 6.0)], f(0.5), f(0.5), + mediumhighp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.mod))); + comm.push(op("mod", "mod", GT, [v(FV, -2.0, 2.0), v(F, 0.9, 6.0)], f(0.5), f(0.5), + mediumhighp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.modScale))); + + comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests."); + funcInfoGroups.push(comm); + + comm.push(op("min", "min", GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(0.5), f(0.5), + all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.min))); + comm.push(op("min", "min", GT, [v(FV, -1.0, 1.0), v(F, -1.0, 1.0)], f(0.5), f(0.5), + all, es3fShaderOperatorTests.binaryVecScalarFuncs(minVecScalar))); + comm.push(op("min", "min", IGT, [v(IGT, -4.0, 4.0), v(IGT, -4.0, 4.0)], f(0.125), f(0.5), + all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.min, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + comm.push(op("min", "min", IGT, [v(IV, -4.0, 4.0), v(I, -4.0, 4.0)], f(0.125), f(0.5), + all, es3fShaderOperatorTests.binaryVecScalarFuncs(minVecScalar, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + comm.push(op("min", "min", UGT, [v(UGT, 0.0, 8.0), v(UGT, 0.0, 8.0)], f(0.125), f(0.0), + all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.min, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + + comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests."); + funcInfoGroups.push(comm); + + comm.push(op("min", "min", UGT, [v(UV, 0.0, 8.0), v(U, 0.0, 8.0)], f(0.125), f(0.0), + all, es3fShaderOperatorTests.binaryVecScalarFuncs(minVecScalar, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + comm.push(op("max", "max", GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(0.5), f(0.5), + all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.max))); + comm.push(op("max", "max", GT, [v(FV, -1.0, 1.0), v(F, -1.0, 1.0)], f(0.5), f(0.5), + all, es3fShaderOperatorTests.binaryVecScalarFuncs(maxVecScalar))); + comm.push(op("max", "max", IGT, [v(IGT, -4.0, 4.0), v(IGT, -4.0, 4.0)], f(0.125), f(0.5), + all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.max, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + comm.push(op("max", "max", IGT, [v(IV, -4.0, 4.0), v(I, -4.0, 4.0)], f(0.125), f(0.5), + all, es3fShaderOperatorTests.binaryVecScalarFuncs(maxVecScalar, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + + comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests."); + funcInfoGroups.push(comm); + + comm.push(op("max", "max", UGT, [v(UGT, 0.0, 8.0), v(UGT, 0.0, 8.0)], f(0.125), f(0.0), + all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.max, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + comm.push(op("max", "max", UGT, [v(UV, 0.0, 8.0), v(U, 0.0, 8.0)], f(0.125), f(0.0), + all, es3fShaderOperatorTests.binaryVecScalarFuncs(maxVecScalar, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + 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), + all, es3fShaderOperatorTests.ternaryGenTypeFuncs(deMath.clamp))); + 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), + all, es3fShaderOperatorTests.ternaryVecScalarScalarFuncs(clampVecScalarScalar))); + 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), + all, es3fShaderOperatorTests.ternaryGenTypeFuncs(deMath.clamp, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + + comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests."); + funcInfoGroups.push(comm); + + 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), + all, es3fShaderOperatorTests.ternaryVecScalarScalarFuncs(clampVecScalarScalar, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + 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), + all, es3fShaderOperatorTests.ternaryGenTypeFuncs(deMath.clamp, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + 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), + all, es3fShaderOperatorTests.ternaryVecScalarScalarFuncs(clampVecScalarScalar, gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT))); + 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), + all, es3fShaderOperatorTests.ternaryGenTypeFuncs(mix))); + 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), + all, es3fShaderOperatorTests.ternaryVecVecScalarFuncs(mixVecVecScalar))); + + comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests."); + funcInfoGroups.push(comm); + + comm.push(op("step", "step", GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 0.0)], f(0.5), f(0.25), + all, es3fShaderOperatorTests.binaryGenTypeFuncs(step))); + comm.push(op("step", "step", GT, [v(F, -1.0, 1.0), v(FV, -1.0, 0.0)], f(0.5), f(0.25), + all, es3fShaderOperatorTests.binaryScalarVecFuncs(stepScalarVec))); + 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), + all, es3fShaderOperatorTests.ternaryGenTypeFuncs(smoothStep))); + 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), + all, es3fShaderOperatorTests.ternaryScalarScalarVecFuncs(smoothStepScalarScalarVec))); + + // 8.4 Geometric Functions. + var geom = new es3fShaderOperatorTests.BuiltinFuncGroup("geometric", "Geometric function tests."); + geom.push(op("length", "length", F, [v(GT, -5.0, 5.0)], f(0.1), f(0.5), + mediumhighp, es3fShaderOperatorTests.unaryScalarGenTypeFuncs(length))); + geom.push(op("distance", "distance", F, [v(GT, -5.0, 5.0), v(GT, -5.0, 5.0)], f(0.1), f(0.5), + mediumhighp, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(distance))); + geom.push(op("dot", "dot", F, [v(GT, -5.0, 5.0), v(GT, -5.0, 5.0)], f(0.1), f(0.5), + mediumhighp, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(dot))); + geom.push(op("cross", "cross", V3, [v(GT, -5.0, 5.0), v(GT, -5.0, 5.0)], f(0.1), f(0.5), + mediumhighp, {vec3: es3fShaderOperatorTests.binaryVecVecFuncs(cross).vec3})); + geom.push(op("normalize", "normalize", GT, [v(GT, 0.1, 4.0)], f(0.5), f(0.5), + mediumhighp, es3fShaderOperatorTests.unaryArrayFuncs(normalize))); + 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), + mediumhighp, es3fShaderOperatorTests.ternaryVecVecVecFuncs(faceforward))); + geom.push(op("reflect", "reflect", GT, [v(GT, -0.8, -0.5), v(GT, 0.5, 0.8)], f(0.5), f(0.5), + mediumhighp, es3fShaderOperatorTests.binaryVecVecFuncs(reflect))); + 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), + mediumhighp, es3fShaderOperatorTests.ternaryVecVecScalarFuncs(refract))); + + funcInfoGroups.push(geom); + + // 8.6 Vector Relational Functions. + var floatComp = new es3fShaderOperatorTests.BuiltinFuncGroup("float_compare", "Floating point comparison tests."); + floatComp.push(op("lessThan", "lessThan", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryVecVecFuncs(lessThanVec))); + floatComp.push(op("lessThanEqual", "lessThanEqual", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryVecVecFuncs(lessThanEqualVec))); + floatComp.push(op("greaterThan", "greaterThan", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryVecVecFuncs(greaterThanVec))); + floatComp.push(op("greaterThanEqual", "greaterThanEqual", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryVecVecFuncs(greaterThanEqualVec))); + floatComp.push(op("equal", "equal", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryVecVecFuncs(allEqualVec))); + floatComp.push(op("notEqual", "notEqual", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryVecVecFuncs(anyNotEqualVec))); + + funcInfoGroups.push(floatComp); + + var intComp = new es3fShaderOperatorTests.BuiltinFuncGroup("int_compare", "Integer comparison tests."); + intComp.push(op("lessThan", "lessThan", BV, [v(IV, 5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryVecVecFuncs(lessThanVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + intComp.push(op("lessThanEqual", "lessThanEqual", BV, [v(IV, -5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryVecVecFuncs(lessThanEqualVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + intComp.push(op("greaterThan", "greaterThan", BV, [v(IV, -5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryVecVecFuncs(greaterThanVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + intComp.push(op("greaterThanEqual", "greaterThanEqual", BV, [v(IV, -5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryVecVecFuncs(greaterThanEqualVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + intComp.push(op("equal", "equal", BV, [v(IV, -5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryVecVecFuncs(allEqualVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + intComp.push(op("notEqual", "notEqual", BV, [v(IV, -5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0), + all, es3fShaderOperatorTests.binaryVecVecFuncs(anyNotEqualVec, gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT))); + + funcInfoGroups.push(intComp); + + var boolComp = new es3fShaderOperatorTests.BuiltinFuncGroup("bool_compare", "Boolean comparison tests."); + var evalBoolEqual = es3fShaderOperatorTests.binaryVecVecFuncs(allEqualVec, gluShaderUtil.DataType.BOOL, + gluShaderUtil.DataType.BOOL); + var evalBoolNotEqual = es3fShaderOperatorTests.binaryVecVecFuncs(anyNotEqualVec, gluShaderUtil.DataType.BOOL, + gluShaderUtil.DataType.BOOL); + var evalBoolAny = es3fShaderOperatorTests.unaryBooleanGenTypeFuncs(boolAny, gluShaderUtil.DataType.BOOL, + gluShaderUtil.DataType.BOOL); + evalBoolAny.scalar = null; + var evalBoolAll = es3fShaderOperatorTests.unaryBooleanGenTypeFuncs(boolAll, gluShaderUtil.DataType.BOOL, + gluShaderUtil.DataType.BOOL); + evalBoolAll.scalar = null; + var evalBoolNot = es3fShaderOperatorTests.unaryArrayFuncs(boolNotVec, gluShaderUtil.DataType.BOOL, + gluShaderUtil.DataType.BOOL); + evalBoolNot.scalar = null; + + boolComp.push(op("equal", "equal", BV, [v(BV, -5.2, 4.9), v(BV, -5.0, 5.0)], f(1.0), f(0.0), + na, evalBoolEqual)); + boolComp.push(op("notEqual", "notEqual", BV, [v(BV, -5.2, 4.9), v(BV, -5.0, 5.0)], f(1.0), f(0.0), + na, evalBoolNotEqual)); + boolComp.push(op("any", "any", B, [v(BV, -1.0, 0.3)], f(1.0), f(0.0), + na, evalBoolAny)); + boolComp.push(op("all", "all", B, [v(BV, -0.3, 1.0)], f(1.0), f(0.0), + na, evalBoolAll)); + boolComp.push(op("not", "not", BV, [v(BV, -1.0, 1.0)], f(1.0), f(0.0), + na, evalBoolNot)); + + funcInfoGroups.push(boolComp); + + var s_shaderTypes = [ + gluShaderProgram.shaderType.VERTEX, + gluShaderProgram.shaderType.FRAGMENT + ]; + + var s_floatTypes = [ + gluShaderUtil.DataType.FLOAT, + gluShaderUtil.DataType.FLOAT_VEC2, + gluShaderUtil.DataType.FLOAT_VEC3, + gluShaderUtil.DataType.FLOAT_VEC4 + ]; + + var s_intTypes = [ + gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT_VEC2, + gluShaderUtil.DataType.INT_VEC3, + gluShaderUtil.DataType.INT_VEC4 + ]; + + var s_uintTypes = [ + gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT_VEC2, + gluShaderUtil.DataType.UINT_VEC3, + gluShaderUtil.DataType.UINT_VEC4 + ]; + + var s_boolTypes = [ + gluShaderUtil.DataType.BOOL, + gluShaderUtil.DataType.BOOL_VEC2, + gluShaderUtil.DataType.BOOL_VEC3, + gluShaderUtil.DataType.BOOL_VEC4 + ]; + + for (var outerGroupNdx = 0; outerGroupNdx < funcInfoGroups.length; outerGroupNdx++) { + // Create outer group. + var outerGroupInfo = funcInfoGroups[outerGroupNdx]; + var outerGroup = new tcuTestCase.DeqpTest(outerGroupInfo.name, outerGroupInfo.description); + this.addChild(outerGroup); + + // Only create new group if name differs from previous one. + var innerGroup = null; + + for (var funcInfoNdx = 0; funcInfoNdx < outerGroupInfo.funcInfos.length; funcInfoNdx++) { + var funcInfo = outerGroupInfo.funcInfos[funcInfoNdx]; + var shaderFuncName = funcInfo.shaderFuncName; + var isBoolCase = (funcInfo.precision == es3fShaderOperatorTests.Precision.None); + var isBoolOut = es3fShaderOperatorTests.isBoolType(funcInfo.outValue); + var isIntOut = es3fShaderOperatorTests.isIntType(funcInfo.outValue); + var isUintOut = es3fShaderOperatorTests.isUintType(funcInfo.outValue); + var isFloatOut = !isBoolOut && !isIntOut && !isUintOut; + + if (!innerGroup || (innerGroup.name != funcInfo.caseName)) { + var groupDesc = 'Built-in function ' + shaderFuncName + '() tests.'; + innerGroup = new tcuTestCase.DeqpTest(funcInfo.caseName, groupDesc); + outerGroup.addChild(innerGroup); + } + + for (var inScalarSize = 1; inScalarSize <= 4; inScalarSize++) { + var outScalarSize = ((funcInfo.outValue == es3fShaderOperatorTests.ValueType.FLOAT) || (funcInfo.outValue == es3fShaderOperatorTests.ValueType.BOOL)) ? 1 : inScalarSize; // \todo [petri] Int. + var outDataType = isFloatOut ? s_floatTypes[outScalarSize - 1] : + isIntOut ? s_intTypes[outScalarSize - 1] : + isUintOut ? s_uintTypes[outScalarSize - 1] : + isBoolOut ? s_boolTypes[outScalarSize - 1] : + undefined; + + var evalFunc = null; + if (inScalarSize == 1) evalFunc = funcInfo.evalFunctions.scalar; + else if (inScalarSize == 2) evalFunc = funcInfo.evalFunctions.vec2; + else if (inScalarSize == 3) evalFunc = funcInfo.evalFunctions.vec3; + else if (inScalarSize == 4) evalFunc = funcInfo.evalFunctions.vec4; + else throw new Error('Invalid scalar size ' + inScalarSize); + + // Skip if no valid eval func. + // \todo [petri] Better check for V3 only etc. cases? + if (evalFunc == null) + continue; + + var precisions = ['low', 'medium', 'high']; + for (var precId = 0; precId < precisions.length; precId++) { + var precision = precisions[precId]; + if ((funcInfo.precision[precision]) || + (funcInfo.precision == es3fShaderOperatorTests.Precision.None && precision === 'medium')) { // use mediump interpolators for booleans + var precisionPrefix = isBoolCase ? '' : precision + 'p_'; + + for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) { + var shaderType = s_shaderTypes[shaderTypeNdx]; + var shaderSpec = new es3fShaderOperatorTests.ShaderDataSpec(); + var shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType); + var isVertexCase = shaderType == gluShaderProgram.shaderType.VERTEX; + var isUnaryOp = (funcInfo.inputs.length == 1); + + // \note Data type names will be added to description and name in a following loop. + var desc = 'Built-in function ' + shaderFuncName + '('; + var name = precisionPrefix; + + // Generate shader op. + var shaderOp = 'res = '; + + var precNames = [gluShaderUtil.precision.PRECISION_LOWP, + gluShaderUtil.precision.PRECISION_MEDIUMP, + gluShaderUtil.precision.PRECISION_HIGHP]; + // Setup shader data info. + shaderSpec.numInputs = 0; + shaderSpec.precision = isBoolCase ? undefined : precNames[precId]; + shaderSpec.output = outDataType; + shaderSpec.resultScale = funcInfo.resultScale; + shaderSpec.resultBias = funcInfo.resultBias; + shaderSpec.referenceScale = funcInfo.referenceScale; + shaderSpec.referenceBias = funcInfo.referenceBias; + + if (funcInfo.type == es3fShaderOperatorTests.OperationType.OPERATOR) { + if (isUnaryOp && funcInfo.isUnaryPrefix) + shaderOp += shaderFuncName; + } else if (funcInfo.type == es3fShaderOperatorTests.OperationType.FUNCTION) + shaderOp += shaderFuncName + '('; + else // SIDE_EFFECT_OPERATOR + shaderOp += 'in0;\n\t'; + + for (var inputNdx = 0; inputNdx < funcInfo.inputs.length; inputNdx++) { + var prevNdx = inputNdx > 0 ? inputNdx - 1 : funcInfo.inputs.length - 1; + var prevValue = funcInfo.inputs[prevNdx]; + var value = funcInfo.inputs[inputNdx]; + + if (value.valueType == es3fShaderOperatorTests.ValueType.NONE) + continue; // Skip unused input. + + var prevInScalarSize = es3fShaderOperatorTests.isScalarType(prevValue.valueType) ? 1 : inScalarSize; + var prevInDataType = es3fShaderOperatorTests.isFloatType(prevValue.valueType) ? s_floatTypes[prevInScalarSize - 1] : + es3fShaderOperatorTests.isIntType(prevValue.valueType) ? s_intTypes[prevInScalarSize - 1] : + es3fShaderOperatorTests.isUintType(prevValue.valueType) ? s_uintTypes[prevInScalarSize - 1] : + es3fShaderOperatorTests.isBoolType(prevValue.valueType) ? s_boolTypes[prevInScalarSize - 1] : + undefined; + + var curInScalarSize = es3fShaderOperatorTests.isScalarType(value.valueType) ? 1 : inScalarSize; + var curInDataType = es3fShaderOperatorTests.isFloatType(value.valueType) ? s_floatTypes[curInScalarSize - 1] : + es3fShaderOperatorTests.isIntType(value.valueType) ? s_intTypes[curInScalarSize - 1] : + es3fShaderOperatorTests.isUintType(value.valueType) ? s_uintTypes[curInScalarSize - 1] : + es3fShaderOperatorTests.isBoolType(value.valueType) ? s_boolTypes[curInScalarSize - 1] : + undefined; + + // Write input type(s) to case description and name. + + if (inputNdx > 0) + desc += ', '; + + desc += gluShaderUtil.getDataTypeName(curInDataType); + + if (inputNdx == 0 || prevInDataType != curInDataType) // \note Only write input type to case name if different from previous input type (avoid overly long names). + name += gluShaderUtil.getDataTypeName(curInDataType) + '_'; + + // Generate op input source. + + if (funcInfo.type == es3fShaderOperatorTests.OperationType.OPERATOR || funcInfo.type == es3fShaderOperatorTests.OperationType.FUNCTION) { + if (inputNdx != 0) { + if (funcInfo.type == es3fShaderOperatorTests.OperationType.OPERATOR && !isUnaryOp) + shaderOp += ' ' + shaderFuncName + ' '; + else + shaderOp += ', '; + } + + shaderOp += 'in' + inputNdx.toString(10); + + if (funcInfo.type == es3fShaderOperatorTests.OperationType.OPERATOR && isUnaryOp && !funcInfo.isUnaryPrefix) + shaderOp += shaderFuncName; + } else{ + if (inputNdx != 0 || (isUnaryOp && funcInfo.isUnaryPrefix)) + shaderOp += (isUnaryOp ? '' : ' ') + shaderFuncName + (isUnaryOp ? '' : ' '); + + shaderOp += inputNdx == 0 ? 'res' : 'in' + inputNdx.toString(10); // \note in0 has already been assigned to res, so start from in1. + + if (isUnaryOp && !funcInfo.isUnaryPrefix) + shaderOp += shaderFuncName; + } + + // Fill in shader info. + shaderSpec.inputs[shaderSpec.numInputs++] = new es3fShaderOperatorTests.ShaderValue(curInDataType, value.rangeMin, value.rangeMax); + } + + if (funcInfo.type == es3fShaderOperatorTests.OperationType.FUNCTION) + shaderOp += ')'; + + shaderOp += ';'; + + desc += ').'; + name += shaderTypeName; + + // Create the test case. + innerGroup.addChild(new es3fShaderOperatorTests.ShaderOperatorCase(name, desc, isVertexCase, evalFunc, shaderOp, shaderSpec)); + } + } + } + } + } + } + + // The ?: selection operator. + + var s_selectionInfo = [ + gluShaderUtil.DataType.FLOAT, + gluShaderUtil.DataType.FLOAT_VEC2, + gluShaderUtil.DataType.FLOAT_VEC3, + gluShaderUtil.DataType.FLOAT_VEC4, + gluShaderUtil.DataType.INT, + gluShaderUtil.DataType.INT_VEC2, + gluShaderUtil.DataType.INT_VEC3, + gluShaderUtil.DataType.INT_VEC4, + gluShaderUtil.DataType.UINT, + gluShaderUtil.DataType.UINT_VEC2, + gluShaderUtil.DataType.UINT_VEC3, + gluShaderUtil.DataType.UINT_VEC4, + gluShaderUtil.DataType.BOOL, + gluShaderUtil.DataType.BOOL_VEC2, + gluShaderUtil.DataType.BOOL_VEC3, + gluShaderUtil.DataType.BOOL_VEC4 + ]; + + var selectionEvalFuncsFloat = es3fShaderOperatorTests.selectionFuncs(gluShaderUtil.DataType.FLOAT); + var selectionEvalFuncsInt = es3fShaderOperatorTests.selectionFuncs(gluShaderUtil.DataType.INT); + var selectionEvalFuncsUint = es3fShaderOperatorTests.selectionFuncs(gluShaderUtil.DataType.UINT); + var selectionEvalFuncsBool = es3fShaderOperatorTests.selectionFuncs(gluShaderUtil.DataType.BOOL); + + var selectionGroup = new tcuTestCase.DeqpTest('selection', 'Selection operator tests'); + this.addChild(selectionGroup); + + for (var typeNdx = 0; typeNdx < s_selectionInfo.length; typeNdx++) { + var curType = s_selectionInfo[typeNdx]; + var scalarSize = gluShaderUtil.getDataTypeScalarSize(curType); + var isBoolCase = gluShaderUtil.isDataTypeBoolOrBVec(curType); + var isFloatCase = gluShaderUtil.isDataTypeFloatOrVec(curType); + var isIntCase = gluShaderUtil.isDataTypeIntOrIVec(curType); + var isUintCase = gluShaderUtil.isDataTypeUintOrUVec(curType); + var dataTypeStr = gluShaderUtil.getDataTypeName(curType); + + var evalFuncs = selectionEvalFuncsFloat; + if (isBoolCase) + evalFuncs = selectionEvalFuncsBool; + else if (isIntCase) + evalFuncs = selectionEvalFuncsInt; + else if (isUintCase) + evalFuncs = selectionEvalFuncsUint; + + var evalFunc = evalFuncs[scalarSize]; + + for (var prec in gluShaderUtil.precision) { + var precision = gluShaderUtil.precision[prec]; + if (isBoolCase && precision != gluShaderUtil.precision.PRECISION_MEDIUMP) // Use mediump interpolators for booleans. + continue; + + var precisionStr = gluShaderUtil.getPrecisionName(precision); + var precisionPrefix = isBoolCase ? '' : (precisionStr + '_'); + + for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) { + var shaderType = s_shaderTypes[shaderTypeNdx]; + var shaderSpec = new es3fShaderOperatorTests.ShaderDataSpec(); + var shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType); + var isVertexCase = shaderType == gluShaderProgram.shaderType.VERTEX; + + var name = precisionPrefix + dataTypeStr + '_' + shaderTypeName; + + shaderSpec.numInputs = 3; + shaderSpec.precision = isBoolCase ? undefined : precision; + shaderSpec.output = curType; + shaderSpec.resultScale = isBoolCase ? f(1.0) : isFloatCase ? f(0.5) : isUintCase ? f(0.5) : f(0.1); + shaderSpec.resultBias = isBoolCase ? f(0.0) : isFloatCase ? f(0.5) : isUintCase ? f(0.0) : f(0.5); + shaderSpec.referenceScale = shaderSpec.resultScale; + shaderSpec.referenceBias = shaderSpec.resultBias; + + var rangeMin = isBoolCase ? -1.0 : isFloatCase ? -1.0 : isUintCase ? 0.0 : -5.0; + var rangeMax = isBoolCase ? 1.0 : isFloatCase ? 1.0 : isUintCase ? 2.0 : 5.0; + + shaderSpec.inputs[0] = new es3fShaderOperatorTests.ShaderValue(gluShaderUtil.DataType.BOOL, f(-1.0), f(1.0)); + shaderSpec.inputs[1] = new es3fShaderOperatorTests.ShaderValue(curType, f(rangeMin), f(rangeMax)); + shaderSpec.inputs[2] = new es3fShaderOperatorTests.ShaderValue(curType, f(rangeMin), f(rangeMax)); + + selectionGroup.addChild(new es3fShaderOperatorTests.ShaderOperatorCase(name, '', isVertexCase, evalFunc, 'res = in0 ? in1 : in2;', shaderSpec)); + } + } + } + + // The sequence operator (comma). + /** @type {tcuTestCase.DeqpTest} */ var sequenceGroup = new tcuTestCase.DeqpTest('sequence', 'sequence'); + this.addChild(sequenceGroup); + + /** @type {tcuTestCase.DeqpTest} */ var sequenceNoSideEffGroup = new tcuTestCase.DeqpTest('no_side_effects', 'Sequence tests without side-effects'); + /** @type {tcuTestCase.DeqpTest} */ var sequenceSideEffGroup = new tcuTestCase.DeqpTest('side_effects', 'Sequence tests with side-effects'); + sequenceGroup.addChild(sequenceNoSideEffGroup); + sequenceGroup.addChild(sequenceSideEffGroup); + + /** + * @struct + * @constructor + * @param {boolean} containsSideEffects + * @param {string} caseName + * @param {string} expressionStr + * @param {number} numInputs + * @param {Array<gluShaderUtil.DataType>} inputTypes + * @param {gluShaderUtil.DataType} resultType + * @param {glsShaderRenderCase.ShaderEvalFunc} evalFunc + */ + var SequenceCase = function(containsSideEffects, caseName, expressionStr, numInputs, inputTypes, resultType, evalFunc) { + /** @type {boolean} */ this.containsSideEffects = containsSideEffects; + /** @type {string} */ this.caseName = caseName; + /** @type {string} */ this.expressionStr = expressionStr; + /** @type {number} */ this.numInputs = numInputs; + /** @type {Array<gluShaderUtil.DataType>} */ this.inputTypes = inputTypes; + /** @type {gluShaderUtil.DataType} */ this.resultType = resultType; + /** @type {glsShaderRenderCase.ShaderEvalFunc} */ this.evalFunc = evalFunc; + }; + + /** @type {Array<SequenceCase>} */ var s_sequenceCases = [ + 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), + new SequenceCase(false, 'float_uint', 'in0 + in2, in1 + in1', 3, [gluShaderUtil.DataType.FLOAT, gluShaderUtil.DataType.UINT, gluShaderUtil.DataType.FLOAT], gluShaderUtil.DataType.UINT, es3fShaderOperatorTests.evalSequenceNoSideEffCase1), + 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), + 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), + + 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), + 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), + 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), + 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) + ]; + + for (var caseNdx = 0; caseNdx < s_sequenceCases.length; caseNdx++) { + for (var precision in gluShaderUtil.precision) { + for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) { + /** @type {gluShaderProgram.shaderType} */ var shaderType = s_shaderTypes[shaderTypeNdx]; + /** @type {es3fShaderOperatorTests.ShaderDataSpec} */ var shaderSpec = new es3fShaderOperatorTests.ShaderDataSpec(); + /** @type {string} */ var shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType); + /** @type {boolean} */ var isVertexCase = shaderType === gluShaderProgram.shaderType.VERTEX; + + /** @type {string} */ var name = gluShaderUtil.getPrecisionName(gluShaderUtil.precision[precision]) + '_' + s_sequenceCases[caseNdx].caseName + '_' + shaderTypeName; + + shaderSpec.numInputs = s_sequenceCases[caseNdx].numInputs; + shaderSpec.precision = gluShaderUtil.precision[precision]; + shaderSpec.output = s_sequenceCases[caseNdx].resultType; + shaderSpec.resultScale = f(0.5); + shaderSpec.resultBias = f(0.0); + shaderSpec.referenceScale = shaderSpec.resultScale; + shaderSpec.referenceBias = shaderSpec.resultBias; + + for (var inputNdx = 0; inputNdx < s_sequenceCases[caseNdx].numInputs; inputNdx++) { + /** @type {gluShaderUtil.DataType} */ var type = s_sequenceCases[caseNdx].inputTypes[inputNdx]; + /** @type {es3fShaderOperatorTests.FloatScalar} */ var rangeMin = gluShaderUtil.isDataTypeFloatOrVec(type) ? + f(-0.5) : gluShaderUtil.isDataTypeIntOrIVec(type) ? + f(-2.0) : gluShaderUtil.isDataTypeUintOrUVec(type) ? + f(0.0) : f(-1.0); + + /** @type {es3fShaderOperatorTests.FloatScalar} */ var rangeMax = gluShaderUtil.isDataTypeFloatOrVec(type) ? + f(0.5) : gluShaderUtil.isDataTypeIntOrIVec(type) ? + f(2.0) : gluShaderUtil.isDataTypeUintOrUVec(type) ? + f(2.0) : f(1.0); + + shaderSpec.inputs[inputNdx] = new es3fShaderOperatorTests.ShaderValue(type, rangeMin, rangeMax); + } + + /** @type {string} */ var expression = 'res = (' + s_sequenceCases[caseNdx].expressionStr + ');'; + + if (s_sequenceCases[caseNdx].containsSideEffects) + sequenceSideEffGroup.addChild(new es3fShaderOperatorTests.ShaderOperatorCase(name, '', isVertexCase, s_sequenceCases[caseNdx].evalFunc, expression, shaderSpec)); + else + sequenceNoSideEffGroup.addChild(new es3fShaderOperatorTests.ShaderOperatorCase(name, '', isVertexCase, s_sequenceCases[caseNdx].evalFunc, expression, shaderSpec)); + } + } + } + +}; + +/** +* Run test +* @param {WebGL2RenderingContext} context +*/ +es3fShaderOperatorTests.run = function(context, range) { + gl = context; + + const canvas = gl.canvas; + canvas.width = canvasWH; + canvas.height = canvasWH; + + //Set up Test Root parameters + var state = tcuTestCase.runner; + state.setRoot(new es3fShaderOperatorTests.ShaderOperatorTests()); + + //Set up name and description of this test series. + setCurrentTestName(state.testCases.fullName()); + description(state.testCases.getDescription()); + + try { + if (range) + state.setRange(range); + //Run test cases + tcuTestCase.runTestCases(); + } + catch (err) { + testFailedOptions('Failed to es3fShaderOperatorTests.run tests', false); + tcuTestCase.runner.terminate(); + } +}; + +}); |