tor-browser

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

uninitialized-test-2.html (20623B)


      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 <!DOCTYPE html>
      7 <html>
      8 <head>
      9 <meta charset="utf-8">
     10 <title>WebGL 2 Uninitialized GL Resources Tests</title>
     11 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
     12 <script src="../../js/js-test-pre.js"></script>
     13 <script src="../../js/webgl-test-utils.js"></script>
     14 </head>
     15 <body>
     16 <div id="description"></div>
     17 <div id="console"></div>
     18 <canvas id="canvas" width="2" height="2"> </canvas>
     19 <script>
     20 "use strict";
     21 description("Tests to check user code cannot access uninitialized data from GL resources.");
     22 
     23 var wtu = WebGLTestUtils;
     24 var gl = wtu.create3DContext("canvas", undefined, 2);
     25 if (!gl)
     26  testFailed("Context created.");
     27 else
     28  testPassed("Context created.");
     29 
     30 // This is the maximum size that will end up being allocated with the tests
     31 // currently written as they are. It could need to be increased later.
     32 var scratchBuffer = new ArrayBuffer(1024 * 1024 * 8 * 4);
     33 function zeroArrayBuffer(arr) {
     34    for (var i = 0; i < arr.length; ++i) {
     35        arr[i] = 0;
     36    }
     37 }
     38 function getUint32Array(length) {
     39  var arr = new Uint32Array(scratchBuffer, 0, length);
     40  zeroArrayBuffer(arr);
     41  return arr;
     42 }
     43 function getInt32Array(length) {
     44  var arr = new Int32Array(scratchBuffer, 0, length);
     45  zeroArrayBuffer(arr);
     46  return arr;
     47 }
     48 function getUint8Array(length) {
     49  var arr = new Uint8Array(scratchBuffer, 0, length);
     50  zeroArrayBuffer(arr);
     51  return arr;
     52 }
     53 function getInt8Array(length) {
     54  var arr = new Int8Array(scratchBuffer, 0, length);
     55  zeroArrayBuffer(arr);
     56  return arr;
     57 }
     58 
     59 function setupTexture(target, texWidth, texHeight, texDepth) {
     60    var is3d = (target == gl.TEXTURE_3D || target == gl.TEXTURE_2D_ARRAY);
     61    var texture = gl.createTexture();
     62    gl.bindTexture(target, texture);
     63    if (is3d) {
     64        gl.texImage3D(target, 0, gl.RGBA8, texWidth, texHeight, texDepth, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
     65    } else if (target == gl.TEXTURE_2D) {
     66        gl.texImage2D(target, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
     67    } else {
     68        gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
     69        gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
     70        gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
     71        gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
     72        gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
     73        gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
     74    }
     75 
     76    // this can be quite undeterministic so to improve odds of seeing uninitialized data write bits
     77    // into tex then delete texture then re-create one with same characteristics (driver will likely reuse mem)
     78    // with this trick on r59046 WebKit/OSX I get FAIL 100% of the time instead of ~15% of the time.
     79 
     80    var badData = getUint8Array(texWidth * texHeight * texDepth * 4);
     81    for (var i = 0; i < badData.length; ++i)
     82        badData[i] = i % 255;
     83 
     84    if (is3d) {
     85        gl.texSubImage3D(target, 0, 0, 0, 0, texWidth, texHeight, texDepth, gl.RGBA, gl.UNSIGNED_BYTE, badData);
     86    } else if (target == gl.TEXTURE_2D) {
     87        gl.texSubImage2D(target, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
     88    } else {
     89        gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
     90        gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
     91        gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
     92        gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
     93        gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
     94        gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
     95    }
     96    gl.finish(); // make sure it has been uploaded
     97 
     98    gl.deleteTexture(texture);
     99    gl.finish(); // make sure it has been deleted
    100 
    101    var texture = gl.createTexture();
    102    gl.bindTexture(target, texture);
    103    return texture;
    104 }
    105 
    106 function checkNonZeroPixels(texture, target, format, type, texWidth, texHeight, level, layer, exceptions) {
    107    var tol = 2;
    108    var is3d = (target == gl.TEXTURE_3D || target == gl.TEXTURE_2D_ARRAY);
    109    switch (target) {
    110      case gl.TEXTURE_CUBE_MAP_POSITIVE_X:
    111      case gl.TEXTURE_CUBE_MAP_NEGATIVE_X:
    112      case gl.TEXTURE_CUBE_MAP_POSITIVE_Y:
    113      case gl.TEXTURE_CUBE_MAP_NEGATIVE_Y:
    114      case gl.TEXTURE_CUBE_MAP_POSITIVE_Z:
    115      case gl.TEXTURE_CUBE_MAP_NEGATIVE_Z:
    116        gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
    117        break;
    118      default:
    119        gl.bindTexture(target, null);
    120        break;
    121    }
    122    var fb = gl.createFramebuffer();
    123    gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
    124    if (is3d) {
    125        gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture, level, layer);
    126    } else {
    127        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, target, texture, level);
    128    }
    129    shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
    130 
    131    var data;
    132    switch (type) {
    133      case gl.UNSIGNED_INT:
    134        data = getUint32Array(texWidth * texHeight * 4);
    135        break;
    136      case gl.INT:
    137        data = getInt32Array(texWidth * texHeight * 4);
    138        break;
    139      case gl.UNSIGNED_BYTE:
    140      default:
    141        data = getUint8Array(texWidth * texHeight * 4);
    142        break;
    143    }
    144    gl.readPixels(0, 0, texWidth, texHeight, format, type, data);
    145 
    146    var k = 0;
    147    var failed_exceptions = 0;
    148    for (var y = 0; y < texHeight; ++y) {
    149        for (var x = 0; x < texWidth; ++x) {
    150            var index = (y * texWidth + x) * 4;
    151            var is_exception = false;
    152            for (var ii = 0; ii < exceptions.length; ++ii) {
    153                if (exceptions[ii].x == x && exceptions[ii].y == y) {
    154                    is_exception = true;
    155                    if (Math.abs(data[index] - exceptions[ii].r) > tol ||
    156                        Math.abs(data[index + 1] - exceptions[ii].g) > tol ||
    157                        Math.abs(data[index + 2] - exceptions[ii].b) > tol ||
    158                        Math.abs(data[index + 3] - exceptions[ii].a) > tol) {
    159                        failed_exceptions++;
    160                    }
    161                }
    162            }
    163            if (is_exception)
    164                continue;
    165            for (var i = 0; i < 4; ++i) {
    166                if (data[index + i] != 0) {
    167                    k++;
    168                }
    169            }
    170        }
    171    }
    172    var info = "Level = " + level;
    173    if (is3d)
    174        info  += ", layer = " + layer;
    175    info += " : ";
    176    if (k) {
    177        testFailed(info + "found " + k + " non-zero elements");
    178    } else {
    179        testPassed(info + "all data initialized");
    180    }
    181    if (exceptions.length > 0) {
    182        if (failed_exceptions) {
    183            testFailed(info + "found " + failed_exceptions + " elements incorrectly overwritten");
    184        } else {
    185            testPassed(info + "all initialized elements stay untouched");
    186        }
    187    }
    188 }
    189 
    190 function testTexImage3D() {
    191 
    192    var max_3d_texture_size = Math.min(gl.getParameter(gl.MAX_3D_TEXTURE_SIZE), 1024);
    193 
    194    var test_cases = [
    195      // TEXTURE_3D + RGBA8
    196      {
    197        target: "TEXTURE_3D",
    198        internal_format: "RGBA8",
    199        format: gl.RGBA,
    200        type: gl.UNSIGNED_BYTE,
    201        read_type: gl.UNSIGNED_BYTE,
    202        width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
    203        height: 256,
    204        depth: 8,
    205        exceptions: [ { x: 0, y: 0, r: 108, g: 72, b: 36, a: 9 } ],
    206      },
    207      {
    208        target: "TEXTURE_3D",
    209        internal_format: "RGBA8",
    210        format: gl.RGBA,
    211        type: gl.UNSIGNED_BYTE,
    212        read_type: gl.UNSIGNED_BYTE,
    213        width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
    214        height: 256,
    215        depth: 8,
    216        exceptions: [],
    217      },
    218      {
    219        target: "TEXTURE_3D",
    220        internal_format: "RGBA8",
    221        format: gl.RGBA,
    222        type: gl.UNSIGNED_BYTE,
    223        read_type: gl.UNSIGNED_BYTE,
    224        width: max_3d_texture_size,
    225        height: max_3d_texture_size,
    226        depth: 4,
    227        exceptions: [ { x: 0, y: 128, r: 108, g: 72, b: 36, a: 9 } ],
    228      },
    229      {
    230        target: "TEXTURE_3D",
    231        internal_format: "RGBA8",
    232        format: gl.RGBA,
    233        type: gl.UNSIGNED_BYTE,
    234        read_type: gl.UNSIGNED_BYTE,
    235        width: max_3d_texture_size,
    236        height: max_3d_texture_size,
    237        depth: 4,
    238        exceptions: [],
    239      },
    240 
    241      // TEXTURE_3D + RGBA8UI
    242      {
    243        target: "TEXTURE_3D",
    244        internal_format: "RGBA8UI",
    245        format: gl.RGBA_INTEGER,
    246        type: gl.UNSIGNED_BYTE,
    247        read_type: gl.UNSIGNED_INT,
    248        width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
    249        height: 256,
    250        depth: 8,
    251        exceptions: [ { x: 0, y: 255, r: 108, g: 72, b: 36, a: 9 } ],
    252      },
    253      {
    254        target: "TEXTURE_3D",
    255        internal_format: "RGBA8UI",
    256        format: gl.RGBA_INTEGER,
    257        type: gl.UNSIGNED_BYTE,
    258        read_type: gl.UNSIGNED_INT,
    259        width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
    260        height: 256,
    261        depth: 8,
    262        exceptions: [],
    263      },
    264      {
    265        target: "TEXTURE_3D",
    266        internal_format: "RGBA8UI",
    267        format: gl.RGBA_INTEGER,
    268        type: gl.UNSIGNED_BYTE,
    269        read_type: gl.UNSIGNED_INT,
    270        width: max_3d_texture_size,
    271        height: max_3d_texture_size,
    272        depth: 4,
    273        exceptions: [ { x: 128, y: 0, r: 108, g: 72, b: 36, a: 9 } ],
    274      },
    275      {
    276        target: "TEXTURE_3D",
    277        internal_format: "RGBA8UI",
    278        format: gl.RGBA_INTEGER,
    279        type: gl.UNSIGNED_BYTE,
    280        read_type: gl.UNSIGNED_INT,
    281        width: max_3d_texture_size,
    282        height: max_3d_texture_size,
    283        depth: 4,
    284        exceptions: [],
    285      },
    286 
    287      // TEXTURE_3D + RGBA8I
    288      {
    289        target: "TEXTURE_3D",
    290        internal_format: "RGBA8I",
    291        format: gl.RGBA_INTEGER,
    292        type: gl.BYTE,
    293        read_type: gl.INT,
    294        width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
    295        height: 256,
    296        depth: 8,
    297        exceptions: [ { x: 128, y: 255, r: 108, g: 72, b: 36, a: 9 } ],
    298      },
    299      {
    300        target: "TEXTURE_3D",
    301        internal_format: "RGBA8I",
    302        format: gl.RGBA_INTEGER,
    303        type: gl.BYTE,
    304        read_type: gl.INT,
    305        width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
    306        height: 256,
    307        depth: 8,
    308        exceptions: [],
    309      },
    310      {
    311        target: "TEXTURE_3D",
    312        internal_format: "RGBA8I",
    313        format: gl.RGBA_INTEGER,
    314        type: gl.BYTE,
    315        read_type: gl.INT,
    316        width: max_3d_texture_size,
    317        height: max_3d_texture_size,
    318        depth: 4,
    319        exceptions: [ { x: 128, y: 128, r: 108, g: 72, b: 36, a: 9 } ],
    320      },
    321      {
    322        target: "TEXTURE_3D",
    323        internal_format: "RGBA8I",
    324        format: gl.RGBA_INTEGER,
    325        type: gl.BYTE,
    326        read_type: gl.INT,
    327        width: max_3d_texture_size,
    328        height: max_3d_texture_size,
    329        depth: 4,
    330        exceptions: [],
    331      },
    332 
    333      // TEXTURE_2D_ARRAY + RGBA8
    334      {
    335        target: "TEXTURE_2D_ARRAY",
    336        internal_format: "RGBA8",
    337        format: gl.RGBA,
    338        type: gl.UNSIGNED_BYTE,
    339        read_type: gl.UNSIGNED_BYTE,
    340        width: 1024,
    341        height: 1024,
    342        depth: 8,
    343        exceptions: [ { x: 1023, y: 0, r: 108, g: 72, b: 36, a: 9 } ],
    344      },
    345      {
    346        target: "TEXTURE_2D_ARRAY",
    347        internal_format: "RGBA8",
    348        format: gl.RGBA,
    349        type: gl.UNSIGNED_BYTE,
    350        read_type: gl.UNSIGNED_BYTE,
    351        width: 1024,
    352        height: 1024,
    353        depth: 8,
    354        exceptions: [],
    355      },
    356      {
    357        target: "TEXTURE_2D_ARRAY",
    358        internal_format: "RGBA8",
    359        format: gl.RGBA,
    360        type: gl.UNSIGNED_BYTE,
    361        read_type: gl.UNSIGNED_BYTE,
    362        width: 64,
    363        height: 64,
    364        depth: 256,  // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
    365        exceptions: [ { x: 63, y: 32, r: 108, g: 72, b: 36, a: 9 } ],
    366      },
    367      {
    368        target: "TEXTURE_2D_ARRAY",
    369        internal_format: "RGBA8",
    370        format: gl.RGBA,
    371        type: gl.UNSIGNED_BYTE,
    372        read_type: gl.UNSIGNED_BYTE,
    373        width: 64,
    374        height: 64,
    375        depth: 256,  // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
    376        exceptions: [],
    377      },
    378 
    379      // TEXTURE_2D_ARRAY + RGBA8UI
    380      {
    381        target: "TEXTURE_2D_ARRAY",
    382        internal_format: "RGBA8UI",
    383        format: gl.RGBA_INTEGER,
    384        type: gl.UNSIGNED_BYTE,
    385        read_type: gl.UNSIGNED_INT,
    386        width: 1024,
    387        height: 1024,
    388        depth: 8,
    389        exceptions: [ { x: 1023, y: 1023, r: 108, g: 72, b: 36, a: 9 } ],
    390      },
    391      {
    392        target: "TEXTURE_2D_ARRAY",
    393        internal_format: "RGBA8UI",
    394        format: gl.RGBA_INTEGER,
    395        type: gl.UNSIGNED_BYTE,
    396        read_type: gl.UNSIGNED_INT,
    397        width: 1024,
    398        height: 1024,
    399        depth: 8,
    400        exceptions: [],
    401      },
    402      {
    403        target: "TEXTURE_2D_ARRAY",
    404        internal_format: "RGBA8UI",
    405        format: gl.RGBA_INTEGER,
    406        type: gl.UNSIGNED_BYTE,
    407        read_type: gl.UNSIGNED_INT,
    408        width: 64,
    409        height: 64,
    410        depth: 256,  // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
    411        exceptions: [ { x: 0, y: 0, r: 108, g: 72, b: 36, a: 9 } ],
    412      },
    413      {
    414        target: "TEXTURE_2D_ARRAY",
    415        internal_format: "RGBA8UI",
    416        format: gl.RGBA_INTEGER,
    417        type: gl.UNSIGNED_BYTE,
    418        read_type: gl.UNSIGNED_INT,
    419        width: 64,
    420        height: 64,
    421        depth: 256,  // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
    422        exceptions: [],
    423      },
    424 
    425      // TEXTURE_2D_ARRAY + RGBA8I
    426      {
    427        target: "TEXTURE_2D_ARRAY",
    428        internal_format: "RGBA8I",
    429        format: gl.RGBA_INTEGER,
    430        type: gl.BYTE,
    431        read_type: gl.INT,
    432        width: 1024,
    433        height: 1024,
    434        depth: 8,
    435        exceptions: [ { x: 512, y: 1023, r: 108, g: 72, b: 36, a: 9 } ],
    436      },
    437      {
    438        target: "TEXTURE_2D_ARRAY",
    439        internal_format: "RGBA8I",
    440        format: gl.RGBA_INTEGER,
    441        type: gl.BYTE,
    442        read_type: gl.INT,
    443        width: 1024,
    444        height: 1024,
    445        depth: 8,
    446        exceptions: [],
    447      },
    448      {
    449        target: "TEXTURE_2D_ARRAY",
    450        internal_format: "RGBA8I",
    451        format: gl.RGBA_INTEGER,
    452        type: gl.BYTE,
    453        read_type: gl.INT,
    454        width: 64,
    455        height: 64,
    456        depth: 256,  // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
    457        exceptions: [ { x: 63, y: 32, r: 108, g: 72, b: 36, a: 9 } ],
    458      },
    459      {
    460        target: "TEXTURE_2D_ARRAY",
    461        internal_format: "RGBA8I",
    462        format: gl.RGBA_INTEGER,
    463        type: gl.BYTE,
    464        read_type: gl.INT,
    465        width: 64,
    466        height: 64,
    467        depth: 256,  // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
    468        exceptions: [],
    469      },
    470 
    471      // If more tests are added here, make sure to increase the size of
    472      // scratchBuffer above, if needed.
    473    ];
    474 
    475    for (var ii = 0; ii < test_cases.length; ++ii) {
    476        debug("");
    477        var test = test_cases[ii];
    478        debug("TexImage3D with target = " + test.target + ", internal_format = " + test.internal_format +
    479              ", width = " + test.width + ", height = " + test.height + ", depth = " + test.depth);
    480        var tex = setupTexture(gl[test.target], test.width, test.height, test.depth);
    481        gl.texImage3D(gl[test.target], 0, gl[test.internal_format], test.width, test.height, test.depth, 0, test.format, test.type, null);
    482        for (var jj = 0; jj < test.exceptions.length; ++jj) {
    483            var exception = test.exceptions[jj];
    484            var data;
    485            switch (test.type) {
    486              case gl.BYTE:
    487                data = getInt8Array(4 * test.depth);
    488                break;
    489              case gl.UNSIGNED_BYTE:
    490                data = getUint8Array(4 * test.depth);
    491                break;
    492              default:
    493                assert(false);
    494            }
    495            for (var pixel = 0; pixel < test.depth; ++pixel) {
    496                data[pixel * 4] = exception.r;
    497                data[pixel * 4 + 1] = exception.g;
    498                data[pixel * 4 + 2] = exception.b;
    499                data[pixel * 4 + 3] = exception.a;
    500            }
    501            gl.texSubImage3D(gl[test.target], 0, exception.x, exception.y, 0, 1, 1, test.depth, test.format, test.type, data);
    502        }
    503        for (var layer = 0; layer < test.depth; ++layer)
    504            checkNonZeroPixels(tex, gl[test.target], test.format, test.read_type, test.width, test.height, 0, layer, test.exceptions);
    505        gl.deleteTexture(tex);
    506        gl.finish();
    507        wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    508    }
    509 }
    510 
    511 function testTexStorage2D() {
    512    var targets = [ "TEXTURE_2D", "TEXTURE_CUBE_MAP" ];
    513    var width = 512;
    514    var height = 512;
    515    var levels = 5;
    516 
    517    for (var ii = 0; ii < targets.length; ++ii) {
    518        debug("");
    519        debug("Reading an uninitialized texture (texStorage2D) should succeed with all bytes set to 0 : target = " + targets[ii]);
    520        var tex = setupTexture(gl[targets[ii]], width, height, 1);
    521        gl.texStorage2D(gl[targets[ii]], levels, gl.RGBA8, width, height);
    522        for (var level = 0; level < levels; ++level) {
    523            if (gl[targets[ii]] == gl.TEXTURE_2D) {
    524                checkNonZeroPixels(tex, gl[targets[ii]], gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
    525            } else {
    526                checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_POSITIVE_X, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
    527                checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
    528                checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_POSITIVE_Y, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
    529                checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
    530                checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_POSITIVE_Z, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
    531                checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
    532            }
    533        }
    534        gl.deleteTexture(tex);
    535        gl.finish();
    536        wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    537    }
    538 }
    539 
    540 function testTexStorage3D() {
    541    var targets = [ "TEXTURE_3D", "TEXTURE_2D_ARRAY" ];
    542    var internal_formats = [ "RGBA8", "RGBA8UI", "RGBA8I" ];
    543    var formats = [ gl.RGBA, gl.RGBA_INTEGER, gl.RGBA_INTEGER ];
    544    var read_types = [ gl.UNSIGNED_BYTE, gl.UNSIGNED_INT, gl.INT ];
    545    var width = 256;  // minimum MAX_3D_TEXTURE_SIZE is 256
    546    var height = 256;  // minimum MAX_3D_TEXTURE_SIZE is 256
    547    var depth = 8;
    548    var levels = 5;
    549 
    550    for (var ii = 0; ii < targets.length; ++ii) {
    551        debug("");
    552        debug("Reading an uninitialized texture (texStorage3D) should succeed with all bytes set to 0 : target = " + targets[ii]);
    553        for (var jj = 0; jj < internal_formats.length; ++jj) {
    554            debug("");
    555            debug("Internal format : " + internal_formats[jj]);
    556            var tex = setupTexture(gl[targets[ii]], width, height, depth);
    557            gl.texStorage3D(gl[targets[ii]], levels, gl[internal_formats[jj]], width, height, depth);
    558            var level_depth = depth;
    559            for (var level = 0; level < levels; ++level) {
    560                for (var layer = 0; layer < level_depth; ++layer) {
    561                    checkNonZeroPixels(tex, gl[targets[ii]], formats[jj], read_types[jj], width, height, level, layer, []);
    562                }
    563                if (gl[targets[ii]] == gl.TEXTURE_3D)
    564                    level_depth = Math.max(1, level_depth >> 1);
    565            }
    566            gl.deleteTexture(tex);
    567            gl.finish();
    568            wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    569        }
    570    }
    571 }
    572 
    573 testTexImage3D();
    574 testTexStorage2D();
    575 testTexStorage3D();
    576 
    577 debug("");
    578 var successfullyParsed = true;
    579 </script>
    580 <script src="../../js/js-test-post.js"></script>
    581 </body>
    582 </html>