views-with-offsets.html (8788B)
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 <link rel="stylesheet" href="../../resources/js-test-style.css"/> 12 <script src="../../js/js-test-pre.js"></script> 13 <script src="../../js/desktop-gl-constants.js"></script> 14 <script src="../../js/webgl-test-utils.js"></script> 15 </head> 16 <body> 17 <div id="description"></div> 18 <div id="console"></div> 19 20 <script> 21 "use strict"; 22 description("Tests texture uploads with ArrayBufferView+offsets"); 23 24 var wtu = WebGLTestUtils; 25 var gl = wtu.create3DContext(null, undefined, 2); 26 console.log(gl.getParameter(gl.VERSION)); 27 28 //// 29 30 function arrToStr(arr) { 31 return "[" + arr.map(x => x.toString()).join(", ") + "]"; 32 } 33 34 function shouldBeWas(shouldBe, was, info) { 35 var text = "Should be " + shouldBe + ", was " + was + "."; 36 if (info) { 37 text = info + ": " + text; 38 } 39 40 if (shouldBe == was) { 41 testPassed(text); 42 return true; 43 } else { 44 testFailed(text); 45 return false; 46 } 47 } 48 49 function shouldBeWasArr(shouldBe, was, info) { 50 if (shouldBe.length != was.length) { 51 testFailed("Length should be " + shouldBe.length + ", was " + was.length + "."); 52 return false; 53 } 54 55 return shouldBeWas(arrToStr(shouldBe), arrToStr(was), info); 56 } 57 58 //// 59 60 // Textures 61 62 var fibArr = [ 63 0, 1, 1, 2, 64 3, 5, 8, 13, 65 21, 34, 55, 89, 66 144, 233, 67 ]; 68 69 var fb = gl.createFramebuffer(); 70 71 function probeWithBadOffset(fnTest, info) { 72 fnTest(+(-1|0)); 73 if (!gl.getError()) { 74 testFailed("Does not support " + info + " with offsets into views."); 75 return false; 76 } 77 return true; 78 } 79 80 // fn(view, offset, expectedError, expectedResult) 81 82 do { 83 var readPixelView = new Uint8Array(4); 84 var testView = new Uint8Array(fibArr); 85 86 function testTexOrSubImage(funcName, fnTexOrSubImage) { 87 debug(""); 88 debug(funcName); 89 90 var fnProbe = function(viewOffset) { 91 fnTexOrSubImage(gl.RGBA, gl.UNSIGNED_BYTE, testView, viewOffset); 92 }; 93 94 if (!probeWithBadOffset(fnProbe, funcName)) 95 return; 96 97 for (var i = 0; i <= testView.length+1; i++) { 98 debug("offset=" + i); 99 100 fnTexOrSubImage(gl.RGBA, gl.UNSIGNED_BYTE, testView, i); 101 102 var effectiveViewLen = testView.length - i; 103 104 if (effectiveViewLen >= 4) { 105 wtu.glErrorShouldBe(gl, gl.NO_ERROR); 106 107 gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, readPixelView); 108 wtu.glErrorShouldBe(gl, gl.NO_ERROR); 109 shouldBeWasArr(testView.slice(i, i+4), readPixelView); 110 111 } else { 112 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION); 113 } 114 } 115 116 debug(""); 117 118 var yellow565 = (0x1f << 11) | (0x3f << 5); 119 var cyan565 = (0x3f << 5) | 0x1f; 120 var arr565 = [yellow565, cyan565]; 121 var view565 = new Uint16Array(arr565); 122 123 function rgb888to565(arr888) { 124 return ((arr888[0] >> 3) << 11) | ((arr888[1] >> 2) << 5) | (arr888[2] >> 3); 125 } 126 127 for (var i = 0; i <= arr565.length+1; i++) { 128 debug("rgb565, offset=" + i); 129 130 fnTexOrSubImage(gl.RGB, gl.UNSIGNED_SHORT_5_6_5, view565, i); 131 132 var effectiveViewLen = arr565.length - i; 133 134 if (effectiveViewLen >= 1) { 135 wtu.glErrorShouldBe(gl, gl.NO_ERROR); 136 137 gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, readPixelView); 138 debug(arrToStr(readPixelView)); 139 wtu.glErrorShouldBe(gl, gl.NO_ERROR); 140 shouldBeWas(arr565[i], rgb888to565(readPixelView)); 141 142 } else { 143 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION); 144 } 145 } 146 } 147 148 var fn2D = function(format, type, view, viewOffset) { 149 gl.texImage2D(gl.TEXTURE_2D, 0, format, 1, 1, 0, format, type, view, viewOffset); 150 } 151 152 var fnSub2D = function(format, type, view, viewOffset) { 153 gl.texImage2D(gl.TEXTURE_2D, 0, format, 1, 1, 0, format, type, null); 154 gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, format, type, view, viewOffset); 155 } 156 157 var fn3D = function(format, type, view, viewOffset) { 158 gl.texImage3D(gl.TEXTURE_3D, 0, format, 1, 1, 1, 0, format, type, view, viewOffset); 159 } 160 161 var fnSub3D = function(format, type, view, viewOffset) { 162 gl.texImage3D(gl.TEXTURE_3D, 0, format, 1, 1, 1, 0, format, type, null); 163 gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, format, type, view, viewOffset); 164 } 165 166 //// 167 168 var tex2d = gl.createTexture(); 169 gl.bindTexture(gl.TEXTURE_2D, tex2d); 170 171 gl.bindFramebuffer(gl.FRAMEBUFFER, fb); 172 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex2d, 0); 173 174 testTexOrSubImage("texImage2D", fn2D); 175 testTexOrSubImage("texSubImage2D", fnSub2D); 176 177 //// 178 179 var tex3d = gl.createTexture(); 180 gl.bindTexture(gl.TEXTURE_3D, tex3d); 181 gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 1, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 182 183 gl.bindFramebuffer(gl.FRAMEBUFFER, fb); 184 gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex3d, 0, 0); 185 186 testTexOrSubImage("texImage3D", fn3D); 187 testTexOrSubImage("texSubImage3D", fnSub3D); 188 } while (false); 189 190 191 do { 192 var compressedFormat = 0; 193 var compressedByteCount; 194 195 if (gl.getExtension("WEBGL_compressed_texture_s3tc")) { 196 var e = gl.getExtension("WEBGL_compressed_texture_s3tc"); 197 compressedFormat = e.COMPRESSED_RGB_S3TC_DXT1_EXT; 198 compressedByteCount = 8; 199 } else if (gl.getExtension("WEBGL_compressed_texture_etc")) { 200 var e = gl.getExtension("WEBGL_compressed_texture_etc"); 201 compressedFormat = e.COMPRESSED_RGB8_ETC2; 202 compressedByteCount = 8; 203 } else { 204 debug("No compressed texture format found. Skipping compressedTex(Sub)Image tests."); 205 break; 206 } 207 208 //// 209 210 var view = new Uint8Array(compressedByteCount+1); 211 212 var fn2D = function(viewOffset) { 213 gl.compressedTexImage2D(gl.TEXTURE_2D, 0, compressedFormat, 4, 4, 0, 214 view, viewOffset, compressedByteCount); 215 }; 216 217 var fnSub2D = function(viewOffset) { 218 gl.compressedTexImage2D(gl.TEXTURE_2D, 0, compressedFormat, 4, 4, 0, 219 view, 0, compressedByteCount); 220 gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 4, 4, compressedFormat, 221 view, viewOffset, compressedByteCount); 222 }; 223 224 var fn3D = function(viewOffset) { 225 gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, compressedFormat, 4, 4, 1, 0, 226 view, viewOffset, compressedByteCount); 227 }; 228 229 var fnSub3D = function(viewOffset) { 230 gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, compressedFormat, 4, 4, 1, 0, 231 view, 0, compressedByteCount); 232 gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, 4, 4, 1, compressedFormat, 233 view, viewOffset, compressedByteCount); 234 }; 235 236 //// 237 238 var testFunc = function(funcName, fnToTest) { 239 debug(""); 240 debug(funcName); 241 242 if (!probeWithBadOffset(fnToTest, funcName)) 243 return; 244 245 var viewLength = view.length; 246 var subViewLength = compressedByteCount; 247 248 for (var i = 0; i <= viewLength+1; i++) { 249 debug("offset=" + i); 250 251 fnToTest(i); 252 var effectiveViewLen = viewLength - i; 253 254 if (effectiveViewLen >= subViewLength) { 255 wtu.glErrorShouldBe(gl, gl.NO_ERROR); 256 257 } else { 258 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE); 259 } 260 } 261 }; 262 263 var tex2d = gl.createTexture(); 264 gl.bindTexture(gl.TEXTURE_2D, tex2d); 265 testFunc("compressedTexImage2D" , fn2D ); 266 testFunc("compressedTexSubImage2D", fnSub2D); 267 268 var tex3d = gl.createTexture(); 269 gl.bindTexture(gl.TEXTURE_2D_ARRAY, tex3d); 270 testFunc("compressedTexImage3D" , fn3D ); 271 testFunc("compressedTexSubImage3D", fnSub3D); 272 } while (false); 273 274 do { 275 debug(""); 276 debug("readPixels"); 277 278 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 279 280 var testColor = [10, 20, 30, 40]; 281 gl.clearColor(testColor[0]/255.0, 282 testColor[1]/255.0, 283 testColor[2]/255.0, 284 testColor[3]/255.0); 285 gl.clear(gl.COLOR_BUFFER_BIT); 286 var readPixelView = new Uint8Array(6); 287 288 function doReadPixels(viewOffset) { 289 gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, readPixelView, viewOffset); 290 return readPixelView; 291 } 292 293 if (!probeWithBadOffset(doReadPixels, "doReadPixels")) 294 break; 295 296 for (var i = 0; i <= readPixelView.length+1; i++) { 297 debug("offset=" + i); 298 var res = doReadPixels(i); 299 var effectiveViewLen = readPixelView.length - i; 300 301 if (effectiveViewLen >= 4) { 302 wtu.glErrorShouldBe(gl, gl.NO_ERROR); 303 shouldBeWasArr(testColor, res.slice(i,i+4)); 304 305 } else if (effectiveViewLen >= 0) { 306 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION); 307 308 } else { 309 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE); 310 } 311 } 312 } while (false); 313 314 debug("") 315 var successfullyParsed = true; 316 </script> 317 318 <script src="../../js/js-test-post.js"></script> 319 </body> 320 </html>