summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-2d.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-2d.html')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-2d.html290
1 files changed, 290 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-2d.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-2d.html
new file mode 100644
index 0000000000..34bff4d3a3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-2d.html
@@ -0,0 +1,290 @@
+<!--
+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>texStorage2D conformance test</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>
+<canvas id="canvas" width="64" height="64"> </canvas>
+<div id="console"></div>
+
+
+<script>
+"use strict";
+description("This test verifies the functionality of texStorage2D.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+var vao = null;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runTexStorage2DTest();
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function enumToString(value) {
+ return wtu.glEnumToString(gl, value);
+}
+
+function runTexStorage2DTest()
+{
+ var texStorage2DTestCases = [
+ {
+ target: gl.TEXTURE_2D,
+ mipmap: false,
+ sizedformat: gl.RGBA8,
+ unsizedformat: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ alpha: true,
+ redpixel: new Uint8Array([0xff, 0x00, 0x00, 0x00]),
+ },
+ {
+ target: gl.TEXTURE_2D,
+ mipmap: true,
+ sizedformat: gl.R11F_G11F_B10F,
+ unsizedformat: gl.RGB,
+ type: gl.UNSIGNED_INT_10F_11F_11F_REV,
+ alpha: false,
+ // Red is unsigned floating point with 5 exponent bits followed by 6 mantissa bits.
+ // The effective value is 2^(exponent - 15) * (1 + mantissa / 64)
+ // See OpenGL ES 3.0.3 spec, section 2.1.3
+ // Here we want to encode the value 1.0, which we achieve with a zero mantissa
+ // and an exponent of 15.
+ redpixel: new Uint32Array([15<<6]),
+ },
+ {
+ target: gl.TEXTURE_2D,
+ mipmap: true,
+ sizedformat: gl.RGBA32F,
+ unsizedformat: gl.RGBA,
+ type: gl.FLOAT,
+ alpha: true,
+ redpixel: new Float32Array([1, 0, 0, 0]),
+ },
+ {
+ target: gl.TEXTURE_CUBE_MAP,
+ mipmap: true,
+ sizedformat: gl.RGBA8,
+ unsizedformat: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ alpha: true,
+ redpixel: new Uint8Array([0xff, 0x00, 0x00, 0x00]),
+ },
+ {
+ target: gl.TEXTURE_CUBE_MAP,
+ mipmap: false,
+ sizedformat: gl.RGB8,
+ unsizedformat: gl.RGB,
+ type: gl.UNSIGNED_BYTE,
+ alpha: false,
+ redpixel: new Uint8Array([0xff, 0x00, 0x00]),
+ },
+ {
+ target: gl.TEXTURE_CUBE_MAP,
+ mipmap: true,
+ sizedformat: gl.RGB10_A2UI,
+ unsizedformat: gl.UNSIGNED_INT_2_10_10_10_REV, // type enum, bad as format
+ },
+ {
+ target: gl.TEXTURE_CUBE_MAP,
+ mipmap: false,
+ sizedformat: gl.R11F_G11F_B10F,
+ unsizedformat: gl.RGB,
+ }
+ ];
+
+ texStorage2DTestCases.forEach(function(testcase){
+ var target = testcase.target;
+ var imageTargets;
+
+ if (target == gl.TEXTURE_2D) {
+ imageTargets = [ gl.TEXTURE_2D ];
+ } else {
+ imageTargets = [ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z ];
+ }
+
+ var tex = gl.createTexture();
+ gl.bindTexture(target, tex);
+ var texsize = 4;
+ var levels = testcase.mipmap
+ ? Math.floor(Math.log(texsize) / Math.log(2)) + 1
+ : 1;
+
+ debug("");
+ debug("Testing texStorage2D with target " + enumToString(target) + ", " +
+ (testcase.mipmap ? "mipmap" : "no mipmap") + ", " +
+ "internalformat: " + enumToString(testcase.sizedformat));
+
+ gl.texStorage2D(target, levels, testcase.sizedformat,
+ 0, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage2D should fail for zero width");
+ gl.texStorage2D(target, levels, testcase.sizedformat,
+ texsize, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage2D should fail for zero height");
+ gl.texStorage2D(target, levels, testcase.sizedformat,
+ texsize, -texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage2D should fail for negative height");
+ gl.texStorage2D(target, 0, testcase.sizedformat,
+ texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage2D should fail for zero levels");
+ gl.texStorage2D(target,
+ Math.ceil(Math.log(texsize) / Math.log(2)) + 2,
+ testcase.sizedformat,
+ texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texStorage2D should fail for too many levels");
+ gl.texStorage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, levels, testcase.sizedformat,
+ texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "texStorage2D should fail for bad target TEXTURE_CUBE_MAP_NEGATIVE_X");
+
+ gl.bindTexture(target, null);
+ gl.texStorage2D(target, levels, testcase.sizedformat,
+ texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texStorage2D should fail when no texture is bound");
+ gl.bindTexture(target, tex);
+
+ // texStorage2D should only accept sized internalformats
+ gl.texStorage2D(target, levels, testcase.unsizedformat,
+ texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "texStorage2D should fail for bad internalformat " + enumToString(testcase.unsizedformat));
+
+ // OK, now let's finally do the successfull texStorage2D call
+ gl.texStorage2D(target, levels, testcase.sizedformat,
+ texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texStorage2D should succeed with a good sized internalformat");
+
+ // check TEXTURE_IMMUTABLE_FORMAT
+ var immutable = gl.getTexParameter(target, gl.TEXTURE_IMMUTABLE_FORMAT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "getTexParameter should succeed with TEXTURE_IMMUTABLE_FORMAT");
+ assertMsg(immutable != 0, "getTexParameter with TEXTURE_IMMUTABLE_FORMAT should not return 0");
+
+ // check operations disallowed on immutable texture
+ gl.texImage2D(imageTargets[0], 0, gl.RGBA, texsize, texsize, 0,
+ gl.RGBA, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage2D should fail on immutable texture");
+ var s3tc = gl.getExtension("WEBGL_compressed_texture_s3tc");
+ // FIXME - should eventually use a compressed format that's core in WebGL2, but
+ // I wanted something that I can run in Firefox today, which doesn't support the new formats yet.
+ if (s3tc) {
+ gl.compressedTexImage2D(imageTargets[0], 0, s3tc.COMPRESSED_RGBA_S3TC_DXT3_EXT,
+ texsize, texsize, 0,
+ new Uint8Array(texsize * texsize));
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "compressedTexImage2D should fail on immutable texture");
+ }
+ gl.copyTexImage2D(imageTargets[0], 0, gl.RGBA, 0, 0, texsize, texsize, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "copyTexImage2D should fail on immutable texture");
+
+ if ('redpixel' in testcase) {
+ // At this point, the texture images have only been defined by
+ // texStorage2D, which per spec should be equivalent to having
+ // defined texture images with null data, which should sample as RGBA 0,0,0,0.
+ gl.texParameteri(target, gl.TEXTURE_MIN_FILTER,
+ testcase.mipmap ? gl.NEAREST_MIPMAP_NEAREST : gl.NEAREST);
+ if (testcase.type == gl.FLOAT) {
+ gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ }
+
+ // Now upload some red texture data
+ var s = texsize;
+ var pixels;
+ if (testcase.redpixel instanceof Uint8Array) {
+ pixels = new Uint8Array(texsize * texsize * testcase.redpixel.length);
+ } else if (testcase.redpixel instanceof Uint16Array) {
+ pixels = new Uint16Array(texsize * texsize * testcase.redpixel.length);
+ } else if (testcase.redpixel instanceof Uint32Array) {
+ pixels = new Uint32Array(texsize * texsize * testcase.redpixel.length);
+ } else if (testcase.redpixel instanceof Float32Array) {
+ pixels = new Float32Array(texsize * texsize * testcase.redpixel.length);
+ }
+ for (var i = 0; i < texsize * texsize; i++) {
+ for (var j = 0; j < testcase.redpixel.length; j++) {
+ pixels[i * testcase.redpixel.length + j] = testcase.redpixel[j];
+ }
+ }
+
+ if (target == gl.TEXTURE_2D) {
+ wtu.setupTexturedQuad(gl);
+ } else if (target == gl.TEXTURE_CUBE_MAP) {
+ wtu.setupTexturedQuadWithCubeMap(gl);
+ }
+
+ wtu.clearAndDrawUnitQuad(gl);
+ var alpha = testcase.alpha ? 0 : 255;
+ wtu.checkCanvas(gl, [0, 0, 0, alpha], "texture should sample as uninitialized texture after texStorage2D");
+
+ if (target == gl.TEXTURE_2D) {
+ for (var l = 0; l < levels; l++) {
+ gl.texSubImage2D(gl.TEXTURE_2D,
+ l, 0, 0,
+ s, s,
+ testcase.unsizedformat, testcase.type,
+ pixels);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D should succeed on immutable texture as long as the format is compatible");
+ s /= 2;
+ }
+ } else if (target == gl.TEXTURE_CUBE_MAP) {
+ for (var l = 0; l < levels; l++) {
+ for (var f = 0; f < 6; f++) {
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + f,
+ l, 0, 0,
+ s, s,
+ testcase.unsizedformat, testcase.type,
+ pixels);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D should succeed on immutable texture as long as the format is compatible");
+ }
+ s /= 2;
+ }
+ }
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, alpha], "texture should sample as red after uploading red pixels with texSubImage2D");
+ }
+ });
+
+ debug("");
+ debug("Test non-square images:");
+ const levels = 4;
+ const maxSize = 1 << (levels-1);
+
+ function expectOk(x,y) {
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texStorage2D(gl.TEXTURE_2D, levels, gl.RGBA8, x, y);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "texStorage2D should succeed with size [" + ([x,y].join(', ')) + "].");
+ gl.deleteTexture(tex);
+ }
+ expectOk(maxSize, maxSize);
+ expectOk(maxSize, 1);
+ expectOk( 1, maxSize);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>