/*------------------------------------------------------------------------- * 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('modules.shared.glsBuiltinPrecisionTests'); goog.require('framework.common.tcuFloatFormat'); goog.require('framework.common.tcuInterval'); goog.require('framework.common.tcuMatrix'); goog.require('framework.common.tcuMatrixUtil'); goog.require('framework.common.tcuTestCase'); goog.require('framework.delibs.debase.deMath'); goog.require('framework.delibs.debase.deRandom'); goog.require('framework.delibs.debase.deUtil'); goog.require('framework.opengl.gluShaderProgram'); goog.require('framework.opengl.gluShaderUtil'); goog.require('framework.opengl.gluVarType'); goog.require('framework.opengl.simplereference.sglrGLContext'); goog.require('modules.shared.glsBuiltinPrecisionTestsUnitTests'); goog.require('modules.shared.glsShaderExecUtil'); goog.scope(function() { var glsBuiltinPrecisionTests = modules.shared.glsBuiltinPrecisionTests; var tcuTestCase = framework.common.tcuTestCase; var gluShaderProgram = framework.opengl.gluShaderProgram; var gluShaderUtil = framework.opengl.gluShaderUtil; var tcuInterval = framework.common.tcuInterval; var tcuFloatFormat = framework.common.tcuFloatFormat; var deRandom = framework.delibs.debase.deRandom; var glsShaderExecUtil = modules.shared.glsShaderExecUtil; var sglrGLContext = framework.opengl.simplereference.sglrGLContext; var deMath = framework.delibs.debase.deMath; var deUtil = framework.delibs.debase.deUtil; var gluVarType = framework.opengl.gluVarType; var tcuMatrix = framework.common.tcuMatrix; var tcuMatrixUtil = framework.common.tcuMatrixUtil; var ref = modules.shared.glsBuiltinPrecisionTestsUnitTests.cppreference; var referenceComparison = modules.shared.glsBuiltinPrecisionTestsUnitTests.referenceComparison; var DE_ASSERT = function(x) { if (!x) throw new Error('Assert failed'); }; var setParentClass = function(child, parent) { child.prototype = Object.create(parent.prototype); child.prototype.constructor = child; }; /** @typedef {(tcuInterval.Interval|Array|tcuMatrix.Matrix)} */ glsBuiltinPrecisionTests.Intervals; /** @typedef {(number|Array|tcuMatrix.Matrix)} */ glsBuiltinPrecisionTests.Value; /** @typedef {(string)} */ glsBuiltinPrecisionTests.Typename; //Change to true for WebGL unit testing var enableUnittests = false; /** * @param {number} value * @return {boolean} */ glsBuiltinPrecisionTests.isFloat = function(value) { return value % 1 !== 0; }; /** * @constructor * @param {string} R * @param {string=} P0 * @param {string=} P1 * @param {string=} P2 * @param {string=} P3 */ glsBuiltinPrecisionTests.Signature = function(R, P0, P1, P2, P3) { this.Ret = R; this.Arg0 = P0 === undefined ? 'void' : P0; this.Arg1 = P1 === undefined ? 'void' : P1; this.Arg2 = P2 === undefined ? 'void' : P2; this.Arg3 = P3 === undefined ? 'void' : P3; }; /** @typedef {Array} */ glsBuiltinPrecisionTests.FuncSet; /** * @constructor * @template T * @param {T} A0 * @param {T} A1 * @param {T} A2 * @param {T} A3 */ glsBuiltinPrecisionTests.Tuple4 = function(A0, A1, A2, A3) { this.a = A0; this.b = A1; this.c = A2; this.d = A3; }; /** * @typedef {!glsBuiltinPrecisionTests.Tuple4} */ glsBuiltinPrecisionTests.ParamNames; /** * Returns true for all other types except Void * @param {string} typename */ glsBuiltinPrecisionTests.isTypeValid = function(typename) { if (typename === 'void') return false; return true; }; /** * Returns true for all other types except Void * @param {*} In * @return {number} */ glsBuiltinPrecisionTests.numInputs = function(In) { return (!glsBuiltinPrecisionTests.isTypeValid(In.In0) ? 0 : !glsBuiltinPrecisionTests.isTypeValid(In.In1) ? 1 : !glsBuiltinPrecisionTests.isTypeValid(In.In2) ? 2 : !glsBuiltinPrecisionTests.isTypeValid(In.In3) ? 3 : 4); }; /** * Returns true for all other types except Void * @param {*} Out * @return {number} */ glsBuiltinPrecisionTests.numOutputs = function(Out) { return (!glsBuiltinPrecisionTests.isTypeValid(Out.Out0) ? 0 : !glsBuiltinPrecisionTests.isTypeValid(Out.Out1) ? 1 : 2); }; /** * @constructor * @param {glsBuiltinPrecisionTests.Typename=} In0_ * @param {glsBuiltinPrecisionTests.Typename=} In1_ * @param {glsBuiltinPrecisionTests.Typename=} In2_ * @param {glsBuiltinPrecisionTests.Typename=} In3_ */ glsBuiltinPrecisionTests.InTypes = function(In0_, In1_, In2_, In3_) { this.In0 = In0_ === undefined ? 'void' : In0_; this.In1 = In1_ === undefined ? 'void' : In1_; this.In2 = In2_ === undefined ? 'void' : In2_; this.In3 = In3_ === undefined ? 'void' : In3_; }; /** * @constructor * @param {glsBuiltinPrecisionTests.Typename=} Out0_ * @param {glsBuiltinPrecisionTests.Typename=} Out1_ */ glsBuiltinPrecisionTests.OutTypes = function(Out0_, Out1_) { this.Out0 = Out0_ === undefined ? 'void' : Out0_; this.Out1 = Out1_ === undefined ? 'void' : Out1_; }; /** * @constructor */ glsBuiltinPrecisionTests.Environment = function() { /** @type {Object} */ this.m_map = {}; }; /** * @param {glsBuiltinPrecisionTests.Variable} variable * @param {*} value */ glsBuiltinPrecisionTests.Environment.prototype.bind = function(variable, value) { this.m_map[variable.getName()] = value; }; /** * @param {*} variable * @return {glsBuiltinPrecisionTests.Intervals} */ glsBuiltinPrecisionTests.Environment.prototype.lookup = function(variable) { if (variable instanceof glsBuiltinPrecisionTests.Variable) return this.m_map[variable.getName()]; throw new Error('Invalid lookup input: ' + variable); }; /** * @constructor * @param {tcuFloatFormat.FloatFormat} format_ * @param {gluShaderUtil.precision} floatPrecision_ * @param {glsBuiltinPrecisionTests.Environment} env_ * @param {number=} callDepth_ */ glsBuiltinPrecisionTests.EvalContext = function(format_, floatPrecision_, env_, callDepth_) { this.format = format_; this.floatPrecision = floatPrecision_; this.env = env_; this.callDepth = callDepth_ === undefined ? 0 : callDepth_; }; /** * @param {string} typename typename * @param {tcuFloatFormat.FloatFormat} fmt * @param {glsBuiltinPrecisionTests.Intervals} value * @return {glsBuiltinPrecisionTests.Intervals} */ glsBuiltinPrecisionTests.convert = function(typename, fmt, value) { var traits = glsBuiltinPrecisionTests.Traits.traitsFactory(typename); if (value instanceof Array) { var ret = []; for (var i = 0; i < value.length; i++) ret.push(traits.doConvert(fmt, value[i])); return ret; } if (value instanceof tcuMatrix.Matrix) { var ret = new tcuMatrix.Matrix(value.rows, value.cols); for (var i = 0; i < value.rows; i++) for (var j = 0; j < value.cols; j++) ret.set(i, j, traits.doConvert(fmt, value.get(i, j))); return ret; } return traits.doConvert(fmt, value); }; /** * Returns true if every element of `ival` contains the corresponding element of `value`. * @param {string} typename typename * @param {glsBuiltinPrecisionTests.Intervals} ival * @param {*} value * @return {boolean} */ glsBuiltinPrecisionTests.contains = function(typename, ival, value) { var traits = glsBuiltinPrecisionTests.Traits.traitsFactory(typename); var contains = true; if (value instanceof Array) { for (var i = 0; i < value.length; i++) contains &= traits.doContains(ival[i], value[i]); return contains; } if (value instanceof tcuMatrix.Matrix) { for (var i = 0; i < value.rows; i++) for (var j = 0; j < value.cols; j++) contains &= traits.doContains(ival.get(i, j), value.get(i, j)); return contains; } return traits.doContains(ival, value); }; /** * @param {string} typename typename * @param {glsBuiltinPrecisionTests.Intervals} ival0 * @param {glsBuiltinPrecisionTests.Intervals} ival1 * @return {glsBuiltinPrecisionTests.Intervals} */ glsBuiltinPrecisionTests.union = function(typename, ival0, ival1) { var traits = glsBuiltinPrecisionTests.Traits.traitsFactory(typename); if (ival0 instanceof Array) { var ret = []; for (var i = 0; i < ival0.length; i++) ret.push(traits.doUnion(ival0[i], ival1[i])); return ret; } if (ival0 instanceof tcuMatrix.Matrix) { var ret = new tcuMatrix.Matrix(ival0.rows, ival0.cols); for (var i = 0; i < ival0.rows; i++) for (var j = 0; j < ival0.cols; j++) ret.set(i, j, traits.doUnion(ival0.get(i, j), ival1.get(i, j))); return ret; } return traits.doUnion(ival0, ival1); }; /** * @param {string} typename * @constructor */ glsBuiltinPrecisionTests.Traits = function(typename) { this.typename = typename; this.rows = 1; this.cols = 1; }; glsBuiltinPrecisionTests.Traits.prototype.isScalar = function() { return this.rows == 1 && this.cols == 1; }; glsBuiltinPrecisionTests.Traits.prototype.isVector = function() { return this.rows > 0 && this.cols == 1; }; glsBuiltinPrecisionTests.Traits.prototype.isMatrix = function() { return this.rows > 0 && this.cols > 1; }; /** * @param {string=} typename */ glsBuiltinPrecisionTests.Traits.traitsFactory = function(typename) { switch (typename) { case 'boolean' : return new glsBuiltinPrecisionTests.TraitsBool(); case 'float' : case 'vec2' : case 'vec3' : case 'vec4' : case 'mat2' : case 'mat2x3' : case 'mat2x4' : case 'mat3x2' : case 'mat3' : case 'mat3x4' : case 'mat4x2' : case 'mat4x3' : case 'mat4' : return new glsBuiltinPrecisionTests.TraitsFloat(typename); case 'int' : return new glsBuiltinPrecisionTests.TraitsInt(); case 'void' : return new glsBuiltinPrecisionTests.TraitsVoid(); default: throw new Error('Invalid typename:' + typename); } }; glsBuiltinPrecisionTests.round = function(typename, fmt, value) { var traits = glsBuiltinPrecisionTests.Traits.traitsFactory(typename); if (value instanceof Array) { var ret = []; for (var i = 0; i < value.length; i++) ret.push(traits.doRound(fmt, value[i])); return ret; } if (value instanceof tcuMatrix.Matrix) { var ret = new tcuMatrix.Matrix(value.rows, value.cols); for (var i = 0; i < value.rows; i++) for (var j = 0; j < value.cols; j++) ret.set(i, j, traits.doRound(fmt, value.get(i, j))); return ret; } return traits.doRound(fmt, value); }; /** * cast the input typed array to correct type * @param {string} typename * @param {goog.TypedArray} input * @return {goog.TypedArray} */ glsBuiltinPrecisionTests.cast = function(typename, input) { var traits = glsBuiltinPrecisionTests.Traits.traitsFactory(typename); return traits.doCast(input); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Traits} */ glsBuiltinPrecisionTests.TraitsVoid = function() { glsBuiltinPrecisionTests.Traits.call(this, 'void'); }; setParentClass(glsBuiltinPrecisionTests.TraitsVoid, glsBuiltinPrecisionTests.Traits); /** * @param {*} value * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.TraitsVoid.prototype.doMakeIVal = function(value) { return new tcuInterval.Interval(); }; /** * @param {*} value1 * @param {*} value2 * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.TraitsVoid.prototype.doUnion = function(value1, value2) { return new tcuInterval.Interval(); }; /** * @param {*} value * @return {boolean} */ glsBuiltinPrecisionTests.TraitsVoid.prototype.doContains = function(value) { return true; }; /** * @param {tcuFloatFormat.FloatFormat} fmt * @param {tcuInterval.Interval} ival * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.TraitsVoid.prototype.doConvert = function(fmt, ival) { return new tcuInterval.Interval(); }; /** * @param {tcuFloatFormat.FloatFormat} fmt * @param {*} ival * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.TraitsVoid.prototype.doRound = function(fmt, ival) { return new tcuInterval.Interval(); }; /** * @param {tcuFloatFormat.FloatFormat} fmt * @param {*} ival */ glsBuiltinPrecisionTests.TraitsVoid.prototype.doPrintIVal = function(fmt, ival) { return '()'; }; /** * @param {tcuFloatFormat.FloatFormat} fmt * @param {*} value */ glsBuiltinPrecisionTests.TraitsVoid.prototype.doPrintValue = function(fmt, value) { return '()'; }; glsBuiltinPrecisionTests.dataTypeSize = function(detailedType) { var size = [1, 1]; switch (detailedType) { case 'vec2' : size[0] = 2; break; case 'vec3' : size[0] = 3; break; case 'vec4' : size[0] = 4; break; case 'mat2' : size = [2 , 2]; break; case 'mat2x3' : size = [3 , 2]; break; case 'mat2x4' : size = [4 , 2]; break; case 'mat3x2' : size = [2 , 3]; break; case 'mat3' : size = [3 , 3]; break; case 'mat3x4' : size = [4 , 3]; break; case 'mat4x2' : size = [2 , 4]; break; case 'mat4x3' : size = [3 , 4]; break; case 'mat4' : size = [4 , 4]; break; } return size; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Traits} * @param {string} typename * @param {string=} detailedType */ glsBuiltinPrecisionTests.ScalarTraits = function(typename, detailedType) { glsBuiltinPrecisionTests.Traits.call(this, typename); var size = glsBuiltinPrecisionTests.dataTypeSize(detailedType); this.rows = size[0]; this.cols = size[1]; /** type{tcuInterval.Interval} */ this.iVal; }; setParentClass(glsBuiltinPrecisionTests.ScalarTraits, glsBuiltinPrecisionTests.Traits); glsBuiltinPrecisionTests.ScalarTraits.prototype = Object.create(glsBuiltinPrecisionTests.Traits.prototype); glsBuiltinPrecisionTests.ScalarTraits.prototype.constructor = glsBuiltinPrecisionTests.ScalarTraits; /** * @param {*} value * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.ScalarTraits.prototype.doMakeIVal = function(value) { // Thankfully all scalar types have a well-defined conversion to `double`, // hence Interval can represent their ranges without problems. return new tcuInterval.Interval(/** @type {number} */ (value)); }; /** * @param {tcuInterval.Interval} a * @param {tcuInterval.Interval} b * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.ScalarTraits.prototype.doUnion = function(a, b) { return a.operatorOrBinary(b); }; /** * @param {tcuInterval.Interval} a * @param {number} value * @return {boolean} */ glsBuiltinPrecisionTests.ScalarTraits.prototype.doContains = function(a, value) { return a.contains(new tcuInterval.Interval(value)); }; /** * @param {tcuFloatFormat.FloatFormat} fmt * @param {tcuInterval.Interval} ival * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.ScalarTraits.prototype.doConvert = function(fmt, ival) { return fmt.convert(ival); }; /** * @param {tcuFloatFormat.FloatFormat} fmt * @param {number} value * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.ScalarTraits.prototype.doRound = function(fmt, value) { return fmt.roundOut(new tcuInterval.Interval(value), false);//TODO cast to double }; /** * @constructor * @extends {glsBuiltinPrecisionTests.ScalarTraits} * @param {string} detailedType */ glsBuiltinPrecisionTests.TraitsFloat = function(detailedType) { glsBuiltinPrecisionTests.ScalarTraits.call(this, 'float', detailedType); }; glsBuiltinPrecisionTests.TraitsFloat.prototype = Object.create(glsBuiltinPrecisionTests.ScalarTraits.prototype); glsBuiltinPrecisionTests.TraitsFloat.prototype.constructor = glsBuiltinPrecisionTests.TraitsFloat; /** * @param {tcuFloatFormat.FloatFormat} fmt * @param {tcuInterval.Interval} ival */ glsBuiltinPrecisionTests.TraitsFloat.prototype.doPrintIVal = function(fmt, ival) { return fmt.intervalToHex(ival); }; /** * @param {goog.TypedArray} input * @return {goog.TypedArray} */ glsBuiltinPrecisionTests.TraitsFloat.prototype.doCast = function(input) { return new Float32Array(input.buffer); }; /** * @param {tcuFloatFormat.FloatFormat} fmt * @param {number} value */ glsBuiltinPrecisionTests.TraitsFloat.prototype.doPrintValue = function(fmt, value) { return fmt.floatToHex(value); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.ScalarTraits} */ glsBuiltinPrecisionTests.TraitsBool = function() { glsBuiltinPrecisionTests.ScalarTraits.call(this, 'boolean'); }; glsBuiltinPrecisionTests.TraitsBool.prototype = Object.create(glsBuiltinPrecisionTests.ScalarTraits.prototype); glsBuiltinPrecisionTests.TraitsBool.prototype.constructor = glsBuiltinPrecisionTests.TraitsBool; /** * @param {tcuFloatFormat.FloatFormat} fmt * @param {tcuInterval.Interval} ival */ glsBuiltinPrecisionTests.TraitsBool.prototype.doPrintIVal = function(fmt, ival) { /** type{string} */ var os = '{'; var ifalse = new tcuInterval.Interval(0); var itrue = new tcuInterval.Interval(1); if (ival.contains(ifalse)) os += 'false'; if (ival.contains(ifalse) && ival.contains(itrue)) os += ', '; if (ival.contains(itrue)) os += 'true'; os += '}'; return os; }; /** * @param {tcuFloatFormat.FloatFormat} fmt * @param {boolean} value */ glsBuiltinPrecisionTests.TraitsBool.prototype.doPrintValue = function(fmt, value) { return value ? 'true' : 'false'; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.ScalarTraits} */ glsBuiltinPrecisionTests.TraitsInt = function() { glsBuiltinPrecisionTests.ScalarTraits.call(this, 'int'); }; glsBuiltinPrecisionTests.TraitsInt.prototype = Object.create(glsBuiltinPrecisionTests.ScalarTraits.prototype); glsBuiltinPrecisionTests.TraitsInt.prototype.constructor = glsBuiltinPrecisionTests.TraitsInt; /** * @param {tcuFloatFormat.FloatFormat} fmt * @param {tcuInterval.Interval} ival */ glsBuiltinPrecisionTests.TraitsInt.prototype.doPrintIVal = function(fmt, ival) { return '[' + (ival.lo()) + ', ' + (ival.hi()) + ']'; }; /** * @param {tcuFloatFormat.FloatFormat} fmt * @param {number} value */ glsBuiltinPrecisionTests.TraitsInt.prototype.doPrintValue = function(fmt, value) { return value.toString(10); }; /** * @constructor */ glsBuiltinPrecisionTests.Statement = function() { }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx */ glsBuiltinPrecisionTests.Statement.prototype.execute = function(ctx) { this.doExecute(ctx); }; /** * @return {string} */ glsBuiltinPrecisionTests.Statement.prototype.print = function() { return this.doPrint(); }; glsBuiltinPrecisionTests.Statement.prototype.toString = function() { return this.print(); }; /** * Output the functions that this expression refers to * @param {glsBuiltinPrecisionTests.FuncSet} dst * */ glsBuiltinPrecisionTests.Statement.prototype.getUsedFuncs = function(dst) { this.doGetUsedFuncs(dst); }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx */ glsBuiltinPrecisionTests.Statement.prototype.doExecute = function(ctx) { throw new Error('Virtual function. Please override.'); }; /** * @return {string} */ glsBuiltinPrecisionTests.Statement.prototype.doPrint = function() { throw new Error('Virtual function. Please override.'); }; /** * Output the functions that this expression refers to * @param {glsBuiltinPrecisionTests.FuncSet} dst * */ glsBuiltinPrecisionTests.Statement.prototype.doGetUsedFuncs = function(dst) { throw new Error('Virtual function. Please override.'); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Statement} * @param {glsBuiltinPrecisionTests.Variable} variable * @param {glsBuiltinPrecisionTests.Expr} value * @param {boolean} isDeclaration */ glsBuiltinPrecisionTests.VariableStatement = function(variable, value, isDeclaration) { this.m_variable = variable; this.m_value = value; this.m_isDeclaration = isDeclaration; }; setParentClass(glsBuiltinPrecisionTests.VariableStatement, glsBuiltinPrecisionTests.Statement); /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx */ glsBuiltinPrecisionTests.VariableStatement.prototype.doExecute = function(ctx) { ctx.env.bind(this.m_variable, this.m_value.evaluate(ctx)); }; /** * @return {string} */ glsBuiltinPrecisionTests.VariableStatement.prototype.doPrint = function() { var v = this.m_variable; var os = ''; if (this.m_isDeclaration) os += gluVarType.declareVariable(gluVarType.getVarTypeOf(v.typename), v.getName()); else os += v.getName(); os += ' = ' + this.m_value.printExpr() + ';\n'; return os; }; /** * Output the functions that this expression refers to * @param {glsBuiltinPrecisionTests.FuncSet} dst * */ glsBuiltinPrecisionTests.VariableStatement.prototype.doGetUsedFuncs = function(dst) { this.m_value.getUsedFuncs(dst); }; /** * @param {glsBuiltinPrecisionTests.Variable} variable * @param {glsBuiltinPrecisionTests.Expr} definiens * @return {glsBuiltinPrecisionTests.VariableStatement} */ glsBuiltinPrecisionTests.variableDeclaration = function(variable, definiens) { return new glsBuiltinPrecisionTests.VariableStatement(variable, definiens, true); }; /** * @param {string} typename * @param {string} name * @param {glsBuiltinPrecisionTests.ExpandContext} ctx * @param {glsBuiltinPrecisionTests.Expr} expr * @return {glsBuiltinPrecisionTests.Variable} */ glsBuiltinPrecisionTests.bindExpression = function(typename, name, ctx, expr) { var variable = ctx.genSym(typename, name); ctx.addStatement(glsBuiltinPrecisionTests.variableDeclaration(variable, expr)); return variable; }; /** * Common base class for all expressions regardless of their type. * @constructor */ glsBuiltinPrecisionTests.ExprBase = function() {}; /** * @return {string} */ glsBuiltinPrecisionTests.ExprBase.prototype.printExpr = function() { return this.doPrintExpr(); }; glsBuiltinPrecisionTests.ExprBase.prototype.toString = function() { return this.printExpr(); }; /** * @return {string} */ glsBuiltinPrecisionTests.ExprBase.prototype.doPrintExpr = function() { throw new Error('Virtual function. Please override.'); }; /** * Output the functions that this expression refers to * @param {glsBuiltinPrecisionTests.FuncSet} dst * */ glsBuiltinPrecisionTests.ExprBase.prototype.getUsedFuncs = function(/*FuncSet&*/ dst) { this.doGetUsedFuncs(dst); }; /** * Output the functions that this expression refers to * @param {glsBuiltinPrecisionTests.FuncSet} dst * */ glsBuiltinPrecisionTests.ExprBase.prototype.doGetUsedFuncs = function(/*FuncSet&*/ dst) { throw new Error('Virtual function. Please override.'); }; /** * Type-specific operations for an expression representing type typename. * @constructor * @extends {glsBuiltinPrecisionTests.ExprBase} * @param {glsBuiltinPrecisionTests.Typename} typename */ glsBuiltinPrecisionTests.Expr = function(typename) { glsBuiltinPrecisionTests.ExprBase.call(this); this.typename = typename; }; setParentClass(glsBuiltinPrecisionTests.Expr, glsBuiltinPrecisionTests.ExprBase); /** * Type-specific operations for an expression representing type typename. * @param {glsBuiltinPrecisionTests.EvalContext} ctx */ glsBuiltinPrecisionTests.Expr.prototype.evaluate = function(ctx) { return this.doEvaluate(ctx); }; /** * Type-specific operations for an expression representing type typename. * @param {glsBuiltinPrecisionTests.EvalContext} ctx */ glsBuiltinPrecisionTests.Expr.prototype.doEvaluate = function(ctx) { throw new Error('Virtual function. Please override.'); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Expr} * @param {glsBuiltinPrecisionTests.Typename} typename * @param {string=} name */ glsBuiltinPrecisionTests.Variable = function(typename, name) { glsBuiltinPrecisionTests.Expr.call(this, typename); /** @type {string} */ this.m_name = name || ''; }; setParentClass(glsBuiltinPrecisionTests.Variable, glsBuiltinPrecisionTests.Expr); /** * @return {string} */ glsBuiltinPrecisionTests.Variable.prototype.getName = function() { return this.m_name; }; /** * @return {string} */ glsBuiltinPrecisionTests.Variable.prototype.doPrintExpr = function() { return this.m_name; }; glsBuiltinPrecisionTests.Variable.prototype.toString = function() { return this.doPrintExpr(); }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @return {*} */ glsBuiltinPrecisionTests.Variable.prototype.doEvaluate = function(ctx) { return ctx.env.lookup(this); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Variable} * @param {*=} t */ glsBuiltinPrecisionTests.Void = function(t) { glsBuiltinPrecisionTests.Variable.call(this, 'void'); }; setParentClass(glsBuiltinPrecisionTests.Void, glsBuiltinPrecisionTests.Variable); glsBuiltinPrecisionTests.Void.prototype.doEvaluate = function(ctx) { return undefined; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Variable} * @param {number} value */ glsBuiltinPrecisionTests.Constant = function(value) { glsBuiltinPrecisionTests.Variable.call(this, 'float'); this.m_value = value; }; setParentClass(glsBuiltinPrecisionTests.Constant, glsBuiltinPrecisionTests.Variable); glsBuiltinPrecisionTests.Constant.prototype.doEvaluate = function(ctx) { return new tcuInterval.Interval(this.m_value); }; /** * @constructor * @param {*} typename */ glsBuiltinPrecisionTests.DefaultSampling = function(typename) { this.typename = typename; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Expr} * @param {glsBuiltinPrecisionTests.Variable} vector * @param {number} index */ glsBuiltinPrecisionTests.VectorVariable = function(vector, index) { glsBuiltinPrecisionTests.Expr.call(this, vector.typename); this.m_vector = vector; this.m_index = index; }; setParentClass(glsBuiltinPrecisionTests.VectorVariable, glsBuiltinPrecisionTests.Expr); /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.VectorVariable.prototype.doEvaluate = function(ctx) { var tmp = this.m_vector.doEvaluate(ctx); return tmp[this.m_index]; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Expr} * @param {glsBuiltinPrecisionTests.Variable} matrix * @param {number} row * @param {number} col */ glsBuiltinPrecisionTests.MatrixVariable = function(matrix, row, col) { glsBuiltinPrecisionTests.Expr.call(this, matrix.typename); this.m_matrix = matrix; this.m_row = row; this.m_col = col; }; setParentClass(glsBuiltinPrecisionTests.MatrixVariable, glsBuiltinPrecisionTests.Expr); /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.MatrixVariable.prototype.doEvaluate = function(ctx) { var tmp = this.m_matrix.doEvaluate(ctx); return tmp.get(this.m_row, this.m_col); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Expr} * @param {glsBuiltinPrecisionTests.Typename} typename * @param {glsBuiltinPrecisionTests.Func} func * @param {glsBuiltinPrecisionTests.Expr=} arg0 * @param {glsBuiltinPrecisionTests.Expr=} arg1 * @param {glsBuiltinPrecisionTests.Expr=} arg2 * @param {glsBuiltinPrecisionTests.Expr=} arg3 */ glsBuiltinPrecisionTests.Apply = function(typename, func, arg0, arg1, arg2, arg3) { glsBuiltinPrecisionTests.Expr.call(this, typename); this.m_func = func; /** @type {glsBuiltinPrecisionTests.Tuple4} */ this.m_args; if (arg0 instanceof glsBuiltinPrecisionTests.Tuple4) this.m_args = /** @type {glsBuiltinPrecisionTests.Tuple4} */ (arg0); else { this.m_args = new glsBuiltinPrecisionTests.Tuple4(arg0 || new glsBuiltinPrecisionTests.Void(), arg1 || new glsBuiltinPrecisionTests.Void(), arg2 || new glsBuiltinPrecisionTests.Void(), arg3 || new glsBuiltinPrecisionTests.Void()); } }; setParentClass(glsBuiltinPrecisionTests.Apply, glsBuiltinPrecisionTests.Expr); /** * @return {string} */ glsBuiltinPrecisionTests.Apply.prototype.doPrintExpr = function() { var args = [this.m_args.a, this.m_args.b, this.m_args.c, this.m_args.d]; return this.m_func.print(args); }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @return {glsBuiltinPrecisionTests.Intervals} */ glsBuiltinPrecisionTests.Apply.prototype.doEvaluate = function(ctx) { var debug = false; if (debug) { glsBuiltinPrecisionTests.Apply.prototype.doEvaluate.level = glsBuiltinPrecisionTests.Apply.prototype.doEvaluate.level || 0; var level = glsBuiltinPrecisionTests.Apply.prototype.doEvaluate.level; glsBuiltinPrecisionTests.Apply.prototype.doEvaluate.level++; var name = this.m_func.constructor.toString(); name = name.replace(/[\s\S]*glsBuiltinPrecisionTests\./m, '').replace(/\.call[\s\S]*/m, ''); if (this.m_func.getName) name += ' ' + this.m_func.getName(); console.log('<' + level + '> Function ' + name); } var a = this.m_args.a.evaluate(ctx); var b = this.m_args.b.evaluate(ctx); var c = this.m_args.c.evaluate(ctx); var d = this.m_args.d.evaluate(ctx); var retVal = this.m_func.applyFunction(ctx, a, b, c, d); if (debug) { console.log('<' + level + '> a: ' + a); console.log('<' + level + '> b: ' + b); console.log('<' + level + '> returning: ' + retVal); glsBuiltinPrecisionTests.Apply.prototype.doEvaluate.level--; } return retVal; }; /** * @param {glsBuiltinPrecisionTests.Func} func * @param {glsBuiltinPrecisionTests.Expr=} arg0 * @param {glsBuiltinPrecisionTests.Expr=} arg1 * @param {glsBuiltinPrecisionTests.Expr=} arg2 * @param {glsBuiltinPrecisionTests.Expr=} arg3 */ var app = function(func, arg0, arg1, arg2, arg3) { return new glsBuiltinPrecisionTests.Apply('float', func, arg0, arg1, arg2, arg3); }; /** * @param {glsBuiltinPrecisionTests.FuncSet} dst */ glsBuiltinPrecisionTests.Apply.prototype.doGetUsedFuncs = function(dst) { this.m_func.getUsedFuncs(dst); this.m_args.a.getUsedFuncs(dst); this.m_args.b.getUsedFuncs(dst); this.m_args.c.getUsedFuncs(dst); this.m_args.d.getUsedFuncs(dst); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Apply} * @param {glsBuiltinPrecisionTests.Func} func * @param {glsBuiltinPrecisionTests.Expr=} arg0 * @param {glsBuiltinPrecisionTests.Expr=} arg1 * @param {glsBuiltinPrecisionTests.Expr=} arg2 * @param {glsBuiltinPrecisionTests.Expr=} arg3 */ glsBuiltinPrecisionTests.ApplyScalar = function(func, arg0, arg1, arg2, arg3) { glsBuiltinPrecisionTests.Apply.call(this, 'float', func, arg0, arg1, arg2, arg3); }; setParentClass(glsBuiltinPrecisionTests.ApplyScalar, glsBuiltinPrecisionTests.Apply); glsBuiltinPrecisionTests.ApplyScalar.prototype.doEvaluate = function(ctx) { var debug = false; if (debug) { glsBuiltinPrecisionTests.ApplyScalar.prototype.doEvaluate.level = glsBuiltinPrecisionTests.ApplyScalar.prototype.doEvaluate.level || 0; var level = glsBuiltinPrecisionTests.ApplyScalar.prototype.doEvaluate.level; glsBuiltinPrecisionTests.ApplyScalar.prototype.doEvaluate.level++; var name = this.m_func.constructor.toString(); name = name.replace(/[\s\S]*glsBuiltinPrecisionTests\./m, '').replace(/\.call[\s\S]*/m, ''); if (this.m_func.getName) name += ' ' + this.m_func.getName(); console.log('scalar<' + level + '> Function ' + name); } var a = this.m_args.a.evaluate(ctx); var b = this.m_args.b.evaluate(ctx); var c = this.m_args.c.evaluate(ctx); var d = this.m_args.d.evaluate(ctx); if (a instanceof Array) { var ret = []; for (var i = 0; i < a.length; i++) { var p0 = a instanceof Array ? a[i] : a; var p1 = b instanceof Array ? b[i] : b; var p2 = c instanceof Array ? c[i] : c; var p3 = d instanceof Array ? d[i] : d; ret.push(this.m_func.applyFunction(ctx, p0, p1, p2, p3)); } return ret; } var retVal = this.m_func.applyFunction(ctx, a, b, c, d); if (debug) { console.log('scalar<' + level + '> a: ' + a); console.log('scalar<' + level + '> b: ' + b); console.log('scalar<' + level + '> return1: ' + ret); console.log('scalar<' + level + '> return2: ' + retVal); glsBuiltinPrecisionTests.Apply.prototype.doEvaluate.level--; } return retVal; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Apply} */ glsBuiltinPrecisionTests.ApplyVar = function(typename, func, arg0, arg1, arg2, arg3) { glsBuiltinPrecisionTests.Apply.call(this, typename, func, arg0, arg1, arg2, arg3); }; setParentClass(glsBuiltinPrecisionTests.ApplyVar, glsBuiltinPrecisionTests.Apply); /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @return {glsBuiltinPrecisionTests.Intervals} */ glsBuiltinPrecisionTests.ApplyVar.prototype.doEvaluate = function(ctx) { return this.m_func.applyFunction(ctx, ctx.env.lookup(this.m_args.a), ctx.env.lookup(this.m_args.b), ctx.env.lookup(this.m_args.c), ctx.env.lookup(this.m_args.d), [this.m_args.a.getName(), this.m_args.b.getName(), this.m_args.c.getName(), this.m_args.d.getName()]); }; /** * @constructor */ glsBuiltinPrecisionTests.FuncBase = function() {}; /** * @return {string} */ glsBuiltinPrecisionTests.FuncBase.prototype.getName = function() { return ''; }; /** * @return {string} */ glsBuiltinPrecisionTests.FuncBase.prototype.getRequiredExtension = function() { return ''; }; /** * @param {Array} args * @return {string} */ glsBuiltinPrecisionTests.FuncBase.prototype.print = function(args) { return ''; }; /** * Index of output parameter, or -1 if none of the parameters is output. * @return {number} */ glsBuiltinPrecisionTests.FuncBase.prototype.getOutParamIndex = function() { return -1; }; /** * @return {string} */ glsBuiltinPrecisionTests.FuncBase.prototype.printDefinition = function() { return this.doPrintDefinition(); }; /** * @return {string} */ glsBuiltinPrecisionTests.FuncBase.prototype.doPrintDefinition = function() { throw new Error('Virtual function. Please override.'); }; /** * typedef set FuncSet; * @param {glsBuiltinPrecisionTests.FuncSet} dst */ glsBuiltinPrecisionTests.FuncBase.prototype.getUsedFuncs = function(dst) { this.doGetUsedFuncs(dst); }; /** * @param {glsBuiltinPrecisionTests.FuncSet} dst */ glsBuiltinPrecisionTests.FuncBase.prototype.doGetUsedFuncs = function(dst) {}; /*************************************/ /** * \brief Function objects. * * Each Func object represents a GLSL function. It can be applied to interval * arguments, and it returns the an interval that is a conservative * approximation of the image of the GLSL function over the argument * intervals. That is, it is given a set of possible arguments and it returns * the set of possible values. * * @constructor * @extends {glsBuiltinPrecisionTests.FuncBase} * @param {glsBuiltinPrecisionTests.Signature} Sig_ template */ glsBuiltinPrecisionTests.Func = function(Sig_) { glsBuiltinPrecisionTests.FuncBase.call(this); this.Sig = Sig_; this.Ret = this.Sig.Ret; this.Arg0 = this.Sig.Arg0; this.Arg1 = this.Sig.Arg1; this.Arg2 = this.Sig.Arg2; this.Arg3 = this.Sig.Arg3; }; glsBuiltinPrecisionTests.Func.prototype = Object.create(glsBuiltinPrecisionTests.FuncBase.prototype); glsBuiltinPrecisionTests.Func.prototype.constructor = glsBuiltinPrecisionTests.Func; /** * @param {Array} args * @return {string} */ glsBuiltinPrecisionTests.Func.prototype.print = function(args) { return this.doPrint(args); }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {glsBuiltinPrecisionTests.Intervals=} Iarg0 * @param {glsBuiltinPrecisionTests.Intervals=} Iarg1 * @param {glsBuiltinPrecisionTests.Intervals=} Iarg2 * @param {glsBuiltinPrecisionTests.Intervals=} Iarg3 * @return {glsBuiltinPrecisionTests.Intervals} */ glsBuiltinPrecisionTests.Func.prototype.applyFunction = function(ctx, Iarg0, Iarg1, Iarg2, Iarg3, variablenames) { return this.applyArgs(ctx, new glsBuiltinPrecisionTests.Tuple4(Iarg0, Iarg1, Iarg2, Iarg3), variablenames); }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {glsBuiltinPrecisionTests.Tuple4} args * @return {glsBuiltinPrecisionTests.Intervals} */ glsBuiltinPrecisionTests.Func.prototype.applyArgs = function(ctx, args, variablenames) { return this.doApply(ctx, args, variablenames); }; /** * @return {glsBuiltinPrecisionTests.ParamNames} */ glsBuiltinPrecisionTests.Func.prototype.getParamNames = function() { return this.doGetParamNames(); }; /** * @param {Array} args * @return {string} */ glsBuiltinPrecisionTests.Func.prototype.doPrint = function(args) { /** type{string} */ var os = this.getName() + '('; // TODO: fix the generics for (var i = 0; i < args.length; i++) if (glsBuiltinPrecisionTests.isTypeValid(args[i].typename)) { if (i != 0) os += ', '; os += args[i]; } os += ')'; return os; }; /** * @return {glsBuiltinPrecisionTests.ParamNames} args */ glsBuiltinPrecisionTests.Func.prototype.doGetParamNames = function() { /** @type {glsBuiltinPrecisionTests.ParamNames} */ var names = new glsBuiltinPrecisionTests.Tuple4('a', 'b', 'c', 'd'); return names; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Func} * @param {glsBuiltinPrecisionTests.Signature} Sig template * */ glsBuiltinPrecisionTests.PrimitiveFunc = function(Sig) { glsBuiltinPrecisionTests.Func.call(this, Sig); this.Ret = Sig.Ret; }; glsBuiltinPrecisionTests.PrimitiveFunc.prototype = Object.create(glsBuiltinPrecisionTests.Func.prototype); glsBuiltinPrecisionTests.PrimitiveFunc.prototype.constructor = glsBuiltinPrecisionTests.PrimitiveFunc; /** * @constructor * @extends {glsBuiltinPrecisionTests.PrimitiveFunc} * @param {string} typename * */ glsBuiltinPrecisionTests.Cond = function(typename) { var sig = new glsBuiltinPrecisionTests.Signature(typename, 'boolean', typename, typename); glsBuiltinPrecisionTests.PrimitiveFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.Cond, glsBuiltinPrecisionTests.PrimitiveFunc); glsBuiltinPrecisionTests.Cond.prototype.getName = function() { return '_cond'; }; glsBuiltinPrecisionTests.Cond.prototype.doPrint = function(args) { var str = '(' + args[0] + ' ? ' + args[1] + ' : ' + args[2] + ')'; return str; }; glsBuiltinPrecisionTests.Cond.prototype.doApply = function(ctx, iargs) { var ret; if (glsBuiltinPrecisionTests.contains(this.Sig.Arg0, iargs.a, 1)) ret = iargs.b; if (glsBuiltinPrecisionTests.contains(this.Sig.Arg0, iargs.a, 0)) { if (ret) ret = glsBuiltinPrecisionTests.union(this.Sig.Ret, ret, iargs.c); else ret = iargs.c; } if (ret) return ret; return new tcuInterval.Interval(); }; /** * If multipleInputs is false, GenVec duplicates first input to proper size * @constructor * @extends {glsBuiltinPrecisionTests.PrimitiveFunc} * @param {number} size * @param {boolean=} multipleInputs */ glsBuiltinPrecisionTests.GenVec = function(size, multipleInputs) { var vecName = glsBuiltinPrecisionTests.sizeToName(size); var p = [ size >= 1 ? 'float' : undefined, size >= 2 ? 'float' : undefined, size >= 3 ? 'float' : undefined, size >= 4 ? 'float' : undefined ]; var sig = new glsBuiltinPrecisionTests.Signature(vecName, p[0], p[1], p[2], p[3]); glsBuiltinPrecisionTests.PrimitiveFunc.call(this, sig); this.size = size; this.vecName = vecName; this.multipleInputs = multipleInputs || false; }; setParentClass(glsBuiltinPrecisionTests.GenVec, glsBuiltinPrecisionTests.PrimitiveFunc); glsBuiltinPrecisionTests.GenVec.prototype.getName = function() { return this.vecName; }; glsBuiltinPrecisionTests.GenVec.prototype.doApply = function(ctx, iargs) { if (this.size == 1) return iargs.a; var ret = this.multipleInputs ? [iargs.a, iargs.b, iargs.c, iargs.d] : [iargs.a, iargs.a, iargs.a, iargs.a]; return ret.slice(0, this.size); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.PrimitiveFunc} * @param {number} rows * @param {number} cols */ glsBuiltinPrecisionTests.GenMat = function(rows, cols) { var name = glsBuiltinPrecisionTests.dataTypeNameOfMatrix('float', rows, cols); var vecName = glsBuiltinPrecisionTests.sizeToName(rows); var p = [ cols >= 1 ? vecName : undefined, cols >= 2 ? vecName : undefined, cols >= 3 ? vecName : undefined, cols >= 4 ? vecName : undefined ]; var sig = new glsBuiltinPrecisionTests.Signature(name, p[0], p[1], p[2], p[3]); glsBuiltinPrecisionTests.PrimitiveFunc.call(this, sig); this.rows = rows; this.cols = cols; this.name = name; this.vecName = vecName; }; setParentClass(glsBuiltinPrecisionTests.GenMat, glsBuiltinPrecisionTests.PrimitiveFunc); glsBuiltinPrecisionTests.GenMat.prototype.getName = function() { return this.name; }; glsBuiltinPrecisionTests.GenMat.prototype.doApply = function(ctx, iargs) { var ret = new tcuMatrix.Matrix(this.rows, this.cols); var inputs = [iargs.a, iargs.b, iargs.c, iargs.d]; for (var i = 0; i < this.rows; i++) for (var j = 0; j < this.cols; j++) ret.set(i, j, inputs[j][i]); return ret; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.PrimitiveFunc} * @param {string} typename * */ glsBuiltinPrecisionTests.CompareOperator = function(typename) { var sig = new glsBuiltinPrecisionTests.Signature('boolean', typename, typename); glsBuiltinPrecisionTests.PrimitiveFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.CompareOperator, glsBuiltinPrecisionTests.PrimitiveFunc); glsBuiltinPrecisionTests.CompareOperator.prototype.doPrint = function(args) { var str = '(' + args[0] + this.getSymbol() + args[1] + ')'; return str; }; glsBuiltinPrecisionTests.CompareOperator.prototype.doApply = function(ctx, iargs) { var arg0 = iargs.a; var arg1 = iargs.b; var ret = new tcuInterval.Interval(); if (this.canSucceed(arg0, arg1)) ret = new tcuInterval.Interval(1); if (this.canFail(arg0, arg1)) ret.operatorOrAssignBinary(new tcuInterval.Interval(0)); return ret; }; /** * @return {string} */ glsBuiltinPrecisionTests.CompareOperator.prototype.getSymbol = function() { throw new Error('Virtual function. Please override.'); }; /** * @param {tcuInterval.Interval} arg0 * @param {tcuInterval.Interval} arg1 * @return {boolean} */ glsBuiltinPrecisionTests.CompareOperator.prototype.canSucceed = function(arg0, arg1) { throw new Error('Virtual function. Please override.'); }; /** * @param {tcuInterval.Interval} arg0 * @param {tcuInterval.Interval} arg1 * @return {boolean} */ glsBuiltinPrecisionTests.CompareOperator.prototype.canFail = function(arg0, arg1) { throw new Error('Virtual function. Please override.'); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.CompareOperator} * @param {string} typename * */ glsBuiltinPrecisionTests.LessThan = function(typename) { glsBuiltinPrecisionTests.CompareOperator.call(this, typename); }; setParentClass(glsBuiltinPrecisionTests.LessThan, glsBuiltinPrecisionTests.CompareOperator); glsBuiltinPrecisionTests.LessThan.prototype.getSymbol = function() { return '<'; }; glsBuiltinPrecisionTests.LessThan.prototype.canSucceed = function(a, b) { return (a.lo() < b.hi()); }; glsBuiltinPrecisionTests.LessThan.prototype.canFail = function(a, b) { return !(a.hi() < b.lo()); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.PrimitiveFunc} * */ glsBuiltinPrecisionTests.FloatFunc1 = function() { var sig = new glsBuiltinPrecisionTests.Signature('float', 'float'); glsBuiltinPrecisionTests.PrimitiveFunc.call(this, sig); }; glsBuiltinPrecisionTests.FloatFunc1.prototype = Object.create(glsBuiltinPrecisionTests.PrimitiveFunc.prototype); glsBuiltinPrecisionTests.FloatFunc1.prototype.constructor = glsBuiltinPrecisionTests.FloatFunc1; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {glsBuiltinPrecisionTests.Tuple4} iargs * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.FloatFunc1.prototype.doApply = function(ctx, iargs) { var a = /** @type {tcuInterval.Interval} */ (iargs.a); return this.applyMonotone(ctx, a); }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {tcuInterval.Interval} iarg0 * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.FloatFunc1.prototype.applyMonotone = function(ctx, iarg0) { /** @type {tcuInterval.Interval} */ var ret = new tcuInterval.Interval(); /** * @param {number=} x * @param {number=} y * @return {tcuInterval.Interval} */ var body = function(x, y) { x = x || 0; return this.applyPoint(ctx, x); }; ret = tcuInterval.applyMonotone1(iarg0, body.bind(this)); ret.operatorOrAssignBinary(this.innerExtrema(ctx, iarg0)); ret.operatorAndAssignBinary(this.getCodomain().operatorOrBinary(new tcuInterval.Interval(NaN))); return ctx.format.convert(ret); }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {tcuInterval.Interval} iargs * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.FloatFunc1.prototype.innerExtrema = function(ctx, iargs) { return new tcuInterval.Interval(); // empty interval, i.e. no extrema }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {number} arg0 * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.FloatFunc1.prototype.applyPoint = function(ctx, arg0) { var exact = this.applyExact(arg0); var prec = this.precision(ctx, exact, arg0); var a = new tcuInterval.Interval(exact); var b = tcuInterval.withNumbers(-prec, prec); return tcuInterval.Interval.operatorSum(a, b); }; /** * @param {number} x * @return {number} */ glsBuiltinPrecisionTests.FloatFunc1.prototype.applyExact = function(x) { throw new Error('Internal error. Cannot apply'); }; /** * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.FloatFunc1.prototype.getCodomain = function() { return tcuInterval.unbounded(true); }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {number} x * @param {number} y * @return {number} */ glsBuiltinPrecisionTests.FloatFunc1.prototype.precision = function(ctx, x, y) { return 0; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.FloatFunc1} */ glsBuiltinPrecisionTests.Negate = function() { glsBuiltinPrecisionTests.FloatFunc1.call(this); }; setParentClass(glsBuiltinPrecisionTests.Negate, glsBuiltinPrecisionTests.FloatFunc1); glsBuiltinPrecisionTests.Negate.prototype.getName = function() { return '_negate'; }; glsBuiltinPrecisionTests.Negate.prototype.doPrint = function(args) { return '-' + args[0]; }; glsBuiltinPrecisionTests.Negate.prototype.precision = function(ctx, ret, x) { return 0; }; glsBuiltinPrecisionTests.Negate.prototype.applyExact = function(x) { return -x; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.FloatFunc1} */ glsBuiltinPrecisionTests.InverseSqrt = function() { glsBuiltinPrecisionTests.FloatFunc1.call(this); }; setParentClass(glsBuiltinPrecisionTests.InverseSqrt, glsBuiltinPrecisionTests.FloatFunc1); glsBuiltinPrecisionTests.InverseSqrt.prototype.getName = function() { return 'inversesqrt'; }; glsBuiltinPrecisionTests.InverseSqrt.prototype.precision = function(ctx, ret, x) { if (x <= 0) return NaN; return ctx.format.ulp(ret, 2.0); }; glsBuiltinPrecisionTests.InverseSqrt.prototype.applyExact = function(x) { return 1 / Math.sqrt(x); }; glsBuiltinPrecisionTests.InverseSqrt.prototype.getCodomain = function() { return tcuInterval.withNumbers(0, Infinity); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.FloatFunc1} */ glsBuiltinPrecisionTests.Round = function() { glsBuiltinPrecisionTests.FloatFunc1.call(this); }; setParentClass(glsBuiltinPrecisionTests.Round, glsBuiltinPrecisionTests.FloatFunc1); glsBuiltinPrecisionTests.Round.prototype.getName = function() { return 'round'; }; glsBuiltinPrecisionTests.Round.prototype.precision = function(ctx, ret, x) { return 0; }; glsBuiltinPrecisionTests.Round.prototype.applyPoint = function(ctx, x) { var truncated = Math.trunc(x); var fract = x - truncated; var ret = new tcuInterval.Interval(); // When x is inf or -inf, truncated would be inf or -inf too. Then fract // would be NaN (inf - inf). While in native c code, it would be 0 (inf) or -0 (-inf). // This behavior in JS differs from that in native c code. if (Math.abs(fract) <= 0.5 || isNaN(fract)) ret.operatorOrAssignBinary(new tcuInterval.Interval(truncated)); if (Math.abs(fract) >= 0.5) ret.operatorOrAssignBinary(new tcuInterval.Interval(truncated + deMath.deSign(fract))); return ret; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.FloatFunc1} * @param {string} name * @param {tcuInterval.DoubleFunc1} func */ glsBuiltinPrecisionTests.CFloatFunc1 = function(name, func) { glsBuiltinPrecisionTests.FloatFunc1.call(this); /** @type {string} */ this.m_name = name; /** @type {tcuInterval.DoubleFunc1} */this.m_func = func; }; glsBuiltinPrecisionTests.CFloatFunc1.prototype = Object.create(glsBuiltinPrecisionTests.FloatFunc1.prototype); glsBuiltinPrecisionTests.CFloatFunc1.prototype.constructor = glsBuiltinPrecisionTests.CFloatFunc1; /** * @return {string} */ glsBuiltinPrecisionTests.CFloatFunc1.prototype.getName = function() { return this.m_name; }; /** * @param {number} x * @return {number} */ glsBuiltinPrecisionTests.CFloatFunc1.prototype.applyExact = function(x) { return this.m_func(x); }; /** * PrimitiveFunc > * @constructor * @extends {glsBuiltinPrecisionTests.PrimitiveFunc} */ glsBuiltinPrecisionTests.FloatFunc2 = function() { /** @type {glsBuiltinPrecisionTests.Signature} */ var Sig = new glsBuiltinPrecisionTests.Signature('float', 'float', 'float'); glsBuiltinPrecisionTests.PrimitiveFunc.call(this, Sig); }; glsBuiltinPrecisionTests.FloatFunc2.prototype = Object.create(glsBuiltinPrecisionTests.PrimitiveFunc.prototype); glsBuiltinPrecisionTests.FloatFunc2.prototype.constructor = glsBuiltinPrecisionTests.FloatFunc2; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {glsBuiltinPrecisionTests.Tuple4} iargs * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.FloatFunc2.prototype.doApply = function(ctx, iargs) { var a = /** @type {tcuInterval.Interval} */ (iargs.a); var b = /** @type {tcuInterval.Interval} */ (iargs.b); return this.applyMonotone(ctx, a, b); }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {tcuInterval.Interval} xi * @param {tcuInterval.Interval} yi * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.FloatFunc2.prototype.applyMonotone = function(ctx, xi, yi) { /** @type {tcuInterval.Interval} */ var ret = new tcuInterval.Interval(); /** * @param {number=} x * @param {number=} y * @return {tcuInterval.Interval} */ var body = function(x, y) { x = x || 0; y = y || 0; return this.applyPoint(ctx, x, y); }; ret = tcuInterval.applyMonotone2(xi, yi, body.bind(this)); ret.operatorOrAssignBinary(this.innerExtrema(ctx, xi, yi)); ret.operatorAndAssignBinary(this.getCodomain().operatorOrBinary(new tcuInterval.Interval(NaN))); return ctx.format.convert(ret); }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {tcuInterval.Interval} xi * @param {tcuInterval.Interval} yi * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.FloatFunc2.prototype.innerExtrema = function(ctx, xi, yi) { return new tcuInterval.Interval(); // empty interval, i.e. no extrema }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {number} x * @param {number} y * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.FloatFunc2.prototype.applyPoint = function(ctx, x, y) { /** @type {number} */ var exact = this.applyExact(x, y); var prec = this.precision(ctx, exact, x, y); var a = new tcuInterval.Interval(exact); var b = tcuInterval.withNumbers(-prec, prec); return tcuInterval.Interval.operatorSum(a, b); }; /** * @param {number} x * @param {number} y * @return {number} */ glsBuiltinPrecisionTests.FloatFunc2.prototype.applyExact = function(x, y) { throw new Error('Virtual function. Please override'); }; /** * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.FloatFunc2.prototype.getCodomain = function() { return tcuInterval.unbounded(true); }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {number} ret * @param {number} x * @param {number} y * @return {number} */ glsBuiltinPrecisionTests.FloatFunc2.prototype.precision = function(ctx, ret, x, y) { throw new Error('Virtual function. Please override'); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.FloatFunc2} * @param {string} name * @param {tcuInterval.DoubleFunc2} func */ glsBuiltinPrecisionTests.CFloatFunc2 = function(name, func) { glsBuiltinPrecisionTests.FloatFunc2.call(this); /** @type {string} */ this.m_name = name; /** @type {tcuInterval.DoubleFunc2} */ this.m_func = func; }; glsBuiltinPrecisionTests.CFloatFunc2.prototype = Object.create(glsBuiltinPrecisionTests.FloatFunc2.prototype); glsBuiltinPrecisionTests.CFloatFunc2.prototype.constructor = glsBuiltinPrecisionTests.CFloatFunc2; /** * @return {string} */ glsBuiltinPrecisionTests.CFloatFunc2.prototype.getName = function() { return this.m_name; }; /** * @param {number} x * @param {number} y * @return {number} */ glsBuiltinPrecisionTests.CFloatFunc2.prototype.applyExact = function(x, y) { return this.m_func(x, y); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.FloatFunc2} */ glsBuiltinPrecisionTests.InfixOperator = function() { glsBuiltinPrecisionTests.FloatFunc2.call(this); }; glsBuiltinPrecisionTests.InfixOperator.prototype = Object.create(glsBuiltinPrecisionTests.FloatFunc2.prototype); glsBuiltinPrecisionTests.InfixOperator.prototype.constructor = glsBuiltinPrecisionTests.InfixOperator; /** * @return {string} */ glsBuiltinPrecisionTests.InfixOperator.prototype.getSymbol = function() { glsBuiltinPrecisionTests.FloatFunc2.call(this); return ''; }; /** * @param {Array} args * @return {string} */ glsBuiltinPrecisionTests.InfixOperator.prototype.doPrint = function(args) { return '(' + args[0] + ' ' + this.getSymbol() + ' ' + args[1] + ')'; }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {number} x * @param {number} y * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.InfixOperator.prototype.applyPoint = function(ctx, x, y) { /** @type {number} */ var exact = this.applyExact(x, y); // Allow either representable number on both sides of the exact value, // but require exactly representable values to be preserved. return ctx.format.roundOut(new tcuInterval.Interval(exact), isFinite(x) && isFinite(y)); }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {number} x * @param {number} y * @param {number} z * @return {number} */ glsBuiltinPrecisionTests.InfixOperator.prototype.precision = function(ctx, x, y, z) { return 0; }; /** * Signature * @constructor * @extends {glsBuiltinPrecisionTests.PrimitiveFunc} */ glsBuiltinPrecisionTests.FloatFunc3 = function() { /** @type {glsBuiltinPrecisionTests.Signature} */ var sig = new glsBuiltinPrecisionTests.Signature('float', 'float', 'float', 'float'); glsBuiltinPrecisionTests.PrimitiveFunc.call(this, sig); }; glsBuiltinPrecisionTests.FloatFunc3.prototype = Object.create(glsBuiltinPrecisionTests.PrimitiveFunc.prototype); glsBuiltinPrecisionTests.FloatFunc3.prototype.constructor = glsBuiltinPrecisionTests.FloatFunc3; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {glsBuiltinPrecisionTests.Tuple4} iargs * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.FloatFunc3.prototype.doApply = function(ctx, iargs) { var a = /** @type {tcuInterval.Interval} */ (iargs.a); var b = /** @type {tcuInterval.Interval} */ (iargs.b); var c = /** @type {tcuInterval.Interval} */ (iargs.c); var retVal = this.applyMonotone(ctx, a, b, c); return retVal; }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {tcuInterval.Interval} xi * @param {tcuInterval.Interval} yi * @param {tcuInterval.Interval} zi * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.FloatFunc3.prototype.applyMonotone = function(ctx, xi, yi, zi) { /** * @param {number=} x * @param {number=} y * @param {number=} z * @return {tcuInterval.Interval} */ var body = function(x, y, z) { x = x || 0; y = y || 0; z = z || 0; return this.applyPoint(ctx, x, y, z); }; var ret = tcuInterval.applyMonotone3(xi, yi, zi, body.bind(this)); var retVal; ret.operatorOrAssignBinary(this.innerExtrema(ctx, xi, yi, zi)); ret.operatorAndAssignBinary(this.getCodomain().operatorOrBinary(new tcuInterval.Interval(NaN))); retVal = ctx.format.convert(ret); return retVal; }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {tcuInterval.Interval} xi * @param {tcuInterval.Interval} yi * @param {tcuInterval.Interval} zi * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.FloatFunc3.prototype.innerExtrema = function(ctx, xi, yi, zi) { return new tcuInterval.Interval(); // empty interval, i.e. no extrema }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {number} x * @param {number} y * @param {number} z * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.FloatFunc3.prototype.applyPoint = function(ctx, x, y, z) { /** @type {number} */ var exact = this.applyExact(x, y, z); /** @type {number} */ var prec = this.precision(ctx, exact, x, y, z); var a = new tcuInterval.Interval(exact); var b = tcuInterval.withNumbers(-prec, prec); return tcuInterval.Interval.operatorSum(a, b); }; /** * @param {number} x * @param {number} y * @param {number} z * @return {number} */ glsBuiltinPrecisionTests.FloatFunc3.prototype.applyExact = function(x, y, z) { throw new Error('Virtual function. Please override'); }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {number} result * @param {number} x * @param {number} y * @param {number} z * @return {number} */ glsBuiltinPrecisionTests.FloatFunc3.prototype.precision = function(ctx, result, x, y, z) { throw new Error('Virtual function. Please override'); }; /** * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.FloatFunc3.prototype.getCodomain = function() { return tcuInterval.unbounded(true); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.FloatFunc3} */ glsBuiltinPrecisionTests.Clamp = function() { glsBuiltinPrecisionTests.FloatFunc3.call(this); }; setParentClass(glsBuiltinPrecisionTests.Clamp, glsBuiltinPrecisionTests.FloatFunc3); glsBuiltinPrecisionTests.Clamp.prototype.getName = function() { return 'clamp'; }; glsBuiltinPrecisionTests.Clamp.prototype.applyExact = function(x, minVal, maxVal) { var debug = false; var retVal; retVal = deMath.clamp(x, minVal, maxVal); if (debug) { console.log('> minVal: ' + minVal); console.log('> maxVal: ' + maxVal); console.log('> x: ' + x); console.log('> ret: ' + retVal); } return retVal; }; glsBuiltinPrecisionTests.Clamp.prototype.precision = function(ctx, result, x, minVal, maxVal) { var debug = false; var retVal; retVal = minVal > maxVal ? NaN : 0; if (debug) { console.log('precision> minVal: ' + minVal); console.log('precision> maxVal: ' + maxVal); console.log('precision> x: ' + x); console.log('precision> ret: ' + retVal); } return retVal; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.InfixOperator} */ glsBuiltinPrecisionTests.Add = function() { glsBuiltinPrecisionTests.InfixOperator.call(this); }; glsBuiltinPrecisionTests.Add.prototype = Object.create(glsBuiltinPrecisionTests.InfixOperator.prototype); glsBuiltinPrecisionTests.Add.prototype.constructor = glsBuiltinPrecisionTests.Add; /** * @return {string} */ glsBuiltinPrecisionTests.Add.prototype.getName = function() { return 'add'; }; /** * @return {string} */ glsBuiltinPrecisionTests.Add.prototype.getSymbol = function() { return '+'; }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {glsBuiltinPrecisionTests.Tuple4} iargs * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.Add.prototype.doApply = function(ctx, iargs) { var a = /** @type {tcuInterval.Interval} */ (iargs.a); var b = /** @type {tcuInterval.Interval} */ (iargs.b); // Fast-path for common case if (iargs.a.isOrdinary() && iargs.b.isOrdinary()) { /** type{tcuInterval.Interval} */ var ret; ret = tcuInterval.setIntervalBounds( function(dummy) { return iargs.a.lo() + iargs.b.lo(); }, function(dummy) { return iargs.a.hi() + iargs.b.hi(); }); return ctx.format.convert(ctx.format.roundOut(ret, true)); } return this.applyMonotone(ctx, a, b); }; /** * @param {number} x * @param {number} y * @return {number} */ glsBuiltinPrecisionTests.Add.prototype.applyExact = function(x, y) { return x + y; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.InfixOperator} */ glsBuiltinPrecisionTests.Sub = function() { glsBuiltinPrecisionTests.InfixOperator.call(this); }; glsBuiltinPrecisionTests.Sub.prototype = Object.create(glsBuiltinPrecisionTests.InfixOperator.prototype); glsBuiltinPrecisionTests.Sub.prototype.constructor = glsBuiltinPrecisionTests.Sub; /** * @return {string} */ glsBuiltinPrecisionTests.Sub.prototype.getName = function() { return 'sub'; }; /** * @return {string} */ glsBuiltinPrecisionTests.Sub.prototype.getSymbol = function() { return '-'; }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {glsBuiltinPrecisionTests.Tuple4} iargs * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.Sub.prototype.doApply = function(ctx, iargs) { var a = /** @type {tcuInterval.Interval} */ (iargs.a); var b = /** @type {tcuInterval.Interval} */ (iargs.b); var retVal; // Fast-path for common case if (iargs.a.isOrdinary() && iargs.b.isOrdinary()) { /** type{tcuInterval.Interval} */ var ret; ret = tcuInterval.setIntervalBounds( function(dummy) { return iargs.a.lo() - iargs.b.hi(); }, function(dummy) { return iargs.a.hi() - iargs.b.lo(); }); return ctx.format.convert(ctx.format.roundOut(ret, true)); } retVal = this.applyMonotone(ctx, a, b); return retVal; }; /** * @param {number} x * @param {number} y * @return {number} */ glsBuiltinPrecisionTests.Sub.prototype.applyExact = function(x, y) { return x - y; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.InfixOperator} */ glsBuiltinPrecisionTests.Mul = function() { glsBuiltinPrecisionTests.InfixOperator.call(this); }; glsBuiltinPrecisionTests.Mul.prototype = Object.create(glsBuiltinPrecisionTests.InfixOperator.prototype); glsBuiltinPrecisionTests.Mul.prototype.constructor = glsBuiltinPrecisionTests.Mul; /** * @return {string} */ glsBuiltinPrecisionTests.Mul.prototype.getName = function() { return 'mul'; }; /** * @return {string} */ glsBuiltinPrecisionTests.Mul.prototype.getSymbol = function() { return '*'; }; glsBuiltinPrecisionTests.isNegative = function(n) { return ((n = +n) || 1 / n) < 0; }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {glsBuiltinPrecisionTests.Tuple4} iargs * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.Mul.prototype.doApply = function(ctx, iargs) { var a = /** @type {tcuInterval.Interval} */ (iargs.a); var b = /** @type {tcuInterval.Interval} */ (iargs.b); // Fast-path for common case if (iargs.a.isOrdinary() && iargs.b.isOrdinary()) { /** type{tcuInterval.Interval} */ var ret = new tcuInterval.Interval(); if (glsBuiltinPrecisionTests.isNegative(a.hi())) { a = a.operatorNegative(); b = b.operatorNegative(); } if (a.lo() >= 0 && b.lo() >= 0) { ret = tcuInterval.setIntervalBounds( function(dummy) { return iargs.a.lo() * iargs.b.lo(); }, function(dummy) { return iargs.a.hi() * iargs.b.hi(); }); return ctx.format.convert(ctx.format.roundOut(ret, true)); } if (a.lo() >= 0 && b.hi() <= 0) { ret = tcuInterval.setIntervalBounds( function(dummy) { return iargs.a.hi() * iargs.b.lo(); }, function(dummy) { return iargs.a.lo() * iargs.b.hi(); }); return ctx.format.convert(ctx.format.roundOut(ret, true)); } } return this.applyMonotone(ctx, a, b); }; /** * @param {number} x * @param {number} y * @return {number} */ glsBuiltinPrecisionTests.Mul.prototype.applyExact = function(x, y) { return x * y; }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {tcuInterval.Interval} xi * @param {tcuInterval.Interval} yi * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.Mul.prototype.innerExtrema = function(ctx, xi, yi) { if (((xi.contains(tcuInterval.NEGATIVE_INFINITY) || xi.contains(tcuInterval.POSITIVE_INFINITY)) && yi.contains(tcuInterval.ZERO)) || ((yi.contains(tcuInterval.NEGATIVE_INFINITY) || yi.contains(tcuInterval.POSITIVE_INFINITY)) && xi.contains(tcuInterval.ZERO))) return new tcuInterval.Interval(NaN); return new tcuInterval.Interval(); // empty interval, i.e. no extrema }; /** * @constructor * @extends {glsBuiltinPrecisionTests.InfixOperator} */ glsBuiltinPrecisionTests.Div = function() { glsBuiltinPrecisionTests.InfixOperator.call(this); }; glsBuiltinPrecisionTests.Div.prototype = Object.create(glsBuiltinPrecisionTests.InfixOperator.prototype); glsBuiltinPrecisionTests.Div.prototype.constructor = glsBuiltinPrecisionTests.Div; /** * @return {string} */ glsBuiltinPrecisionTests.Div.prototype.getName = function() { return 'div'; }; /** * @return {string} */ glsBuiltinPrecisionTests.Div.prototype.getSymbol = function() { return '/'; }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {tcuInterval.Interval} nom * @param {tcuInterval.Interval} den * @return {tcuInterval.Interval} */ glsBuiltinPrecisionTests.Div.prototype.innerExtrema = function(ctx, nom, den) { var ret = new tcuInterval.Interval(); if (den.contains(tcuInterval.ZERO)) { if (nom.contains(tcuInterval.ZERO)) ret.operatorOrAssignBinary(tcuInterval.NAN); if (nom.lo() < 0 || nom.hi() > 0.0) ret.operatorOrAssignBinary(tcuInterval.unbounded()); } return ret; }; glsBuiltinPrecisionTests.Div.prototype.precision = function(ctx, ret, nom, den) { var fmt = ctx.format; // \todo [2014-03-05 lauri] Check that the limits in GLSL 3.10 are actually correct. // For now, we assume that division's precision is 2.5 ULP when the value is within // [2^MINEXP, 2^MAXEXP-1] if (den === 0) return 0; // Result must be exactly inf else if (deMath.deInBounds32(Math.abs(den), deMath.deLdExp(1, fmt.getMinExp()), deMath.deLdExp(1, fmt.getMaxExp() - 1))) return fmt.ulp(ret, 2.5); else return Infinity; // Can be any number, but must be a number. }; /** * @param {number} x * @param {number} y * @return {number} */ glsBuiltinPrecisionTests.Div.prototype.applyExact = function(x, y) { return x / y; }; glsBuiltinPrecisionTests.Div.prototype.applyPoint = function(ctx, x, y) { var ret = glsBuiltinPrecisionTests.FloatFunc2.prototype.applyPoint.call(this, ctx, x, y); if (isFinite(x) && isFinite(y) && y != 0) { var dst = ctx.format.convert(ret); if (dst.contains(tcuInterval.NEGATIVE_INFINITY)) { ret.operatorOrAssignBinary(-ctx.format.getMaxValue()); } if (dst.contains(tcuInterval.POSITIVE_INFINITY)) { ret.operatorOrAssignBinary(+ctx.format.getMaxValue()); } } return ret; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.PrimitiveFunc} */ glsBuiltinPrecisionTests.CompWiseFunc = function(typename, Sig) { glsBuiltinPrecisionTests.PrimitiveFunc.call(this, Sig); this.typename = typename; }; setParentClass(glsBuiltinPrecisionTests.CompWiseFunc, glsBuiltinPrecisionTests.PrimitiveFunc); /** * @return {string} */ glsBuiltinPrecisionTests.CompWiseFunc.prototype.getName = function() { return this.doGetScalarFunc().getName(); }; /** * @param {Array} args * @return {string} */ glsBuiltinPrecisionTests.CompWiseFunc.prototype.doPrint = function(args) { return this.doGetScalarFunc().print(args); }; /** * @return {glsBuiltinPrecisionTests.Func} */ glsBuiltinPrecisionTests.CompWiseFunc.prototype.doGetScalarFunc = function() { throw new Error('Virtual function. Please override.'); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.CompWiseFunc} * @param {number} rows * @param {number} cols */ glsBuiltinPrecisionTests.CompMatFuncBase = function(rows, cols) { var name = glsBuiltinPrecisionTests.dataTypeNameOfMatrix('float', rows, cols); glsBuiltinPrecisionTests.CompWiseFunc.call(this, 'float', new glsBuiltinPrecisionTests.Signature(name, name, name)); this.rows = rows; this.cols = cols; }; setParentClass(glsBuiltinPrecisionTests.CompMatFuncBase, glsBuiltinPrecisionTests.CompWiseFunc); glsBuiltinPrecisionTests.CompMatFuncBase.prototype.doApply = function(ctx, iargs) { var ret = new tcuMatrix.Matrix(this.rows, this.cols); var fun = this.doGetScalarFunc(); for (var row = 0; row < this.rows; ++row) for (var col = 0; col < this.cols; ++col) ret.set(row, col, fun.applyFunction(ctx, iargs.a.get(row, col), iargs.b.get(row, col))); return ret; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.CompMatFuncBase} * @param {function(new:glsBuiltinPrecisionTests.Func)} F * @param {number} rows * @param {number} cols */ glsBuiltinPrecisionTests.CompMatFunc = function(F, rows, cols) { glsBuiltinPrecisionTests.CompMatFuncBase.call(this, rows, cols); this.m_function = F; }; setParentClass(glsBuiltinPrecisionTests.CompMatFunc, glsBuiltinPrecisionTests.CompMatFuncBase); /** * @return {glsBuiltinPrecisionTests.Func} */ glsBuiltinPrecisionTests.CompMatFunc.prototype.doGetScalarFunc = function() { return new this.m_function(); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Mul} */ glsBuiltinPrecisionTests.ScalarMatrixCompMult = function() { glsBuiltinPrecisionTests.Mul.call(this); }; setParentClass(glsBuiltinPrecisionTests.ScalarMatrixCompMult, glsBuiltinPrecisionTests.Mul); /** * @return {string} */ glsBuiltinPrecisionTests.ScalarMatrixCompMult.prototype.getName = function() { return 'matrixCompMult'; }; /** * @param {Array} args * @return {string} */ glsBuiltinPrecisionTests.ScalarMatrixCompMult.prototype.doPrint = function(args) { return glsBuiltinPrecisionTests.Func.prototype.doPrint.call(this, args); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.CompMatFunc} * @param {number} rows * @param {number} cols */ glsBuiltinPrecisionTests.MatrixCompMult = function(rows, cols) { glsBuiltinPrecisionTests.CompMatFunc.call(this, glsBuiltinPrecisionTests.ScalarMatrixCompMult, rows, cols); }; setParentClass(glsBuiltinPrecisionTests.MatrixCompMult, glsBuiltinPrecisionTests.CompMatFunc); /** * @constructor * @extends {glsBuiltinPrecisionTests.PrimitiveFunc} * @param {number} rows * @param {number} cols */ glsBuiltinPrecisionTests.OuterProduct = function(rows, cols) { var name = glsBuiltinPrecisionTests.dataTypeNameOfMatrix('float', rows, cols); var sig = new glsBuiltinPrecisionTests.Signature(name, 'vec' + rows, 'vec' + cols); glsBuiltinPrecisionTests.PrimitiveFunc.call(this, sig); this.rows = rows; this.cols = cols; }; setParentClass(glsBuiltinPrecisionTests.OuterProduct, glsBuiltinPrecisionTests.PrimitiveFunc); /** * @return {string} */ glsBuiltinPrecisionTests.OuterProduct.prototype.getName = function() { return 'outerProduct'; }; glsBuiltinPrecisionTests.OuterProduct.prototype.doApply = function(ctx, iargs) { var ret = new tcuMatrix.Matrix(this.rows, this.cols); var mul = new glsBuiltinPrecisionTests.Mul(); for (var row = 0; row < this.rows; ++row) { for (var col = 0; col < this.cols; ++col) ret.set(row, col, mul.applyFunction(ctx, iargs.a[row], iargs.b[col])); } return ret; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.PrimitiveFunc} * @param {number} rows * @param {number} cols */ glsBuiltinPrecisionTests.Transpose = function(rows, cols) { var nameRet = glsBuiltinPrecisionTests.dataTypeNameOfMatrix('float', rows, cols); var nameParam = glsBuiltinPrecisionTests.dataTypeNameOfMatrix('float', cols, rows); var sig = new glsBuiltinPrecisionTests.Signature(nameRet, nameParam); glsBuiltinPrecisionTests.PrimitiveFunc.call(this, sig); this.rows = rows; this.cols = cols; }; setParentClass(glsBuiltinPrecisionTests.Transpose, glsBuiltinPrecisionTests.PrimitiveFunc); /** * @return {string} */ glsBuiltinPrecisionTests.Transpose.prototype.getName = function() { return 'transpose'; }; glsBuiltinPrecisionTests.Transpose.prototype.doApply = function(ctx, iargs) { var ret = new tcuMatrix.Matrix(this.rows, this.cols); for (var row = 0; row < this.rows; ++row) for (var col = 0; col < this.cols; ++col) ret.set(row, col, iargs.a.get(col, row)); return ret; }; /** * @constructor * @param {*} In */ glsBuiltinPrecisionTests.Inputs = function(In) { // vector in0; // vector in1; // vector in2; // vector in3; this.in0 = []; this.in1 = []; this.in2 = []; this.in3 = []; }; /** * @constructor * @param {number} size * @param {*} Out */ glsBuiltinPrecisionTests.Outputs = function(size, Out) { // Outputs (size_t size) : out0(size), out1(size) {} this.out0 = []; this.out1 = []; }; /** * @constructor * @param {*} In * @param {*} Out */ glsBuiltinPrecisionTests.Variables = function(In, Out) { this.in0 = new glsBuiltinPrecisionTests.Variable(In.In0); this.in1 = new glsBuiltinPrecisionTests.Variable(In.In1); this.in2 = new glsBuiltinPrecisionTests.Variable(In.In2); this.in3 = new glsBuiltinPrecisionTests.Variable(In.In3); this.out0 = new glsBuiltinPrecisionTests.Variable(Out.Out0); this.out1 = new glsBuiltinPrecisionTests.Variable(Out.Out1); }; /** * @constructor * @param {function(new:glsBuiltinPrecisionTests.Func)} F * @return {glsBuiltinPrecisionTests.GenFuncs} */ glsBuiltinPrecisionTests.makeVectorizedFuncs = function(F) { return new glsBuiltinPrecisionTests.GenFuncs( new F(), new glsBuiltinPrecisionTests.VectorizedFunc(new F(), 2), new glsBuiltinPrecisionTests.VectorizedFunc(new F(), 3), new glsBuiltinPrecisionTests.VectorizedFunc(new F(), 4)); }; /** * @constructor * @param {glsBuiltinPrecisionTests.Typename} typename */ glsBuiltinPrecisionTests.Sampling = function(typename) { this.typename = typename; }; /** * @param {glsBuiltinPrecisionTests.Typename} typename * @param {number=} size * @return {glsBuiltinPrecisionTests.Sampling} */ glsBuiltinPrecisionTests.SamplingFactory = function(typename, size) { if (size > 1) return new glsBuiltinPrecisionTests.DefaultSamplingVector(typename, size); switch (typename) { case 'vec4' : return new glsBuiltinPrecisionTests.DefaultSamplingVector('float', 4); case 'vec3' : return new glsBuiltinPrecisionTests.DefaultSamplingVector('float', 3); case 'vec2' : return new glsBuiltinPrecisionTests.DefaultSamplingVector('float', 2); case 'boolean' : return new glsBuiltinPrecisionTests.DefaultSamplingBool(typename); case 'float' : return new glsBuiltinPrecisionTests.DefaultSamplingFloat(typename); case 'mat2': return new glsBuiltinPrecisionTests.DefaultSamplingMatrix('float', 2, 2); case 'mat2x3': return new glsBuiltinPrecisionTests.DefaultSamplingMatrix('float', 3, 2); case 'mat2x4': return new glsBuiltinPrecisionTests.DefaultSamplingMatrix('float', 4, 2); case 'mat3x2': return new glsBuiltinPrecisionTests.DefaultSamplingMatrix('float', 2, 3); case 'mat3': return new glsBuiltinPrecisionTests.DefaultSamplingMatrix('float', 3, 3); case 'mat3x4': return new glsBuiltinPrecisionTests.DefaultSamplingMatrix('float', 4, 3); case 'mat4x2': return new glsBuiltinPrecisionTests.DefaultSamplingMatrix('float', 2, 4); case 'mat4x3': return new glsBuiltinPrecisionTests.DefaultSamplingMatrix('float', 3, 4); case 'mat4': return new glsBuiltinPrecisionTests.DefaultSamplingMatrix('float', 4, 4); case 'int' : return new glsBuiltinPrecisionTests.DefaultSamplingInt(typename); } return new glsBuiltinPrecisionTests.DefaultSamplingVoid(typename); }; /** * @param {tcuFloatFormat.FloatFormat} fmt * @param {Array<*>} arr */ glsBuiltinPrecisionTests.Sampling.prototype.genFixeds = function(fmt, arr) { throw new Error('Virtual function. Please override.'); }; /** * @param {tcuFloatFormat.FloatFormat} fmt * @param {gluShaderUtil.precision} precision * @param {deRandom.Random} random * @return {*} */ glsBuiltinPrecisionTests.Sampling.prototype.genRandom = function(fmt, precision, random) { return 0; }; /** * @return {number} */ glsBuiltinPrecisionTests.Sampling.prototype.getWeight = function() { return 0; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Sampling} * @param {glsBuiltinPrecisionTests.Typename} typename */ glsBuiltinPrecisionTests.DefaultSamplingVoid = function(typename) { glsBuiltinPrecisionTests.Sampling.call(this, typename); }; glsBuiltinPrecisionTests.DefaultSamplingVoid.prototype = Object.create(glsBuiltinPrecisionTests.Sampling.prototype); glsBuiltinPrecisionTests.DefaultSamplingVoid.prototype.constructor = glsBuiltinPrecisionTests.DefaultSamplingVoid; /** * @param {tcuFloatFormat.FloatFormat} fmt * @param {Array} dst */ glsBuiltinPrecisionTests.DefaultSamplingVoid.prototype.genFixeds = function(fmt, dst) { dst.push(NaN); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Sampling} * @param {glsBuiltinPrecisionTests.Typename} typename */ glsBuiltinPrecisionTests.DefaultSamplingBool = function(typename) { glsBuiltinPrecisionTests.Sampling.call(this, typename); }; glsBuiltinPrecisionTests.DefaultSamplingBool.prototype = Object.create(glsBuiltinPrecisionTests.Sampling.prototype); glsBuiltinPrecisionTests.DefaultSamplingBool.prototype.constructor = glsBuiltinPrecisionTests.DefaultSamplingBool; /** * @param {tcuFloatFormat.FloatFormat} fmt * @param {Array} dst */ glsBuiltinPrecisionTests.DefaultSamplingBool.prototype.genFixeds = function(fmt, dst) { dst.push(true); dst.push(false); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Sampling} * @param {glsBuiltinPrecisionTests.Typename} typename */ glsBuiltinPrecisionTests.DefaultSamplingInt = function(typename) { glsBuiltinPrecisionTests.Sampling.call(this, typename); }; glsBuiltinPrecisionTests.DefaultSamplingInt.prototype = Object.create(glsBuiltinPrecisionTests.Sampling.prototype); glsBuiltinPrecisionTests.DefaultSamplingInt.prototype.constructor = glsBuiltinPrecisionTests.DefaultSamplingInt; glsBuiltinPrecisionTests.DefaultSamplingInt.prototype.genRandom = function(fmt, prec, rnd) { /** @type {number} */ var exp = rnd.getInt(0, this.getNumBits(prec) - 2); /** @type {number} */ var sign = rnd.getBool() ? -1 : 1; return sign * rnd.getInt(0, 1 << exp); }; glsBuiltinPrecisionTests.DefaultSamplingInt.prototype.genFixeds = function(fmt, dst) { dst.push(0); dst.push(-1); dst.push(1); }; glsBuiltinPrecisionTests.DefaultSamplingInt.prototype.getWeight = function() { return 1.0; }; /** * @param {gluShaderUtil.precision} prec * @return {number} */ glsBuiltinPrecisionTests.DefaultSamplingInt.prototype.getNumBits = function(prec) { switch (prec) { case gluShaderUtil.precision.PRECISION_LOWP: return 8; case gluShaderUtil.precision.PRECISION_MEDIUMP: return 16; case gluShaderUtil.precision.PRECISION_HIGHP: return 32; default: throw new Error('Invalid precision: ' + prec); } }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Sampling} * @param {glsBuiltinPrecisionTests.Typename} typename */ glsBuiltinPrecisionTests.DefaultSamplingFloat = function(typename) { glsBuiltinPrecisionTests.Sampling.call(this, typename); }; glsBuiltinPrecisionTests.DefaultSamplingFloat.prototype = Object.create(glsBuiltinPrecisionTests.Sampling.prototype); glsBuiltinPrecisionTests.DefaultSamplingFloat.prototype.constructor = glsBuiltinPrecisionTests.DefaultSamplingFloat; glsBuiltinPrecisionTests.DefaultSamplingFloat.prototype.genRandom = function(format, prec, rnd) { /** type{number} */ var minExp = format.getMinExp(); /** type{number} */ var maxExp = format.getMaxExp(); /** type{boolean} */ var haveSubnormal = format.hasSubnormal() != tcuFloatFormat.YesNoMaybe.NO; // Choose exponent so that the cumulative distribution is cubic. // This makes the probability distribution quadratic, with the peak centered on zero. /** type{number} */ var minRoot = deMath.deCbrt(minExp - 0.5 - (haveSubnormal ? 1.0 : 0.0)); /** type{number} */ var maxRoot = deMath.deCbrt(maxExp + 0.5); /** type{number} */ var fractionBits = format.getFractionBits(); /** type{number} */ var exp = deMath.rint(Math.pow(rnd.getFloat(minRoot, maxRoot), 3.0)); /** type{number} */ var base = 0.0; // integral power of two /** type{number} */ var quantum = 0.0; // smallest representable difference in the binade /** type{number} */ var significand = 0.0; // Significand. // DE_ASSERT(fractionBits < std::numeric_limits::digits); // Generate some occasional special numbers switch (rnd.getInt(0, 64)) { case 0: return 0; case 1: return Number.POSITIVE_INFINITY; case 2: return Number.NEGATIVE_INFINITY; case 3: return NaN; default: break; } if (exp >= minExp) { // Normal number base = deMath.deFloatLdExp(1.0, exp); quantum = deMath.deFloatLdExp(1.0, exp - fractionBits); } else { // Subnormal base = 0.0; quantum = deMath.deFloatLdExp(1.0, minExp - fractionBits); } switch (rnd.getInt(0, 16)) { // The highest number in this binade, significand is all bits one. case 0: significand = base - quantum; break; // Significand is one. case 1: significand = quantum; break; // Significand is zero. case 2: significand = 0.0; break; // Random (evenly distributed) significand. default: { /** type{number} */ var intFraction = rnd.getInt() & ((1 << fractionBits) - 1); significand = intFraction * quantum; } } // Produce positive numbers more often than negative. return (rnd.getInt(0, 3) == 0 ? -1.0 : 1.0) * (base + significand); }; glsBuiltinPrecisionTests.DefaultSamplingFloat.prototype.genFixeds = function(format, dst) { /** @type {number} */ var minExp = format.getMinExp(); /** @type {number} */ var maxExp = format.getMaxExp(); /** @type {number} */ var fractionBits = format.getFractionBits(); /** @type {number} */ var minQuantum = deMath.deFloatLdExp(1.0, minExp - fractionBits); /** @type {number} */ var minNormalized = deMath.deFloatLdExp(1.0, minExp); /** @type {number} */ var maxQuantum = deMath.deFloatLdExp(1.0, maxExp - fractionBits); // If unit testing is enabled, include exact numbers if (enableUnittests) { dst.push(0.2); dst.push(0.5); } // NaN dst.push(NaN); // Zero dst.push(0.0); for (var sign = -1; sign <= 1; sign += 2) { // Smallest subnormal dst.push(sign * minQuantum); // Largest subnormal dst.push(sign * (minNormalized - minQuantum)); // Smallest normalized dst.push(sign * minNormalized); // Next smallest normalized dst.push(sign * (minNormalized + minQuantum)); dst.push(sign * 0.5); dst.push(sign * 1.0); dst.push(sign * 2.0); // Largest number dst.push(sign * (deMath.deFloatLdExp(1.0, maxExp) + (deMath.deFloatLdExp(1.0, maxExp) - maxQuantum))); dst.push(sign * Number.POSITIVE_INFINITY); } }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Sampling} * @param {glsBuiltinPrecisionTests.Typename} typename * @param {number} size */ glsBuiltinPrecisionTests.DefaultSamplingVector = function(typename, size) { glsBuiltinPrecisionTests.Sampling.call(this, typename); this.size = size; }; glsBuiltinPrecisionTests.DefaultSamplingVector.prototype = Object.create(glsBuiltinPrecisionTests.Sampling.prototype); glsBuiltinPrecisionTests.DefaultSamplingVector.prototype.constructor = glsBuiltinPrecisionTests.DefaultSamplingVector; glsBuiltinPrecisionTests.DefaultSamplingVector.prototype.genRandom = function(fmt, prec, rnd) { /** @type {Array<*>} */ var ret = []; for (var ndx = 0; ndx < this.size; ++ndx) ret[ndx] = glsBuiltinPrecisionTests.SamplingFactory(this.typename).genRandom(fmt, prec, rnd); return ret; }; glsBuiltinPrecisionTests.DefaultSamplingVector.prototype.genFixeds = function(fmt, dst) { /** @type {Array<*>} */ var scalars = []; glsBuiltinPrecisionTests.SamplingFactory(this.typename).genFixeds(fmt, scalars); for (var scalarNdx = 0; scalarNdx < scalars.length; ++scalarNdx) { var value = []; for (var i = 0; i < this.size; i++) value[i] = scalars[scalarNdx]; dst.push(value); } }; glsBuiltinPrecisionTests.DefaultSamplingVector.prototype.getWeight = function() { return Math.pow(glsBuiltinPrecisionTests.SamplingFactory(this.typename).getWeight(), this.size); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Sampling} * @param {glsBuiltinPrecisionTests.Typename} typename * @param {number} rows * @param {number} cols */ glsBuiltinPrecisionTests.DefaultSamplingMatrix = function(typename, rows, cols) { glsBuiltinPrecisionTests.Sampling.call(this, typename); this.rows = rows; this.cols = cols; }; glsBuiltinPrecisionTests.DefaultSamplingMatrix.prototype = Object.create(glsBuiltinPrecisionTests.Sampling.prototype); glsBuiltinPrecisionTests.DefaultSamplingMatrix.prototype.constructor = glsBuiltinPrecisionTests.DefaultSamplingMatrix; glsBuiltinPrecisionTests.DefaultSamplingMatrix.prototype.genRandom = function(fmt, prec, rnd) { /** @type {tcuMatrix.Matrix} */ var ret = new tcuMatrix.Matrix(this.rows, this.cols); var sampler = glsBuiltinPrecisionTests.SamplingFactory(this.typename); for (var rowNdx = 0; rowNdx < this.rows; ++rowNdx) for (var colNdx = 0; colNdx < this.cols; ++colNdx) ret.set(rowNdx, colNdx, sampler.genRandom(fmt, prec, rnd)); return ret; }; glsBuiltinPrecisionTests.DefaultSamplingMatrix.prototype.genFixeds = function(fmt, dst) { /** @type {Array} */ var scalars = []; glsBuiltinPrecisionTests.SamplingFactory(this.typename).genFixeds(fmt, scalars); for (var scalarNdx = 0; scalarNdx < scalars.length; ++scalarNdx) dst.push(new tcuMatrix.Matrix(this.rows, this.cols, scalars[scalarNdx])); if (this.cols == this.rows) { var mat = new tcuMatrix.Matrix(this.rows, this.cols, 0); var x = 1; mat.set(0, 0, x); for (var ndx = 0; ndx < this.cols; ++ndx) { mat.set(this.cols - 1 - ndx, ndx, x); x *= 2; } dst.push(mat); } }; glsBuiltinPrecisionTests.DefaultSamplingMatrix.prototype.getWeight = function() { return Math.pow(glsBuiltinPrecisionTests.SamplingFactory(this.typename).getWeight(), this.rows * this.cols); }; /** * @constructor * @param {number=} size * @param {glsBuiltinPrecisionTests.InTypes} In */ glsBuiltinPrecisionTests.Samplings = function(In, size) { this.in0 = glsBuiltinPrecisionTests.SamplingFactory(In.In0, size); this.in1 = glsBuiltinPrecisionTests.SamplingFactory(In.In1, size); this.in2 = glsBuiltinPrecisionTests.SamplingFactory(In.In2, size); this.in3 = glsBuiltinPrecisionTests.SamplingFactory(In.In3, size); }; /** * @param {glsBuiltinPrecisionTests.InTypes} In * @param {number=} size * @constructor * @extends {glsBuiltinPrecisionTests.Samplings} */ glsBuiltinPrecisionTests.DefaultSamplings = function(In, size) { glsBuiltinPrecisionTests.Samplings.call(this, In, size); }; /** * @constructor * @extends {tcuTestCase.DeqpTest} * @param {glsBuiltinPrecisionTests.Context} context * @param {string} name * @param {string} extension */ glsBuiltinPrecisionTests.PrecisionCase = function(context, name, extension) { /** @type {string} */ this.m_extension = extension === undefined ? '' : extension; /** @type {glsBuiltinPrecisionTests.Context} */ this.m_ctx = context; /** @type {*} */ this.m_status; /** @type {deRandom.Random} */ this.m_rnd = new deRandom.Random(1234); // (0xdeadbeefu + context.testContext.getCommandLine().getBaseSeed()) tcuTestCase.DeqpTest.call(this, name, extension); }; glsBuiltinPrecisionTests.PrecisionCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype); glsBuiltinPrecisionTests.PrecisionCase.prototype.constructor = glsBuiltinPrecisionTests.PrecisionCase; /** * @return {tcuFloatFormat.FloatFormat} */ glsBuiltinPrecisionTests.PrecisionCase.prototype.getFormat = function() { return this.m_ctx.floatFormat; }; /** * Return an output value extracted from flat array * @param {goog.NumberArray} output * @param {number} index Index of the element to extract * @param {*} reference Reference for type informaion * @return {glsBuiltinPrecisionTests.Value} */ glsBuiltinPrecisionTests.getOutput = function(output, index, reference) { if (reference instanceof Array) { var ret = []; var size = reference.length; for (var i = 0; i < size; i++) ret[i] = output[size * index + i]; return ret; } if (reference instanceof tcuMatrix.Matrix) { var ret = new tcuMatrix.Matrix(reference.rows, reference.cols); var size = reference.rows * reference.cols; for (var i = 0; i < reference.rows; i++) for (var j = 0; j < reference.cols; j++) ret.set(i, j, output[size * index + j * reference.rows + i]); return ret; } return output[index]; }; /** * @param {glsBuiltinPrecisionTests.Variables} variables Variables * @param {glsBuiltinPrecisionTests.Inputs} inputs Inputs * @param {glsBuiltinPrecisionTests.Statement} stmt */ glsBuiltinPrecisionTests.PrecisionCase.prototype.testStatement = function(variables, inputs, stmt) { /** @type {tcuFloatFormat.FloatFormat} */ var fmt = this.getFormat(); /** @type {number} */ var inCount = glsBuiltinPrecisionTests.numInputs(this.In); /** @type {number} */ var outCount = glsBuiltinPrecisionTests.numOutputs(this.Out); /** @type {number} */ var numValues = (inCount > 0) ? inputs.in0.length : 1; /** @type {tcuFloatFormat.FloatFormat} */ var highpFmt = this.m_ctx.highpFormat; var outputs = []; /** @type {number} */ var maxMsgs = 100; /** @type {number} */ var numErrors = 0; /** @type {glsShaderExecUtil.ShaderSpec} */ var spec = new glsShaderExecUtil.ShaderSpec(); /** @type {glsBuiltinPrecisionTests.Environment} */ var env = new glsBuiltinPrecisionTests.Environment(); // Hoisted out of the inner loop for optimization. switch (inCount) { case 4: DE_ASSERT(inputs.in3.length == numValues); case 3: DE_ASSERT(inputs.in2.length == numValues); case 2: DE_ASSERT(inputs.in1.length == numValues); case 1: DE_ASSERT(inputs.in0.length == numValues); default: break; } if (enableUnittests) numValues = 2; // TODO: Fix logging //Print out the statement and its definitions // bufferedLogToConsole("Statement: " + stmt); // var funcInfo = '' // var funcs = {}; // stmt.getUsedFuncs(funcs); // for (var key in funcs) { // var func = funcs[key]; // funcInfo += func.printDefinition(); // }; // if (funcInfo.length > 0) // bufferedLogToConsole('Reference definitions:' + funcInfo); // Initialize ShaderSpec from precision, variables and statement. spec.globalDeclarations = 'precision ' + gluShaderUtil.getPrecisionName(this.m_ctx.precision) + ' float;\n'; if (this.m_extension.length > 0) spec.globalDeclarations += '#extension ' + this.m_extension + ' : require\n'; spec.inputs = []; switch (inCount) { case 4: spec.inputs[3] = this.makeSymbol(variables.in3); case 3: spec.inputs[2] = this.makeSymbol(variables.in2); case 2: spec.inputs[1] = this.makeSymbol(variables.in1); case 1: spec.inputs[0] = this.makeSymbol(variables.in0); default: break; } spec.outputs = []; switch (outCount) { case 2: spec.outputs[1] = this.makeSymbol(variables.out1); case 1: spec.outputs[0] = this.makeSymbol(variables.out0); default: break; } spec.source = stmt; if (enableUnittests == false) { // Run the shader with inputs. /** @type {glsShaderExecUtil.ShaderExecutor} */ var executor = glsShaderExecUtil.createExecutor(this.m_ctx.shaderType, spec); /** @type {Array<*>} */ var inputArr = [ tcuMatrixUtil.flatten(inputs.in0), tcuMatrixUtil.flatten(inputs.in1), tcuMatrixUtil.flatten(inputs.in2), tcuMatrixUtil.flatten(inputs.in3) ]; // executor.log(log()); if (!executor.isOk()) testFailed('Shader compilation failed'); executor.useProgram(); var outputArray = executor.execute(numValues, inputArr); switch (outCount) { case 2: outputs[1] = glsBuiltinPrecisionTests.cast(this.Out.Out1, outputArray[1]); case 1: outputs[0] = glsBuiltinPrecisionTests.cast(this.Out.Out0, outputArray[0]); default: break; } } // Initialize environment with dummy values so we don't need to bind in inner loop. var in0 = new tcuInterval.Interval(); var in1 = new tcuInterval.Interval(); var in2 = new tcuInterval.Interval(); var in3 = new tcuInterval.Interval(); var reference0 = new tcuInterval.Interval(); var reference1 = new tcuInterval.Interval(); env.bind(variables.in0, in0); env.bind(variables.in1, in1); env.bind(variables.in2, in2); env.bind(variables.in3, in3); env.bind(variables.out0, reference0); env.bind(variables.out1, reference1); // For each input tuple, compute output reference interval and compare // shader output to the reference. for (var valueNdx = 0; valueNdx < numValues; valueNdx++) { /** @type {boolean} */ var result = true; var value0, value1; var msg = ''; var in0_ = glsBuiltinPrecisionTests.convert(this.Arg0, fmt, glsBuiltinPrecisionTests.round(this.Arg0, fmt, inputs.in0[valueNdx])); var in1_ = glsBuiltinPrecisionTests.convert(this.Arg1, fmt, glsBuiltinPrecisionTests.round(this.Arg1, fmt, inputs.in1[valueNdx])); var in2_ = glsBuiltinPrecisionTests.convert(this.Arg2, fmt, glsBuiltinPrecisionTests.round(this.Arg2, fmt, inputs.in2[valueNdx])); var in3_ = glsBuiltinPrecisionTests.convert(this.Arg3, fmt, glsBuiltinPrecisionTests.round(this.Arg3, fmt, inputs.in3[valueNdx])); env.bind(variables.in0, in0_); env.bind(variables.in1, in1_); env.bind(variables.in2, in2_); env.bind(variables.in3, in3_); stmt.execute(new glsBuiltinPrecisionTests.EvalContext(fmt, this.m_ctx.precision, env)); switch (outCount) { case 2: reference1 = glsBuiltinPrecisionTests.convert(this.Out.Out1, highpFmt, env.lookup(variables.out1)); if (enableUnittests) result = referenceComparison(reference1, valueNdx + outCount - 1, this.m_ctx.floatFormat); else { value1 = glsBuiltinPrecisionTests.getOutput(outputs[1], valueNdx, reference1); if (!glsBuiltinPrecisionTests.contains(this.Out.Out1, reference1, value1)) { msg = 'Shader output 1 (' + value1 + ') is outside acceptable range: ' + reference1; result = false; } } case 1: reference0 = glsBuiltinPrecisionTests.convert(this.Out.Out0, highpFmt, env.lookup(variables.out0)); if (enableUnittests) result = referenceComparison(reference0, valueNdx + outCount - 1, this.m_ctx.floatFormat); else { value0 = glsBuiltinPrecisionTests.getOutput(outputs[0], valueNdx, reference0); if (!glsBuiltinPrecisionTests.contains(this.Out.Out0, reference0, value0)) { msg = 'Shader output 0 (' + value0 + ') is outside acceptable range: ' + reference0; result = false; } } default: break; } if (!result) ++numErrors; if (!result && numErrors <= maxMsgs) { /** @type {string} */ var builder = ''; builder += (result ? 'Passed' : 'Failed') + '\n' + msg + '\n sample:\n' + valueNdx; if (inCount > 0) { builder += '\t' + variables.in0.getName() + ' = ' + inputs.in0[valueNdx] + '\n'; } if (inCount > 1) { builder += '\t' + variables.in1.getName() + ' = ' + inputs.in1[valueNdx] + '\n'; } if (inCount > 2) { builder += '\t' + variables.in2.getName() + ' = ' + inputs.in2[valueNdx] + '\n'; } if (inCount > 3) { builder += '\t' + variables.in3.getName() + ' = ' + inputs.in3[valueNdx] + '\n'; } if (enableUnittests == false) { if (outCount > 0) { builder += '\t' + variables.out0.getName() + ' = ' + value0 + '\n' + '\tExpected range: ' + reference0 + '\n'; } if (outCount > 1) { builder += '\t' + variables.out1.getName() + ' = ' + value1 + '\n' + '\tExpected range: ' + reference1 + '\n'; } } bufferedLogToConsole(builder); } } if (numErrors > maxMsgs) { bufferedLogToConsole('(Skipped ' + (numErrors - maxMsgs) + ' messages.)'); } if (numErrors == 0) { testPassed('All ' + numValues + ' inputs passed.'); } else { testFailed('' + numErrors + '/' + numValues + ' inputs failed.'); } }; /** * @param {glsBuiltinPrecisionTests.Variable} variable Variable * @return {glsShaderExecUtil.Symbol} */ glsBuiltinPrecisionTests.PrecisionCase.prototype.makeSymbol = function(variable) { var v = variable; return new glsShaderExecUtil.Symbol(v.getName(), gluVarType.getVarTypeOf(v.typename, this.m_size, this.m_ctx.precision)); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Tuple4} * @param {*} in0 * @param {*} in1 * @param {*} in2 * @param {*} in3 */ glsBuiltinPrecisionTests.InTuple = function(in0, in1, in2, in3) { glsBuiltinPrecisionTests.Tuple4.call(this, in0, in1, in2, in3); }; glsBuiltinPrecisionTests.InTuple.prototype = Object.create(glsBuiltinPrecisionTests.Tuple4.prototype); glsBuiltinPrecisionTests.InTuple.prototype.constructor = glsBuiltinPrecisionTests.InTuple; /** * @param {*} In * @param {glsBuiltinPrecisionTests.Samplings} samplings Samplings * @param {tcuFloatFormat.FloatFormat} floatFormat * @param {gluShaderUtil.precision} intPrecision * @param {number} numSamples * @param {deRandom.Random} rnd * @return {glsBuiltinPrecisionTests.Inputs} */ glsBuiltinPrecisionTests.generateInputs = function(In, samplings, floatFormat, intPrecision, numSamples, rnd) { /*Inputs*/ var ret = new glsBuiltinPrecisionTests.Inputs(In); /*Inputs*/ var fixedInputs = new glsBuiltinPrecisionTests.Inputs(In); // set, InputLess > > seenInputs; /** @type {Array} */ var seenInputs = []; samplings.in0.genFixeds(floatFormat, fixedInputs.in0); samplings.in1.genFixeds(floatFormat, fixedInputs.in1); samplings.in2.genFixeds(floatFormat, fixedInputs.in2); samplings.in3.genFixeds(floatFormat, fixedInputs.in3); for (var ndx0 = 0; ndx0 < fixedInputs.in0.length; ++ndx0) { for (var ndx1 = 0; ndx1 < fixedInputs.in1.length; ++ndx1) { for (var ndx2 = 0; ndx2 < fixedInputs.in2.length; ++ndx2) { for (var ndx3 = 0; ndx3 < fixedInputs.in3.length; ++ndx3) { var tuple = new glsBuiltinPrecisionTests.InTuple(fixedInputs.in0[ndx0], fixedInputs.in1[ndx1], fixedInputs.in2[ndx2], fixedInputs.in3[ndx3]); seenInputs.push(tuple); ret.in0.push(tuple.a); ret.in1.push(tuple.b); ret.in2.push(tuple.c); ret.in3.push(tuple.d); } } } } for (var ndx = 0; ndx < numSamples; ++ndx) { var in0 = samplings.in0.genRandom(floatFormat, intPrecision, rnd); var in1 = samplings.in1.genRandom(floatFormat, intPrecision, rnd); var in2 = samplings.in2.genRandom(floatFormat, intPrecision, rnd); var in3 = samplings.in3.genRandom(floatFormat, intPrecision, rnd); var tuple = new glsBuiltinPrecisionTests.InTuple(in0, in1, in2, in3); // if (de::contains(seenInputs, tuple)) // continue; seenInputs.push(tuple); ret.in0.push(in0); ret.in1.push(in1); ret.in2.push(in2); ret.in3.push(in3); } return ret; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.PrecisionCase} * @param {string} name * @param {glsBuiltinPrecisionTests.FuncBase} func */ glsBuiltinPrecisionTests.FuncCaseBase = function(context, name, func) { glsBuiltinPrecisionTests.PrecisionCase.call(this, context, name, func.getRequiredExtension()); }; glsBuiltinPrecisionTests.FuncCaseBase.prototype = Object.create(glsBuiltinPrecisionTests.PrecisionCase.prototype); glsBuiltinPrecisionTests.FuncCaseBase.prototype.constructor = glsBuiltinPrecisionTests.FuncCaseBase; glsBuiltinPrecisionTests.FuncCaseBase.prototype.iterate = function() { assertMsgOptions(!(this.m_extension !== undefined && this.m_extension.trim() !== '') && !sglrGLContext.isExtensionSupported(gl, this.m_extension), 'Unsupported extension: ' + this.m_extension, false, true); this.runTest(); // m_status.setTestContextResult(m_testCtx); return tcuTestCase.IterateResult.STOP; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.FuncCaseBase} * @param {glsBuiltinPrecisionTests.Context} context * @param {string} name * @param {glsBuiltinPrecisionTests.Func} func */ glsBuiltinPrecisionTests.InOutFuncCase = function(context, name, func) { glsBuiltinPrecisionTests.FuncCaseBase.call(this, context, name, func); this.Sig = func.Sig; this.m_func = func; this.Ret = func.Sig.Ret; this.Arg0 = func.Sig.Arg0; this.Arg1 = func.Sig.Arg1; this.Arg2 = func.Sig.Arg2; this.Arg3 = func.Sig.Arg3; this.In = new glsBuiltinPrecisionTests.InTypes(this.Arg0, this.Arg2, this.Arg3); this.Out = new glsBuiltinPrecisionTests.OutTypes(this.Ret, this.Arg1); this.m_size = this.m_func.m_size; }; glsBuiltinPrecisionTests.InOutFuncCase.prototype = Object.create(glsBuiltinPrecisionTests.FuncCaseBase.prototype); glsBuiltinPrecisionTests.InOutFuncCase.prototype.constructor = glsBuiltinPrecisionTests.InOutFuncCase; /** * Samplings * @return {glsBuiltinPrecisionTests.Samplings} */ glsBuiltinPrecisionTests.InOutFuncCase.prototype.getSamplings = function() { return new glsBuiltinPrecisionTests.DefaultSamplings(this.In, this.m_size); }; /** * @param {glsBuiltinPrecisionTests.Signature} Sig_ */ glsBuiltinPrecisionTests.InOutFuncCase.prototype.runTest = function(Sig_) { /** @type {glsBuiltinPrecisionTests.Inputs} */ var inputs = (glsBuiltinPrecisionTests.generateInputs( this.In, this.getSamplings(), this.m_ctx.floatFormat, this.m_ctx.precision, this.m_ctx.numRandoms, this.m_rnd)); var variables = new glsBuiltinPrecisionTests.Variables(this.In, this.Out); // Variables variables; // variables.out0 = new glsBuiltinPrecisionTests.Variable(this.Out.Out0, 'out0'); variables.out1 = new glsBuiltinPrecisionTests.Variable(this.Arg1, 'out1'); variables.in0 = new glsBuiltinPrecisionTests.Variable(this.Arg0, 'in0'); variables.in1 = new glsBuiltinPrecisionTests.Variable(this.Arg2, 'in1'); variables.in2 = new glsBuiltinPrecisionTests.Variable(this.Arg3, 'in2'); variables.in3 = new glsBuiltinPrecisionTests.Variable('void', 'in3'); var expr = glsBuiltinPrecisionTests.applyVar(this.m_func, variables.in0, variables.out1, variables.in1, variables.in2); var stmt = glsBuiltinPrecisionTests.variableAssignment(variables.out0, expr); this.testStatement(variables, inputs, stmt); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.FuncCaseBase} * @param {glsBuiltinPrecisionTests.Context} context * @param {string} name * @param {glsBuiltinPrecisionTests.Func} func */ glsBuiltinPrecisionTests.FuncCase = function(context, name, func) { glsBuiltinPrecisionTests.FuncCaseBase.call(this, context, name, func); this.Sig = func.Sig; this.m_func = func; this.Ret = func.Sig.Ret; this.Arg0 = func.Sig.Arg0; this.Arg1 = func.Sig.Arg1; this.Arg2 = func.Sig.Arg2; this.Arg3 = func.Sig.Arg3; this.In = new glsBuiltinPrecisionTests.InTypes(this.Arg0, this.Arg1, this.Arg2, this.Arg3); this.Out = new glsBuiltinPrecisionTests.OutTypes(this.Ret); this.m_size = this.m_func.m_size; }; glsBuiltinPrecisionTests.FuncCase.prototype = Object.create(glsBuiltinPrecisionTests.FuncCaseBase.prototype); glsBuiltinPrecisionTests.FuncCase.prototype.constructor = glsBuiltinPrecisionTests.FuncCase; /** * Samplings * @return {glsBuiltinPrecisionTests.Samplings} */ glsBuiltinPrecisionTests.FuncCase.prototype.getSamplings = function() { return new glsBuiltinPrecisionTests.DefaultSamplings(this.In, this.m_size); }; /** * @param {glsBuiltinPrecisionTests.Signature} Sig_ */ glsBuiltinPrecisionTests.FuncCase.prototype.runTest = function(Sig_) { /** @type {glsBuiltinPrecisionTests.Inputs} */ var inputs = (glsBuiltinPrecisionTests.generateInputs( this.In, this.getSamplings(), this.m_ctx.floatFormat, this.m_ctx.precision, this.m_ctx.numRandoms, this.m_rnd)); var variables = new glsBuiltinPrecisionTests.Variables(this.In, this.Out); // Variables variables; // variables.out0 = new glsBuiltinPrecisionTests.Variable(this.Ret, 'out0'); variables.out1 = new glsBuiltinPrecisionTests.Variable('void', 'out1'); variables.in0 = new glsBuiltinPrecisionTests.Variable(this.Arg0, 'in0'); variables.in1 = new glsBuiltinPrecisionTests.Variable(this.Arg1, 'in1'); variables.in2 = new glsBuiltinPrecisionTests.Variable(this.Arg2, 'in2'); variables.in3 = new glsBuiltinPrecisionTests.Variable(this.Arg3, 'in3'); var expr = glsBuiltinPrecisionTests.applyVar(this.m_func, variables.in0, variables.in1, variables.in2, variables.in3); var stmt = glsBuiltinPrecisionTests.variableAssignment(variables.out0, expr); this.testStatement(variables, inputs, stmt); }; /** * @param {glsBuiltinPrecisionTests.Func} func * @param {glsBuiltinPrecisionTests.Variable} arg0 * @param {glsBuiltinPrecisionTests.Variable} arg1 * @param {glsBuiltinPrecisionTests.Variable} arg2 * @param {glsBuiltinPrecisionTests.Variable} arg3 * @return {glsBuiltinPrecisionTests.ApplyVar} */ glsBuiltinPrecisionTests.applyVar = function(func, arg0, arg1, arg2, arg3) { return new glsBuiltinPrecisionTests.ApplyVar(func.Sig, func, arg0, arg1, arg2, arg3); }; /** * @param {glsBuiltinPrecisionTests.Variable} variable * @param {glsBuiltinPrecisionTests.ApplyVar} value * @param {boolean} isDeclaration */ glsBuiltinPrecisionTests.variableStatement = function(variable, value, isDeclaration) { return new glsBuiltinPrecisionTests.VariableStatement(variable, value, isDeclaration); }; /** * @param {glsBuiltinPrecisionTests.Variable} variable * @param {glsBuiltinPrecisionTests.ApplyVar} value */ glsBuiltinPrecisionTests.variableAssignment = function(variable, value) { return glsBuiltinPrecisionTests.variableStatement(variable, value, false); }; /** * @constructor */ glsBuiltinPrecisionTests.CaseFactories = function() {}; /** * @return {Array} */ glsBuiltinPrecisionTests.CaseFactories.prototype.getFactories = function() {}; /** * @constructor * @extends {glsBuiltinPrecisionTests.CaseFactories} */ glsBuiltinPrecisionTests.BuiltinFuncs = function() { /** @type {Array} */ this.m_factories = []; }; glsBuiltinPrecisionTests.BuiltinFuncs.prototype = Object.create(glsBuiltinPrecisionTests.CaseFactories.prototype); glsBuiltinPrecisionTests.BuiltinFuncs.prototype.constructor = glsBuiltinPrecisionTests.BuiltinFuncs; /** * @return {Array} */ glsBuiltinPrecisionTests.BuiltinFuncs.prototype.getFactories = function() { return this.m_factories.slice(); }; /** * @param {glsBuiltinPrecisionTests.CaseFactory} fact */ glsBuiltinPrecisionTests.BuiltinFuncs.prototype.addFactory = function(fact) { this.m_factories.push(fact); }; /** * @param {glsBuiltinPrecisionTests.Context} context * @param {string} name * @param {glsBuiltinPrecisionTests.Func} func * @return {glsBuiltinPrecisionTests.PrecisionCase} */ glsBuiltinPrecisionTests.createFuncCase = function(context, name, func) { switch (func.getOutParamIndex()) { case -1: return new glsBuiltinPrecisionTests.FuncCase(context, name, func); case 1: return new glsBuiltinPrecisionTests.InOutFuncCase(context, name, func); default: throw new Error(!'Impossible'); } }; /** * @constructor */ glsBuiltinPrecisionTests.CaseFactory = function() {}; /** * @return {string} */ glsBuiltinPrecisionTests.CaseFactory.prototype.getName = function() { return ''; }; /** * @return {string} */ glsBuiltinPrecisionTests.CaseFactory.prototype.getDesc = function() { return ''; }; /** * @param {glsBuiltinPrecisionTests.Context} ctx */ glsBuiltinPrecisionTests.CaseFactory.prototype.createCase = function(ctx) { throw new Error('Virtual function. Please override.'); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.CaseFactory} * @param {glsBuiltinPrecisionTests.Func} func */ glsBuiltinPrecisionTests.SimpleFuncCaseFactory = function(func) { glsBuiltinPrecisionTests.CaseFactory.call(this); this.m_func = func; }; setParentClass(glsBuiltinPrecisionTests.SimpleFuncCaseFactory, glsBuiltinPrecisionTests.CaseFactory); glsBuiltinPrecisionTests.SimpleFuncCaseFactory.prototype.getName = function() { return this.m_func.getName().toLowerCase(); }; glsBuiltinPrecisionTests.SimpleFuncCaseFactory.prototype.getDesc = function() { return "Function '" + this.getName() + "'"; }; glsBuiltinPrecisionTests.SimpleFuncCaseFactory.prototype.createCase = function(ctx) { return glsBuiltinPrecisionTests.createFuncCase(ctx, ctx.name, this.m_func); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.CaseFactory} */ glsBuiltinPrecisionTests.FuncCaseFactory = function() { glsBuiltinPrecisionTests.CaseFactory.call(this); }; setParentClass(glsBuiltinPrecisionTests.FuncCaseFactory, glsBuiltinPrecisionTests.CaseFactory); glsBuiltinPrecisionTests.FuncCaseFactory.prototype.getFunc = function() { throw new Error('Virtual function. Please override.'); }; glsBuiltinPrecisionTests.FuncCaseFactory.prototype.getName = function() { return this.getFunc().getName().toLowerCase(); }; glsBuiltinPrecisionTests.FuncCaseFactory.prototype.getDesc = function() { return "Function '" + this.getFunc().getName() + "'"; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.FuncCaseFactory} */ glsBuiltinPrecisionTests.TemplateFuncCaseFactory = function(genF) { glsBuiltinPrecisionTests.FuncCaseFactory.call(this); this.m_genF = genF; }; setParentClass(glsBuiltinPrecisionTests.TemplateFuncCaseFactory, glsBuiltinPrecisionTests.FuncCaseFactory); glsBuiltinPrecisionTests.TemplateFuncCaseFactory.prototype.getFunc = function() { return new this.m_genF(1); }; /** * @param {glsBuiltinPrecisionTests.Context} ctx */ glsBuiltinPrecisionTests.TemplateFuncCaseFactory.prototype.createCase = function(ctx) { var group = tcuTestCase.newTest(ctx.name, ctx.name); group.addChild(glsBuiltinPrecisionTests.createFuncCase(ctx, 'scalar', new this.m_genF(1))); group.addChild(glsBuiltinPrecisionTests.createFuncCase(ctx, 'vec2', new this.m_genF(2))); group.addChild(glsBuiltinPrecisionTests.createFuncCase(ctx, 'vec3', new this.m_genF(3))); group.addChild(glsBuiltinPrecisionTests.createFuncCase(ctx, 'vec4', new this.m_genF(4))); return group; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.FuncCaseFactory} */ glsBuiltinPrecisionTests.MatrixFuncCaseFactory = function(genF) { glsBuiltinPrecisionTests.FuncCaseFactory.call(this); this.m_genF = genF; }; setParentClass(glsBuiltinPrecisionTests.MatrixFuncCaseFactory, glsBuiltinPrecisionTests.FuncCaseFactory); glsBuiltinPrecisionTests.MatrixFuncCaseFactory.prototype.getFunc = function() { return new this.m_genF(2, 2); }; /** * @param {glsBuiltinPrecisionTests.Context} ctx */ glsBuiltinPrecisionTests.MatrixFuncCaseFactory.prototype.createCase = function(ctx) { var group = tcuTestCase.newTest(ctx.name, ctx.name); this.addCase(ctx, group, 2, 2); this.addCase(ctx, group, 3, 2); this.addCase(ctx, group, 4, 2); this.addCase(ctx, group, 2, 3); this.addCase(ctx, group, 3, 3); this.addCase(ctx, group, 4, 3); this.addCase(ctx, group, 2, 4); this.addCase(ctx, group, 3, 4); this.addCase(ctx, group, 4, 4); return group; }; /** * @param {glsBuiltinPrecisionTests.Context} ctx * @param {tcuTestCase.DeqpTest} group * @param {number} rows * @param {number} cols */ glsBuiltinPrecisionTests.MatrixFuncCaseFactory.prototype.addCase = function(ctx, group, rows, cols) { var name = glsBuiltinPrecisionTests.dataTypeNameOfMatrix('float', rows, cols); group.addChild(glsBuiltinPrecisionTests.createFuncCase(ctx, name, new this.m_genF(rows, cols))); }; glsBuiltinPrecisionTests.dataTypeNameOfMatrix = function(typename, rows, cols) { switch (typename) { case 'float': if (rows === cols) return 'mat' + rows; else return 'mat' + cols + 'x' + rows; } throw new Error('Invalid arguments (' + typename + ', ' + rows + ', ' + cols + ')'); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.FuncCaseFactory} */ glsBuiltinPrecisionTests.SquareMatrixFuncCaseFactory = function(genF) { glsBuiltinPrecisionTests.FuncCaseFactory.call(this); this.m_genF = genF; }; setParentClass(glsBuiltinPrecisionTests.SquareMatrixFuncCaseFactory, glsBuiltinPrecisionTests.FuncCaseFactory); glsBuiltinPrecisionTests.SquareMatrixFuncCaseFactory.prototype.getFunc = function() { return new this.m_genF(2); }; /** * @param {glsBuiltinPrecisionTests.Context} ctx */ glsBuiltinPrecisionTests.SquareMatrixFuncCaseFactory.prototype.createCase = function(ctx) { var group = tcuTestCase.newTest(ctx.name, ctx.name); group.addChild(glsBuiltinPrecisionTests.createFuncCase(ctx, 'mat2', new this.m_genF(2))); return group; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.PrimitiveFunc} * @param {glsBuiltinPrecisionTests.Func} scalarFunc * @param {number=} size */ glsBuiltinPrecisionTests.GenFunc = function(scalarFunc, size) { glsBuiltinPrecisionTests.PrimitiveFunc.call(this, scalarFunc.Sig); this.m_func = scalarFunc; this.m_size = size; }; glsBuiltinPrecisionTests.GenFunc.prototype = Object.create(glsBuiltinPrecisionTests.PrimitiveFunc.prototype); glsBuiltinPrecisionTests.GenFunc.prototype.constructor = glsBuiltinPrecisionTests.GenFunc; /** * @return {string} */ glsBuiltinPrecisionTests.GenFunc.prototype.getName = function() { return this.m_func.getName(); }; /** * @return {number} */ glsBuiltinPrecisionTests.GenFunc.prototype.getOutParamIndex = function() { return this.m_func.getOutParamIndex(); }; /** * @return {string} */ glsBuiltinPrecisionTests.GenFunc.prototype.getRequiredExtension = function() { return this.m_func.getRequiredExtension(); }; /** * @param {Array} args */ glsBuiltinPrecisionTests.GenFunc.prototype.doPrint = function(args) { return this.m_func.print(args); }; /** * @param {glsBuiltinPrecisionTests.EvalContext} ctx * @param {glsBuiltinPrecisionTests.Tuple4} iargs * @return {*} */ glsBuiltinPrecisionTests.GenFunc.prototype.doApply = function(ctx, iargs) { /** @type {Array<*>} */ var ret = []; if (this.m_size > 1) { for (var ndx = 0; ndx < this.m_size; ++ndx) { var a = iargs.a === undefined ? undefined : iargs.a[ndx]; var b = iargs.b === undefined ? undefined : iargs.b[ndx]; var c = iargs.c === undefined ? undefined : iargs.c[ndx]; var d = iargs.d === undefined ? undefined : iargs.d[ndx]; ret[ndx] = this.m_func.applyFunction(ctx, a, b, c, d); } } else ret[0] = this.m_func.applyFunction(ctx, iargs.a, iargs.b, iargs.c, iargs.d); return ret; }; /** * @param {glsBuiltinPrecisionTests.FuncSet} dst */ glsBuiltinPrecisionTests.GenFunc.prototype.doGetUsedFuncs = function(dst) { this.m_func.getUsedFuncs(dst); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.GenFunc} * @param {glsBuiltinPrecisionTests.Func} func * @param {number} size */ glsBuiltinPrecisionTests.VectorizedFunc = function(func, size) { glsBuiltinPrecisionTests.GenFunc.call(this, func, size); }; glsBuiltinPrecisionTests.VectorizedFunc.prototype = Object.create(glsBuiltinPrecisionTests.GenFunc.prototype); glsBuiltinPrecisionTests.VectorizedFunc.prototype.constructor = glsBuiltinPrecisionTests.VectorizedFunc; /** * @constructor * @param {glsBuiltinPrecisionTests.Func} func_ * @param {glsBuiltinPrecisionTests.GenFunc} func2_ * @param {glsBuiltinPrecisionTests.GenFunc} func3_ * @param {glsBuiltinPrecisionTests.GenFunc} func4_ */ glsBuiltinPrecisionTests.GenFuncs = function(func_, func2_, func3_, func4_) { this.func = func_; this.func2 = func2_; this.func3 = func3_; this.func4 = func4_; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.CaseFactory} * @param {glsBuiltinPrecisionTests.GenFuncs} funcs * @param {string} name */ glsBuiltinPrecisionTests.GenFuncCaseFactory = function(funcs, name) { glsBuiltinPrecisionTests.CaseFactory.call(this); this.m_funcs = funcs; this.m_name = name; }; glsBuiltinPrecisionTests.GenFuncCaseFactory.prototype = Object.create(glsBuiltinPrecisionTests.CaseFactory.prototype); glsBuiltinPrecisionTests.GenFuncCaseFactory.prototype.constructor = glsBuiltinPrecisionTests.GenFuncCaseFactory; /** * @param {glsBuiltinPrecisionTests.Context} ctx * @return {tcuTestCase.DeqpTest} */ glsBuiltinPrecisionTests.GenFuncCaseFactory.prototype.createCase = function(ctx) { /** @type {tcuTestCase.DeqpTest} */ var group = tcuTestCase.newTest(ctx.name, ctx.name); group.addChild(glsBuiltinPrecisionTests.createFuncCase(ctx, 'scalar', this.m_funcs.func)); group.addChild(glsBuiltinPrecisionTests.createFuncCase(ctx, 'vec2', this.m_funcs.func2)); group.addChild(glsBuiltinPrecisionTests.createFuncCase(ctx, 'vec3', this.m_funcs.func3)); group.addChild(glsBuiltinPrecisionTests.createFuncCase(ctx, 'vec4', this.m_funcs.func4)); return group; }; /** * @return {string} */ glsBuiltinPrecisionTests.GenFuncCaseFactory.prototype.getName = function() { return this.m_name; }; /** * @return {string} */ glsBuiltinPrecisionTests.GenFuncCaseFactory.prototype.getDesc = function() { return "Function '" + this.m_funcs.func.getName() + "'"; }; /** * @constructor * @param {string} name_ * @param {tcuFloatFormat.FloatFormat} floatFormat_ * @param {tcuFloatFormat.FloatFormat} highpFormat_ * @param {gluShaderUtil.precision} precision_ * @param {gluShaderProgram.shaderType} shaderType_ * @param {number} numRandoms_ */ glsBuiltinPrecisionTests.Context = function(name_, floatFormat_, highpFormat_, precision_, shaderType_, numRandoms_) { /** @type {string} */ this.name = name_; /** @type {tcuFloatFormat.FloatFormat} */ this.floatFormat = floatFormat_; /** @type {tcuFloatFormat.FloatFormat} */ this.highpFormat = highpFormat_; /** @type {gluShaderUtil.precision} */ this.precision = precision_; /** @type {gluShaderProgram.shaderType} */ this.shaderType = shaderType_; /** @type {number} */ this.numRandoms = numRandoms_; }; /** * @constructor * @param {tcuFloatFormat.FloatFormat} highp_ * @param {tcuFloatFormat.FloatFormat} mediump_ * @param {tcuFloatFormat.FloatFormat} lowp_ * @param {Array} shaderTypes_ * @param {number} numRandoms_ */ glsBuiltinPrecisionTests.PrecisionTestContext = function(highp_, mediump_, lowp_, shaderTypes_, numRandoms_) { /** @type {Array} */ this.shaderTypes = shaderTypes_; /** @type {Array} */ this.formats = []; this.formats[gluShaderUtil.precision.PRECISION_HIGHP] = highp_; this.formats[gluShaderUtil.precision.PRECISION_MEDIUMP] = mediump_; this.formats[gluShaderUtil.precision.PRECISION_LOWP] = lowp_; /** @type {number} */ this.numRandoms = numRandoms_; }; /** * \brief Simple incremental counter. * * This is used to make sure that different ExpandContexts will not produce * overlapping temporary names. * @constructor * */ glsBuiltinPrecisionTests.Counter = function() { this.m_count = 0; }; glsBuiltinPrecisionTests.Counter.prototype.get = function() { return this.m_count++; }; /** * @constructor */ glsBuiltinPrecisionTests.ExpandContext = function(counter) { this.m_counter = counter; this.m_statements = []; }; /** * @param {string} typename * @param {string} baseName * @return {glsBuiltinPrecisionTests.Variable} */ glsBuiltinPrecisionTests.ExpandContext.prototype.genSym = function(typename, baseName) { return new glsBuiltinPrecisionTests.Variable(typename, baseName + this.m_counter.get()); }; glsBuiltinPrecisionTests.ExpandContext.prototype.addStatement = function(/*const StatementP&*/ stmt) { this.m_statements.push(stmt); }; glsBuiltinPrecisionTests.ExpandContext.prototype.getStatements = function() { return this.m_statements; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Func} * @param {glsBuiltinPrecisionTests.Signature} Sig_ template */ glsBuiltinPrecisionTests.DerivedFunc = function(Sig_) { glsBuiltinPrecisionTests.Func.call(this, Sig_); }; setParentClass(glsBuiltinPrecisionTests.DerivedFunc, glsBuiltinPrecisionTests.Func); glsBuiltinPrecisionTests.DerivedFunc.prototype.doPrintDefinition = function() { var os = ''; var paramNames = this.getParamNames(); this.initialize(); os += this.Ret + ' ' + this.getName() + '('; if (glsBuiltinPrecisionTests.isTypeValid(this.Arg0)) os += this.Arg0 + ' ' + paramNames.a; if (glsBuiltinPrecisionTests.isTypeValid(this.Arg1)) os += ', ' + this.Arg1 + ' ' + paramNames.b; if (glsBuiltinPrecisionTests.isTypeValid(this.Arg2)) os += ', ' + this.Arg2 + ' ' + paramNames.c; if (glsBuiltinPrecisionTests.isTypeValid(this.Arg3)) os += ', ' + this.Arg3 + ' ' + paramNames.d; os += ')\n{\n'; for (var ndx = 0; ndx < this.m_body.length; ++ndx) os += this.m_body[ndx]; os += 'return ' + this.m_ret + ';\n'; os += '}\n'; return os; }; glsBuiltinPrecisionTests.DerivedFunc.prototype.doApply = function(ctx, args) { var funEnv = new glsBuiltinPrecisionTests.Environment(); this.initialize(); funEnv.bind(this.m_var0, args.a); funEnv.bind(this.m_var1, args.b); funEnv.bind(this.m_var2, args.c); funEnv.bind(this.m_var3, args.d); var funCtx = new glsBuiltinPrecisionTests.EvalContext(ctx.format, ctx.floatPrecision, funEnv, ctx.callDepth); for (var ndx = 0; ndx < this.m_body.length; ++ndx) this.m_body[ndx].execute(funCtx); var ret = this.m_ret.evaluate(funCtx); // \todo [lauri] Store references instead of values in environment args.a = funEnv.lookup(this.m_var0); args.b = funEnv.lookup(this.m_var1); args.c = funEnv.lookup(this.m_var2); args.d = funEnv.lookup(this.m_var3); return ret; }; glsBuiltinPrecisionTests.DerivedFunc.prototype.initialize = function() { if (!this.m_ret) { var paramNames = this.getParamNames(); var symCounter = new glsBuiltinPrecisionTests.Counter(); var ctx = new glsBuiltinPrecisionTests.ExpandContext(symCounter); this.m_var0 = new glsBuiltinPrecisionTests.Variable(this.Arg0, paramNames.a); this.m_var1 = new glsBuiltinPrecisionTests.Variable(this.Arg1, paramNames.b); this.m_var2 = new glsBuiltinPrecisionTests.Variable(this.Arg2, paramNames.c); this.m_var3 = new glsBuiltinPrecisionTests.Variable(this.Arg3, paramNames.d); var args = new glsBuiltinPrecisionTests.Tuple4(this.m_var0, this.m_var1, this.m_var2, this.m_var3); this.m_ret = this.doExpand(ctx, args); this.m_body = ctx.getStatements(); } }; /** * @constructor * @extends {glsBuiltinPrecisionTests.Func} * @param {glsBuiltinPrecisionTests.Signature} Sig_ template */ glsBuiltinPrecisionTests.Alternatives = function(Sig_) { glsBuiltinPrecisionTests.Func.call(this, Sig_); }; setParentClass(glsBuiltinPrecisionTests.Alternatives,glsBuiltinPrecisionTests.Func); glsBuiltinPrecisionTests.Alternatives.prototype.getName = function() { return 'alternatives'; }; glsBuiltinPrecisionTests.Alternatives.prototype.doPrintDefinition = function() {}; glsBuiltinPrecisionTests.Alternatives.prototype.doGetUsedFuncs = function(dst) {}; glsBuiltinPrecisionTests.Alternatives.prototype.doApply = function(ctx,args) { return glsBuiltinPrecisionTests.union(this.Sig.Ret,args.a,args.b); }; glsBuiltinPrecisionTests.Alternatives.prototype.doPrint = function(args) { return '{' + args[0] + '|' + args[1] + '}'; }; glsBuiltinPrecisionTests.sizeToName = function(size) { switch (size) { case 4: return 'vec4'; case 3: return 'vec3'; case 2: return 'vec2'; } return 'float'; }; /** * @constructor * @param {number} size * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Dot = function(size) { var name = glsBuiltinPrecisionTests.sizeToName(size); var sig = new glsBuiltinPrecisionTests.Signature('float', name, name); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); this.m_inputSize = size; }; setParentClass(glsBuiltinPrecisionTests.Dot, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Dot.prototype.getName = function() { return 'dot'; }; glsBuiltinPrecisionTests.Dot.prototype.doExpand = function(ctx, args) { if (this.m_inputSize > 1) { var val = app(new glsBuiltinPrecisionTests.Mul(), new glsBuiltinPrecisionTests.VectorVariable(args.a, 0), new glsBuiltinPrecisionTests.VectorVariable(args.b, 0)); for (var i = 1; i < this.m_inputSize; i++) { var tmp = new glsBuiltinPrecisionTests.Apply('float', new glsBuiltinPrecisionTests.Mul(), new glsBuiltinPrecisionTests.VectorVariable(args.a, i), new glsBuiltinPrecisionTests.VectorVariable(args.b, i)); val = app(new glsBuiltinPrecisionTests.Add(), val, tmp); } return val; } else { // args.a * args.b var ret = app(new glsBuiltinPrecisionTests.Mul(), args.a, args.b); return ret; } }; /** * @constructor * @param {number} size * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Length = function(size) { var name = glsBuiltinPrecisionTests.sizeToName(size); var sig = new glsBuiltinPrecisionTests.Signature('float', name); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); this.m_inputSize = size; }; setParentClass(glsBuiltinPrecisionTests.Length, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Length.prototype.getName = function() { return 'length'; }; glsBuiltinPrecisionTests.Length.prototype.doExpand = function(ctx, args) { //sqrt(dot(args.a, args.a)); var v0 = app(new glsBuiltinPrecisionTests.Dot(this.m_inputSize), args.a, args.a); var v1 = app(new glsBuiltinPrecisionTests.Sqrt(), v0); return v1; }; /** * @constructor * @param {number} size * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Distance = function(size) { var name = glsBuiltinPrecisionTests.sizeToName(size); var sig = new glsBuiltinPrecisionTests.Signature('float', name, name); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); this.m_inputSize = size; }; setParentClass(glsBuiltinPrecisionTests.Distance, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Distance.prototype.getName = function() { return 'distance'; }; glsBuiltinPrecisionTests.Distance.prototype.doExpand = function(ctx, args) { //length(args.a - args.b); var v0 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.Sub(), args.a, args.b); var v1 = app(new glsBuiltinPrecisionTests.Length(this.m_inputSize), v0); return v1; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Cross = function() { var sig = new glsBuiltinPrecisionTests.Signature('vec3', 'vec3', 'vec3'); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); this.m_inputSize = 3; }; setParentClass(glsBuiltinPrecisionTests.Cross, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Cross.prototype.getName = function() { return 'cross'; }; glsBuiltinPrecisionTests.Cross.prototype.doExpand = function(ctx, args) { // vec3(x.a[1] * x.b[2] - x.b[1] * x.a[2], // x.a[2] * x.b[0] - x.b[2] * x.a[0], // x.a[0] * x.b[1] - x.b[0] * x.a[1]); var a = [], b = []; for (var i = 0; i < this.m_inputSize; i++) { a[i] = new glsBuiltinPrecisionTests.VectorVariable(args.a, i); b[i] = new glsBuiltinPrecisionTests.VectorVariable(args.b, i); } var v0 = app(new glsBuiltinPrecisionTests.Mul(), a[1], b[2]); var v1 = app(new glsBuiltinPrecisionTests.Mul(), b[1], a[2]); var v2 = app(new glsBuiltinPrecisionTests.Sub(), v0, v1); var v3 = app(new glsBuiltinPrecisionTests.Mul(), a[2], b[0]); var v4 = app(new glsBuiltinPrecisionTests.Mul(), b[2], a[0]); var v5 = app(new glsBuiltinPrecisionTests.Sub(), v3, v4); var v6 = app(new glsBuiltinPrecisionTests.Mul(), a[0], b[1]); var v7 = app(new glsBuiltinPrecisionTests.Mul(), b[0], a[1]); var v8 = app(new glsBuiltinPrecisionTests.Sub(), v6, v7); var v9 = app(new glsBuiltinPrecisionTests.GenVec(this.m_inputSize, true), v2, v5, v8); return v9; }; /** * @constructor * @param {number} size * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Normalize = function(size) { var name = glsBuiltinPrecisionTests.sizeToName(size); var sig = new glsBuiltinPrecisionTests.Signature(name, name); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); this.m_inputSize = size; }; setParentClass(glsBuiltinPrecisionTests.Normalize, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Normalize.prototype.getName = function() { return 'normalize'; }; glsBuiltinPrecisionTests.Normalize.prototype.doExpand = function(ctx, args) { //args.a / length(args.a); var v0 = app(new glsBuiltinPrecisionTests.Length(this.m_inputSize), args.a); var v1 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.Div(), args.a, v0); return v1; }; /** * @constructor * @param {number} size * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.FaceForward = function(size) { var name = glsBuiltinPrecisionTests.sizeToName(size); var sig = new glsBuiltinPrecisionTests.Signature(name, name, name, name); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); this.m_inputSize = size; this.typename = name; }; setParentClass(glsBuiltinPrecisionTests.FaceForward, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.FaceForward.prototype.getName = function() { return 'faceforward'; }; glsBuiltinPrecisionTests.FaceForward.prototype.doExpand = function(ctx, args) { //cond(dot(args.c, args.b) < constant(0.0f), args.a, -args.a); var zero = new glsBuiltinPrecisionTests.Constant(0); var v0 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.Negate(), args.a); var v1 = app(new glsBuiltinPrecisionTests.Dot(this.m_inputSize), args.c, args.b); var v2 = app(new glsBuiltinPrecisionTests.LessThan('float'), v1, zero); var v3 = app(new glsBuiltinPrecisionTests.Cond(this.typename), v2, args.a, v0); return v3; }; /** * @constructor * @param {number} size * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Reflect = function(size) { var name = glsBuiltinPrecisionTests.sizeToName(size); var sig = new glsBuiltinPrecisionTests.Signature(name, name, name); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); this.m_inputSize = size; }; setParentClass(glsBuiltinPrecisionTests.Reflect, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Reflect.prototype.getName = function() { return 'reflect'; }; glsBuiltinPrecisionTests.Reflect.prototype.doExpand = function(ctx, args) { //args.a - (args.b * dot(args.b, args.a) * constant(2.0f)); var two = new glsBuiltinPrecisionTests.Constant(2); var v0 = app(new glsBuiltinPrecisionTests.Dot(this.m_inputSize), args.b, args.a); var v1 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.Mul(), args.b, v0); var v2 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.Mul(), v1, two); var v3 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.Sub(), args.a, v2); return v3; }; /** * @constructor * @param {number} size * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Refract = function(size) { var name = glsBuiltinPrecisionTests.sizeToName(size); var sig = new glsBuiltinPrecisionTests.Signature(name, name, name, 'float'); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); this.m_inputSize = size; this.typename = name; }; setParentClass(glsBuiltinPrecisionTests.Refract, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Refract.prototype.getName = function() { return 'refract'; }; glsBuiltinPrecisionTests.Refract.prototype.doExpand = function(ctx, args) { var i = args.a; var n = args.b; var eta = args.c; var zero = new glsBuiltinPrecisionTests.Constant(0); var one = new glsBuiltinPrecisionTests.Constant(1); // dotNI = dot(n, i) var v0 = app(new glsBuiltinPrecisionTests.Dot(this.m_inputSize), n, i); var dotNI = glsBuiltinPrecisionTests.bindExpression('float', 'dotNI', ctx, v0); // k = 1 - eta * eta * (1 - dotNI * dotNI) var v1 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.Mul(), dotNI, dotNI); var v2 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.Sub(), one, v1); var v3 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.Mul(), eta, eta); var v4 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.Mul(), v3, v2); var v5 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.Sub(), one, v4); var k = glsBuiltinPrecisionTests.bindExpression('float', 'k', ctx, v5); // i * eta - n * (eta * dotNI + sqrt(k)) var v6 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.Mul(), eta, dotNI); var v7 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.Sqrt(), k); var v8 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.Add(), v6, v7); var v9 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.Mul(), n, v8); var v10 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.Mul(), i, eta); var v11 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.Sub(), v10, v9); var v12 = new glsBuiltinPrecisionTests.ApplyScalar(new glsBuiltinPrecisionTests.LessThan('float'), k, zero); var zeroVector = app(new glsBuiltinPrecisionTests.GenVec(this.m_inputSize), zero); var v13 = app(new glsBuiltinPrecisionTests.Cond(this.typename), v12, zeroVector, v11); return v13; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Radians = function() { var sig = new glsBuiltinPrecisionTests.Signature('float', 'float'); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.Radians, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Radians.prototype.getName = function() { return 'radians'; }; glsBuiltinPrecisionTests.Radians.prototype.doExpand = function(ctx, args) { var val = app(new glsBuiltinPrecisionTests.Div(), new glsBuiltinPrecisionTests.Constant(Math.PI), new glsBuiltinPrecisionTests.Constant(180)); return new glsBuiltinPrecisionTests.Apply('float', new glsBuiltinPrecisionTests.Mul(), val, args.a); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Degrees = function() { var sig = new glsBuiltinPrecisionTests.Signature('float', 'float'); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.Degrees, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Degrees.prototype.getName = function() { return 'degrees'; }; glsBuiltinPrecisionTests.Degrees.prototype.doExpand = function(ctx, args) { var val = app(new glsBuiltinPrecisionTests.Div(), new glsBuiltinPrecisionTests.Constant(180), new glsBuiltinPrecisionTests.Constant(Math.PI)); return new glsBuiltinPrecisionTests.Apply('float', new glsBuiltinPrecisionTests.Mul(), val, args.a); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Sinh = function() { var sig = new glsBuiltinPrecisionTests.Signature('float', 'float'); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.Sinh, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Sinh.prototype.getName = function() { return 'sinh'; }; glsBuiltinPrecisionTests.Sinh.prototype.doExpand = function(ctx, args) { // (exp(x) - exp(-x)) / constant(2.0f) var x = args.a; var v0 = app(new glsBuiltinPrecisionTests.Exp(), x); var v1 = app(new glsBuiltinPrecisionTests.Negate(), x); var v2 = app(new glsBuiltinPrecisionTests.Exp(), v1); var v3 = app(new glsBuiltinPrecisionTests.Sub(), v0, v2); var v4 = new glsBuiltinPrecisionTests.Constant(2); var v5 = new glsBuiltinPrecisionTests.Apply('float', new glsBuiltinPrecisionTests.Div, v3, v4); return v5; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Cosh = function() { var sig = new glsBuiltinPrecisionTests.Signature('float', 'float'); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.Cosh, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Cosh.prototype.getName = function() { return 'cosh'; }; glsBuiltinPrecisionTests.Cosh.prototype.doExpand = function(ctx, args) { // (exp(x) + exp(-x)) / constant(2.0f) var x = args.a; var v0 = app(new glsBuiltinPrecisionTests.Exp(), x); var v1 = app(new glsBuiltinPrecisionTests.Negate(), x); var v2 = app(new glsBuiltinPrecisionTests.Exp(), v1); var v3 = app(new glsBuiltinPrecisionTests.Add(), v0, v2); var v4 = new glsBuiltinPrecisionTests.Constant(2); var v5 = new glsBuiltinPrecisionTests.Apply('float', new glsBuiltinPrecisionTests.Div, v3, v4); return v5; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Tanh = function() { var sig = new glsBuiltinPrecisionTests.Signature('float', 'float'); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.Tanh, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Tanh.prototype.getName = function() { return 'tanh'; }; glsBuiltinPrecisionTests.Tanh.prototype.doExpand = function(ctx, args) { // sinh(x) / cosh(x) var x = args.a; var v0 = app(new glsBuiltinPrecisionTests.Sinh(), x); var v1 = app(new glsBuiltinPrecisionTests.Cosh(), x); var v2 = new glsBuiltinPrecisionTests.Apply('float', new glsBuiltinPrecisionTests.Div, v0, v1); return v2; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.ASinh = function() { var sig = new glsBuiltinPrecisionTests.Signature('float', 'float'); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.ASinh, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.ASinh.prototype.getName = function() { return 'asinh'; }; glsBuiltinPrecisionTests.ASinh.prototype.doExpand = function(ctx, args) { // log(x + sqrt(x * x + constant(1.0f))) var x = args.a; var v0 = app(new glsBuiltinPrecisionTests.Mul(), x, x); var v1 = new glsBuiltinPrecisionTests.Constant(1); var v2 = app(new glsBuiltinPrecisionTests.Add(), v0, v1); var v3 = app(new glsBuiltinPrecisionTests.Sqrt(), v2); var v4 = app(new glsBuiltinPrecisionTests.Add(), x, v3); var v5 = app(new glsBuiltinPrecisionTests.Log(), v4); return v5; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.ACosh = function() { var sig = new glsBuiltinPrecisionTests.Signature('float', 'float'); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.ACosh, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.ACosh.prototype.getName = function() { return 'acosh'; }; glsBuiltinPrecisionTests.ACosh.prototype.doExpand = function(ctx, args) { // log(x + sqrt((x + constant(1.0f)) * (x - constant(1.0f)))) var x = args.a; var one = new glsBuiltinPrecisionTests.Constant(1); var v0 = app(new glsBuiltinPrecisionTests.Add(), x, one); var v1 = app(new glsBuiltinPrecisionTests.Sub(), x, one); var v2 = app(new glsBuiltinPrecisionTests.Mul(), v0, v1); var v3 = app(new glsBuiltinPrecisionTests.Sqrt(), v2); var v4 = app(new glsBuiltinPrecisionTests.Add(), x, v3); var v5 = app(new glsBuiltinPrecisionTests.Log(), v4); return v5; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.ATanh = function() { var sig = new glsBuiltinPrecisionTests.Signature('float', 'float'); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.ATanh, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.ATanh.prototype.getName = function() { return 'atanh'; }; glsBuiltinPrecisionTests.ATanh.prototype.doExpand = function(ctx, args) { // constant(0.5f) * log((constant(1.0f) + x) / (constant(1.0f) - x)) var x = args.a; var one = new glsBuiltinPrecisionTests.Constant(1); var half = new glsBuiltinPrecisionTests.Constant(0.5); var v0 = app(new glsBuiltinPrecisionTests.Add(), one, x); var v1 = app(new glsBuiltinPrecisionTests.Sub(), one, x); var v2 = app(new glsBuiltinPrecisionTests.Div(), v0, v1); var v3 = app(new glsBuiltinPrecisionTests.Log(), v2); var v4 = app(new glsBuiltinPrecisionTests.Mul(), half, v3); return v4; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Sqrt = function() { var sig = new glsBuiltinPrecisionTests.Signature('float', 'float'); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.Sqrt, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Sqrt.prototype.getName = function() { return 'sqrt'; }; glsBuiltinPrecisionTests.Sqrt.prototype.doExpand = function(ctx, args) { // constant(1.0f) / app(x) var x = args.a; var one = new glsBuiltinPrecisionTests.Constant(1); var v0 = app(new glsBuiltinPrecisionTests.InverseSqrt(), x); var v1 = app(new glsBuiltinPrecisionTests.Div(), one, v0); return v1; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Fract = function() { var sig = new glsBuiltinPrecisionTests.Signature('float', 'float'); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.Fract, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Fract.prototype.getName = function() { return 'fract'; }; glsBuiltinPrecisionTests.Fract.prototype.doExpand = function(ctx, args) { // x - floor(x) var x = args.a; var v0 = app(new glsBuiltinPrecisionTests.Floor(), x); var v1 = app(new glsBuiltinPrecisionTests.Sub(), x, v0); return v1; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Mod = function() { var sig = new glsBuiltinPrecisionTests.Signature('float', 'float', 'float'); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.Mod, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Mod.prototype.getName = function() { return 'mod'; }; glsBuiltinPrecisionTests.Mod.prototype.doExpand = function(ctx, args) { // x - y * floor(x/y) var x = args.a; var y = args.b; var v0 = app(new glsBuiltinPrecisionTests.Div(), x, y); var v1 = app(new glsBuiltinPrecisionTests.Floor(), v0); var v2 = app(new glsBuiltinPrecisionTests.Mul(), y, v1); var v3 = app(new glsBuiltinPrecisionTests.Sub(), x, v2); return v3; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.PrimitiveFunc} */ glsBuiltinPrecisionTests.Modf = function() { var sig = new glsBuiltinPrecisionTests.Signature('float', 'float', 'float'); glsBuiltinPrecisionTests.PrimitiveFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.Modf, glsBuiltinPrecisionTests.PrimitiveFunc); glsBuiltinPrecisionTests.Modf.prototype.getName = function() { return 'modf'; }; glsBuiltinPrecisionTests.Modf.prototype.doApply = function(ctx, iargs, variablenames) { var intPart; var func1 = function(x) { intPart = Math.trunc(x); return x - intPart; }; var func2 = function(x) { return Math.trunc(x); }; var fracIV = tcuInterval.applyMonotone1p(func1, iargs.a); var wholeIV = tcuInterval.applyMonotone1p(func2, iargs.a); if (!iargs.a.isFinite()) { // Behavior on modf(Inf) not well-defined, allow anything as a fractional part // See Khronos bug 13907 fracIV.operatorOrAssignBinary(tcuInterval.NAN); } ctx.env.m_map[variablenames[1]] = wholeIV; return fracIV; }; glsBuiltinPrecisionTests.Modf.prototype.getOutParamIndex = function() { return 1; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Mix = function() { var sig = new glsBuiltinPrecisionTests.Signature('float', 'float', 'float', 'float'); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.Mix, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Mix.prototype.getName = function() { return 'mix'; }; glsBuiltinPrecisionTests.Mix.prototype.operation1 = function(ctx, args) { // (x * (constant(1.0f) - a)) + y * a var x = args.a; var y = args.b; var a = args.c; var one = new glsBuiltinPrecisionTests.Constant(1); var v0 = app(new glsBuiltinPrecisionTests.Sub(), one, a); var v1 = app(new glsBuiltinPrecisionTests.Mul(), x, v0); var v2 = app(new glsBuiltinPrecisionTests.Mul(), y, a); var v3 = app(new glsBuiltinPrecisionTests.Add(), v1, v2); return v3; }; glsBuiltinPrecisionTests.Mix.prototype.operation2 = function(ctx, args) { // x + (y - x) * a var x = args.a; var y = args.b; var a = args.c; var v0 = app(new glsBuiltinPrecisionTests.Sub(), y, x); var v1 = app(new glsBuiltinPrecisionTests.Mul(), a, v0); var v2 = app(new glsBuiltinPrecisionTests.Add(), x, v1); return v2; }; glsBuiltinPrecisionTests.Mix.prototype.doExpand = function(ctx, args){ return app(new glsBuiltinPrecisionTests.Alternatives(this.Sig), this.operation1(ctx, args), this.operation2(ctx, args), new glsBuiltinPrecisionTests.Void(), new glsBuiltinPrecisionTests.Void()); } /** * @constructor * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.SmoothStep = function() { var sig = new glsBuiltinPrecisionTests.Signature('float', 'float', 'float', 'float'); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.SmoothStep, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.SmoothStep.prototype.getName = function() { return 'smoothstep'; }; glsBuiltinPrecisionTests.SmoothStep.prototype.doExpand = function(ctx, args) { var edge0 = args.a; var edge1 = args.b; var x = args.c; var zero = new glsBuiltinPrecisionTests.Constant(0); var one = new glsBuiltinPrecisionTests.Constant(1); //clamp((x - edge0) / (edge1 - edge0), constant(0.0f), constant(1.0f)); var v0 = app(new glsBuiltinPrecisionTests.Sub(), x, edge0); var v1 = app(new glsBuiltinPrecisionTests.Sub(), edge1, edge0); var v2 = app(new glsBuiltinPrecisionTests.Div(), v0, v1); var v3 = app(new glsBuiltinPrecisionTests.Clamp(), v2, zero, one); var t = glsBuiltinPrecisionTests.bindExpression('float', 't', ctx, v3); //(t * t * (constant(3.0f) - constant(2.0f) * t)) var two = new glsBuiltinPrecisionTests.Constant(2); var three = new glsBuiltinPrecisionTests.Constant(3); var v4 = app(new glsBuiltinPrecisionTests.Mul(), v3, v3); var v5 = app(new glsBuiltinPrecisionTests.Mul(), two, v3); var v6 = app(new glsBuiltinPrecisionTests.Sub(), three, v5); var v7 = app(new glsBuiltinPrecisionTests.Mul(), v4, v6); return v7; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Pow = function() { var sig = new glsBuiltinPrecisionTests.Signature('float', 'float', 'float'); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.Pow, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Pow.prototype.getName = function() { return 'pow'; }; glsBuiltinPrecisionTests.Pow.prototype.doExpand = function(ctx, args) { // exp2(y * log2(x)) var x = args.a; var y = args.b; var v0 = app(new glsBuiltinPrecisionTests.Log2(), x); var v1 = app(new glsBuiltinPrecisionTests.Mul(), y, v0); var v2 = app(new glsBuiltinPrecisionTests.Exp2(), v1); return v2; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.CFloatFunc1} */ glsBuiltinPrecisionTests.ExpFunc = function(name, func) { glsBuiltinPrecisionTests.CFloatFunc1.call(this, name, func); }; setParentClass(glsBuiltinPrecisionTests.ExpFunc, glsBuiltinPrecisionTests.CFloatFunc1); glsBuiltinPrecisionTests.ExpFunc.prototype.getCodomain = function() { return tcuInterval.withNumbers(0, Infinity); }; glsBuiltinPrecisionTests.ExpFunc.prototype.precision = function(ctx, ret, x) { switch (ctx.floatPrecision) { case gluShaderUtil.precision.PRECISION_HIGHP: return ctx.format.ulp(ret, 3.0 + 2.0 * Math.abs(x)); case gluShaderUtil.precision.PRECISION_MEDIUMP: return ctx.format.ulp(ret, 2.0 + 2.0 * Math.abs(x)); case gluShaderUtil.precision.PRECISION_LOWP: return ctx.format.ulp(ret, 2.0); default: throw new Error(!'Impossible'); } }; /** * @constructor * @extends {glsBuiltinPrecisionTests.ExpFunc} */ glsBuiltinPrecisionTests.Exp = function() { glsBuiltinPrecisionTests.ExpFunc.call(this, 'exp', Math.exp); }; setParentClass(glsBuiltinPrecisionTests.Exp, glsBuiltinPrecisionTests.ExpFunc); /** * @constructor * @extends {glsBuiltinPrecisionTests.ExpFunc} */ glsBuiltinPrecisionTests.Exp2 = function() { /** * @param {number} x * @return {number} */ var exp2 = function(x) { return Math.exp(x * Math.LN2); }; glsBuiltinPrecisionTests.ExpFunc.call(this, 'exp2', exp2); }; setParentClass(glsBuiltinPrecisionTests.Exp2, glsBuiltinPrecisionTests.ExpFunc); /** * @constructor * @extends {glsBuiltinPrecisionTests.CFloatFunc1} */ glsBuiltinPrecisionTests.LogFunc = function(name, func) { glsBuiltinPrecisionTests.CFloatFunc1.call(this, name, func); }; setParentClass(glsBuiltinPrecisionTests.LogFunc, glsBuiltinPrecisionTests.CFloatFunc1); glsBuiltinPrecisionTests.LogFunc.prototype.precision = function(ctx, ret, x) { if (x <= 0) return NaN; switch (ctx.floatPrecision) { case gluShaderUtil.precision.PRECISION_HIGHP: return (0.5 <= x && x <= 2.0) ? deMath.deLdExp(1.0, -21) : ctx.format.ulp(ret, 3.0); case gluShaderUtil.precision.PRECISION_MEDIUMP: return (0.5 <= x && x <= 2.0) ? deMath.deLdExp(1.0, -7) : ctx.format.ulp(ret, 2.0); case gluShaderUtil.precision.PRECISION_LOWP: return ctx.format.ulp(ret, 2.0); default: throw new Error(!'Impossible'); } }; /** * @constructor * @extends {glsBuiltinPrecisionTests.LogFunc} */ glsBuiltinPrecisionTests.Log = function() { glsBuiltinPrecisionTests.LogFunc.call(this, 'log', Math.log); }; setParentClass(glsBuiltinPrecisionTests.Log, glsBuiltinPrecisionTests.LogFunc); /** * @constructor * @extends {glsBuiltinPrecisionTests.LogFunc} */ glsBuiltinPrecisionTests.Log2 = function() { glsBuiltinPrecisionTests.LogFunc.call(this, 'log2', Math.log2); }; setParentClass(glsBuiltinPrecisionTests.Log2, glsBuiltinPrecisionTests.LogFunc); /** * @constructor * @extends {glsBuiltinPrecisionTests.CFloatFunc1} */ glsBuiltinPrecisionTests.PreciseFunc1 = function(name, func) { glsBuiltinPrecisionTests.CFloatFunc1.call(this, name, func); }; setParentClass(glsBuiltinPrecisionTests.PreciseFunc1, glsBuiltinPrecisionTests.CFloatFunc1); glsBuiltinPrecisionTests.PreciseFunc1.prototype.precision = function(ctx, ret, x) { return 0; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.PreciseFunc1} */ glsBuiltinPrecisionTests.Abs = function() { glsBuiltinPrecisionTests.PreciseFunc1.call(this, 'abs', Math.abs); }; setParentClass(glsBuiltinPrecisionTests.Abs, glsBuiltinPrecisionTests.PreciseFunc1); /** * @constructor * @extends {glsBuiltinPrecisionTests.PreciseFunc1} */ glsBuiltinPrecisionTests.Sign = function() { glsBuiltinPrecisionTests.PreciseFunc1.call(this, 'sign', Math.sign); }; setParentClass(glsBuiltinPrecisionTests.Sign, glsBuiltinPrecisionTests.PreciseFunc1); /** * @constructor * @extends {glsBuiltinPrecisionTests.PreciseFunc1} */ glsBuiltinPrecisionTests.Floor = function() { glsBuiltinPrecisionTests.PreciseFunc1.call(this, 'floor', Math.floor); }; setParentClass(glsBuiltinPrecisionTests.Floor, glsBuiltinPrecisionTests.PreciseFunc1); /** * @constructor * @extends {glsBuiltinPrecisionTests.PreciseFunc1} */ glsBuiltinPrecisionTests.RoundEven = function() { glsBuiltinPrecisionTests.PreciseFunc1.call(this, 'roundEven', deMath.rint); }; setParentClass(glsBuiltinPrecisionTests.RoundEven, glsBuiltinPrecisionTests.PreciseFunc1); /** * @constructor * @extends {glsBuiltinPrecisionTests.PreciseFunc1} */ glsBuiltinPrecisionTests.Ceil = function() { glsBuiltinPrecisionTests.PreciseFunc1.call(this, 'ceil', Math.ceil); }; setParentClass(glsBuiltinPrecisionTests.Ceil, glsBuiltinPrecisionTests.PreciseFunc1); /** * @constructor * @extends {glsBuiltinPrecisionTests.PreciseFunc1} */ glsBuiltinPrecisionTests.Trunc = function() { glsBuiltinPrecisionTests.PreciseFunc1.call(this, 'trunc', Math.trunc); }; setParentClass(glsBuiltinPrecisionTests.Trunc, glsBuiltinPrecisionTests.PreciseFunc1); /** * @constructor * @extends {glsBuiltinPrecisionTests.CFloatFunc2} */ glsBuiltinPrecisionTests.PreciseFunc2 = function(name, func) { glsBuiltinPrecisionTests.CFloatFunc2.call(this, name, func); }; setParentClass(glsBuiltinPrecisionTests.PreciseFunc2, glsBuiltinPrecisionTests.CFloatFunc2); glsBuiltinPrecisionTests.PreciseFunc2.prototype.precision = function(ctx, ret, x, y) { return 0; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.PreciseFunc2} */ glsBuiltinPrecisionTests.Min = function() { glsBuiltinPrecisionTests.PreciseFunc2.call(this, 'min', Math.min); }; setParentClass(glsBuiltinPrecisionTests.Min, glsBuiltinPrecisionTests.PreciseFunc2); /** * @constructor * @extends {glsBuiltinPrecisionTests.PreciseFunc2} */ glsBuiltinPrecisionTests.Max = function() { glsBuiltinPrecisionTests.PreciseFunc2.call(this, 'max', Math.max); }; setParentClass(glsBuiltinPrecisionTests.Max, glsBuiltinPrecisionTests.PreciseFunc2); /** * @constructor * @extends {glsBuiltinPrecisionTests.PreciseFunc2} */ glsBuiltinPrecisionTests.Step = function() { /** * @param {number} edge * @param {number} x * return number */ var step = function(edge, x) { return x < edge ? 0.0 : 1.0; }; glsBuiltinPrecisionTests.PreciseFunc2.call(this, 'step', step); }; setParentClass(glsBuiltinPrecisionTests.Step, glsBuiltinPrecisionTests.PreciseFunc2); /** * @constructor * @extends {glsBuiltinPrecisionTests.CFloatFunc1} */ glsBuiltinPrecisionTests.TrigFunc = function(name, func, loEx, hiEx) { glsBuiltinPrecisionTests.CFloatFunc1.call(this, name, func); this.m_loExtremum = loEx; this.m_hiExtremum = hiEx; }; setParentClass(glsBuiltinPrecisionTests.TrigFunc, glsBuiltinPrecisionTests.CFloatFunc1); glsBuiltinPrecisionTests.TrigFunc.prototype.innerExtrema = function(ctx, angle) { var lo = angle.lo(); var hi = angle.hi(); var loSlope = this.doGetSlope(lo); var hiSlope = this.doGetSlope(hi); // Detect the high and low values the function can take between the // interval endpoints. if (angle.length() >= 2.0 * Math.PI) { // The interval is longer than a full cycle, so it must get all possible values. return this.m_hiExtremum.operatorOrBinary(this.m_loExtremum); } else if (loSlope == 1 && hiSlope == -1) { // The slope can change from positive to negative only at the maximum value. return this.m_hiExtremum; } else if (loSlope == -1 && hiSlope == 1) { // The slope can change from negative to positive only at the maximum value. return this.m_loExtremum; } else if (loSlope == hiSlope && deMath.deSign(this.applyExact(hi) - this.applyExact(lo)) * loSlope == -1) { // The slope has changed twice between the endpoints, so both extrema are included. return this.m_hiExtremum.operatorOrBinary(this.m_loExtremum); } return new tcuInterval.Interval(); }; glsBuiltinPrecisionTests.TrigFunc.prototype.getCodomain = function() { // Ensure that result is always within [-1, 1], or NaN (for +-inf) var v = tcuInterval.withIntervals(new tcuInterval.Interval(-1), new tcuInterval.Interval(1)); return v.operatorOrBinary(tcuInterval.NAN); }; glsBuiltinPrecisionTests.TrigFunc.prototype.precision = function(ctx, ret, arg) { if (ctx.floatPrecision == gluShaderUtil.precision.PRECISION_HIGHP) { // Use precision from OpenCL fast relaxed math if (-Math.PI <= arg && arg <= Math.PI) { return deMath.deLdExp(1.0, -11); } else { // "larger otherwise", let's pick |x| * 2^-12 , which is slightly over // 2^-11 at x == pi. return deMath.deLdExp(Math.abs(arg), -12); } } else if (ctx.floatPrecision == gluShaderUtil.precision.PRECISION_MEDIUMP) { if (-Math.PI <= arg && arg <= Math.PI) { // from OpenCL half-float extension specification return ctx.format.ulp(ret, 2.0); } else { // |x| * 2^-10 , slightly larger than 2 ULP at x == pi return deMath.deLdExp(Math.abs(arg), -10); } } else { // from OpenCL half-float extension specification return ctx.format.ulp(ret, 2.0); } }; /** * @param {number} angle * @return number */ glsBuiltinPrecisionTests.TrigFunc.prototype.doGetSlope = function(angle) { throw new Error('Virtual function. Please override.'); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.TrigFunc} */ glsBuiltinPrecisionTests.Sin = function() { glsBuiltinPrecisionTests.TrigFunc.call(this, 'sin', Math.sin, new tcuInterval.Interval(-1), new tcuInterval.Interval(1)); }; setParentClass(glsBuiltinPrecisionTests.Sin, glsBuiltinPrecisionTests.TrigFunc); glsBuiltinPrecisionTests.Sin.prototype.doGetSlope = function(angle) { return deMath.deSign(Math.cos(angle)); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.TrigFunc} */ glsBuiltinPrecisionTests.Cos = function() { glsBuiltinPrecisionTests.TrigFunc.call(this, 'cos', Math.cos, new tcuInterval.Interval(-1), new tcuInterval.Interval(1)); }; setParentClass(glsBuiltinPrecisionTests.Cos, glsBuiltinPrecisionTests.TrigFunc); glsBuiltinPrecisionTests.Cos.prototype.doGetSlope = function(angle) { return -deMath.deSign(Math.sin(angle)); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Tan = function() { var sig = new glsBuiltinPrecisionTests.Signature('float', 'float'); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.Tan, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Tan.prototype.getName = function() { return 'tan'; }; glsBuiltinPrecisionTests.Tan.prototype.doExpand = function(ctx, args) { // sin(x) * (constant(1.0f) / cos(x) var x = args.a; var sin = app(new glsBuiltinPrecisionTests.Sin(), x); var cos = app(new glsBuiltinPrecisionTests.Cos(), x); var expr = app(new glsBuiltinPrecisionTests.Div(), new glsBuiltinPrecisionTests.Constant(1), cos); expr = new glsBuiltinPrecisionTests.Apply('float', new glsBuiltinPrecisionTests.Mul(), sin, expr); return expr; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.CFloatFunc1} */ glsBuiltinPrecisionTests.ASin = function() { glsBuiltinPrecisionTests.CFloatFunc1.call(this, 'asin', Math.asin); }; setParentClass(glsBuiltinPrecisionTests.ASin, glsBuiltinPrecisionTests.CFloatFunc1); glsBuiltinPrecisionTests.ASin.prototype.precision = function(ctx, ret, x) { if (!deMath.deInBounds32(x, -1.0, 1.0)) return NaN; if (ctx.floatPrecision == gluShaderUtil.precision.PRECISION_HIGHP) { // Absolute error of 2^-11 return deMath.deLdExp(1.0, -11); } else { // Absolute error of 2^-8 return deMath.deLdExp(1.0, -8); } }; /** * @constructor * @extends {glsBuiltinPrecisionTests.CFloatFunc1} */ glsBuiltinPrecisionTests.ArcTrigFunc = function(name, func, precisionULPs, domain, coddomain) { glsBuiltinPrecisionTests.CFloatFunc1.call(this, name, func); this.m_precision = precisionULPs; this.m_domain = domain; this.m_codomain = coddomain; }; setParentClass(glsBuiltinPrecisionTests.ArcTrigFunc, glsBuiltinPrecisionTests.CFloatFunc1); glsBuiltinPrecisionTests.ArcTrigFunc.prototype.precision = function(ctx, ret, x) { if (!this.m_domain.contains(new tcuInterval.Interval(x))) return NaN; if (ctx.floatPrecision == gluShaderUtil.precision.PRECISION_HIGHP) { // Use OpenCL's precision return ctx.format.ulp(ret, this.m_precision); } else { // Use OpenCL half-float spec return ctx.format.ulp(ret, 2.0); } }; /** * @constructor * @extends {glsBuiltinPrecisionTests.ArcTrigFunc} */ glsBuiltinPrecisionTests.ACos = function() { glsBuiltinPrecisionTests.ArcTrigFunc.call(this, 'acos', Math.acos, 4096.0, tcuInterval.withNumbers(-1, 1), tcuInterval.withNumbers(0, Math.PI)); }; setParentClass(glsBuiltinPrecisionTests.ACos, glsBuiltinPrecisionTests.ArcTrigFunc); /** * @constructor * @extends {glsBuiltinPrecisionTests.ArcTrigFunc} */ glsBuiltinPrecisionTests.ATan = function() { glsBuiltinPrecisionTests.ArcTrigFunc.call(this, 'atan', Math.atan, 4096.0, tcuInterval.unbounded(), tcuInterval.withNumbers(-Math.PI * 0.5, Math.PI * 0.5)); }; setParentClass(glsBuiltinPrecisionTests.ATan, glsBuiltinPrecisionTests.ArcTrigFunc); /** * @constructor * @extends {glsBuiltinPrecisionTests.CFloatFunc2} */ glsBuiltinPrecisionTests.ATan2 = function() { glsBuiltinPrecisionTests.CFloatFunc2.call(this, 'atan', Math.atan2); }; setParentClass(glsBuiltinPrecisionTests.ATan2, glsBuiltinPrecisionTests.CFloatFunc2); glsBuiltinPrecisionTests.ATan2.prototype.innerExtrema = function(ctx, xi, yi) { var ret = new tcuInterval.Interval(); if (yi.contains(tcuInterval.ZERO)) { if (xi.contains(tcuInterval.ZERO)) ret.operatorOrAssignBinary(tcuInterval.NAN); if (xi.intersects(tcuInterval.withNumbers(-Infinity, 0))) ret.operatorOrAssignBinary(tcuInterval.withNumbers(-Math.PI, Math.PI)); } if (ctx.format.hasInf() != tcuFloatFormat.YesNoMaybe.YES && (!yi.isFinite() || !xi.isFinite())) { // Infinities may not be supported, allow anything, including NaN ret.operatorOrAssignBinary(tcuInterval.NAN); } return ret; }; glsBuiltinPrecisionTests.ATan2.prototype.precision = function(ctx, ret, x, y) { if (ctx.floatPrecision == gluShaderUtil.precision.PRECISION_HIGHP) return ctx.format.ulp(ret, 4096.0); else return ctx.format.ulp(ret, 2.0); }; /** * @constructor * @param {number} size * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.DeterminantBase = function(size) { var sig = new glsBuiltinPrecisionTests.Signature('float', 'mat' + size); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.DeterminantBase, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.DeterminantBase.prototype.getName = function() { return 'determinant'; }; /** * @constructor * @extends {glsBuiltinPrecisionTests.DeterminantBase} */ glsBuiltinPrecisionTests.Determinant = function() { // TODO: Support sizes 3 and 4 this.size = 2; glsBuiltinPrecisionTests.DeterminantBase.call(this, this.size); }; setParentClass(glsBuiltinPrecisionTests.Determinant, glsBuiltinPrecisionTests.DeterminantBase); glsBuiltinPrecisionTests.Determinant.prototype.doExpand = function(ctx, args) { // mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1] var elem0_0 = new glsBuiltinPrecisionTests.MatrixVariable(args.a, 0, 0); var elem0_1 = new glsBuiltinPrecisionTests.MatrixVariable(args.a, 0, 1); var elem1_0 = new glsBuiltinPrecisionTests.MatrixVariable(args.a, 1, 0); var elem1_1 = new glsBuiltinPrecisionTests.MatrixVariable(args.a, 1, 1); var val0 = app(new glsBuiltinPrecisionTests.Mul(), elem0_0, elem1_1); var val1 = app(new glsBuiltinPrecisionTests.Mul(), elem0_1, elem1_0); return new glsBuiltinPrecisionTests.Apply('float', new glsBuiltinPrecisionTests.Sub(), val0, val1); }; /** * @constructor * @extends {glsBuiltinPrecisionTests.DerivedFunc} */ glsBuiltinPrecisionTests.Inverse = function() { this.size = 2; var name = 'mat' + this.size; var sig = new glsBuiltinPrecisionTests.Signature(name, name); glsBuiltinPrecisionTests.DerivedFunc.call(this, sig); }; setParentClass(glsBuiltinPrecisionTests.Inverse, glsBuiltinPrecisionTests.DerivedFunc); glsBuiltinPrecisionTests.Inverse.prototype.getName = function() { return 'inverse'; }; glsBuiltinPrecisionTests.Inverse.prototype.doExpand = function(ctx, args) { var mat = args.a; var v0 = app(new glsBuiltinPrecisionTests.Determinant(), mat); var det = glsBuiltinPrecisionTests.bindExpression('float', 'det', ctx, v0); var elem0_0 = new glsBuiltinPrecisionTests.MatrixVariable(args.a, 0, 0); var elem0_1 = new glsBuiltinPrecisionTests.MatrixVariable(args.a, 0, 1); var elem1_0 = new glsBuiltinPrecisionTests.MatrixVariable(args.a, 1, 0); var elem1_1 = new glsBuiltinPrecisionTests.MatrixVariable(args.a, 1, 1); var result0_0 = app(new glsBuiltinPrecisionTests.Div(), elem1_1, det); var result0_1 = app(new glsBuiltinPrecisionTests.Div(), elem0_1, det); result0_1 = app(new glsBuiltinPrecisionTests.Negate(), result0_1); var result1_0 = app(new glsBuiltinPrecisionTests.Div(), elem1_0, det); result1_0 = app(new glsBuiltinPrecisionTests.Negate(), result1_0); var result1_1 = app(new glsBuiltinPrecisionTests.Div(), elem0_0, det); var col0 = app(new glsBuiltinPrecisionTests.GenVec(this.size, true), result0_0, result1_0); var col1 = app(new glsBuiltinPrecisionTests.GenVec(this.size, true), result0_1, result1_1); var ret = app(new glsBuiltinPrecisionTests.GenMat(this.size, this.size), col0, col1); return ret; }; /** * @param {glsBuiltinPrecisionTests.PrecisionTestContext} ctx * @param {glsBuiltinPrecisionTests.CaseFactory} factory * @return {tcuTestCase.DeqpTest} */ glsBuiltinPrecisionTests.createFuncGroup = function(ctx, factory) { /** @type {tcuTestCase.DeqpTest} */ var group = tcuTestCase.newTest(factory.getName(), factory.getDesc()); for (var precNdx in gluShaderUtil.precision) { /** @type {gluShaderUtil.precision} */ var precision = gluShaderUtil.precision[precNdx]; /** @type {string} */ var precName = gluShaderUtil.getPrecisionName(precision); /** @type {tcuFloatFormat.FloatFormat} */ var fmt = ctx.formats[precision]; /** @type {tcuFloatFormat.FloatFormat} */ var highpFmt = ctx.formats[gluShaderUtil.precision.PRECISION_HIGHP]; for (var shaderNdx in ctx.shaderTypes) { /** @type {gluShaderProgram.shaderType} */ var shaderType = ctx.shaderTypes[shaderNdx]; /** @type {string} */ var shaderName = gluShaderProgram.getShaderTypeName(shaderType); /** @type {string} */ var name = precName + '_' + shaderName; /** @type {glsBuiltinPrecisionTests.Context} */ var caseCtx = new glsBuiltinPrecisionTests.Context(name, fmt, highpFmt, precision, shaderType, ctx.numRandoms); group.addChild(factory.createCase(caseCtx)); } } return group; }; /** * @param {glsBuiltinPrecisionTests.CaseFactories} cases * @param {Array} shaderTypes * @param {tcuTestCase.DeqpTest} dstGroup */ glsBuiltinPrecisionTests.addBuiltinPrecisionTests = function(cases, shaderTypes, dstGroup) { /** @type {tcuFloatFormat.FloatFormat} */ var highp = new tcuFloatFormat.FloatFormat(-126, 127, 23, true, tcuFloatFormat.YesNoMaybe.MAYBE, // subnormals tcuFloatFormat.YesNoMaybe.YES, // infinities tcuFloatFormat.YesNoMaybe.MAYBE); // NaN // \todo [2014-04-01 lauri] Check these once Khronos bug 11840 is resolved. /** @type {tcuFloatFormat.FloatFormat} */ var mediump = new tcuFloatFormat.FloatFormat(-13, 13, 9, false); // A fixed-point format is just a floating point format with a fixed // exponent and support for subnormals. /** @type {tcuFloatFormat.FloatFormat} */ var lowp = new tcuFloatFormat.FloatFormat(0, 0, 7, false, tcuFloatFormat.YesNoMaybe.YES); /** @type {glsBuiltinPrecisionTests.PrecisionTestContext} */ var ctx = new glsBuiltinPrecisionTests.PrecisionTestContext(highp, mediump, lowp, shaderTypes, 16384); for (var ndx = 0; ndx < cases.getFactories().length; ++ndx) dstGroup.addChild(glsBuiltinPrecisionTests.createFuncGroup(ctx, cases.getFactories()[ndx])); }; /** * @param {function(new:glsBuiltinPrecisionTests.Func)} F * @param {glsBuiltinPrecisionTests.CaseFactories} funcs * @param {string=} name */ glsBuiltinPrecisionTests.addScalarFactory = function(F, funcs, name) { if (name === undefined) name = (new F()).getName(); funcs.addFactory(new glsBuiltinPrecisionTests.GenFuncCaseFactory(glsBuiltinPrecisionTests.makeVectorizedFuncs(F), name)); }; /** * @param {function(new:glsBuiltinPrecisionTests.Func)} F */ glsBuiltinPrecisionTests.createSimpleFuncCaseFactory = function(F) { return new glsBuiltinPrecisionTests.SimpleFuncCaseFactory(new F()); }; /** * @param {number} caseId test case Id * @return {glsBuiltinPrecisionTests.CaseFactories} */ glsBuiltinPrecisionTests.createES3BuiltinCases = function(caseId) { /** @type {glsBuiltinPrecisionTests.CaseFactories} */ var funcs = new glsBuiltinPrecisionTests.BuiltinFuncs(); switch (caseId) { case 0: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Add, funcs); break; case 1: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Sub, funcs); break; case 2: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Mul, funcs); break; case 3: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Div, funcs); break; case 4: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Radians, funcs); break; case 5: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Degrees, funcs); break; case 6: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Sin, funcs); break; case 7: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Cos, funcs); break; case 8: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Tan, funcs); break; case 9: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.ASin, funcs); break; case 10: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.ACos, funcs); break; case 11: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.ATan, funcs); break; case 12: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.ATan2, funcs, 'atan2'); break; case 13: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Sinh, funcs); break; case 14: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Cosh, funcs); break; case 15: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Tanh, funcs); break; case 16: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.ASinh, funcs); break; case 17: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.ACosh, funcs); break; case 18: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.ATanh, funcs); break; case 19: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Pow, funcs); break; case 20: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Exp, funcs); break; case 21: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Exp2, funcs); break; case 22: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Log, funcs); break; case 23: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Log2, funcs); break; case 24: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Sqrt, funcs); break; case 25: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.InverseSqrt, funcs); break; case 26: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Abs, funcs); break; case 27: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Sign, funcs); break; case 28: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Floor, funcs); break; case 29: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Trunc, funcs); break; case 30: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Round, funcs); break; case 31: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.RoundEven, funcs); break; case 32: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Ceil, funcs); break; case 33: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Fract, funcs); break; case 34: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Mod, funcs); break; case 35: funcs.addFactory(glsBuiltinPrecisionTests.createSimpleFuncCaseFactory(glsBuiltinPrecisionTests.Modf)); break; case 36: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Min, funcs); break; case 37: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Max, funcs); break; case 38: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Mix, funcs); break; case 39: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Step, funcs); break; case 40: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.SmoothStep, funcs); break; case 41: glsBuiltinPrecisionTests.addScalarFactory(glsBuiltinPrecisionTests.Clamp, funcs); break; case 42: funcs.addFactory(new glsBuiltinPrecisionTests.TemplateFuncCaseFactory(glsBuiltinPrecisionTests.Length)); break; case 43: funcs.addFactory(new glsBuiltinPrecisionTests.TemplateFuncCaseFactory(glsBuiltinPrecisionTests.Distance)); break; case 44: funcs.addFactory(new glsBuiltinPrecisionTests.TemplateFuncCaseFactory(glsBuiltinPrecisionTests.Dot)); break; case 45: funcs.addFactory(glsBuiltinPrecisionTests.createSimpleFuncCaseFactory(glsBuiltinPrecisionTests.Cross)); break; case 46: funcs.addFactory(new glsBuiltinPrecisionTests.TemplateFuncCaseFactory(glsBuiltinPrecisionTests.Normalize)); break; case 47: funcs.addFactory(new glsBuiltinPrecisionTests.TemplateFuncCaseFactory(glsBuiltinPrecisionTests.FaceForward)); break; case 48: funcs.addFactory(new glsBuiltinPrecisionTests.TemplateFuncCaseFactory(glsBuiltinPrecisionTests.Reflect)); break; case 49: funcs.addFactory(new glsBuiltinPrecisionTests.TemplateFuncCaseFactory(glsBuiltinPrecisionTests.Refract)); break; case 50: funcs.addFactory(new glsBuiltinPrecisionTests.MatrixFuncCaseFactory(glsBuiltinPrecisionTests.MatrixCompMult)); break; case 51: funcs.addFactory(new glsBuiltinPrecisionTests.MatrixFuncCaseFactory(glsBuiltinPrecisionTests.OuterProduct)); break; case 52: funcs.addFactory(new glsBuiltinPrecisionTests.MatrixFuncCaseFactory(glsBuiltinPrecisionTests.Transpose)); break; case 53: funcs.addFactory(new glsBuiltinPrecisionTests.SquareMatrixFuncCaseFactory(glsBuiltinPrecisionTests.Determinant)); break; case 54: funcs.addFactory(new glsBuiltinPrecisionTests.SquareMatrixFuncCaseFactory(glsBuiltinPrecisionTests.Inverse)); break; default: break; } return funcs; }; });