tor-browser

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

webgl-stencil-texturing.html (13101B)


      1 <!--
      2 Copyright (c) 2023 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 WEBGL_stencil_texturing Conformance Tests</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 <div id="console"></div>
     19 <script>
     20 "use strict";
     21 description("This test verifies the functionality of the WEBGL_stencil_texturing extension, if it is available.");
     22 
     23 debug("");
     24 
     25 var wtu = WebGLTestUtils;
     26 var gl = wtu.create3DContext(null, null, 2);
     27 var ext;
     28 
     29 function runTestNoExtension() {
     30    debug("");
     31    debug("Check the texture parameter without the extension");
     32 
     33    const tex = gl.createTexture();
     34    gl.bindTexture(gl.TEXTURE_2D, tex);
     35 
     36    shouldBeNull("gl.getTexParameter(gl.TEXTURE_2D, 0x90EA /* DEPTH_STENCIL_TEXTURE_MODE_WEBGL */)");
     37    wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown without enabling the extension");
     38    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
     39 
     40    gl.texParameteri(gl.TEXTURE_2D, 0x90EA /* DEPTH_STENCIL_TEXTURE_MODE_WEBGL */, gl.DEPTH_COMPONENT);
     41    wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown for texParameteri without enabling the extension");
     42    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
     43 
     44    gl.texParameterf(gl.TEXTURE_2D, 0x90EA /* DEPTH_STENCIL_TEXTURE_MODE_WEBGL */, gl.DEPTH_COMPONENT);
     45    wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown for texParameterf without enabling the extension");
     46    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
     47 
     48    const sampler = gl.createSampler();
     49    gl.samplerParameteri(sampler, 0x90EA /* DEPTH_STENCIL_TEXTURE_MODE_WEBGL */, gl.DEPTH_COMPONENT);
     50    wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown for samplerParameteri");
     51    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
     52    gl.samplerParameterf(sampler, 0x90EA /* DEPTH_STENCIL_TEXTURE_MODE_WEBGL */, gl.DEPTH_COMPONENT);
     53    wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown for samplerParameterf");
     54    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
     55 }
     56 
     57 function checkEnums() {
     58    debug("");
     59    debug("Check enums");
     60    shouldBe("ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL", "0x90EA");
     61    shouldBe("ext.STENCIL_INDEX_WEBGL",              "0x1901");
     62 }
     63 
     64 function checkQueries() {
     65    const tex = gl.createTexture();
     66    gl.bindTexture(gl.TEXTURE_2D, tex);
     67 
     68    debug("");
     69    debug("Check default texture state");
     70    shouldBe('gl.getTexParameter(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL)', 'gl.DEPTH_COMPONENT');
     71    debug("");
     72    debug("Check texture state updates using texParameteri");
     73    gl.texParameteri(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, ext.STENCIL_INDEX_WEBGL);
     74    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
     75    shouldBe('gl.getTexParameter(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL)', 'ext.STENCIL_INDEX_WEBGL');
     76    gl.texParameteri(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, gl.DEPTH_COMPONENT);
     77    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
     78    shouldBe('gl.getTexParameter(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL)', 'gl.DEPTH_COMPONENT');
     79    gl.texParameteri(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, 0);
     80    wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "invalid depth stencil mode value rejected by texParameteri");
     81    shouldBe('gl.getTexParameter(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL)', 'gl.DEPTH_COMPONENT');
     82    debug("");
     83    debug("Check texture state updates using texParameterf");
     84    gl.texParameterf(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, ext.STENCIL_INDEX_WEBGL);
     85    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
     86    shouldBe('gl.getTexParameter(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL)', 'ext.STENCIL_INDEX_WEBGL');
     87    gl.texParameterf(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, gl.DEPTH_COMPONENT);
     88    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
     89    shouldBe('gl.getTexParameter(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL)', 'gl.DEPTH_COMPONENT');
     90    gl.texParameterf(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, 0);
     91    wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "invalid depth stencil mode value rejected by texParameterf");
     92    shouldBe('gl.getTexParameter(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL)', 'gl.DEPTH_COMPONENT');
     93 
     94    debug("");
     95    debug("Check that depth stencil texture mode is not accepted as a sampler state");
     96    const sampler = gl.createSampler();
     97    gl.samplerParameteri(sampler, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, gl.DEPTH_COMPONENT);
     98    wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown for samplerParameteri");
     99    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
    100    gl.samplerParameterf(sampler, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, gl.DEPTH_COMPONENT);
    101    wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown for samplerParameterf");
    102    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
    103 }
    104 
    105 function checkSampling() {
    106    const formats = [
    107        {name: "DEPTH_COMPONENT16", internalFormat: gl.DEPTH_COMPONENT16,
    108         format: gl.DEPTH_COMPONENT, type: gl.UNSIGNED_SHORT},
    109        {name: "DEPTH_COMPONENT24", internalFormat: gl.DEPTH_COMPONENT24,
    110         format: gl.DEPTH_COMPONENT, type: gl.UNSIGNED_INT},
    111        {name: "DEPTH_COMPONENT32F", internalFormat: gl.DEPTH_COMPONENT32F,
    112         format: gl.DEPTH_COMPONENT, type: gl.FLOAT},
    113        {name: "DEPTH24_STENCIL8", internalFormat: gl.DEPTH24_STENCIL8,
    114         format: gl.DEPTH_STENCIL, type: gl.UNSIGNED_INT_24_8},
    115        {name: "DEPTH32F_STENCIL8", internalFormat: gl.DEPTH32F_STENCIL8,
    116         format: gl.DEPTH_STENCIL, type: gl.FLOAT_32_UNSIGNED_INT_24_8_REV}
    117    ];
    118 
    119    gl.enable(gl.DEPTH_TEST);
    120    gl.enable(gl.STENCIL_TEST);
    121    gl.stencilFunc(gl.ALWAYS, 170, 0xFF);
    122    gl.stencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE);
    123 
    124    wtu.setupUnitQuad(gl);
    125 
    126    const drawProgram = wtu.setupProgram(gl, [wtu.simpleVertexShader,
    127                                              wtu.simpleColorFragmentShader]);
    128 
    129    const readDepthProgram = wtu.setupProgram(gl, [wtu.simpleTextureVertexShaderESSL300,
    130                                                   wtu.simpleTextureFragmentShaderESSL300]);
    131 
    132    const readStencilShader = `#version 300 es
    133        precision highp float;
    134        uniform highp usampler2D tex;
    135        in vec2 texCoord;
    136        out vec4 out_color;
    137        void main() {
    138            out_color = vec4(texture(tex, texCoord)) / 255.0;
    139        }`;
    140    const readStencilProgram = wtu.setupProgram(gl, [wtu.simpleTextureVertexShaderESSL300,
    141                                                     readStencilShader]);
    142 
    143    for (const format of formats) {
    144        debug("");
    145        debug(`Testing depth stencil texture modes with ${format.name}`);
    146        const fbo = gl.createFramebuffer();
    147        gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    148 
    149        const rbo = gl.createRenderbuffer();
    150        gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
    151        gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 1, 1);
    152        gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo);
    153 
    154        const tex = gl.createTexture();
    155        gl.bindTexture(gl.TEXTURE_2D, tex);
    156        gl.texImage2D(gl.TEXTURE_2D, 0, format.internalFormat, 1, 1, 0, format.format, format.type, null);
    157        wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture created");
    158 
    159        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, tex, 0);
    160        if (format.format == gl.DEPTH_STENCIL) {
    161            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.TEXTURE_2D, tex, 0);
    162        }
    163        wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE);
    164 
    165        gl.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
    166        gl.useProgram(drawProgram);
    167        wtu.drawUnitQuad(gl);
    168        wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors after drawing to the depth or depth stencil texture");
    169 
    170        // Detach the depth or depth stencil texture to avoid feedback loop
    171        gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, null);
    172        wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE);
    173 
    174        const magFilters = ['NEAREST', 'LINEAR'];
    175 
    176        const minFilters = [
    177            'NEAREST',
    178            'LINEAR',
    179            'NEAREST_MIPMAP_NEAREST',
    180            'LINEAR_MIPMAP_NEAREST',
    181            'NEAREST_MIPMAP_LINEAR',
    182            'LINEAR_MIPMAP_LINEAR'
    183        ];
    184 
    185        const modes = [
    186            [gl.DEPTH_COMPONENT, 'DEPTH_COMPONENT'],
    187            [ext.STENCIL_INDEX_WEBGL, 'STENCIL_INDEX_WEBGL']
    188        ];
    189 
    190        const programs = [
    191            [readDepthProgram, 'depth'],
    192            [readStencilProgram, 'stencil']
    193        ];
    194 
    195        function validFilters(magFilter, minFilter) {
    196            return magFilter == gl.NEAREST &&
    197                   (minFilter == gl.NEAREST || minFilter == gl.NEAREST_MIPMAP_NEAREST);
    198        }
    199 
    200        for (const program of programs) {
    201            gl.useProgram(program[0]);
    202            for (const mode of modes) {
    203                gl.texParameteri(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, mode[0]);
    204                for (const magFilter of magFilters) {
    205                    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl[magFilter]);
    206                    for (const minFilter of minFilters) {
    207                        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl[minFilter]);
    208                        debug(`Program: ${program[1]}, mode: ${mode[1]}, mag: ${magFilter}, min: ${minFilter}`);
    209 
    210                        gl.clear(gl.COLOR_BUFFER_BIT);
    211                        wtu.drawUnitQuad(gl);
    212 
    213                        if (format.format == gl.DEPTH_COMPONENT || mode[0] == gl.DEPTH_COMPONENT) {
    214                            if (program[1] == 'depth') {
    215                                wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
    216                                if (validFilters(gl[magFilter], gl[minFilter])) {
    217                                    wtu.checkCanvasRect(gl, 0, 0, 1, 1, [128, 0, 0, 255], "sampling depth from complete texture", 1);
    218                                } else {
    219                                    wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 0, 255], "sampling depth from incomplete texture", 1);
    220                                }
    221                            } else {
    222                                wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "sampling depth using incompatible program");
    223                            }
    224                        } else {
    225                            if (program[1] == 'stencil') {
    226                                wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
    227                                if (validFilters(gl[magFilter], gl[minFilter])) {
    228                                    wtu.checkCanvasRect(gl, 0, 0, 1, 1, [170, 0, 0, 1], "sampling stencil from complete texture", 1);
    229                                } else {
    230                                    // Incomplete textures may produce [0, 0, 0, 1] or [0, 0, 0, 255].
    231                                    const value = new Uint8Array(4);
    232                                    gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, value);
    233                                    wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    234                                    const msg = "sampling stencil from incomplete texture";
    235                                    if (value[0] == 0 && value[1] == 0 && value[2] == 0 && (value[3] == 1 || value[3] == 255)) {
    236                                        testPassed(msg);
    237                                    } else {
    238                                        testFailed(`${msg}: ${value}`);
    239                                    }
    240                                }
    241                            } else {
    242                                wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "sampling stencil using incompatible program");
    243                            }
    244                        }
    245                    }
    246                }
    247            }
    248        }
    249    }
    250 }
    251 
    252 function runTest() {
    253    if (!gl) {
    254        testFailed("context does not exist");
    255        return;
    256    }
    257    testPassed("context exists");
    258 
    259    runTestNoExtension();
    260 
    261    ext = gl.getExtension("WEBGL_stencil_texturing");
    262    wtu.runExtensionSupportedTest(gl, "WEBGL_stencil_texturing", ext !== null);
    263 
    264    if (ext !== null) {
    265        checkEnums();
    266        checkQueries();
    267        checkSampling();
    268    } else {
    269        testPassed("No WEBGL_stencil_texturing support -- this is legal");
    270    }
    271 }
    272 
    273 runTest();
    274 
    275 var successfullyParsed = true;
    276 </script>
    277 <script src="../../js/js-test-post.js"></script>
    278 </body>
    279 </html>