copy-texture-image-webgl-specific.html (10851B)
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>WebGL CopyTexImage Tests</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 <canvas id="example" width="2" height="2"></canvas> 18 <div id="description"></div> 19 <div id="console"></div> 20 <script> 21 "use strict"; 22 23 var wtu = WebGLTestUtils; 24 description("This test verifies the functionality of copyTexImage."); 25 26 var gl = wtu.create3DContext("example", undefined, 2); 27 28 function copytexsubimage3d_invalid_operation_feedbackloops() { 29 debug(""); 30 debug("Testing copytexsubimage3d_invalid_operation_feedbackloops"); 31 var texture = gl.createTexture(); 32 gl.bindTexture(gl.TEXTURE_3D, texture); 33 var uint8 = new Uint8Array(32); 34 var layer = 0; 35 var width = 2; 36 var height = 2; 37 var depth = 2; 38 gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8); 39 40 var fbo = gl.createFramebuffer(); 41 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 42 gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture, 0, layer); 43 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) { 44 gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, 0, layer, 0, 0, width, height); 45 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "gl.INVALID_OPERATION is generated"); 46 } else { 47 testFailed("framebuffer not complete"); 48 } 49 50 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 51 gl.deleteFramebuffer(fbo); 52 gl.deleteTexture(texture); 53 }; 54 55 function copytexsubimage3d_valid_operation_diff_level() { 56 debug(""); 57 debug("Testing copytexsubimage3d_valid_operation_diff_level"); 58 var texture = gl.createTexture(); 59 gl.bindTexture(gl.TEXTURE_3D, texture); 60 var uint8 = new Uint8Array(32); 61 var level1 = 0; 62 var level2 = 1; 63 var width = 2; 64 var height = 2; 65 var depth = 2; 66 gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8); 67 gl.generateMipmap(gl.TEXTURE_3D); 68 69 var fbo = gl.createFramebuffer(); 70 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 71 gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture, level1, 0); 72 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) { 73 gl.copyTexSubImage3D(gl.TEXTURE_3D, level2, 0, 0, 0, 0, 0, width/2, height/2); 74 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D should succeed."); 75 } else { 76 testFailed("framebuffer not complete"); 77 } 78 79 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 80 gl.deleteFramebuffer(fbo); 81 gl.deleteTexture(texture); 82 }; 83 84 function copytexsubimage3d_valid_operation_diff_layer() { 85 debug(""); 86 debug("Testing copytexsubimage3d_valid_operation_diff_layer"); 87 var texture = gl.createTexture(); 88 gl.bindTexture(gl.TEXTURE_3D, texture); 89 var uint8 = new Uint8Array(32); 90 var layer1 = 0; 91 var layer2 = 1; 92 var width = 2; 93 var height = 2; 94 var depth = 2; 95 gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8); 96 97 var fbo = gl.createFramebuffer(); 98 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 99 gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture, 0, layer1); 100 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) { 101 gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, 0, layer2, 0, 0, width, height); 102 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D should succeed."); 103 } else { 104 testFailed("framebuffer not complete"); 105 } 106 107 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 108 gl.deleteFramebuffer(fbo); 109 gl.deleteTexture(texture); 110 } 111 112 function copytexsubimage3d_texture_wrongly_initialized() { 113 debug(""); 114 debug("Testing copytexsubimage3d_texture_wrongly_initialized"); 115 var texture = []; 116 texture[0] = gl.createTexture(); 117 texture[1] = gl.createTexture(); 118 var layer = 0; 119 var width = 2; 120 var height = 2; 121 var depth = 2; 122 gl.bindTexture(gl.TEXTURE_2D, texture[0]); 123 var uint = new Uint8Array([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10]); 124 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint); 125 126 var fbo = gl.createFramebuffer(); 127 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 128 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture[0], 0); 129 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) { 130 gl.bindTexture(gl.TEXTURE_3D, texture[1]); 131 gl.texStorage3D(gl.TEXTURE_3D, 1, gl.RGBA8, width, height, depth); 132 gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, 0, layer, 0, 0, width, height); 133 gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture[1], 0, layer); 134 var bytes = new Uint8Array(width * height * 4); 135 gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, bytes); 136 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readpixel should succeed."); 137 for (var x = 0; x < width * height * 4; x++) { 138 if (bytes[x] != uint[x]) { 139 testFailed("byte comparison failure, byte at "+ x + " was " + bytes[x] + 140 ", should be " + uint[x]); 141 break; 142 } 143 } 144 } else { 145 testFailed("framebuffer not complete"); 146 } 147 148 gl.bindTexture(gl.TEXTURE_2D, null); 149 gl.bindTexture(gl.TEXTURE_3D, null); 150 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 151 gl.deleteFramebuffer(fbo); 152 gl.deleteTexture(texture[0]); 153 gl.deleteTexture(texture[1]); 154 }; 155 156 function copytexsubimage3d_out_of_bounds_test_helper(xx, yy, copyWidth, copyHeight) { 157 var texture = []; 158 texture[0] = gl.createTexture(); 159 texture[1] = gl.createTexture(); 160 var layer = 0; 161 var width = 2; 162 var height = 2; 163 var depth = 2; 164 var width2 = 4; 165 var height2 = 4; 166 var xoffset = 0; 167 var yoffset = 0; 168 var uint = new Uint8Array(width * height * 4); 169 for (var i = 0; i < uint.length; i++) { 170 uint[i] = 0x01; 171 } 172 var uint2 = new Uint8Array(width2 * height2 * depth * 4); 173 for (var i = 0; i < uint2.length; i++) { 174 uint2[i] = 0xFF; 175 } 176 177 var fbo = gl.createFramebuffer(); 178 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 179 180 gl.bindTexture(gl.TEXTURE_2D, texture[0]); 181 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint); 182 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture[0], 0); 183 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) { 184 gl.bindTexture(gl.TEXTURE_3D, texture[1]); 185 gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, width2, height2, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint2); 186 gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, xoffset, yoffset, layer, xx, yy, copyWidth, copyHeight); 187 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "using copyTexSubImage3D: x = " + xx + ", y = " + yy + " width = " + copyWidth + ", height = " + copyHeight); 188 189 gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture[1], 0, layer); 190 var bytes = new Uint8Array(width2 * height2 * 4); 191 gl.readPixels(0, 0, width2, height2, gl.RGBA, gl.UNSIGNED_BYTE, bytes); 192 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readpixel should succeed."); 193 194 var sourceX = new Object(); 195 var sourceY = new Object(); 196 Clip(xx, copyWidth, width, sourceX); 197 Clip(yy, copyHeight, height, sourceY); 198 var destX = sourceX.start - xx + xoffset; 199 var rangeX = sourceX.range; 200 var destY = sourceY.start - yy + yoffset; 201 var rangeY = sourceY.range; 202 for (var y = 0; y < height2; y++) { 203 for (var x = 0; x < width2 * 4; x++) { 204 var current = y * height2 * 4 + x; 205 // pixels copied from read framebuffer should be 0x01 206 if (x >= destX * 4 && x < (destX + rangeX) * 4 && y >= destY && y < destY + rangeY) { 207 if (bytes[current] != 0x01) { 208 testFailed("byte comparison failure, byte at "+ (current) + " was " + 209 bytes[current] +", should be 1"); 210 break; 211 } 212 // pixels out-of-bounds should be untouched 213 } else { 214 if (bytes[current] != 0xFF) { 215 testFailed("byte comparison failure, byte at "+ (current) + " was " + 216 bytes[current] + ", should be 255"); 217 break; 218 } 219 } 220 } 221 // Test failed; abort 222 if (x < width2 * 4) { 223 break; 224 } 225 } 226 } else { 227 testFailed("framebuffer not complete"); 228 } 229 230 gl.bindTexture(gl.TEXTURE_2D, null); 231 gl.bindTexture(gl.TEXTURE_3D, null); 232 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 233 gl.deleteFramebuffer(fbo); 234 gl.deleteTexture(texture[0]); 235 gl.deleteTexture(texture[1]); 236 } 237 238 function copytexsubimage3d_out_of_bounds() { 239 debug(""); 240 debug("Test pixels outside of read framebuffer for CopyTexSubImage3D"); 241 242 for(var i=0; i < testlist.length; i++) { 243 copytexsubimage3d_out_of_bounds_test_helper(testlist[i][0], testlist[i][1], testlist[i][2], testlist[i][3]); 244 } 245 }; 246 247 /** 248 * This array defines some copy areas for CopyTexSubImage3D. 249 * A copy area is defined by x coordinate, y coordinate, copyWidth and copyHeight. 250 * the source read framebuffer is (0, 0, 2, 2). 251 */ 252 var testlist = [ 253 [-1, -1, 4, 4], 254 255 [0, 0, 3, 3], 256 [-1, -1, 3, 3], 257 [-1, 0, 3, 3], 258 [0, -1, 3, 3], 259 260 [0, 0, 2, 3], 261 [0, 0, 3, 2], 262 [-1, 0, 3, 2], 263 [0, -1, 2, 3], 264 265 [-2, -2, 3, 3], 266 [-2, 1, 3, 3], 267 [1, -2, 3, 3], 268 [1, 1, 3, 3], 269 270 [2 , 2 ,3, 3] 271 ]; 272 273 274 function Clip(start, range, sourceRange, target) { 275 if (start < 0) { 276 range += start; 277 start = 0; 278 } 279 var end = start + range; 280 if(end > sourceRange) { 281 range -= end - sourceRange; 282 } 283 target.start = start; 284 target.range = range; 285 } 286 287 if (!gl) { 288 testFailed("WebGL context does not exist"); 289 } else { 290 testPassed("WebGL context exists"); 291 copytexsubimage3d_invalid_operation_feedbackloops(); 292 copytexsubimage3d_valid_operation_diff_level(); 293 copytexsubimage3d_valid_operation_diff_layer(); 294 copytexsubimage3d_texture_wrongly_initialized(); 295 copytexsubimage3d_out_of_bounds(); 296 } 297 298 var successfullyParsed = true; 299 </script> 300 <script src="../../../js/js-test-post.js"></script> 301 302 </body> 303 </html>