blob: 4dc3be70f33ce57c59755bd0e828b7250f2b2bb8 [file] [log] [blame]
/*-------------------------------------------------------------------------
* 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<tcuInterval.Interval>|tcuMatrix.Matrix)} */
glsBuiltinPrecisionTests.Intervals;
/** @typedef {(number|Array<number>|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.FuncBase>} */
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<string>}
*/
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 || '<undefined>';
};
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<glsBuiltinPrecisionTests.ExprBase>} 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<const FuncBase*> 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 <typename Sig_>
*/
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<glsBuiltinPrecisionTests.ExprBase>} 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<glsBuiltinPrecisionTests.ExprBase>} 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 <typename Sig>
*
*/
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<Signature<float, float, float> >
* @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<glsBuiltinPrecisionTests.ExprBase>} 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<float, float, float, float>
* @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<glsBuiltinPrecisionTests.ExprBase>} 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<glsBuiltinPrecisionTests.ExprBase>} 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<typename In::In0> in0;
// vector<typename In::In1> in1;
// vector<typename In::In2> in2;
// vector<typename In::In3> 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<number>} 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<Boolean>} 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<float>::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<number>} */ 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<In, Out>
* @param {glsBuiltinPrecisionTests.Inputs} inputs Inputs<In>
* @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<typename>
* @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<In>
* @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<In>*/ var ret = new glsBuiltinPrecisionTests.Inputs(In);
/*Inputs<In>*/ var fixedInputs = new glsBuiltinPrecisionTests.Inputs(In);
// set<InTuple<In>, InputLess<InTuple<In> > > seenInputs;
/** @type {Array<glsBuiltinPrecisionTests.InTuple,glsBuiltinPrecisionTests.InputLess>} */
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<In>
* @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<In, Out> 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<In>
* @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<In, Out> 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.CaseFactory>}
*/
glsBuiltinPrecisionTests.CaseFactories.prototype.getFactories = function() {};
/**
* @constructor
* @extends {glsBuiltinPrecisionTests.CaseFactories}
*/
glsBuiltinPrecisionTests.BuiltinFuncs = function() {
/** @type {Array<glsBuiltinPrecisionTests.CaseFactory>} */ this.m_factories = [];
};
glsBuiltinPrecisionTests.BuiltinFuncs.prototype = Object.create(glsBuiltinPrecisionTests.CaseFactories.prototype);
glsBuiltinPrecisionTests.BuiltinFuncs.prototype.constructor = glsBuiltinPrecisionTests.BuiltinFuncs;
/**
* @return {Array<glsBuiltinPrecisionTests.CaseFactory>}
*/
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<glsBuiltinPrecisionTests.ExprBase>} 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<gluShaderProgram.shaderType>} shaderTypes_
* @param {number} numRandoms_
*/
glsBuiltinPrecisionTests.PrecisionTestContext = function(highp_, mediump_, lowp_, shaderTypes_, numRandoms_) {
/** @type {Array<gluShaderProgram.shaderType>} */ this.shaderTypes = shaderTypes_;
/** @type {Array<tcuFloatFormat.FloatFormat>} */ 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 <typename Sig_>
*/
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 <typename Sig_>
*/
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<Size>(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<InverseSqrt>(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<gluShaderProgram.shaderType>} 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;
};
});