tor-browser

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

multisampling-depth-resolve.html (6066B)


      1 <!--
      2 Copyright (c) 2022 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 framebuffer to texture conformance test.</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 <canvas id="canvas"></canvas>
     18 <div id="description"></div>
     19 <div id="console"></div>
     20 <script>
     21 "use strict";
     22 description("Test resolving multisample depth buffer");
     23 debug('Reduced test case for <a href="https://bugs.webkit.org/show_bug.cgi?id=238118">https://bugs.webkit.org/show_bug.cgi?id=238118</a>');
     24 
     25 // Reproduces an inconistent behavior where if:
     26 // 1) You render into a multisampling frame buffer
     27 // 2) Geometry is drawn with DEPTH_TEST disabled and then enabled
     28 // 3) More than one frame is rendered via requestAnimationFrame
     29 
     30 const size = 64;
     31 const halfSize = size / 2;
     32 
     33 let wtu = WebGLTestUtils;
     34 let canvas = document.getElementById("canvas");
     35 canvas.width = size;
     36 canvas.height = size;
     37 
     38 let gl = wtu.create3DContext("canvas", {}, 2);
     39 
     40 function createTexture(res, format, bytes) {
     41    let texture = gl.createTexture();
     42    gl.bindTexture(gl.TEXTURE_2D, texture);
     43    gl.texStorage2D(gl.TEXTURE_2D, 1, format, res, res);
     44    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
     45    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
     46    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
     47    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
     48    gl.bindTexture(gl.TEXTURE_2D, null);
     49    return texture;
     50 }
     51 
     52 function createRenderBuffer(res, format, samples) {
     53    let rb = gl.createRenderbuffer();
     54    gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
     55    if (samples > 1)
     56        gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples, format, res, res);
     57    else
     58        gl.renderbufferStorage(gl.RENDERBUFFER, format, res, res);
     59    return rb;
     60 }
     61 
     62 let yellowQuadVAO = gl.createVertexArray();
     63 gl.bindVertexArray(yellowQuadVAO);
     64 let yellowQuadProgram = wtu.setupColorQuad(gl, 0, { scale: 0.75 });
     65 
     66 let blueQuadVAO = gl.createVertexArray();
     67 gl.bindVertexArray(blueQuadVAO);
     68 let blueQuadProgram = wtu.setupColorQuad(gl, 0, { scale: 0.5 });
     69 
     70 let fsVAO = gl.createVertexArray();
     71 gl.bindVertexArray(fsVAO);
     72 let fsProgram = wtu.setupTexturedQuad(gl, 0, 1);
     73 gl.useProgram(fsProgram);
     74 let fsTexLoc = gl.getUniformLocation(fsProgram, "tex");
     75 gl.uniform1i(fsTexLoc, 0);
     76 
     77 // An incorrect render can occur if...
     78 
     79 // 1) You use renderbufferStorageMultisample.
     80 const msaaSamples = 4;
     81 const colorRB = createRenderBuffer(size, gl.RGBA8, msaaSamples);
     82 const depthRB = createRenderBuffer(size, gl.DEPTH_COMPONENT16, msaaSamples);
     83 const resolveTex = createTexture(size, gl.RGBA8);
     84 
     85 let renderFBO = gl.createFramebuffer();
     86 gl.bindFramebuffer(gl.FRAMEBUFFER, renderFBO);
     87 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRB);
     88 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthRB);
     89 
     90 let resolveFBO = gl.createFramebuffer();
     91 gl.bindFramebuffer(gl.FRAMEBUFFER, resolveFBO);
     92 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, resolveTex, 0);
     93 gl.bindFramebuffer(gl.FRAMEBUFFER, null);
     94 
     95 gl.disable(gl.CULL_FACE);
     96 gl.disable(gl.BLEND);
     97 
     98 var frameCount = 0;
     99 function runTest() {
    100    // 2) Render from requestAnimationFrame, only starting with the 2nd frame.
    101    gl.bindFramebuffer(gl.FRAMEBUFFER, renderFBO);
    102 
    103    // Clear background red
    104    gl.clearColor(1, 0, 0, 1);
    105    gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);
    106 
    107    // 3) You disable gl.DEPTH_TEST
    108    gl.disable(gl.DEPTH_TEST);
    109    gl.depthMask(false);
    110 
    111    gl.bindVertexArray(yellowQuadVAO);
    112    gl.useProgram(yellowQuadProgram);
    113    wtu.drawUByteColorQuad(gl, [ 255, 255, 0, 255 ]);
    114 
    115    // 4) And re-enable gl.DEPTH_TEST
    116    gl.enable(gl.DEPTH_TEST);
    117    gl.depthMask(true);
    118 
    119    gl.bindVertexArray(blueQuadVAO);
    120    gl.useProgram(blueQuadProgram);
    121    wtu.drawUByteColorQuad(gl, [ 0, 0, 255, 255 ]);
    122 
    123    // Resolve the multisample framebuffer to a texture
    124    gl.bindFramebuffer(gl.READ_FRAMEBUFFER, renderFBO);
    125    gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, resolveFBO);
    126    gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 0.0, 0.0]);
    127    gl.blitFramebuffer(0, 0, size, size,
    128        0, 0, size, size,
    129        gl.COLOR_BUFFER_BIT, gl.LINEAR);
    130    gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
    131    gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
    132 
    133    // Draw the resolved texture to the backbuffer
    134    gl.bindTexture(gl.TEXTURE_2D, resolveTex);
    135    gl.useProgram(fsProgram);
    136    gl.bindVertexArray(fsVAO);
    137    wtu.drawUnitQuad(gl);
    138 
    139    // 5) The incorrect render can occur on the second rendered frame, called from
    140    // requestAnimationFrame.
    141    frameCount++;
    142    if (frameCount == 2) {
    143        checkRenderingResults("multisampling-depth-resolve");
    144        wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors at the end of the test.");
    145        finishTest();
    146    } else {
    147        requestAnimationFrame(runTest);
    148    }
    149 }
    150 
    151 requestAnimationFrame(runTest);
    152 
    153 function checkRenderingResults(prefix) {
    154    // Outer color should be red
    155    wtu.checkCanvasRect(gl,
    156                        1, 1,
    157                        2, 2,
    158                        [255, 0, 0, 255],
    159                        prefix + ": outer pixels should be red");
    160 
    161    // Outer quad should be rendered yellow.
    162    wtu.checkCanvasRect(gl,
    163                        10, 10,
    164                        2, 2,
    165                        [255, 255, 0, 255],
    166                        prefix + ": outer quad should be yellow");
    167 
    168    // Center quad should be rendered blue.
    169    wtu.checkCanvasRect(gl,
    170                        halfSize / 2 + 1, halfSize / 2 + 1,
    171                        2, 2,
    172                        [0, 0, 255, 255],
    173                        prefix + ": center quad should be blue");
    174 }
    175 
    176 var successfullyParsed = true;
    177 </script>
    178 </body>
    179 </html>