tor-browser

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

instanced-arrays.html (12717B)


      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: 50px; height: 50px;"> </canvas>
     20 <div id="console"></div>
     21 <!-- Shaders for testing instanced draws -->
     22 <script id="outputVertexShader" type="x-shader/x-vertex">
     23 attribute vec4 aPosition;
     24 attribute vec2 aOffset;
     25 attribute vec4 aColor;
     26 varying vec4 vColor;
     27 void main() {
     28    vColor = aColor;
     29    gl_Position = aPosition + vec4(aOffset, 0.0, 0.0);
     30 }
     31 </script>
     32 
     33 <script id="outputFragmentShader" type="x-shader/x-fragment">
     34 precision mediump float;
     35 varying vec4 vColor;
     36 void main() {
     37    gl_FragColor = vColor;
     38 }
     39 </script>
     40 
     41 <script>
     42 "use strict";
     43 description("This test verifies the functionality of Instanced Arrays.");
     44 
     45 debug("");
     46 
     47 var wtu = WebGLTestUtils;
     48 var canvas = document.getElementById("canvas");
     49 var gl = wtu.create3DContext(canvas, null, 2);
     50 
     51 if (!gl) {
     52    testFailed("WebGL context does not exist");
     53 } else {
     54    testPassed("WebGL context exists");
     55 
     56    runDivisorTest();
     57    runOutputTests();
     58    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
     59 }
     60 
     61 function runDivisorTest() {
     62    debug("Testing VERTEX_ATTRIB_ARRAY_DIVISOR");
     63 
     64    shouldBe("gl.VERTEX_ATTRIB_ARRAY_DIVISOR", "0x88FE");
     65 
     66    var max_vertex_attribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
     67 
     68    for (var i = 0; i < max_vertex_attribs; ++i) {
     69        var queried_value = gl.getVertexAttrib(i, gl.VERTEX_ATTRIB_ARRAY_DIVISOR);
     70        if(queried_value == 0){
     71            testPassed("Vertex attribute " + i + " must has a default divisor of 0");
     72        }
     73        else{
     74            testFailed("Default divisor of vertex attribute " + i + " should be: 0, returned value was: " + queried_value);
     75        }
     76    }
     77 
     78    gl.vertexAttribDivisor(max_vertex_attribs, 2);
     79    wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "vertexAttribDivisor index set greater than or equal to MAX_VERTEX_ATTRIBS should be an invalid value");
     80 
     81    gl.vertexAttribDivisor(max_vertex_attribs-1, 2);
     82    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "vertexAttribDivisor index set less than MAX_VERTEX_ATTRIBS should succeed");
     83 
     84    var queried_value = gl.getVertexAttrib(max_vertex_attribs-1, gl.VERTEX_ATTRIB_ARRAY_DIVISOR);
     85    if(queried_value == 2){
     86        testPassed("Set value of VERTEX_ATTRIB_ARRAY_DIVISOR matches expecation");
     87    }
     88    else{
     89        testFailed("Set value of VERTEX_ATTRIB_ARRAY_DIVISOR should be: 2, returned value was: " + queried_value);
     90    }
     91 }
     92 
     93 function runOutputTests() {
     94    var e = 2; // Amount of variance to allow in result pixels - may need to be tweaked higher
     95    var instanceCount = 4;
     96 
     97    debug("Testing various draws for valid built-in function behavior");
     98 
     99    canvas.width = 50; canvas.height = 50;
    100    gl.viewport(0, 0, canvas.width, canvas.height);
    101    gl.clearColor(0, 0, 0, 0);
    102 
    103    var positionLoc = 0;
    104    var offsetLoc = 2;
    105    var colorLoc = 3;
    106    var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"], ['aPosition', 'aOffset', 'aColor'], [positionLoc, offsetLoc, colorLoc]);
    107 
    108    var offsets = new Float32Array([
    109        -1.0,  1.0,
    110         1.0,  1.0,
    111        -1.0, -1.0,
    112         1.0, -1.0,
    113    ]);
    114    var offsetBuffer = gl.createBuffer();
    115    gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
    116    gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW);
    117    gl.enableVertexAttribArray(offsetLoc);
    118    gl.vertexAttribPointer(offsetLoc, 2, gl.FLOAT, false, 0, 0);
    119    gl.vertexAttribDivisor(offsetLoc, 1);
    120 
    121    var colors = new Float32Array([
    122        1.0, 0.0, 0.0, 1.0, // Red
    123        0.0, 1.0, 0.0, 1.0, // Green
    124        0.0, 0.0, 1.0, 1.0, // Blue
    125        1.0, 1.0, 0.0, 1.0, // Yellow
    126        // extra data when colorLoc divisor is set back to 0
    127        1.0, 1.0, 0.0, 1.0, // Yellow
    128        1.0, 1.0, 0.0, 1.0, // Yellow
    129    ]);
    130    var colorBuffer = gl.createBuffer();
    131    gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    132    gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
    133    gl.enableVertexAttribArray(colorLoc);
    134    gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0);
    135    gl.vertexAttribDivisor(colorLoc, 1);
    136 
    137    // Draw 1: Draw Non-indexed instances
    138    debug("Testing drawArraysInstanced");
    139    gl.clear(gl.COLOR_BUFFER_BIT);
    140    wtu.setupUnitQuad(gl, 0);
    141 
    142    // Test drawArraysInstanced error conditions
    143    gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
    144    wtu.checkCanvasRect(gl, 0, canvas.height/2, canvas.width/2, canvas.height/2, [255, 0, 0, 255]);
    145    wtu.checkCanvasRect(gl, canvas.width/2, canvas.height/2, canvas.width/2, canvas.height/2, [0, 255, 0, 255]);
    146    wtu.checkCanvasRect(gl, 0, 0, canvas.width/2, canvas.height/2, [0, 0, 255, 255]);
    147    wtu.checkCanvasRect(gl, canvas.width/2, 0, canvas.width/2, canvas.height/2, [255, 255, 0, 255]);
    148 
    149    gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, -1);
    150    wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "drawArraysInstanced cannot have a primcount less than 0");
    151 
    152    gl.drawArraysInstanced(gl.TRIANGLES, 0, -1, instanceCount);
    153    wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "drawArraysInstanced cannot have a count less than 0");
    154 
    155    gl.vertexAttribDivisor(positionLoc, 1);
    156    gl.clear(gl.COLOR_BUFFER_BIT);
    157    gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
    158    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "It's allowed for all vertex attributes to have non-zero divisors when calling drawArraysInstanced");
    159    gl.drawArrays(gl.TRIANGLES, 0, 6);
    160    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "It's allowed for all vertex attributes to have non-zero divisors when calling drawArrays");
    161    wtu.checkCanvas(gl, [0, 0, 0, 0], "Nothing should be drawn on the framebuffer when all attributes have non-zero divisors (not enough vertices per instance to form a triangle)");
    162    gl.vertexAttribDivisor(positionLoc, 0);
    163 
    164    gl.drawArraysInstanced(gl.POINTS, 0, 6, instanceCount);
    165    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstanced with POINTS should succeed");
    166    gl.drawArraysInstanced(gl.LINES, 0, 6, instanceCount);
    167    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstanced with LINES should succeed");
    168    gl.drawArraysInstanced(gl.LINE_LIST, 0, 6, instanceCount);
    169    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstanced with LINE_LIST should return succeed");
    170    gl.drawArraysInstanced(gl.TRI_LIST, 0, 6, instanceCount);
    171    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstanced with TRI_LIST should succeed");
    172 
    173    gl.drawArraysInstanced(desktopGL['QUAD_STRIP'], 0, 6, instanceCount);
    174    wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawArraysInstanced with QUAD_STRIP should return INVALID_ENUM");
    175    gl.drawArraysInstanced(desktopGL['QUADS'], 0, 6, instanceCount);
    176    wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawArraysInstanced with QUADS should return INVALID_ENUM");
    177    gl.drawArraysInstanced(desktopGL['POLYGON'], 0, 6, instanceCount);
    178    wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawArraysInstanced with POLYGON should return INVALID_ENUM");
    179 
    180    debug("Testing drawArraysInstanced with param 'first' > 0");
    181    gl.clear(gl.COLOR_BUFFER_BIT);
    182    wtu.setupQuad(gl, {
    183        positionLocation: 0,
    184        scale: 0.5
    185    });
    186    var offsetsHalf = new Float32Array([
    187        -0.5,  0.5,
    188         0.5,  0.5,
    189        -0.5, -0.5,
    190         0.5, -0.5
    191    ]);
    192    gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
    193    gl.bufferData(gl.ARRAY_BUFFER, offsetsHalf, gl.STATIC_DRAW);
    194 
    195    gl.drawArraysInstanced(gl.TRIANGLES, 3, 3, instanceCount);
    196    var w = Math.floor(0.25*canvas.width),
    197        h = Math.floor(0.25*canvas.height);
    198    wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0.5*canvas.height, w, h, [255, 0, 0, 255]);
    199    wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0.5*canvas.height, w, h, [0, 255, 0, 255]);
    200    wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0, w, h, [0, 0, 255, 255]);
    201    wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0, w, h, [255, 255, 0, 255]);
    202 
    203    debug("Testing drawArraysInstanced with attributes 'divisor' reset to 0");
    204    debug("Correct rendering output: 4 yellow triangles");
    205    debug("Possible incorrect rendering output: missing triangles, or triangles with different color at each vertex");
    206    gl.vertexAttribDivisor(colorLoc, 0);
    207    gl.clear(gl.COLOR_BUFFER_BIT);
    208    gl.drawArraysInstanced(gl.TRIANGLES, 3, 3, instanceCount);
    209    wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0.5*canvas.height, w, h, [255, 255, 0, 255]);
    210    wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0.5*canvas.height, w, h, [255, 255, 0, 255]);
    211    wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0, w, h, [255, 255, 0, 255]);
    212    wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0, w, h, [255, 255, 0, 255]);
    213    gl.vertexAttribDivisor(colorLoc, 1);
    214 
    215    wtu.setupUnitQuad(gl, 0);
    216    gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
    217    gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW);
    218 
    219    // Draw 2: Draw indexed instances
    220    debug("Testing drawElementsInstanced");
    221    gl.clear(gl.COLOR_BUFFER_BIT);
    222    wtu.setupIndexedQuad(gl, 1, 0);
    223    gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
    224    wtu.checkCanvasRect(gl, 0, canvas.height/2, canvas.width/2, canvas.height/2, [255, 0, 0, 255]);
    225    wtu.checkCanvasRect(gl, canvas.width/2, canvas.height/2, canvas.width/2, canvas.height/2, [0, 255, 0, 255]);
    226    wtu.checkCanvasRect(gl, 0, 0, canvas.width/2, canvas.height/2, [0, 0, 255, 255]);
    227    wtu.checkCanvasRect(gl, canvas.width/2, 0, canvas.width/2, canvas.height/2, [255, 255, 0, 255]);
    228 
    229    // Test drawElementsInstanced error conditions
    230    gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, -1);
    231    wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "drawElementsInstanced cannot have a primcount less than 0");
    232 
    233    gl.drawElementsInstanced(gl.TRIANGLES, -1, gl.UNSIGNED_SHORT, 0, instanceCount);
    234    wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "drawElementsInstanced cannot have a count less than 0");
    235 
    236    gl.vertexAttribDivisor(positionLoc, 1);
    237    gl.clear(gl.COLOR_BUFFER_BIT);
    238    gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
    239    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "It's allowed for all vertex attributes to have non-zero divisors when calling drawElementsInstanced");
    240    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
    241    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "It's allowed for all vertex attributes to have non-zero divisors when calling drawElements");
    242    wtu.checkCanvas(gl, [0, 0, 0, 0], "Nothing should be drawn on the framebuffer when all attributes have non-zero divisors (not enough vertices per instance to form a triangle)");
    243    gl.vertexAttribDivisor(positionLoc, 0);
    244 
    245    gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0, instanceCount);
    246    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstanced with UNSIGNED_BYTE should succeed");
    247 
    248    gl.drawElementsInstanced(gl.POINTS, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
    249    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstanced with POINTS should succeed");
    250    gl.drawElementsInstanced(gl.LINES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
    251    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstanced with LINES should succeed");
    252    gl.drawElementsInstanced(gl.LINE_LIST, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
    253    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstanced with LINE_LIST should return succeed");
    254    gl.drawElementsInstanced(gl.TRI_LIST, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
    255    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstanced with TRI_LIST should succeed");
    256 
    257    gl.drawElementsInstanced(desktopGL['QUAD_STRIP'], 6, gl.UNSIGNED_SHORT, 0, instanceCount);
    258    wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawElementsInstanced with QUAD_STRIP should return INVALID_ENUM");
    259    gl.drawElementsInstanced(desktopGL['QUADS'], 6, gl.UNSIGNED_SHORT, 0, instanceCount);
    260    wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawElementsInstanced with QUADS should return INVALID_ENUM");
    261    gl.drawElementsInstanced(desktopGL['POLYGON'], 6, gl.UNSIGNED_SHORT, 0, instanceCount);
    262    wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawElementsInstanced with POLYGON should return INVALID_ENUM");
    263 }
    264 
    265 debug("");
    266 var successfullyParsed = true;
    267 </script>
    268 <script src="../../js/js-test-post.js"></script>
    269 
    270 </body>
    271 </html>