summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance2/glsl3')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/00_test_list.txt59
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-as-return-value.html150
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign-constructor.html91
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign.html93
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-complex-indexing.html87
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-element-increment.html131
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-equality.html240
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-in-complex-expression.html144
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-initialize-with-same-name-array.html48
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-length-side-effects.html100
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/attrib-location-length-limits.html89
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/bool-type-cast-bug-uint-ivec-uvec.html368
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/compare-structs-containing-arrays.html86
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/compound-assignment-type-combination.html26
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/const-array-init.html98
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/const-struct-from-array-as-function-parameter.html59
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/float-parsing.html167
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forbidden-operators.html124
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forward-declaration.html90
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/frag-depth.html157
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/fragment-shader-loop-crash.html72
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/gradient-in-discontinuous-loop.html75
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/input-with-interpotaion-as-lvalue.html83
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-default-precision.html71
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-invariant.html88
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/loops-with-side-effects.html211
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major-dynamic-indexing.html118
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major.html51
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/misplaced-version-directive.html111
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/no-attribute-vertex-shader.html63
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/precision-side-effects-bug.html125
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/reciprocal-sqrt-of-sum-of-squares-crash.html66
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-array-indexing.html94
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-no-precision.html88
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sequence-operator-returns-non-constant.html59
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-linking.html84
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-1024-character-define.html36
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-1024-character-identifier.frag.html105
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-1025-character-define.html36
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-1025-character-identifier.frag.html36
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-invalid-characters.html37
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-mis-matching-uniform-block.html59
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/short-circuiting-in-loop-condition.html180
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/switch-case.html351
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-non-constant-offset.html170
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-out-of-range.html106
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-uniform-texture-coordinate.html170
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/tricky-loop-conditions.html327
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uint-int-shift-bug.html106
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/unary-minus-operator-in-dynamic-loop.html248
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layout-match.html57
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layouts.html63
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-location-length-limits.html89
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-struct-with-non-square-matrix.html51
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uninitialized-local-global-variables.html98
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/valid-invariant.html95
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/varying-struct-inline-definition.html62
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-nv-driver-bug.html67
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html50
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing.html369
60 files changed, 6834 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/00_test_list.txt
new file mode 100644
index 0000000000..5a47d470f9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/00_test_list.txt
@@ -0,0 +1,59 @@
+array-as-return-value.html
+array-assign.html
+array-assign-constructor.html
+array-complex-indexing.html
+array-element-increment.html
+array-equality.html
+array-in-complex-expression.html
+--min-version 2.0.1 array-initialize-with-same-name-array.html
+--min-version 2.0.1 array-length-side-effects.html
+attrib-location-length-limits.html
+bool-type-cast-bug-uint-ivec-uvec.html
+compare-structs-containing-arrays.html
+compound-assignment-type-combination.html
+const-array-init.html
+--min-version 2.0.1 const-struct-from-array-as-function-parameter.html
+--min-version 2.0.1 float-parsing.html
+forbidden-operators.html
+--min-version 2.0.1 forward-declaration.html
+frag-depth.html
+--min-version 2.0.1 fragment-shader-loop-crash.html
+--min-version 2.0.1 gradient-in-discontinuous-loop.html
+--min-version 2.0.1 input-with-interpotaion-as-lvalue.html
+invalid-default-precision.html
+invalid-invariant.html
+loops-with-side-effects.html
+--min-version 2.0.1 matrix-row-major.html
+--min-version 2.0.1 matrix-row-major-dynamic-indexing.html
+misplaced-version-directive.html
+--min-version 2.0.1 no-attribute-vertex-shader.html
+--min-version 2.0.1 precision-side-effects-bug.html
+--min-version 2.0.1 reciprocal-sqrt-of-sum-of-squares-crash.html
+sampler-no-precision.html
+--min-version 2.0.1 sampler-array-indexing.html
+sequence-operator-returns-non-constant.html
+shader-linking.html
+shader-with-1024-character-define.html
+shader-with-1024-character-identifier.frag.html
+shader-with-1025-character-define.html
+shader-with-1025-character-identifier.frag.html
+shader-with-invalid-characters.html
+shader-with-mis-matching-uniform-block.html
+short-circuiting-in-loop-condition.html
+--min-version 2.0.1 switch-case.html
+--min-version 2.0.1 texture-offset-non-constant-offset.html
+texture-offset-out-of-range.html
+--min-version 2.0.1 texture-offset-uniform-texture-coordinate.html
+--min-version 2.0.1 tricky-loop-conditions.html
+--min-version 2.0.1 uint-int-shift-bug.html
+--min-version 2.0.1 unary-minus-operator-in-dynamic-loop.html
+uniform-block-layouts.html
+uniform-block-layout-match.html
+uniform-location-length-limits.html
+--min-version 2.0.1 uniform-struct-with-non-square-matrix.html
+--min-version 2.0.1 uninitialized-local-global-variables.html
+valid-invariant.html
+--min-version 2.0.1 varying-struct-inline-definition.html
+vector-dynamic-indexing.html
+--min-version 2.0.1 vector-dynamic-indexing-nv-driver-bug.html
+--min-version 2.0.1 vector-dynamic-indexing-swizzled-lvalue.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-as-return-value.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-as-return-value.html
new file mode 100644
index 0000000000..45d7353111
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-as-return-value.html
@@ -0,0 +1,150 @@
+<!--
+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 array as return value 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="fshaderReturnedArrayNotUsed" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int g = 0;
+
+int[2] plus() {
+ ++g;
+ return int[2](g, g);
+}
+
+void main() {
+ // The function call should be evaluated even if the returned array is not used.
+ plus();
+ my_FragColor = vec4(0.0, ((g == 1) ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script id="fshaderCompareReturnedArray" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int g = 0;
+
+int[2] createArray() {
+ ++g;
+ return int[2](g, g);
+}
+
+void main() {
+ // Comparing a returned array should work.
+ if (createArray() == int[2](1, 1)) {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ } else {
+ my_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+ }
+}
+</script>
+<script id="fshaderReturnReturnedArray" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int g = 0;
+
+int[2] foo() {
+ ++g;
+ return int[2](g, g);
+}
+
+int[2] bar(int addition) {
+ g += addition;
+ // Returning a returned array should work.
+ return foo();
+}
+
+void main() {
+ int a[2] = bar(1);
+ bool arrayCorrect = true;
+ for (int i = 0; i < 2; ++i) {
+ if (a[i] != 2) {
+ arrayCorrect = false;
+ }
+ }
+ my_FragColor = vec4(0.0, ((g == 2 && arrayCorrect) ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script id="fshaderReturnedArrayAsParameter" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int g = 0;
+
+int[2] createArray() {
+ ++g;
+ return int[2](g, g);
+}
+
+bool isSuccess(int[2] a) {
+ bool arrayCorrect = true;
+ for (int i = 0; i < 2; ++i) {
+ if (a[i] != 1) {
+ arrayCorrect = false;
+ }
+ }
+ return arrayCorrect;
+}
+
+void main() {
+ bool success = isSuccess(createArray());
+ my_FragColor = vec4(0.0, (success ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Arrays as return values should work");
+debug("");
+debug("This test is targeted to stress syntax tree transformations that might need to be done in shader translation when the platform doesn't natively support arrays as return values.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderReturnedArrayNotUsed',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Expression where a returned array is not used'
+},
+{
+ fShaderId: 'fshaderCompareReturnedArray',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Expression where a returned array is compared'
+},
+{
+ fShaderId: 'fshaderReturnReturnedArray',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Expression where a returned array is returned again'
+},
+{
+ fShaderId: 'fshaderReturnedArrayAsParameter',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Expression where a returned array is passed as a parameter'
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign-constructor.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign-constructor.html
new file mode 100644
index 0000000000..c47f3d7123
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign-constructor.html
@@ -0,0 +1,91 @@
+<!--
+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 array constructor assignment 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="fshaderNonConstantConstructorParameter" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform int u;
+
+out vec4 my_FragColor;
+
+void main() {
+ // Test assigning a constructor result as opposed to initializing with a
+ // constructor result.
+ int a[3];
+ a = int[3](0, 1, u);
+ bool fail = false;
+ for (int i = 0; i < 2; ++i) {
+ if (a[i] != i) {
+ fail = true;
+ }
+ }
+ if (a[2] != u) {
+ fail = true;
+ }
+ my_FragColor = vec4(0.0, (fail ? 0.0 : 1.0), 0.0, 1.0);
+}
+</script>
+<script id="fshaderArrayOfStructs" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+struct S {
+ int foo;
+};
+
+void main() {
+ // Test assigning a constructor result as opposed to initializing with a
+ // constructor result.
+ S a[3];
+ a = S[3](S(0), S(1), S(2));
+ bool fail = false;
+ for (int i = 0; i < 3; ++i) {
+ if (a[i].foo != i) {
+ fail = true;
+ }
+ }
+ my_FragColor = vec4(0.0, (fail ? 0.0 : 1.0), 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Assigning return values of array constructors should work.");
+debug("");
+
+// This test only covers cases which are not covered by the dEQP tests.
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderNonConstantConstructorParameter',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Assigning a constructor result',
+ uniforms: [{name: "u", functionName: "uniform1i", value: 5}]
+},
+{
+ fShaderId: 'fshaderArrayOfStructs',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Assigning an array of structs'
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign.html
new file mode 100644
index 0000000000..94c1507b29
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign.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 array assignment 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="fshaderSimple" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ // This simple test uses the ESSL1 style array initialization in order
+ // to be able to test array assignment independently of array constructors.
+ int a[3];
+ int b[3];
+ for (int i = 0; i < 3; ++i) {
+ a[i] = 0;
+ b[i] = i;
+ }
+ a = b;
+ bool fail = false;
+ for (int i = 0; i < 3; ++i) {
+ if (a[i] != i) {
+ fail = true;
+ }
+ }
+ my_FragColor = vec4(0.0, (fail ? 0.0 : 1.0), 0.0, 1.0);
+}
+</script>
+<script id="fshaderArrayOfStructs" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+struct S {
+ int foo;
+};
+
+void main() {
+ // This simple test uses the ESSL1 style array initialization in order
+ // to be able to test array assignment independently of array constructors.
+ S a[3];
+ S b[3];
+ for (int i = 0; i < 3; ++i) {
+ a[i].foo = 0;
+ b[i].foo = i;
+ }
+ a = b;
+ bool fail = false;
+ for (int i = 0; i < 3; ++i) {
+ if (a[i].foo != i) {
+ fail = true;
+ }
+ }
+ my_FragColor = vec4(0.0, (fail ? 0.0 : 1.0), 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Assigning arrays should work.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderSimple',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Arrays of integers'
+},
+{
+ fShaderId: 'fshaderArrayOfStructs',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Arrays of structs'
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-complex-indexing.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-complex-indexing.html
new file mode 100644
index 0000000000..2ff9fa1c5a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-complex-indexing.html
@@ -0,0 +1,87 @@
+<!--
+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 Indexing complex array expressions</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>
+<!--
+Array indexing is detailed in the ESSL 3.00 spec section 5.9
+ESSL 3.00 revisions after 3.00.4 changed the definition from 'subscripted array names' to 'subscripted arrays'
+-->
+<script id="fshader-assignment" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 color;
+
+void main() {
+ float a[2] = float[2](0.0, 0.0);
+ float b[2] = float[2](2.0, 1.0);
+ float c = (a = b)[0];
+ color = (c == 2.0) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);
+}
+</script>
+<script id="fshader-function" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 color;
+bool hasRan = false;
+
+float[2] functionReturnArray() {
+ hasRan = true;
+ return float[2](2.0, 1.0);
+}
+
+void main() {
+ float c = (functionReturnArray())[0];
+ color = ((c == 2.0) && hasRan) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);
+}
+</script>
+<script id="fshader-array-initialization" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 color;
+
+void main() {
+ float a = (float[3](2.0, 1.0, 0.0))[0];
+ color = (a == 2.0) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Indexing complex array expressions");
+debug("");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshader-assignment',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Test indexing a variable assignment: (a = b)[0]'
+},
+{
+ fShaderId: 'fshader-function',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Test indexing a function return with a side-effect: (functionReturnArray())[0]'
+},
+{
+ fShaderId: 'fshader-array-initialization',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Test indexing an array initialization: (float[3](2.0, 1.0, 0.0))[0]'
+},
+], 2);
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-element-increment.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-element-increment.html
new file mode 100644
index 0000000000..2a3e555472
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-element-increment.html
@@ -0,0 +1,131 @@
+<!--
+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 initialized array element increment/decrement 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="fshaderFloatArrayIncrement" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ float A[2] = float[2](0.0, 1.0);
+ A[0]++;
+ my_FragColor = vec4(1.0 - A[0], A[0], 0.0, 1.0);
+}
+</script>
+<script id="fshaderVectorArrayIncrement" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ vec4 V[2] = vec4[2](vec4(0.0, 2.0, 3.0, 4.0), vec4(5.0, 6.0, 7.0, 8.0));
+ V[0][0]++;
+ my_FragColor = vec4(1.0 - V[0][0], V[0][0], 0.0, 1.0);
+}
+</script>
+<script id="fshaderVectorElementIncrement" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ vec4 v = vec4(0.0, 2.0, 3.0, 4.0);
+ v[0]++;
+ my_FragColor = vec4(1.0 - v[0], v[0], 0.0, 1.0);
+}
+</script>
+<script id="fshaderFloatArrayDecrement" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ float A[2] = float[2](2.0, 1.0);
+ A[0]--;
+ my_FragColor = vec4(1.0 - A[0], A[0], 0.0, 1.0);
+}
+</script>
+<script id="fshaderVectorArrayDecrement" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ vec4 V[2] = vec4[2](vec4(2.0, 2.0, 3.0, 4.0), vec4(5.0, 6.0, 7.0, 8.0));
+ V[0][0]--;
+ my_FragColor = vec4(1.0 - V[0][0], V[0][0], 0.0, 1.0);
+}
+</script>
+<script id="fshaderVectorElementDecrement" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ vec4 v = vec4(2.0, 2.0, 3.0, 4.0);
+ v[0]--;
+ my_FragColor = vec4(1.0 - v[0], v[0], 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Incrementing or decrementing elements of arrays with initializers should work.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderFloatArrayIncrement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Increment an element of a vector array'
+},
+{
+ fShaderId: 'fshaderVectorArrayIncrement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Increment an element of a vector array'
+},
+{
+ fShaderId: 'fshaderVectorElementIncrement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Increment an element of a vector'
+},
+{
+ fShaderId: 'fshaderFloatArrayDecrement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Decrement an element of a vector array'
+},
+{
+ fShaderId: 'fshaderVectorArrayDecrement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Decrement an element of a vector array'
+},
+{
+ fShaderId: 'fshaderVectorElementDecrement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Decrement an element of a vector'
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-equality.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-equality.html
new file mode 100644
index 0000000000..dcffa2c0a3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-equality.html
@@ -0,0 +1,240 @@
+<!--
+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 array equality 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="fshaderSimple" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ // This simple test uses the ESSL1 style array initialization in order
+ // to be able to test array equality independently of array constructors.
+ int a[3];
+ int b[3];
+ int c[3];
+ for (int i = 0; i < 3; ++i) {
+ a[i] = i;
+ b[i] = i;
+ c[i] = i + 1;
+ }
+ bool success = (a == b) && (a != c);
+ my_FragColor = vec4(0.0, (success ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script id="fshaderArrayOfStructs" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+struct S {
+ int foo;
+};
+
+void main() {
+ // This simple test uses the ESSL1 style array initialization in order
+ // to be able to test array equality independently of array constructors.
+ S a[3];
+ S b[3];
+ S c[3];
+ for (int i = 0; i < 3; ++i) {
+ a[i].foo = i;
+ b[i].foo = i;
+ c[i].foo = i + 1;
+ }
+ bool success = (a == b) && (a != c);
+ my_FragColor = vec4(0.0, (success ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script id="simple-float-array-fs" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+uniform float a[3];
+uniform float b[3];
+
+out vec4 fragColor;
+
+void main(void) {
+ fragColor = vec4(0.0, 0.0, 0.0, 1.0);
+
+ if (a == b) {
+ fragColor.g = 1.0;
+ }
+}
+</script>
+<script id="simple-vec-array-fs" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+uniform vec3 a[3];
+uniform vec3 b[3];
+
+out vec4 fragColor;
+
+void main(void) {
+ fragColor = vec4(0.0, 0.0, 0.0, 1.0);
+
+ if (a == b) {
+ fragColor.g = 1.0;
+ }
+}
+</script>
+<script id="simple-mat-array-fs" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+uniform mat3 a[3];
+uniform mat3 b[3];
+
+out vec4 fragColor;
+
+void main(void) {
+ fragColor = vec4(0.0, 0.0, 0.0, 1.0);
+
+ if (a == b) {
+ fragColor.g = 1.0;
+ }
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Comparing arrays should work.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderSimple',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Arrays of integers'
+},
+{
+ fShaderId: 'fshaderArrayOfStructs',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Arrays of structs'
+},
+{
+ fShaderId: "simple-float-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ passMsg: "Simple float array with default values",
+},
+{
+ fShaderId: "simple-float-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ renderColor: [0, 0, 0, 255],
+ uniforms: [
+ { name: 'a', functionName: 'uniform1fv', value: [1, 2, 3]},
+ { name: 'b', functionName: 'uniform1fv', value: [1, 2, 4]},
+ ],
+ passMsg: "Simple float array with different values",
+},
+{
+ fShaderId: "simple-float-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ uniforms: [
+ { name: 'a', functionName: 'uniform1fv', value: [1, 2, 3]},
+ { name: 'b', functionName: 'uniform1fv', value: [1, 2, 3]},
+ ],
+ passMsg: "Simple float array with same values",
+},
+{
+ fShaderId: "simple-vec-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ passMsg: "Simple vec array with default values",
+},
+{
+ fShaderId: "simple-vec-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ renderColor: [0, 0, 0, 255],
+ uniforms: [
+ { name: 'a', functionName: 'uniform3fv', value: [1, 2, 3, 4, 5, 6, 7, 8, 9]},
+ { name: 'b', functionName: 'uniform3fv', value: [1, 2, 3, 4, 5, 6, 7, 8, 10]},
+ ],
+ passMsg: "Simple vec array with different values",
+},
+{
+ fShaderId: "simple-vec-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ uniforms: [
+ { name: 'a', functionName: 'uniform3fv', value: [1, 2, 3, 4, 5, 6, 7, 8, 9]},
+ { name: 'b', functionName: 'uniform3fv', value: [1, 2, 3, 4, 5, 6, 7, 8, 9]},
+ ],
+ passMsg: "Simple vec array with same values",
+},
+{
+// "simple-mat-array-fs"
+ fShaderId: "simple-mat-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ passMsg: "Simple mat array with default values",
+},
+{
+ fShaderId: "simple-mat-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ renderColor: [0, 0, 0, 255],
+ uniforms: [
+ { name: 'a', functionName: 'uniformMatrix3fv', value: [
+ 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ ]},
+ { name: 'b', functionName: 'uniformMatrix3fv', value: [
+ 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 31, 32, 33, 34, 35, 36, 37, 30, 39,
+ ]},
+ ],
+ passMsg: "Simple vec array with different values",
+},
+{
+ fShaderId: "simple-mat-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ uniforms: [
+ { name: 'a', functionName: 'uniformMatrix3fv', value: [
+ 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ ]},
+ { name: 'b', functionName: 'uniformMatrix3fv', value: [
+ 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ ]},
+ ],
+ passMsg: "Simple vec array with same values",
+},
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-in-complex-expression.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-in-complex-expression.html
new file mode 100644
index 0000000000..9e55a0a016
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-in-complex-expression.html
@@ -0,0 +1,144 @@
+<!--
+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 array in complex expression 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="fshaderAndShortCircuits" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int g = 0;
+
+int[2] plus() {
+ ++g;
+ return int[2](g, g);
+}
+
+bool minus() {
+ --g;
+ return false;
+}
+
+void main() {
+ int a[2] = int[2](0, 0);
+ // The function call must not be evaluated, since && short-circuits
+ minus() && (a == plus());
+ my_FragColor = vec4(0.0, ((g == -1) ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script id="fshaderOrShortCircuits" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int g = 0;
+
+int[2] plus() {
+ ++g;
+ return int[2](g, g);
+}
+
+bool minus() {
+ --g;
+ return true;
+}
+
+void main() {
+ int a[2] = int[2](0, 0);
+ // The function call must not be evaluated, since || short-circuits.
+ minus() || (a == plus());
+ my_FragColor = vec4(0.0, ((g == -1) ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script id="fshaderTernaryOnlyEvaluatesOneOperand" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int g = 0;
+
+int[2] plus() {
+ ++g;
+ return int[2](g, g);
+}
+
+void main() {
+ int a[2] = int[2](0, 0);
+ // The function call must not be evaluated, since the condition is true.
+ (g == 0) ? true : (a == plus());
+ my_FragColor = vec4(0.0, ((g == 0) ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script id="fshaderSequenceSideEffectsAffectingComparedArrayContent" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int[2] func(int param) {
+ return int[2](param, param);
+}
+
+void main() {
+ int a[2];
+ for (int i = 0; i < 2; ++i) {
+ a[i] = 1;
+ }
+ int j = 0;
+ // Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9).
+ // The function call that returns the array needs to be evaluated after ++j
+ // for the expression to return the correct value (true).
+ bool result = ((++j), (a == func(j)));
+ my_FragColor = vec4(0.0, (result ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Arrays in complex expressions should work");
+debug("");
+debug("This test is targeted to stress syntax tree transformations that might need to be done in shader translation when the platform doesn't natively support arrays as return values.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderAndShortCircuits',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Expression where an array is returned from a function call inside an operand to && that doesn't get evaluated as result of short-circuiting"
+},
+{
+ fShaderId: 'fshaderOrShortCircuits',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Expression where an array is returned from a function call inside an operand to || that doesn't get evaluated as result of short-circuiting"
+},
+{
+ fShaderId: 'fshaderTernaryOnlyEvaluatesOneOperand',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Expression where an array is returned from a function call in an operand of a ternary operator that doesn't get evaluated"
+},
+{
+ fShaderId: 'fshaderSequenceSideEffectsAffectingComparedArrayContent',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Expression where first operand of a sequence operator has side effects which affect the second operand that returns an array'
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-initialize-with-same-name-array.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-initialize-with-same-name-array.html
new file mode 100644
index 0000000000..cf81f84dd0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-initialize-with-same-name-array.html
@@ -0,0 +1,48 @@
+<!--
+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 array initializer that references an array 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="fshaderInitArray" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+
+void main()
+{
+ float foo[2] = float[2](1.0, 1.0);
+ {
+ float foo[2] = foo;
+ my_FragColor = vec4(0.0, foo[0], 0.0, foo[1]);
+ }
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Initializing an array with another array with the same name should work. See GLSL ES 3.00.6 section 4.2.2.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderInitArray',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Array that is initialized with an array of the same name from an outer scope'
+},
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-length-side-effects.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-length-side-effects.html
new file mode 100644
index 0000000000..fb32153c66
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-length-side-effects.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>GLSL: test that length() method called on a complex expression works</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="fshaderLengthOfAssignment" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ int a[3] = int[3](1, 2, 3);
+ int b[3] = int[3](4, 5, 6);
+ int c = (a = b).length();
+ if (c == 3 && a[0] == 4 && a[1] == 5 && a[2] == 6) {
+ my_FragColor = vec4(0, 1, 0, 1);
+ } else {
+ my_FragColor = vec4(1, 0, 0, 1);
+ }
+}
+</script>
+<script id="fshaderLengthOfFunctionCall" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int sideEffectCounter = 0;
+
+int[2] func() {
+ ++sideEffectCounter;
+ int a[2];
+ return a;
+}
+
+void main() {
+ int b = (func()).length();
+ if (sideEffectCounter == 1 && b == 2) {
+ my_FragColor = vec4(0, 1, 0, 1);
+ } else {
+ my_FragColor = vec4(1, 0, 0, 1);
+ }
+}
+</script>
+<script id="fshaderLengthOfConstructor" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ int a = (int[1](0)).length();
+ if (a == 1) {
+ my_FragColor = vec4(0, 1, 0, 1);
+ } else {
+ my_FragColor = vec4(1, 0, 0, 1);
+ }
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+debug('length() method is allowed to be called on arbitrary expressions returning arrays. ESSL 3.00 section 5.9 says that length is allowed on "array names", but ESSL 3.20 has newer, clarified wording that says that it is allowed for "arrays". This was always the intent of the spec.');
+GLSLConformanceTester.runRenderTests([
+ {
+ fShaderId: "fshaderLengthOfAssignment",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Fragment shader which tries to evaluate the length of an assignment operation should succeed."
+ },
+ {
+ fShaderId: "fshaderLengthOfFunctionCall",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Fragment shader which tries to evaluate the length of a return value should succeed."
+ },
+ {
+ fShaderId: "fshaderLengthOfConstructor",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Fragment shader which tries to evaluate the length of a newly constructed array should succeed."
+ }
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/attrib-location-length-limits.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/attrib-location-length-limits.html
new file mode 100644
index 0000000000..d5bfc174cc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/attrib-location-length-limits.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>WebGL attrib location length tests</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>
+</head>
+<body>
+<canvas id="example" width="50" height="50">
+There is supposed to be an example drawing here, but it's not important.
+</canvas>
+<div id="description">Verify limits on the lengths of attribute locations per WebGL 2 spec "Maximum Uniform and Attribute Location Lengths"</div>
+<div id="console"></div>
+<script id="goodVertexShader" type="x-shader/x-vertex">
+// A vertex shader where the needed attrib location is exactly 1024 characters.
+attribute vec4 vPosition1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345;
+void main()
+{
+ gl_Position = vPosition1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345;
+}
+</script>
+<script id="badVertexShader" type="x-shader/x-vertex">
+// A vertex shader where the needed attrib location is 1025 characters.
+attribute vec4 vPosition12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456;
+
+void main()
+{
+ gl_Position = vPosition12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456;
+}
+</script>
+<script id="fragmentShader" type="x-shader/x-fragment">
+precision mediump float;
+
+void main() {
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script>
+"use strict";
+description("test attrib location length limit");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", undefined, 2);
+
+debug("Test attrib location underneath the length limit");
+var program = wtu.loadProgramFromScript(gl, "goodVertexShader", "fragmentShader");
+shouldBe('gl.getProgramParameter(program, gl.LINK_STATUS)', 'true');
+var attrib1024Name = "vPosition1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345";
+gl.bindAttribLocation(program, 0, attrib1024Name);
+wtu.glErrorShouldBe(gl, gl.NONE);
+var attribLoc = gl.getAttribLocation(program, attrib1024Name);
+if (attribLoc == -1) {
+ testFailed("attrib location was -1, should not be");
+} else {
+ testPassed("attrib location should not be -1");
+}
+wtu.glErrorShouldBe(gl, gl.NONE);
+
+debug("Test attrib length over the length limit");
+var attrib1025Name = attrib1024Name + "6";
+
+debug("Shader compilation or link should fail");
+shouldBe('wtu.loadProgramFromScriptExpectError(gl, "badVertexShader", "fragmentShader")', 'null');
+wtu.glErrorShouldBe(gl, gl.NONE);
+
+debug("Attempt to bind too-long attrib location should produce error");
+program = gl.createProgram();
+gl.bindAttribLocation(program, 0, attrib1025Name);
+wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
+
+debug("Attempt to fetch too-long attrib location should produce error");
+program = wtu.loadStandardProgram(gl);
+shouldBe('gl.getAttribLocation(program, attrib1025Name)', '-1');
+wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/bool-type-cast-bug-uint-ivec-uvec.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/bool-type-cast-bug-uint-ivec-uvec.html
new file mode 100644
index 0000000000..88af6137c5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/bool-type-cast-bug-uint-ivec-uvec.html
@@ -0,0 +1,368 @@
+<!--
+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 uint(bool), ivec(bvec), and uvec(bvec) 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-uint-1" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+flat out uint uvalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ uvalue = uint(bvalue);
+}
+</script>
+<script id="fshader-uint-1" type="x-shader/x-fragment">#version 300 es
+flat in uint uvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ if (uvalue == 1u)
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (uvalue == 0u)
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-simple" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+}
+</script>
+<script id="fshader-uint-2" type="x-shader/x-fragment">#version 300 es
+uniform bool bvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ uint uvalue = uint(bvalue);
+
+ if (uvalue == 1u)
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (uvalue == 0u)
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-ivec2-1" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+flat out ivec2 ivalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ ivalue = ivec2(bvec2(bvalue, bvalue));
+}
+</script>
+<script id="fshader-ivec2-1" type="x-shader/x-fragment">#version 300 es
+flat in ivec2 ivalue;
+out highp vec4 myFragColor;
+
+void main() {
+ if (ivalue == ivec2(1, 1))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (ivalue == ivec2(0, 0))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="fshader-ivec2-2" type="x-shader/x-fragment">#version 300 es
+uniform bool bvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ ivec2 ivalue = ivec2(bvec2(bvalue, bvalue));
+
+ if (ivalue == ivec2(1, 1))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (ivalue == ivec2(0, 0))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-uvec2-1" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+flat out uvec2 uvalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ uvalue = uvec2(bvec2(bvalue, bvalue));
+}
+</script>
+<script id="fshader-uvec2-1" type="x-shader/x-fragment">#version 300 es
+flat in uvec2 uvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ if (uvalue == uvec2(1u, 1u))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (uvalue == uvec2(0u, 0u))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="fshader-uvec2-2" type="x-shader/x-fragment">#version 300 es
+uniform bool bvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ uvec2 uvalue = uvec2(bvec2(bvalue, bvalue));
+
+ if (uvalue == uvec2(1u, 1u))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (uvalue == uvec2(0u, 0u))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-ivec3-1" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+flat out ivec3 ivalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ ivalue = ivec3(bvec3(bvalue, bvalue, bvalue));
+}
+</script>
+<script id="fshader-ivec3-1" type="x-shader/x-fragment">#version 300 es
+flat in ivec3 ivalue;
+out highp vec4 myFragColor;
+
+void main() {
+ if (ivalue == ivec3(1, 1, 1))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (ivalue == ivec3(0, 0, 0))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="fshader-ivec3-2" type="x-shader/x-fragment">#version 300 es
+uniform bool bvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ ivec3 ivalue = ivec3(bvec3(bvalue, bvalue, bvalue));
+
+ if (ivalue == ivec3(1, 1, 1))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (ivalue == ivec3(0, 0, 0))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-uvec3-1" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+flat out uvec3 uvalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ uvalue = uvec3(bvec3(bvalue, bvalue, bvalue));
+}
+</script>
+<script id="fshader-uvec3-1" type="x-shader/x-fragment">#version 300 es
+flat in uvec3 uvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ if (uvalue == uvec3(1u, 1u, 1u))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (uvalue == uvec3(0u, 0u, 0u))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="fshader-uvec3-2" type="x-shader/x-fragment">#version 300 es
+uniform bool bvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ uvec3 uvalue = uvec3(bvec3(bvalue, bvalue, bvalue));
+
+ if (uvalue == uvec3(1u, 1u, 1u))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (uvalue == uvec3(0u, 0u, 0u))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-ivec4-1" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+flat out ivec4 ivalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ ivalue = ivec4(bvec4(bvalue, bvalue, bvalue, bvalue));
+}
+</script>
+<script id="fshader-ivec4-1" type="x-shader/x-fragment">#version 300 es
+flat in ivec4 ivalue;
+out highp vec4 myFragColor;
+
+void main() {
+ if (ivalue == ivec4(1, 1, 1, 1))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (ivalue == ivec4(0, 0, 0, 0))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="fshader-ivec4-2" type="x-shader/x-fragment">#version 300 es
+uniform bool bvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ ivec4 ivalue = ivec4(bvec4(bvalue, bvalue, bvalue, bvalue));
+
+ if (ivalue == ivec4(1, 1, 1, 1))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (ivalue == ivec4(0, 0, 0, 0))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-uvec4-1" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+flat out uvec4 uvalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ uvalue = uvec4(bvec4(bvalue, bvalue, bvalue, bvalue));
+}
+</script>
+<script id="fshader-uvec4-1" type="x-shader/x-fragment">#version 300 es
+flat in uvec4 uvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ if (uvalue == uvec4(1u, 1u, 1u, 1u))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (uvalue == uvec4(0u, 0u, 0u, 0u))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="fshader-uvec4-2" type="x-shader/x-fragment">#version 300 es
+uniform bool bvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ uvec4 uvalue = uvec4(bvec4(bvalue, bvalue, bvalue, bvalue));
+
+ if (uvalue == uvec4(1u, 1u, 1u, 1u))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (uvalue == uvec4(0u, 0u, 0u, 0u))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script type="application/javascript">
+"use strict";
+description("Verify uint(bool), ivec(bvec), and uvec(bvec) work correctly");
+debug("");
+var wtu = WebGLTestUtils;
+function test() {
+ var gl = wtu.create3DContext("canvas", undefined, 2);
+ if (!gl) {
+ testFailed("context does not exist");
+ return;
+ }
+ wtu.setupUnitQuad(gl);
+
+ var testCases = [
+ { vshader: "vshader-uint-1", fshader: "fshader-uint-1", desc: "vertex shader uint" },
+ { vshader: "vshader-simple", fshader: "fshader-uint-2", desc: "fragment shader uint" },
+ { vshader: "vshader-ivec2-1", fshader: "fshader-ivec2-1", desc: "vertex shader ivec2" },
+ { vshader: "vshader-simple", fshader: "fshader-ivec2-2", desc: "fragment shader ivec2" },
+ { vshader: "vshader-uvec2-1", fshader: "fshader-uvec2-1", desc: "vertex shader uvec2" },
+ { vshader: "vshader-simple", fshader: "fshader-uvec2-2", desc: "fragment shader uvec2" },
+ { vshader: "vshader-ivec3-1", fshader: "fshader-ivec3-1", desc: "vertex shader ivec3" },
+ { vshader: "vshader-simple", fshader: "fshader-ivec3-2", desc: "fragment shader ivec3" },
+ { vshader: "vshader-uvec3-1", fshader: "fshader-uvec3-1", desc: "vertex shader uvec3" },
+ { vshader: "vshader-simple", fshader: "fshader-uvec3-2", desc: "fragment shader uvec3" },
+ { vshader: "vshader-ivec4-1", fshader: "fshader-ivec4-1", desc: "vertex shader ivec4" },
+ { vshader: "vshader-simple", fshader: "fshader-ivec4-2", desc: "fragment shader ivec4" },
+ { vshader: "vshader-uvec4-1", fshader: "fshader-uvec4-1", desc: "vertex shader uvec4" },
+ { vshader: "vshader-simple", fshader: "fshader-uvec4-2", desc: "fragment shader uvec4" },
+ ];
+
+ 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/conformance2/glsl3/compare-structs-containing-arrays.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/compare-structs-containing-arrays.html
new file mode 100644
index 0000000000..4748ae5153
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/compare-structs-containing-arrays.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>GLSL array equality test with structs containing arrays</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>
+<!--
+Structure array comparisons are detailed in the ESSL 3.00 spec section 5.7
+-->
+<script id="fshader-same-struct" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 color;
+
+struct MyStruct {
+ bool a[2];
+};
+
+void main() {
+ MyStruct b;
+ b.a[0] = true;
+ b.a[1] = false;
+
+ MyStruct c;
+ c.a[0] = true;
+ c.a[1] = false;
+
+ color = b == c ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);
+}
+</script>
+<script id="fshader-different-struct" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 color;
+
+struct MyStruct {
+ bool a[2];
+};
+
+void main() {
+ MyStruct b;
+ b.a[0] = true;
+ b.a[1] = true;
+
+ MyStruct c;
+ c.a[0] = true;
+ c.a[1] = false;
+
+ color = b != c ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Comparing structs containing arrays should work.");
+debug("");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshader-same-struct',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Comparing two structs containing arrays with the same values should equal to each other'
+},
+{
+ fShaderId: 'fshader-different-struct',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Comparing two structs containing arrays with different values should not equal to each other'
+},
+], 2);
+
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/compound-assignment-type-combination.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/compound-assignment-type-combination.html
new file mode 100644
index 0000000000..76d70efd7b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/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(2)">
+<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/conformance2/glsl3/const-array-init.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/const-array-init.html
new file mode 100644
index 0000000000..c992c03b63
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/const-array-init.html
@@ -0,0 +1,98 @@
+<!--
+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>Constant array initialization 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="fshaderGlobalConstArray" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 my_FragColor;
+
+const vec4 constants[2] = vec4[] (
+ vec4(0.6, 0.3, 0.0, 3.0),
+ vec4(-0.6, 0.7, 0.0, -2.0)
+);
+
+void main()
+{
+ my_FragColor = constants[0] + constants[1];
+ return;
+}
+</script>
+<script id="fshaderGlobalConstArrayWithReferenceToConstArray" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 my_FragColor;
+
+const vec4 constants[2] = vec4[] (
+ vec4(0.6, 0.3, 0.0, 3.0),
+ vec4(-0.6, 0.7, 0.0, -2.0)
+);
+
+const vec4 constants2[2] = vec4[] (
+ constants[1],
+ constants[0]
+);
+
+void main()
+{
+ my_FragColor = constants2[0] + constants2[1];
+ return;
+}
+</script>
+<script id="fshaderGlobalConstArrayInitializedToConstArray" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 my_FragColor;
+
+const vec4 constants[2] = vec4[] (
+ vec4(0.6, 0.3, 0.0, 3.0),
+ vec4(-0.6, 0.7, 0.0, -2.0)
+);
+
+const vec4 constants2[2] = constants;
+
+void main()
+{
+ my_FragColor = constants2[0] + constants2[1];
+ return;
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description("Test initializing a constant global array");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderGlobalConstArray',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Global constant array with vec4 constructors and literals in the initializer"
+},
+{
+ fShaderId: 'fshaderGlobalConstArrayWithReferenceToConstArray',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Global constant array which indexes another global constant array in the initializer"
+},
+{
+ fShaderId: 'fshaderGlobalConstArrayInitializedToConstArray',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Global constant array initialized to another global constant array"
+}
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/const-struct-from-array-as-function-parameter.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/const-struct-from-array-as-function-parameter.html
new file mode 100644
index 0000000000..e67e0e0dd5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/const-struct-from-array-as-function-parameter.html
@@ -0,0 +1,59 @@
+<!--
+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 passing struct from a const array into a function parameter 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="fShaderTest" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+struct S { float member; };
+
+const S s[2] = S[]( S(1.), S(2.));
+
+bool useStruct( S s) { return s.member > 0.0; }
+
+out vec4 outColor;
+
+void main( void )
+{
+ outColor = vec4(0.0, 0.0, 0.0, 1.0);
+ for (int i = 0; i < 2; ++i) {
+ if (useStruct(s[i])) {
+ outColor.g++;
+ }
+ }
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+
+// Covers bug:
+// http://crbug.com/871434
+
+GLSLConformanceTester.runTests([
+{
+ fShaderId: 'fShaderTest',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Passing a struct from a dynamically indexed const array into a non-const function parameter should work.',
+ render: true
+}
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/float-parsing.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/float-parsing.html
new file mode 100644
index 0000000000..fcd4d8a731
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/float-parsing.html
@@ -0,0 +1,167 @@
+<!--
+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>Float parsing corner 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="fshaderParsedFloatOverflowToInfinity" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+
+void main()
+{
+ // Out-of-range floats should overflow to infinity
+ // GLSL ES 3.00.6 section 4.1.4 Floats:
+ // "If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity"
+ float correct = isinf(1.0e40) ? 1.0 : 0.0;
+ my_FragColor = vec4(0.0, correct, 0.0, 1.0);
+}
+</script>
+<script id="fshaderParsedFloatUnderflowToZero" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+
+void main()
+{
+ // GLSL ES 3.00.6 section 4.1.4 Floats:
+ // "A value with a magnitude too small to be represented as a mantissa and exponent is converted to zero."
+ // 1.0e-50 is small enough that it can't even be stored as subnormal.
+ float correct = (1.0e-50 == 0.0) ? 1.0 : 0.0;
+ my_FragColor = vec4(0.0, correct, 0.0, 1.0);
+}
+</script>
+<script id="fshaderParsedFloatSmallMantissa" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+
+void main()
+{
+ // GLSL ES 3.00.6 section 4.1.4 Floats:
+ // "There is no limit on the number of digits in any digit-sequence."
+ // The below float string has 100 zeros after the decimal point, but represents 1.0.
+ float x = 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e101;
+ my_FragColor = vec4(0.0, x, 0.0, 1.0);
+}
+</script>
+<script id="fshaderParsedFloatLargeMantissa" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+
+void main()
+{
+ // GLSL ES 3.00.6 section 4.1.4 Floats:
+ // "There is no limit on the number of digits in any digit-sequence."
+ // The below float string has 100 zeros, but represents 1.0.
+ float x = 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0e-100;
+ my_FragColor = vec4(0.0, x, 0.0, 1.0);
+}
+</script>
+<script id="fshaderParsedFloatExponentAboveMaxInt" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+
+void main()
+{
+ // Out-of-range floats should overflow to infinity
+ // GLSL ES 3.00.6 section 4.1.4 Floats:
+ // "If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity"
+ float correct = isinf(1.0e2147483649) ? 1.0 : 0.0;
+ my_FragColor = vec4(0.0, correct, 0.0, 1.0);
+}
+</script>
+<script id="fshaderNonConstFloatIsInfinity" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+
+uniform float u; // Assumed to have the default value 0.0
+
+void main()
+{
+ // Out-of-range floats should overflow to infinity
+ // GLSL ES 3.00.6 section 4.1.4 Floats:
+ // "If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity"
+ float f = 1.0e2048 - u;
+ float correct = (isinf(f) && f > 0.0) ? 1.0 : 0.0;
+ my_FragColor = vec4(0.0, correct, 0.0, 1.0);
+}
+</script>
+<script id="fshaderNonConstFloatIsNegativeInfinity" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+
+uniform float u; // Assumed to have the default value 0.0
+
+void main()
+{
+ // Out-of-range floats should overflow to infinity
+ // GLSL ES 3.00.6 section 4.1.4 Floats:
+ // "If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity"
+ float f = -1.0e2048 + u;
+ float correct = (isinf(f) && f < 0.0) ? 1.0 : 0.0;
+ my_FragColor = vec4(0.0, correct, 0.0, 1.0);
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description();
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderParsedFloatOverflowToInfinity',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Floats of too large magnitude should be converted infinity."
+},
+{
+ fShaderId: 'fshaderParsedFloatUnderflowToZero',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Floats of too small magnitude should be converted to zero."
+},
+{
+ fShaderId: 'fshaderParsedFloatSmallMantissa',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Number of digits in any digit-sequence is not limited - test with a small mantissa and large exponent."
+},
+{
+ fShaderId: 'fshaderParsedFloatLargeMantissa',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Number of digits in any digit-sequence is not limited - test with a large mantissa and negative exponent."
+},
+{
+ fShaderId: 'fshaderParsedFloatExponentAboveMaxInt',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Test that an exponent that slightly overflows signed 32-bit int range works."
+},
+{
+ fShaderId: 'fshaderNonConstFloatIsInfinity',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Test that a non-constant float that has infinity as a value is processed correctly by isinf()."
+},
+{
+ fShaderId: 'fshaderNonConstFloatIsNegativeInfinity',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Test that a non-constant float that has negative infinity as a value is processed correctly by isinf()."
+}
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forbidden-operators.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forbidden-operators.html
new file mode 100644
index 0000000000..ec5c7c9bfb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forbidden-operators.html
@@ -0,0 +1,124 @@
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL GLSL Conformance Tests - Unsupported variants of operators</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="fshader-array-ternary-operator" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+void main()
+{
+ float a[3];
+ float b[3];
+ float c[3] = true ? a : b;
+}
+</script>
+<script id="fshader-struct-array-ternary-operator" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+struct MyStruct {
+ bool a[3];
+};
+
+void main()
+{
+ MyStruct b;
+ MyStruct c;
+ MyStruct d = true ? b : c;
+}
+</script>
+<script id="fshader-void-ternary-operator" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+void foo() {}
+
+void main()
+{
+ true ? foo() : foo();
+}
+</script>
+<script id="fshader-array-sequence-operator" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+void main()
+{
+ float a[3];
+ float b[3] = (true, a);
+}
+</script>
+<script id="fshader-struct-array-sequence-operator" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+struct MyStruct {
+ bool a[3];
+};
+
+void main()
+{
+ MyStruct b;
+ MyStruct c = (true, b);
+}
+</script>
+<script id="fshader-void-sequence-operator" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+void foo() {}
+
+void main()
+{
+ (foo(), foo());
+}
+</script>
+<script>
+"use strict";
+description("Check unsupported variants of operators.");
+
+// WebGL 2.0 spec section "Unsupported variants of GLSL ES 3.00 operators"
+
+GLSLConformanceTester.runTests([
+{ fShaderId: 'fshader-array-ternary-operator',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Using ternary operators with arrays is not allowed",
+},
+{ fShaderId: 'fshader-struct-array-ternary-operator',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Using ternary operators with structs containing arrays is not allowed",
+},
+{ fShaderId: 'fshader-void-ternary-operator',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Using ternary operators with void is not allowed",
+},
+{ fShaderId: 'fshader-array-sequence-operator',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Using sequence operators with arrays is not allowed",
+},
+{ fShaderId: 'fshader-struct-array-sequence-operator',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Using sequence operators with structs containing arrays is not allowed",
+},
+{ fShaderId: 'fshader-void-sequence-operator',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Using sequence operators with void is not allowed",
+}
+], 2);
+
+debug("");
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forward-declaration.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forward-declaration.html
new file mode 100644
index 0000000000..b3afcb846d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forward-declaration.html
@@ -0,0 +1,90 @@
+<!--
+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 3.00 forward declaration 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="vertexShaderForwardDecl" type="x-shader/x-vertex">#version 300 es
+precision mediump float;
+
+// Forward declaration. Breaks on Pixel C due to flattening of
+// precision qualifiers. It seems the GLSL compiler can't handle the
+// precision qualifier on the return value.
+float identity(float val);
+
+float identity(float val) {
+ return val;
+}
+
+void main(void) {
+ gl_Position = vec4(identity(1.0), 0.0, 0.0, 1.0);
+}
+</script>
+<script id="vertexShader" type="x-shader/x-vertex">#version 300 es
+void main(void) {
+ gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script id="fragmentShader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+void main(void) {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="fragmentShaderForwardDecl" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+// Forward declaration. Breaks on Pixel C due to flattening of
+// precision qualifiers. It seems the GLSL compiler can't handle the
+// precision qualifier on the return value.
+float identity(float val);
+
+float identity(float val) {
+ return val;
+}
+
+out vec4 my_FragColor;
+void main(void) {
+ my_FragColor = vec4(0.0, identity(1.0), 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Forward declarations of functions should succeed.");
+
+GLSLConformanceTester.runTests([
+ {
+ vShaderId: "vertexShaderForwardDecl",
+ vShaderSuccess: true,
+ fShaderId: "fragmentShader",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "vertex shader with forward declaration must pass",
+ },
+ {
+ vShaderId: "vertexShader",
+ vShaderSuccess: true,
+ fShaderId: "fragmentShaderForwardDecl",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "fragment shader with forward declaration must pass",
+ },
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/frag-depth.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/frag-depth.html
new file mode 100644
index 0000000000..afbbfad741
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/frag-depth.html
@@ -0,0 +1,157 @@
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Frag Depth Conformance 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>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<!-- Shaders for testing fragment depth writing -->
+
+<!-- Shader omitting the required #version -->
+<script id="fragmentShaderESSL1" type="x-shader/x-fragment">
+precision mediump float;
+void main() {
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ gl_FragDepth = 1.0;
+}
+</script>
+<!-- Shader with required #version -->
+<script id="fragmentShaderESSL3" 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);
+ gl_FragDepth = 1.0;
+}
+</script>
+<!-- Shader using the EXT suffix -->
+<script id="fragmentShaderESSL3EXT" 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);
+ gl_FragDepthEXT = 1.0;
+}
+</script>
+<!-- Shaders to link with test fragment shaders -->
+<script id="vertexShaderESSL1" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+void main() {
+ gl_Position = vPosition;
+}
+</script>
+<script id="vertexShaderESSL3" type="x-shader/x-vertex">#version 300 es
+in vec4 vPosition;
+void main() {
+ gl_Position = vPosition;
+}
+</script>
+
+<!-- Shader to test output -->
+<script id="outputFragmentShader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform float uDepth;
+
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ gl_FragDepth = uDepth;
+}
+</script>
+
+<script>
+"use strict";
+description("This test verifies the functionality of setting fragment depth in a shader.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runShaderTests();
+ debug("");
+ runOutputTests();
+}
+
+function runShaderTests() {
+ debug("");
+ debug("Testing various shader compiles");
+
+ // Always expect ESSL1 shaders to fail
+ var fragmentProgramESSL1 = wtu.loadProgramFromScriptExpectError(gl, "vertexShaderESSL1", "fragmentShaderESSL1");
+ if (fragmentProgramESSL1) {
+ testFailed("gl_FragDepth allowed in ESSL1 shader - should be disallowed");
+ } else {
+ testPassed("gl_FragDepth disallowed in ESSL1 shader");
+ }
+
+ // Try to compile a shader using the built-ins that should only succeed if enabled
+ var testFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "vertexShaderESSL3", "fragmentShaderESSL3");
+ if (testFragmentProgram) {
+ testPassed("gl_FragDepth allowed in ESSL3 shader");
+ } else {
+ testFailed("gl_FragDepth disallowed in ESSL3 shader");
+ }
+
+ var testFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "vertexShaderESSL3", "fragmentShaderESSL3EXT");
+ if (testFragmentProgram) {
+ testFailed("gl_FragDepthEXT allowed in ESSL3 shader - should only allow gl_FragDepth");
+ } else {
+ testPassed("gl_FragDepthEXT disallowed in ESSL3 shader");
+ }
+}
+
+function runOutputTests() {
+ debug("Testing rendering results from writing to gl_FragData");
+
+ canvas.width = 50; canvas.height = 50;
+ gl.viewport(0, 0, canvas.width, canvas.height);
+
+ // Enable depth testing with a clearDepth of 0.5
+ // This makes it so that fragments are only rendered when
+ // gl_FragDepth is < 0.5
+ gl.clearDepth(0.5);
+ gl.enable(gl.DEPTH_TEST);
+
+ var positionLoc = 0;
+ var texcoordLoc = 1;
+ var program = wtu.setupProgram(gl, ["vertexShaderESSL3", "outputFragmentShader"], ['vPosition'], [0]);
+ var quadParameters = wtu.setupUnitQuad(gl, 0, 1);
+ var depthUniform = gl.getUniformLocation(program, "uDepth");
+
+ // Draw 1: Greater than clear depth
+ gl.uniform1f(depthUniform, 1.0);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 255, 255, 255]);
+
+ // Draw 2: Less than clear depth
+ gl.uniform1f(depthUniform, 0.0);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, 255]);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/fragment-shader-loop-crash.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/fragment-shader-loop-crash.html
new file mode 100644
index 0000000000..a171b94e26
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/fragment-shader-loop-crash.html
@@ -0,0 +1,72 @@
+<!--
+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>Fragment shader containing loop 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>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+precision highp float;
+out vec2 v_tex_coord;
+uniform mat4 matrix;
+
+void main() {
+ v_tex_coord = vec2(0.0, 0.0);
+ gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+
+in vec2 v_tex_coord;
+out vec4 out_color;
+
+uniform sampler2D texture_1;
+uniform vec2 resolution;
+
+vec4 do_loops(vec4 z)
+{
+ vec4 v[16];
+ for (int i = 0; i < 16; i++)
+ {
+ v[i] = z;
+ }
+ return v[1];
+}
+
+void main() {
+ out_color = do_loops(vec4(0.2, 0.4, 0.6, 1.0)) - texture(texture_1, v_tex_coord);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+const wtu = WebGLTestUtils;
+const tests = [
+ {
+ vShaderSource: wtu.getScript('vshader'),
+ fShaderSource: wtu.getScript('fshader'),
+ vShaderSuccess: true,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Fragment shader containing a simple loop should compile and link'
+ }
+];
+
+GLSLConformanceTester.runTests(tests, 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/gradient-in-discontinuous-loop.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/gradient-in-discontinuous-loop.html
new file mode 100644
index 0000000000..db13d61f6e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/gradient-in-discontinuous-loop.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>Short circuit in loop condition 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vertex-shader" type="x-shader/x-vertex">#version 300 es
+ precision highp float;
+ in vec4 aPosition;
+
+ void main() {
+ gl_Position = aPosition;
+ }
+</script>
+<script id="fragment-shader" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+precision highp int;
+
+uniform vec4 iMouse;
+uniform sampler2D iChannel0;
+
+float map(float p)
+{
+ return texture(iChannel0, vec2(p, p), 0.0).y;
+}
+
+out vec4 outColor;
+
+void main(void)
+{
+ float sum = 0.0;
+
+ for(int i=0; i<1000; i++)
+ {
+ if( sum > 0.99 ) break;
+ float p = iMouse.x + gl_FragCoord.x;
+ sum = map(p);
+ }
+
+ outColor = vec4(sum);
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description("Test an HLSL compiler freeze on a gradient inside a discontinuous loop.");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(undefined, undefined, 2);
+wtu.setupUnitQuad(gl);
+
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ var program = wtu.setupProgram(gl, ["vertex-shader", "fragment-shader"], ['aPosition'], undefined, true);
+ if (!program) {
+ testFailed('Program compilation failed');
+ }
+}
+var successfullyParsed = true;
+finishTest();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/input-with-interpotaion-as-lvalue.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/input-with-interpotaion-as-lvalue.html
new file mode 100644
index 0000000000..fa6d87cd12
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/input-with-interpotaion-as-lvalue.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>Negative tests for writting to a shader input with interpolation qualifier</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>
+<!--
+According to ESSL 3.00.6 section 4.3.4:
+"Variables declared as in or centroid in may not be written to during shader execution.",
+these tests ensure that a compile error is generated when using a shader input with interpolation qualifier as l-value.
+-->
+<script type="application/javascript">
+"use strict";
+description();
+
+var vertexShaderTemplate = [
+ '#version 300 es',
+ '$(InterpolationQualifier) out float v_float_varying;',
+ 'void main()',
+ '{',
+ ' v_float_varying = 1.0;',
+ ' gl_Position = vec4(0.0, 0.0, 0.0, 1.0);',
+ '}'
+].join('\n');
+
+var fragmentShaderTemplate = [
+ '#version 300 es',
+ 'precision mediump float;',
+ '$(InterpolationQualifier) in float v_float_varying;',
+ 'out vec4 my_color;',
+ 'void main()',
+ '{',
+ ' v_float_varying = 1.0;',
+ ' my_color = vec4(1.0, 0.0, 0.0, v_float_varying);',
+ '}'
+].join('\n');
+
+var errorMessageTemplate = "Writting to shader inputs with '$(InterpolationQualifier)' qualifier must fail";
+
+var testDataList = [
+{
+ InterpolationQualifier: 'flat'
+},
+{
+ InterpolationQualifier: 'smooth'
+},
+{
+ InterpolationQualifier: 'centroid'
+}
+];
+
+var wtu = WebGLTestUtils;
+
+var tests = [];
+for (var i = 0; i < testDataList.length; ++i) {
+ tests.push({
+ vShaderSource: wtu.replaceParams(vertexShaderTemplate, testDataList[i]),
+ vShaderSuccess: true,
+ fShaderSource: wtu.replaceParams(fragmentShaderTemplate, testDataList[i]),
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: wtu.replaceParams(errorMessageTemplate, testDataList[i])
+ });
+}
+
+GLSLConformanceTester.runTests(tests, 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-default-precision.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-default-precision.html
new file mode 100644
index 0000000000..375c95610c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-default-precision.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>Default precision qualifiers should only work with int, float and sampler types</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>
+<!-- See ESSL 3.00 section 4.5.4 -->
+<script id="precisionVec" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+precision mediump vec2;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="precisionVoid" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+precision mediump void;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="precisionUint" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+precision mediump uint;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+GLSLConformanceTester.runTests([
+ {
+ fShaderId: "precisionVec",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "default precision qualifier shouldn't work with vec2"
+ },
+ {
+ fShaderId: "precisionVoid",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "default precision qualifier shouldn't work with void"
+ },
+ {
+ fShaderId: "precisionUint",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "default precision qualifier shouldn't work with uint"
+ }
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-invariant.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-invariant.html
new file mode 100644
index 0000000000..f0d2b46ad1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-invariant.html
@@ -0,0 +1,88 @@
+<!--
+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>Negative tests for the use of the invariant qualifier and pragma</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="vertexShaderInvariant" type="text/something-not-javascript">#version 300 es
+precision mediump float;
+invariant out vec4 v_varying;
+
+void main()
+{
+ v_varying = vec4(0.0, 0.0, 0.0, 1.0);
+ gl_Position = v_varying;
+}
+</script>
+<script id="fragmentShaderVariant" type="text/something-not-javascript">#version 300 es
+precision mediump float;
+
+in vec4 v_varying;
+out vec4 my_color;
+
+void main()
+{
+ my_color = v_varying;
+}
+</script>
+<script id="fragmentShaderInputInvariant" type="text/something-not-javascript">#version 300 es
+precision mediump float;
+
+invariant in vec4 v_varying;
+out vec4 my_color;
+
+void main()
+{
+ my_color = v_varying;
+}
+</script>
+<script id="fragmentShaderGlobalInvariant" type="text/something-not-javascript">#version 300 es
+#pragma STDGL invariant(all)
+precision mediump float;
+
+in vec4 v_varying;
+out vec4 my_color;
+
+void main()
+{
+ my_color = v_varying;
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+GLSLConformanceTester.runTests([
+ {
+ vShaderId: "vertexShaderInvariant",
+ vShaderSuccess: true,
+ fShaderId: "fragmentShaderGlobalInvariant",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "fragment shader with global invariant pragma must fail",
+ },
+ {
+ vShaderId: "vertexShaderInvariant",
+ vShaderSuccess: true,
+ fShaderId: "fragmentShaderInputInvariant",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "fragment shader with an input variable which is invariant must fail",
+ },
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/loops-with-side-effects.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/loops-with-side-effects.html
new file mode 100644
index 0000000000..c8a977b8ca
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/loops-with-side-effects.html
@@ -0,0 +1,211 @@
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Loops and side-effects 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>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+
+<!-- Variations on counter functions that used to give incorrect result on OSX 10.9 -->
+<script id="counter0" type="x-shader/x-shader">
+bool s0 = false;
+while(true) {
+ bool bar = s0;
+ if (!bar) {
+ bar = i < 3;
+ i = i + 1;
+ }
+ bool foo = !bar;
+ if (foo) {
+ break;
+ }
+ s0 = false;
+ n ++;
+}
+return n;
+</script>
+<script id="counter1" type="x-shader/x-shader">
+while(true) {
+ bool bar = i < 3;
+ i = i + 1;
+ bool foo = !bar;
+ if (foo) {
+ break;
+ }
+ n ++;
+}
+return n;
+</script>
+<script id="counter2" type="x-shader/x-shader">
+bool s0 = true;
+while(true) {
+ bool bar = s0;
+ if (!bar) {
+ bar = i < 3;
+ i = i + 1;
+ }
+ bool foo = !bar;
+ if (foo) {
+ break;
+ }
+ s0 = false;
+ n ++;
+}
+return n;
+</script>
+<script id="counter3" type="x-shader/x-shader">
+bool s0 = true;
+while(true) {
+ bool bar = s0;
+ if (!bar) {
+ bar = i++ < 3;
+ }
+ bool foo = !bar;
+ if (foo) {
+ break;
+ }
+ s0 = false;
+ n ++;
+}
+return n;
+</script>
+<script id="counter4" type="x-shader/x-shader">
+bool s0 = true;
+while(true) {
+ bool bar = s0 || (i++ < 3);
+ bool foo = !bar;
+ if (foo) {
+ break;
+ }
+ s0 = false;
+ n ++;
+}
+return n;
+</script>
+<script id="counter5" type="x-shader/x-shader">
+bool s0 = true;
+while(true) {
+ if (!(s0 || (i++ < 3))) {
+ break;
+ }
+ s0 = false;
+ n ++;
+}
+return n;
+</script>
+<script id="counter6" type="x-shader/x-shader">
+bool s0 = true;
+while(s0 || (i++ < 3)) {
+ s0 = false;
+ n ++;
+}
+return n;
+</script>
+
+<script id="counter7" type="x-shader/x-shader">
+do {
+ n++;
+} while (i++ < 3);
+return n;
+</script>
+<script>
+"use strict";
+description("This test checks for bugs related to loops and side-effects.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ for (var i = 0; i < 8; i++) {
+ tryCounter(document.getElementById("counter" + i).text);
+ debug("");
+ }
+}
+
+function evaluateCounter(source) {
+ var jsSource = "(function(n, i) {" +
+ source.split("bool").join("var") +
+ "})(0, 0)";
+
+ return eval(jsSource);
+}
+
+function makeFSSource(source) {
+ var fsSource =
+ "#version 300 es\n" +
+ "precision highp float;\n" +
+ "in float vertexCounter;\n" +
+ "uniform int uVertZero;\n" +
+ "uniform int uReference;\n" +
+ "out vec4 fragColor;\n" +
+ "int counter(int n, int i) {\n" +
+ source +
+ "}\n" +
+ "void main() {\n" +
+ " fragColor = vec4(0.0, 0.0, 0.0, 1.0);\n" +
+ " fragColor.r = float(counter(uVertZero, uVertZero) == uReference);\n" +
+ " fragColor.g = float(int(vertexCounter) == uReference);\n" +
+ "}\n";
+ return fsSource;
+}
+
+function makeVSSource(source) {
+ var vsSource =
+ "#version 300 es\n" +
+ "out float vertexCounter;\n" +
+ "uniform int uFragZero;\n" +
+ "in vec4 vPosition;\n" +
+ "int counter(int n, int i) {\n" +
+ source +
+ "}\n" +
+ "void main() {\n" +
+ " gl_Position = vPosition;\n" +
+ " vertexCounter = float(counter(uFragZero, uFragZero));\n" +
+ "}\n";
+ return vsSource;
+}
+
+function tryCounter(source) {
+ canvas.width = 50; canvas.height = 50;
+ gl.viewport(0, 0, canvas.width, canvas.height);
+ wtu.setupUnitQuad(gl, 0, 1);
+
+ var program = wtu.setupProgram(gl, [makeVSSource(source), makeFSSource(source)], ['vPosition'], [0], true);
+
+ gl.uniform1i(gl.getUniformLocation(program, "uVertZero"), 0);
+ gl.uniform1i(gl.getUniformLocation(program, "uFragZero"), 0);
+
+ var reference = evaluateCounter(source);
+ gl.uniform1i(gl.getUniformLocation(program, "uReference"), reference);
+
+ gl.useProgram(program);
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 0]);
+ wtu.checkCanvas(gl, [255, 255, 0, 255]);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major-dynamic-indexing.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major-dynamic-indexing.html
new file mode 100644
index 0000000000..ec6a9bbd1b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major-dynamic-indexing.html
@@ -0,0 +1,118 @@
+<!--
+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>Dynamically-indexed row-major matrix 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="fshaderIndexRowMajorMatrixArrayInUniformBlock" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+layout(row_major) uniform a {
+ mat4 u_mats[1];
+};
+
+void main() {
+ float f = u_mats[u_zero + 0][2][1];
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderRowMatrixIndexedByRowMatrixInUniformBlock" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+uniform Stuff {
+ layout(row_major) mat4 u_mat[3];
+ layout(row_major) mat4 u_ndx[3];
+} stuff;
+
+
+out vec4 my_FragColor;
+
+void main() {
+ vec4 row = stuff.u_mat[int(stuff.u_ndx[1][1][3])][2];
+ my_FragColor = row == vec4(9, 10, 11, 12) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Indexing row-major matrices within a uniform block should work");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderIndexRowMajorMatrixArrayInUniformBlock',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: '',
+ uniformBlocks: [{name: "a", value: new Float32Array([
+ 0, 0, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ ])}],
+},
+{
+ fShaderId: 'fshaderRowMatrixIndexedByRowMatrixInUniformBlock',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: '',
+ uniformBlocks: [{name: "Stuff", value: new Float32Array([
+ // mat4 u_mat[3]
+ 1, 2, 3, 4,
+ 5, 6, 7, 8,
+ 9, 10, 11, 12,
+ 13, 14, 15, 16,
+
+ // +-- we should be pulling out this column
+ // |
+ // V
+ 1, 5, 9, 13,
+ 2, 6, 10, 14,
+ 3, 7, 11, 15,
+ 4, 8, 12, 16,
+
+ 2, 10, 18, 22,
+ 4, 12, 20, 28,
+ 6, 14, 22, 30,
+ 8, 16, 24, 32,
+
+ // mat4 u_ndx[3]
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+
+ 0, 0, 0, 0,
+ 0, 0, 0, 2,
+ 0, 0, 0, 0,
+ 0, 1, 0, 0,
+ // ^
+ // |
+ // +-- we should be reading this value as an index into u_mat
+
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ ])}],
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major.html
new file mode 100644
index 0000000000..3c56bdacf1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major.html
@@ -0,0 +1,51 @@
+<!--
+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>Row-major matrix 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="fshaderUniformMatrixRowMajor" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out highp vec4 my_FragColor;
+layout(std140, row_major) uniform b {
+ mat4x3 m;
+};
+void main() {
+ // If the matrix is interpreted as row-major, then the translation components will be 0,1,0, or solid green.
+ my_FragColor = mat4(m) * vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Row-major matrix layouts should work.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderUniformMatrixRowMajor',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: '',
+ uniformBlocks: [{name: "b", value: new Float32Array([
+ 0, 0, 0, 0, // Red
+ 0, 0, 0, 1, // Green
+ 0, 0, 0, 0, // Blue
+ ])}]
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/misplaced-version-directive.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/misplaced-version-directive.html
new file mode 100644
index 0000000000..e0168c5830
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/misplaced-version-directive.html
@@ -0,0 +1,111 @@
+<!--
+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>#version directive should be on the very first line of a OpenGL ES Shading Language 3.00 shader</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>
+<!-- Version directive should be on the very first line in ESSL 3, see ESSL 3 section 3.3 -->
+<script id="VertexShaderCommentBeforeVersion" type="x-shader/x-vertex">// This shader is wrong, this is the first line that should have version
+#version 300 es
+precision mediump float;
+in vec4 aPosition;
+
+void main() {
+ gl_Position = aPosition;
+}
+</script>
+<script id="VertexShaderNewlineBeforeVersion" type="x-shader/x-vertex">
+#version 300 es
+precision mediump float;
+in vec4 aPosition;
+
+void main() {
+ gl_Position = aPosition;
+}
+</script>
+<script id="CorrectVertexShader" type="x-shader/x-vertex">#version 300 es
+precision mediump float;
+in vec4 aPosition;
+
+void main() {
+ gl_Position = aPosition;
+}
+</script>
+<script id="FragmentShaderCommentBeforeVersion" type="x-shader/x-fragment">// This shader is wrong, this is the first line that should have version
+#version 300 es
+precision mediump float;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="FragmentShaderNewlineBeforeVersion" type="x-shader/x-fragment">
+#version 300 es
+precision mediump float;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="CorrectFragmentShader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+GLSLConformanceTester.runTests([
+ {
+ vShaderId: "VertexShaderNewlineBeforeVersion",
+ vShaderSuccess: false,
+ fShaderId: "CorrectFragmentShader",
+ fShaderSuccess: true,
+ linkSuccess: false,
+ passMsg: "Vertex shader with a newline before the version directive should fail."
+ },
+ {
+ vShaderId: "VertexShaderCommentBeforeVersion",
+ vShaderSuccess: false,
+ fShaderId: "CorrectFragmentShader",
+ fShaderSuccess: true,
+ linkSuccess: false,
+ passMsg: "Vertex shader with a comment before the version directive should fail."
+ },
+ {
+ vShaderId: "CorrectVertexShader",
+ vShaderSuccess: true,
+ fShaderId: "FragmentShaderCommentBeforeVersion",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Fragment shader with a comment before the version directive should fail."
+ },
+ {
+ vShaderId: "CorrectVertexShader",
+ vShaderSuccess: true,
+ fShaderId: "FragmentShaderNewlineBeforeVersion",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Fragment shader with a newline before the version directive should fail."
+ }
+], 2);
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/no-attribute-vertex-shader.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/no-attribute-vertex-shader.html
new file mode 100644
index 0000000000..eabbd9779d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/no-attribute-vertex-shader.html
@@ -0,0 +1,63 @@
+<!--
+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>Test no attribute vertex 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vertex-shader" type="x-shader/x-vertex">#version 300 es
+
+void main() {
+ ivec2 xy = ivec2(
+ gl_VertexID % 2,
+ (gl_VertexID / 2 + gl_VertexID / 3) % 2);
+ gl_Position = vec4(vec2(xy) * 2. - 1., 0, 1);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 result;
+void main() {
+ result = vec4(0, 1, 0, 1);
+}
+</script>
+<script>
+"use strict";
+description("Test no attribute shaders work as expected");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+function test() {
+ debug("");
+ var program = wtu.setupProgram(gl, ["vertex-shader", "fshader"], undefined, undefined, true);
+ if (!program) {
+ testFailed('Program compilation failed');
+ return;
+ }
+
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green", 0);
+};
+
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ test();
+}
+var successfullyParsed = true;
+finishTest();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/precision-side-effects-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/precision-side-effects-bug.html
new file mode 100644
index 0000000000..c717c4ee94
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/precision-side-effects-bug.html
@@ -0,0 +1,125 @@
+<!--
+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>Verify precision side effects (Adreno 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-simple" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+
+void main() {
+ gl_Position = vec4(aPosition, 1.0);
+}
+</script>
+<script id="fshader-int" type="x-shader/x-fragment">#version 300 es
+out highp vec4 myFragColor;
+void main() {
+ highp int t;
+ t = 0 | (int(t == t) * 0x8000);
+
+ if (t == 0x8000)
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script id="fshader-ivec2" type="x-shader/x-fragment">#version 300 es
+out highp vec4 myFragColor;
+void main() {
+ highp ivec2 t;
+ t = 0 | (ivec2(t == t) * 0x8000);
+
+ if (t == ivec2(0x8000))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script id="fshader-ivec3" type="x-shader/x-fragment">#version 300 es
+out highp vec4 myFragColor;
+void main() {
+ highp ivec3 t;
+ t = 0 | (ivec3(t == t) * 0x8000);
+
+ if (t == ivec3(0x8000))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script id="fshader-ivec4" type="x-shader/x-fragment">#version 300 es
+out highp vec4 myFragColor;
+void main() {
+ highp ivec4 t;
+ t = 0 | (ivec4(t == t) * 0x8000);
+
+ if (t == ivec4(0x8000))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Verify precision side effects");
+debug("");
+debug("When this test is run on Adreno (no repros on other vendors so far):");
+debug(" - the result of the expression 0 | (int(e0 == e0) * 0x8000) somehow returns -32768 instead of 32768 despite the variable using highp precision;");
+debug(" - splitting the expression along | fixes the issue (could also be observed with other operators).");
+debug('For additional reference see this <a href="https://github.com/KhronosGroup/WebGL/pull/3192">pull request</a> and <a href="http://crbug.com/1155942">Chromium bug</a>');
+debug("");
+var wtu = WebGLTestUtils;
+function test() {
+ var gl = wtu.create3DContext("canvas", undefined, 2);
+ if (!gl) {
+ testFailed("context does not exist");
+ return;
+ }
+ wtu.setupUnitQuad(gl);
+
+ var testCases = [
+ { vshader: "vshader-simple", fshader: "fshader-int", desc: "fragment shader int" },
+ { vshader: "vshader-simple", fshader: "fshader-ivec2", desc: "fragment shader ivec2" },
+ { vshader: "vshader-simple", fshader: "fshader-ivec3", desc: "fragment shader ivec3" },
+ { vshader: "vshader-simple", fshader: "fshader-ivec4", desc: "fragment shader ivec4" },
+ ];
+
+ 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 {
+ debug("Testing " + test.desc);
+ 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/conformance2/glsl3/reciprocal-sqrt-of-sum-of-squares-crash.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/reciprocal-sqrt-of-sum-of-squares-crash.html
new file mode 100644
index 0000000000..691523aea0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/reciprocal-sqrt-of-sum-of-squares-crash.html
@@ -0,0 +1,66 @@
+<!--
+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>Shader identified as containing reciprocal square root of sum of squares 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>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+void main() {
+ gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+
+#define CRASH 1
+
+out vec4 fragmentColor;
+void main()
+{
+ vec2 p = gl_FragCoord.xy;
+ // This expression meets the requirement of being the reciprocal
+ // square root of a sum of squares.
+ float d = 1.0 / length(p);
+#if CRASH
+ if (p.x > 0.0)
+ {
+ d *= 2.0;
+ }
+#endif
+ fragmentColor = vec4(d);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+debug('Regression test for <a href="https://crbug.com/1079309">crbug.com/1079309</a>');
+const wtu = WebGLTestUtils;
+const tests = [
+ {
+ vShaderSource: wtu.getScript('vshader'),
+ fShaderSource: wtu.getScript('fshader'),
+ vShaderSuccess: true,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Shader containing expression that driver recognizes as reciprocal square root of sum of squares should compile and link'
+ }
+];
+
+GLSLConformanceTester.runTests(tests, 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-array-indexing.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-array-indexing.html
new file mode 100644
index 0000000000..f2f124873b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-array-indexing.html
@@ -0,0 +1,94 @@
+<!--
+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>ESSL300 sampler array indexing rules</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="vs" type="text/plain">#version 300 es
+void main() {}
+</script>
+<script id="fs_constant_integer_expression" type="text/plain">#version 300 es
+precision mediump float;
+uniform sampler2D u_tex[2];
+
+void main()
+{
+ texture(u_tex[0], vec2(0));
+ texture(u_tex[1], vec2(0));
+}
+</script>
+<script id="fs_constant_index_expression" type="text/plain">#version 300 es
+precision mediump float;
+uniform sampler2D u_tex[2];
+
+void main()
+{
+ for (int i = 0; i < 2; i++) {
+ texture(u_tex[i], vec2(0));
+ }
+}
+</script>
+<script id="fs_constant_integer_expression_switch" type="text/plain">#version 300 es
+precision mediump float;
+uniform sampler2D u_tex[2];
+
+void main()
+{
+ for (int i = 0; i < 2; i++) {
+ switch (i) {
+ case 0:
+ texture(u_tex[0], vec2(0));
+ break;
+ case 1:
+ texture(u_tex[1], vec2(0));
+ break;
+ }
+ }
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+GLSLConformanceTester.runTests([
+ {
+ vShaderId: "vs",
+ vShaderSuccess: true,
+ fShaderId: "fs_constant_integer_expression",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "indexing into an array of samplers with constant-integer-expression is required",
+ },
+ {
+ vShaderId: "vs",
+ vShaderSuccess: true,
+ fShaderId: "fs_constant_index_expression",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "indexing into an array of samplers with constant-index-expression is forbidden in essl300",
+ },
+ {
+ vShaderId: "vs",
+ vShaderSuccess: true,
+ fShaderId: "fs_constant_integer_expression_switch",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "constant-index-expression can be converted into fs_constant_integer_expression via a switch",
+ },
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-no-precision.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-no-precision.html
new file mode 100644
index 0000000000..8205fa5c25
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-no-precision.html
@@ -0,0 +1,88 @@
+<!--
+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 sampler with no precision qualifier 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="vshaderSamplerNoPrecision" type="x-shader/x-vertex">#version 300 es
+precision mediump float;
+
+uniform $(samplerType) u_sampler;
+
+void main() {
+ gl_Position = vec4(0.0);
+}
+</script>
+<script id="fshaderSamplerNoPrecision" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform $(samplerType) u_sampler;
+
+void main() {
+ my_FragColor = vec4(0.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("ESSL3 sampler with no precision qualifier should not compile.");
+
+var wtu = WebGLTestUtils;
+
+var fragmentShaderTemplate = wtu.getScript('fshaderSamplerNoPrecision');
+var vertexShaderTemplate = wtu.getScript('vshaderSamplerNoPrecision');
+
+// ESSL 3.00.4 section 4.5.4 types with no predefined precision.
+var samplerTypes = [
+ 'sampler3D',
+ 'samplerCubeShadow',
+ 'sampler2DShadow',
+ 'sampler2DArray',
+ 'sampler2DArrayShadow',
+ 'isampler2D',
+ 'isampler3D',
+ 'isamplerCube',
+ 'isampler2DArray',
+ 'usampler2D',
+ 'usampler3D',
+ 'usamplerCube',
+ 'usampler2DArray'
+];
+
+var tests = [];
+
+for (var i = 0; i < samplerTypes.length; ++i) {
+ var type = samplerTypes[i];
+ var vertexShaderSrc = wtu.replaceParams(vertexShaderTemplate, {'samplerType': type});
+ tests.push({
+ vShaderSource: vertexShaderSrc,
+ vShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: 'Vertex shader with a ' + type + ' uniform with no precision qualifier should not compile'
+ });
+ var fragmentShaderSrc = wtu.replaceParams(fragmentShaderTemplate, {'samplerType': type});
+ tests.push({
+ fShaderSource: fragmentShaderSrc,
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: 'Fragment shader with a ' + type + ' uniform with no precision qualifier should not compile'
+ });
+}
+
+GLSLConformanceTester.runTests(tests, 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sequence-operator-returns-non-constant.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sequence-operator-returns-non-constant.html
new file mode 100644
index 0000000000..d5d0e5eb71
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sequence-operator-returns-non-constant.html
@@ -0,0 +1,59 @@
+<!--
+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>Sequence operator returns non-constant 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>
+<!--
+Sequence operator and non-constant expressions are detailed in the ESSL 3.00 spec section 12.43
+-->
+<script id="fshader-non-const-expression" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+void main() {
+ const float a = (0.0, 1.0);
+}
+</script>
+<script id="fshader-non-const-expression-as-array-size" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+void main() {
+ float a[(2, 3)];
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Checks sequence operators returning non-constants and cannot be used as an array size.");
+debug("");
+
+GLSLConformanceTester.runTests([
+{
+ fShaderId: 'fshader-non-const-expression',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: 'Sequence operator cannot return a constant expression'
+},
+{
+ fShaderId: 'fshader-non-const-expression-as-array-size',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: 'Sequence operator return value cannot be used as an array size'
+},
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-linking.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-linking.html
new file mode 100644
index 0000000000..6210e0577b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-linking.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>OpenGL ES Shading Language 1.00 and OpenGL ES Shading Language 3.00 shaders should not link with each other</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="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(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="ESSL1VertexShader" type="x-shader/x-vertex">
+precision mediump float;
+attribute vec4 aPosition;
+
+void main() {
+ gl_Position = aPosition;
+}
+</script>
+<script id="ESSL1FragmentShader" type="x-shader/x-fragment">
+precision mediump float;
+
+void main() {
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+// See OpenGL ES Shading Language 3.00 spec section 1.5 or 3.3
+GLSLConformanceTester.runTests([
+ {
+ vShaderId: "ES3VertexShader",
+ vShaderSuccess: true,
+ fShaderId: "ES3FragmentShader",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "OpenGL ES Shading Language 3.00 vertex shader should link with OpenGL ES Shading Language 3.00 fragment shader."
+ },
+ {
+ vShaderId: "ES3VertexShader",
+ vShaderSuccess: true,
+ fShaderId: "ESSL1FragmentShader",
+ fShaderSuccess: true,
+ linkSuccess: false,
+ passMsg: "OpenGL ES Shading Language 3.00 vertex shader should not link with OpenGL ES Shading Language 1.00 fragment shader."
+ },
+ {
+ vShaderId: "ESSL1VertexShader",
+ vShaderSuccess: true,
+ fShaderId: "ES3FragmentShader",
+ fShaderSuccess: true,
+ linkSuccess: false,
+ passMsg: "OpenGL ES Shading Language 1.00 vertex shader should not link with OpenGL ES Shading Language 3.00 fragment shader."
+ }
+], 2);
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-1024-character-define.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-1024-character-define.html
new file mode 100644
index 0000000000..26fae7b726
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-1024-character-define.html
@@ -0,0 +1,36 @@
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL GLSL Conformance Tests</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="vertexShader" type="text/something-not-javascript">
+// vertex shader that uses 1024 character token in #define should succeed
+#define LEN_1024_OK XxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxX
+
+void main()
+{
+ gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script>
+"use strict";
+GLSLConformanceTester.runTest();
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-1024-character-identifier.frag.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-1024-character-identifier.frag.html
new file mode 100644
index 0000000000..e69abd2428
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-1024-character-identifier.frag.html
@@ -0,0 +1,105 @@
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL GLSL Conformance Tests</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="fragmentShader1024" type="text/something-not-javascript">
+// shader that uses 1024 character identifier should succeed
+precision mediump float;
+uniform float a123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123;
+void main()
+{
+ gl_FragColor = vec4(a123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123, 0.0, 0.0, 1.0);
+}
+</script>
+<script id="fragmentShader_before" type="text/something-not-javascript">
+// shader that uses 1024 character identifier that starts with underscore should succeed
+precision mediump float;
+uniform float _a12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012;
+void main()
+{
+ gl_FragColor = vec4(_a12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012, 0.0, 0.0, 1.0);
+}
+</script>
+<script id="fragmentShader_after" type="text/something-not-javascript">
+// shader that uses 1024 character identifier that ends with underscore should succeed
+precision mediump float;
+uniform float a12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012_;
+void main()
+{
+ gl_FragColor = vec4(a12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012_, 0.0, 0.0, 1.0);
+}
+</script>
+<script id="fragmentShader1024_odd" type="text/something-not-javascript">
+// shader that uses 1024 character identifier with odd characters as underscores should succeed
+precision mediump float;
+uniform float a_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_;
+void main()
+{
+ gl_FragColor = vec4(a_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_4_6_8_0_2_, 0.0, 0.0, 1.0);
+}
+</script>
+<script id="fragmentShader1024_even" type="text/something-not-javascript">
+// shader that uses 1024 character identifier with even characters as underscores should succeed
+precision mediump float;
+uniform float a1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3;
+void main()
+{
+ gl_FragColor = vec4(a1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3_5_7_9_1_3, 0.0, 0.0, 1.0);
+}
+</script>
+<script>
+"use strict";
+GLSLConformanceTester.runTests([
+ {
+ fShaderId: 'fragmentShader1024',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'shader with 1024 character identifier should succeed'
+ },
+ {
+ fShaderId: 'fragmentShader_before',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'shader with 1024 character identifier that starts with underscore should succeed'
+ },
+ {
+ fShaderId: 'fragmentShader_after',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'shader with 1024 character identifier that ends with underscore should succeed'
+ },
+ {
+ fShaderId: 'fragmentShader1024_odd',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'shader with 1024 character identifier with odd characters as underscores should succeed'
+ },
+ {
+ fShaderId: 'fragmentShader1024_even',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'shader with 1024 character identifier with even characters as underscores should succeed'
+ }
+]);
+var successfullyParsed = true;
+</script>
+</body>
+</html>
+
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-1025-character-define.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-1025-character-define.html
new file mode 100644
index 0000000000..92e47f222b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-1025-character-define.html
@@ -0,0 +1,36 @@
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL GLSL Conformance Tests</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="vertexShader" type="text/something-not-javascript">
+// vertex shader that uses 1025 character token in #define should fail
+#define LEN_1025_BAD XxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxX
+
+void main()
+{
+ gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script>
+"use strict";
+GLSLConformanceTester.runTest();
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-1025-character-identifier.frag.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-1025-character-identifier.frag.html
new file mode 100644
index 0000000000..ca17222f43
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-1025-character-identifier.frag.html
@@ -0,0 +1,36 @@
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL GLSL Conformance Tests</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="fragmentShader" type="text/something-not-javascript">
+// shader that uses 1025 character identifier should fail
+precision mediump float;
+uniform float a1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234;
+void main()
+{
+ gl_FragColor = vec4(a1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234, 0.0, 0.0, 1.0);
+}
+</script>
+<script>
+"use strict";
+GLSLConformanceTester.runTest();
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-invalid-characters.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-invalid-characters.html
new file mode 100644
index 0000000000..5494c46dcd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-invalid-characters.html
@@ -0,0 +1,37 @@
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL GLSL Conformance Tests</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="vertexShader" type="text/something-not-javascript">
+// vertex shader that uses backlash character in comments should succeed
+// This is a li\ne wi\th backlash \\ characters \
+in comments
+
+void main()
+{
+ gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script>
+"use strict";
+GLSLConformanceTester.runTest();
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-mis-matching-uniform-block.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-mis-matching-uniform-block.html
new file mode 100644
index 0000000000..2bf41a3825
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-mis-matching-uniform-block.html
@@ -0,0 +1,59 @@
+<!--
+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 mis-matching uniform block</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="vshader-uniform-block-precision" type="text/something-not-javascript">#version 300 es
+uniform Block {
+ mediump vec4 val;
+};
+
+void main()
+{
+ gl_Position = val;
+}
+</script>
+<script id="fshader-uniform-block-precision" type="text/something-not-javascript">#version 300 es
+uniform Block {
+ highp vec4 val;
+};
+
+out highp vec4 out_FragColor;
+void main()
+{
+ out_FragColor = val;
+}
+</script>
+<script>
+"use strict";
+description("Shaders with precision mis-matching uniform blocks should fail");
+
+GLSLConformanceTester.runTests([
+{
+ vShaderId: 'vshader-uniform-block-precision',
+ vShaderSuccess: true,
+ fShaderId: 'fshader-uniform-block-precision',
+ fShaderSuccess: true,
+ linkSuccess: false,
+ passMsg: "Shaders with precision mis-matching uniform blocks should fail"
+},
+], 2);
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/short-circuiting-in-loop-condition.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/short-circuiting-in-loop-condition.html
new file mode 100644
index 0000000000..802d67aa4a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/short-circuiting-in-loop-condition.html
@@ -0,0 +1,180 @@
+<!--
+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 circuit in loop condition 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="fshaderWhile" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform bool u;
+out vec4 result;
+int sideEffectCounter;
+
+bool foo() {
+ ++sideEffectCounter;
+ return true;
+}
+
+void main() {
+ sideEffectCounter = 0;
+ int iterations = 0;
+
+ while(u && foo()) {
+ ++iterations;
+ if (iterations >= 10) {
+ break;
+ }
+ }
+
+ bool success = (u && sideEffectCounter == 10) || (!u && sideEffectCounter == 0);
+ result = success ? vec4(0, 1.0, 0, 1.0) : vec4(0, 1.0, 0, 0);
+}
+</script>
+<script id="fshaderForCondition" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform bool u;
+out vec4 result;
+int sideEffectCounter;
+
+bool foo() {
+ ++sideEffectCounter;
+ return true;
+}
+
+void main() {
+ sideEffectCounter = 0;
+ for(int iterations = 0; u && foo();) {
+ ++iterations;
+ if (iterations >= 10) {
+ break;
+ }
+ }
+
+ bool success = (u && sideEffectCounter == 10) || (!u && sideEffectCounter == 0);
+ result = success ? vec4(0, 1.0, 0, 1.0) : vec4(0, 1.0, 0, 0);
+}
+</script>
+<script id="fshaderFor" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform bool u;
+out vec4 result;
+int sideEffectCounter;
+
+bool foo() {
+ ++sideEffectCounter;
+ return true;
+}
+
+void main() {
+ sideEffectCounter = 0;
+ for(int iterations = 0; true; u && foo()) {
+ ++iterations;
+ if (iterations > 10) {
+ break;
+ }
+ }
+
+ bool success = (u && sideEffectCounter == 10) || (!u && sideEffectCounter == 0);
+ result = success ? vec4(0, 1.0, 0, 1.0) : vec4(0, 1.0, 0, 0);
+}
+</script>
+<script id="fshaderDoWhile" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform bool u;
+out vec4 result;
+int sideEffectCounter;
+
+bool foo() {
+ ++sideEffectCounter;
+ return true;
+}
+
+void main() {
+ sideEffectCounter = 0;
+ int iterations = 0;
+
+ do {
+ ++iterations;
+ if (iterations > 10) {
+ break;
+ }
+ } while (u && foo());
+
+ bool success = (u && sideEffectCounter == 10) || (!u && sideEffectCounter == 0);
+ result = success ? vec4(0, 1.0, 0, 1.0) : vec4(0, 1.0, 0, 0);
+}
+</script>
+<script id="fshaderSequence" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform bool u;
+out vec4 result;
+int sideEffectCounter;
+
+bool foo() {
+ ++sideEffectCounter;
+ return true;
+}
+
+void main() {
+ sideEffectCounter = 0;
+ int iterations = 0;
+
+ while(u, u && foo()) {
+ ++iterations;
+ if (iterations >= 10) {
+ break;
+ }
+ }
+
+ bool success = (u && sideEffectCounter == 10) || (!u && sideEffectCounter == 0);
+ result = success ? vec4(0, 1.0, 0, 1.0) : vec4(0, 1.0, 0, 0);
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description("Test behavior of a short-circuiting operator in a loop using a function call with side effects");
+
+var testShaders = [
+ {fShaderId: 'fshaderWhile', description: 'in while loop condition'},
+ {fShaderId: 'fshaderForCondition', description: 'in for loop condition'},
+ {fShaderId: 'fshaderFor', description: 'in for loop expression'},
+ {fShaderId: 'fshaderDoWhile', description: 'in do-while loop condition'},
+ {fShaderId: 'fshaderSequence', description: 'inside a sequence in while loop condition'}
+];
+
+var testList = [];
+
+for (var i = 0; i < testShaders.length; ++i) {
+ testList.push({
+ fShaderId: testShaders[i].fShaderId,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Short-circuiting operator with a true condition ' + testShaders[i].description,
+ uniforms: [{name: "u", functionName: "uniform1i", value: 1}]
+ });
+ testList.push({
+ fShaderId: testShaders[i].fShaderId,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Short-circuiting operator with a false condition ' + testShaders[i].description,
+ uniforms: [{name: "u", functionName: "uniform1i", value: 0}]
+ });
+}
+
+GLSLConformanceTester.runRenderTests(testList, 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/switch-case.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/switch-case.html
new file mode 100644
index 0000000000..4ab422c958
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/switch-case.html
@@ -0,0 +1,351 @@
+<!--
+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 switch/case corner case 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="fshaderDeclarationInsideSwitch" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ my_FragColor = vec4(1, 0, 0, 1);
+ switch (u_zero)
+ {
+ case 0:
+ ivec2 i;
+ i = ivec2(1, 0);
+ my_FragColor = vec4(0, i[0], 0, 1);
+ }
+}
+</script>
+<script id="fshaderDeclarationInsideSwitchDefault" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ my_FragColor = vec4(1, 0, 0, 1);
+ switch (u_zero)
+ {
+ default:
+ ivec2 i;
+ i = ivec2(1, 0);
+ my_FragColor = vec4(0, i[0], 0, 1);
+ }
+}
+</script>
+<script id="fshaderDeclarationInsideSwitchLiteral" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+out vec4 my_FragColor;
+
+void main()
+{
+ my_FragColor = vec4(1, 0, 0, 1);
+ switch (0)
+ {
+ case 0:
+ ivec2 i;
+ i = ivec2(1, 0);
+ my_FragColor = vec4(0, i[0], 0, 1);
+ }
+}
+</script>
+<script id="fshaderDeclarationInsideSwitchLiteralDefault" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+out vec4 my_FragColor;
+
+void main()
+{
+ my_FragColor = vec4(1, 0, 0, 1);
+ switch (0)
+ {
+ default:
+ ivec2 i;
+ i = ivec2(1, 0);
+ my_FragColor = vec4(0, i[0], 0, 1);
+ }
+}
+</script>
+<script id="fshaderDeclarationInsideSwitchScope" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+// GLSL ES 3.10 clarifies the scoping rules that are relevant here. In section 4.2.2 it says:
+// "The statement following a switch (...) forms a nested scope."
+// There are no other special scoping rules with regards to switch statements.
+
+void main()
+{
+ my_FragColor = vec4(1, 0, 0, 1);
+ switch (u_zero)
+ {
+ case 0:
+ ivec2 i;
+ i = ivec2(1, 0);
+ default:
+ my_FragColor = vec4(0, i[0], 0, 1);
+ }
+}
+</script>
+<script id="fshaderFallThroughAll" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ int i = 0;
+ // switch should fall through both cases.
+ switch(u_zero)
+ {
+ case 0:
+ i += 1;
+ case 1:
+ i += 2;
+ }
+ if (i == 3)
+ {
+ my_FragColor = vec4(0, 1, 0, 1);
+ }
+ else
+ {
+ my_FragColor = vec4(1, 0, 0, 1);
+ }
+}
+</script>
+<script id="fshaderEmptySwitchStatement" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ switch(u_zero)
+ {
+ }
+ my_FragColor = vec4(0, 1, 0, 1);
+}
+</script>
+<script id="fshaderLastCaseHasEmptyDeclaration" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ // Empty declaration should count as a statement.
+ switch(u_zero)
+ {
+ case 0:
+ int;
+ }
+ my_FragColor = vec4(0, 1, 0, 1);
+}
+</script>
+<script id="fshaderLastCaseHasEmptyBlock" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ // Empty block should count as a statement.
+ switch(u_zero)
+ {
+ case 0:
+ {}
+ }
+ my_FragColor = vec4(0, 1, 0, 1);
+}
+</script>
+<script id="fshaderLastCaseHasConstantStatement" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ // Empty statement should count as a statement.
+ switch(u_zero)
+ {
+ case 0:
+ 0;
+ }
+ my_FragColor = vec4(0, 1, 0, 1);
+}
+</script>
+<script id="fshaderLastCaseHasEmptyStatement" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ // Empty statement should count as a statement.
+ switch(u_zero)
+ {
+ case 0:
+ ;
+ }
+ my_FragColor = vec4(0, 1, 0, 1);
+}
+</script>
+<script id="fshaderCaseInsideBlock" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ // Case statements must not be nested in blocks.
+ // GLSL ES 3.00 spec is a bit vague on this but GLSL ES 3.10 section 6.2 is clearer.
+ switch(u_zero)
+ {
+ case 1:
+ {
+ case 0:
+ my_FragColor = vec4(1, 0, 0, 1);
+ }
+ }
+ my_FragColor = vec4(0, 1, 0, 1);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+
+// Covers bugs:
+// http://anglebug.com/2177
+// http://anglebug.com/2178
+// http://anglebug.com/2179
+
+GLSLConformanceTester.runTests([
+{
+ fShaderId: 'fshaderDeclarationInsideSwitch',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Declaration inside switch should work.',
+ render: true
+},
+{
+ fShaderId: 'fshaderDeclarationInsideSwitchDefault',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Declaration inside switch default case should work.',
+ render: true
+},
+{
+ fShaderId: 'fshaderDeclarationInsideSwitchLiteral',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Declaration inside switch with literal value should work.',
+ render: true
+},
+{
+ fShaderId: 'fshaderDeclarationInsideSwitchLiteralDefault',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Declaration inside switch with literal value and default case should work.',
+ render: true
+},
+{
+ fShaderId: 'fshaderDeclarationInsideSwitchScope',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Declaration inside switch should be scoped until the end of the switch statement.',
+ render: true
+},
+{
+ fShaderId: 'fshaderFallThroughAll',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Falling through all cases in switch/case should work.',
+ render: true
+},
+{
+ fShaderId: 'fshaderEmptySwitchStatement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Empty switch statements are valid.'
+},
+{
+ fShaderId: 'fshaderLastCaseHasEmptyDeclaration',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Empty declaration should count as a statement for the purposes of switch statement validation.'
+},
+{
+ fShaderId: 'fshaderLastCaseHasEmptyBlock',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Empty block should count as a statement for the purposes of switch statement validation.'
+},
+{
+ fShaderId: 'fshaderLastCaseHasConstantStatement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Constant statement should count as a statement for the purposes of switch statement validation.'
+},
+{
+ fShaderId: 'fshaderLastCaseHasEmptyStatement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Empty statement should count as a statement for the purposes of switch statement validation.'
+},
+{
+ fShaderId: 'fshaderCaseInsideBlock',
+ fShaderSuccess: false,
+ passMsg: 'Case statements must not be nested inside blocks.'
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-non-constant-offset.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-non-constant-offset.html
new file mode 100644
index 0000000000..8fd483140d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-non-constant-offset.html
@@ -0,0 +1,170 @@
+<!--
+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 texture offset with non-constant offset 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="fshaderTextureOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec2 u_texCoord;
+
+void main() {
+ ivec2 offset = ivec2(0);
+ my_FragColor = textureOffset(u_sampler, u_texCoord, offset);
+}
+</script>
+<script id="fshaderTextureProjOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec4 u_texCoord;
+
+void main() {
+ ivec2 offset = ivec2(0);
+ my_FragColor = textureProjOffset(u_sampler, u_texCoord, offset);
+}
+</script>
+<script id="fshaderTextureLodOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec2 u_texCoord;
+uniform float u_lod;
+
+void main() {
+ ivec2 offset = ivec2(0);
+ my_FragColor = textureLodOffset(u_sampler, u_texCoord, u_lod, offset);
+}
+</script>
+<script id="fshaderTextureProjLodOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec4 u_texCoord;
+uniform float u_lod;
+
+void main() {
+ ivec2 offset = ivec2(0);
+ my_FragColor = textureProjLodOffset(u_sampler, u_texCoord, u_lod, offset);
+}
+</script>
+<script id="fshaderTextureGradOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec2 u_texCoord;
+uniform vec2 u_dPdx;
+uniform vec2 u_dPdy;
+
+void main() {
+ ivec2 offset = ivec2(0);
+ my_FragColor = textureGradOffset(u_sampler, u_texCoord, u_dPdx, u_dPdy, offset);
+}
+</script>
+<script id="fshaderTextureProjGradOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec4 u_texCoord;
+uniform vec2 u_dPdx;
+uniform vec2 u_dPdy;
+
+void main() {
+ ivec2 offset = ivec2(0);
+ my_FragColor = textureProjGradOffset(u_sampler, u_texCoord, u_dPdx, u_dPdy, offset);
+}
+</script>
+<script id="fshaderTexelFetchOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec2 u_texCoord;
+uniform vec2 u_lod;
+
+void main() {
+ ivec2 offset = ivec2(0);
+ my_FragColor = texelFetchOffset(u_sampler, ivec2(u_texCoord), int(u_lod), offset);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("A non-constant offset is not valid in texture offset functions.");
+
+var wtu = WebGLTestUtils;
+
+var shaderTextureOffsetSrc = wtu.getScript('fshaderTextureOffset');
+var shaderTextureLodOffsetSrc = wtu.getScript('fshaderTextureLodOffset');
+var shaderTextureGradOffsetSrc = wtu.getScript('fshaderTextureGradOffset');
+var shaderTextureProjOffsetSrc = wtu.getScript('fshaderTextureProjOffset');
+var shaderTextureProjLodOffsetSrc = wtu.getScript('fshaderTextureProjLodOffset');
+var shaderTextureProjGradOffsetSrc = wtu.getScript('fshaderTextureProjGradOffset');
+var shaderTexelFetchOffsetSrc = wtu.getScript('fshaderTexelFetchOffset');
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+if (!gl) {
+ testFailed("Unable to initialize WebGL 2.0 context.");
+} else {
+ GLSLConformanceTester.runTests([
+ {
+ fShaderSource: shaderTextureOffsetSrc,
+ fShaderSuccess: false,
+ passMsg: 'textureOffset with non-constant offset is invalid'
+ },
+ {
+ fShaderSource: shaderTextureLodOffsetSrc,
+ fShaderSuccess: false,
+ passMsg: 'textureLodOffset with non-constant offset is invalid'
+ },
+ {
+ fShaderSource: shaderTextureGradOffsetSrc,
+ fShaderSuccess: false,
+ passMsg: 'textureGradOffset with non-constant offset is invalid'
+ },
+ {
+ fShaderSource: shaderTextureProjOffsetSrc,
+ fShaderSuccess: false,
+ passMsg: 'textureProjOffset with non-constant offset is invalid'
+ },
+ {
+ fShaderSource: shaderTextureProjLodOffsetSrc,
+ fShaderSuccess: false,
+ passMsg: 'textureProjLodOffset with non-constant offset is invalid'
+ },
+ {
+ fShaderSource: shaderTextureProjGradOffsetSrc,
+ fShaderSuccess: false,
+ passMsg: 'textureProjGradOffset with non-constant offset is invalid'
+ },
+ {
+ fShaderSource: shaderTexelFetchOffsetSrc,
+ fShaderSuccess: false,
+ passMsg: 'texelFetchOffset with non-constant offset is invalid'
+ }
+ ], 2);
+}
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-out-of-range.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-out-of-range.html
new file mode 100644
index 0000000000..99e698fb6e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-out-of-range.html
@@ -0,0 +1,106 @@
+<!--
+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 out-of-range texture offset 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="vshaderInvalidOffset" type="x-shader/x-vertex">#version 300 es
+in vec4 a_position;
+in vec2 a_in0;
+out vec2 v_texCoord;
+
+void main()
+{
+ gl_Position = a_position;
+ v_texCoord = a_in0;
+}
+</script>
+<script id="fshaderInvalidOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+in vec2 v_texCoord;
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform int x;
+
+void main() {
+ my_FragColor = textureOffset(u_sampler, v_texCoord, ivec2(0, $(yoffset)));
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Out-of-range texture offset should not compile.");
+
+var wtu = WebGLTestUtils;
+
+var vshader = wtu.getScript('vshaderInvalidOffset');
+var fshaderTemplate = wtu.getScript('fshaderInvalidOffset');
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+if (!gl) {
+ testFailed("Unable to initialize WebGL 2.0 context.");
+} else {
+ var minOffset = gl.getParameter(gl.MIN_PROGRAM_TEXEL_OFFSET);
+ var maxOffset = gl.getParameter(gl.MAX_PROGRAM_TEXEL_OFFSET);
+
+ var shaderSrcValidMin = wtu.replaceParams(fshaderTemplate, {'yoffset': minOffset});
+ var shaderSrcValidMax = wtu.replaceParams(fshaderTemplate, {'yoffset': maxOffset});
+ var shaderSrcBelowMin = wtu.replaceParams(fshaderTemplate, {'yoffset': (minOffset - 1)});
+ var shaderSrcAboveMax = wtu.replaceParams(fshaderTemplate, {'yoffset': (maxOffset + 1)});
+ var shaderSrcDynamic = wtu.replaceParams(fshaderTemplate, {'yoffset': 'x'});
+
+ GLSLConformanceTester.runTests([
+ {
+ vShaderSource: vshader,
+ fShaderSource: shaderSrcValidMin,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Minimum in-range texture offset should compile'
+ },
+ {
+ vShaderSource: vshader,
+ fShaderSource: shaderSrcValidMax,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Maximum in-range texture offset should compile'
+ },
+ {
+ vShaderSource: vshader,
+ fShaderSource: shaderSrcBelowMin,
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: 'Texture offset below minimum valid value should not compile'
+ },
+ {
+ vShaderSource: vshader,
+ fShaderSource: shaderSrcAboveMax,
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: 'Texture offset above maximum valid value should not compile'
+ },
+ {
+ vShaderSource: vshader,
+ fShaderSource: shaderSrcDynamic,
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: 'Dynamic texture offset should not compile'
+ }
+ ], 2);
+}
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-uniform-texture-coordinate.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-uniform-texture-coordinate.html
new file mode 100644
index 0000000000..56caf47f46
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-uniform-texture-coordinate.html
@@ -0,0 +1,170 @@
+<!--
+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 texture offset with uniform texture coordinates 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="fshaderTextureOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec2 u_texCoord;
+
+void main() {
+ my_FragColor = textureOffset(u_sampler, u_texCoord, ivec2(0, 1));
+}
+</script>
+<script id="fshaderTextureProjOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec4 u_texCoord;
+
+void main() {
+ my_FragColor = textureProjOffset(u_sampler, u_texCoord, ivec2(0, 1));
+}
+</script>
+<script id="fshaderTextureLodOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec2 u_texCoord;
+uniform float u_lod;
+
+void main() {
+ my_FragColor = textureLodOffset(u_sampler, u_texCoord, u_lod, ivec2(0, 1));
+}
+</script>
+<script id="fshaderTextureProjLodOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec4 u_texCoord;
+uniform float u_lod;
+
+void main() {
+ my_FragColor = textureProjLodOffset(u_sampler, u_texCoord, u_lod, ivec2(0, 1));
+}
+</script>
+<script id="fshaderTextureGradOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec2 u_texCoord;
+uniform vec2 u_dPdx;
+uniform vec2 u_dPdy;
+
+void main() {
+ my_FragColor = textureGradOffset(u_sampler, u_texCoord, u_dPdx, u_dPdy, ivec2(0, 1));
+}
+</script>
+<script id="fshaderTextureProjGradOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec4 u_texCoord;
+uniform vec2 u_dPdx;
+uniform vec2 u_dPdy;
+
+void main() {
+ my_FragColor = textureProjGradOffset(u_sampler, u_texCoord, u_dPdx, u_dPdy, ivec2(0, 1));
+}
+</script>
+<script id="fshaderTexelFetchOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec2 u_texCoord;
+uniform vec2 u_lod;
+
+void main() {
+ my_FragColor = texelFetchOffset(u_sampler, ivec2(u_texCoord), int(u_lod), ivec2(0, 1));
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Texture coordinates expressed as uniform variable should not crash in texture offset functions.");
+
+var wtu = WebGLTestUtils;
+
+var shaderTextureOffsetSrc = wtu.getScript('fshaderTextureOffset');
+var shaderTextureLodOffsetSrc = wtu.getScript('fshaderTextureLodOffset');
+var shaderTextureGradOffsetSrc = wtu.getScript('fshaderTextureGradOffset');
+var shaderTextureProjOffsetSrc = wtu.getScript('fshaderTextureProjOffset');
+var shaderTextureProjLodOffsetSrc = wtu.getScript('fshaderTextureProjLodOffset');
+var shaderTextureProjGradOffsetSrc = wtu.getScript('fshaderTextureProjGradOffset');
+var shaderTexelFetchOffsetSrc = wtu.getScript('fshaderTexelFetchOffset');
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+if (!gl) {
+ testFailed("Unable to initialize WebGL 2.0 context.");
+} else {
+ GLSLConformanceTester.runTests([
+ {
+ fShaderSource: shaderTextureOffsetSrc,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'textureOffset with uniform texture coordinates should not crash'
+ },
+ {
+ fShaderSource: shaderTextureLodOffsetSrc,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'textureLodOffset with uniform texture coordinates should not crash'
+ },
+ {
+ fShaderSource: shaderTextureGradOffsetSrc,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'textureGradOffset with uniform texture coordinates should not crash'
+ },
+ {
+ fShaderSource: shaderTextureProjOffsetSrc,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'textureProjOffset with uniform texture coordinates should not crash'
+ },
+ {
+ fShaderSource: shaderTextureProjLodOffsetSrc,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'textureProjLodOffset with uniform texture coordinates should not crash'
+ },
+ {
+ fShaderSource: shaderTextureProjGradOffsetSrc,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'textureProjGradOffset with uniform texture coordinates should not crash'
+ },
+ {
+ fShaderSource: shaderTexelFetchOffsetSrc,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'texelFetchOffset with uniform texture coordinates should not crash'
+ }
+ ], 2);
+}
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/tricky-loop-conditions.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/tricky-loop-conditions.html
new file mode 100644
index 0000000000..1bf57d1a02
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/tricky-loop-conditions.html
@@ -0,0 +1,327 @@
+<!--
+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 tricky loop conditions and loop expressions</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>
+<!--
+Some tricky shader expressions might be subject to syntax tree transformations that need to create
+new statements. Ensure that these expressions also work inside loop conditions and loop expressions.
+-->
+<script type="application/javascript">
+"use strict";
+description("Indexing complex array expressions");
+debug("");
+
+// All the templates run the given sequence:
+// 1. loopExpression or loopCondition
+// 2. loopContents
+// 3. Break loop if it's done loopIterations iterations, else go back to 1.
+
+var forLoopExpressionTemplate = [
+ '#version 300 es',
+ 'precision mediump float;',
+ 'out vec4 color;',
+ '$(globalScopePrefix)',
+ 'void main() {',
+ '$(mainPrefix)',
+ ' for (int i = 0; true; $(loopExpression))',
+ ' {',
+ ' ++i;',
+ ' if (i > 1) {',
+ ' $(loopContents)',
+ ' if (i > $(loopIterations)) { break; }',
+ ' }',
+ ' }',
+ ' color = ($(passCondition)) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);',
+ '}'
+].join('\n');
+
+var forLoopConditionTemplate = [
+ '#version 300 es',
+ 'precision mediump float;',
+ 'out vec4 color;',
+ '$(globalScopePrefix)',
+ 'void main() {',
+ '$(mainPrefix)',
+ ' for (int i = 1; $(loopCondition); ++i)',
+ ' {',
+ ' $(loopContents)',
+ ' if (i >= $(loopIterations)) { break; }',
+ ' }',
+ ' color = ($(passCondition)) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);',
+ '}'
+].join('\n');
+
+var whileLoopConditionTemplate = [
+ '#version 300 es',
+ 'precision mediump float;',
+ 'out vec4 color;',
+ '$(globalScopePrefix)',
+ 'void main() {',
+ '$(mainPrefix)',
+ ' int i = 0;',
+ ' while ($(loopCondition))',
+ ' {',
+ ' $(loopContents)',
+ ' ++i;',
+ ' if (i >= $(loopIterations)) { break; }',
+ ' }',
+ ' color = ($(passCondition)) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);',
+ '}'
+].join('\n');
+
+var doWhileLoopConditionTemplate = [
+ '#version 300 es',
+ 'precision mediump float;',
+ 'out vec4 color;',
+ '$(globalScopePrefix)',
+ 'void main() {',
+ '$(mainPrefix)',
+ ' int i = 0;',
+ // Run the loop condition one extra time to make the different test types behave the same
+ ' $(loopCondition);',
+ ' do {',
+ ' $(loopContents)',
+ ' ++i;',
+ ' if (i >= $(loopIterations)) { break; }',
+ ' }',
+ ' while ($(loopCondition));',
+ ' color = ($(passCondition)) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);',
+ '}'
+].join('\n');
+
+var testDataList = [
+{
+ description: 'indexing an array assignment',
+ globalScopePrefix: '',
+ mainPrefix: [
+ 'float a[2] = float[2](0.0, 0.0);',
+ 'float b[2] = float[2](2.0, 1.0);',
+ 'float c = 0.0;'
+ ].join('\n'),
+ loopExpression: 'c = (a = b)[0]',
+ loopCondition: 'bool((c = (a = b)[0]) + 1.0)',
+ loopContents: 'b[0] += 1.0;',
+ loopIterations: 3,
+ passCondition: 'abs(c - 4.0) < 0.01'
+},
+{
+ description: 'indexing a function returning an array',
+ globalScopePrefix: [
+ 'int sideEffectCounter = 0;',
+ 'float[2] functionReturnArray() {',
+ ' ++sideEffectCounter;',
+ ' return float[2](float(sideEffectCounter), 1.0);',
+ '}'
+ ].join('\n'),
+ mainPrefix: 'float c = 0.0;',
+ loopExpression: 'c = functionReturnArray()[0]',
+ loopCondition: 'bool(c = functionReturnArray()[0])',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'abs(c - 3.0) < 0.01 && sideEffectCounter == 3'
+},
+{
+ description: 'indexing an array constructor',
+ globalScopePrefix: '',
+ mainPrefix: 'int c = 0;',
+ loopExpression: 'c = (int[2](c + 1, c + 2))[1]',
+ loopCondition: 'bool(c = (int[2](c + 1, c + 2))[1])',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'c == 6'
+},
+{
+ description: 'indexing an array constructor inside a sequence operator',
+ globalScopePrefix: [
+ 'int sideEffectCounter = 0;',
+ 'int func() {',
+ ' sideEffectCounter++;',
+ ' return sideEffectCounter;',
+ '}'
+ ].join('\n'),
+ mainPrefix: 'int c = 0;',
+ loopExpression: 'c = (func(), (int[2](c + 1, c + 2))[1])',
+ loopCondition: 'bool(c = (func(), (int[2](c + 1, c + 2))[1]))',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'c == 6 && sideEffectCounter == 3'
+},
+{
+ description: 'dynamic indexing of a vector',
+ globalScopePrefix: '',
+ mainPrefix: [
+ 'vec4 v = vec4(1.0, 2.0, 3.0, 4.0);',
+ 'float c = 0.0;',
+ 'int j = 0;'
+ ].join('\n'),
+ loopExpression: 'c = v[j]',
+ loopCondition: 'bool(c = v[j])',
+ loopContents: '++j;',
+ loopIterations: 3,
+ passCondition: 'abs(c - 3.0) < 0.01'
+},
+{
+ description: 'short-circuiting operator',
+ globalScopePrefix: [
+ 'int sideEffectCounter = 0;',
+ 'bool func() {',
+ ' sideEffectCounter++;',
+ ' return sideEffectCounter > 0;',
+ '}'
+ ].join('\n'),
+ mainPrefix: '',
+ loopExpression: 'func() && func()',
+ loopCondition: 'func() && func()',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'sideEffectCounter == 6'
+},
+{
+ description: 'short-circuiting operator',
+ globalScopePrefix: [
+ 'int sideEffectCounter = 0;',
+ 'bool func() {',
+ ' sideEffectCounter++;',
+ ' return sideEffectCounter > 0;',
+ '}'
+ ].join('\n'),
+ mainPrefix: '',
+ loopExpression: 'func() || func()',
+ loopCondition: 'func() || func()',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'sideEffectCounter == 3'
+},
+{
+ description: 'short-circuiting operator',
+ globalScopePrefix: [
+ 'int sideEffectCounterA = 0;',
+ 'bool funcA() {',
+ ' sideEffectCounterA++;',
+ ' return sideEffectCounterA > 1;',
+ '}',
+ 'int sideEffectCounterB = 0;',
+ 'bool funcB() {',
+ ' sideEffectCounterB++;',
+ ' return sideEffectCounterB > 0;',
+ '}'
+ ].join('\n'),
+ mainPrefix: '',
+ loopExpression: 'funcA() ? true : funcB()',
+ loopCondition: 'funcA() ? true : funcB()',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'sideEffectCounterA == 3 && sideEffectCounterB == 1'
+},
+{
+ description: 'high-precision constant',
+ globalScopePrefix: [
+ 'const highp float f = 2048.5;',
+ 'uniform mediump float u_zero;'
+ ].join('\n'),
+ mainPrefix: 'float c = 0.0;',
+ loopExpression: 'c = fract(u_zero + f)',
+ loopCondition: 'bool(c = fract(u_zero + f))',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'abs(c - 0.5) < 0.01'
+},
+{
+ description: 'l-value indexing side effects combined with static indexing of a vector',
+ globalScopePrefix: [
+ 'int sideEffectCounter = 0;',
+ 'int func() {',
+ ' sideEffectCounter++;',
+ ' return sideEffectCounter > 1 ? 1 : 0;',
+ '}'
+ ].join('\n'),
+ mainPrefix: [
+ 'vec4[2] V;',
+ 'V[0] = vec4(1.0);',
+ 'V[1] = vec4(3.0);'
+ ].join('\n'),
+ loopExpression: 'V[func()][0]++',
+ loopCondition: 'bool(V[func()][0]++)',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'abs(V[0][0] - 2.0) < 0.01 && abs(V[1][0] - 5.0) < 0.01 && sideEffectCounter == 3'
+},
+{
+ description: 'l-value indexing side effects combined with dynamically indexing a vector',
+ globalScopePrefix: [
+ 'int sideEffectCounter = 0;',
+ 'uniform int u_zero;',
+ 'int func() {',
+ ' sideEffectCounter++;',
+ ' return sideEffectCounter > 1 ? 1 : 0;',
+ '}'
+ ].join('\n'),
+ mainPrefix: [
+ 'vec4[2] V;',
+ 'V[0] = vec4(1.0);',
+ 'V[1] = vec4(3.0);'
+ ].join('\n'),
+ loopExpression: 'V[func()][u_zero + 1]++',
+ loopCondition: 'bool(V[func()][u_zero + 1]++)',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'abs(V[0][1] - 2.0) < 0.01 && abs(V[1][1] - 5.0) < 0.01 && sideEffectCounter == 3'
+}
+];
+
+var tests = [];
+
+var wtu = WebGLTestUtils;
+
+for (var i = 0; i < testDataList.length; ++i) {
+ var testData = testDataList[i];
+ if ('loopCondition' in testData) {
+ tests.push({
+ fShaderSource: wtu.replaceParams(forLoopConditionTemplate, testData),
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Test ' + testData.description + ': ' + testData.loopCondition + ' inside a for loop condition'
+ });
+ tests.push({
+ fShaderSource: wtu.replaceParams(whileLoopConditionTemplate, testData),
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Test ' + testData.description + ': ' + testData.loopCondition + ' inside a while loop condition'
+ });
+ tests.push({
+ fShaderSource: wtu.replaceParams(doWhileLoopConditionTemplate, testData),
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Test ' + testData.description + ': ' + testData.loopCondition + ' inside a do-while loop condition'
+ });
+ }
+ if ('loopExpression' in testData) {
+ tests.push({
+ fShaderSource: wtu.replaceParams(forLoopExpressionTemplate, testData),
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Test ' + testData.description + ': ' + testData.loopExpression + ' inside a for loop expression'
+ });
+ }
+}
+
+GLSLConformanceTester.runRenderTests(tests, 2);
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uint-int-shift-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uint-int-shift-bug.html
new file mode 100644
index 0000000000..499d266e7b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uint-int-shift-bug.html
@@ -0,0 +1,106 @@
+<!--
+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>Verify (uint(int) >> 31) works correctly (Adreno 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-uint-1" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+flat out highp uint uvalue;
+uniform highp int ivalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ uvalue = uint(ivalue) >> 31u;
+}
+</script>
+<script id="fshader-uint-1" type="x-shader/x-fragment">#version 300 es
+flat in highp uint uvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ if (uvalue == 1u)
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-simple" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+}
+</script>
+<script id="fshader-uint-2" type="x-shader/x-fragment">#version 300 es
+uniform highp int ivalue;
+out highp vec4 myFragColor;
+
+void main() {
+ uint uvalue = uint(ivalue) >> 31u;
+
+ if (uvalue == 1u)
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script type="application/javascript">
+"use strict";
+description("Verify (uint(int) >> 31) works correctly");
+debug("");
+var wtu = WebGLTestUtils;
+function test() {
+ var gl = wtu.create3DContext("canvas", undefined, 2);
+ if (!gl) {
+ testFailed("context does not exist");
+ return;
+ }
+ wtu.setupUnitQuad(gl);
+
+ var testCases = [
+ { vshader: "vshader-uint-1", fshader: "fshader-uint-1", desc: "vertex shader uint" },
+ { vshader: "vshader-simple", fshader: "fshader-uint-2", desc: "fragment shader uint" },
+ ];
+
+ 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, 'ivalue');
+ 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/conformance2/glsl3/unary-minus-operator-in-dynamic-loop.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/unary-minus-operator-in-dynamic-loop.html
new file mode 100644
index 0000000000..200acbe6de
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/unary-minus-operator-in-dynamic-loop.html
@@ -0,0 +1,248 @@
+<!--
+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>Unary minus operator on int or uint variables in a dynamic loop in vertex 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" style="border: none;" width="1024" height="128"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script id="shader-vs-int" type="x-shader/x-vertex">#version 300 es
+in highp vec4 pos;
+
+uniform int u_one;
+uniform int u_two;
+uniform int u_three;
+
+out mediump vec4 v_color;
+void main() {
+ int array[3];
+ array[0] = u_one; // array[0] should be 1
+ array[1] = -u_two; // array[1] should be -2
+ array[2] = u_three; // array[2] should be 3
+ int result = 0;
+ for (int i = 0; i < u_three; i++) {
+ result += array[i];
+ }
+ v_color = (result == 2) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+ gl_Position = pos;
+}
+</script>
+
+<script id="shader-vs-uint" type="x-shader/x-vertex">#version 300 es
+in highp vec4 pos;
+
+uniform uint u_one;
+uniform uint u_two;
+uniform uint u_three;
+
+out mediump vec4 v_color;
+void main() {
+ uint array[3];
+ array[0] = u_one; // array[0] should be 1u
+ array[1] = -u_two; // array[1] should be -2u
+ array[2] = u_three; // array[2] should be 3u
+ uint result = 0u;
+ for (uint i = 0u; i < u_three; i++) {
+ result += array[i];
+ }
+ v_color = (result == 2u) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+ gl_Position = pos;
+}
+</script>
+
+<script id="shader-vs-int-multiple-brackets" type="x-shader/x-vertex">#version 300 es
+in highp vec4 pos;
+
+uniform int u_one;
+uniform int u_two;
+uniform int u_three;
+
+out mediump vec4 v_color;
+void main() {
+ int array[3];
+ array[0] = u_one; // array[0] should be 1
+ array[1] = -(-(-u_two + 1) + 1); // array[1] should be -2
+ array[2] = u_three; // array[2] should be 3
+ int result = 0;
+ for (int i = 0; i < u_three; i++) {
+ result += array[i];
+ }
+ v_color = (result == 2) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+ gl_Position = pos;
+}
+</script>
+
+<script id="shader-vs-uint-multiple-brackets" type="x-shader/x-vertex">#version 300 es
+in highp vec4 pos;
+
+uniform uint u_one;
+uniform uint u_two;
+uniform uint u_three;
+
+out mediump vec4 v_color;
+void main() {
+ uint array[3];
+ array[0] = u_one; // array[0] should be 1u
+ array[1] = -(-(-u_two + 1u) + 1u); // array[1] should be -2u
+ array[2] = u_three; // array[2] should be 3u
+ uint result = 0u;
+ for (uint i = 0u; i < u_three; i++) {
+ result += array[i];
+ }
+ v_color = (result == 2u) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+ gl_Position = pos;
+}
+</script>
+
+<script id="shader-vs-int-implicit-unary-minus" type="x-shader/x-vertex">#version 300 es
+in highp vec4 pos;
+
+uniform int u_one;
+uniform int u_two;
+uniform int u_three;
+
+out mediump vec4 v_color;
+void main() {
+ int array[3];
+ array[0] = u_one; // array[0] should be 1
+ array[1] = 1 - u_two;
+ array[2] = u_three; // array[2] should be 3
+ int result = 0;
+ array[1] -= 1; // array[1] should be -u_two == -2
+ for (int i = 0; i < u_three; i++) {
+ result += array[i];
+ }
+ v_color = (result == 2) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+ gl_Position = pos;
+}
+</script>
+
+<script id="shader-vs-uint-implicit-unary-minus" type="x-shader/x-vertex">#version 300 es
+in highp vec4 pos;
+
+uniform uint u_one;
+uniform uint u_two;
+uniform uint u_three;
+
+out mediump vec4 v_color;
+void main() {
+ uint array[3];
+ array[0] = u_one; // array[0] should be 1u
+ array[1] = 1u - u_two;
+ array[2] = u_three; // array[2] should be 3u
+ uint result = 0u;
+ array[1] -= 1u; // array[1] should be -u_two == -2u
+ for (uint i = 0u; i < u_three; i++) {
+ result += array[i];
+ }
+ v_color = (result == 2u) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+ gl_Position = pos;
+}
+</script>
+
+<script id="shader-fs" type="x-shader/x-fragment">#version 300 es
+in mediump vec4 v_color;
+out mediump vec4 o_color;
+
+void main() {
+ o_color = v_color;
+}
+</script>
+
+<script>
+"use strict";
+
+function test() {
+ description();
+ debug("This test exposes an Intel driver bug on Windows.");
+ debug("");
+
+ var wtu = WebGLTestUtils;
+ var gl = wtu.create3DContext("canvas", undefined, 2);
+ if (!gl) {
+ testFailed("WebGL 2 context does not exist");
+ return;
+ }
+
+ var testNum = 0;
+ var border = 10; // border between test squares for visibility
+ var squareSize = 128;
+ var expectedColor = [0, 255, 0, 255]; // green
+
+ function subTest_int(message, VertexShader) {
+ debug(message);
+ var startX = (squareSize + border) * testNum;
+ var program = wtu.setupProgram(
+ gl, [VertexShader, "shader-fs"], ["pos"], null, true);
+ gl.viewport(startX, 0, squareSize, squareSize);
+
+ var one = gl.getUniformLocation(program, "u_one");
+ var two = gl.getUniformLocation(program, "u_two");
+ var three = gl.getUniformLocation(program, "u_three");
+ gl.uniform1i(one, 1);
+ gl.uniform1i(two, 2);
+ gl.uniform1i(three, 3);
+
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(
+ gl, startX, 0, squareSize, squareSize,
+ expectedColor, "square should be green", 1);
+ debug("");
+ testNum++;
+ }
+
+ function subTest_uint(message, VertexShader) {
+ debug(message);
+ var startX = (squareSize + border) * testNum;
+ var program = wtu.setupProgram(
+ gl, [VertexShader, "shader-fs"], ["pos"], null, true);
+ gl.viewport(startX, 0, squareSize, squareSize);
+
+ var one = gl.getUniformLocation(program, "u_one");
+ var two = gl.getUniformLocation(program, "u_two");
+ var three = gl.getUniformLocation(program, "u_three");
+ gl.uniform1ui(one, 1);
+ gl.uniform1ui(two, 2);
+ gl.uniform1ui(three, 3);
+
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(
+ gl, startX, 0, squareSize, squareSize,
+ expectedColor, "square should be green", 1);
+ debug("");
+ testNum++;
+ }
+
+ if (!gl) {
+ testFailed("context does not exist");
+ } else {
+ wtu.setupUnitQuad(gl);
+ subTest_int("Test unary minus operator on int.", "shader-vs-int");
+ subTest_uint("Test unary minus operator on unsigned int.", "shader-vs-uint");
+ subTest_int("Test unary minus operator on int with multiple brackets.", "shader-vs-int-multiple-brackets");
+ subTest_uint("Test unary minus operator on unsigned int with multiple brackets.", "shader-vs-uint-multiple-brackets");
+ subTest_int("Test implicit unary minus operator on int.", "shader-vs-int-implicit-unary-minus");
+ subTest_uint("Test implicit unary minus operator on unsigned int.", "shader-vs-uint-implicit-unary-minus");
+ }
+}
+
+test();
+var successfullyParsed = true;
+finishTest();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layout-match.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layout-match.html
new file mode 100644
index 0000000000..b92cefc882
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layout-match.html
@@ -0,0 +1,57 @@
+<!--
+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>WebGL2 Uniform Block Layout Behavior Testing</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="ES3VertexShader" type="x-shader/x-vertex">#version 300 es
+layout(std140) uniform Block
+{
+ highp vec4 val;
+};
+
+void main() {
+ gl_Position = vec4(val);
+}
+</script>
+<script id="ES3FragmentShader" type="x-shader/x-fragment">#version 300 es
+uniform Block
+{
+ highp vec4 val;
+};
+out highp vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(val);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+GLSLConformanceTester.runTests([
+ {
+ vShaderId: "ES3VertexShader",
+ vShaderSuccess: true,
+ fShaderId: "ES3FragmentShader",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "A uniform block's layout defaults to std140 if not specified."
+ },
+], 2);
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layouts.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layouts.html
new file mode 100644
index 0000000000..2dbfc664ee
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layouts.html
@@ -0,0 +1,63 @@
+<!--
+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>Disallowed uniform block layouts</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="fshaderPackedUniformBlock" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+layout(packed) uniform foo {
+ vec4 bar;
+};
+
+void main() {
+ my_FragColor = bar;
+}
+</script>
+<script id="fshaderSharedUniformBlock" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+layout(shared) uniform foo {
+ vec4 bar;
+};
+
+void main() {
+ my_FragColor = bar;
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("WebGL does not allow interface blocks with shared or packed layouts.");
+
+GLSLConformanceTester.runTests([
+{
+ fShaderId: 'fshaderPackedUniformBlock',
+ fShaderSuccess: false,
+ passMsg: 'Packed uniform buffers are disallowed'
+},
+{
+ fShaderId: 'fshaderSharedUniformBlock',
+ fShaderSuccess: false,
+ passMsg: 'Shared uniform buffers are disallowed'
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-location-length-limits.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-location-length-limits.html
new file mode 100644
index 0000000000..33bb787529
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-location-length-limits.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>WebGL uniform location length tests</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>
+</head>
+<body>
+<canvas id="example" width="50" height="50">
+There is supposed to be an example drawing here, but it's not important.
+</canvas>
+<div id="description">Verify limits on the lengths of uniform locations per WebGL 2 spec, "Maximum Uniform and Attribute Location Lengths".</div>
+<div id="console"></div>
+<script id="goodVertexShader" type="x-shader/x-vertex">
+// A vertex shader where the needed uniform location is exactly 1024 characters.
+struct Nesting2 {
+ vec4 identifier254CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345;
+};
+
+struct Nesting1 {
+ Nesting2 identifier256CharactersLong_012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567;
+};
+
+uniform Nesting1 identifier512CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345670123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345;
+
+void main() {
+ gl_Position = identifier512CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345670123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345.identifier256CharactersLong_012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567.identifier254CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345;
+}
+</script>
+<script id="badVertexShader" type="x-shader/x-vertex">
+// A vertex shader where the needed uniform location is 1025 characters.
+struct Nesting2 {
+ vec4 identifier255CharactersLong_01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456;
+};
+
+struct Nesting1 {
+ Nesting2 identifier256CharactersLong_012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567;
+};
+
+uniform Nesting1 identifier512CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345670123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345;
+
+void main() {
+ Nesting2 temp = identifier512CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345670123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345.identifier256CharactersLong_012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567;
+ gl_Position = temp.identifier255CharactersLong_01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456;
+}
+</script>
+<script id="fragmentShader" type="x-shader/x-fragment">
+precision mediump float;
+
+void main() {
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", undefined, 2);
+var uniform1024Name = "identifier512CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345670123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345.identifier256CharactersLong_012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567.identifier254CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345";
+var uniform1025Name = "identifier512CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345670123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345.identifier256CharactersLong_012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567.identifier255CharactersLong_01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456";
+
+debug("Test uniform location underneath the length limit");
+var program = wtu.loadProgramFromScript(gl, "goodVertexShader", "fragmentShader");
+shouldBe('gl.getProgramParameter(program, gl.LINK_STATUS)', 'true');
+var uniformLoc = gl.getUniformLocation(program, uniform1024Name);
+shouldBeNonNull('uniformLoc');
+wtu.glErrorShouldBe(gl, gl.NONE);
+
+debug("Test uniform location over the length limit");
+program = wtu.loadProgramFromScript(gl, "badVertexShader", "fragmentShader");
+wtu.glErrorShouldBe(gl, gl.NONE);
+shouldBe('gl.getProgramParameter(program, gl.LINK_STATUS)', 'true');
+var uniformLoc = gl.getUniformLocation(program, uniform1025Name);
+wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
+shouldBeNull('uniformLoc');
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-struct-with-non-square-matrix.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-struct-with-non-square-matrix.html
new file mode 100644
index 0000000000..9df7b5a88f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-struct-with-non-square-matrix.html
@@ -0,0 +1,51 @@
+<!--
+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 uniform struct with a non-square matrix 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="fshaderUniformStructWithNonSquareMatrixAndBoolean" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out highp vec4 my_color;
+struct S
+{
+ mat2x4 m;
+ bool b;
+};
+uniform S uni;
+void main()
+{
+ my_color = vec4(0, 1, 0, 1);
+ if (!uni.b) { my_color.g = 0.0; }
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderUniformStructWithNonSquareMatrixAndBoolean',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Set a boolean member in a uniform struct that also contains a non-square-matrix',
+ uniforms: [{name: "uni.b", functionName: "uniform1i", value: 1}]
+},
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uninitialized-local-global-variables.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uninitialized-local-global-variables.html
new file mode 100644
index 0000000000..0d5be3da22
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uninitialized-local-global-variables.html
@@ -0,0 +1,98 @@
+<!--
+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>Uninitialized local/global variables should be initialized (ESSL 3.00 cases)</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>
+
+<!--
+This test covers cases that can't be tested with ESSL 1.00 due to Appendix A limitations.
+The ESSL 1.00 cases are covered in conformance/glsl/misc/uninitialized-local-global-variables.html
+-->
+
+<script id="vs_uninit_in_frag" type="x-shader/x-vertex">#version 300 es
+precision highp float;
+in vec4 a_position;
+void main() {
+ gl_Position = a_position;
+}
+</script>
+
+<!-- Uninitialized variables in a for loop initializer in fragment shader -->
+<script id="fs_uninit_variables_in_loop_in_frag" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+void main() {
+ int i = 0;
+ for (vec4 uninit, uninit2[2] = vec4[2](uninit, uninit); i < 1; ++i) {
+ my_FragColor = uninit2[0];
+ }
+}
+</script>
+
+<!-- Uninitialized nameless struct in a for loop initializer in fragment shader -->
+<script id="fs_uninit_nameless_struct_in_loop_in_frag" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+void main() {
+ int i = 0;
+ for (struct { vec4 v; } uninit; i < 1; ++i) {
+ my_FragColor = uninit.v;
+ }
+}
+</script>
+
+</head>
+<body>
+<canvas id="canvas" width="50" height="50"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description('Uninitialized local/global variables should be initialized: http://anglebug.com/1966');
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas", undefined, 2);
+wtu.setupUnitQuad(gl);
+
+var cases = [
+ {
+ name: "Uninitialized variables in a for loop initializer in fragment shader",
+ prog: ["vs_uninit_in_frag", "fs_uninit_variables_in_loop_in_frag"],
+ },
+ {
+ name: "Uninitialized nameless struct in a for loop initializer in fragment shader",
+ prog: ["vs_uninit_in_frag", "fs_uninit_nameless_struct_in_loop_in_frag"],
+ }
+];
+
+function runTest() {
+ for (var i = 0; i < cases.length; ++i) {
+ debug("");
+ debug(cases[i].name);
+ var program = wtu.setupProgram(gl, cases[i].prog, ["a_position"], undefined, true);
+ gl.clearColor(1.0, 0.0, 0.0, 1.0);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 0, 0, 0]);
+ }
+
+ debug("");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+runTest();
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/valid-invariant.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/valid-invariant.html
new file mode 100644
index 0000000000..a4fffaf061
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/valid-invariant.html
@@ -0,0 +1,95 @@
+<!--
+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>Positive tests for the use of the invariant qualifier and pragma</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="vertexShaderInvariant" type="text/something-not-javascript">#version 300 es
+precision mediump float;
+invariant out vec4 v_varying;
+
+void main()
+{
+ v_varying = vec4(0.0, 0.0, 0.0, 1.0);
+ gl_Position = v_varying;
+}
+</script>
+<script id="vertexShaderSeparateInvariant" type="text/something-not-javascript">#version 300 es
+precision mediump float;
+out vec4 v_varying;
+invariant v_varying;
+
+void main()
+{
+ v_varying = vec4(0.0, 0.0, 0.0, 1.0);
+ gl_Position = v_varying;
+}
+</script>
+<script id="vertexShaderGlobalInvariant" type="text/something-not-javascript">#version 300 es
+#pragma STDGL invariant(all)
+precision mediump float;
+out vec4 v_varying;
+
+void main()
+{
+ v_varying = vec4(0.0, 0.0, 0.0, 1.0);
+ gl_Position = v_varying;
+}
+</script>
+<script id="fragmentShaderVariant" type="text/something-not-javascript">#version 300 es
+precision mediump float;
+
+in vec4 v_varying;
+out vec4 my_color;
+
+void main()
+{
+ my_color = v_varying;
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+GLSLConformanceTester.runTests([
+ {
+ vShaderId: "vertexShaderInvariant",
+ vShaderSuccess: true,
+ fShaderId: "fragmentShaderVariant",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "vertex shader with invariant varying and fragment shader with variant varying must succeed",
+ },
+ {
+ vShaderId: "vertexShaderGlobalInvariant",
+ vShaderSuccess: true,
+ fShaderId: "fragmentShaderVariant",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "vertex shader with invariant (global setting) varying and fragment shader with variant varying must succeed",
+ },
+ {
+ vShaderId: "vertexShaderSeparateInvariant",
+ vShaderSuccess: true,
+ fShaderId: "fragmentShaderVariant",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "vertex shader with invariant (separately set) varying and fragment shader with variant varying must succeed",
+ },
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/varying-struct-inline-definition.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/varying-struct-inline-definition.html
new file mode 100644
index 0000000000..f3ac2485e1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/varying-struct-inline-definition.html
@@ -0,0 +1,62 @@
+<!--
+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 varying struct with inline definition 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="vshader" type="x-shader/x-vertex">#version 300 es
+
+in vec4 vPosition;
+
+flat out struct S {
+ int field;
+} v_s;
+
+void main() {
+ v_s.field = 1;
+ gl_Position = vPosition;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+
+flat in struct S {
+ int field;
+} v_s;
+
+out vec4 my_FragColor;
+
+void main() {
+ my_FragColor = vec4(1 - v_s.field, v_s.field, 0, 1);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+
+GLSLConformanceTester.runRenderTests([
+{
+ vShaderId: 'vshader',
+ vShaderSuccess: true,
+ fShaderId: 'fshader',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Vertex output struct / fragment input struct with an inline definition should compile and link'
+}
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-nv-driver-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-nv-driver-bug.html
new file mode 100644
index 0000000000..767bfd915d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-nv-driver-bug.html
@@ -0,0 +1,67 @@
+<!--
+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 dynamic vector and matrix indexing 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="fshaderLValueVectorBeingIndexedHasSideEffects" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+int sideEffectCounter = 0;
+
+int funcWithSideEffects() {
+ sideEffectCounter++;
+ return 1;
+}
+
+void main() {
+ vec4 V[2];
+ V[0] = vec4(1.0, 2.0, 3.0, 4.0);
+ V[1] = vec4(5.0, 6.0, 7.0, 8.0);
+ // In case this is broken down to two expressions where one reads V[funcWithSideEffects()]
+ // and another writes it, it needs to be made sure that funcWithSideEffects() only gets called once.
+ V[funcWithSideEffects()][u_zero + 1]++;
+ vec4 expectedV0 = vec4(1.0, 2.0, 3.0, 4.0);
+ vec4 expectedV1 = vec4(5.0, 7.0, 7.0, 8.0);
+ float f = 1.0 - distance(V[0], expectedV0) - distance(V[1], expectedV1);
+ if (sideEffectCounter != 1) {
+ f = 0.0;
+ }
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Dynamic indexing of vectors and matrices should work.");
+
+debug("This test exposes a NVidia driver bug on Linux");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderLValueVectorBeingIndexedHasSideEffects',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index a vector expression that itself has side effects, in an l-value'
+},
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html
new file mode 100644
index 0000000000..4b82d6ed30
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.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>GLSL swizzled vector l-value dynamic indexing 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>
+<!--
+ The shader first assigns v.x to v.z (1.0)
+ Then v.y to v.y (2.0)
+ Then v.z to v.x (1.0)
+-->
+<script id="fshaderSwizzledLValueIndexing" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+void main() {
+ vec3 v = vec3(1.0, 2.0, 3.0);
+ for (int i = 0; i < 3; i++) {
+ v.zyx[i] = v[i];
+ }
+ my_FragColor = distance(v, vec3(1.0, 2.0, 1.0)) < 0.01 ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Dynamic indexing of swizzled l-values should work.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderSwizzledLValueIndexing',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index an l-value swizzled vector'
+},
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing.html
new file mode 100644
index 0000000000..5bf60578ad
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing.html
@@ -0,0 +1,369 @@
+<!--
+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 dynamic vector and matrix indexing 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="fshaderIndexMatrixTwice" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main() {
+ mat2 m = mat2(0.0, 0.0, 0.0, 1.0);
+ float f = m[u_zero + 1][u_zero + 1];
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexWithValueFromIndexingExpression" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main() {
+ ivec2 i = ivec2(0, 2);
+ vec4 v = vec4(0.0, 0.2, 1.0, 0.4);
+ float f = v[i[u_zero + 1]];
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexLValue" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main() {
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ v[u_zero + 1] = 5.0;
+ vec4 expected = vec4(1.0, 5.0, 3.0, 4.0);
+ float f = 1.0 - distance(v, expected);
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexLValueWithValueFromIndexingExpression" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main() {
+ ivec2 i = ivec2(0, 2);
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ v[i[u_zero + 1]] = 5.0;
+ vec4 expected = vec4(1.0, 2.0, 5.0, 4.0);
+ float f = 1.0 - distance(v, expected);
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexBuiltInFunctionCallOutParameter" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main() {
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ modf(5.5, v[u_zero + 3]);
+ vec4 expected = vec4(1.0, 2.0, 3.0, 5.0);
+ float f = 1.0 - distance(v, expected);
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexUserDefinedFunctionCallOutParameter" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void foo(out float f) {
+ modf(5.5, f);
+}
+
+void main() {
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ foo(v[u_zero + 3]);
+ vec4 expected = vec4(1.0, 2.0, 3.0, 5.0);
+ float f = 1.0 - distance(v, expected);
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexUserDefinedFunctionCallInOutParameter" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void foo(inout float f) {
+ float g = f + 2.5;
+ modf(g, f);
+}
+
+void main() {
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ foo(v[u_zero + 2]);
+ vec4 expected = vec4(1.0, 2.0, 5.0, 4.0);
+ float f = 1.0 - distance(v, expected);
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexWithSideEffects" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+int sideEffectCounter = 0;
+
+int funcWithSideEffects() {
+ sideEffectCounter++;
+ return 2;
+}
+
+void main() {
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ v[funcWithSideEffects()] = 5.0;
+ vec4 expected = vec4(1.0, 2.0, 5.0, 4.0);
+ float f = 1.0 - distance(v, expected);
+ if (sideEffectCounter != 1) {
+ f = 0.0;
+ }
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexInOutWithSideEffects" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+int sideEffectCounter = 0;
+
+int funcWithSideEffects() {
+ sideEffectCounter++;
+ return 2;
+}
+
+void main() {
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ v[funcWithSideEffects()]++;
+ vec4 expected = vec4(1.0, 2.0, 4.0, 4.0);
+ float f = 1.0 - distance(v, expected);
+ if (sideEffectCounter != 1) {
+ f = 0.0;
+ }
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexUserDefinedFunctionCallInOutParameterWithIndexWithSideEffects" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+int sideEffectCounter = 0;
+
+void foo(inout float f) {
+ float g = f + 2.5;
+ modf(g, f);
+}
+
+int funcWithSideEffects() {
+ sideEffectCounter++;
+ return 2;
+}
+
+void main() {
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ foo(v[funcWithSideEffects()]);
+ vec4 expected = vec4(1.0, 2.0, 5.0, 4.0);
+ float f = 1.0 - distance(v, expected);
+ if (sideEffectCounter != 1) {
+ f = 0.0;
+ }
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexLValueWithUint" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform uint u_zero;
+
+void main() {
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ v[u_zero] = 5.0;
+ vec4 expected = vec4(5.0, 2.0, 3.0, 4.0);
+ float f = 1.0 - distance(v, expected);
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexUniform" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform vec4 u_zeroVec;
+uniform uint u_zero;
+
+void main() {
+ // This test is just to catch a crash bug that occurred in ANGLE's workaround.
+ // Rendering result is not meaningful.
+ float f = u_zeroVec[u_zero];
+ my_FragColor = vec4(f, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="fshaderSequenceDynamicIndexingVectorLvalue" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform int u_zero;
+
+int sideEffectCounter = 0;
+float func() {
+ ++sideEffectCounter;
+ return -1.0;
+}
+
+void main() {
+ vec4 v = vec4(0.0, 2.0, 4.0, 6.0);
+ float f = (func(), (++v[u_zero + sideEffectCounter]));
+ my_FragColor = (abs(f - 3.0) < 0.01 && abs(v[1] - 3.0) < 0.01 && sideEffectCounter == 1) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+}
+</script>
+<script id="fshaderIndexMatrixTwiceInLValue" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main() {
+ mat2 m = mat2(0.0, 0.0, 0.0, 0.0);
+ m[u_zero + 1][u_zero + 1] = float(u_zero + 1);
+ float f = m[1][1];
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Dynamic indexing of vectors and matrices should work.");
+
+debug("Dynamic indexing of vectors and matrices requires complex workarounds on HLSL backends. Try to test possible bugs those workarounds might have.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderIndexMatrixTwice',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index matrix and then index the resulting vector in the same expression'
+},
+{
+ fShaderId: 'fshaderIndexWithValueFromIndexingExpression',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index a vector with an index that is the result of indexing'
+},
+{
+ fShaderId: 'fshaderIndexLValue',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index on the left-hand side of assignment'
+},
+{
+ fShaderId: 'fshaderIndexLValueWithValueFromIndexingExpression',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index on the left-hand side of assignment with an index that is the result of indexing'
+},
+{
+ fShaderId: 'fshaderIndexBuiltInFunctionCallOutParameter',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index the out parameter passed to built-in modf'
+},
+{
+ fShaderId: 'fshaderIndexUserDefinedFunctionCallOutParameter',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index an out parameter passed to an user-defined function'
+},
+{
+ fShaderId: 'fshaderIndexUserDefinedFunctionCallInOutParameter',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index an inout parameter passed to an user-defined function'
+},
+{
+ fShaderId: 'fshaderIndexWithSideEffects',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Use expression with side effects as an index of an l-value'
+},
+{
+ fShaderId: 'fshaderIndexInOutWithSideEffects',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Use expression with side effects as an index of an l-value that is both read and written'
+},
+{
+ fShaderId: 'fshaderIndexUserDefinedFunctionCallInOutParameterWithIndexWithSideEffects',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index an inout parameter passed to an user-defined function with an index with side effects'
+},
+{
+ fShaderId: 'fshaderIndexLValueWithUint',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index on the left-hand side of assignment with an uint'
+},
+{
+ fShaderId: 'fshaderIndexUniform',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index a uniform with a uniform'
+},
+{
+ fShaderId: 'fshaderSequenceDynamicIndexingVectorLvalue',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Sequence operator with dynamic indexing of a vector as an l-value inside'
+},
+{
+ fShaderId: 'fshaderIndexMatrixTwiceInLValue',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index matrix and then index the resulting vector in the same expression inside an l-value'
+}
+], 2);
+</script>
+</body>
+</html>
+