tor-browser

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

tex-storage-2d.html (12119B)


      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>texStorage2D 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 <div id="description"></div>
     18 <canvas id="canvas" width="64" height="64"> </canvas>
     19 <div id="console"></div>
     20 
     21 
     22 <script>
     23 "use strict";
     24 description("This test verifies the functionality of texStorage2D.");
     25 
     26 debug("");
     27 
     28 var wtu = WebGLTestUtils;
     29 var canvas = document.getElementById("canvas");
     30 var gl = wtu.create3DContext(canvas, null, 2);
     31 var vao = null;
     32 
     33 if (!gl) {
     34    testFailed("WebGL context does not exist");
     35 } else {
     36    testPassed("WebGL context exists");
     37 
     38    runTexStorage2DTest();
     39 
     40    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
     41 }
     42 
     43 function enumToString(value) {
     44  return wtu.glEnumToString(gl, value);
     45 }
     46 
     47 function runTexStorage2DTest()
     48 {
     49    var texStorage2DTestCases = [
     50        {
     51            target: gl.TEXTURE_2D,
     52            mipmap: false,
     53            sizedformat: gl.RGBA8,
     54            unsizedformat: gl.RGBA,
     55            type: gl.UNSIGNED_BYTE,
     56            alpha: true,
     57            redpixel: new Uint8Array([0xff, 0x00, 0x00, 0x00]),
     58        },
     59        {
     60            target: gl.TEXTURE_2D,
     61            mipmap: true,
     62            sizedformat: gl.R11F_G11F_B10F,
     63            unsizedformat: gl.RGB,
     64            type: gl.UNSIGNED_INT_10F_11F_11F_REV,
     65            alpha: false,
     66            // Red is unsigned floating point with 5 exponent bits followed by 6 mantissa bits.
     67            // The effective value is 2^(exponent - 15) * (1 + mantissa / 64)
     68            // See OpenGL ES 3.0.3 spec, section 2.1.3
     69            // Here we want to encode the value 1.0, which we achieve with a zero mantissa
     70            // and an exponent of 15.
     71            redpixel: new Uint32Array([15<<6]),
     72        },
     73        {
     74            target: gl.TEXTURE_2D,
     75            mipmap: true,
     76            sizedformat: gl.RGBA32F,
     77            unsizedformat: gl.RGBA,
     78            type: gl.FLOAT,
     79            alpha: true,
     80            redpixel: new Float32Array([1, 0, 0, 0]),
     81        },
     82        {
     83            target: gl.TEXTURE_CUBE_MAP,
     84            mipmap: true,
     85            sizedformat: gl.RGBA8,
     86            unsizedformat: gl.RGBA,
     87            type: gl.UNSIGNED_BYTE,
     88            alpha: true,
     89            redpixel: new Uint8Array([0xff, 0x00, 0x00, 0x00]),
     90        },
     91        {
     92            target: gl.TEXTURE_CUBE_MAP,
     93            mipmap: false,
     94            sizedformat: gl.RGB8,
     95            unsizedformat: gl.RGB,
     96            type: gl.UNSIGNED_BYTE,
     97            alpha: false,
     98            redpixel: new Uint8Array([0xff, 0x00, 0x00]),
     99        },
    100        {
    101            target: gl.TEXTURE_CUBE_MAP,
    102            mipmap: true,
    103            sizedformat: gl.RGB10_A2UI,
    104            unsizedformat: gl.UNSIGNED_INT_2_10_10_10_REV, // type enum, bad as format
    105        },
    106        {
    107            target: gl.TEXTURE_CUBE_MAP,
    108            mipmap: false,
    109            sizedformat: gl.R11F_G11F_B10F,
    110            unsizedformat: gl.RGB,
    111        }
    112    ];
    113 
    114    texStorage2DTestCases.forEach(function(testcase){
    115        var target = testcase.target;
    116        var imageTargets;
    117 
    118        if (target == gl.TEXTURE_2D) {
    119            imageTargets = [ gl.TEXTURE_2D ];
    120        } else {
    121            imageTargets = [ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
    122                             gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
    123                             gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
    124                             gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
    125                             gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
    126                             gl.TEXTURE_CUBE_MAP_NEGATIVE_Z ];
    127        }
    128 
    129        var tex = gl.createTexture();
    130        gl.bindTexture(target, tex);
    131        var texsize = 4;
    132        var levels = testcase.mipmap
    133                     ? Math.floor(Math.log(texsize) / Math.log(2)) + 1
    134                     : 1;
    135 
    136        debug("");
    137        debug("Testing texStorage2D with target " + enumToString(target) + ", " +
    138              (testcase.mipmap ? "mipmap" : "no mipmap") + ", " +
    139              "internalformat: " + enumToString(testcase.sizedformat));
    140 
    141        gl.texStorage2D(target, levels, testcase.sizedformat,
    142                        0, texsize);
    143        wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage2D should fail for zero width");
    144        gl.texStorage2D(target, levels, testcase.sizedformat,
    145                        texsize, 0);
    146        wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage2D should fail for zero height");
    147        gl.texStorage2D(target, levels, testcase.sizedformat,
    148                        texsize, -texsize);
    149        wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage2D should fail for negative height");
    150        gl.texStorage2D(target, 0, testcase.sizedformat,
    151                        texsize, texsize);
    152        wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage2D should fail for zero levels");
    153        gl.texStorage2D(target,
    154                        Math.ceil(Math.log(texsize) / Math.log(2)) + 2,
    155                        testcase.sizedformat,
    156                        texsize, texsize);
    157        wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texStorage2D should fail for too many levels");
    158        gl.texStorage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, levels, testcase.sizedformat,
    159                    texsize, texsize);
    160        wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "texStorage2D should fail for bad target TEXTURE_CUBE_MAP_NEGATIVE_X");
    161 
    162        gl.bindTexture(target, null);
    163        gl.texStorage2D(target, levels, testcase.sizedformat,
    164                        texsize, texsize);
    165        wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texStorage2D should fail when no texture is bound");
    166        gl.bindTexture(target, tex);
    167 
    168        // texStorage2D should only accept sized internalformats
    169        gl.texStorage2D(target, levels, testcase.unsizedformat,
    170                        texsize, texsize);
    171        wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "texStorage2D should fail for bad internalformat " + enumToString(testcase.unsizedformat));
    172 
    173        // OK, now let's finally do the successfull texStorage2D call
    174        gl.texStorage2D(target, levels, testcase.sizedformat,
    175                        texsize, texsize);
    176        wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texStorage2D should succeed with a good sized internalformat");
    177 
    178        // check TEXTURE_IMMUTABLE_FORMAT
    179        var immutable = gl.getTexParameter(target, gl.TEXTURE_IMMUTABLE_FORMAT);
    180        wtu.glErrorShouldBe(gl, gl.NO_ERROR, "getTexParameter should succeed with TEXTURE_IMMUTABLE_FORMAT");
    181        assertMsg(immutable != 0, "getTexParameter with TEXTURE_IMMUTABLE_FORMAT should not return 0");
    182 
    183        // check operations disallowed on immutable texture
    184        gl.texImage2D(imageTargets[0], 0, gl.RGBA, texsize, texsize, 0,
    185                      gl.RGBA, gl.UNSIGNED_BYTE, null);
    186        wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage2D should fail on immutable texture");
    187        var s3tc = gl.getExtension("WEBGL_compressed_texture_s3tc");
    188        // FIXME - should eventually use a compressed format that's core in WebGL2, but
    189        // I wanted something that I can run in Firefox today, which doesn't support the new formats yet.
    190        if (s3tc) {
    191            gl.compressedTexImage2D(imageTargets[0], 0, s3tc.COMPRESSED_RGBA_S3TC_DXT3_EXT,
    192                                    texsize, texsize, 0,
    193                                    new Uint8Array(texsize * texsize));
    194            wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "compressedTexImage2D should fail on immutable texture");
    195        }
    196        gl.copyTexImage2D(imageTargets[0], 0, gl.RGBA, 0, 0, texsize, texsize, 0);
    197        wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "copyTexImage2D should fail on immutable texture");
    198 
    199        if ('redpixel' in testcase) {
    200            // At this point, the texture images have only been defined by
    201            // texStorage2D, which per spec should be equivalent to having
    202            // defined texture images with null data, which should sample as RGBA 0,0,0,0.
    203            gl.texParameteri(target, gl.TEXTURE_MIN_FILTER,
    204                             testcase.mipmap ? gl.NEAREST_MIPMAP_NEAREST : gl.NEAREST);
    205            if (testcase.type == gl.FLOAT) {
    206                gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    207            }
    208 
    209            // Now upload some red texture data
    210            var s = texsize;
    211            var pixels;
    212            if (testcase.redpixel instanceof Uint8Array) {
    213                pixels = new Uint8Array(texsize * texsize * testcase.redpixel.length);
    214            } else if (testcase.redpixel instanceof Uint16Array) {
    215                pixels = new Uint16Array(texsize * texsize * testcase.redpixel.length);
    216            } else if (testcase.redpixel instanceof Uint32Array) {
    217                pixels = new Uint32Array(texsize * texsize * testcase.redpixel.length);
    218            } else if (testcase.redpixel instanceof Float32Array) {
    219                pixels = new Float32Array(texsize * texsize * testcase.redpixel.length);
    220            }
    221            for (var i = 0; i < texsize * texsize; i++) {
    222                for (var j = 0; j < testcase.redpixel.length; j++) {
    223                    pixels[i * testcase.redpixel.length + j] = testcase.redpixel[j];
    224                }
    225            }
    226 
    227            if (target == gl.TEXTURE_2D) {
    228                wtu.setupTexturedQuad(gl);
    229            } else if (target == gl.TEXTURE_CUBE_MAP) {
    230                wtu.setupTexturedQuadWithCubeMap(gl);
    231            }
    232 
    233            wtu.clearAndDrawUnitQuad(gl);
    234            var alpha = testcase.alpha ? 0 : 255;
    235            wtu.checkCanvas(gl, [0, 0, 0, alpha], "texture should sample as uninitialized texture after texStorage2D");
    236 
    237            if (target == gl.TEXTURE_2D) {
    238                for (var l = 0; l < levels; l++) {
    239                    gl.texSubImage2D(gl.TEXTURE_2D,
    240                                     l, 0, 0,
    241                                     s, s,
    242                                     testcase.unsizedformat, testcase.type,
    243                                     pixels);
    244                    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D should succeed on immutable texture as long as the format is compatible");
    245                    s /= 2;
    246                }
    247            } else if (target == gl.TEXTURE_CUBE_MAP) {
    248                for (var l = 0; l < levels; l++) {
    249                    for (var f = 0; f < 6; f++) {
    250                        gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + f,
    251                                         l, 0, 0,
    252                                         s, s,
    253                                         testcase.unsizedformat, testcase.type,
    254                                         pixels);
    255                        wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D should succeed on immutable texture as long as the format is compatible");
    256                    }
    257                    s /= 2;
    258                }
    259            }
    260 
    261            wtu.clearAndDrawUnitQuad(gl);
    262            wtu.checkCanvas(gl, [255, 0, 0, alpha], "texture should sample as red after uploading red pixels with texSubImage2D");
    263        }
    264    });
    265 
    266    debug("");
    267    debug("Test non-square images:");
    268    const levels = 4;
    269    const maxSize = 1 << (levels-1);
    270 
    271    function expectOk(x,y) {
    272        const tex = gl.createTexture();
    273        gl.bindTexture(gl.TEXTURE_2D, tex);
    274        gl.texStorage2D(gl.TEXTURE_2D, levels, gl.RGBA8, x, y);
    275        wtu.glErrorShouldBe(gl, gl.NO_ERROR,
    276                            "texStorage2D should succeed with size [" + ([x,y].join(', ')) + "].");
    277        gl.deleteTexture(tex);
    278    }
    279    expectOk(maxSize, maxSize);
    280    expectOk(maxSize,       1);
    281    expectOk(      1, maxSize);
    282 }
    283 
    284 debug("");
    285 var successfullyParsed = true;
    286 </script>
    287 <script src="../../../js/js-test-post.js"></script>
    288 
    289 </body>
    290 </html>