tor-browser

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

instanced-rendering-bug.html (9067B)


      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>WebGL Instanced Arrays Conformance Tests</title>
     12 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
     13 <script src="../../js/desktop-gl-constants.js"></script>
     14 <script src="../../js/js-test-pre.js"></script>
     15 <script src="../../js/webgl-test-utils.js"></script>
     16 </head>
     17 <body>
     18 <div id="description"></div>
     19 <canvas id="canvas" style="width: 128px; height: 128px;"> </canvas>
     20 <div id="console"></div>
     21 <script id="outputVertexShader" type="x-shader/x-vertex">#version 300 es
     22 in highp vec2 aPosition;
     23 in highp float aOffset;
     24 in highp float aColor;
     25 out mediump float vColor;
     26 void main() {
     27    gl_Position = vec4(aPosition, 0.0, 1.0) + vec4(aOffset, 0.0, 0.0, 0.0);
     28    vColor = aColor;
     29 }
     30 </script>
     31 
     32 <script id="outputFragmentShader" type="x-shader/x-fragment">#version 300 es
     33 layout(location = 0) out mediump vec4 oColor;
     34 in mediump float vColor;
     35 void main() {
     36    oColor = vec4(vColor, 0.0, 0.0, 1.0);
     37 }
     38 </script>
     39 
     40 <script>
     41 "use strict";
     42 description("This test verifies a bug related with instanced rendering on Mac AMD.");
     43 debug("http://crbug.com/645298");
     44 
     45 debug("");
     46 
     47 var wtu = WebGLTestUtils;
     48 var canvas = document.getElementById("canvas");
     49 var gl = wtu.create3DContext(canvas, null, 2);
     50 
     51 // The second and fourth test cases fail - it seems if the divisor doesn't change,
     52 // the next instanced draw call behaves incorrectly.
     53 // Also note that if we don't perform a readPixels (in wtu.checkCanvasRect), the bug
     54 // isn't triggered.
     55 var testCases = [
     56    { instanceCount: 8, divisor: 4 },
     57    { instanceCount: 6, divisor: 4 },
     58    { instanceCount: 6, divisor: 3 },
     59    { instanceCount: 8, divisor: 3 },
     60 ];
     61 
     62 if (!gl) {
     63    testFailed("WebGL context does not exist");
     64 } else {
     65    testPassed("WebGL context exists");
     66 
     67    for (var ii = 0; ii < testCases.length; ++ii) {
     68        runDrawArraysTest(testCases[ii].instanceCount, testCases[ii].divisor);
     69    }
     70 
     71    for (var ii = 0; ii < testCases.length; ++ii) {
     72        runDrawElementsTest(testCases[ii].instanceCount, testCases[ii].divisor);
     73    }
     74 }
     75 
     76 function runDrawArraysTest(instanceCount, divisor) {
     77    debug("");
     78    debug("Testing drawArraysInstanced: instanceCount = " + instanceCount + ", divisor = " + divisor);
     79 
     80    gl.viewport(0, 0, canvas.width, canvas.height);
     81 
     82    var vao = gl.createVertexArray();
     83    gl.bindVertexArray(vao);
     84 
     85    var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"]);
     86    var positionLoc = gl.getAttribLocation(program, "aPosition");
     87    var offsetLoc = gl.getAttribLocation(program, "aOffset");
     88    var colorLoc = gl.getAttribLocation(program, "aColor");
     89    if (!program || positionLoc < 0 || offsetLoc < 0 || colorLoc < 0) {
     90        testFailed("Set up program failed");
     91        return;
     92    }
     93    testPassed("Set up program succeeded");
     94 
     95    var scale = 1.0 / instanceCount;
     96 
     97    gl.enableVertexAttribArray(positionLoc);
     98    gl.vertexAttribDivisor(positionLoc, 0);
     99    var positions = new Float32Array([
    100         1.0 * scale,  1.0,
    101        -1.0 * scale,  1.0,
    102        -1.0 * scale, -1.0,
    103         1.0 * scale,  1.0,
    104        -1.0 * scale, -1.0,
    105         1.0 * scale, -1.0,
    106    ]);
    107    var positionBuffer = gl.createBuffer();
    108    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    109    gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
    110    gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);
    111 
    112    gl.enableVertexAttribArray(offsetLoc);
    113    gl.vertexAttribDivisor(offsetLoc, 1);
    114    var offsets = new Float32Array(instanceCount);
    115    for (var ii = 0; ii < instanceCount; ++ii) {
    116        offsets[ii] = scale * (1 - instanceCount + ii * 2);
    117    }
    118    var offsetBuffer = gl.createBuffer();
    119    gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
    120    gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW);
    121    gl.vertexAttribPointer(offsetLoc, 1, gl.FLOAT, false, 0, 0);
    122 
    123    gl.enableVertexAttribArray(colorLoc);
    124    gl.vertexAttribDivisor(colorLoc, divisor);
    125    var colorCount = instanceCount / divisor;
    126    if ((instanceCount % divisor) != 0)
    127        colorCount++;
    128    var colors = new Float32Array(colorCount);
    129    for (var ii = 0; ii < colorCount; ++ii) {
    130        colors[ii] = 1.0 / colorCount * (ii + 1);
    131    }
    132    var colorBuffer = gl.createBuffer();
    133    gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    134    gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
    135    gl.vertexAttribPointer(colorLoc, 1, gl.FLOAT, false, 0, 0);
    136 
    137    gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
    138    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstanced should succeed");
    139 
    140    var colorIndex = -1;
    141    for (var ii = 0; ii < instanceCount; ++ii) {
    142        if ((ii % divisor) == 0)
    143            colorIndex++;
    144        var refColor = [ Math.floor(colors[colorIndex] * 255), 0, 0, 255 ];
    145        wtu.checkCanvasRect(gl, Math.floor(canvas.width / instanceCount * ii) + 1, 0, 1, canvas.height, refColor,
    146            "instance " + ii + " should be " + refColor, 2);
    147    }
    148 
    149    gl.deleteBuffer(positionBuffer);
    150    gl.deleteBuffer(offsetBuffer);
    151    gl.deleteBuffer(colorBuffer);
    152    gl.deleteProgram(program);
    153    gl.deleteVertexArray(vao);
    154    gl.bindBuffer(gl.ARRAY_BUFFER, null);
    155    gl.useProgram(null);
    156    gl.bindVertexArray(null);
    157    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clean up should succeed");
    158 }
    159 
    160 function runDrawElementsTest(instanceCount, divisor) {
    161    debug("");
    162    debug("Testing drawElementsInstanced: instanceCount = " + instanceCount + ", divisor = " + divisor);
    163 
    164    gl.viewport(0, 0, canvas.width, canvas.height);
    165 
    166    var vao = gl.createVertexArray();
    167    gl.bindVertexArray(vao);
    168 
    169    var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"]);
    170    var positionLoc = gl.getAttribLocation(program, "aPosition");
    171    var offsetLoc = gl.getAttribLocation(program, "aOffset");
    172    var colorLoc = gl.getAttribLocation(program, "aColor");
    173    if (!program || positionLoc < 0 || offsetLoc < 0 || colorLoc < 0) {
    174        testFailed("Set up program failed");
    175        return;
    176    }
    177    testPassed("Set up program succeeded");
    178 
    179    var scale = 1.0 / instanceCount;
    180 
    181    gl.enableVertexAttribArray(positionLoc);
    182    gl.vertexAttribDivisor(positionLoc, 0);
    183    var positions = new Float32Array([
    184         1.0 * scale,  1.0,
    185        -1.0 * scale,  1.0,
    186        -1.0 * scale, -1.0,
    187         1.0 * scale, -1.0,
    188    ]);
    189    var positionBuffer = gl.createBuffer();
    190    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    191    gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
    192    gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);
    193 
    194    gl.enableVertexAttribArray(offsetLoc);
    195    gl.vertexAttribDivisor(offsetLoc, 1);
    196    var offsets = new Float32Array(instanceCount);
    197    for (var ii = 0; ii < instanceCount; ++ii) {
    198        offsets[ii] = scale * (1 - instanceCount + ii * 2);
    199    }
    200    var offsetBuffer = gl.createBuffer();
    201    gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
    202    gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW);
    203    gl.vertexAttribPointer(offsetLoc, 1, gl.FLOAT, false, 0, 0);
    204 
    205    gl.enableVertexAttribArray(colorLoc);
    206    gl.vertexAttribDivisor(colorLoc, divisor);
    207    var colorCount = instanceCount / divisor;
    208    if ((instanceCount % divisor) != 0)
    209        colorCount++;
    210    var colors = new Float32Array(colorCount);
    211    for (var ii = 0; ii < colorCount; ++ii) {
    212        colors[ii] = 1.0 / colorCount * (ii + 1);
    213    }
    214    var colorBuffer = gl.createBuffer();
    215    gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    216    gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
    217    gl.vertexAttribPointer(colorLoc, 1, gl.FLOAT, false, 0, 0);
    218 
    219    var indexBuffer = gl.createBuffer();
    220    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
    221    var indices = new Uint16Array([0, 1, 2, 0, 2, 3]);
    222    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
    223 
    224    gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
    225    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstanced should succeed");
    226 
    227    var colorIndex = -1;
    228    for (var ii = 0; ii < instanceCount; ++ii) {
    229        if ((ii % divisor) == 0)
    230            colorIndex++;
    231        var refColor = [ Math.floor(colors[colorIndex] * 255), 0, 0, 255 ];
    232        wtu.checkCanvasRect(gl, Math.floor(canvas.width / instanceCount * ii) + 1, 0, 1, canvas.height, refColor,
    233            "instance " + ii + " should be " + refColor, 2);
    234    }
    235 
    236    gl.deleteBuffer(positionBuffer);
    237    gl.deleteBuffer(offsetBuffer);
    238    gl.deleteBuffer(colorBuffer);
    239    gl.deleteBuffer(indexBuffer);
    240    gl.deleteProgram(program);
    241    gl.deleteVertexArray(vao);
    242    gl.bindBuffer(gl.ARRAY_BUFFER, null);
    243    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
    244    gl.useProgram(null);
    245    gl.bindVertexArray(null);
    246    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clean up should succeed");
    247 }
    248 
    249 debug("");
    250 var successfullyParsed = true;
    251 </script>
    252 <script src="../../js/js-test-post.js"></script>
    253 </body>
    254 </html>