summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance2/misc/uninitialized-test-2.html
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/uninitialized-test-2.html583
1 files changed, 583 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/uninitialized-test-2.html b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/uninitialized-test-2.html
new file mode 100644
index 0000000000..4befe35c93
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/uninitialized-test-2.html
@@ -0,0 +1,583 @@
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 2 Uninitialized GL Resources Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script>
+"use strict";
+description("Tests to check user code cannot access uninitialized data from GL resources.");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas", undefined, 2);
+if (!gl)
+ testFailed("Context created.");
+else
+ testPassed("Context created.");
+
+// This is the maximum size that will end up being allocated with the tests
+// currently written as they are. It could need to be increased later.
+var scratchBuffer = new ArrayBuffer(1024 * 1024 * 8 * 4);
+function zeroArrayBuffer(arr) {
+ for (var i = 0; i < arr.length; ++i) {
+ arr[i] = 0;
+ }
+}
+function getUint32Array(length) {
+ var arr = new Uint32Array(scratchBuffer, 0, length);
+ zeroArrayBuffer(arr);
+ return arr;
+}
+function getInt32Array(length) {
+ var arr = new Int32Array(scratchBuffer, 0, length);
+ zeroArrayBuffer(arr);
+ return arr;
+}
+function getUint8Array(length) {
+ var arr = new Uint8Array(scratchBuffer, 0, length);
+ zeroArrayBuffer(arr);
+ return arr;
+}
+function getInt8Array(length) {
+ var arr = new Int8Array(scratchBuffer, 0, length);
+ zeroArrayBuffer(arr);
+ return arr;
+}
+
+function setupTexture(target, texWidth, texHeight, texDepth) {
+ var is3d = (target == gl.TEXTURE_3D || target == gl.TEXTURE_2D_ARRAY);
+ var texture = gl.createTexture();
+ gl.bindTexture(target, texture);
+ if (is3d) {
+ gl.texImage3D(target, 0, gl.RGBA8, texWidth, texHeight, texDepth, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ } else if (target == gl.TEXTURE_2D) {
+ gl.texImage2D(target, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ } else {
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ }
+
+ // this can be quite undeterministic so to improve odds of seeing uninitialized data write bits
+ // into tex then delete texture then re-create one with same characteristics (driver will likely reuse mem)
+ // with this trick on r59046 WebKit/OSX I get FAIL 100% of the time instead of ~15% of the time.
+
+ var badData = getUint8Array(texWidth * texHeight * texDepth * 4);
+ for (var i = 0; i < badData.length; ++i)
+ badData[i] = i % 255;
+
+ if (is3d) {
+ gl.texSubImage3D(target, 0, 0, 0, 0, texWidth, texHeight, texDepth, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ } else if (target == gl.TEXTURE_2D) {
+ gl.texSubImage2D(target, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ } else {
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ }
+ gl.finish(); // make sure it has been uploaded
+
+ gl.deleteTexture(texture);
+ gl.finish(); // make sure it has been deleted
+
+ var texture = gl.createTexture();
+ gl.bindTexture(target, texture);
+ return texture;
+}
+
+function checkNonZeroPixels(texture, target, format, type, texWidth, texHeight, level, layer, exceptions) {
+ var tol = 2;
+ var is3d = (target == gl.TEXTURE_3D || target == gl.TEXTURE_2D_ARRAY);
+ switch (target) {
+ case gl.TEXTURE_CUBE_MAP_POSITIVE_X:
+ case gl.TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case gl.TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case gl.TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case gl.TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case gl.TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
+ break;
+ default:
+ gl.bindTexture(target, null);
+ break;
+ }
+ var fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ if (is3d) {
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture, level, layer);
+ } else {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, target, texture, level);
+ }
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+
+ var data;
+ switch (type) {
+ case gl.UNSIGNED_INT:
+ data = getUint32Array(texWidth * texHeight * 4);
+ break;
+ case gl.INT:
+ data = getInt32Array(texWidth * texHeight * 4);
+ break;
+ case gl.UNSIGNED_BYTE:
+ default:
+ data = getUint8Array(texWidth * texHeight * 4);
+ break;
+ }
+ gl.readPixels(0, 0, texWidth, texHeight, format, type, data);
+
+ var k = 0;
+ var failed_exceptions = 0;
+ for (var y = 0; y < texHeight; ++y) {
+ for (var x = 0; x < texWidth; ++x) {
+ var index = (y * texWidth + x) * 4;
+ var is_exception = false;
+ for (var ii = 0; ii < exceptions.length; ++ii) {
+ if (exceptions[ii].x == x && exceptions[ii].y == y) {
+ is_exception = true;
+ if (Math.abs(data[index] - exceptions[ii].r) > tol ||
+ Math.abs(data[index + 1] - exceptions[ii].g) > tol ||
+ Math.abs(data[index + 2] - exceptions[ii].b) > tol ||
+ Math.abs(data[index + 3] - exceptions[ii].a) > tol) {
+ failed_exceptions++;
+ }
+ }
+ }
+ if (is_exception)
+ continue;
+ for (var i = 0; i < 4; ++i) {
+ if (data[index + i] != 0) {
+ k++;
+ }
+ }
+ }
+ }
+ var info = "Level = " + level;
+ if (is3d)
+ info += ", layer = " + layer;
+ info += " : ";
+ if (k) {
+ testFailed(info + "found " + k + " non-zero elements");
+ } else {
+ testPassed(info + "all data initialized");
+ }
+ if (exceptions.length > 0) {
+ if (failed_exceptions) {
+ testFailed(info + "found " + failed_exceptions + " elements incorrectly overwritten");
+ } else {
+ testPassed(info + "all initialized elements stay untouched");
+ }
+ }
+}
+
+function testTexImage3D() {
+
+ var max_3d_texture_size = Math.min(gl.getParameter(gl.MAX_3D_TEXTURE_SIZE), 1024);
+
+ var test_cases = [
+ // TEXTURE_3D + RGBA8
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [ { x: 0, y: 0, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [ { x: 0, y: 128, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [],
+ },
+
+ // TEXTURE_3D + RGBA8UI
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [ { x: 0, y: 255, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [ { x: 128, y: 0, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [],
+ },
+
+ // TEXTURE_3D + RGBA8I
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [ { x: 128, y: 255, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [ { x: 128, y: 128, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [],
+ },
+
+ // TEXTURE_2D_ARRAY + RGBA8
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [ { x: 1023, y: 0, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [ { x: 63, y: 32, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [],
+ },
+
+ // TEXTURE_2D_ARRAY + RGBA8UI
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [ { x: 1023, y: 1023, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [ { x: 0, y: 0, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [],
+ },
+
+ // TEXTURE_2D_ARRAY + RGBA8I
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [ { x: 512, y: 1023, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [ { x: 63, y: 32, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [],
+ },
+
+ // If more tests are added here, make sure to increase the size of
+ // scratchBuffer above, if needed.
+ ];
+
+ for (var ii = 0; ii < test_cases.length; ++ii) {
+ debug("");
+ var test = test_cases[ii];
+ debug("TexImage3D with target = " + test.target + ", internal_format = " + test.internal_format +
+ ", width = " + test.width + ", height = " + test.height + ", depth = " + test.depth);
+ var tex = setupTexture(gl[test.target], test.width, test.height, test.depth);
+ gl.texImage3D(gl[test.target], 0, gl[test.internal_format], test.width, test.height, test.depth, 0, test.format, test.type, null);
+ for (var jj = 0; jj < test.exceptions.length; ++jj) {
+ var exception = test.exceptions[jj];
+ var data;
+ switch (test.type) {
+ case gl.BYTE:
+ data = getInt8Array(4 * test.depth);
+ break;
+ case gl.UNSIGNED_BYTE:
+ data = getUint8Array(4 * test.depth);
+ break;
+ default:
+ assert(false);
+ }
+ for (var pixel = 0; pixel < test.depth; ++pixel) {
+ data[pixel * 4] = exception.r;
+ data[pixel * 4 + 1] = exception.g;
+ data[pixel * 4 + 2] = exception.b;
+ data[pixel * 4 + 3] = exception.a;
+ }
+ gl.texSubImage3D(gl[test.target], 0, exception.x, exception.y, 0, 1, 1, test.depth, test.format, test.type, data);
+ }
+ for (var layer = 0; layer < test.depth; ++layer)
+ checkNonZeroPixels(tex, gl[test.target], test.format, test.read_type, test.width, test.height, 0, layer, test.exceptions);
+ gl.deleteTexture(tex);
+ gl.finish();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ }
+}
+
+function testTexStorage2D() {
+ var targets = [ "TEXTURE_2D", "TEXTURE_CUBE_MAP" ];
+ var width = 512;
+ var height = 512;
+ var levels = 5;
+
+ for (var ii = 0; ii < targets.length; ++ii) {
+ debug("");
+ debug("Reading an uninitialized texture (texStorage2D) should succeed with all bytes set to 0 : target = " + targets[ii]);
+ var tex = setupTexture(gl[targets[ii]], width, height, 1);
+ gl.texStorage2D(gl[targets[ii]], levels, gl.RGBA8, width, height);
+ for (var level = 0; level < levels; ++level) {
+ if (gl[targets[ii]] == gl.TEXTURE_2D) {
+ checkNonZeroPixels(tex, gl[targets[ii]], gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ } else {
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_POSITIVE_X, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_POSITIVE_Y, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_POSITIVE_Z, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ }
+ }
+ gl.deleteTexture(tex);
+ gl.finish();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ }
+}
+
+function testTexStorage3D() {
+ var targets = [ "TEXTURE_3D", "TEXTURE_2D_ARRAY" ];
+ var internal_formats = [ "RGBA8", "RGBA8UI", "RGBA8I" ];
+ var formats = [ gl.RGBA, gl.RGBA_INTEGER, gl.RGBA_INTEGER ];
+ var read_types = [ gl.UNSIGNED_BYTE, gl.UNSIGNED_INT, gl.INT ];
+ var width = 256; // minimum MAX_3D_TEXTURE_SIZE is 256
+ var height = 256; // minimum MAX_3D_TEXTURE_SIZE is 256
+ var depth = 8;
+ var levels = 5;
+
+ for (var ii = 0; ii < targets.length; ++ii) {
+ debug("");
+ debug("Reading an uninitialized texture (texStorage3D) should succeed with all bytes set to 0 : target = " + targets[ii]);
+ for (var jj = 0; jj < internal_formats.length; ++jj) {
+ debug("");
+ debug("Internal format : " + internal_formats[jj]);
+ var tex = setupTexture(gl[targets[ii]], width, height, depth);
+ gl.texStorage3D(gl[targets[ii]], levels, gl[internal_formats[jj]], width, height, depth);
+ var level_depth = depth;
+ for (var level = 0; level < levels; ++level) {
+ for (var layer = 0; layer < level_depth; ++layer) {
+ checkNonZeroPixels(tex, gl[targets[ii]], formats[jj], read_types[jj], width, height, level, layer, []);
+ }
+ if (gl[targets[ii]] == gl.TEXTURE_3D)
+ level_depth = Math.max(1, level_depth >> 1);
+ }
+ gl.deleteTexture(tex);
+ gl.finish();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ }
+ }
+}
+
+testTexImage3D();
+testTexStorage2D();
+testTexStorage3D();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
+