tex-input-validation.js (16215B)
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 // This test relies on the surrounding web page defining a variable 8 // "contextVersion" which indicates what version of WebGL it's running 9 // on -- 1 for WebGL 1.0, 2 for WebGL 2.0, etc. 10 11 "use strict"; 12 description("Validate tex functions input parameters"); 13 14 var wtu = WebGLTestUtils; 15 var gl = null; 16 var tex = null; 17 var error = 0; 18 19 shouldBeNonNull("gl = wtu.create3DContext(undefined, undefined, contextVersion)"); 20 shouldBeNonNull("tex = gl.createTexture()"); 21 gl.bindTexture(gl.TEXTURE_2D, tex); 22 wtu.glErrorShouldBe(gl, gl.NO_ERROR); 23 24 function enumToString(value) { 25 return wtu.glEnumToString(gl, value); 26 } 27 28 function testTexParameter(testCase) { 29 var msg = "paramName: " + enumToString(testCase.pname); 30 error = testCase.expectedError; 31 gl.texParameteri(testCase.target, testCase.pname, testCase.param); 32 wtu.glErrorShouldBe(gl, error, msg); 33 gl.texParameterf(testCase.target, testCase.pname, testCase.param); 34 wtu.glErrorShouldBe(gl, error, msg); 35 } 36 37 function testGetTexParameter(testCase) { 38 var msg = "paramName: " + enumToString(testCase.pname); 39 error = testCase.expectedError; 40 gl.getTexParameter(testCase.target, testCase.pname); 41 wtu.glErrorShouldBe(gl, error, msg); 42 } 43 44 function testTexImage2D(testCase) { 45 var level = 0; 46 var width = 16; 47 var height = 16; 48 var msg = " internalFormat: " + enumToString(testCase.internalFormat) + 49 " target: " + enumToString(testCase.target) + 50 " format: " + enumToString(testCase.format) + 51 " type: " + enumToString(testCase.type) + 52 " border: " + testCase.border; 53 54 gl.texImage2D(testCase.target, level, testCase.internalFormat, width, height, testCase.border, testCase.format, testCase.type, null); 55 error = testCase.expectedError; 56 wtu.glErrorShouldBe(gl, error, msg); 57 } 58 59 function testTexSubImage2D(testCase) { 60 var level = 0; 61 var xoffset = 0; 62 var yoffset = 0; 63 var width = 16; 64 var height = 16; 65 var msg = " format: " + enumToString(testCase.format) + 66 " type: " + enumToString(testCase.type); 67 var array = new Uint8Array(width * height * 4); 68 69 gl.texSubImage2D(testCase.target, level, xoffset, yoffset, width, height, testCase.format, testCase.type, array); 70 error = testCase.expectedError; 71 wtu.glErrorShouldBe(gl, error, msg); 72 } 73 74 function testCopyTexImage2D(testCase) { 75 var level = 0; 76 var x = 0; 77 var y = 0; 78 var width = 16; 79 var height = 16; 80 var msg = " colorBufferFormat: " + enumToString(testCase.colorBufferFormat) + 81 " internalFormat: " + enumToString(testCase.internalFormat) + 82 " target: " + enumToString(testCase.target) + 83 " border: " + testCase.border; 84 85 gl.renderbufferStorage(gl.RENDERBUFFER, testCase.colorBufferFormat, width, height); 86 wtu.glErrorShouldBe(gl, gl.NO_ERROR); 87 shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); 88 89 gl.copyTexImage2D(testCase.target, level, testCase.internalFormat, x, y, width, height, testCase.border); 90 error = testCase.expectedError; 91 wtu.glErrorShouldBe(gl, error, msg); 92 } 93 94 function testCopyTexSubImage2D(testCase) { 95 var level = 0; 96 var x = 0; 97 var y = 0; 98 var width = 16; 99 var height = 16; 100 var xoffset = 0; 101 var yoffset = 0; 102 var border = 0; 103 var type = gl.UNSIGNED_BYTE; 104 var msg = " colorBufferFormat: " + enumToString(testCase.colorBufferFormat) + 105 " internalFormat: " + enumToString(testCase.internalFormat) + 106 " target: " + enumToString(testCase.target); 107 108 gl.renderbufferStorage(gl.RENDERBUFFER, testCase.colorBufferFormat, width, height); 109 wtu.glErrorShouldBe(gl, gl.NO_ERROR); 110 shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); 111 112 gl.texImage2D(testCase.target, level, testCase.internalFormat, xoffset + width, yoffset + height, border, testCase.internalFormat, type, null); 113 wtu.glErrorShouldBe(gl, gl.NO_ERROR); 114 115 gl.copyTexSubImage2D(testCase.target, level, xoffset, yoffset, x, y, width, height); 116 error = testCase.expectedError; 117 wtu.glErrorShouldBe(gl, error, msg); 118 } 119 120 function testCopyFromInternalFBO(testCase) { 121 var target = gl.TEXTURE_2D; 122 var level = 0; 123 var x = 0; 124 var y = 0; 125 var width = 16; 126 var height = 16; 127 var xoffset = 0; 128 var yoffset = 0; 129 var border = 0; 130 var type = gl.UNSIGNED_BYTE; 131 var msg = " colorBufferFormat: " + enumToString(testCase.contextAlpha ? gl.RGBA : gl.RGB) + 132 " internalFormat: " + enumToString(testCase.internalFormat); 133 134 if (testCase.contextAlpha) { 135 gl = wtu.create3DContext(null, { alpha: true }, contextVersion); 136 } else { 137 gl = wtu.create3DContext(null, { alpha: false }, contextVersion); 138 } 139 shouldBeNonNull("gl"); 140 shouldBeNonNull("tex = gl.createTexture()"); 141 gl.bindTexture(target, tex); 142 if (testCase.subImage) { 143 gl.texImage2D(target, level, testCase.internalFormat, xoffset + width, yoffset + height, border, testCase.internalFormat, type, null); 144 wtu.glErrorShouldBe(gl, gl.NO_ERROR); 145 gl.copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); 146 } else { 147 wtu.glErrorShouldBe(gl, gl.NO_ERROR); 148 gl.copyTexImage2D(target, level, testCase.internalFormat, x, y, width, height, border); 149 } 150 error = testCase.expectedError; 151 wtu.glErrorShouldBe(gl, error, msg); 152 } 153 154 // Only for WebGL2.0. 155 function testTexImage3D(testCase) { 156 var level = 0; 157 var width = 16; 158 var height = 16; 159 var depth = 16; 160 var msg = " internalFormat: " + enumToString(testCase.internalFormat) + 161 " target: " + enumToString(testCase.target) + 162 " format: " + enumToString(testCase.format) + 163 " type: " + enumToString(testCase.type) + 164 " border: " + testCase.border; 165 166 gl.texImage3D(testCase.target, level, testCase.internalFormat, width, height, depth, testCase.border, testCase.format, testCase.type, null); 167 error = testCase.expectedError; 168 wtu.glErrorShouldBe(gl, error, msg); 169 } 170 171 function testTexSubImage3D(testCase) { 172 var level = 0; 173 var xoffset = 0; 174 var yoffset = 0; 175 var zoffset = 0; 176 var width = 16; 177 var height = 16; 178 var depth = 16; 179 var msg = " format: " + enumToString(testCase.format) + 180 " type: " + enumToString(testCase.type); 181 var array = new Uint8Array(width * height * depth * 4); 182 183 gl.texSubImage3D(testCase.target, level, xoffset, yoffset, zoffset, width, height, depth, testCase.format, testCase.type, array); 184 error = testCase.expectedError; 185 wtu.glErrorShouldBe(gl, error, msg); 186 } 187 188 189 // Start checking. 190 191 debug(""); 192 debug("Checking TexParameter: a set of inputs that are valid in GL but invalid in WebGL"); 193 194 testCases = [ 195 { target: 0x0DE0, // GL_TEXTURE_1D 196 pname: gl.TEXTURE_WRAP_T, 197 param: gl.REPEAT, 198 expectedError: gl.INVALID_ENUM }, 199 { target: gl.TEXTURE_2D, 200 pname: gl.TEXTURE_WRAP_T, 201 param: 0x2900, // GL_CLAMP 202 expectedError: gl.INVALID_ENUM }, 203 { target: gl.TEXTURE_2D, 204 pname: gl.TEXTURE_WRAP_T, 205 param: gl.REPEAT, 206 expectedError: gl.NO_ERROR } 207 ]; 208 209 if (contextVersion < 2) { 210 testCases = testCases.concat([ 211 { target: gl.TEXTURE_2D, 212 pname: 0x813A, // GL_TEXTURE_MIN_LOD 213 param: 0, 214 expectedError: gl.INVALID_ENUM } 215 ]); 216 } else { 217 testCases = testCases.concat([ 218 { target: gl.TEXTURE_2D, 219 pname: 0x8E42, // GL_TEXTURE_SWIZZLE_R 220 param: 0x1903, // GL_RED 221 expectedError: gl.INVALID_ENUM }, 222 { target: gl.TEXTURE_2D, 223 pname: 0x8072, // GL_TEXTURE_WRAP_R 224 param: 0x2900, // GL_CLAMP 225 expectedError: gl.INVALID_ENUM } 226 ]); 227 } 228 229 for (var ii = 0; ii < testCases.length; ++ii) { 230 testTexParameter(testCases[ii]); 231 } 232 233 debug(""); 234 debug("Checking GetTexParameter: a set of inputs that are valid in GL but invalid in WebGL"); 235 236 testCases = [ 237 { target: 0x0DE0, // GL_TEXTURE_1D 238 pname: gl.TEXTURE_WRAP_T, 239 expectedError: gl.INVALID_ENUM }, 240 { target: gl.TEXTURE_2D, 241 pname: gl.TEXTURE_WRAP_T, 242 expectedError: gl.NO_ERROR } 243 ]; 244 245 if (contextVersion < 2) { 246 testCases = testCases.concat([ 247 { target: gl.TEXTURE_2D, 248 pname: 0x813A, // GL_TEXTURE_MIN_LOD 249 expectedError: gl.INVALID_ENUM } 250 ]); 251 } else { 252 testCases = testCases.concat([ 253 { target: gl.TEXTURE_2D, 254 pname: 0x8E42, // GL_TEXTURE_SWIZZLE_R 255 expectedError: gl.INVALID_ENUM } 256 ]); 257 } 258 259 for (var ii = 0; ii < testCases.length; ++ii) { 260 testGetTexParameter(testCases[ii]); 261 } 262 263 debug(""); 264 debug("Checking TexImage2D: a set of inputs that are valid in GL but invalid in WebGL"); 265 266 var testCases = [ 267 { target: 0x8064, // GL_PROXY_TEXTURE_2D 268 internalFormat: gl.RGBA, 269 border: 0, 270 format: gl.RGBA, 271 type: gl.UNSIGNED_BYTE, 272 expectedError: gl.INVALID_ENUM }, 273 { target: gl.TEXTURE_2D, 274 internalFormat: 0x1903, // GL_RED 275 border: 0, 276 format: 0x1903, // GL_RED 277 type: gl.UNSIGNED_BYTE, 278 expectedError: [gl.INVALID_ENUM, gl.INVALID_VALUE, gl.INVALID_OPERATION] }, 279 { target: gl.TEXTURE_2D, 280 internalFormat: gl.RGBA, 281 border: 1, 282 format: gl.RGBA, 283 type: gl.UNSIGNED_BYTE, 284 expectedError: gl.INVALID_VALUE }, 285 { target: gl.TEXTURE_2D, 286 internalFormat: gl.RGBA, 287 border: 0, 288 format: gl.RGB, 289 type: gl.UNSIGNED_BYTE, 290 expectedError: gl.INVALID_OPERATION }, 291 { target: gl.TEXTURE_2D, 292 internalFormat: gl.RGBA, 293 border: 0, 294 format: gl.RGBA, 295 type: gl.UNSIGNED_BYTE, 296 expectedError: gl.NO_ERROR } 297 ]; 298 299 if (contextVersion < 2) { 300 testCases = testCases.concat([ 301 { target: gl.TEXTURE_2D, 302 internalFormat: gl.RGBA, 303 border: 0, 304 format: gl.RGBA, 305 type: gl.BYTE, 306 expectedError: gl.INVALID_ENUM } 307 ]); 308 } else { 309 testCases = testCases.concat([ 310 { target: gl.TEXTURE_2D, 311 internalFormat: gl.RGBA, 312 border: 0, 313 format: gl.RGBA, 314 type: gl.BYTE, 315 expectedError: gl.INVALID_OPERATION }, 316 { target: gl.TEXTURE_3D, 317 internalFormat: gl.RGBA, 318 border: 0, 319 format: gl.RGBA, 320 type: gl.UNSIGNED_BYTE, 321 expectedError: gl.INVALID_ENUM } 322 ]); 323 } 324 325 for (var ii = 0; ii < testCases.length; ++ii) { 326 testTexImage2D(testCases[ii]); 327 } 328 329 debug(""); 330 debug("Checking TexSubImage2D: a set of inputs that are valid in GL but invalid in WebGL"); 331 332 testCases = [ 333 { target: gl.TEXTURE_2D, 334 format: gl.RGBA, 335 type: gl.UNSIGNED_BYTE, 336 expectedError: gl.NO_ERROR } 337 ]; 338 339 if (contextVersion < 2) { 340 testCases = testCases.concat([ 341 { target: gl.TEXTURE_2D, 342 format: 0x1903, // GL_RED 343 type: gl.UNSIGNED_BYTE, 344 expectedError: [gl.INVALID_ENUM, gl.INVALID_OPERATION] }, 345 { target: gl.TEXTURE_2D, 346 format: gl.RGBA, 347 type: gl.BYTE, 348 expectedError: [gl.INVALID_ENUM, gl.INVALID_OPERATION] } 349 ]); 350 } else { 351 testCases = testCases.concat([ 352 { target: gl.TEXTURE_2D, 353 format: gl.RED, 354 type: gl.UNSIGNED_BYTE, 355 expectedError: gl.INVALID_OPERATION }, 356 { target: gl.TEXTURE_2D, 357 format: gl.RGBA, 358 type: gl.BYTE, 359 expectedError: gl.INVALID_OPERATION }, 360 { target: gl.TEXTURE_3D, 361 format: gl.RGBA, 362 type: gl.UNSIGNED_BYTE, 363 expectedError: gl.INVALID_ENUM }, 364 ]); 365 } 366 367 for (var ii = 0; ii < testCases.length; ++ii) { 368 testTexSubImage2D(testCases[ii]); 369 } 370 371 debug(""); 372 debug("Checking CopyTexImage2D: a set of inputs that are valid in GL but invalid in WebGL"); 373 374 var colorBuffer = null; 375 var fbo = null; 376 377 shouldBeNonNull("fbo = gl.createFramebuffer()"); 378 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 379 shouldBeNonNull("colorBuffer = gl.createRenderbuffer()"); 380 gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); 381 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); 382 wtu.glErrorShouldBe(gl, gl.NO_ERROR); 383 384 testCases = [ 385 { target: gl.TEXTURE_2D, 386 colorBufferFormat: gl.RGB565, 387 internalFormat: 0x8054, // GL_RGB16 388 border: 0, 389 expectedError: gl.INVALID_ENUM }, 390 { target: gl.TEXTURE_2D, 391 colorBufferFormat: gl.RGB565, 392 internalFormat: gl.RGBA, 393 border: 1, 394 expectedError: gl.INVALID_VALUE }, 395 { target: gl.TEXTURE_2D, 396 colorBufferFormat: gl.RGB565, 397 internalFormat: gl.RGBA, 398 border: 0, 399 expectedError: gl.INVALID_OPERATION }, 400 { target: gl.TEXTURE_2D, 401 colorBufferFormat: gl.RGB565, 402 internalFormat: gl.RGB, 403 border: 0, 404 expectedError: gl.NO_ERROR } 405 ]; 406 407 if (contextVersion > 1) { 408 testCases = testCases.concat([ 409 { target: gl.TEXTURE_3D, 410 colorBufferFormat: gl.RGB5_A1, 411 internalFormat: gl.RGBA, 412 border: 0, 413 expectedError: gl.INVALID_ENUM } 414 ]); 415 } 416 417 for (var ii = 0; ii < testCases.length; ++ii) { 418 testCopyTexImage2D(testCases[ii]); 419 } 420 421 debug(""); 422 debug("Checking CopyTexSubImage2D: a set of inputs that are valid in GL but invalid in WebGL"); 423 424 testCases = [ 425 { target: gl.TEXTURE_2D, 426 colorBufferFormat: gl.RGB5_A1, 427 internalFormat: gl.RGBA, 428 expectedError: gl.NO_ERROR }, 429 { target: gl.TEXTURE_2D, 430 colorBufferFormat: gl.RGB565, 431 internalFormat: gl.RGBA, 432 expectedError: gl.INVALID_OPERATION } 433 ]; 434 435 for (var ii = 0; ii < testCases.length; ++ii) { 436 testCopyTexSubImage2D(testCases[ii]); 437 } 438 439 debug(""); 440 debug("Checking CopyTex{Sub}Image2D: copy from WebGL internal framebuffer"); 441 442 testCases = [ 443 { contextAlpha: true, 444 internalFormat: gl.RGBA, 445 subImage: false, 446 expectedError: gl.NO_ERROR }, 447 { contextAlpha: false, 448 internalFormat: gl.RGBA, 449 subImage: false, 450 expectedError: gl.INVALID_OPERATION }, 451 { contextAlpha: true, 452 internalFormat: gl.RGBA, 453 subImage: true, 454 expectedError: gl.NO_ERROR }, 455 { contextAlpha: false, 456 internalFormat: gl.RGBA, 457 subImage: true, 458 expectedError: gl.INVALID_OPERATION } 459 ]; 460 461 for (var ii = 0; ii < testCases.length; ++ii) { 462 testCopyFromInternalFBO(testCases[ii]); 463 } 464 465 if (contextVersion > 1) { 466 // Create new texture for testing api of WebGL 2.0. 467 shouldBeNonNull("tex = gl.createTexture()"); 468 gl.bindTexture(gl.TEXTURE_3D, tex); 469 wtu.glErrorShouldBe(gl, gl.NO_ERROR); 470 471 debug(""); 472 debug("Checking TexImage3D: a set of inputs that are valid in GL but invalid in WebGL"); 473 474 var testCases = [ 475 { target: 0x8070, // GL_PROXY_TEXTURE_3D 476 internalFormat: gl.RGBA, 477 border: 0, 478 format: gl.RGBA, 479 type: gl.UNSIGNED_BYTE, 480 expectedError: gl.INVALID_ENUM }, 481 { target: gl.TEXTURE_3D, 482 internalFormat: gl.RGBA, 483 border: 0, 484 format: gl.RGB, 485 type: gl.UNSIGNED_BYTE, 486 expectedError: gl.INVALID_OPERATION }, 487 { target: gl.TEXTURE_3D, 488 internalFormat: gl.RGBA, 489 border: 0, 490 format: gl.RGBA, 491 type: gl.BYTE, 492 expectedError: gl.INVALID_OPERATION}, 493 { target: gl.TEXTURE_3D, 494 internalFormat: gl.RGBA, 495 border: 0, 496 format: gl.RGBA, 497 type: gl.UNSIGNED_BYTE, 498 expectedError: gl.NO_ERROR } 499 ]; 500 501 for (var ii = 0; ii < testCases.length; ++ii) { 502 testTexImage3D(testCases[ii]); 503 } 504 505 debug(""); 506 debug("Checking TexImage3D: bad target, internalformats, formats, types"); 507 508 var testCases = [ 509 { target: gl.TEXTURE_2D, 510 internalFormat: gl.RGBA, 511 border: 0, 512 format: gl.RGBA, 513 type: gl.UNSIGNED_BYTE, 514 expectedError: gl.INVALID_ENUM }, 515 { target: gl.TEXTURE_3D, 516 internalFormat: gl.RG, 517 border: 0, 518 format: gl.RGBA, 519 type: gl.UNSIGNED_BYTE, 520 expectedError: [gl.INVALID_VALUE, gl.INVALID_OPERATION]}, 521 { target: gl.TEXTURE_3D, 522 internalFormat: gl.RGBA, 523 border: 0, 524 format: gl.RG8, 525 type: gl.UNSIGNED_BYTE, 526 expectedError: gl.INVALID_ENUM }, 527 { target: gl.TEXTURE_3D, 528 internalFormat: gl.RGBA, 529 border: 0, 530 format: gl.RGBA, 531 type: gl.INT, 532 expectedError: gl.INVALID_OPERATION}, 533 ]; 534 535 for (var ii = 0; ii < testCases.length; ++ii) { 536 testTexImage3D(testCases[ii]); 537 } 538 539 debug(""); 540 debug("Checking TexSubImage3D: a set of inputs that are valid in GL but invalid in WebGL"); 541 542 testCases = [ 543 { target: gl.TEXTURE_3D, 544 format: 0x80E0, // GL_BGR 545 type: gl.UNSIGNED_BYTE, 546 expectedError: gl.INVALID_ENUM }, 547 { target: gl.TEXTURE_3D, 548 format: gl.RGBA, 549 type: 0x8032, // GL_UNSIGNED_BYTE_3_3_2 550 expectedError: gl.INVALID_ENUM }, 551 { target: gl.TEXTURE_3D, 552 format: gl.RGBA, 553 type: gl.UNSIGNED_BYTE, 554 expectedError: gl.NO_ERROR } 555 ]; 556 557 for (var ii = 0; ii < testCases.length; ++ii) { 558 testTexSubImage3D(testCases[ii]); 559 } 560 561 } 562 563 var successfullyParsed = true;