summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-uniform-packing-restrictions.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-uniform-packing-restrictions.html')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-uniform-packing-restrictions.html251
1 files changed, 251 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-uniform-packing-restrictions.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-uniform-packing-restrictions.html
new file mode 100644
index 0000000000..22a968470f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-uniform-packing-restrictions.html
@@ -0,0 +1,251 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL uniform packing restrctions Conformance Test</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../../resources/glsl-feature-tests.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="example" width="2" height="2"> </canvas>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 a_position;
+void main()
+{
+ gl_Position = a_position;
+}
+</script>
+<script id="fshader" type="x-shader/x-vertex">
+precision mediump float;
+varying vec4 v_varying;
+void main()
+{
+ gl_FragColor = v_varying;
+}
+</script>
+<script id="vshaderArrayTest" type="x-shader/x-vertex">
+attribute vec4 a_position;
+varying vec4 v_varying;
+uniform $(type) u_uniform[$(numTestType)];
+void main()
+{
+ v_varying = $(result);
+ gl_Position = a_position;
+}
+</script>
+<script id="fshaderArrayTest" type="x-shader/x-fragment">
+precision mediump float;
+uniform $(type) u_uniform[$(numTestType)];
+void main()
+{
+ gl_FragColor = $(result);
+}
+</script>
+<script id="vshaderUniformTest" type="x-shader/x-fragment">
+attribute vec4 a_position;
+varying vec4 v_varying;
+$(uniforms)
+void main()
+{
+ $(code)
+ v_varying = $(result);
+ gl_Position = a_position;
+}
+</script>
+<script id="fshaderUniformTest" type="x-shader/x-fragment">
+precision mediump float;
+$(uniforms)
+void main()
+{
+ $(code)
+ gl_FragColor = $(result);
+}
+</script>
+<script>
+"use strict";
+description();
+debug("");
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example");
+
+var uniformTypes = [
+ { type: "bool", componentsPerRow: 1, rows: 1, fType: "float", uniToF: "float(u_uniform$(id)$(index))", fToVec4: "vec4($(f), 0, 0, 0)"},
+ { type: "float", componentsPerRow: 1, rows: 1, fType: "float", uniToF: "u_uniform$(id)$(index)", fToVec4: "vec4($(f), 0, 0, 0)"},
+ { type: "int", componentsPerRow: 1, rows: 1, fType: "float", uniToF: "float(u_uniform$(id)$(index))", fToVec4: "vec4($(f), 0, 0, 0)"},
+ { type: "vec2", componentsPerRow: 2, rows: 1, fType: "vec2", uniToF: "u_uniform$(id)$(index)", fToVec4: "vec4($(f), 0, 0)"},
+ { type: "ivec2", componentsPerRow: 2, rows: 1, fType: "vec2", uniToF: "vec2(u_uniform$(id)$(index))", fToVec4: "vec4($(f), 0, 0)"},
+ { type: "bvec2", componentsPerRow: 2, rows: 1, fType: "vec2", uniToF: "vec2(u_uniform$(id)$(index))", fToVec4: "vec4($(f), 0, 0)"},
+ { type: "vec3", componentsPerRow: 3, rows: 1, fType: "vec3", uniToF: "u_uniform$(id)$(index)", fToVec4: "vec4($(f), 0)"},
+ { type: "ivec3", componentsPerRow: 3, rows: 1, fType: "vec3", uniToF: "vec3(u_uniform$(id)$(index))", fToVec4: "vec4($(f), 0)"},
+ { type: "bvec3", componentsPerRow: 3, rows: 1, fType: "vec3", uniToF: "vec3(u_uniform$(id)$(index))", fToVec4: "vec4($(f), 0)"},
+ { type: "vec4", componentsPerRow: 4, rows: 1, fType: "vec4", uniToF: "u_uniform$(id)$(index)", fToVec4: "$(f)"},
+ { type: "ivec4", componentsPerRow: 4, rows: 1, fType: "vec4", uniToF: "vec4(u_uniform$(id)$(index))", fToVec4: "$(f)"},
+ { type: "bvec4", componentsPerRow: 4, rows: 1, fType: "vec4", uniToF: "vec4(u_uniform$(id)$(index))", fToVec4: "$(f)"},
+// Yes, the spec says mat2 takes 4 columns, 2 rows.
+ { type: "mat2", componentsPerRow: 4, rows: 2, fType: "vec2", uniToF: "vec2(u_uniform$(id)$(index)[0])", fToVec4: "vec4($(f), 0, 0)"},
+ { type: "mat3", componentsPerRow: 3, rows: 3, fType: "vec3", uniToF: "vec3(u_uniform$(id)$(index)[0])", fToVec4: "vec4($(f), 0)"},
+ { type: "mat4", componentsPerRow: 4, rows: 4, fType: "vec4", uniToF: "vec4(u_uniform$(id)$(index)[0])", fToVec4: "$(f)"},
+// Samplers generally have more restrictive limits.
+// { type: "sampler2D", componentsPerRow: 1, rows: 1, code: "vec4(texture2D(u_uniform[$(index)], vec2(0, 0)))", },
+// { type: "samplerCube", componentsPerRow: 1, rows: 1, code: "vec4(textureCube(u_uniform[$(index)], vec3(0, 0, 0)))", },
+];
+
+var vBaseSource = wtu.getScript("vshader");
+var fBaseSource = wtu.getScript("fshader");
+var vArrayTestSource = wtu.getScript("vshaderArrayTest");
+var fArrayTestSource = wtu.getScript("fshaderArrayTest");
+var vUniformTestSource = wtu.getScript("vshaderUniformTest");
+var fUniformTestSource = wtu.getScript("fshaderUniformTest");
+
+var tests = [];
+var shaderTypes = [
+ { type: "vertex",
+ // For tests that expect failure which shader might fail.
+ vertExpectation: false,
+ fragExpectation: true,
+ vertArrayTest: vArrayTestSource,
+ fragArrayTest: fBaseSource,
+ vertUniformTest: vUniformTestSource,
+ fragUniformTest: fBaseSource,
+ maxVectors: gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS),
+ minVectors: 127, // GLSL ES 1.0.17 Appendix A.7 and A.8. Reserve one row for constants in the code, hence 128 - 1.
+ },
+ { type: "fragment",
+ // For tests that expect failure which shader might fail.
+ vertExpectation: true,
+ fragExpectation: false,
+ vertArrayTest: vBaseSource,
+ fragArrayTest: fArrayTestSource,
+ vertUniformTest: vBaseSource,
+ fragUniformTest: fUniformTestSource,
+ maxVectors: gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS),
+ minVectors: 15, // GLSL ES 1.0.17 Appendix A.8 - minimum value of gl_maxFragmentUniformVectors is 16. Again, reserve a row for constants.
+ },
+];
+for (var ss = 0; ss < shaderTypes.length; ++ss) {
+ var shaderType = shaderTypes[ss];
+ debug("max " + shaderType.type + ": " + shaderType.maxVectors);
+ for (var ii = 0; ii < uniformTypes.length; ++ii) {
+ var info = uniformTypes[ii];
+ wtu.log("checking: " + info.type);
+ // Compute the maximum amount of this type allowed in a single array.
+ var maxInArray = Math.floor(shaderType.maxVectors / info.rows);
+ // Compute the minimum required to work in a single array.
+ var minVars = Math.floor(shaderType.minVectors / info.rows);
+ // Compute the maximum allowed as single elements
+ var maxPerRow = Math.floor(4 / info.componentsPerRow);
+ var maxPacked = Math.floor(shaderType.maxVectors * maxPerRow / info.rows);
+
+ // Test array[1] of the type
+ var uniToF = wtu.replaceParams(info.uniToF, {id: "", index: "[0]"});
+ var vec4 = wtu.replaceParams(info.fToVec4, {f: uniToF});
+ tests.push({
+ vShaderSource: wtu.replaceParams(shaderType.vertArrayTest, {numTestType: 1, result: vec4}, info),
+ vShaderSuccess: true,
+ fShaderSource: wtu.replaceParams(shaderType.fragArrayTest, {numTestType: 1, result: vec4}, info),
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: shaderType.type + " shader with uniform array of " + info.type + " with 1 element should succeed",
+ });
+
+ // Note: We can't test an array filling all uniform space as actual GL drivers are
+ // only required to be able to do the minimum number. After that it can fail for
+ // multiple reasons, including uniform registers being reserved for the implementation's
+ // own use. Constants also take up uniform registers.
+
+ // Test required number of uniforms
+ var uniToF = wtu.replaceParams(info.uniToF, {id: "", index: "[" + (minVars - 1) + "]"});
+ var vec4 = wtu.replaceParams(info.fToVec4, {f: uniToF});
+ tests.push({
+ vShaderSource: wtu.replaceParams(shaderType.vertArrayTest, {numTestType: minVars, result: vec4}, info),
+ vShaderSuccess: true,
+ fShaderSource: wtu.replaceParams(shaderType.fragArrayTest, {numTestType: minVars, result: vec4}, info),
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: shaderType.type + " shader with uniform array of " + info.type + " with " + minVars + " elements (the minimum required) should succeed",
+ });
+
+ // Test array[max + 1] accessing last element. WebGL requires this to fail.
+ var uniToF = wtu.replaceParams(info.uniToF, {id: "", index: "[" + maxInArray + "]"});
+ var vec4 = wtu.replaceParams(info.fToVec4, {f: uniToF});
+ tests.push({
+ vShaderSource: wtu.replaceParams(shaderType.vertArrayTest, {numTestType: maxInArray + 1, result: vec4}, info),
+ vShaderSuccess: shaderType.vertExpectation,
+ fShaderSource: wtu.replaceParams(shaderType.fragArrayTest, {numTestType: maxInArray + 1, result: vec4}, info),
+ fShaderSuccess: shaderType.fragExpectation,
+ linkSuccess: false,
+ passMsg: shaderType.type + " shader with uniform array of " + info.type + " with " + (maxInArray + 1) + " elements (one past maximum) accessing last element should fail",
+ });
+
+ // Test array[max + 1] accessing first element. WebGL requires this to fail but ES allows truncating array.
+ var uniToF = wtu.replaceParams(info.uniToF, {id: "", index: "[0]"});
+ var vec4 = wtu.replaceParams(info.fToVec4, {f: uniToF});
+ tests.push({
+ vShaderSource: wtu.replaceParams(shaderType.vertArrayTest, {numTestType: maxInArray + 1, result: vec4}, info),
+ vShaderSuccess: shaderType.vertExpectation,
+ fShaderSource: wtu.replaceParams(shaderType.fragArrayTest, {numTestType: maxInArray + 1, result: vec4}, info),
+ fShaderSuccess: shaderType.fragExpectation,
+ linkSuccess: false,
+ passMsg: shaderType.type + " shader with uniform array of " + info.type + " with " + (maxInArray + 1) + " elements (one past maximum) accessing first element should fail",
+ });
+
+ // Note: We can't test max uniforms as actual GL drivers are only required to be able
+ // to do the minimum number. After that it can fail for multiple reasons, including
+ // uniform registers being reserved for the implementation's own use or also instruction
+ // space limitations. Strictly speaking, guaranteed supported length of a shader
+ // executable is defined by the GLES2 conformance tests according to GLSL ES 1.0.17
+ // Appendix A.2. This does not give us an exact limit: this test only aims to fit within
+ // instruction space limits imposed by existing GLES2 compliant hardware.
+
+ var generateCode = function(numVars) {
+ var uniforms = [];
+ var sumTerms = [];
+ for (var uu = 0; uu < numVars; ++uu) {
+ uniforms.push(" uniform " + info.type + " u_uniform" + uu + ";");
+ sumTerms.push(wtu.replaceParams(info.uniToF, {id: uu, index: ""}));
+ }
+ return {
+ uniforms: uniforms.join("\n"),
+ code: info.fType + " sum = " + sumTerms.join(" + \n ") + ";",
+ result: wtu.replaceParams(info.fToVec4, {f: 'sum'})
+ };
+ };
+
+ // Test max+1 uniforms of type.
+ tests.push({
+ vShaderSource: wtu.replaceParams(shaderType.vertUniformTest, generateCode(maxPacked + 1), info),
+ vShaderSuccess: shaderType.vertExpectation,
+ fShaderSource: wtu.replaceParams(shaderType.fragUniformTest, generateCode(maxPacked + 1), info),
+ fShaderSuccess: shaderType.fragExpectation,
+ linkSuccess: false,
+ passMsg: shaderType.type + " shader with " + (maxPacked + 1) + " uniforms of " + info.type + " (one past maximum) should fail",
+ });
+
+ // Test required uniforms of type.
+ tests.push({
+ vShaderSource: wtu.replaceParams(shaderType.vertUniformTest, generateCode(minVars), info),
+ vShaderSuccess: true,
+ fShaderSource: wtu.replaceParams(shaderType.fragUniformTest, generateCode(minVars), info),
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: shaderType.type + " shader with " + minVars + " uniforms of " + info.type + " (the minimum required) should succeed",
+ });
+ }
+}
+GLSLConformanceTester.runTests(tests);
+var successfullyParsed = true;
+</script>
+</body>
+</html>
+