read-pixels-from-fbo-test.html (19541B)
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 2 ReadPixels 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 <div id="console"></div> 19 <script> 20 "use strict"; 21 description("Checks that ReadPixels from a fbo works as expected."); 22 23 var wtu = WebGLTestUtils; 24 var gl = wtu.create3DContext(undefined, undefined, 2); 25 gl.pixelStorei(gl.PACK_ALIGNMENT, 1); 26 27 function getChannelCount(format) { 28 switch (format) { 29 case gl.RED: 30 case gl.RED_INTEGER: 31 case gl.ALPHA: 32 case gl.LUMINANCE: 33 return 1; 34 case gl.RB: 35 case gl.RB_INTEGER: 36 case gl.LUMINANCE_ALPHA: 37 return 2; 38 case gl.RGB: 39 case gl.RGB_INTEGER: 40 return 3; 41 case gl.RGBA: 42 case gl.RGBA_INTEGER: 43 return 4; 44 default: 45 return 0; 46 } 47 } 48 49 function getUnpackInfo(type) { 50 switch (type) { 51 case gl.UNSIGNED_SHORT_5_6_5: 52 return {bitsCount: [5, 6, 5], isReverse: false}; 53 case gl.UNSIGNED_SHORT_4_4_4_4: 54 return {bitsCount: [4, 4, 4, 4], isReverse: false}; 55 case gl.UNSIGNED_SHORT_5_5_5_1: 56 return {bitsCount: [5, 5, 5, 1], isReverse: false}; 57 case gl.UNSIGNED_INT_2_10_10_10_REV: 58 return {bitsCount: [2, 10, 10, 10], isReverse: true}; 59 case gl.UNSIGNED_INT_10F_11F_11F_REV: 60 return {bitsCount: [10, 11, 11], isReverse: true}; 61 case gl.UNSIGNED_INT_5_9_9_9_REV: 62 return {bitsCount: [5, 9, 9, 9], isReverse: true}; 63 default: 64 return null; 65 } 66 } 67 68 // bitsCount is an array contains bit count for each component. 69 function unpack(value, channelCount, bitsCount, isReverse) { 70 var result = new Array(channelCount); 71 72 var accumBitsCount = 0; 73 for (var i = channelCount - 1; i >= 0; --i) { 74 var currentChannel = isReverse ? (channelCount - i - 1) : i; 75 var mask = 0xFFFFFFFF >>> (32 - bitsCount[i]); 76 result[currentChannel] = ((value >> accumBitsCount) & mask); 77 accumBitsCount += bitsCount[i]; 78 } 79 80 return result; 81 } 82 83 function getColor(buf, index, readFormat, readType) { 84 var channelCount = getChannelCount(readFormat); 85 var result = new Array(channelCount); 86 87 var unpackInfo = getUnpackInfo(readType); 88 if (unpackInfo) { 89 result = unpack(buf[index], channelCount, unpackInfo.bitsCount, unpackInfo.isReverse); 90 } else { 91 for (var i = 0; i < channelCount; ++i) { 92 result[i] = buf[index + i]; 93 } 94 } 95 96 return result; 97 } 98 99 function convertToSRGB(val) { 100 if (val <= 0) { 101 return 0; 102 } else if (val < 0.0031308) { 103 return 12.92 * val; 104 } else if (val < 1) { 105 return 1.055 * Math.pow(val, 0.41666) - 0.055; 106 } else { 107 return 1; 108 } 109 } 110 111 function denormalizeColor(srcInternalFormat, destType, color) { 112 var result = color.slice(); 113 var tol = 0; 114 115 var srcIsNormalized = false; 116 117 switch (srcInternalFormat) { 118 case gl.R8: 119 case gl.RG8: 120 case gl.RGB8: 121 case gl.RGBA8: 122 case gl.RGB5_A1: 123 case gl.SRGB8_ALPHA8: 124 case gl.RGB10_A2: 125 srcIsNormalized = true; 126 tol = 6; 127 break; 128 case gl.RGB565: 129 // RGB565 needs slightly extra tolerance, at least on Google Pixel. crbug.com/682753 130 srcIsNormalized = true; 131 tol = 7; 132 break; 133 case gl.RGBA4: 134 srcIsNormalized = true; 135 tol = 10; 136 break; 137 } 138 139 if (!srcIsNormalized) { 140 return { color: result, tol: tol }; 141 } 142 143 if (srcInternalFormat == gl.SRGB8_ALPHA8) { 144 for (var i = 0; i < 3; ++i) { 145 result[i] = convertToSRGB(result[i]); 146 } 147 } 148 149 switch (destType) { 150 case gl.UNSIGNED_BYTE: 151 result = result.map(val => { return val * 0xFF}); 152 break; 153 case gl.UNSIGNED_SHORT: 154 // On Linux NVIDIA, tol of 33 is necessary to pass the test. 155 tol = 40; 156 result = result.map(val => { return val * 0xFFFF}); 157 break; 158 case gl.UNSIGNED_INT: 159 tol = 40; 160 result = result.map(val => { return val * 0xFFFFFFFF}); 161 break; 162 case gl.UNSIGNED_SHORT_4_4_4_4: 163 result = result.map(val => { return val * 0xF}); 164 break; 165 case gl.UNSIGNED_SHORT_5_5_5_1: 166 result[0] = result[0] * 0x1F; 167 result[1] = result[1] * 0x1F; 168 result[2] = result[2] * 0x1F; 169 result[3] = result[3] * 0x1; 170 break; 171 case gl.UNSIGNED_SHORT_5_6_5: 172 result[0] = result[0] * 0x1F; 173 result[1] = result[1] * 0x3F; 174 result[2] = result[2] * 0x1F; 175 break; 176 case gl.UNSIGNED_INT_2_10_10_10_REV: 177 tol = 25; 178 result[0] = result[0] * 0x3FF; 179 result[1] = result[1] * 0x3FF; 180 result[2] = result[2] * 0x3FF; 181 result[3] = result[3] * 0x3; 182 break; 183 case gl.UNSIGNED_INT_5_9_9_9_REV: 184 result[0] = result[0] * 0x1FF; 185 result[1] = result[1] * 0x1FF; 186 result[2] = result[2] * 0x1FF; 187 result[3] = result[3] * 0x1F; 188 break; 189 } 190 191 return { color: result, tol: tol }; 192 } 193 194 function compareColor(buf, index, expectedColor, srcInternalFormat, 195 srcFormat, srcType, readFormat, readType) { 196 var srcChannelCount = getChannelCount(srcFormat); 197 var readChannelCount = getChannelCount(readFormat); 198 199 var color = getColor(buf, index, readFormat, readType); 200 expectedColor = denormalizeColor(srcInternalFormat, readType, expectedColor); 201 202 var minChannel = Math.min(srcChannelCount, readChannelCount); 203 for (var i = 0; i < minChannel; ++i) { 204 if (Math.abs(expectedColor.color[i] - color[i]) > expectedColor.tol) { 205 testFailed("Expected color = " + expectedColor.color + ", was = " + color); 206 return false; 207 } 208 } 209 210 return true; 211 } 212 213 var textureTestCases = [ 214 { 215 texInternalFormat: 'R8', texFormat: 'RED', texType: 'UNSIGNED_BYTE', 216 readFormat: 'RGBA', readType: 'UNSIGNED_BYTE', 217 clearColor: [0.5, 0.0, 0.0, 0], 218 }, 219 { 220 texInternalFormat: 'R8UI', texFormat: 'RED_INTEGER', texType: 'UNSIGNED_BYTE', 221 readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT', 222 clearColor: [250, 0, 0, 0], 223 }, 224 { 225 texInternalFormat: 'R8I', texFormat: 'RED_INTEGER', texType: 'BYTE', 226 readFormat: 'RGBA_INTEGER', readType: 'INT', 227 clearColor: [-126, 0, 0, 0], 228 }, 229 { 230 texInternalFormat: 'R16UI', texFormat: 'RED_INTEGER', texType: 'UNSIGNED_SHORT', 231 readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT', 232 clearColor: [30001, 0, 0, 0], 233 }, 234 { 235 texInternalFormat: 'R16I', texFormat: 'RED_INTEGER', texType: 'SHORT', 236 readFormat: 'RGBA_INTEGER', readType: 'INT', 237 clearColor: [-14189, 0, 0, 0], 238 }, 239 { 240 texInternalFormat: 'R32UI', texFormat: 'RED_INTEGER', texType: 'UNSIGNED_INT', 241 readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT', 242 clearColor: [126726, 0, 0, 0], 243 }, 244 { 245 texInternalFormat: 'R32I', texFormat: 'RED_INTEGER', texType: 'INT', 246 readFormat: 'RGBA_INTEGER', readType: 'INT', 247 clearColor: [-126726, 0, 0, 0], 248 }, 249 250 { 251 texInternalFormat: 'RG8', texFormat: 'RG', texType: 'UNSIGNED_BYTE', 252 readFormat: 'RGBA', readType: 'UNSIGNED_BYTE', 253 clearColor: [0.5, 0.7, 0.0, 0], 254 }, 255 { 256 texInternalFormat: 'RG8UI', texFormat: 'RG_INTEGER', texType: 'UNSIGNED_BYTE', 257 readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT', 258 clearColor: [250, 124, 0, 0], 259 }, 260 { 261 texInternalFormat: 'RG8I', texFormat: 'RG_INTEGER', texType: 'BYTE', 262 readFormat: 'RGBA_INTEGER', readType: 'INT', 263 clearColor: [-55, 124, 0, 0], 264 }, 265 { 266 texInternalFormat: 'RG16UI', texFormat: 'RG_INTEGER', texType: 'UNSIGNED_SHORT', 267 readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT', 268 clearColor: [30001, 18, 0, 0], 269 }, 270 { 271 texInternalFormat: 'RG16I', texFormat: 'RG_INTEGER', texType: 'SHORT', 272 readFormat: 'RGBA_INTEGER', readType: 'INT', 273 clearColor: [-14189, 6735, 0, 0], 274 }, 275 { 276 texInternalFormat: 'RG32UI', texFormat: 'RG_INTEGER', texType: 'UNSIGNED_INT', 277 readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT', 278 clearColor: [126726, 1976, 0, 0], 279 }, 280 { 281 texInternalFormat: 'RG32I', texFormat: 'RG_INTEGER', texType: 'INT', 282 readFormat: 'RGBA_INTEGER', readType: 'INT', 283 clearColor: [-126726, 126726, 0, 0], 284 }, 285 286 { 287 texInternalFormat: 'RGB8', texFormat: 'RGB', texType: 'UNSIGNED_BYTE', 288 readFormat: 'RGBA', readType: 'UNSIGNED_BYTE', 289 clearColor: [0.5, 1, 0, 0], 290 }, 291 { 292 texInternalFormat: 'RGB565', texFormat: 'RGB', texType: 'UNSIGNED_BYTE', 293 readFormat: 'RGBA', readType: 'UNSIGNED_BYTE', 294 clearColor: [0.5, 0.7, 0.2, 0], 295 }, 296 { 297 texInternalFormat: 'RGB565', texFormat: 'RGB', texType: 'UNSIGNED_SHORT_5_6_5', 298 readFormat: 'RGBA', readType: 'UNSIGNED_BYTE', 299 clearColor: [0.5, 0.7, 0.2, 0], 300 }, 301 302 { 303 texInternalFormat: 'RGBA8', texFormat: 'RGBA', texType: 'UNSIGNED_BYTE', 304 readFormat: 'RGBA', readType: 'UNSIGNED_BYTE', 305 clearColor: [0.5, 0, 1, 0.7], 306 }, 307 { 308 texInternalFormat: 'SRGB8_ALPHA8', texFormat: 'RGBA', texType: 'UNSIGNED_BYTE', 309 readFormat: 'RGBA', readType: 'UNSIGNED_BYTE', 310 clearColor: [0.5, 0, 1, 0.7], 311 }, 312 { 313 texInternalFormat: 'RGB5_A1', texFormat: 'RGBA', texType: 'UNSIGNED_BYTE', 314 readFormat: 'RGBA', readType: 'UNSIGNED_BYTE', 315 clearColor: [0.5, 0, 0.7, 1], 316 }, 317 { 318 texInternalFormat: 'RGB5_A1', texFormat: 'RGBA', texType: 'UNSIGNED_SHORT_5_5_5_1', 319 readFormat: 'RGBA', readType: 'UNSIGNED_BYTE', 320 clearColor: [0.5, 0.7, 1, 0], 321 }, 322 { 323 texInternalFormat: 'RGB5_A1', texFormat: 'RGBA', texType: 'UNSIGNED_INT_2_10_10_10_REV', 324 readFormat: 'RGBA', readType: 'UNSIGNED_BYTE', 325 clearColor: [0.5, 0.7, 0, 1], 326 }, 327 { 328 texInternalFormat: 'RGBA4', texFormat: 'RGBA', texType: 'UNSIGNED_BYTE', 329 readFormat: 'RGBA', readType: 'UNSIGNED_BYTE', 330 clearColor: [0.5, 0.7, 1, 0], 331 }, 332 { 333 texInternalFormat: 'RGBA4', texFormat: 'RGBA', texType: 'UNSIGNED_SHORT_4_4_4_4', 334 readFormat: 'RGBA', readType: 'UNSIGNED_BYTE', 335 clearColor: [1, 0, 0.5, 0.7], 336 }, 337 { 338 texInternalFormat: 'RGBA8UI', texFormat: 'RGBA_INTEGER', texType: 'UNSIGNED_BYTE', 339 readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT', 340 clearColor: [127, 0, 255, 178], 341 }, 342 { 343 texInternalFormat: 'RGBA8I', texFormat: 'RGBA_INTEGER', texType: 'BYTE', 344 readFormat: 'RGBA_INTEGER', readType: 'INT', 345 clearColor: [-55, 56, 80, 127], 346 }, 347 { 348 texInternalFormat: 'RGB10_A2UI', texFormat: 'RGBA_INTEGER', texType: 'UNSIGNED_INT_2_10_10_10_REV', 349 readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT', 350 clearColor: [178, 0, 127, 3], 351 }, 352 { 353 texInternalFormat: 'RGBA16UI', texFormat: 'RGBA_INTEGER', texType: 'UNSIGNED_SHORT', 354 readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT', 355 clearColor: [14189, 6735, 0, 19], 356 }, 357 { 358 texInternalFormat: 'RGBA16I', texFormat: 'RGBA_INTEGER', texType: 'SHORT', 359 readFormat: 'RGBA_INTEGER', readType: 'INT', 360 clearColor: [14189, -6735, 0, 19], 361 }, 362 { 363 texInternalFormat: 'RGBA32UI', texFormat: 'RGBA_INTEGER', texType: 'UNSIGNED_INT', 364 readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT', 365 clearColor: [126726, 6726, 98765, 2015], 366 }, 367 { 368 texInternalFormat: 'RGBA32I', texFormat: 'RGBA_INTEGER', texType: 'INT', 369 readFormat: 'RGBA_INTEGER', readType: 'INT', 370 clearColor: [126726, -6726, -98765, 2015], 371 }, 372 373 { 374 texInternalFormat: 'RGB10_A2', texFormat: 'RGBA', texType: 'UNSIGNED_INT_2_10_10_10_REV', 375 readFormat: 'RGBA', readType: 'UNSIGNED_BYTE', 376 clearColor: [0.7, 0, 0.5, 1], 377 }, 378 379 // TODO(zmo): add float/half_float test cases with extension supports. 380 ]; 381 382 function getArrayTypeFromReadPixelsType(gl, type) { 383 switch (type) { 384 case gl.UNSIGNED_BYTE: 385 return Uint8Array; 386 case gl.BYTE: 387 return Int8Array; 388 case gl.UNSIGNED_SHORT: 389 case gl.UNSIGNED_SHORT_5_6_5: 390 case gl.UNSIGNED_SHORT_4_4_4_4: 391 case gl.UNSIGNED_SHORT_5_5_5_1: 392 return Uint16Array; 393 case gl.SHORT: 394 return Int16Array; 395 case gl.UNSIGNED_INT: 396 case gl.UNSIGNED_INT_2_10_10_10_REV: 397 case gl.UNSIGNED_INT_10F_11F_11F_REV: 398 case gl.UNSIGNED_INT_5_9_9_9_REV: 399 return Uint32Array; 400 case gl.INT: 401 return Int32Array; 402 case gl.HALF_FLOAT: 403 return Uint16Array; 404 case gl.FLOAT: 405 return Float32Array; 406 default: 407 return null; 408 } 409 } 410 411 function getFormatString(gl, format) { 412 switch (format) { 413 case gl.RED: 414 return 'RED'; 415 case gl.RED_INTEGER: 416 return 'RED_INTEGER'; 417 case gl.RG: 418 return 'RG'; 419 case gl.RG_INTEGER: 420 return 'RG_INTEGER'; 421 case gl.RGB: 422 return 'RGB'; 423 case gl.RGB_INTEGER: 424 return 'RGB_INTEGER'; 425 case gl.RGBA: 426 return 'RGBA'; 427 case gl.RGBA_INTEGER: 428 return 'RGBA_INTEGER'; 429 case gl.LUMINANCE: 430 return 'LUMINANCE'; 431 case gl.LUMINANCE_ALPHA: 432 return 'LUMINANCE_ALPHA'; 433 case gl.ALPHA: 434 return 'ALPHA'; 435 default: 436 return ''; 437 }; 438 } 439 440 function getTypeString(gl, type) { 441 switch (type) { 442 case gl.UNSIGNED_BYTE: 443 return 'UNSIGNED_BYTE'; 444 case gl.BYTE: 445 return 'BYTE'; 446 case gl.UNSIGNED_SHORT: 447 return 'UNSIGNED_SHORT'; 448 case gl.SHORT: 449 return 'SHORT'; 450 case gl.UNSIGNED_INT: 451 return 'UNSIGNED_INT'; 452 case gl.INT: 453 return 'INT'; 454 case gl.UNSIGNED_SHORT_5_6_5: 455 return 'UNSIGNED_SHORT_5_6_5'; 456 case gl.UNSIGNED_SHORT_5_5_5_1: 457 return 'UNSIGNED_SHORT_5_5_5_1'; 458 case gl.UNSIGNED_INT_2_10_10_10_REV: 459 return 'UNSIGNED_INT_2_10_10_10_REV'; 460 case gl.UNSIGNED_SHORT_4_4_4_4: 461 return 'UNSIGNED_SHORT_4_4_4_4'; 462 case gl.UNSIGNED_INT_10F_11F_11F_REV: 463 return 'UNSIGNED_INT_10F_11F_11F_REV'; 464 case gl.UNSIGNED_INT_5_9_9_9_REV: 465 return 'UNSIGNED_INT_5_9_9_9_REV'; 466 default: 467 return ''; 468 }; 469 } 470 471 function elementCountPerPixel(gl, readFormat, readType) { 472 switch (readFormat) { 473 case gl.RED: 474 case gl.RED_INTEGER: 475 case gl.ALPHA: 476 case gl.LUMINANCE: 477 return 1; 478 case gl.RG: 479 case gl.RG_INTEGER: 480 case gl.LUMINANCE_ALPHA: 481 return 2; 482 case gl.RGB: 483 case gl.RGB_INTEGER: 484 switch (readType) { 485 case gl.UNSIGNED_SHORT_5_6_5: 486 return 1; 487 default: 488 return 3; 489 } 490 case gl.RGBA: 491 case gl.RGBA_INTEGER: 492 switch (readType) { 493 case gl.UNSIGNED_SHORT_4_4_4_4: 494 case gl.UNSIGNED_SHORT_5_5_5_1: 495 case gl.UNSIGNED_INT_2_10_10_10_REV: 496 case gl.UNSIGNED_INT_10F_11F_11F_REV: 497 case gl.UNSIGNED_INT_5_9_9_9_REV: 498 return 1; 499 default: 500 return 4; 501 } 502 default: 503 testFailed("Unexpected read format/type = " + readFormat + "/" + readType); 504 return 0; 505 } 506 } 507 508 function testReadPixels(gl, srcInternalFormat, srcFormat, srcType, 509 readFormat, readType, expectedColor) { 510 var arrayType = getArrayTypeFromReadPixelsType(gl, readType); 511 var buf = new arrayType(width * height * 4); 512 gl.readPixels(0, 0, width, height, readFormat, readType, buf); 513 wtu.glErrorShouldBe( 514 gl, gl.NO_ERROR, "readPixels should generate no error"); 515 var diffFound = false; 516 for (var ii = 0; ii < width * height; ++ii) { 517 var offset = ii * elementCountPerPixel(gl, readFormat, readType); 518 if (!compareColor(buf, offset, expectedColor, srcInternalFormat, srcFormat, srcType, 519 readFormat, readType)) { 520 diffFound = true; 521 break; 522 } 523 } 524 if (!diffFound) { 525 testPassed("Color read back as expected"); 526 } 527 } 528 529 function clearBuffer(gl, texInternalFormat, clearColor) { 530 var value; 531 switch (texInternalFormat) { 532 case gl.R8UI: 533 case gl.R16UI: 534 case gl.R32UI: 535 case gl.RG8UI: 536 case gl.RG16UI: 537 case gl.RG32UI: 538 case gl.RGBA8UI: 539 case gl.RGBA16UI: 540 case gl.RGBA32UI: 541 case gl.RGB10_A2UI: 542 value = new Uint32Array(4); 543 for (var ii = 0; ii < 4; ++ii) 544 value[ii] = clearColor[ii]; 545 gl.clearBufferuiv(gl.COLOR, 0, value); 546 break; 547 case gl.R8I: 548 case gl.R16I: 549 case gl.R32I: 550 case gl.RG8I: 551 case gl.RG16I: 552 case gl.RG32I: 553 case gl.RGBA8I: 554 case gl.RGBA16I: 555 case gl.RGBA32I: 556 value = new Int32Array(4); 557 for (var ii = 0; ii < 4; ++ii) 558 value[ii] = clearColor[ii]; 559 gl.clearBufferiv(gl.COLOR, 0, value); 560 break; 561 default: 562 gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); 563 gl.clear(gl.COLOR_BUFFER_BIT); 564 break; 565 } 566 } 567 568 for (var tt = 0; tt < textureTestCases.length; ++tt) { 569 var test = textureTestCases[tt]; 570 debug(""); 571 debug("ReadPixels from fbo with texture = (" + test.texInternalFormat + 572 ", " + test.texFormat + ", " + test.texType + 573 "), format = " + test.readFormat + ", type = " + test.readType); 574 var width = 2; 575 var height = 2; 576 var fbo = gl.createFramebuffer(); 577 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 578 var colorImage = gl.createTexture(); 579 gl.bindTexture(gl.TEXTURE_2D, colorImage); 580 gl.texImage2D(gl.TEXTURE_2D, 0, gl[test.texInternalFormat], width, height, 0, 581 gl[test.texFormat], gl[test.texType], null); 582 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, 583 gl.TEXTURE_2D, colorImage, 0); 584 wtu.glErrorShouldBe( 585 gl, gl.NO_ERROR, "Setting up fbo should generate no error"); 586 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) { 587 debug("fbo is not complete, skip"); 588 continue; 589 } 590 clearBuffer(gl, gl[test.texInternalFormat], test.clearColor); 591 wtu.glErrorShouldBe( 592 gl, gl.NO_ERROR, "Clear color should generate no error"); 593 594 var implFormat = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT); 595 var implType = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE); 596 var implFormatString = getFormatString(gl, implFormat); 597 var implTypeString = getTypeString(gl, implType); 598 599 if (gl[test.texInternalFormat] == gl.RGB10_A2) { 600 // This is a special case where three read format/type are supported. 601 var readTypes = [gl.UNSIGNED_BYTE, gl.UNSIGNED_INT_2_10_10_10_REV]; 602 var readTypeStrings = ['UNSIGNED_BYTE', 'UNSIGNED_INT_2_10_10_10_REV']; 603 if (implFormat == gl.RGBA && implTypeString != '') { 604 readTypes.push(implType); 605 readTypeStrings.push(implTypeString); 606 } else { 607 testFailed("Unimplemented Implementation dependent color read format/type = " + 608 implFormat + "/" + implType); 609 } 610 for (var rr = 0; rr < readTypes.length; ++rr) { 611 debug("Special case RGB10_A2, format = RGBA, type = " + readTypeStrings[rr]); 612 testReadPixels(gl, gl[test.texInternalFormat], gl[test.texFormat], gl[test.texType], 613 gl.RGBA, readTypes[rr], test.clearColor); 614 } 615 } else { 616 testReadPixels(gl, gl[test.texInternalFormat], gl[test.texFormat], gl[test.texType], 617 gl[test.readFormat], gl[test.readType], test.clearColor); 618 619 debug("Testing implementation dependent color read format = " + implFormatString + 620 ", type = " + implTypeString); 621 if (implFormatString == '') { 622 testFailed("Invalid IMPLEMENTATION_COLOR_READ_FORMAT = " + implFormat); 623 continue; 624 } 625 if (implTypeString == '') { 626 testFailed("Invalid IMPLEMENTATION_COLOR_READ_TYPE = " + implType); 627 continue; 628 } 629 testReadPixels(gl, gl[test.texInternalFormat], gl[test.texFormat], gl[test.texType], 630 implFormat, implType, test.clearColor); 631 632 gl.deleteTexture(colorImage); 633 gl.deleteFramebuffer(fbo); 634 } 635 } 636 637 debug("") 638 var successfullyParsed = true; 639 </script> 640 <script src="../../js/js-test-post.js"></script> 641 </body> 642 </html>