tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

constant-index-out-of-range.html (7878B)


      1 <!--
      2 Copyright (c) 2019 The Khronos Group Inc.
      3 Use of this source code is governed by an MIT-style license that can be
      4 found in the LICENSE.txt file.
      5 -->
      6 
      7 <!DOCTYPE html>
      8 <html>
      9 <head>
     10 <meta charset="utf-8">
     11 <title>Indexing with a constant expression should compile only if the index is in range</title>
     12 <link rel="stylesheet" href="../resources/js-test-style.css"/>
     13 <link rel="stylesheet" href="../resources/glsl-feature-tests.css"/>
     14 <script src="../js/js-test-pre.js"></script>
     15 <script src="../js/webgl-test-utils.js"></script>
     16 <script src="../js/glsl-conformance-test.js"></script>
     17 <script id="VertexArrayTemplate" type="x-shader/x-vertex">
     18 precision mediump float;
     19 
     20 uniform float ua[4];
     21 
     22 $(init)
     23 
     24 void main() {
     25    float c = ua[$(constantExpression)];
     26    gl_Position = vec4(c);
     27 }
     28 </script>
     29 <script id="FragmentArrayTemplate" type="x-shader/x-fragment">
     30 precision mediump float;
     31 
     32 uniform float ua[4];
     33 
     34 $(init)
     35 
     36 void main() {
     37    float c = ua[$(constantExpression)];
     38    gl_FragColor = vec4(c);
     39 }
     40 </script>
     41 <script id="VertexVectorTemplate" type="x-shader/x-vertex">
     42 precision mediump float;
     43 
     44 uniform vec4 uv;
     45 
     46 $(init)
     47 
     48 void main() {
     49    float c = uv[$(constantExpression)];
     50    gl_Position = vec4(c);
     51 }
     52 </script>
     53 <script id="FragmentVectorTemplate" type="x-shader/x-fragment">
     54 precision mediump float;
     55 
     56 uniform vec4 uv;
     57 
     58 $(init)
     59 
     60 void main() {
     61    float c = uv[$(constantExpression)];
     62    gl_FragColor = vec4(c);
     63 }
     64 </script>
     65 <script id="VertexMatrixTemplate" type="x-shader/x-vertex">
     66 precision mediump float;
     67 
     68 uniform mat4 um;
     69 
     70 $(init)
     71 
     72 void main() {
     73    float c = um[$(constantExpression)].x;
     74    gl_Position = vec4(c);
     75 }
     76 </script>
     77 <script id="FragmentMatrixTemplate" type="x-shader/x-fragment">
     78 precision mediump float;
     79 
     80 uniform mat4 um;
     81 
     82 $(init)
     83 
     84 void main() {
     85    float c = um[$(constantExpression)].x;
     86    gl_FragColor = vec4(c);
     87 }
     88 </script>
     89 </head>
     90 <body onload="runTest()">
     91 <div id="description"></div>
     92 <div id="console"></div>
     93 <script type="application/javascript">
     94 "use strict";
     95 description();
     96 
     97 var wtu = WebGLTestUtils;
     98 
     99 // ESSL 1.00 section 4.1.9 Arrays
    100 // It is illegal to index an array with an integral constant expression greater than or equal to its
    101 // declared size. It is also illegal to index an array with a negative constant expression.
    102 
    103 // ESSL 1.00 section 5.5 Vector Components
    104 // Reading from or writing to a vector using a constant integral expression with a value that is negative
    105 // or greater than or equal to the size of the vector is illegal.
    106 
    107 // ESSL 1.00 section 5.6 Matrix components
    108 // The behavior when accessing a component outside the bounds of a matrix are the same as those for
    109 // vectors and arrays. The compiler must generate an error if the index expression is a constant expression.
    110 
    111 // ESSL 1.00 spec section 5.10.
    112 // A constant expression is one of
    113 // * a literal value (e.g., 5 or true)
    114 // * a global or local variable qualified as const excluding function parameters
    115 // * an expression formed by an operator on operands that are constant expressions, including getting
    116 // an element of a constant vector or a constant matrix, or a field of a constant structure
    117 // * a constructor whose arguments are all constant expressions
    118 // * a built-in function call whose arguments are all constant expressions, with the exception of the
    119 // texture lookup functions.
    120 
    121 var runTest = function() {
    122  var vsArrayTemplate = document.getElementById('VertexArrayTemplate').text;
    123  var fsArrayTemplate = document.getElementById('FragmentArrayTemplate').text;
    124  var vsVectorTemplate = document.getElementById('VertexVectorTemplate').text;
    125  var fsVectorTemplate = document.getElementById('FragmentVectorTemplate').text;
    126  var vsMatrixTemplate = document.getElementById('VertexMatrixTemplate').text;
    127  var fsMatrixTemplate = document.getElementById('FragmentMatrixTemplate').text;
    128 
    129  var tests = [];
    130 
    131  var pushTest = function(constantExpression, expectSuccess, opt_init) {
    132    if (opt_init === undefined) {
    133        opt_init = '';
    134    }
    135    tests.push({
    136      vShaderSource: wtu.replaceParams(vsArrayTemplate, {constantExpression: constantExpression, init: opt_init}),
    137      vShaderSuccess: expectSuccess,
    138      linkSuccess: expectSuccess,
    139      passMsg: "Using " + constantExpression + " as an index for an array with size 4 in a vertex shader should " + (expectSuccess ? "compile." : "fail compilation.")
    140    });
    141    tests.push({
    142      fShaderSource: wtu.replaceParams(fsArrayTemplate, {constantExpression: constantExpression, init: opt_init}),
    143      fShaderSuccess: expectSuccess,
    144      linkSuccess: expectSuccess,
    145      passMsg: "Using " + constantExpression + " as an index for an array with size 4 in a fragment shader should " + (expectSuccess ? "compile." : "fail compilation.")
    146    });
    147    tests.push({
    148      vShaderSource: wtu.replaceParams(vsVectorTemplate, {constantExpression: constantExpression, init: opt_init}),
    149      vShaderSuccess: expectSuccess,
    150      linkSuccess: expectSuccess,
    151      passMsg: "Using " + constantExpression + " as a vec4 index in a vertex shader should " + (expectSuccess ? "compile." : "fail compilation.")
    152    });
    153    tests.push({
    154      fShaderSource: wtu.replaceParams(fsVectorTemplate, {constantExpression: constantExpression, init: opt_init}),
    155      fShaderSuccess: expectSuccess,
    156      linkSuccess: expectSuccess,
    157      passMsg: "Using " + constantExpression + " as a vec4 index in a fragment shader should " + (expectSuccess ? "compile." : "fail compilation.")
    158    });
    159    tests.push({
    160      vShaderSource: wtu.replaceParams(vsMatrixTemplate, {constantExpression: constantExpression, init: opt_init}),
    161      vShaderSuccess: expectSuccess,
    162      linkSuccess: expectSuccess,
    163      passMsg: "Using " + constantExpression + " as a mat4 index in a vertex shader should " + (expectSuccess ? "compile." : "fail compilation.")
    164    });
    165    tests.push({
    166      fShaderSource: wtu.replaceParams(fsMatrixTemplate, {constantExpression: constantExpression, init: opt_init}),
    167      fShaderSuccess: expectSuccess,
    168      linkSuccess: expectSuccess,
    169      passMsg: "Using " + constantExpression + " as a mat4 index in a fragment shader should " + (expectSuccess ? "compile." : "fail compilation.")
    170    });
    171  }
    172 
    173  pushTest('0', true);
    174  pushTest('3', true);
    175  pushTest('-1', false);
    176  pushTest('4', false);
    177  pushTest('2 + 2', false);
    178  pushTest('6 - 2', false);
    179  pushTest('2 * 2', false);
    180  pushTest('8 / 2', false);
    181  pushTest('int(true) * 4', false);
    182  pushTest('ivec4(4).x', false);
    183  pushTest('ivec4(4)[0]', false);
    184  pushTest('int(vec4(5.0).x)', false);
    185  pushTest('int(mat4(5.0)[0].x)', false);
    186 
    187  pushTest('int(radians(360.0))', false);
    188  pushTest('int(degrees(1.0))', false);
    189  pushTest('int(5.0 + sin(0.0))', false);
    190  pushTest('int(5.0 + asin(0.0))', false);
    191  pushTest('int(pow(2.0, 3.0))', false);
    192  pushTest('int(exp(3.0))', false);
    193  pushTest('int(exp2(4.0))', false);
    194  pushTest('int(floor(-0.5))', false); // floor(-0.5) = -1.0
    195  pushTest('int(5.0 + fract(-3.5))', false);
    196  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
    197  pushTest('int(mix(2.0, 8.0, 0.9))', false);
    198  pushTest('int(length(vec4(3.0)))', false);
    199  pushTest('int(lessThan(vec4(2.0), vec4(3.0)).x) * 4', false);
    200 
    201  pushTest('true ? 5 : 0', false);
    202  pushTest('int(false ? 0.0 : 5.0)', false);
    203  pushTest('my_struct(5, 1).field', false, 'struct my_struct { int field; int field2; };');
    204 
    205  pushTest('int(-0.9)', true); // conversion to int drops the fractional part
    206 
    207  // Sequence operator returns the value of the right-most expression.
    208  // Note that the sequence operator is allowed in constant expressions in ESSL 1.00,
    209  // but not in ESSL 3.00, so with ESSL 3.00 failing compilation would not be required.
    210  pushTest('5, 1', true);
    211  pushTest('1, 5', false);
    212 
    213  GLSLConformanceTester.runTests(tests);
    214 }
    215 
    216 var successfullyParsed = true;
    217 </script>
    218 </body>
    219 </html>