| <!-- |
| 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> |
| |