summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs
parentInitial commit. (diff)
downloadfirefox-esr-upstream.tar.xz
firefox-esr-upstream.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/00_test_list.txt52
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/README.md18
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-ambiguous-function-call.html72
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-constructor-invalid-parameters.html56
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-d3d11-compiler-error.html96
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-dx-variable-bug.html96
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/array-of-struct-with-int-first-position.html141
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html52
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/bool-type-cast-bug-int-float.html312
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/character-set.html115
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/compare-loop-index-to-uniform.html50
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/complex-glsl-does-not-crash.html191
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/compound-assignment-type-combination.html26
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/conditional-discard-in-loop.html142
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/conditional-discard-optimization.html117
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/conditional-texture-fetch.html130
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/constant-precision-qualifier.html115
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/essl3-shaders-with-webgl1.html138
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/floor-div-cos-should-not-truncate.html80
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/floored-division-accuracy.html69
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/fragcoord-linking-bug.html93
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html66
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/global-invariant-does-not-leak-across-shaders.html77
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/if-return-and-elseif.html65
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/in-parameter-passed-as-inout-argument-and-global.html52
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/init-array-with-loop.html84
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/invariant-does-not-leak-across-shaders.html74
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/logic-inside-block-without-braces.html86
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/long-expressions-should-not-crash.html136
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/loop-if-loop-gradient.html75
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/modulo-arithmetic-accuracy.html68
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/multiplication-assignment.html50
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/nested-functions-should-not-crash.html89
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/nested-loops-with-break-and-continue.html83
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/nested-sequence-operator.html47
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/pow-of-small-constant-in-user-defined-function.html74
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/pow-with-constant-exponent-should-not-crash.html65
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/qualcomm-crash.html136
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/qualcomm-loop-with-continue-crash.html71
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sampler-array-struct-function-arg.html72
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sampler-array-using-loop-index.html81
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sampler-struct-function-arg.html113
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sequence-operator-evaluation-order.html116
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sketchfab-lighting-shader-crash.html84
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/struct-constructor-highp-bug.html50
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/struct-with-single-member-constructor.html52
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/temp-expressions-should-not-crash.html100
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/unary-minus-operator-float-bug.html49
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/undefined-index-should-not-crash.html64
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/uniforms-should-not-lose-values.html81
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/varying-arrays-should-not-be-reversed.html82
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/vector-matrix-constructor-scalarization.html181
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop-complex.html80
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html99
54 files changed, 4863 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/00_test_list.txt
new file mode 100644
index 0000000000..c84e94bbd0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/00_test_list.txt
@@ -0,0 +1,52 @@
+--min-version 1.0.4 angle-ambiguous-function-call.html
+--min-version 1.0.4 angle-constructor-invalid-parameters.html
+--min-version 1.0.3 angle-d3d11-compiler-error.html
+--min-version 1.0.3 angle-dx-variable-bug.html
+--min-version 1.0.3 array-of-struct-with-int-first-position.html
+--min-version 1.0.4 assign-to-swizzled-twice-in-function.html
+--min-version 1.0.4 bool-type-cast-bug-int-float.html
+--min-version 1.0.4 character-set.html
+--min-version 1.0.3 compare-loop-index-to-uniform.html
+--min-version 1.0.3 complex-glsl-does-not-crash.html
+--min-version 1.0.4 compound-assignment-type-combination.html
+--min-version 1.0.3 conditional-discard-in-loop.html
+--min-version 1.0.3 conditional-discard-optimization.html
+--min-version 1.0.4 conditional-texture-fetch.html
+--min-version 1.0.3 constant-precision-qualifier.html
+--min-version 1.0.3 --max-version 1.99 essl3-shaders-with-webgl1.html
+--min-version 1.0.4 floor-div-cos-should-not-truncate.html
+--min-version 1.0.3 floored-division-accuracy.html
+--min-version 1.0.3 fragcoord-linking-bug.html
+--min-version 1.0.4 gl-fragcoord-multisampling-bug.html
+--min-version 1.0.4 global-invariant-does-not-leak-across-shaders.html
+--min-version 1.0.4 if-return-and-elseif.html
+--min-version 1.0.4 init-array-with-loop.html
+--min-version 1.0.4 invariant-does-not-leak-across-shaders.html
+--min-version 1.0.4 in-parameter-passed-as-inout-argument-and-global.html
+--min-version 1.0.4 logic-inside-block-without-braces.html
+--min-version 1.0.3 long-expressions-should-not-crash.html
+--min-version 1.0.4 loop-if-loop-gradient.html
+--min-version 1.0.3 modulo-arithmetic-accuracy.html
+--min-version 1.0.3 multiplication-assignment.html
+--min-version 1.0.3 nested-functions-should-not-crash.html
+--min-version 1.0.4 nested-loops-with-break-and-continue.html
+--min-version 1.0.4 nested-sequence-operator.html
+--min-version 1.0.4 pow-of-small-constant-in-user-defined-function.html
+--min-version 1.0.4 pow-with-constant-exponent-should-not-crash.html
+--min-version 1.0.4 qualcomm-crash.html
+--min-version 1.0.4 qualcomm-loop-with-continue-crash.html
+--min-version 1.0.4 sampler-array-struct-function-arg.html
+--min-version 1.0.3 sampler-array-using-loop-index.html
+--min-version 1.0.4 sampler-struct-function-arg.html
+--min-version 1.0.4 sequence-operator-evaluation-order.html
+--min-version 1.0.4 sketchfab-lighting-shader-crash.html
+--min-version 1.0.4 struct-constructor-highp-bug.html
+--min-version 1.0.4 struct-with-single-member-constructor.html
+--min-version 1.0.3 temp-expressions-should-not-crash.html
+--min-version 1.0.4 unary-minus-operator-float-bug.html
+--min-version 1.0.4 undefined-index-should-not-crash.html
+--min-version 1.0.3 uniforms-should-not-lose-values.html
+--min-version 1.0.4 varying-arrays-should-not-be-reversed.html
+--min-version 1.0.4 vector-matrix-constructor-scalarization.html
+--min-version 1.0.4 vector-scalar-arithmetic-inside-loop.html
+--min-version 1.0.4 vector-scalar-arithmetic-inside-loop-complex.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/README.md b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/README.md
new file mode 100644
index 0000000000..d917f6d741
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/README.md
@@ -0,0 +1,18 @@
+BUGS
+====
+
+This folder is for GLSL tests that test driver specific bugs.
+
+Most tests in other folders are fairly generic. While they might
+only fail on specific drivers the tests themselves are designed
+to test something in a generic way.
+
+Tests in this folder on the otherhand are very targeted. They may
+have very specific shaders that only fail under specific circumstances
+on specific drivers.
+
+An example might be if there was a driver that failed only when
+and identifier was named "ABC". It makes no sense to have a generic
+test that says "must allow ABC". A generic test would test some
+subset of all possible identifiers not just one.
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-ambiguous-function-call.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-ambiguous-function-call.html
new file mode 100644
index 0000000000..c7f10a05f5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-ambiguous-function-call.html
@@ -0,0 +1,72 @@
+<!--
+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>ANGLE ambiguous function call test</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="fshaderAmbiguousHLSLFunctionCall" type="x-shader/x-fragment">
+precision mediump float;
+uniform vec4 uv;
+uniform mat2 um;
+vec4 foo(vec4 v) {
+ return v;
+}
+vec4 foo(mat2 m) {
+ return vec4(m);
+}
+void main()
+{
+ gl_FragColor = foo(uv) + foo(um);
+}
+</script>
+<script id="fshaderAmbiguousHLSLStructFunctionCall" type="x-shader/x-fragment">
+precision mediump float;
+uniform float u_zero;
+struct S { float foo; };
+struct S2 { float foo; };
+float get(S s) { return s.foo + u_zero; }
+float get(S2 s2) { return 0.25 + s2.foo + u_zero; }
+void main()
+{
+ S s;
+ s.foo = 0.5;
+ S2 s2;
+ s2.foo = 0.25;
+ gl_FragColor = vec4(0.0, get(s) + get(s2), 0.0, 1.0);
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description("Test overloaded functions with vec4 and mat2 parameters that have had issues in ANGLE. Issues were due to HLSL compiler treating float4 and float2x2 as the same type when resolving which overloaded function to call.");
+
+GLSLConformanceTester.runTests([
+{
+ fShaderId: 'fshaderAmbiguousHLSLFunctionCall',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Disambiguate correctly between overloaded function calls with 4-component float parameters"
+},
+{
+ fShaderId: 'fshaderAmbiguousHLSLStructFunctionCall',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Disambiguate correctly between overloaded function calls with struct parameters",
+ render: true
+}
+]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-constructor-invalid-parameters.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-constructor-invalid-parameters.html
new file mode 100644
index 0000000000..6c663811f1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-constructor-invalid-parameters.html
@@ -0,0 +1,56 @@
+<!--
+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>ANGLE constructor bugs test</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="fshaderSamplerInConstructorArguments" type="x-shader/x-fragment">
+precision mediump float;
+uniform sampler2D s;
+void main()
+{
+ gl_FragColor = vec4(0.0, s, 0.0, 0.0);
+}
+</script>
+<script id="fshaderVoidInConstructorArguments" type="x-shader/x-fragment">
+precision mediump float;
+void foo() {}
+void main()
+{
+ gl_FragColor = vec4(0.0, foo(), 0.0, 0.0);
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description("Test constructors that have had issues in ANGLE");
+
+GLSLConformanceTester.runTests([
+{
+ fShaderId: 'fshaderSamplerInConstructorArguments',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Sampler in constructor arguments should not compile"
+},
+{
+ fShaderId: 'fshaderVoidInConstructorArguments',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Void in constructor arguments should not compile"
+},
+]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-d3d11-compiler-error.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-d3d11-compiler-error.html
new file mode 100644
index 0000000000..158ddad08f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-d3d11-compiler-error.html
@@ -0,0 +1,96 @@
+<!--
+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>ANGLE D3D11 Bug - Shader compilation error</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+
+<script id="vs" type="x-shader/x-fragment">
+precision mediump float;
+uniform float A;
+void main() {
+ bool B = bool(A);
+ float x = B ? -A : 1.+A;
+ float y = B ? 1.+A : -A;
+ gl_Position = vec4(x, y, 0, 0);
+}
+
+</script>
+<script id="fs" type="x-shader/x-fragment">
+precision mediump float;
+void main() {
+ gl_FragColor = vec4(1, 0, 0, 1);
+}
+</script>
+
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script>
+"use strict";
+// See http://crbug.com/371868 for original failing case.
+description("This test checks an ANGLE D3D11 shader compiler error.");
+
+debug("");
+debug("Canvas.getContext");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas");
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ debug("");
+ debug("Checking shader compilation and linking.");
+
+ checkCompilation();
+}
+
+function checkCompilation() {
+ var vs = gl.createShader(gl.VERTEX_SHADER);
+ gl.shaderSource(vs, document.getElementById("vs").text);
+ gl.compileShader(vs);
+ if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {
+ testFailed("Vertex Shader failed to compile: " + gl.getShaderInfoLog(vs));
+ return;
+ }
+
+ var fs = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(fs, document.getElementById("fs").text);
+ gl.compileShader(fs);
+ if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {
+ testFailed("Fragment Shader failed to compile: " + gl.getShaderInfoLog(fs));
+ return;
+ }
+
+ var p = gl.createProgram();
+ gl.attachShader(p, vs);
+ gl.attachShader(p, fs);
+ gl.linkProgram(p);
+ if (!gl.getProgramParameter(p, gl.LINK_STATUS)) {
+ testFailed("Program failed to link: " + gl.getProgramInfoLog(p));
+ return;
+ }
+
+ testPassed("Linked Successfully");
+}
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-dx-variable-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-dx-variable-bug.html
new file mode 100644
index 0000000000..c094beff66
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-dx-variable-bug.html
@@ -0,0 +1,96 @@
+<!--
+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>ANGLE D3D11 Bug - Variables beginning with "dx_"</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+
+<script id="vs" type="x-shader/x-fragment">
+precision mediump float;
+attribute vec4 position;
+varying float dx_var;
+void main() {
+ gl_Position = position;
+ dx_var = position.x;
+}
+
+</script>
+<script id="fs" type="x-shader/x-fragment">
+precision mediump float;
+varying float dx_var;
+void main() {
+ gl_FragColor = vec4(dx_var, 0, 0, 1);
+}
+</script>
+
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script>
+"use strict";
+// See http://crbug.com/371868 for original failing case.
+description("This test checks an ANGLE D3D11 shader compiler error.");
+
+debug("");
+debug("Canvas.getContext");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas");
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ debug("");
+ debug("Checking shader compilation and linking.");
+
+ checkCompilation()
+}
+
+function checkCompilation() {
+ var vs = gl.createShader(gl.VERTEX_SHADER);
+ gl.shaderSource(vs, document.getElementById("vs").text);
+ gl.compileShader(vs);
+ if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {
+ testFailed("Vertex Shader failed to compile: " + gl.getShaderInfoLog(vs));
+ return;
+ }
+
+ var fs = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(fs, document.getElementById("fs").text);
+ gl.compileShader(fs);
+ if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {
+ testFailed("Fragment Shader failed to compile: " + gl.getShaderInfoLog(fs));
+ return;
+ }
+
+ var p = gl.createProgram();
+ gl.attachShader(p, vs);
+ gl.attachShader(p, fs);
+ gl.linkProgram(p);
+ if (!gl.getProgramParameter(p, gl.LINK_STATUS)) {
+ testFailed("Program failed to link: " + gl.getProgramInfoLog(p));
+ return;
+ }
+
+ testPassed("Linked Successfully");
+}
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/array-of-struct-with-int-first-position.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/array-of-struct-with-int-first-position.html
new file mode 100644
index 0000000000..e7dd805566
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/array-of-struct-with-int-first-position.html
@@ -0,0 +1,141 @@
+<!--
+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>Driver Bug - Array of structs with int or bool in first position</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+
+<body>
+<canvas id="example" style="border: none;" width="788" height="256"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script id="shader-vs" type="x-shader/x-vertex">
+attribute vec2 pos;
+void main(void) {
+ gl_Position = vec4(pos, 0.0, 1.0);
+}
+</script>
+
+<script id="shader-fs-int" type="x-shader/x-fragment">
+precision mediump float;
+struct Light {
+ int unused;
+ vec3 color;
+};
+const int numLights = 1;
+void main() {
+ Light lights[numLights];
+ lights[0].color = vec3(0.0, 0.5, 0.0);
+
+ vec3 result = vec3(0.0, 0.0, 0.0);
+ for (int i=0; i<numLights; i++) {
+ result += lights[i].color;
+ }
+ gl_FragColor = vec4(result.rgb, 1.0);
+}
+</script>
+
+<script id="shader-fs-bool" type="x-shader/x-fragment">
+precision mediump float;
+struct Light {
+ bool unused;
+ vec3 color;
+};
+const int numLights = 1;
+void main() {
+ Light lights[numLights];
+ lights[0].color = vec3(0.0, 0.5, 0.0);
+
+ vec3 result = vec3(0.0, 0.0, 0.0);
+ for (int i=0; i<numLights; i++) {
+ result += lights[i].color;
+ }
+ gl_FragColor = vec4(result.rgb, 1.0);
+}
+</script>
+
+<script id="shader-fs-bool-read" type="x-shader/x-fragment">
+precision mediump float;
+struct Light {
+ bool useLight;
+ vec3 color;
+};
+const int numLights = 1;
+void main() {
+ Light lights[numLights];
+ lights[0].color = vec3(0.0, 0.5, 0.0);
+ lights[0].useLight = true;
+
+ vec3 result = vec3(0.0, 0.0, 0.0);
+ for (int i=0; i<numLights; i++) {
+ Light light = lights[i];
+ if (light.useLight) {
+ result += light.color;
+ }
+ }
+ gl_FragColor = vec4(result.rgb, 1.0);
+}
+</script>
+
+<script>
+"use strict";
+
+function test() {
+ description();
+ debug(
+ "This test checks accessing an array of structs, where the struct " +
+ "definition has an int or bool in the first position. " +
+ "This test has has failed in OS X on some NVIDIA cards, " +
+ "such as the NVIDIA GeForce GT 650M. If things are working " +
+ "correctly, then there will be a series of 50% green squares.")
+ debug("");
+
+ var wtu = WebGLTestUtils;
+ var canvas = document.getElementById("example");
+ var gl = wtu.create3DContext(canvas);
+
+ var testNum = 0;
+ var border = 10; // border between test squares for visibility
+ var squareSize = 256;
+ var expectedColor = [0, 127, 0, 255]; // 50% green
+
+ function subTest(message, fragmentShader) {
+ debug(message);
+ var startX = (squareSize + border) * testNum;
+ var program = wtu.setupProgram(
+ gl, ["shader-vs", fragmentShader], ["pos"], null, true);
+ gl.viewport(startX, 0, squareSize, squareSize);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(
+ gl, startX, 0, squareSize, squareSize,
+ expectedColor, "square should be 50% green", 1);
+ debug("");
+ testNum++;
+ }
+
+ if (!gl) {
+ testFailed("context does not exist");
+ } else {
+ wtu.setupUnitQuad(gl);
+ subTest("Test unused int in first struct position.", "shader-fs-int");
+ subTest("Test unused bool in first struct position.", "shader-fs-bool");
+ subTest("Test used bool in first struct position.", "shader-fs-bool-read");
+ }
+}
+
+test();
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html
new file mode 100644
index 0000000000..847127a408
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html
@@ -0,0 +1,52 @@
+<!--
+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>Assigning an assignment to a swizzled value inside function</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+
+vec2 f()
+{
+ vec2 r = vec2(0);
+ r.x = r.y = 1.0;
+ return r;
+}
+
+void main()
+{
+ gl_FragColor.ga = f();
+}
+
+</script>
+<script type="text/javascript">
+"use strict";
+description();
+
+// Minimal test case based on report at http://crbug.com/798117
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshader',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Assigning an assignment to a swizzled value inside a user-defined function"
+}
+]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/bool-type-cast-bug-int-float.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/bool-type-cast-bug-int-float.html
new file mode 100644
index 0000000000..984c4e0289
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/bool-type-cast-bug-int-float.html
@@ -0,0 +1,312 @@
+<!--
+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>Verify int(bool) and float(bool) work correctly (Mac AMD driver bug)</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader-int1" type="x-shader/x-vertex">
+attribute vec3 aPosition;
+varying mediump float fvalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ int ivalue = int(bvalue);
+ if (ivalue == 0) {
+ fvalue = 0.0;
+ } else if (ivalue == 1) {
+ fvalue = 1.0;
+ } else {
+ fvalue = -1.0;
+ }
+}
+</script>
+<script id="fshader-int1" type="x-shader/x-fragment">
+varying mediump float fvalue;
+
+void main() {
+ if (fvalue == 1.0)
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (fvalue == 0.0)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-int2" type="x-shader/x-vertex">
+attribute vec3 aPosition;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+}
+</script>
+<script id="fshader-int2" type="x-shader/x-fragment">
+uniform bool bvalue;
+
+void main() {
+ int ivalue = int(bvalue);
+
+ if (ivalue == 1)
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (ivalue == 0)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-float1" type="x-shader/x-vertex">
+attribute vec3 aPosition;
+varying mediump float fvalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ fvalue = float(bvalue);
+}
+</script>
+<script id="fshader-float1" type="x-shader/x-fragment">
+varying mediump float fvalue;
+
+void main() {
+ if (fvalue == 1.0)
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (fvalue == 0.0)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-float2" type="x-shader/x-vertex">
+attribute vec3 aPosition;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+}
+</script>
+<script id="fshader-float2" type="x-shader/x-fragment">
+uniform bool bvalue;
+
+void main() {
+ mediump float fvalue = float(bvalue);
+
+ if (fvalue == 1.0)
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (fvalue == 0.0)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-vec2-1" type="x-shader/x-vertex">
+attribute vec3 aPosition;
+varying mediump vec2 fvalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ fvalue = vec2(bvalue);
+}
+</script>
+<script id="fshader-vec2-1" type="x-shader/x-fragment">
+varying mediump vec2 fvalue;
+
+void main() {
+ if (fvalue == vec2(1.0, 1.0))
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (fvalue == vec2(0.0, 0.0))
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-vec2-2" type="x-shader/x-vertex">
+attribute vec3 aPosition;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+}
+</script>
+<script id="fshader-vec2-2" type="x-shader/x-fragment">
+precision mediump float;
+uniform bool bvalue;
+
+void main() {
+ vec2 fvalue = vec2(bvalue);
+
+ if (fvalue == vec2(1.0, 1.0))
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (fvalue == vec2(0.0, 0.0))
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-vec3-1" type="x-shader/x-vertex">
+attribute vec3 aPosition;
+varying mediump vec3 fvalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ fvalue = vec3(bvalue);
+}
+</script>
+<script id="fshader-vec3-1" type="x-shader/x-fragment">
+varying mediump vec3 fvalue;
+
+void main() {
+ if (fvalue == vec3(1.0, 1.0, 1.0))
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (fvalue == vec3(0.0, 0.0, 0.0))
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-vec3-2" type="x-shader/x-vertex">
+attribute vec3 aPosition;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+}
+</script>
+<script id="fshader-vec3-2" type="x-shader/x-fragment">
+precision mediump float;
+uniform bool bvalue;
+
+void main() {
+ vec3 fvalue = vec3(bvalue);
+
+ if (fvalue == vec3(1.0, 1.0, 1.0))
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (fvalue == vec3(0.0, 0.0, 0.0))
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-vec4-1" type="x-shader/x-vertex">
+attribute vec3 aPosition;
+varying mediump vec4 fvalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ fvalue = vec4(bvalue);
+}
+</script>
+<script id="fshader-vec4-1" type="x-shader/x-fragment">
+varying mediump vec4 fvalue;
+
+void main() {
+ if (fvalue == vec4(1.0, 1.0, 1.0, 1.0))
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (fvalue == vec4(0.0, 0.0, 0.0, 0.0))
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-vec4-2" type="x-shader/x-vertex">
+attribute vec3 aPosition;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+}
+</script>
+<script id="fshader-vec4-2" type="x-shader/x-fragment">
+precision mediump float;
+uniform bool bvalue;
+
+void main() {
+ vec4 fvalue = vec4(bvalue);
+
+ if (fvalue == vec4(1.0, 1.0, 1.0, 1.0))
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (fvalue == vec4(0.0, 0.0, 0.0, 0.0))
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+ <script type="application/javascript">
+"use strict";
+description("Verify int(bool) and float(bool) work correctly");
+debug("");
+var wtu = WebGLTestUtils;
+function test() {
+ var gl = wtu.create3DContext("canvas");
+ if (!gl) {
+ testFailed("context does not exist");
+ return;
+ }
+ wtu.setupUnitQuad(gl);
+
+ var testCases = [
+ { vshader: "vshader-int1", fshader: "fshader-int1", desc: "vertex shader int" },
+ { vshader: "vshader-int2", fshader: "fshader-int2", desc: "fragment shader int" },
+ { vshader: "vshader-float1", fshader: "fshader-float1", desc: "vertex shader float" },
+ { vshader: "vshader-float2", fshader: "fshader-float2", desc: "fragment shader float" },
+ { vshader: "vshader-vec2-1", fshader: "fshader-vec2-1", desc: "vertex shader vec2" },
+ { vshader: "vshader-vec2-2", fshader: "fshader-vec2-2", desc: "fragment shader vec2" },
+ { vshader: "vshader-vec3-1", fshader: "fshader-vec3-1", desc: "vertex shader vec3" },
+ { vshader: "vshader-vec3-2", fshader: "fshader-vec3-2", desc: "fragment shader vec3" },
+ { vshader: "vshader-vec4-1", fshader: "fshader-vec4-1", desc: "vertex shader vec4" },
+ { vshader: "vshader-vec4-2", fshader: "fshader-vec4-2", desc: "fragment shader vec4" },
+ ];
+
+ for (var idx = 0; idx < testCases.length; ++idx) {
+ var test = testCases[idx];
+
+ debug("");
+ var program = wtu.setupProgram(gl, [test.vshader, test.fshader], ["aPosition"]);
+ if (!program) {
+ testFailed("Fail to set up program");
+ } else {
+ var uniformLoc = gl.getUniformLocation(program, 'bvalue');
+ debug("Testing " + test.desc + " with false");
+ gl.uniform1i(uniformLoc, 0);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 255, 0, 255]);
+ debug("Testing " + test.desc + " with true");
+ gl.uniform1i(uniformLoc, 1);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, 255]);
+ gl.deleteProgram(program);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from testing");
+ }
+ }
+};
+
+test();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/character-set.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/character-set.html
new file mode 100644
index 0000000000..6d6fca5f89
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/character-set.html
@@ -0,0 +1,115 @@
+<!--
+Copyright (c) 2020 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>Character Set</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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="canvas" width="2" height="2"> </canvas>
+<script>
+"use strict";
+// See http://crbug.com/1108588 for original failing case.
+// Check "OpenGL Registry The OpenGL ES Shading Language"
+// Section 3.2 Character Sets For more info
+description("This test checks character set validation for glsl.");
+
+debug("");
+debug("Canvas.getContext");
+
+let wtu = WebGLTestUtils;
+let gl = wtu.create3DContext("canvas");
+let consoleDiv = document.getElementById("console");
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ debug("");
+ debug("Checking shader character set validation and compilation");
+
+ runTest();
+}
+
+function testShaderSource(shaderSource, msg) {
+ if (!quietMode()) {
+ wtu.addShaderSource(consoleDiv, "test fragment shader", shaderSource);
+ }
+
+ let shader = gl.createShader(gl.FRAGMENT_SHADER);
+ if (shader == null) {
+ testFailed("*** Error: unable to create shader '" + shaderSource + "'");
+ return;
+ }
+
+ gl.shaderSource(shader, shaderSource);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, msg);
+}
+
+function MUST(ifTruthy) {
+ return ifTruthy ? 'MUST' : 'MUST NOT';
+}
+
+function runTest() {
+
+ const BAD_STRINGS = [
+ '$',
+ '"',
+ '一些注释',
+ '#line 42 "foo.glsl"',
+ ];
+ const TESTS = [
+ ['in identifier', s => s, false],
+ ['in comment', s => `// ${s}`, true, true],
+ ['in ifdef-out', s => `#if 0 \n${s} \n#endif`, true],
+ ['in ifdef-out #preproc', s => `#if 0 \n#${s} \n#endif`, true],
+ ['in #preproc', s => `#${s}`, false],
+ ['in comment after #define', s => `#define TEST // ${s}`, true], // Regression test for crbug.com/940865
+ ];
+
+ const glsl_tests = [];
+
+ for (const s of BAD_STRINGS) {
+ for (const [where, template, validCompile] of TESTS) {
+ const st = template(s);
+ const src = `
+precision mediump float;
+${st}
+void main() {
+ gl_FragColor = vec4(1, 0, 0, 1);
+}`.trim();
+
+ testShaderSource(src, `shaderSource allows Out-of-charset string '${s}' ${where} until compilation.`);
+
+ glsl_tests.push(
+ {
+ fShaderSource: src,
+ fShaderSuccess: validCompile,
+ linkSuccess: validCompile,
+ passMsg: `Out-of-charset string '${s}' ${where} ${MUST(validCompile)} compile.`
+ }
+ );
+ }
+ }
+
+ GLSLConformanceTester.runTests(glsl_tests);
+}
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/compare-loop-index-to-uniform.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/compare-loop-index-to-uniform.html
new file mode 100644
index 0000000000..a96da7fea9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/compare-loop-index-to-uniform.html
@@ -0,0 +1,50 @@
+<!--
+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>Driver bug - Comparing loop index against uniform in a fragment shader should work</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform int uCount;
+
+void main() {
+ float a = 0.0;
+ for (int i = 0; i < 5; ++i) {
+ if (i < uCount) {
+ a += 0.2;
+ }
+ }
+ gl_FragColor = vec4(1.0 - a, a, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Comparing loop index to an uniform in a fragment shader should work.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshader',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Compare a loop index to an uniform',
+ uniforms: [{name: "uCount", functionName: "uniform1i", value: 5}]
+}
+]);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/complex-glsl-does-not-crash.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/complex-glsl-does-not-crash.html
new file mode 100644
index 0000000000..7b324def84
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/complex-glsl-does-not-crash.html
@@ -0,0 +1,191 @@
+<!--
+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>Driver Bug - complex glsl should not crash</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 = $(code);
+ 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 = $(code);
+}
+</script>
+<script id="vshaderUniformTest" type="x-shader/x-fragment">
+attribute vec4 a_position;
+varying vec4 v_varying;
+$(uniforms)
+void main()
+{
+ v_varying = $(code);
+ gl_Position = a_position;
+}
+</script>
+<script id="fshaderUniformTest" type="x-shader/x-fragment">
+precision mediump float;
+$(uniforms)
+void main()
+{
+ gl_FragColor = $(code);
+}
+</script>
+<script>
+"use strict";
+description();
+debug("");
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example");
+
+var uniformTypes = [
+ { type: "bool", componentsPerRow: 1, rows: 1, code: "vec4(u_uniform$(id)$(index), 0, 0, 0)", },
+ { type: "float", componentsPerRow: 1, rows: 1, code: "vec4(u_uniform$(id)$(index), 0, 0, 0)", },
+ { type: "int", componentsPerRow: 1, rows: 1, code: "vec4(u_uniform$(id)$(index), 0, 0, 0)", },
+ { type: "vec2", componentsPerRow: 2, rows: 1, code: "vec4(u_uniform$(id)$(index), 0, 0)", },
+ { type: "ivec2", componentsPerRow: 2, rows: 1, code: "vec4(u_uniform$(id)$(index), 0, 0)", },
+ { type: "bvec2", componentsPerRow: 2, rows: 1, code: "vec4(u_uniform$(id)$(index), 0, 0)", },
+ { type: "vec3", componentsPerRow: 3, rows: 1, code: "vec4(u_uniform$(id)$(index), 0)", },
+ { type: "ivec3", componentsPerRow: 3, rows: 1, code: "vec4(u_uniform$(id)$(index), 0)", },
+ { type: "bvec3", componentsPerRow: 3, rows: 1, code: "vec4(u_uniform$(id)$(index), 0)", },
+ { type: "vec4", componentsPerRow: 4, rows: 1, code: "vec4(u_uniform$(id)$(index))", },
+ { type: "ivec4", componentsPerRow: 4, rows: 1, code: "vec4(u_uniform$(id)$(index))", },
+ { type: "bvec4", componentsPerRow: 4, rows: 1, code: "vec4(u_uniform$(id)$(index))", },
+// Yes, the spec says mat2 takes 4 columns, 2 rows.
+ { type: "mat2", componentsPerRow: 4, rows: 2, code: "vec4(u_uniform$(id)$(index)[0], 0, 0)", },
+ { type: "mat3", componentsPerRow: 3, rows: 3, code: "vec4(u_uniform$(id)$(index)[0], 0)", },
+ { type: "mat4", componentsPerRow: 4, rows: 4, code: "vec4(u_uniform$(id)$(index)[0])", },
+// Samplers generally have more restictive 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: 128, // GLSL ES 1.0.17 Appendix A.7,
+ },
+ { 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: 16, // GLSL ES 1.0.17 Appendix A.7,
+ },
+];
+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 numVars = 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 numPerRow = Math.floor(4 / info.componentsPerRow);
+ var numMax = Math.floor(shaderType.maxVectors * numPerRow / info.rows);
+
+ // Test array[max] of the type
+ // Note: We can't test for success or failer as actual GL drivers are only required to be able to
+ // do the minimum number. After that it can fail for any reason.
+ var code = wtu.replaceParams(info.code, {id: "", index: "[" + (numVars - 1) + "]"});
+ tests.push({
+ vShaderSource: wtu.replaceParams(shaderType.vertArrayTest, {numTestType: numVars, code: code}, info),
+ vShaderSuccess: true,
+ fShaderSource: wtu.replaceParams(shaderType.fragArrayTest, {numTestType: numVars, code: code}, info),
+ fShaderSuccess: true,
+ linkSuccess: true,
+ ignoreResults: true,
+ passMsg: shaderType.type + " shader with uniform array of " + info.type + " with " + numVars + " elements (the maximum)",
+ });
+
+ var generateCode = function(numVars) {
+ var uniforms = [];
+ var codes = [];
+ for (var uu = 0; uu < numVars; ++uu) {
+ uniforms.push(" uniform " + info.type + " u_uniform" + uu + ";");
+ codes.push(wtu.replaceParams(info.code, {id: uu, index: ""}));
+ }
+ return {
+ uniforms: uniforms.join("\n"),
+ code: codes.join(" + \n "),
+ };
+ };
+
+ // Test max uniforms of type.
+ tests.push({
+ vShaderSource: wtu.replaceParams(shaderType.vertUniformTest, generateCode(numMax), info),
+ vShaderSuccess: shaderType.vertExpectation,
+ fShaderSource: wtu.replaceParams(shaderType.fragUniformTest, generateCode(numMax), info),
+ fShaderSuccess: shaderType.fragExpectation,
+ linkSuccess: true,
+ ignoreResults: true,
+ passMsg: shaderType.type + " shader with " + (numMax) + " uniforms of " + info.type,
+ });
+ }
+}
+GLSLConformanceTester.runTests(tests);
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/compound-assignment-type-combination.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/compound-assignment-type-combination.html
new file mode 100644
index 0000000000..7b61946b35
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/compound-assignment-type-combination.html
@@ -0,0 +1,26 @@
+<!--
+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>Result type should match the l-value type in compound assignment</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>
+<script src="../../../js/tests/compound-assignment-type-combination.js"></script>
+</head>
+<body onload="runTest(1)">
+<div id="description"></div>
+<div id="console"></div>
+<script type="application/javascript">
+description();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/conditional-discard-in-loop.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/conditional-discard-in-loop.html
new file mode 100644
index 0000000000..1c4709dd10
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/conditional-discard-in-loop.html
@@ -0,0 +1,142 @@
+<!--
+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>Conditional discard in loop issue</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+
+<body>
+<canvas id="output" style="border: none;" width="256" height="256"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script id="shader-vs" type="x-shader/x-vertex">
+// Inputs
+attribute vec4 a_position;
+attribute vec2 a_tex_coords;
+
+// Output
+varying vec2 v_tex_coords;
+
+void main(void) {
+ v_tex_coords = a_tex_coords;
+ gl_Position = a_position;
+}
+</script>
+
+<script id="shader-fs" type="x-shader/x-fragment">
+precision mediump float;
+
+// Constants
+const float TEXEL_COUNT_V = 256.0;
+const float TEXEL_HEIGHT = 1.0 / TEXEL_COUNT_V;
+const float SEP_IX = TEXEL_COUNT_V / 2.0;
+
+const vec4 GREEN = vec4(0.0, 1.0, 0.0, 1.0);
+const vec4 BLUE = vec4(0.0, 0.0, 1.0, 1.0);
+
+// Input
+varying vec2 v_tex_coords;
+
+uniform sampler2D u_data;
+
+// Without this function or directly returning the data, the issue does not occur
+mediump vec4 UnpackData(in vec4 inData) {
+ float s = inData.x;
+ // Note s is always 0
+ // mod(0, 1) = 0
+ // So return value = (0, 0, -1, 0)
+ return vec4(0.0, 0.0, mod(s, 1.0) - 1.0, 0.0);
+
+ // Comment out the line above and uncomment the line below and the test succeeds on angle-dx11
+ // return vec4(0.0, 0.0, -1.0, 0.0);
+}
+
+void main(void) {
+ // Set initial color
+ gl_FragColor = BLUE;
+
+ if (gl_FragCoord.y <= SEP_IX) {
+ mediump vec2 addr = vec2(v_tex_coords.x, TEXEL_HEIGHT);
+
+ for (float e_ix = 0.0; e_ix < TEXEL_COUNT_V; ++e_ix) {
+ vec4 entry = texture2D(u_data, addr);
+ mediump vec4 unpack = UnpackData(entry);
+
+ // Buffer is filled with 0, unpack is always (0, 0, -1, 0)
+ // So discard is always triggered
+ if (unpack.z == -1.0) {
+ discard;
+ }
+
+ addr.y += unpack.z * TEXEL_HEIGHT;
+ }
+ // If discard is not triggered the output color is blue
+ }
+ else {
+ gl_FragColor = GREEN;
+ }
+}
+</script>
+
+
+<script>
+"use strict";
+
+description();
+debug("");
+debug("If the code is executed correctly, the upper half of the viewport will be green, the lower half will be red.");
+debug("This is a conformance suite test for the issue reported here : https://code.google.com/p/angleproject/issues/detail?id=706");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("output");
+var gl = wtu.create3DContext(canvas);
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+
+ // Create texture filled with zero's
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ wtu.fillTexture(gl, tex, 256, 256, [0, 0, 0, 0]);
+
+ // Clear complete viewport to red
+ gl.clearColor(1.0, 0.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ var attribBuffers = wtu.setupUnitQuad(gl, 0, 1);
+ var program = wtu.setupProgram(gl, ["shader-vs", "shader-fs"], ["a_position", "a_tex_coords"], [0, 1], true);
+
+ // Bind texture
+ var uniformMap = wtu.getUniformMap(gl, program);
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.uniform1i(uniformMap.u_data.location, 0);
+
+ // Draw
+ wtu.drawUnitQuad(gl);
+
+ // Verify output
+ wtu.checkCanvasRect(gl, 0, 0, 256, 128, [ 255, 0, 0, 255 ], "should be red", 1);
+ wtu.checkCanvasRect(gl, 0, 128, 256, 128, [ 0, 255, 0, 255 ], "should be green", 1);
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/conditional-discard-optimization.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/conditional-discard-optimization.html
new file mode 100644
index 0000000000..1c3b1bb6fb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/conditional-discard-optimization.html
@@ -0,0 +1,117 @@
+<!--
+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.
+-->
+
+<!-- author: Bill Baxter (wbaxter at google.com) -->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>ANGLE WebGL Shader Conditionals Repro</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+
+<body>
+<canvas id="repro" style="border: none;" width="256" height="256"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script id="shader-vs" type="x-shader/x-vertex">
+attribute vec2 pos;
+varying mediump float varA;
+void main(void) {
+ varA = 0.;
+ gl_Position = vec4(pos, 0.0, 1.0);
+}
+</script>
+
+<script id="shader-fs" type="x-shader/x-fragment">
+precision mediump float;
+varying float varA;
+void main(void) {
+ if (varA < -1. || (varA < -1. && varA > 1.)) {
+ discard;
+ }
+ gl_FragColor = vec4(0, 1, 0, 1) + 2. * varA * 2.;
+}
+</script>
+
+<script id="shader-fs-mutable" type="x-shader/x-fragment">
+precision mediump float;
+varying float varA;
+void main(void) {
+ float b = varA;
+ if (varA < (b -= 1.) || (varA < b && varA > (b += 2.))) {
+ discard;
+ }
+ gl_FragColor = vec4(0, 1, 0, 1) + 2. * varA * 2.;
+}
+</script>
+<script id="shader-fs-unfolded" type="x-shader/x-fragment">
+precision mediump float;
+varying float varA;
+void main(void) {
+ bool s1 = varA < -1.;
+ if (!s1) {
+ bool s2 = varA < -1.;
+ if (s2) {
+ s2 = varA > 1.;
+ }
+ s1 = s2;
+ }
+ if (s1) {
+ discard;
+ }
+ gl_FragColor = vec4(0, 1, 0, 1) + 2. * varA * 2.;
+}
+</script>
+<script>
+"use strict";
+
+description();
+debug("");
+debug("If things are working correctly, then there will be a green square.");
+debug("Otherwise it will be a black void.");
+debug("This is a repro for an issue seen on the D3D9 ANGLE implementation of WebGL on Chrome in a shader with a conditional discard, where the conditional is of the form (a || (b && c)).");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("repro");
+var gl = wtu.create3DContext(canvas);
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ wtu.setupUnitQuad(gl);
+
+ debug("");
+ debug("Testing shader with conditional discard");
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ var program = wtu.setupProgram(gl, ["shader-vs", "shader-fs"], ["pos"], undefined, true);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 128, 128, 128, 128, [ 0, 255, 0, 255 ], "should be green", 1);
+
+ debug("");
+ debug("Testing conditional discard with side-effects in conditions");
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ var programMutable = wtu.setupProgram(gl, ["shader-vs", "shader-fs-mutable"], ["pos"], undefined, true);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 128, 128, 128, 128, [ 0, 255, 0, 255 ], "should be green", 1);
+
+ debug("");
+ debug("Testing conditional discard with unfolded condition logic");
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ var programMutable = wtu.setupProgram(gl, ["shader-vs", "shader-fs-unfolded"], ["pos"], undefined, true);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 128, 128, 128, 128, [ 0, 255, 0, 255 ], "should be green", 1);
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/conditional-texture-fetch.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/conditional-texture-fetch.html
new file mode 100644
index 0000000000..f382b8c800
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/conditional-texture-fetch.html
@@ -0,0 +1,130 @@
+<!--
+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>Conditional texture fetch test</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<canvas id="output" style="border: none;" width="64" height="64"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshaderConditionalTextureFetch" type="x-shader/x-vertex">
+attribute vec2 a_position;
+attribute vec4 a_canvasTileColor;
+attribute vec2 a_texCoord;
+varying vec2 texCoord;
+varying vec4 canvasTileColor;
+void main()
+{
+ canvasTileColor = a_canvasTileColor;
+ texCoord = a_texCoord;
+ gl_Position = vec4(a_position, 0.0, 1.0);
+}
+</script>
+<script id="fshaderConditionalTextureFetch" type="x-shader/x-fragment">
+precision mediump float;
+varying vec4 canvasTileColor;
+uniform bool hasTexture;
+uniform sampler2D canvasTileTexture;
+varying vec2 texCoord;
+uniform vec4 uvRect;
+void main()
+{
+ vec4 finalColor = canvasTileColor;
+ if (hasTexture) {
+ vec2 clampedUV = clamp(texCoord.xy, uvRect.xy, uvRect.zw);
+ finalColor = texture2D(canvasTileTexture, clampedUV);
+ }
+ gl_FragColor = finalColor;
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description();
+debug("If the test passes correctly the viewport will be green.");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("output");
+var gl = wtu.create3DContext(canvas);
+
+var createGreenTexture = function() {
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ wtu.fillTexture(gl, texture, 1, 1, [0, 255, 0, 255]);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ return texture;
+};
+
+var test = function(greenTexture) {
+ // This is a reduced test case for a problem reported by Figma.
+ // Program compilation produces the following warning/error on ANGLE's
+ // D3D9 backend:
+ // [WARNING:angle_platform_impl.cc(51)] : rx::HLSLCompiler::compileToBinary(228): C:\fakepath(26,12): error X6077: texld/texldb/texldp/dsx/dsy instructions with r# as source cannot be used inside dynamic conditional 'if' blocks, dynamic conditional subroutine calls, or loop/rep with break*.
+ //
+ // All of the operations in the shader -- including the clamping of the
+ // texture coordinates -- seem to be needed in order to provoke this
+ // error.
+ //
+ // However, this doesn't seem to produce incorrect rendering results.
+ var program = wtu.setupProgram(
+ gl,
+ ["vshaderConditionalTextureFetch",
+ "fshaderConditionalTextureFetch"],
+ ["a_position", "a_canvasTileColor", "a_texCoord"],
+ [0, 1, 2],
+ true);
+ if (!program) {
+ testFailed("Shader compilation/link failed");
+ } else {
+ // Set up buffers
+ wtu.setupUnitQuad(gl, 0, 2);
+
+ // Set up constant color (red)
+ gl.vertexAttrib4f(1, 1, 0, 0, 1);
+
+ var uniformMap = wtu.getUniformMap(gl, program);
+
+ // Use texturing
+ gl.uniform1i(uniformMap["hasTexture"].location, 1);
+
+ // Bind texture
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, greenTexture);
+ gl.uniform1i(uniformMap["canvasTileTexture"].location, 0);
+
+ // Set up (essentially no-op) clamp rectangle
+ gl.uniform4f(uniformMap["uvRect"].location, 0, 0, 0.25, 0.25);
+
+ // Draw
+ wtu.clearAndDrawUnitQuad(gl);
+
+ // Verify output
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green", 1);
+ }
+};
+
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ var tex = createGreenTexture();
+ test(tex);
+}
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/constant-precision-qualifier.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/constant-precision-qualifier.html
new file mode 100644
index 0000000000..d3628862bc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/constant-precision-qualifier.html
@@ -0,0 +1,115 @@
+<!--
+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>Bug - the precision qualifier of a constant variable should affect the precision of a consuming operation</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="fshader" type="x-shader/x-fragment">
+// It is assumed that uTest is set to 0. It's here to make the expression not constant.
+uniform mediump float uTest;
+
+void main() {
+ // exact representation of 4096.5 requires 13 bits of relative precision.
+ const highp float c = 4096.5;
+ mediump float a = 0.0;
+ // Below, addition should be evaluated at highp, since one of the operands has the highp qualifier.
+ // Thus fract should also be evaluated at highp.
+ // See OpenGL ES Shading Language spec section 4.5.2.
+ // This should make the result 0.5, since highp provides at least 16 bits of relative precision.
+ // (exceptions for operation precision are allowed for a small number of computationally
+ // intensive built-in functions, but it is reasonable to think that fract is not one of those).
+ // However, if fract() is incorrectly evaluated at minimum precision fulfilling mediump criteria,
+ // or at IEEE half float precision, the result is 0.0.
+ a = fract(c + uTest);
+
+ // Multiply by 2.0 to make the color green.
+ gl_FragColor = vec4(0.0, 2.0 * a, 0.0, 1.0);
+}
+</script>
+<script id="fshaderNoConstants" type="x-shader/x-fragment">
+// This shader has the same functionality as the one above, but it doesn't contain
+// operations that can be constant folded at compile-time.
+// It's here to provide a point of comparison.
+uniform mediump float uTest;
+uniform highp float uTestHigh;
+
+void main() {
+ highp float c = 4096.5 + uTestHigh;
+ mediump float a = 0.0;
+ a = fract(c + uTest);
+ gl_FragColor = vec4(0.0, 2.0 * a, 0.0, 1.0);
+}
+</script>
+<script id="fshaderAllHighp" type="x-shader/x-fragment">
+// This shader has the same functionality as the one above, but it only uses highp.
+// It's here to provide a point of comparison.
+uniform highp float uTest;
+
+void main() {
+ highp float c = 4096.5 + uTest;
+ highp float a = 0.0;
+ a = fract(c + uTest);
+ gl_FragColor = vec4(0.0, 2.0 * a, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+
+function test() {
+ var wtu = WebGLTestUtils;
+ var gl = wtu.create3DContext();
+ if (!gl) {
+ testFailed("context does not exist");
+ finishTest();
+ return;
+ }
+ if (gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision == 0) {
+ testPassed("highp precision not supported");
+ finishTest();
+ } else {
+ GLSLConformanceTester.runRenderTests([
+ {
+ fShaderId: 'fshader',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'The precision qualifier of a constant affects built-in function results',
+ uniforms: [{name: "uTest", functionName: "uniform1f", value: 0}]
+ },
+ {
+ fShaderId: 'fshaderNoConstants',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'The precision qualifier of a variable affects built-in function results',
+ uniforms: [{name: "uTest", functionName: "uniform1f", value: 0},
+ {name: "uTestHigh", functionName: "uniform1f", value: 0}]
+ },
+ {
+ fShaderId: 'fshaderAllHighp',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'All variables are qualified as highp',
+ uniforms: [{name: "uTest", functionName: "uniform1f", value: 0}]
+ },
+ ]);
+ }
+};
+
+test();
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/essl3-shaders-with-webgl1.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/essl3-shaders-with-webgl1.html
new file mode 100644
index 0000000000..47e58c5c92
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/essl3-shaders-with-webgl1.html
@@ -0,0 +1,138 @@
+<!--
+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>Browser bug - WebGL 1 context should not accept OpenGL ES 3 shading language shaders</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>
+<script id="ES1VertexShader" type="x-shader/x-vertex">
+precision mediump float;
+attribute vec4 aPosition;
+
+void main() {
+ gl_Position = aPosition;
+}
+</script>
+<script id="ES1FragmentShader" type="x-shader/x-fragment">
+precision mediump float;
+
+void main() {
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<!-- Note that the version directive should be on the very first line in ESSL 3, see ESSL 3 section 3.3 -->
+<script id="ES3VertexShader" type="x-shader/x-vertex">#version 300 es
+precision mediump float;
+in vec4 aPosition;
+
+void main() {
+ gl_Position = aPosition;
+}
+</script>
+<script id="ES3FragmentShader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 my_FragColor;
+
+void main() {
+ my_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script id="emptyES3FragmentShader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+void main() {
+}
+</script>
+<script id="vertexShaderWithInQualifier" type="x-shader/x-vertex">
+precision mediump float;
+in vec4 aPosition;
+
+void main() {
+ gl_Position = aPosition;
+}
+</script>
+<script id="fragmentShaderWithOutQualifier" type="x-shader/x-fragment">
+precision mediump float;
+out vec4 my_FragColor;
+
+void main() {
+ my_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("OpenGL ES 3 shading language shaders should not be accepted by WebGL 1.");
+GLSLConformanceTester.runTests([
+ {
+ vShaderId: "ES3VertexShader",
+ vShaderSuccess: false,
+ fShaderId: "ES1FragmentShader",
+ fShaderSuccess: true,
+ linkSuccess: false,
+ passMsg: "OpenGL ES 3 shading language vertex shader with an in variable should not be accepted by WebGL 1."
+ },
+ {
+ vShaderId: "ES1VertexShader",
+ vShaderSuccess: true,
+ fShaderId: "ES3FragmentShader",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "OpenGL ES 3 shading language fragment shader with an out variable should not be accepted by WebGL 1."
+ },
+ {
+ vShaderId: "ES1VertexShader",
+ vShaderSuccess: true,
+ fShaderId: "emptyES3FragmentShader",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "OpenGL ES 3 shading language fragment shader with an empty body should not be accepted by WebGL 1."
+ },
+ {
+ vShaderId: "ES3VertexShader",
+ vShaderSuccess: false,
+ fShaderId: "ES3FragmentShader",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "OpenGL ES 3 shading language shaders should not be linked by WebGL 1."
+ },
+ {
+ vShaderId: "ES3VertexShader",
+ vShaderSuccess: false,
+ fShaderId: "emptyES3FragmentShader",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "OpenGL ES 3 shading language shaders including fragment shader with empty body should not be linked by WebGL 1."
+ },
+ {
+ vShaderId: "vertexShaderWithInQualifier",
+ vShaderSuccess: false,
+ fShaderId: "ES1FragmentShader",
+ fShaderSuccess: true,
+ linkSuccess: false,
+ passMsg: "Vertex shader with an in qualifier on a global variable should not be accepted by WebGL 1."
+ },
+ {
+ vShaderId: "ES1VertexShader",
+ vShaderSuccess: true,
+ fShaderId: "fragmentShaderWithOutQualifier",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Fragment shader with an out qualifier on a global variable should not be accepted by WebGL 1."
+ }
+]);
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/floor-div-cos-should-not-truncate.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/floor-div-cos-should-not-truncate.html
new file mode 100644
index 0000000000..69a019aa1b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/floor-div-cos-should-not-truncate.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Floor + divide + cosine should not truncate intermediate results.</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script id="vshader" type="x-shader/x-vertex">
+precision highp float;
+
+attribute vec3 pos;
+
+// This divisor must be greater than the 32-bit floating point
+// representation of 1e6 / (2 * pi) to repro.
+const float magic = 159154.953125;
+
+void main(void) {
+ // This floor must be present to repro.
+ float x = floor(pos.x);
+
+ // This divide and cosine must be present to repro.
+ x = cos(x / magic);
+
+ // If the GPU truncated 'x / magic' to 0, then 'cos(x / magic)' will produce
+ // 1.0, the green square will be moved offscreen, and the red background
+ // will be visible.
+ gl_Position.x = pos.y + x * 2.0;
+ gl_Position.y = pos.z;
+ gl_Position.z = 0.0;
+ gl_Position.w = 1.0;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+precision highp float;
+
+void main(void) {
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+
+<script type="application/javascript">
+"use strict";
+description("Flooring a number, then dividing by a large number, then computing the cosine of that should not truncate the intermediate values.");
+debug("Regression test for <a href='https://code.google.com/p/angleproject/issues/detail?id=1179'>https://code.google.com/p/angleproject/issues/detail?id=1179</a>");
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas");
+var program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['pos'], undefined, true);
+
+gl.clearColor(1, 0, 0, 1);
+gl.clear(gl.COLOR_BUFFER_BIT);
+
+var magic = 159154.953125;
+var x = (Math.PI / 2.0) * magic;
+var data = [
+ x, -1, -1,
+ x, 1, -1,
+ x, 1, 1,
+ x, -1, -1,
+ x, 1, 1,
+ x, -1, 1
+];
+
+gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
+gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
+gl.enableVertexAttribArray(0);
+gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 12, 0);
+
+gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+wtu.checkCanvas(gl, [0,255,0,255], "should be 0,255,0,255");
+finishTest();
+</script>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/floored-division-accuracy.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/floored-division-accuracy.html
new file mode 100644
index 0000000000..6986344d3a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/floored-division-accuracy.html
@@ -0,0 +1,69 @@
+<!--
+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.
+-->
+
+<!-- author: Bill Baxter (wbaxter at google.com) -->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Floored Division Accuracy Bug</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+
+<script id="shader-vs" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+uniform float divisor;
+varying vec4 vColor;
+void main(void) {
+ gl_Position = vPosition;
+ float index = 9.0;
+ // Floating point operations don't have any guaranteed precision, but they
+ // should at least be accurate to 1 part in 10^5.
+ float value = floor((index / divisor) * 1.00001);
+ vColor = (value == 3.) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+}
+</script>
+
+<script id="shader-fs" type="x-shader/x-fragment">
+precision mediump float;
+varying vec4 vColor;
+void main(void) {
+ gl_FragColor = vColor;
+}
+</script>
+<script>
+"use strict";
+description();
+
+debug("");
+// Reproduces bug seen on Mac OS X with AMD Radeon HD 6490 GPU
+debug("If things are working correctly, then the square will be green.");
+debug("If your card thinks floor(9. / 3.) is not 3 to within 1 part in 10^5, ");
+debug("then the square will be red.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ vShaderId: 'shader-vs',
+ vShaderSuccess: true,
+ fShaderId: 'shader-fs',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Test that floor(9. / 3.) is 3 to within 1 part in 10^5',
+ uniforms: [{name: "divisor", functionName: "uniform1f", value: 3}]
+}
+]);
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/fragcoord-linking-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/fragcoord-linking-bug.html
new file mode 100644
index 0000000000..f22632c0a4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/fragcoord-linking-bug.html
@@ -0,0 +1,93 @@
+<!--
+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>GLSL compiler bug referencing gl_FragCoord</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<!-- These shaders were extracted from Skia's GPU accelerated backend "Ganesh". -->
+<script id="shader-vs" type="x-shader/x-vertex">
+uniform mat3 uViewM;
+uniform mat3 uStageMatrix_Stage1;
+uniform vec4 urtAdjustment;
+attribute vec2 aPosition;
+attribute vec4 aColor;
+varying vec4 vColor;
+varying vec2 vMatrixCoord_Stage1;
+void main() {
+ vec3 pos3 = uViewM * vec3(aPosition, 1);
+ vColor = aColor;
+ { // Stage 0: XferEffect
+ }
+ vMatrixCoord_Stage1 = (uStageMatrix_Stage1 * vec3(aPosition, 1)).xy;
+ { // Stage 1: Texture
+ }
+ gl_Position = vec4(dot(pos3.xz, urtAdjustment.xy), dot(pos3.yz, urtAdjustment.zw), 0, pos3.z);
+}
+</script>
+
+<script id="shader-fs" type="x-shader/x-fragment">
+precision mediump float;
+uniform sampler2D uDstCopySampler;
+uniform vec2 uDstCopyUpperLeft;
+uniform vec2 uDstCopyCoordScale;
+uniform float uRTHeight;
+uniform sampler2D uSampler0_Stage1;
+varying vec4 vColor;
+varying vec2 vMatrixCoord_Stage1;
+void main() {
+ vec4 fragCoordYDown = vec4(gl_FragCoord.x, uRTHeight - gl_FragCoord.y, gl_FragCoord.zw);
+ // Read color from copy of the destination.
+ vec2 _dstTexCoord = (fragCoordYDown.xy - uDstCopyUpperLeft) * uDstCopyCoordScale;
+ _dstTexCoord.y = 1.0 - _dstTexCoord.y;
+ vec4 _dstColor = texture2D(uDstCopySampler, _dstTexCoord);
+
+ vec4 output_Stage0;
+ { // Stage 0: XferEffect
+ // SkXfermode::Mode: Multiply
+ output_Stage0.a = vColor.a + (1.0 - vColor.a) * _dstColor.a;
+ output_Stage0.rgb = (1.0 - vColor.a) * _dstColor.rgb + (1.0 - _dstColor.a) * vColor.rgb + vColor.rgb * _dstColor.rgb;
+ }
+ vec4 output_Stage1;
+ { // Stage 1: Texture
+ output_Stage1 = texture2D(uSampler0_Stage1, vMatrixCoord_Stage1);
+ }
+ gl_FragColor = ((output_Stage0 * output_Stage1) + ((vec4(1) - output_Stage1) * _dstColor));
+}
+</script>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+description();
+debug("");
+debug('Verify shaders using gl_FragCoord z and w components compile and link correctly');
+debug('Regression test for Qualcomm bug ID CR649654');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext();
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ var program = wtu.setupProgram(gl, ["shader-vs", "shader-fs"], null, null, true);
+ if (program) {
+ testPassed("Program compiled and linked successfully");
+ } else {
+ testFailed("Program failed to compile and link");
+ }
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html
new file mode 100644
index 0000000000..ef1184d49f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>gl_FragCoord multisampling bug</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="canvasHolder"></div>
+<div id="description"></div>
+<div id="console"></div>
+
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 a_position;
+void main() {
+ gl_Position = vec4(a_position.xy, 1.0, 1.0);
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+
+void main() {
+ float depth = gl_FragCoord.z / gl_FragCoord.w;
+ gl_FragColor = vec4( 0.0, depth, 0.0, 1.0 );
+}
+</script>
+
+<script type="application/javascript">
+"use strict";
+description("gl_FragCoord multisampling bug");
+debug("Verifies gl_FragCoord z/w values are unaffected by multisampling.");
+debug('Regression test for <a href="https://github.com/mrdoob/three.js/issues/7769">Three.js Issue 7769</a>');
+var wtu = WebGLTestUtils;
+for (var ii = 0; ii < 2; ++ii) {
+ debug("Testing " + (ii > 0 ? "with" : "without") + " multisampling");
+ var canvas = document.createElement('canvas');
+ canvas.width = 256;
+ canvas.height = 256;
+ canvas.style.padding = "2px";
+ document.getElementById('canvasHolder').appendChild(canvas);
+ var options;
+ if (ii > 0) {
+ options = { antialias: true };
+ }
+ var gl = wtu.create3DContext(canvas, options);
+
+ gl.clearColor(1, 0, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ var attribBuffers = wtu.setupUnitQuad(gl, 0, 1);
+ var program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['a_position'], [0], true);
+ if (!program) {
+ testFailed("Shader compilation/link failed");
+ } else {
+ // Draw
+ wtu.drawUnitQuad(gl);
+ // Verify output
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green", 3);
+ }
+}
+
+finishTest();
+</script>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/global-invariant-does-not-leak-across-shaders.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/global-invariant-does-not-leak-across-shaders.html
new file mode 100644
index 0000000000..b02622bb29
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/global-invariant-does-not-leak-across-shaders.html
@@ -0,0 +1,77 @@
+<!--
+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>Global invariant does not leak across shaders</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="InvariantVertex" type="x-shader/x-vertex">
+#pragma STDGL invariant(all)
+
+void main()
+{
+ gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script id="Fragment" type="x-shader/x-fragment">
+precision mediump float;
+
+void main()
+{
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="VertexWithVarying" type="x-shader/x-vertex">
+varying vec2 testVarying;
+
+void main() {
+ gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
+ testVarying = vec2(0.0, 0.0);
+}
+</script>
+<script id="FragmentWithVarying" type="x-shader/x-fragment">
+precision mediump float;
+varying vec2 testVarying;
+
+void main()
+{
+ gl_FragColor = vec4(testVarying, 0.0, 1.0);
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description("The use of the global invariant pragma in one shader must not affect other shaders.");
+
+GLSLConformanceTester.runTests([
+ {
+ vShaderId: "InvariantVertex",
+ vShaderSuccess: true,
+ fShaderId: "Fragment",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Shaders using global invariant pragma should compile and link."
+ },
+ {
+ vShaderId: "VertexWithVarying",
+ vShaderSuccess: true,
+ fShaderId: "FragmentWithVarying",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Shaders not using global invariant pragma should compile and link."
+ },
+]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/if-return-and-elseif.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/if-return-and-elseif.html
new file mode 100644
index 0000000000..4e88ae83be
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/if-return-and-elseif.html
@@ -0,0 +1,65 @@
+<!--
+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>If with return and else if in fragment shader</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 pos;
+varying vec2 vPos;
+void main()
+{
+ gl_Position = pos;
+ vPos = pos.xy;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+
+varying vec2 vPos;
+void main()
+{
+ if(vPos.x < 1.0) // This colors the whole canvas green
+ {
+ gl_FragColor = vec4(0, 1, 0, 1);
+ return;
+ }
+ else if(vPos.x < 1.1) // This should have no effect
+ {
+ gl_FragColor = vec4(1, 0, 0, 1);
+ }
+}
+
+</script>
+<script type="text/javascript">
+"use strict";
+description();
+
+// Minimal test case based on report at http://anglebug.com/2325
+
+GLSLConformanceTester.runRenderTests([
+{
+ vShaderId: 'vshader',
+ vShaderSuccess: true,
+ fShaderId: 'fshader',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "If and else if in fragment shader"
+}
+]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/in-parameter-passed-as-inout-argument-and-global.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/in-parameter-passed-as-inout-argument-and-global.html
new file mode 100644
index 0000000000..77edd0ec3a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/in-parameter-passed-as-inout-argument-and-global.html
@@ -0,0 +1,52 @@
+<!--
+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>Function in parameter passed as an inout argument and a global variable with the same name</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="fshaderParameters" type="x-shader/x-fragment">
+precision mediump float;
+uniform vec3 u_zero;
+vec3 p;
+void G(inout vec3 q) {
+ p += q;
+}
+void F(in vec3 p) {
+ G(p);
+}
+void main(){
+ F(u_zero + vec3(0.0, 1.0, 0.0));
+ gl_FragColor = vec4(p, 1.0);
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description();
+
+// This is intended to test an issue seen on NVIDIA OpenGL drivers (at least up to version 388.59).
+// http://crbug.com/792210
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderParameters',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Function in parameter passed as an inout argument and a global variable with the same name"
+}
+]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/init-array-with-loop.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/init-array-with-loop.html
new file mode 100644
index 0000000000..2bd24765bd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/init-array-with-loop.html
@@ -0,0 +1,84 @@
+<!--
+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>Initializing an array with a loop test</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="fshaderInitLoop" type="x-shader/x-fragment">
+precision mediump float;
+
+void initGlobals();
+
+uniform vec4 in0;
+vec4 out0;
+
+float func(float a[4]) {
+ a[0] = -1.0;
+ return a[0];
+}
+
+float arr[4];
+
+bool isOk(vec4 a) {
+ vec4 ref = -(in0 + 1.0);
+ if (abs(a.x - ref.x) < 0.05 && abs(a.y - ref.y) < 0.05 && abs(a.z - ref.z) < 0.05 && abs(a.w - ref.w) < 0.05)
+ {
+ return true;
+ }
+ return false;
+}
+
+void main() {
+ initGlobals();
+ arr[0] = in0.x + 1.0;
+ arr[1] = in0.y + 1.0;
+ arr[2] = in0.z + 1.0;
+ arr[3] = in0.w + 1.0;
+ mediump float f = func(arr);
+ out0 = f * vec4(arr[0], arr[1], arr[2], arr[3]);
+ if (isOk(out0))
+ {
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ }
+ else
+ {
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ }
+}
+
+void initGlobals() {
+ out0 = vec4(0.0, 0.0, 0.0, 0.0);
+ for (int i = 0; i < 4; ++i)
+ {
+ arr[i] = 0.0;
+ }
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description();
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderInitLoop',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Initialize a global array using a for loop"
+}
+]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/invariant-does-not-leak-across-shaders.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/invariant-does-not-leak-across-shaders.html
new file mode 100644
index 0000000000..d203731012
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/invariant-does-not-leak-across-shaders.html
@@ -0,0 +1,74 @@
+<!--
+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>Invariant does not leak across shaders</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="InvariantVertex" type="x-shader/x-vertex">
+varying vec4 v_varying;
+invariant v_varying;
+
+void main()
+{
+ gl_Position = v_varying;
+}
+</script>
+<script id="InvariantFragment" type="x-shader/x-fragment">
+precision mediump float;
+invariant varying vec4 v_varying;
+
+void main()
+{
+ gl_FragColor = v_varying;
+}
+</script>
+<script id="VertexWithVarying" type="x-shader/x-vertex">
+varying vec4 v_varying;
+
+void main() {
+ gl_Position = v_varying;
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description("The use of the invariant qualifier in one shader must not affect other shaders.");
+
+debug("");
+debug("This is a deliberate subset of conformance/glsl/misc/shaders-with-invariance.html.");
+debug("Compared with the original tests, order of the tests is different.");
+debug("This test covers an ANGLE bug. See crbug.com/634813.");
+
+GLSLConformanceTester.runTests([
+ {
+ vShaderId: "InvariantVertex",
+ vShaderSuccess: true,
+ fShaderId: "InvariantFragment",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Shaders using invariant qualifier should compile and link."
+ },
+ {
+ vShaderId: "VertexWithVarying",
+ vShaderSuccess: true,
+ fShaderId: "InvariantFragment",
+ fShaderSuccess: true,
+ linkSuccess: false,
+ passMsg: "vertex shader with variant varying and fragment shader with invariant varying must fail"
+ },
+]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/logic-inside-block-without-braces.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/logic-inside-block-without-braces.html
new file mode 100644
index 0000000000..2bbac4dbd0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/logic-inside-block-without-braces.html
@@ -0,0 +1,86 @@
+<!--
+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>Short-circuiting logic operator with side effects inside if statement without braces should work</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="fshaderIf" type="x-shader/x-fragment">
+precision mediump float;
+uniform bool uFalse;
+
+float wrong = 0.0;
+
+bool foo() {
+ wrong += 1.0;
+ return !uFalse;
+}
+
+bool bar() {
+ return !uFalse;
+}
+
+void main() {
+ // No braces here - that can affect whether the contents of the if get parsed as a block or a statement.
+ if (uFalse)
+ foo() && bar();
+ gl_FragColor = vec4(0.0, 1.0 - wrong, 0.0, 1.0);
+}
+</script>
+<script id="fshaderFor" type="x-shader/x-fragment">
+precision mediump float;
+
+float wrong = 0.0;
+
+bool foo() {
+ wrong += 1.0;
+ return false;
+}
+
+bool bar() {
+ return false;
+}
+
+void main() {
+ // No braces here - that can affect whether the contents of the for get parsed as a block or a statement.
+ for (int i = 0; i < 0; ++i)
+ foo() && bar();
+ gl_FragColor = vec4(0.0, 1.0 - wrong, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Short-circuiting logic operator with side effects inside if/for statement without braces should work.");
+debug("");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderIf',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Short-circuiting operator inside if statement without braces',
+ uniforms: [{name: "uFalse", functionName: "uniform1i", value: 0}]
+},
+{
+ fShaderId: 'fshaderFor',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Short-circuiting operator inside for statement without braces'
+}
+]);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/long-expressions-should-not-crash.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/long-expressions-should-not-crash.html
new file mode 100644
index 0000000000..eaf0509b23
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/long-expressions-should-not-crash.html
@@ -0,0 +1,136 @@
+<!--
+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>Driver Bug - long experssions should not crash</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<canvas id="example" width="40" height="40"> </canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+void main(){
+ gl_Position = vec4(0, 0, 0, 1);
+}
+</script>
+<script id="vshaderUniformTest" type="x-shader/x-vertex">
+uniform vec4 u_uniform;
+void main(){
+ gl_Position =
+ $(code)
+ vec4(0, 0, 0, 1);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+void main()
+{
+ gl_FragColor = vec4(0, 0, 0, 0);
+}
+</script>
+<script id="fshaderUniformTest" type="x-shader/x-fragment">
+precision mediump float;
+uniform vec4 u_uniform;
+void main()
+{
+ gl_FragColor =
+ $(code)
+ vec4(0, 0, 0, 0);
+}
+</script>
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext();
+
+var vUniformTestSource = wtu.getScript("vshaderUniformTest");
+var fUniformTestSource = wtu.getScript("fshaderUniformTest");
+
+var tests = [
+];
+var counts = [
+ { count:10,
+ mustPass: true,
+ },
+ { count:100,
+ mustPass: true,
+ },
+ { count: 1000,
+ mustPass: false,
+ },
+ { count: 10000,
+ mustPass: false,
+ },
+];
+var operatorSets = [
+ ["+", "-", "/", "*"],
+ ["+"],
+ ["-"],
+];
+counts.forEach(function(info) {
+ operatorSets.forEach(function(operators) {
+ var generateCode = function(numVars) {
+ var codes = [];
+ for (var uu = 0; uu < numVars; ++uu) {
+ codes.push("u_uniform " + operators[uu % operators.length]);
+ }
+ return {
+ code: codes.join("\n "),
+ };
+ };
+
+ var subs = generateCode(info.count);
+ tests.push({
+ vShaderId: "vshader",
+ vShaderSuccess: true,
+ fShaderSource: wtu.replaceParams(fUniformTestSource, subs),
+ fShaderSuccess: true,
+ linkSuccess: true,
+ ignoreResults: !info.mustPass,
+ passMsg: "shader with " + info.count + " [" + operators + "] operators in expression in multiple lines",
+ });
+ tests.push({
+ vShaderSource: wtu.replaceParams(vUniformTestSource, subs),
+ vShaderSuccess: true,
+ fShaderId: "fshader",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ ignoreResults: !info.mustPass,
+ passMsg: "shader with " + info.count + " [" + operators + "] operators in expression in multiple lines",
+ });
+ subs.code = subs.code.replace(/\n /g, "")
+ tests.push({
+ vShaderId: "vshader",
+ vShaderSuccess: true,
+ fShaderSource: wtu.replaceParams(fUniformTestSource, subs),
+ fShaderSuccess: true,
+ linkSuccess: true,
+ ignoreResults: !info.mustPass,
+ passMsg: "shader with " + info.count + " [" + operators + "] operators in expression in one line",
+ });
+ tests.push({
+ vShaderSource: wtu.replaceParams(vUniformTestSource, subs),
+ vShaderSuccess: true,
+ fShaderId: "fshader",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ ignoreResults: !info.mustPass,
+ passMsg: "shader with " + info.count + " [" + operators + "] operators in expression in one line",
+ });
+ });
+});
+GLSLConformanceTester.runTests(tests);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/loop-if-loop-gradient.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/loop-if-loop-gradient.html
new file mode 100644
index 0000000000..914604ad07
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/loop-if-loop-gradient.html
@@ -0,0 +1,75 @@
+<!--
+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>Gradient loop in if in loop crash</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script id='vshader' type='x-shader/x-vertex'>
+precision highp float;
+void main() {
+gl_Position = vec4( 1.0, 1.0, 1.0, 1.0 );
+}
+</script>
+<script id='fshader' type='x-shader/x-fragment'>
+precision mediump float;
+uniform lowp sampler2D iChannel0;
+
+void main(){
+ highp float c;
+ for (mediump float i = 0.0; i <= 1.0; i++) {
+ if (gl_FragCoord.x < 0.0) {
+ for (mediump float l = 0.0; l < 2.0; l++) { // with 1 as a bound it works
+ c = texture2D(iChannel0, vec2(l), 0.0).x;
+ }
+ }
+ }
+ gl_FragColor = vec4(c, vec3(1.0));
+}
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test checks an ANGLE regression that was caused by a complex ShaderToy shader. <a href='https://code.google.com/p/chromium/issues/detail?id=524297'>crbug.com/524297</a>");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext();
+
+gl.canvas.addEventListener("webglcontextlost", function(e) {
+ testFailed("WebGL context lost");
+});
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ debug("");
+
+ var program = wtu.setupProgram(gl, ['vshader', 'fshader']);
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
+ testFailed("Program failed to link");
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+// Cycle through a rAF once to give any webglcontextlost events a chance to propagate
+window.requestAnimationFrame(function() { finishTest(); });
+
+debug("");
+var successfullyParsed = true;
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/modulo-arithmetic-accuracy.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/modulo-arithmetic-accuracy.html
new file mode 100644
index 0000000000..6e39f69ab7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/modulo-arithmetic-accuracy.html
@@ -0,0 +1,68 @@
+<!--
+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.
+-->
+
+<!-- author: Bill Baxter (wbaxter at google.com) -->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Modulo Arithmetic Accuracy Bug</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+
+<script id="shader-vs" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+uniform float divisor;
+varying vec4 vColor;
+void main(void) {
+ gl_Position = vPosition;
+ float index = 9.0;
+ // mod(x, y) is computed as x-y*floor(x/y). There are no guarantees on
+ // the precision of floating point operations in WebGL shaders, but division
+ // should be accurate to at least 1 part in 10^5.
+ float value = mod(index * 1.00001, divisor);
+ vColor = (value < 1.) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+}
+</script>
+
+<script id="shader-fs" type="x-shader/x-fragment">
+precision mediump float;
+varying vec4 vColor;
+void main(void) {
+ gl_FragColor = vColor;
+}
+</script>
+<script>
+"use strict";
+
+description();
+debug("");
+// Reproduces bug seen on Mac OS X with AMD Radeon HD 6490 GPU
+debug("If things are working correctly, then the square will be green.");
+debug("If your card thinks mod(9,3) is not 0, then the square will be red.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ vShaderId: 'shader-vs',
+ vShaderSuccess: true,
+ fShaderId: 'shader-fs',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Test that mod(9/3) is 0',
+ uniforms: [{name: "divisor", functionName: "uniform1f", value: 3}]
+}
+]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/multiplication-assignment.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/multiplication-assignment.html
new file mode 100644
index 0000000000..cb157cdec6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/multiplication-assignment.html
@@ -0,0 +1,50 @@
+<!--
+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>Multiplication assignment operator compilation bug</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform mat3 rot;
+float foo(vec3 bar) {
+ bar *= rot;
+ return 0.0;
+}
+
+void main(void){
+ gl_FragColor = vec4(foo(vec3(0)));
+}
+</script>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+description();
+debug("");
+debug('Verify multiplication assignment operator compiles correctly - regression test for <a href="https://code.google.com/p/chromium/issues/detail?id=384847">Chromium bug 384847</a>');
+
+GLSLConformanceTester.runTests([
+{
+ fShaderId: 'fshader',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "vec3 *= mat3 multiplication assignment operator",
+}
+]);
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/nested-functions-should-not-crash.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/nested-functions-should-not-crash.html
new file mode 100644
index 0000000000..130f0a0e4f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/nested-functions-should-not-crash.html
@@ -0,0 +1,89 @@
+<!--
+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>Driver Bug - nested functions should not crash</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<canvas id="example" width="40" height="40"> </canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+void main(){
+ gl_Position = vec4(0, 0, 0, 1);
+}
+</script>
+<script id="fshaderUniformTest" type="x-shader/x-fragment">
+precision mediump float;
+uniform vec4 u_uniform;
+
+$(code)
+
+void main()
+{
+ gl_FragColor = function0();
+}
+</script>
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext();
+
+var fUniformTestSource = wtu.getScript("fshaderUniformTest");
+
+var tests = [
+];
+var counts = [
+ { count:10,
+ mustPass: true,
+ },
+ { count:100,
+ mustPass: false,
+ },
+ { count: 1000,
+ mustPass: false,
+ },
+ { count: 10000,
+ mustPass: false,
+ },
+];
+var operators = ["+", "-", "/", "*"];
+counts.forEach(function(info) {
+ var generateCode = function(numVars) {
+ var codes = [];
+ codes.push("vec4 function" + numVars + "() { return u_uniform; }");
+ for (var uu = 0; uu < numVars; ++uu) {
+ var id = numVars - uu - 1;
+ codes.push("vec4 function" + id + "() { return function" + (id + 1) + "(); }");
+ }
+ return {
+ code: codes.join("\n\n"),
+ };
+ };
+
+ var subs = generateCode(info.count);
+ tests.push({
+ vShaderId: "vshader",
+ vShaderSuccess: true,
+ fShaderSource: wtu.replaceParams(fUniformTestSource, subs),
+ fShaderSuccess: true,
+ linkSuccess: true,
+ ignoreResults: !info.mustPass,
+ passMsg: "shader with " + info.count + " nested functions",
+ });
+});
+GLSLConformanceTester.runTests(tests);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/nested-loops-with-break-and-continue.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/nested-loops-with-break-and-continue.html
new file mode 100644
index 0000000000..d6a744741a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/nested-loops-with-break-and-continue.html
@@ -0,0 +1,83 @@
+<!--
+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>Using nested loops with break and/or continue statements in a fragment shader should work</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css" />
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec3 aPosition;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform int uCount;
+
+void main() {
+ int a = 0;
+ for (int i = 0; i < 10; ++i) {
+ if (i >= uCount) { break; }
+ for (int j = 0; j < 10; ++j) {
+ if (j >= uCount) { continue; }
+ a += 1;
+ }
+ for (int j = 0; j < 10; ++j) {
+ if (j >= uCount) { break; }
+ a += 1;
+ }
+ for (int j = 0; j < 10; ++j) {
+ if (j >= uCount) { continue; }
+ a += 1;
+ }
+ for (int j = 0; j < 10; ++j) {
+ if (j >= uCount) { break; }
+ a += 1;
+ }
+ for (int j = 0; j < 10; ++j) {
+ if (j >= uCount) { continue; }
+ a += 1;
+ }
+ }
+ float b = (float(a) / 125.0) * (64.0 / 255.0);
+ gl_FragColor = vec4(b, 1.0 - b, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Multiple loops using break and continue statements should work.");
+debug("");
+var wtu = WebGLTestUtils;
+function test() {
+ var gl = wtu.create3DContext("canvas");
+ if (!gl) {
+ testFailed("context does not exist");
+ return;
+ }
+ wtu.setupUnitQuad(gl);
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["aPosition"], undefined, true);
+ var uniformLoc = gl.getUniformLocation(program, 'uCount');
+ gl.uniform1i(uniformLoc, 5);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvas(gl, [64, 191, 0, 255], "should be 64,191,0,255");
+};
+
+test();
+finishTest();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/nested-sequence-operator.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/nested-sequence-operator.html
new file mode 100644
index 0000000000..b202b854ff
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/nested-sequence-operator.html
@@ -0,0 +1,47 @@
+<!--
+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>Nested sequence operator</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="fshaderNestedSequenceOperator" type="x-shader/x-fragment">
+precision mediump float;
+// Note that keep_flop_positive is expected to keep its default value false.
+uniform bool keep_flop_positive;
+float flop;
+void main()
+{
+ flop = -1.0,
+ (flop *= -1.0,
+ keep_flop_positive ? 0.0 : flop *= -1.0),
+ gl_FragColor = vec4(0, -flop, 0, 1);
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description("Test a nested sequence operator with a ternary operator inside. The ternary operator needs to be converted into an if statement on a HLSL based WebGL backend, which makes this case tricky.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderNestedSequenceOperator',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Nested sequence operator is evaluated in the expected order."
+}
+]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/pow-of-small-constant-in-user-defined-function.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/pow-of-small-constant-in-user-defined-function.html
new file mode 100644
index 0000000000..d5fa55b898
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/pow-of-small-constant-in-user-defined-function.html
@@ -0,0 +1,74 @@
+<!--
+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>Bug - calculating powers of constants smaller than 1.0e-5 in user-defined functions should work</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec3 aPosition;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">
+precision highp float;
+
+float fun(float arg) {
+ // These values are still easily within the highp range.
+ // The minimum range in terms of 10's exponent is around -19 to 19, and IEEE-754 single precision range is higher than that.
+ return 1.0e12 * pow(arg, 2.0);
+}
+
+void main() {
+ // Note that the bug did not reproduce if an uniform was passed to the function instead of a constant,
+ // or if the expression was moved outside the user-defined function.
+ const float a = 1.0e-6;
+ float b = fun(a);
+ if (abs(b - 1.0) < 0.01) {
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); // green
+ } else {
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // red
+ }
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+debug("");
+var wtu = WebGLTestUtils;
+function test() {
+ var gl = wtu.create3DContext("canvas");
+ if (!gl) {
+ testFailed("context does not exist");
+ return;
+ }
+ if (gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision == 0) {
+ testPassed("highp precision not supported");
+ } else {
+ wtu.setupUnitQuad(gl);
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["aPosition"], undefined, true);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 0, 0, 256, 256, [0, 255, 0, 255]);
+ }
+};
+
+test();
+finishTest();
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/pow-with-constant-exponent-should-not-crash.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/pow-with-constant-exponent-should-not-crash.html
new file mode 100644
index 0000000000..8e95842b12
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/pow-with-constant-exponent-should-not-crash.html
@@ -0,0 +1,65 @@
+<!--
+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>Bug - pow() with constant vector exponent should not crash</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="fshaderTest" type="x-shader/x-fragment">
+precision mediump float;
+void main()
+{
+ // pow() with a constant vector exponent may cause a crash on NVIDIA 331 series OpenGL drivers
+ vec2 v = pow(gl_FragCoord.xy, vec2(2.0));
+ float y = pow(v, vec2(0.45, 0.5)).y;
+ gl_FragColor = vec4(0.0, 1.0 + y - gl_FragCoord.y, 0.0, 1.0);
+}
+</script>
+<script id="fshaderNestedTest" type="x-shader/x-fragment">
+precision mediump float;
+void main()
+{
+ // pow() with a constant vector exponent may cause a crash on NVIDIA 331 series OpenGL drivers
+ // workarounds for this should work even if problematic pow() statements are nested within
+ // each other.
+ float y = pow(pow(gl_FragCoord.xy, vec2(2.0)), vec2(0.45, 0.5)).y;
+ gl_FragColor = vec4(0.0, 1.0 + y - gl_FragCoord.y, 0.0, 1.0);
+}
+</script>
+<script>
+"use strict";
+
+// This test has quite a lot of tolerance since pow() doesn't have explicit precision requirements
+// in ESSL1, and in ESSL3 the limits are very loose.
+GLSLConformanceTester.runRenderTests([
+ {
+ fShaderId: "fshaderTest",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ renderTolerance: 20,
+ passMsg: "shader with pow() with a constant vector exponent should not crash",
+ },
+ {
+ fShaderId: "fshaderNestedTest",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ renderTolerance: 20,
+ passMsg: "shader with nested pow() calls with constant vector exponents should not crash",
+ }
+]);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/qualcomm-crash.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/qualcomm-crash.html
new file mode 100644
index 0000000000..f1ef1e47ab
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/qualcomm-crash.html
@@ -0,0 +1,136 @@
+<!--
+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>Qualcomm program link crash Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script id='vshader1' type='x-shader/x-vertex'>
+precision highp float;
+void main() {
+gl_Position = vec4( 1.0, 1.0, 1.0, 1.0 );
+}
+</script>
+<script id='fshader1' type='x-shader/x-fragment'>
+precision highp float;
+uniform int renderType;
+uniform sampler2D texMap;
+void main() {
+ vec2 uv = vec2(0.0, 0.0);
+ if( renderType == 0 ) {
+ gl_FragColor = texture2D( texMap, uv );
+ } else {
+ vec4 texture = texture2D( texMap, uv );
+ gl_FragColor = texture;
+ }
+}
+</script>
+
+<script id='vshader2' type='x-shader/x-vertex'>
+attribute vec3 vertex_position;
+uniform mat4 matrix_model;
+uniform mat4 matrix_viewProjection;
+
+attribute vec4 vertex_boneWeights;
+attribute vec4 vertex_boneIndices;
+
+uniform sampler2D texture_poseMap;
+uniform vec2 texture_poseMapSize;
+
+mat4 getBoneMatrix(const in float i)
+{
+ float j = i * 4.0;
+ float x = mod(j, float(texture_poseMapSize.x));
+ float y = floor(j / float(texture_poseMapSize.x));
+
+ float dx = 1.0 / float(texture_poseMapSize.x);
+ float dy = 1.0 / float(texture_poseMapSize.y);
+
+ y = dy * (y + 0.5);
+
+ vec4 v1 = texture2D(texture_poseMap, vec2(dx * (x + 0.5), y));
+ vec4 v2 = texture2D(texture_poseMap, vec2(dx * (x + 1.5), y));
+ vec4 v3 = texture2D(texture_poseMap, vec2(dx * (x + 2.5), y));
+ vec4 v4 = texture2D(texture_poseMap, vec2(dx * (x + 3.5), y));
+
+ mat4 bone = mat4(v1, v2, v3, v4);
+
+ return bone;
+}
+
+void main(void)
+{
+ mat4 modelMatrix = vertex_boneWeights.x * getBoneMatrix(vertex_boneIndices.x) +
+ vertex_boneWeights.y * getBoneMatrix(vertex_boneIndices.y) +
+ vertex_boneWeights.z * getBoneMatrix(vertex_boneIndices.z) +
+ vertex_boneWeights.w * getBoneMatrix(vertex_boneIndices.w);
+
+ vec4 positionW = modelMatrix * vec4(vertex_position, 1.0);
+ gl_Position = matrix_viewProjection * positionW;
+
+}
+</script>
+<script id='fshader2' type='x-shader/x-fragment'>
+precision highp float;
+void main() {
+ gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 );
+}
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test checks a known bug in some Qualcomm drivers which causes crashes when linking certain shaders. <a href='https://code.google.com/p/chromium/issues/detail?id=498947'>crbug.com/498947</a>");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext();
+
+gl.canvas.addEventListener("webglcontextlost", function(e) {
+ testFailed("WebGL context lost");
+});
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ debug("");
+
+ if (gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision == 0) {
+ testPassed("highp precision not supported");
+ } else {
+ var program1 = wtu.setupProgram(gl, ['vshader1', 'fshader1']);
+ if (!gl.getProgramParameter(program1, gl.LINK_STATUS)) {
+ testFailed("Program failed to link");
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+
+ debug("");
+
+ var program2 = wtu.setupProgram(gl, ['vshader2', 'fshader2']);
+ if (!gl.getProgramParameter(program2, gl.LINK_STATUS)) {
+ testFailed("Program failed to link");
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+ }
+}
+
+// Cycle through a rAF once to give any webglcontextlost events a chance to propagate
+window.requestAnimationFrame(function() { finishTest(); });
+
+debug("");
+var successfullyParsed = true;
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/qualcomm-loop-with-continue-crash.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/qualcomm-loop-with-continue-crash.html
new file mode 100644
index 0000000000..ff94c52268
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/qualcomm-loop-with-continue-crash.html
@@ -0,0 +1,71 @@
+<!--
+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>Qualcomm loop with continue crash test</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script id='vshader1' type='x-shader/x-vertex'>
+void main ()
+{
+}
+</script>
+<script id='fshader1' type='x-shader/x-fragment'>
+void main ()
+{
+ int count1 = 0, count2 = 0;
+ for(int i=0;i<4;i++)
+ {
+ if(count1 == 2)
+ continue;
+ }
+}
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test exercises a crash on Adreno 300 series GPUs when compiling certain loop constructs. <a href='https://code.google.com/p/chromium/issues/detail?id=527761'>crbug.com/527761</a>");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext();
+
+gl.canvas.addEventListener("webglcontextlost", function(e) {
+ testFailed("WebGL context lost");
+});
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ debug("");
+
+ var program1 = wtu.setupProgram(gl, ['vshader1', 'fshader1']);
+ if (!gl.getProgramParameter(program1, gl.LINK_STATUS)) {
+ testFailed("Program failed to link");
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+
+ debug("");
+}
+
+// Cycle through a rAF once to give any webglcontextlost events a chance to propagate
+window.requestAnimationFrame(function() { finishTest(); });
+
+debug("");
+var successfullyParsed = true;
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sampler-array-struct-function-arg.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sampler-array-struct-function-arg.html
new file mode 100644
index 0000000000..b39179a186
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sampler-array-struct-function-arg.html
@@ -0,0 +1,72 @@
+<!--
+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>GLSL struct containing an array of samplers passed into a user-defined function</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+
+<canvas id="output" style="border: none;" width="64" height="64"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderSampler" type="x-shader/x-fragment">
+precision mediump float;
+
+struct S {
+ sampler2D sam[2];
+};
+
+uniform S uni;
+
+vec4 useSampler(S arg)
+{
+ return texture2D(arg.sam[0], vec2(0.0, 0.0));
+}
+
+void main() {
+ gl_FragColor = vec4(useSampler(uni));
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("output");
+var gl = wtu.create3DContext(canvas);
+
+if (!gl) {
+ testFailed("Could not create a GL context.");
+} else {
+ debug("Drawing with a shader that uses a sampler array in a struct passed into a function.");
+ var program = wtu.setupProgram(
+ gl, [wtu.simpleVertexShader, 'fshaderSampler'], ['a_position'], [0], true);
+ wtu.setupUnitQuad(gl);
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ wtu.fillTexture(gl, tex, 1, 1, [0, 255, 0, 255]);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sampler-array-using-loop-index.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sampler-array-using-loop-index.html
new file mode 100644
index 0000000000..c5707a1f89
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sampler-array-using-loop-index.html
@@ -0,0 +1,81 @@
+<!--
+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>Sampler arrays using loop index should compile fine.</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"> </script>
+</head>
+<body>
+<canvas id="example" width="4" height="4" style="width: 40px; height: 30px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+void main()
+{
+ gl_Position = vPosition;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform sampler2D uni[2];
+
+float zero(int x)
+{
+ return float(x) - float(x);
+}
+
+void main()
+{
+ vec4 c = vec4(0,0,0,0);
+ for (int ii = 1; ii < 3; ++ii) {
+ if (c.x > 255.0) {
+ c.x = 255.0 + zero(ii);
+ break;
+ }
+ c += texture2D(uni[ii - 1], vec2(0.5, 0.5));
+ }
+ gl_FragColor = c;
+}
+</script>
+<script>
+"use strict";
+description(document.title);
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example");
+var program = wtu.setupTexturedQuad(gl);
+
+//------------------------------------------------------------------------------
+var program = wtu.setupProgram(
+ gl, ['vshader', 'fshader'], ['vPosition'], undefined, true);
+
+for (var ii = 0; ii < 2; ++ii) {
+ var loc = gl.getUniformLocation(program, "uni[" + ii + "]");
+ gl.activeTexture(gl.TEXTURE0 + ii);
+ var tex = gl.createTexture();
+ wtu.fillTexture(gl, tex, 1, 1, [32, 16, 8, ii * 9], 0);
+ gl.uniform1i(loc, ii);
+}
+
+wtu.clearAndDrawUnitQuad(gl);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+wtu.checkCanvas(gl, [64, 32, 16, 9],
+ "Should render correctly", 1);
+
+var successfullyParsed = true;
+
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sampler-struct-function-arg.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sampler-struct-function-arg.html
new file mode 100644
index 0000000000..f2bc755444
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sampler-struct-function-arg.html
@@ -0,0 +1,113 @@
+<!--
+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>Passing a struct containing a sampler to a function.</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+
+<body>
+<canvas id="output" style="border: none;" width="64" height="64"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script id="shader-fs" type="x-shader/x-fragment">
+ precision mediump float;
+
+ struct SomeStruct{
+ sampler2D source;
+ };
+
+ vec4 fun(SomeStruct s){
+ return texture2D(s.source, vec2(0.5));
+ }
+
+ uniform SomeStruct green;
+ void main(){
+ gl_FragColor = fun(green);
+ }
+</script>
+
+<script id="shader-fs-array" type="x-shader/x-fragment">
+ precision mediump float;
+
+ struct SomeStruct{
+ sampler2D source;
+ };
+
+ vec4 fun(SomeStruct s[2]){
+ return texture2D(s[0].source, vec2(0.5));
+ }
+
+ uniform SomeStruct green[2];
+ void main(){
+ gl_FragColor = fun(green);
+ }
+</script>
+
+<script>
+"use strict";
+
+description();
+debug("If the test passes correctly the viewport will be green.");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("output");
+var gl = wtu.create3DContext(canvas);
+
+var textureGreen;
+
+var createGreenTexture = function() {
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ wtu.fillTexture(gl, texture, 1, 1, [0, 255, 0, 255]);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ return texture;
+};
+
+var test = function(fragShaderId, texUniformName) {
+ var program = wtu.setupProgram(gl, [wtu.simpleVertexShader, fragShaderId], ["a_position"], [0], true);
+
+ if (!program) {
+ testFailed("Shader compilation/link failed");
+ } else {
+ // Bind texture
+ var uniformMap = wtu.getUniformMap(gl, program);
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, textureGreen);
+ gl.uniform1i(uniformMap[texUniformName].location, 0);
+
+ // Draw
+ wtu.clearAndDrawUnitQuad(gl);
+
+ // Verify output
+ wtu.checkCanvasRect(gl, 0, 128, 256, 128, [0, 255,0, 255], "should be green", 1);
+ }
+};
+
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ wtu.setupUnitQuad(gl, 0, 1);
+ textureGreen = createGreenTexture();
+ test("shader-fs", "green.source");
+ test("shader-fs-array", "green[0].source");
+}
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sequence-operator-evaluation-order.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sequence-operator-evaluation-order.html
new file mode 100644
index 0000000000..7e9af6f1aa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sequence-operator-evaluation-order.html
@@ -0,0 +1,116 @@
+<!--
+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>GLSL short-circuiting operators should be evaluated after previous operands in a sequence</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<canvas id="canvas" width="64" height="64"> </canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderSequenceSideEffectsAffectTernary" type="x-shader/x-fragment">
+precision mediump float;
+
+bool correct = true;
+
+uniform float u_zero;
+
+float wrong() {
+ correct = false;
+ return 0.0;
+}
+
+void main() {
+ // ESSL 1.00 section 5.9, about sequence operator:
+ // "All expressions are evaluated, in order, from left to right"
+ // Also use a ternary operator where the third operand has side effects to make sure
+ // only the second operand is evaluated.
+ float a = u_zero - 0.5; // Result should be -0.5.
+ float green = (a++, a > 0.0 ? 1.0 : wrong());
+ gl_FragColor = vec4(0.0, correct ? green : 0.0, 0.0, 1.0);
+}
+</script>
+<script id="fshaderSequenceSideEffectsAffectAnd" type="x-shader/x-fragment">
+precision mediump float;
+
+uniform bool u_false;
+
+bool sideEffectA = false;
+bool funcA() {
+ sideEffectA = true;
+ return true;
+}
+
+bool sideEffectB = false;
+bool funcB() {
+ sideEffectB = true;
+ return true;
+}
+
+void main() {
+ bool b = (funcA(), u_false == sideEffectA && funcB());
+ gl_FragColor = (!b && sideEffectA && !sideEffectB) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+}
+</script>
+<script id="fshaderSequenceSideEffectsAffectOr" type="x-shader/x-fragment">
+precision mediump float;
+
+uniform bool u_false;
+
+bool sideEffectA = false;
+bool funcA() {
+ sideEffectA = true;
+ return false;
+}
+
+bool sideEffectB = false;
+bool funcB() {
+ sideEffectB = true;
+ return false;
+}
+
+void main() {
+ bool b = (funcA(), (u_false == !sideEffectA) || funcB());
+ gl_FragColor = (b && sideEffectA && !sideEffectB) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+debug("");
+debug("This test is targeted to stress syntax tree transformations that might need to be done in shader translation to unfold operators.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderSequenceSideEffectsAffectTernary',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Expression where first operand of a sequence operator has side effects which affect the second operand that is a ternary operator'
+},
+{
+ fShaderId: 'fshaderSequenceSideEffectsAffectAnd',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Expression where first operand of a sequence operator has side effects which affect the second operand that is an and operator'
+},
+{
+ fShaderId: 'fshaderSequenceSideEffectsAffectOr',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Expression where first operand of a sequence operator has side effects which affect the second operand that is an or operator'
+}
+]);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sketchfab-lighting-shader-crash.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sketchfab-lighting-shader-crash.html
new file mode 100644
index 0000000000..73416d17de
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sketchfab-lighting-shader-crash.html
@@ -0,0 +1,84 @@
+<!--
+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>Sketchfab Lighting Shader Crash</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script id='vshader1' type='x-shader/x-vertex'>
+attribute float testValue; // Can be uniform as well.
+varying mediump float FragVarying; // Necessary to reproduce.
+
+void main() {
+ // Crashes with mat4 as well. Does not crash with vectors.
+ mat2 projectionMatrix = mat2(0.0, 0.0, 0.0, 0.0);
+ if (testValue == 1.0)
+ {
+ // Using the matrix variable appears necessary.
+ projectionMatrix[0][0] = 1.0;
+ }
+
+ FragVarying = 0.0;
+ // Referencing the matrix is necessary though clearly the compiler
+ // doesn't realize the assignment is useless.
+ gl_Position = vec4(projectionMatrix[1][0], 0.0, 0.0, 1.0);
+}
+</script>
+<script id='fshader1' type='x-shader/x-fragment'>
+precision mediump float;
+varying float FragVarying;
+
+void main() {
+ gl_FragColor = vec4(FragVarying, 0.0, 0.0, 1.0);
+}
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test demonstrates a crash on the Nexus 5 (Adreno 330) when compiling Sketchfab's lighting shader. <a href='https://code.google.com/p/chromium/issues/detail?id=551937'>crbug.com/551937</a>");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext();
+
+gl.canvas.addEventListener("webglcontextlost", function(e) {
+ testFailed("WebGL context lost");
+});
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ debug("");
+
+ var program1 = wtu.setupProgram(gl, ['vshader1', 'fshader1']);
+ if (!gl.getProgramParameter(program1, gl.LINK_STATUS)) {
+ testFailed("Program failed to link");
+ } else {
+ testPassed("Program linked successfully");
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+
+ debug("");
+}
+
+// Cycle through rAF a few times to give any webglcontextlost events a chance to propagate.
+wtu.waitForComposite(function() { finishTest(); });
+
+debug("");
+var successfullyParsed = true;
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/struct-constructor-highp-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/struct-constructor-highp-bug.html
new file mode 100644
index 0000000000..afb72e1916
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/struct-constructor-highp-bug.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Struct constructor highp bug.</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="fshader" type="x-shader/x-fragment">
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+
+struct Test {
+ vec3 color;
+};
+
+void main() {
+ vec3 color = vec3( 0.0, 1.0, 0.0 );
+ Test test = Test( color );
+ gl_FragColor = vec4( test.color, 1.0 );
+}
+</script>
+
+<script type="application/javascript">
+"use strict";
+description("Struct constructors should evaluate properly.");
+debug("Regression test for Three.js bug worked around in <a href='https://github.com/mrdoob/three.js/pull/7556'>https://github.com/mrdoob/three.js/pull/7556</a> that reproduced on Nexus 4 and 5 (Adreno 320 and 330).");
+debug("When high precision is used in the fragment shader on these devices, bugs occur in evaluation of structs' constructors. Thanks to Mr. doob for the reduced test case.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshader',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Struct contstructor evaluation"
+}
+]);
+
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/struct-with-single-member-constructor.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/struct-with-single-member-constructor.html
new file mode 100644
index 0000000000..8d1008326f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/struct-with-single-member-constructor.html
@@ -0,0 +1,52 @@
+<!--
+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>GLSL struct with a single member constructor test</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="fshader" type="x-shader/x-fragment">
+#version 100
+
+precision mediump float;
+
+struct S {
+ mat2 rotation;
+};
+void main(void)
+{
+ float angle = 1.0;
+ S(mat2(1.0, angle, 1.0, 1.0));
+}
+</script>
+<script>
+"use strict";
+description();
+debug("This is a regression test for <a href='https://bugs.chromium.org/p/swiftshader/issues/detail?id=56'>Swiftshader bug 56</a>.");
+debug("");
+
+GLSLConformanceTester.runTests([
+{
+ fShaderId: 'fshader',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Construct a struct with a single matrix member"
+}
+]);
+
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/temp-expressions-should-not-crash.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/temp-expressions-should-not-crash.html
new file mode 100644
index 0000000000..c28db1daad
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/temp-expressions-should-not-crash.html
@@ -0,0 +1,100 @@
+<!--
+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>Driver Bug - temp experssions should not crash</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<canvas id="example" width="40" height="40"> </canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+void main(){
+ gl_Position = vec4(0, 0, 0, 1);
+}
+</script>
+<script id="fshaderUniformTest" type="x-shader/x-fragment">
+precision mediump float;
+uniform vec4 u_uniform;
+void main()
+{
+ vec4 temp = vec4(0, 0, 0, 0);
+$(code)
+ gl_FragColor = temp;
+}
+</script>
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext();
+
+var fUniformTestSource = wtu.getScript("fshaderUniformTest");
+
+var tests = [
+];
+var counts = [
+ { count:100,
+ mustPass: true,
+ },
+ { count: 1000,
+ mustPass: false,
+ },
+ { count: 10000,
+ mustPass: false,
+ },
+];
+var operators = ["+", "-", "/", "*"];
+counts.forEach(function(info) {
+ var generateCode = function(numVars) {
+ var codes = [];
+ var count = 0;
+ var step = 10;
+ for (var uu = 0; uu < numVars; uu += step) {
+ var subCodes = [""];
+ for (var vv = 0; vv < step; ++vv) {
+ subCodes.push(operators[(count++) % operators.length]);
+ }
+ subCodes.push("");
+ codes.push(" temp += " + subCodes.join("\n u_uniform ") + ";");
+ }
+ return {
+ code: codes.join("\n"),
+ };
+ };
+
+ var subs = generateCode(info.count);
+ tests.push({
+ vShaderId: "vshader",
+ vShaderSuccess: true,
+ fShaderSource: wtu.replaceParams(fUniformTestSource, subs),
+ fShaderSuccess: true,
+ linkSuccess: true,
+ ignoreResults: !info.mustPass,
+ passMsg: "shader with uniform with " + info.count + " operators in temp expressions in multiple lines",
+ });
+ subs.code = subs.code.replace(/\n +/g, " ")
+ tests.push({
+ vShaderId: "vshader",
+ vShaderSuccess: true,
+ fShaderSource: wtu.replaceParams(fUniformTestSource, subs),
+ fShaderSuccess: true,
+ linkSuccess: true,
+ ignoreResults: !info.mustPass,
+ passMsg: "shader with uniform with " + info.count + " operators in temp expressions in one line",
+ });
+});
+GLSLConformanceTester.runTests(tests);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/unary-minus-operator-float-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/unary-minus-operator-float-bug.html
new file mode 100644
index 0000000000..85f7231444
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/unary-minus-operator-float-bug.html
@@ -0,0 +1,49 @@
+<!--
+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>GLSL unary minus operator with float bug Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+void main () {
+ float f = -1.0;
+ // atan(tan(0.5), -f) is in range [1.5707, 1.5708) on Mac OSX 10.11 with Intel GPU.
+ // But it should be 0.5.
+ gl_FragColor = vec4(atan(tan(0.5), -f), 0.0, 0.0, 1.0);
+}
+</script>
+<script>
+"use strict";
+description("Test for unary minus operator with float bug on MacOSX 10.11 with Intel GPU");
+debug("This is a regression test for <a href='https://bugs.chromium.org/p/chromium/issues/detail?id=308366'>Chromium Issue 308366</a>");
+debug("");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshader',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Evaluate unary minus operator and atan(x, y)",
+ renderTolerance: 3,
+ renderColor: [127, 0, 0, 255]
+}
+]);
+
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/undefined-index-should-not-crash.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/undefined-index-should-not-crash.html
new file mode 100644
index 0000000000..0c97c987f8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/undefined-index-should-not-crash.html
@@ -0,0 +1,64 @@
+<!--
+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>Bug - indexing with 'int()' should not crash</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<canvas id="example" width="40" height="40"> </canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+void main(){
+ gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script id="fshaderTest" type="x-shader/x-fragment">
+precision mediump float;
+uniform vec4 uniformVec;
+uniform mat4 uniformMat;
+uniform float uniformArray[4];
+void main()
+{
+ vec4 tempVec = vec4(0.0);
+ mat4 tempMat = mat4(0.0);
+ float tempArray[4];
+ gl_FragColor = vec4($(indexed)[int()]);
+}
+</script>
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+
+var fTestSource = wtu.getScript("fshaderTest");
+
+var tests = [];
+
+var indexedValues = ['tempVec', 'tempMat[0]', 'tempArray', 'uniformVec', 'uniformMat[0]', 'uniformArray'];
+
+for (var i = 0; i < indexedValues.length; ++i) {
+ var subs = {indexed: indexedValues[i]};
+ tests.push({
+ vShaderId: "vshader",
+ vShaderSuccess: true,
+ fShaderSource: wtu.replaceParams(fTestSource, subs),
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "shader with invalid index expression int() should not compile",
+ });
+}
+GLSLConformanceTester.runTests(tests);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/uniforms-should-not-lose-values.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/uniforms-should-not-lose-values.html
new file mode 100644
index 0000000000..fc99f0f87f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/uniforms-should-not-lose-values.html
@@ -0,0 +1,81 @@
+<!--
+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>Driver Bug - Uniforms should no lose values</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="canvas" width="512" height="256"> </canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+uniform float k,u;
+uniform mat4 l;
+attribute vec3 a;
+void main(){
+ gl_Position=l*vec4(a,1.+u+k);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform float w,x,y,z;
+void main() {
+ gl_FragColor=vec4(1.-y,y,w+x+z,1);
+}
+</script>
+<script>
+"use strict";
+// Certain drivers fail this test. Specifically Mac NVidia GT 330 on OSX 10.8.2
+description();
+debug("");
+var wtu = WebGLTestUtils;
+function test() {
+ var gl = wtu.create3DContext("canvas");
+ if (!gl) {
+ testFailed("context does not exist");
+ return;
+ }
+
+ wtu.setupUnitQuad(gl);
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["a"], undefined, true);
+
+ var setUniformf = function(name, val) {
+ var loc = gl.getUniformLocation(program, name);
+ var func = 'uniform' + val.length + 'fv';
+ gl[func](loc, val);
+ };
+
+ var setUniformMat = function(name, val) {
+ var loc = gl.getUniformLocation(program, name);
+ var func = 'uniformMatrix' + Math.sqrt(val.length) + 'fv';
+ gl[func](loc, false, val);
+ };
+
+ setUniformMat('l', [1, 0 ,0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
+ gl.viewport(0, 0, 256, 256);
+ setUniformf('y', [0]);
+ wtu.drawUnitQuad(gl);
+ gl.viewport(256, 0, 256, 256);
+ setUniformf('y', [1]);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 0, 0, 256, 256, [255, 0, 0, 255]);
+ wtu.checkCanvasRect(gl, 256, 0, 256, 256, [0, 255, 0, 255]);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+test();
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/varying-arrays-should-not-be-reversed.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/varying-arrays-should-not-be-reversed.html
new file mode 100644
index 0000000000..14cdd9fe09
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/varying-arrays-should-not-be-reversed.html
@@ -0,0 +1,82 @@
+<!--
+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>Varying arrays should not be reversed</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="canvas" width="512" height="256"> </canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+varying float colors[3];
+uniform vec3 testData;
+attribute vec3 position;
+void main(){
+ gl_Position = vec4(position, 1.0);
+ colors[0] = testData.x;
+ colors[1] = testData.y;
+ colors[2] = testData.z;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+varying float colors[3];
+void main() {
+ gl_FragColor = vec4(colors[0], colors[1], colors[2], 1.0);
+}
+</script>
+<script>
+"use strict";
+description("Varying arrays should not be reversed.");
+debug("This issue has been seen in Chrome on Nexus 7 2013 (Adreno 320) and Moto G3 (Adreno 306).");
+debug("");
+debug("If things are working correctly, the vertical stripes should be: red, green, blue, light blue, orange");
+debug("");
+debug("If they are not, the red and blue channels will appear to be swapped and you will see: blue, green, red, orange, light blue");
+var wtu = WebGLTestUtils;
+function test() {
+ var gl = wtu.create3DContext("canvas");
+ if (!gl) {
+ testFailed("context does not exist");
+ return;
+ }
+
+ wtu.setupUnitQuad(gl);
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["position"], undefined, true);
+ var loc = gl.getUniformLocation(program, 'testData');
+
+ var triples = [
+ [255, 0, 0],
+ [0, 255, 0],
+ [0, 0, 255],
+ [0, 128, 255],
+ [255, 128, 0]
+ ];
+
+ for (var i = 0; i < triples.length; i++) {
+ var triple = triples[i];
+ var x = i * 64;
+ gl.viewport(x, 0, 64, 256);
+ gl.uniform3f(loc, triple[0] / 255, triple[1] / 255, triple[2] / 255);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, x, 0, 64, 256, [triple[0], triple[1], triple[2], 255]);
+ }
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+test();
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/vector-matrix-constructor-scalarization.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/vector-matrix-constructor-scalarization.html
new file mode 100644
index 0000000000..a6ad3483c3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/vector-matrix-constructor-scalarization.html
@@ -0,0 +1,181 @@
+<!--
+Copyright (c) 2021 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></title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<!--
+
+Original Shadertoy:
+https://www.shadertoy.com/view/ttGyzh
+
+ float a = 0.; // bug
+ #define A 0. // ok
+//#define A min(0.,iTime) // bug
+
+
+ #define r(a) mat2( cos( a + vec4(0,-1.5708,1.5708,0) ) ) // bug
+//#define r(a) mat2( cos(a), -sin(a), sin(a), cos(a) ) // no bug
+//#define r(a) cos(a),sin(a)) // no bug ( vec instead of mat )
+//#define r(a) cos(a+vec2(0,-1.5708)) // no bug ( vec instead of mat )
+
+vec2 c;
+#define f(U,a) ( c = (U) * r(a) , sin(10.*c.x) )
+
+void mainImage( out vec4 O, vec2 U )
+{
+ U /= iResolution.xy;
+
+ O = U.y > .5
+ ? vec4( f(U,a) , f(U*4.,a) , 0,0) // top
+ : vec4( f(U,A) , f(U*4.,A) , 0,0); // bottom
+}
+-->
+
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec2 aPosition;
+attribute vec2 aTexCoord;
+
+varying vec2 vTexCoord;
+
+void main(void) {
+ gl_Position = vec4(aPosition, 0.0, 1.0);
+ vTexCoord = aTexCoord;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+
+varying vec2 vTexCoord;
+
+float a = 0.;
+#define A 0.
+
+#define r(a) mat2( cos( a + vec4(0,-1.5708,1.5708,0) ) )
+vec2 c;
+#define f(U,a) ( c = (U) * r(a) , sin(10.*c.x) )
+
+void main() {
+ vec2 U = vTexCoord;
+
+ gl_FragColor = U.y > .5
+ ? vec4( f(U,a) , f(U*4.,a) , 0,1.0) // top
+ : vec4( f(U,A) , f(U*4.,A) , 0,1.0); // bottom
+}
+</script>
+
+<script id="compileVShader" type="x-shader/x-vertex">
+varying vec2 v_texcoord;
+
+void main() {
+ v_texcoord = vec2(0.0, 0.0);
+ gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script id="compileFShader" type="x-shader/x-fragment">
+// From http://crbug.com/398694
+precision mediump float;
+uniform sampler2D s_texture;
+uniform vec4 color_weights;
+varying vec2 v_texcoord;
+void main() {
+ gl_FragColor = color_weights * mat4(
+ vec4(texture2D(s_texture, v_texcoord).rgb, 1.0),
+ vec4(texture2D(s_texture, v_texcoord).rgb, 1.0),
+ vec4(texture2D(s_texture, v_texcoord).rgb, 1.0),
+ vec4(texture2D(s_texture, v_texcoord).rgb, 1.0));
+}
+</script>
+
+</head>
+<body>
+<canvas id="example"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+debug("");
+
+description("Vector and matrix constructor scalarization workaround (SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS) caused bugs");
+debug('Regression test for <a href="http://crbug.com/1165751">crbug.com/1165751</a>');
+
+// Note: Firefox reports that without this workaround, there are
+// failures on at least Windows / Intel GPU / OpenGL on:
+// conformance/glsl/constructors/glsl-construct-mat2.html
+// https://searchfox.org/mozilla-central/source/dom/canvas/WebGLShaderValidator.cpp#63
+
+// Chromium reported that
+// conformance/glsl/misc/shader-struct-scope.html failed on macOS and
+// on Linux AMD without this workaround enabled:
+// http://crbug.com/angleproject/701
+
+const wtu = WebGLTestUtils;
+const canvas = document.getElementById("example");
+const sz = canvas.width = canvas.height = 256;
+const gl = wtu.create3DContext(canvas, undefined);
+
+if (!gl) {
+ testFailed("WebGL context creation failed");
+ finishTest();
+} else {
+ testPassed("WebGL context creation succeeded");
+ runDrawTest();
+ runCompileTest();
+ finishTest();
+}
+
+function runDrawTest() {
+ debug("Ensure that shader translation isn't broken by the vector and matrix constructor scalarization workaround");
+ let positionLocation = 0;
+ let texCoordLocation = 1;
+ wtu.setupUnitQuad(gl, positionLocation, texCoordLocation);
+ let program = wtu.setupProgram(gl, ["vshader", "fshader"],
+ ["aPosition", "aTexCoord"],
+ [positionLocation, texCoordLocation], true);
+ if (!program) {
+ testFailed("Error compiling shaders");
+ return;
+ }
+ gl.useProgram(program);
+ // Buffers returned from setupQuad above, and ignored, are already bound.
+ wtu.drawUnitQuad(gl);
+
+ // Top and bottom halves should be roughly equal. Go through one
+ // horizontal scanline in the middle.
+ const compareHeight = sz / 4;
+ let pixelValue = new Uint8Array(4);
+ let allEqual = true;
+ // Empirically found that tolerance between the top and bottom
+ // needs to be up to roughly 8 on some platforms.
+ const tolerance = 8;
+ let tempBuf = new Uint8Array(4);
+ // Step over some pixels to spew slightly fewer comparison messages.
+ for (let x = 0; x < sz; x += 4) {
+ gl.readPixels(x, compareHeight, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixelValue);
+ wtu.checkCanvasRect(gl, x, sz - compareHeight, 1, 1, pixelValue, undefined, tolerance, tempBuf);
+ }
+}
+
+function runCompileTest() {
+ debug("Running compilation test");
+ let program = wtu.setupProgram(gl, ["compileVShader", "compileFShader"], [], [], true);
+ if (program) {
+ testPassed("Shader previously requiring SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS compiled successfully");
+ } else {
+ testFailed("Shader previously requiring SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS failed to compile");
+ }
+}
+
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop-complex.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop-complex.html
new file mode 100644
index 0000000000..3b1277c1be
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop-complex.html
@@ -0,0 +1,80 @@
+<!--
+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>GLSL vector/scalar arithmetic inside a for loop (complex cases)</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="fShaderVectorCompoundMulAndAddInSeparateStatementsInsideForLoop" type="x-shader/x-fragment">
+precision mediump float;
+
+void main() {
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+ for (int i = 0; i < 2; i++)
+ {
+ float x = gl_FragCoord.x;
+ float y = (x *= 2.0);
+ gl_FragColor = gl_FragColor + vec4(y, y, y, y);
+ }
+ if (gl_FragColor.g == gl_FragColor.r &&
+ gl_FragColor.b == gl_FragColor.r &&
+ gl_FragColor.a == gl_FragColor.r)
+ {
+ gl_FragColor = vec4(0, 1, 0, 1);
+ }
+}
+</script>
+<script id="fShaderVectorCompoundMulAndAddInSeparateStatementsInsideForLoop2" type="x-shader/x-fragment">
+precision mediump float;
+
+void main() {
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+ for (int i = 0; i < 2; i++)
+ {
+ float x = gl_FragCoord.x;
+ float y = (x *= 2.0);
+ gl_FragColor = gl_FragColor + vec4(x, y, x, y);
+ }
+ if (gl_FragColor.g == gl_FragColor.r &&
+ gl_FragColor.b == gl_FragColor.r &&
+ gl_FragColor.a == gl_FragColor.r)
+ {
+ gl_FragColor = vec4(0, 1, 0, 1);
+ }
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description();
+
+// See http://crbug.com/772651
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fShaderVectorCompoundMulAndAddInSeparateStatementsInsideForLoop',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Adding a vector that's just 4 copies of a scalar to another vector inside for loop should work."
+},
+{
+ fShaderId: 'fShaderVectorCompoundMulAndAddInSeparateStatementsInsideForLoop2',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Adding a vector that's just 4 copies of a scalar stored in two different variables to another vector inside for loop should work."
+}
+]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html
new file mode 100644
index 0000000000..622ea38129
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html
@@ -0,0 +1,99 @@
+<!--
+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>GLSL vector/scalar arithmetic inside a for loop</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.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>
+<script id="fShaderVectorMulAndAddInsideForLoop" type="x-shader/x-fragment">
+void main(){
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+ for (int i = 0; i < 2; i++)
+ {
+ gl_FragColor += (2.0 * gl_FragCoord.x);
+ }
+ if (gl_FragColor.g == gl_FragColor.r &&
+ gl_FragColor.b == gl_FragColor.r &&
+ gl_FragColor.a == gl_FragColor.r)
+ {
+ gl_FragColor = vec4(0, 1, 0, 1);
+ }
+}
+</script>
+<script id="fShaderVectorCompoundMulAndAddInsideForLoop" type="x-shader/x-fragment">
+precision mediump float;
+
+void main() {
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+ for (int i = 0; i < 2; i++)
+ {
+ float x = gl_FragCoord.x;
+ gl_FragColor = gl_FragColor + (x *= 2.0);
+ }
+ if (gl_FragColor.g == gl_FragColor.r &&
+ gl_FragColor.b == gl_FragColor.r &&
+ gl_FragColor.a == gl_FragColor.r)
+ {
+ gl_FragColor = vec4(0, 1, 0, 1);
+ }
+}
+</script>
+<script id="fShaderVectorCompoundDivAndAddInsideForLoop" type="x-shader/x-fragment">
+precision mediump float;
+
+void main() {
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+ for (int i = 0; i < 2; i++)
+ {
+ float x = gl_FragCoord.x;
+ gl_FragColor = gl_FragColor + (x /= 2.0);
+ }
+ if (gl_FragColor.g == gl_FragColor.r &&
+ gl_FragColor.b == gl_FragColor.r &&
+ gl_FragColor.a == gl_FragColor.r)
+ {
+ gl_FragColor = vec4(0, 1, 0, 1);
+ }
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description();
+
+// See http://crbug.com/772651
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fShaderVectorMulAndAddInsideForLoop',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Adding a scalar to a vector inside for loop should work."
+},
+{
+ fShaderId: 'fShaderVectorCompoundMulAndAddInsideForLoop',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Adding a scalar (target of a compound assignment/multiplication operation) to a vector inside for loop should work."
+},
+{
+ fShaderId: 'fShaderVectorCompoundDivAndAddInsideForLoop',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Adding a scalar (target of a compound assignment/division operation) to a vector inside for loop should work."
+}
+]);
+</script>
+</body>
+</html>