diff options
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/js/glsl-constructor-tests-generator.js')
-rw-r--r-- | dom/canvas/test/webgl-conf/checkout/js/glsl-constructor-tests-generator.js | 919 |
1 files changed, 919 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/js/glsl-constructor-tests-generator.js b/dom/canvas/test/webgl-conf/checkout/js/glsl-constructor-tests-generator.js new file mode 100644 index 0000000000..b5c1602980 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/js/glsl-constructor-tests-generator.js @@ -0,0 +1,919 @@ +/* +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +*/ + + +var GLSLConstructorTestsGenerator = (function() { + +var wtu = WebGLTestUtils; + +// Shader code templates +var constructorVertexTemplate = [ + "attribute vec4 vPosition;", + + "precision mediump int;", + "precision mediump float;", + + // Colors used to signal correctness of component values comparison + "const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);", + "const vec4 red = vec4(1.0, 0.0, 0.0, 1.0);", + + // Error bound used in comparison of floating point values + "$(errorBound)", + + "varying vec4 vColor;", + + "void main() {", + " $(argsList)", + + " $(type) v = $(type)($(argsConstr));", + + " if ($(checkCompVals))", + " vColor = green;", + " else", + " vColor = red;", + + " gl_Position = vPosition;", + "}" +].join("\n"); + + +var passThroughColorFragmentShader = [ + "precision mediump float;", + + "varying vec4 vColor;", + + "void main() {", + " gl_FragColor = vColor;", + "}" +].join('\n'); + + +var constructorFragmentTemplate = [ + "precision mediump int;", + "precision mediump float;", + + // Colors used to signal correctness of component values comparison + "const vec4 green = vec4(0.0, 1.0, 0.0, 1.0); ", + "const vec4 red = vec4(1.0, 0.0, 0.0, 1.0); ", + + // Error bound used in comparison of floating point values + "$(errorBound)", + + "void main() {", + " $(argsList)", + + " $(type) v = $(type)($(argsConstr));", + + " if ($(checkCompVals))", + " gl_FragColor = green;", + " else", + " gl_FragColor = red;", + "}" +].join("\n"); + + +// Coding of the different argument types +// s : scalar +// v2 : vec2 +// v3 : vec3 +// v4 : vec4 +// m2 : mat2 +// m3 : mat3 +// m4 : mat4 + +// Returns the dimensions of the type +// Count of columns, count of rows +function getTypeCodeDimensions(typeCode) { + switch (typeCode) { + case "s": return [1, 1]; + case "v2": return [1, 2]; + case "v3": return [1, 3]; + case "v4": return [1, 4]; + case "m2": return [2, 2]; + case "m3": return [3, 3]; + case "m4": return [4, 4]; + + default: + wtu.error("GLSLConstructorTestsGenerator.getTypeCodeDimensions(), unknown type code"); + debugger; + } +}; + + +// Returns the component count for the type code +function getTypeCodeComponentCount(typeCode) { + var dim = getTypeCodeDimensions(typeCode); + + return dim[0] * dim[1]; +} + + +// Returns glsl name of type code +function getGLSLBaseTypeName(typeCode) { + switch(typeCode) { + case "s": return ""; + case "v2": return "vec2"; + case "v3": return "vec3"; + case "v4": return "vec4"; + case "m2": return "mat2"; + case "m3": return "mat3"; + case "m4": return "mat4"; + + default: + wtu.error("GLSLConstructorTestsGenerator.getGLSLBaseTypeName(), unknown type code"); + debugger; + } +} + + +// Returns the scalar glsl type name related to the structured type +function getGLSLScalarType(targetType) { + switch(targetType[0]) { + case 'i': return "int"; + case 'b': return "bool"; + + case 'v': + case 'm': + return "float"; + + default: + wtu.error("GLSLConstructorTestsGenerator.getGLSLScalarType(), unknown target type"); + debugger; + } +} + + +// Returns the scalar prefix for the associated scalar type +function getGLSLScalarPrefix(targetType) { + switch(targetType[0]) { + case 'i': + case 'b': + return targetType[0]; + + case 'v': + case 'm': + return ''; + + default: + wtu.error("GLSLConstructorTestsGenerator.getGLSLScalarPrefix(), unknown target type"); + debugger; + } +} + + +// Returns the type for a specified target type and argument type code +function getGLSLArgumentType(typeCode, targetType) { + var baseType = getGLSLBaseTypeName(typeCode); + if (baseType !== "") { + if (typeCode[0] === "v") { + // Vectors come in different flavours + return getGLSLScalarPrefix(targetType) + baseType; + } + else + return baseType; + } + else + return getGLSLScalarType(targetType); +} + + +// Returns the glsl type of the argument components +function getGLSLArgumentComponentType(argTypeCode, targetType) { + var scalarType; + + if (argTypeCode[0] === "m") { + // Matrices are always floats + scalarType = "float"; + } + else + scalarType = getGLSLScalarType(targetType); + + return scalarType; +} + + +function getGLSLColumnSize(targetType) { + colSize = parseInt(targetType.slice(-1)); + + if (!isNaN(colSize)) + return colSize; + + wtu.error("GLSLConstructorTestsGenerator.getGLSLColumnSize(), invalid target type"); + debugger; +} + + +// Returns correct string representation of scalar value +function getScalarTypeValStr(val, scalarType) { + if (val == null) + debugger; + + switch (scalarType) { + case "float": return val.toFixed(1); + case "int": return val; + case "bool": return (val === 0) ? "false" : "true"; + + default: + wtu.error("GLSLConstructorTestsGenerator.getScalarTypeValStr(), unknown scalar type"); + debugger; + } +} + + +// Returns true if the glsl type name is a matrix +function isGLSLTypeMatrix(type) { + return (type.indexOf("mat") !== -1); +} + + +// Returns true if the glsl type name is a vector +function isGLSLTypeVector(type) { + return (type.indexOf("vec") !== -1); +} + + +// Returns the count of components +function getGLSLTypeComponentCount(type) { + var colSize = getGLSLColumnSize(type); + + if (isGLSLTypeMatrix(type)) + return colSize * colSize; + else + return colSize; +} + + +// Returns the constructor expression with the components set to a sequence of scalar values +// Like vec3(1.0, 2.0, 3.0) +function getComponentSequenceConstructorExpression(typeCode, firstCompValue, targetType) { + var scalarType = getGLSLArgumentComponentType(typeCode, targetType); + + if (typeCode === "s") { + // Scalar + return getScalarTypeValStr(firstCompValue, scalarType) + ";"; + } + else { + // Structured typeargTypeCode[0] === "m" + compCount = getTypeCodeComponentCount(typeCode); + var constrExpParts = new Array(compCount); + for (var aa = 0; aa < compCount; ++aa) + constrExpParts[aa] = getScalarTypeValStr(firstCompValue + aa, scalarType); + + return getGLSLArgumentType(typeCode, targetType) + "(" + constrExpParts.join(", ") + ");"; + } +} + + +// Returns the expression to select a component of the structured type +function getComponentSelectorExpStr(targetType, compIx) { + if (isGLSLTypeMatrix(targetType)) { + var colRowIx = getColRowIndexFromLinearIndex(compIx, getGLSLColumnSize(targetType)); + return "v[" + colRowIx.colIx + "][" + colRowIx.rowIx + "]"; + } + else + return "v[" + compIx + "]"; +} + + +// Returns expression which validates the components set by the constructor expression +function getComponentValidationExpression(refCompVals, targetType) { + // Early out for invalid arguments + if (refCompVals.length === 0) + return "false"; + + var scalarType = getGLSLScalarType(targetType); + var checkComponentValueParts = new Array(refCompVals.length); + for (var cc = 0; cc < refCompVals.length; ++cc) { + var val_str = getScalarTypeValStr(refCompVals[cc], scalarType); + var comp_sel_exp = getComponentSelectorExpStr(targetType, cc); + if (scalarType === "float") { + // Comparison of floating point values with error bound + checkComponentValueParts[cc] = "abs(" + comp_sel_exp + " - " + val_str + ") <= errorBound"; + } + else { + // Simple comparison to expected value + checkComponentValueParts[cc] = comp_sel_exp + " == " + val_str; + } + } + + return checkComponentValueParts.join(" && "); +} + + +// Returns substitution parts to turn the shader template into testable shader code +function getTestShaderParts(targetType, argExp, firstCompValue) { + // glsl code of declarations of arguments + var argsListParts = new Array(argExp.length); + + // glsl code of constructor expression + var argsConstrParts = new Array(argExp.length); + + // glsl type expression + var typeExpParts = new Array(argExp.length); + for (var aa = 0; aa < argExp.length; ++aa) { + var typeCode = argExp[aa]; + var argCompCount = getTypeCodeComponentCount(typeCode); + var argName = "a" + aa; + var argType = getGLSLArgumentType(typeCode, targetType); + var argConstrExp = argType + " " + argName + " = " + getComponentSequenceConstructorExpression(typeCode, firstCompValue, targetType); + + // Add construction of one argument + // Indent if not first argument + argsListParts[aa] = ((aa > 0) ? " " : "") + argConstrExp; + + // Add argument name to target type argument list + argsConstrParts[aa] = argName; + + // Add type name to type expression + typeExpParts[aa] = argType; + + // Increment argument component value so all argument component arguments have a unique value + firstCompValue += argCompCount; + } + + return { + argsList: argsListParts.join("\n") + "\n", + argsConstr: argsConstrParts.join(", "), + typeExp: targetType + "(" + typeExpParts.join(", ") + ")" + }; +} + + +// Utility functions to manipulate the array of reference values + +// Returns array filled with identical values +function getArrayWithIdenticalValues(size, val) { + var matArray = new Array(size); + for (var aa = 0; aa < size; ++aa) + matArray[aa] = val; + + return matArray; +} + + +// Returns array filled with increasing values from a specified start value +function getArrayWithIncreasingValues(size, start) { + var matArray = new Array(size); + for (var aa = 0; aa < size; ++aa) + matArray[aa] = start + aa; + + return matArray; +} + + +// Utility functions to manipulate the array of reference values if the target type is a matrix + +// Returns an array which is the column order layout of a square matrix where the diagonal is set to a specified value +function matCompArraySetDiagonal(matArray, diagVal) { + // The entries for the diagonal start at array index 0 and increase + // by column size + 1 + var colSize = Math.round(Math.sqrt(matArray.length)); + var dIx = 0; + do { + matArray[dIx] = diagVal; + dIx += (colSize + 1); + } + while (dIx < colSize * colSize); + + return matArray; +} + + +// Returns an array which contains the values of an identity matrix read out in column order +function matCompArrayCreateDiagonalMatrix(colSize, diagVal) { + var size = colSize * colSize; + var matArray = new Array(size); + for (var aa = 0; aa < size; ++aa) + matArray[aa] = 0; + + return matCompArraySetDiagonal(matArray, diagVal); +} + + +// Returns the column and row index from the linear index if the components of the matrix are stored in column order in an array +// in a one dimensional array in column order +function getColRowIndexFromLinearIndex(linIx, colSize) { + return { + colIx: Math.floor(linIx / colSize), + rowIx: linIx % colSize + }; +} + + +// Returns the linear index for matrix column and row index for a specified matrix size +function getLinearIndexFromColRowIndex(rowColIx, colSize) { + return rowColIx.colIx * colSize + rowColIx.rowIx; +} + + +// Returns a matrix set from another matrix +function matCompArraySetMatrixFromMatrix(dstColSize, srcMatArray) { + // Overwrite components from destination with the source component values at the same col, row coordinates + var dstMatArray = matCompArrayCreateDiagonalMatrix(dstColSize, 1); + + var srcColSize = Math.round(Math.sqrt(srcMatArray.length)); + + for (var c_ix = 0; c_ix < srcMatArray.length; ++c_ix) { + var srcMatIx = getColRowIndexFromLinearIndex(c_ix, srcColSize); + if (srcMatIx.colIx < dstColSize && srcMatIx.rowIx < dstColSize) { + // Source matrix coordinates are valid destination matrix coordinates + dstMatArray[getLinearIndexFromColRowIndex(srcMatIx, dstColSize)] = srcMatArray[c_ix]; + } + } + + return dstMatArray; +} + + +// Returns the glsl code to verify if the components are set correctly +// and the message to display for the test +function getConstructorExpressionInfo(targetType, argExp, firstCompValue) { + var argCompCountsSum = 0; + var argCompCounts = new Array(argExp.length); + for (var aa = 0; aa < argExp.length; ++aa) { + argCompCounts[aa] = getTypeCodeComponentCount(argExp[aa]); + argCompCountsSum += argCompCounts[aa]; + } + + var targetCompCount = getGLSLTypeComponentCount(targetType); + + var refCompVals; + var testMsg; + var valid; + + if (argCompCountsSum === 0) { + // A constructor needs at least one argument + refCompVals = []; + testMsg = "invalid (no arguments)"; + valid = false; + } + else { + if (isGLSLTypeVector(targetType)) { + if (argCompCountsSum === 1) { + // One scalar argument + // Vector constructor with one scalar argument set all components to the same value + refCompVals = getArrayWithIdenticalValues(targetCompCount, firstCompValue); + testMsg = "valid (all components set to the same value)"; + valid = true; + } + else { + // Not one scalar argument + if (argCompCountsSum < targetCompCount) { + // Not all components set + refCompVals = []; + testMsg = "invalid (not enough arguments)"; + valid = false; + } + else { + // argCompCountsSum >= targetCompCount + // All components set + var lastArgFirstCompIx = argCompCountsSum - argCompCounts[argCompCounts.length - 1]; + + if (lastArgFirstCompIx < targetCompCount) { + // First component of last argument is used + refCompVals = getArrayWithIncreasingValues(targetCompCount, firstCompValue); + testMsg = "valid"; + valid = true; + } + else { + // First component of last argument is not used + refCompVals = []; + testMsg = "invalid (unused argument)"; + valid = false; + } + } + } + } + else { + // Matrix target type + if (argCompCountsSum === 1) { + // One scalar argument + // Matrix constructors with one scalar set all components on the diagonal to the same value + // All other components are set to zero + refCompVals = matCompArrayCreateDiagonalMatrix(Math.round(Math.sqrt(targetCompCount)), firstCompValue); + testMsg = "valid (diagonal components set to the same value, off-diagonal components set to zero)"; + valid = true; + } + else { + // Not one scalar argument + if (argExp.length === 1 && argExp[0][0] === "m") { + // One single matrix argument + var dstColSize = getGLSLColumnSize(targetType); + refCompVals = matCompArraySetMatrixFromMatrix(dstColSize, getArrayWithIncreasingValues(getTypeCodeComponentCount(argExp[0]), firstCompValue)); + testMsg = "valid, components at corresponding col, row indices are set from argument, other components are set from identity matrix"; + valid = true; + } + else { + // More than one argument or one argument not of type matrix + // Can be treated in the same manner + // Arguments can not be of type matrix + var matFound = false; + for (var aa = 0; aa < argExp.length; ++aa) + if (argExp[aa][0] === "m") + matFound = true; + + if (matFound) { + refCompVals = []; + testMsg = "invalid, argument list greater than one contains matrix type"; + valid = false; + } + else { + if (argCompCountsSum < targetCompCount) { + refCompVals = []; + testMsg = "invalid (not enough arguments)"; + valid = false; + } + else { + // argCompCountsSum >= targetCompCount + // All components set + var lastArgFirstCompIx = argCompCountsSum - argCompCounts[argCompCounts.length - 1]; + + if (lastArgFirstCompIx < targetCompCount) { + // First component of last argument is used + refCompVals = getArrayWithIncreasingValues(targetCompCount, firstCompValue); + testMsg = "valid"; + valid = true; + } + else { + // First component of last argument is not used + refCompVals = []; + testMsg = "invalid (unused argument)"; + valid = false; + } + } + } + } + } + } + } + + // Check if no case is missed + if (testMsg == null || valid == null) { + wtu.error("GLSLConstructorTestsGenerator.getConstructorExpressionInfo(), info not set"); + debugger; + } + + return { + refCompVals: refCompVals, + testMsg: testMsg, + valid: valid + }; +} + + +// Returns a vertex shader testcase and a fragment shader testcase +function getVertexAndFragmentShaderTestCase(targetType, argExp) { + var firstCompValue = 0; + if (isGLSLTypeMatrix(targetType)) { + // Use value different from 0 and 1 + // 0 and 1 are values used by matrix constructed from a matrix or a single scalar + firstCompValue = 2; + } + + var argCode = getTestShaderParts (targetType, argExp, firstCompValue); + var expInfo = getConstructorExpressionInfo(targetType, argExp, firstCompValue); + + var substitutions = { + type: targetType, + errorBound: (getGLSLScalarType(targetType) === "float") ? "const float errorBound = 1.0E-5;" : "", + argsList: argCode.argsList, + argsConstr: argCode.argsConstr, + checkCompVals: getComponentValidationExpression(expInfo.refCompVals, targetType) + }; + + return [ { + // Test constructor argument list in vertex shader + vShaderSource: wtu.replaceParams(constructorVertexTemplate, substitutions), + vShaderSuccess: expInfo.valid, + fShaderSource: passThroughColorFragmentShader, + fShaderSuccess: true, + linkSuccess: expInfo.valid, + passMsg: "Vertex shader : " + argCode.typeExp + ", " + expInfo.testMsg, + render: expInfo.valid + }, { + // Test constructor argument list in fragment shader + fShaderSource: wtu.replaceParams(constructorFragmentTemplate, substitutions), + fShaderSuccess: expInfo.valid, + linkSuccess: expInfo.valid, + passMsg: "Fragment shader : " + argCode.typeExp + ", " + expInfo.testMsg, + render: expInfo.valid + } + ]; +} + + +// Incrementing the argument expressions +// Utility object which defines the order of incrementing the argument types +var typeCodeIncrementer = { + s: { typeCode: "v2", order: 0 }, + v2: { typeCode: "v3", order: 1 }, + v3: { typeCode: "v4", order: 2 }, + v4: { typeCode: "m2", order: 3 }, + m2: { typeCode: "m3", order: 4 }, + m3: { typeCode: "m4", order: 5 }, + m4: { typeCode: "s", order: 6 }, + first: "s" +} + + +// Returns the next argument sequence +function getNextArgumentSequence(inSeq) { + var nextSeq; + if (inSeq.length === 0) { + // Current argument sequence is empty, add first argument + nextSeq = [typeCodeIncrementer.first]; + } + else { + nextSeq = new Array(inSeq.length); + var overflow = true; + for (var aa = 0; aa < inSeq.length; ++aa) { + var currArg = inSeq[aa]; + if (overflow) { + // Increment the current argument type + var nextArg = typeCodeIncrementer[currArg].typeCode; + nextSeq[aa] = nextArg; + overflow = (nextArg === typeCodeIncrementer.first); + } + else { + // Copy remainder of sequence + nextSeq[aa] = currArg; + } + } + + if (overflow) { + nextSeq.push(typeCodeIncrementer.first); + } + } + + return nextSeq; +} + + +// Returns true if two argument expressions are equal +function areArgExpEqual(expA, expB) { + if (expA.length !== expB.length) + return false; + + for (var aa = 0; aa < expA.length; ++aa) + if (expA[aa] !== expB[aa]) + return false; + + return true; +} + + +// Returns true if first argument expression is smaller +// (comes before the second one in iterating order) +// compared to the second argument expression +function isArgExpSmallerOrEqual(argExpA, argExpB) { + var aLen = argExpA.length; + var bLen = argExpB.length; + if (aLen !== bLen) + return (aLen < bLen); + + // Argument type expression lengths are equal + for (var aa = aLen - 1; aa >= 0; --aa) { + var argA = argExpA[aa]; + var argB = argExpB[aa]; + + if (argA !== argB) { + var aOrder = typeCodeIncrementer[argA].order; + var bOrder = typeCodeIncrementer[argB].order; + if (aOrder !== bOrder) + return (aOrder < bOrder); + } + } + + // Argument type expressions are equal + return true; +} + + +// Returns the next argument expression from sequence set +// Returns null if end is reached +function getNextArgumentExpression(testExp, testSet) { + var testInterval = testSet[testExp.ix]; + + if (areArgExpEqual(testExp.argExp, testInterval[1])) { + // End of current interval reached + if (testExp.ix === testSet.length - 1) { + // End of set reached + return null; + } + else { + // Return first argument expression of next interval + var nextIx = testExp.ix + 1; + return { ix: nextIx, argExp: testSet[nextIx][0] }; + } + } + else { + // Return next expression in current interval + return { ix: testExp.ix, argExp: getNextArgumentSequence(testExp.argExp) }; + } +} + + +// Returns an array of the parts in the string separated by commas and with the white space trimmed +function convertCsvToArray(str) { + // Checks type codes in input + function checkInput(el, ix, arr) { + var typeCode = el.trim(); + if (!(typeCode in typeCodeIncrementer) && typeCode !== "first") { + wtu.error("GLSLConstructorTestsGenerator.convertCsvToArray(), unknown type code" + typeCode); + debugger; + } + + arr[ix] = typeCode; + } + + var spArr = str.split(","); + + // Convert empty string to empty array + if (spArr.length === 1 && spArr[0].trim() === "") + spArr = []; + + spArr.forEach(checkInput); + + return spArr; +} + + +// Processes the set of specified test sequences +function processInputs(testSequences) { + var testSet = new Array(testSequences.length); + for (var tt = 0; tt < testSequences.length; ++tt) { + var interval = testSequences[tt]; + var bounds = interval.split("-"); + var begin = convertCsvToArray(bounds[0]); + var end = convertCsvToArray(bounds[bounds.length - 1]); + + // Check if interval is valid + if (!isArgExpSmallerOrEqual(begin, end)) { + wtu.error("GLSLConstructorTestsGenerator.processInputs(), interval not valid"); + debugger; + } + + testSet[tt] = [ begin, end ]; + } + + return testSet; +} + + +/** + * Returns list of test cases for vector types + * All combinations of arguments up to one unused argument of one component are tested + * @param {targetType} Name of target type to test the constructor expressions on + * @param {testSet} Set of intervals of argument sequences to test + */ +function getConstructorTests(targetType, testSequences) { + // List of tests to return + var testInfos = []; + + // List of argument types + var testSet = processInputs(testSequences); + var testExp = { ix: 0, argExp: testSet[0][0] }; + + do { + // Add one vertex shader test case and one fragment shader test case + testInfos = testInfos.concat(getVertexAndFragmentShaderTestCase(targetType, testExp.argExp)); + + // Generate next argument expression + testExp = getNextArgumentExpression(testExp, testSet); + } + while (testExp != null); + + return testInfos; +} + + +// Returns default test argument expression set +// For details on input format : see bottom of file +function getDefaultTestSet(targetType) { + switch(targetType) { + case "vec2": + case "ivec2": + case "bvec2": + return [ + // No arguments and all single argument expressions + " - m4", + + // All two argument expressions with a scalar as second argument + "s, s - m4, s", + + // All two arguments expressions with a scalar as first argument + "s, v2", "s, v3", "s, v4", "s, m2", "s, m3", "s, m4", + + // Three argument expression + "s, s, s" + ]; + + case "vec3": + case "ivec3": + case "bvec3": + return [ + // No arguments and all single argument expressions + " - m4", + + // All two argument expressions with a scalar as second argument + "s, s - m4, s", + + // All two argument expressions with a scalar as first argument + "s, v2", "s, v3", "s, v4", "s, m2", "s, m3", "s, m4", + + // All three argument expressions with two scalars as second and third argument + "s, s, s - m4, s, s", + + // All three argument expressions with two scalars as first and second argument + "s, s, v2", "s, s, v3", "s, s, v4", "s, s, m2", "s, s, m3", "s, s, m4", + + // Four argument expression + "s, s, s, s" + ]; + + case "vec4": + case "ivec4": + case "bvec4": + case "mat2": + return [ + // No arguments and all single argument expressions + " - m4", + + // All two argument expressions with a scalar as second argument + "s, s - m4, s", + + // All two argument expressions with a scalar as first argument + "s, v2", "s, v3", "s, v4", "s, m2", "s, m3", "s, m4", + + // All three argument expressions with two scalars as second and third argument + "s, s, s - m4, s, s", + + // All three argument expressions with two scalars as first and second argument + "s, s, v2", "s, s, v3", "s, s, v4", "s, s, m2", "s, s, m3", "s, s, m4", + + // All four argument expressions with three scalars as second, third and fourth argument + "s, s, s, s - m4, s, s, s", + + // All four argument expressions with three scalars as first, second and third argument + "s, s, s, v2", "s, s, s, v3", "s, s, s, v4", "s, s, s, m2", "s, s, s, m3", "s, s, s, m4", + + // Five argument expression + "s, s, s, s, s" + ]; + + case "mat3": + case "mat4": + return [ + // No arguments and all single argument expressions + " - m4", + + // All two argument expressions with a scalar as second argument + "s, s - m4, s", + + // All two argument expressions with a scalar as first argument + "s, v2", "s, v3", "s, v4", "s, m2", "s, m3", "s, m4", + + // Several argument sequences + "v4, s, v4", "v4, s, v3, v2", "v4, v4, v3, v2", "v4, v4, v4, v4", "v2, v2, v2, v2, v2", "v2, v2, v2, v2, v2, v2, v2, v2", + "v3, v3, v3", "v3, v3, v3, s", "v3, v3, v3, v3, v3, s", "v3, v3, v3, v3, v3, s, s", + ]; + } +} + + +// Return publics +return { + getConstructorTests: getConstructorTests, + getDefaultTestSet: getDefaultTestSet +}; + +}()); + + +// Input is an array of intervals of argument types +// The generated test argument sequences are from (including) the lower interval boundary +// until (including) the upper boundary +// Coding and order of the different argument types : +// s : scalar +// v2 : vec2 +// v3 : vec3 +// v4 : vec4 +// m2 : mat2 +// m3 : mat3 +// m4 : mat4 + +// One interval is put in one string +// Low and high bound are separated by a dash. +// If there is no dash it is regarded as an interval of one expression +// The individual argument codes are separated by commas +// The individual arguments are incremented from left to right +// The left most argument is the one which is incremented first +// Once the left most arguments wraps the second argument is increased +// Examples : +// "s - m4" : All single arguments from scalar up to (including) mat4 +// "m2, s - m4, s" : All two argument expressions with a matrix argument as first argument and a scalar as second argument +// " - m4, m4" : The empty argument, all one arguments and all two argument expressions +// "m2, s, v3, m4" : One 4 argument expression : mat2, scalar, vec3, mat4 |