diff options
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/extra/constant-index-out-of-range.html')
-rw-r--r-- | dom/canvas/test/webgl-conf/checkout/extra/constant-index-out-of-range.html | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/extra/constant-index-out-of-range.html b/dom/canvas/test/webgl-conf/checkout/extra/constant-index-out-of-range.html new file mode 100644 index 0000000000..f16ade96af --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/constant-index-out-of-range.html @@ -0,0 +1,219 @@ +<!-- +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>Indexing with a constant expression should compile only if the index is in range</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 id="VertexArrayTemplate" type="x-shader/x-vertex"> +precision mediump float; + +uniform float ua[4]; + +$(init) + +void main() { + float c = ua[$(constantExpression)]; + gl_Position = vec4(c); +} +</script> +<script id="FragmentArrayTemplate" type="x-shader/x-fragment"> +precision mediump float; + +uniform float ua[4]; + +$(init) + +void main() { + float c = ua[$(constantExpression)]; + gl_FragColor = vec4(c); +} +</script> +<script id="VertexVectorTemplate" type="x-shader/x-vertex"> +precision mediump float; + +uniform vec4 uv; + +$(init) + +void main() { + float c = uv[$(constantExpression)]; + gl_Position = vec4(c); +} +</script> +<script id="FragmentVectorTemplate" type="x-shader/x-fragment"> +precision mediump float; + +uniform vec4 uv; + +$(init) + +void main() { + float c = uv[$(constantExpression)]; + gl_FragColor = vec4(c); +} +</script> +<script id="VertexMatrixTemplate" type="x-shader/x-vertex"> +precision mediump float; + +uniform mat4 um; + +$(init) + +void main() { + float c = um[$(constantExpression)].x; + gl_Position = vec4(c); +} +</script> +<script id="FragmentMatrixTemplate" type="x-shader/x-fragment"> +precision mediump float; + +uniform mat4 um; + +$(init) + +void main() { + float c = um[$(constantExpression)].x; + gl_FragColor = vec4(c); +} +</script> +</head> +<body onload="runTest()"> +<div id="description"></div> +<div id="console"></div> +<script type="application/javascript"> +"use strict"; +description(); + +var wtu = WebGLTestUtils; + +// ESSL 1.00 section 4.1.9 Arrays +// It is illegal to index an array with an integral constant expression greater than or equal to its +// declared size. It is also illegal to index an array with a negative constant expression. + +// ESSL 1.00 section 5.5 Vector Components +// Reading from or writing to a vector using a constant integral expression with a value that is negative +// or greater than or equal to the size of the vector is illegal. + +// ESSL 1.00 section 5.6 Matrix components +// The behavior when accessing a component outside the bounds of a matrix are the same as those for +// vectors and arrays. The compiler must generate an error if the index expression is a constant expression. + +// ESSL 1.00 spec section 5.10. +// A constant expression is one of +// * a literal value (e.g., 5 or true) +// * a global or local variable qualified as const excluding function parameters +// * an expression formed by an operator on operands that are constant expressions, including getting +// an element of a constant vector or a constant matrix, or a field of a constant structure +// * a constructor whose arguments are all constant expressions +// * a built-in function call whose arguments are all constant expressions, with the exception of the +// texture lookup functions. + +var runTest = function() { + var vsArrayTemplate = document.getElementById('VertexArrayTemplate').text; + var fsArrayTemplate = document.getElementById('FragmentArrayTemplate').text; + var vsVectorTemplate = document.getElementById('VertexVectorTemplate').text; + var fsVectorTemplate = document.getElementById('FragmentVectorTemplate').text; + var vsMatrixTemplate = document.getElementById('VertexMatrixTemplate').text; + var fsMatrixTemplate = document.getElementById('FragmentMatrixTemplate').text; + + var tests = []; + + var pushTest = function(constantExpression, expectSuccess, opt_init) { + if (opt_init === undefined) { + opt_init = ''; + } + tests.push({ + vShaderSource: wtu.replaceParams(vsArrayTemplate, {constantExpression: constantExpression, init: opt_init}), + vShaderSuccess: expectSuccess, + linkSuccess: expectSuccess, + passMsg: "Using " + constantExpression + " as an index for an array with size 4 in a vertex shader should " + (expectSuccess ? "compile." : "fail compilation.") + }); + tests.push({ + fShaderSource: wtu.replaceParams(fsArrayTemplate, {constantExpression: constantExpression, init: opt_init}), + fShaderSuccess: expectSuccess, + linkSuccess: expectSuccess, + passMsg: "Using " + constantExpression + " as an index for an array with size 4 in a fragment shader should " + (expectSuccess ? "compile." : "fail compilation.") + }); + tests.push({ + vShaderSource: wtu.replaceParams(vsVectorTemplate, {constantExpression: constantExpression, init: opt_init}), + vShaderSuccess: expectSuccess, + linkSuccess: expectSuccess, + passMsg: "Using " + constantExpression + " as a vec4 index in a vertex shader should " + (expectSuccess ? "compile." : "fail compilation.") + }); + tests.push({ + fShaderSource: wtu.replaceParams(fsVectorTemplate, {constantExpression: constantExpression, init: opt_init}), + fShaderSuccess: expectSuccess, + linkSuccess: expectSuccess, + passMsg: "Using " + constantExpression + " as a vec4 index in a fragment shader should " + (expectSuccess ? "compile." : "fail compilation.") + }); + tests.push({ + vShaderSource: wtu.replaceParams(vsMatrixTemplate, {constantExpression: constantExpression, init: opt_init}), + vShaderSuccess: expectSuccess, + linkSuccess: expectSuccess, + passMsg: "Using " + constantExpression + " as a mat4 index in a vertex shader should " + (expectSuccess ? "compile." : "fail compilation.") + }); + tests.push({ + fShaderSource: wtu.replaceParams(fsMatrixTemplate, {constantExpression: constantExpression, init: opt_init}), + fShaderSuccess: expectSuccess, + linkSuccess: expectSuccess, + passMsg: "Using " + constantExpression + " as a mat4 index in a fragment shader should " + (expectSuccess ? "compile." : "fail compilation.") + }); + } + + pushTest('0', true); + pushTest('3', true); + pushTest('-1', false); + pushTest('4', false); + pushTest('2 + 2', false); + pushTest('6 - 2', false); + pushTest('2 * 2', false); + pushTest('8 / 2', false); + pushTest('int(true) * 4', false); + pushTest('ivec4(4).x', false); + pushTest('ivec4(4)[0]', false); + pushTest('int(vec4(5.0).x)', false); + pushTest('int(mat4(5.0)[0].x)', false); + + pushTest('int(radians(360.0))', false); + pushTest('int(degrees(1.0))', false); + pushTest('int(5.0 + sin(0.0))', false); + pushTest('int(5.0 + asin(0.0))', false); + pushTest('int(pow(2.0, 3.0))', false); + pushTest('int(exp(3.0))', false); + pushTest('int(exp2(4.0))', false); + pushTest('int(floor(-0.5))', false); // floor(-0.5) = -1.0 + pushTest('int(5.0 + fract(-3.5))', false); + pushTest('int(mod(2.0, -4.0))', false); // mod(2.0, -4.0) = 2.0 - (-4.0) * floor(2.0 / -4.0) = 2.0 + 4.0 * (-1.0) = -2.0 + pushTest('int(mix(2.0, 8.0, 0.9))', false); + pushTest('int(length(vec4(3.0)))', false); + pushTest('int(lessThan(vec4(2.0), vec4(3.0)).x) * 4', false); + + pushTest('true ? 5 : 0', false); + pushTest('int(false ? 0.0 : 5.0)', false); + pushTest('my_struct(5, 1).field', false, 'struct my_struct { int field; int field2; };'); + + pushTest('int(-0.9)', true); // conversion to int drops the fractional part + + // Sequence operator returns the value of the right-most expression. + // Note that the sequence operator is allowed in constant expressions in ESSL 1.00, + // but not in ESSL 3.00, so with ESSL 3.00 failing compilation would not be required. + pushTest('5, 1', true); + pushTest('1, 5', false); + + GLSLConformanceTester.runTests(tests); +} + +var successfullyParsed = true; +</script> +</body> +</html> |