tor-browser

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

too-small-buffers.html (10734B)


      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>TF too small buffers</title>
     12 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
     13 <script src="../../js/js-test-pre.js"></script>
     14 <script src="../../js/webgl-test-utils.js"></script>
     15 </head>
     16 <body>
     17 <div id="description"></div>
     18 <canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
     19 <div id="console"></div>
     20 <script id="vshader" type="x-shader/x-vertex">#version 300 es
     21 in float in_value1;
     22 in float in_value2;
     23 out float out_value1;
     24 out float out_value2;
     25 void main() {
     26   out_value1 = in_value1 * 2.;
     27   out_value2 = in_value2 * 2.;
     28 }
     29 </script>
     30 <script id="fshader" type="x-shader/x-fragment">#version 300 es
     31 precision mediump float;
     32 out vec4 dummy;
     33 void main() {
     34  dummy = vec4(0.);
     35 }
     36 </script>
     37 <script>
     38 "use strict";
     39 description("Transform feedback into buffers that are too small should produce errors.");
     40 
     41 var wtu = WebGLTestUtils;
     42 var canvas = document.getElementById("canvas");
     43 var gl = wtu.create3DContext(canvas, null, 2);
     44 
     45 if (!gl) {
     46    testFailed("WebGL context does not exist");
     47 } else {
     48    testPassed("WebGL context exists");
     49 }
     50 
     51 const progInterleaved = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
     52    ["out_value1", "out_value2"], gl.INTERLEAVED_ATTRIBS,
     53    ["in_value1", "in_value2"]);
     54 const progSeparate = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
     55    ["out_value1", "out_value2"], gl.SEPARATE_ATTRIBS,
     56    ["in_value1", "in_value2"]);
     57 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "program compilation");
     58 
     59 // Attrib 1 contains 4 vertices. Attrib 2 contains 4 instance indices.
     60 const vertexBuffer0 = gl.createBuffer();
     61 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer0);
     62 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 2, 3, 4]), gl.STATIC_DRAW);
     63 const vertexBuffer1 = gl.createBuffer();
     64 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer1);
     65 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 2, 3, 4]), gl.STATIC_DRAW);
     66 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer0);
     67 gl.enableVertexAttribArray(0);
     68 gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 0);
     69 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer1);
     70 gl.enableVertexAttribArray(1);
     71 gl.vertexAttribPointer(1, 1, gl.FLOAT, false, 0, 0);
     72 gl.vertexAttribDivisor(1, 1);
     73 
     74 let tfBuffer0 = gl.createBuffer();
     75 let tfBuffer1 = gl.createBuffer();
     76 
     77 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "setup");
     78 
     79 const sizeOfFloat = 4;
     80 
     81 let cases = [
     82    { name: "drawArrays",
     83      drawFunction: ()=>gl.drawArrays(gl.POINTS, 0, 4),
     84      result: [[2, 4, 6, 8], [2, 2, 2, 2]]},
     85    { name: "drawArraysInstanced one instance",
     86      drawFunction: ()=>gl.drawArraysInstanced(gl.POINTS, 0, 4, 1),
     87      result: [[2, 4, 6, 8], [2, 2, 2, 2]]},
     88    { name: "drawArraysInstanced four instances",
     89      drawFunction: ()=>gl.drawArraysInstanced(gl.POINTS, 0, 1, 4),
     90      result: [[2, 2, 2, 2], [2, 4, 6, 8]]},
     91  ];
     92 
     93 for (let {name, drawFunction, result} of cases) {
     94  debug("<h1>" + name + "</h1>")
     95 
     96  let interleavedResult = [];
     97  for (let i = 0; i < result[0].length; i++) {
     98    interleavedResult.push(result[0][i], result[1][i]);
     99  }
    100 
    101  let doTransformFeedback = (drawFunction, error) => {
    102    gl.beginTransformFeedback(gl.POINTS);
    103    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "before draw");
    104    drawFunction();
    105    wtu.glErrorShouldBe(gl, error, "draw");
    106    gl.endTransformFeedback();
    107  }
    108 
    109  gl.useProgram(progInterleaved);
    110 
    111  debug("<h3>interleaved - Baseline success case</h3>")
    112  gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
    113  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat, gl.STREAM_READ);
    114  doTransformFeedback(drawFunction, gl.NO_ERROR);
    115  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, interleavedResult);
    116 
    117  debug("<h3>interleaved - Buffer too small</h3>")
    118  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat-1, gl.STREAM_READ);
    119  doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
    120  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER,
    121      [0, 0, 0, 0, 0, 0, 0]);
    122 
    123  debug("<h3>interleaved - Multiple draws success case</h3>")
    124  gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
    125  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat*2, gl.STREAM_READ);
    126  doTransformFeedback(()=>{drawFunction(); drawFunction()}, gl.NO_ERROR);
    127  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, interleavedResult.concat(interleavedResult))
    128 
    129  debug("<h3>interleaved - Too small for multiple draws</h3>")
    130  gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
    131  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat*2-1, gl.STREAM_READ);
    132  doTransformFeedback(()=>{drawFunction(); drawFunction()}, gl.INVALID_OPERATION);
    133  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, interleavedResult.concat([0, 0, 0, 0, 0, 0, 0]))
    134 
    135  debug("<h3>interleaved - bindBufferRange too small</h3>")
    136  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat, gl.STREAM_READ);
    137  gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0, 0, 7*sizeOfFloat);
    138  doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
    139  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER,
    140      [0, 0, 0, 0, 0, 0, 0, 0]);
    141 
    142  debug("<h3>interleaved - bindBufferRange larger than buffer</h3>")
    143  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat-1, gl.STREAM_READ);
    144  gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0, 0, 8*sizeOfFloat);
    145  doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
    146  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER,
    147      [0, 0, 0, 0, 0, 0, 0]);
    148 
    149  gl.useProgram(progSeparate);
    150 
    151  debug("<h3>separate - Baseline success case</h3>")
    152  gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
    153  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
    154  gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1);
    155  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
    156  doTransformFeedback(drawFunction, gl.NO_ERROR);
    157  gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
    158  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[0]);
    159  gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
    160  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[1]);
    161 
    162  debug("<h3>separate - Buffer too small</h3>")
    163  gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
    164  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
    165  gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1);
    166  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat-1, gl.STREAM_READ);
    167  doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
    168  gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
    169  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0, 0]);
    170  gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
    171  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0]);
    172 
    173  debug("<h3>separate - multiple draws success case</h3>")
    174  gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
    175  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat*2, gl.STREAM_READ);
    176  gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1);
    177  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat*2, gl.STREAM_READ);
    178  doTransformFeedback(()=>{drawFunction(); drawFunction();}, gl.NO_ERROR);
    179  gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
    180  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[0].concat(result[0]));
    181  gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
    182  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[1].concat(result[1]));
    183 
    184  debug("<h3>separate - Too small for multiple draws</h3>")
    185  gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
    186  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat*2, gl.STREAM_READ);
    187  gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1);
    188  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat*2-1, gl.STREAM_READ);
    189  doTransformFeedback(()=>{drawFunction(); drawFunction();}, gl.INVALID_OPERATION);
    190  gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
    191  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[0].concat([0, 0, 0, 0]));
    192  gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
    193  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[1].concat([0, 0, 0]));
    194 
    195  debug("<h3>separate - bindBufferRange too small</h3>")
    196  gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
    197  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
    198  gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1, 0, 3*sizeOfFloat);
    199  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
    200  doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
    201  gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
    202  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0, 0]);
    203  gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
    204  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0]);
    205 
    206  debug("<h3>separate - bindBufferRange larger than buffer</h3>")
    207  gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
    208  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
    209  gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1, 0, 4*sizeOfFloat);
    210  gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat-1, gl.STREAM_READ);
    211  doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
    212  gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
    213  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0, 0]);
    214  gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
    215  wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0]);
    216 }
    217 
    218 debug("<h1>integer overflow</h1>")
    219 
    220 gl.useProgram(progInterleaved);
    221 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer0);
    222 gl.bufferData(gl.ARRAY_BUFFER, (1<<16)*sizeOfFloat, gl.STREAM_READ);
    223 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer1);
    224 gl.bufferData(gl.ARRAY_BUFFER, (1<<16)*sizeOfFloat, gl.STREAM_READ);
    225 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
    226 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, (1<<16)*sizeOfFloat*2, gl.STREAM_READ);
    227 
    228 gl.beginTransformFeedback(gl.POINTS);
    229 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "before draw");
    230 // If count and primcount are stored in 32-bit signed integers and then
    231 // multiplied to calculate the number of transform feedback vertices, the
    232 // calculation will overflow to 0.
    233 gl.drawArraysInstanced(gl.POINTS, 0, 1<<16, 1<<16);
    234 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "integer overflow and/or buffer too small");
    235 gl.endTransformFeedback();
    236 
    237 finishTest();
    238 
    239 </script>
    240 
    241 </body>
    242 </html>