tex-storage-and-subimage-3d.html (10355B)
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>texStorage3D and texSubImage3D 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 texStorage3D and texSubImage3D."); 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 runTexStorageAndSubImage3DTest(); 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 runTexStorageAndSubImage3DTest() 48 { 49 var texStorage3DTestCases = [ 50 { 51 target: gl.TEXTURE_3D, 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_3D, 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_3D, 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 84 texStorage3DTestCases.forEach(function(testcase){ 85 var tex = gl.createTexture(); 86 gl.bindTexture(gl.TEXTURE_3D, tex); 87 var texsize = 4; 88 var levels = testcase.mipmap 89 ? Math.floor(Math.log(texsize) / Math.log(2)) + 1 90 : 1; 91 92 debug(""); 93 debug("Testing texStorage3D with " + 94 (testcase.mipmap ? "mipmap" : "no mipmap") + ", " + 95 "internalformat: " + enumToString(testcase.sizedformat)); 96 97 gl.texStorage3D(gl.TEXTURE_3D, levels, testcase.sizedformat, 98 0, texsize, texsize); 99 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage3D should fail for zero width"); 100 gl.texStorage3D(gl.TEXTURE_3D, levels, testcase.sizedformat, 101 texsize, 0, texsize); 102 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage3D should fail for zero height"); 103 gl.texStorage3D(gl.TEXTURE_3D, levels, testcase.sizedformat, 104 texsize, texsize, 0); 105 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage3D should fail for zero depth"); 106 gl.texStorage3D(gl.TEXTURE_3D, levels, testcase.sizedformat, 107 texsize, -texsize, texsize); 108 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage3D should fail for negative height"); 109 gl.texStorage3D(gl.TEXTURE_3D, 0, testcase.sizedformat, 110 texsize, texsize, texsize); 111 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage3D should fail for zero levels"); 112 if (testcase.mipmap) { 113 gl.texStorage3D(gl.TEXTURE_3D, 114 levels + 1, 115 testcase.sizedformat, 116 texsize, texsize, texsize); 117 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texStorage3D should fail for too many levels"); 118 } 119 gl.texStorage3D(gl.TEXTURE_2D, 120 levels, 121 testcase.sizedformat, 122 texsize, texsize, texsize); 123 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "texStorage3D should fail for target TEXTURE_2D"); 124 gl.texStorage3D(gl.TEXTURE_CUBE_MAP, 125 levels, 126 testcase.sizedformat, 127 texsize, texsize, texsize); 128 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "texStorage3D should fail for target TEXTURE_CUBE_MAP"); 129 gl.bindTexture(gl.TEXTURE_3D, null); 130 gl.texStorage3D(gl.TEXTURE_3D, levels, testcase.sizedformat, 131 texsize, texsize, texsize); 132 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texStorage3D should fail when no texture is bound"); 133 gl.bindTexture(gl.TEXTURE_3D, tex); 134 135 // texStorage3D should only accept sized internalformats 136 gl.texStorage3D(gl.TEXTURE_3D, levels, testcase.unsizedformat, 137 texsize, texsize, texsize); 138 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "texStorage3D should fail for bad internalformat " + enumToString(testcase.unsizedformat)); 139 140 var pixels; 141 var number_of_pixels = texsize * texsize * texsize; 142 if (testcase.redpixel instanceof Uint8Array) { 143 pixels = new Uint8Array(number_of_pixels * testcase.redpixel.length); 144 } else if (testcase.redpixel instanceof Uint16Array) { 145 pixels = new Uint16Array(number_of_pixels * testcase.redpixel.length); 146 } else if (testcase.redpixel instanceof Uint32Array) { 147 pixels = new Uint32Array(number_of_pixels * testcase.redpixel.length); 148 } else if (testcase.redpixel instanceof Float32Array) { 149 pixels = new Float32Array(number_of_pixels * testcase.redpixel.length); 150 } 151 for (var i = 0; i < number_of_pixels; i++) { 152 for (var j = 0; j < testcase.redpixel.length; j++) { 153 pixels[i * testcase.redpixel.length + j] = testcase.redpixel[j]; 154 } 155 } 156 157 gl.texSubImage3D(gl.TEXTURE_2D, 158 0, 0, 0, 0, 159 texsize, texsize, texsize, 160 testcase.unsizedformat, testcase.type, 161 pixels); 162 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 163 "texSubImage3D should generate INVALID_ENUM if passed TEXTURE_2D target"); 164 gl.texSubImage3D(gl.TEXTURE_3D, 165 0, 0, 0, 0, 166 texsize, texsize, texsize, 167 testcase.unsizedformat, testcase.type, 168 pixels); 169 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, 170 "texSubImage3D should fail if texStorage3D has not succeeded"); 171 172 // OK, now let's finally do the successfull texStorage3D call 173 gl.texStorage3D(gl.TEXTURE_3D, levels, testcase.sizedformat, 174 texsize, texsize, texsize); 175 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texStorage3D should succeed with a good sized internalformat"); 176 177 // Subsequent texStorage3D calls should fail, even identical ones. 178 gl.texStorage3D(gl.TEXTURE_3D, levels, testcase.sizedformat, 179 texsize, texsize, texsize); 180 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texStorage3D should fail on immutable-format texture"); 181 182 var s = texsize; 183 for (var l = 0; l < levels; l++) { 184 gl.texSubImage3D(gl.TEXTURE_3D, 185 l, 0, 0, 0, 186 s, s, s, 187 testcase.unsizedformat, testcase.type, 188 pixels); 189 s /= 2; 190 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage3D should succeed on immutable texture as long as the format is compatible"); 191 } 192 gl.texSubImage3D(gl.TEXTURE_3D, 193 levels, 0, 0, 0, 194 texsize, texsize, texsize, 195 testcase.unsizedformat, testcase.type, 196 pixels); 197 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage3D should fail for too-high level"); 198 gl.texSubImage3D(gl.TEXTURE_3D, 199 0, 1, 0, 0, 200 texsize, texsize, texsize, 201 testcase.unsizedformat, testcase.type, 202 pixels); 203 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texSubImage3D should fail for dimension out of range"); 204 }); 205 206 debug(""); 207 debug("Test non-square images:"); 208 const levels = 4; 209 const maxSize = 1 << (levels-1); 210 211 function expectOk(target, x,y,z, err) { 212 debug("(target=" + target + ", size=[" + ([x,y,z].join(', ')) + "])"); 213 const tex = gl.createTexture(); 214 gl.bindTexture(gl[target], tex); 215 gl.texStorage3D(gl[target], levels+1, gl.RGBA8, x, y, z); 216 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "levels=levels+1"); 217 218 gl.texStorage3D(gl[target], levels, gl.RGBA8, x, y, z); 219 wtu.glErrorShouldBe(gl, gl[err], "levels=levels"); 220 gl.deleteTexture(tex); 221 } 222 expectOk("TEXTURE_3D", maxSize, maxSize, maxSize, "NO_ERROR"); 223 expectOk("TEXTURE_3D", maxSize, maxSize, 1, "NO_ERROR"); 224 expectOk("TEXTURE_3D", maxSize, 1, maxSize, "NO_ERROR"); 225 expectOk("TEXTURE_3D", maxSize, 1, 1, "NO_ERROR"); 226 expectOk("TEXTURE_3D", 1, maxSize, maxSize, "NO_ERROR"); 227 expectOk("TEXTURE_3D", 1, maxSize, 1, "NO_ERROR"); 228 expectOk("TEXTURE_3D", 1, 1, maxSize, "NO_ERROR"); 229 230 expectOk("TEXTURE_2D_ARRAY", maxSize, maxSize, 10, "NO_ERROR"); 231 expectOk("TEXTURE_2D_ARRAY", maxSize, 1, 10, "NO_ERROR"); 232 expectOk("TEXTURE_2D_ARRAY", 1, maxSize, 10, "NO_ERROR"); 233 expectOk("TEXTURE_2D_ARRAY", 1, 1, 10, "INVALID_OPERATION"); 234 } 235 236 debug(""); 237 var successfullyParsed = true; 238 </script> 239 <script src="../../../js/js-test-post.js"></script> 240 241 </body> 242 </html>