tcuCompressedTexture.js (41508B)
1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES Utilities 3 * ------------------------------------------------ 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 */ 20 21 /*--------------------------------------------------------------------*//*! 22 * \brief Map tcu::TextureFormat to GL pixel transfer format. 23 * 24 * Maps generic texture format description to GL pixel transfer format. 25 * If no mapping is found, throws tcu::InternalError. 26 * 27 * \param texFormat Generic texture format. 28 * \return GL pixel transfer format. 29 *//*--------------------------------------------------------------------*/ 30 'use strict'; 31 goog.provide('framework.common.tcuCompressedTexture'); 32 goog.require('framework.common.tcuTexture'); 33 goog.require('framework.delibs.debase.deMath'); 34 35 goog.scope(function() { 36 37 var tcuCompressedTexture = framework.common.tcuCompressedTexture; 38 var tcuTexture = framework.common.tcuTexture; 39 var deMath = framework.delibs.debase.deMath; 40 41 var DE_ASSERT = function(x) { 42 if (!x) 43 throw new Error('Assert failed'); 44 }; 45 46 /** 47 * @enum 48 */ 49 tcuCompressedTexture.Format = { 50 ETC1_RGB8: 0, 51 EAC_R11: 1, 52 EAC_SIGNED_R11: 2, 53 EAC_RG11: 3, 54 EAC_SIGNED_RG11: 4, 55 ETC2_RGB8: 5, 56 ETC2_SRGB8: 6, 57 ETC2_RGB8_PUNCHTHROUGH_ALPHA1: 7, 58 ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: 8, 59 ETC2_EAC_RGBA8: 9, 60 ETC2_EAC_SRGB8_ALPHA8: 10, 61 62 ASTC_4x4_RGBA: 11, 63 ASTC_5x4_RGBA: 12, 64 ASTC_5x5_RGBA: 13, 65 ASTC_6x5_RGBA: 14, 66 ASTC_6x6_RGBA: 15, 67 ASTC_8x5_RGBA: 16, 68 ASTC_8x6_RGBA: 17, 69 ASTC_8x8_RGBA: 18, 70 ASTC_10x5_RGBA: 19, 71 ASTC_10x6_RGBA: 20, 72 ASTC_10x8_RGBA: 21, 73 ASTC_10x10_RGBA: 22, 74 ASTC_12x10_RGBA: 23, 75 ASTC_12x12_RGBA: 24, 76 ASTC_4x4_SRGB8_ALPHA8: 25, 77 ASTC_5x4_SRGB8_ALPHA8: 26, 78 ASTC_5x5_SRGB8_ALPHA8: 27, 79 ASTC_6x5_SRGB8_ALPHA8: 28, 80 ASTC_6x6_SRGB8_ALPHA8: 29, 81 ASTC_8x5_SRGB8_ALPHA8: 30, 82 ASTC_8x6_SRGB8_ALPHA8: 31, 83 ASTC_8x8_SRGB8_ALPHA8: 32, 84 ASTC_10x5_SRGB8_ALPHA8: 33, 85 ASTC_10x6_SRGB8_ALPHA8: 34, 86 ASTC_10x8_SRGB8_ALPHA8: 35, 87 ASTC_10x10_SRGB8_ALPHA8: 36, 88 ASTC_12x10_SRGB8_ALPHA8: 37, 89 ASTC_12x12_SRGB8_ALPHA8: 38 90 }; 91 92 tcuCompressedTexture.divRoundUp = function(a, b) { 93 return Math.floor(a / b) + ((a % b) ? 1 : 0); 94 }; 95 96 tcuCompressedTexture.isEtcFormat = function(fmt) { 97 // WebGL2 supports ETC2 and EAC formats 98 switch (fmt) { 99 // case tcuCompressedTexture.Format.ETC1_RGB8: 100 case tcuCompressedTexture.Format.EAC_R11: 101 case tcuCompressedTexture.Format.EAC_SIGNED_R11: 102 case tcuCompressedTexture.Format.EAC_RG11: 103 case tcuCompressedTexture.Format.EAC_SIGNED_RG11: 104 case tcuCompressedTexture.Format.ETC2_RGB8: 105 case tcuCompressedTexture.Format.ETC2_SRGB8: 106 case tcuCompressedTexture.Format.ETC2_RGB8_PUNCHTHROUGH_ALPHA1: 107 case tcuCompressedTexture.Format.ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: 108 case tcuCompressedTexture.Format.ETC2_EAC_RGBA8: 109 case tcuCompressedTexture.Format.ETC2_EAC_SRGB8_ALPHA8: 110 return true; 111 112 default: 113 return false; 114 } 115 }; 116 117 tcuCompressedTexture.etcDecompressInternal = function() { 118 119 var ETC2_BLOCK_WIDTH = 4; 120 var ETC2_BLOCK_HEIGHT = 4; 121 var ETC2_UNCOMPRESSED_PIXEL_SIZE_A8 = 1; 122 var ETC2_UNCOMPRESSED_PIXEL_SIZE_R11 = 2; 123 var ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11 = 4; 124 var ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8 = 3; 125 var ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8 = 4; 126 var ETC2_UNCOMPRESSED_BLOCK_SIZE_A8 = ETC2_BLOCK_WIDTH * ETC2_BLOCK_HEIGHT * ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; 127 var ETC2_UNCOMPRESSED_BLOCK_SIZE_R11 = ETC2_BLOCK_WIDTH * ETC2_BLOCK_HEIGHT * ETC2_UNCOMPRESSED_PIXEL_SIZE_R11; 128 var ETC2_UNCOMPRESSED_BLOCK_SIZE_RG11 = ETC2_BLOCK_WIDTH * ETC2_BLOCK_HEIGHT * ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11; 129 var ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8 = ETC2_BLOCK_WIDTH * ETC2_BLOCK_HEIGHT * ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8; 130 var ETC2_UNCOMPRESSED_BLOCK_SIZE_RGBA8 = ETC2_BLOCK_WIDTH * ETC2_BLOCK_HEIGHT * ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8; 131 132 /** 133 * @param {ArrayBuffer} src Source ArrayBuffer 134 * @return {Uint8Array} 135 */ 136 var get64BitBlock = function(src, blockNdx) { 137 var block = new Uint8Array(src, blockNdx * 8, 8); 138 return block; 139 }; 140 141 /** 142 * @param {ArrayBuffer} src Source ArrayBuffer 143 * Return the first 64 bits of a 128 bit block. 144 */ 145 var get128BitBlockStart = function(src, blockNdx) { 146 return get64BitBlock(src, 2 * blockNdx); 147 }; 148 149 /** 150 * @param {ArrayBuffer} src Source ArrayBuffer 151 * Return the last 64 bits of a 128 bit block. 152 */ 153 var get128BitBlockEnd = function(src, blockNdx) { 154 return get64BitBlock(src, 2 * blockNdx + 1); 155 }; 156 157 var mask8 = function(src, low, high) { 158 if (low > 7 || high < 0) 159 return { 160 value: 0, 161 bits: 0 162 }; 163 164 var numBits = high - low + 1; 165 var mask = (1 << numBits) - 1; 166 167 return { 168 value: (src >> low) & mask, 169 bits: numBits 170 }; 171 }; 172 173 var getBits64 = function(src, low, high) { 174 var result = 0; 175 var bits = 0; 176 var lowIndex = low; 177 var highIndex = high; 178 for (var i = 7; i >= 0; i--) { 179 var v = mask8(src[i], Math.max(0, lowIndex), Math.min(7, highIndex)); 180 lowIndex = lowIndex - 8; 181 highIndex = highIndex - 8; 182 result = result | (v.value << bits); 183 bits = v.bits; 184 } 185 return result; 186 }; 187 188 var getBit64 = function(src, bit) { 189 return getBits64(src, bit, bit); 190 }; 191 192 var extendSigned3To8 = function(src) { 193 var isNeg = (src & (1 << 2)) != 0; 194 var val = isNeg ? src - 8 : src; 195 return val; 196 }; 197 198 var extend4To8 = function(src) { 199 return src * 255 / 15; 200 }; 201 202 var extend5To8 = function(src) { 203 return src * 255 / 31; 204 }; 205 206 var extend6To8 = function(src) { 207 return src * 255 / 63; 208 }; 209 210 var extend7To8 = function(src) { 211 return src * 255 / 127; 212 }; 213 214 var extend11To16 = function(src) { 215 return src * 32.015144; 216 }; 217 218 var extend11To16WithSign = function(src) { 219 if (src < 0) 220 return -extend11To16(-src); 221 else 222 return extend11To16(src); 223 }; 224 225 /** 226 * @param { (Uint16Array|Int16Array) } dst 227 * @param {Uint8Array} src 228 * @param {boolean} signedMode 229 */ 230 var decompressEAC11Block = function(dst, src, signedMode) { 231 var modifierTable = [ 232 [-3, -6, -9, -15, 2, 5, 8, 14], 233 [-3, -7, -10, -13, 2, 6, 9, 12], 234 [-2, -5, -8, -13, 1, 4, 7, 12], 235 [-2, -4, -6, -13, 1, 3, 5, 12], 236 [-3, -6, -8, -12, 2, 5, 7, 11], 237 [-3, -7, -9, -11, 2, 6, 8, 10], 238 [-4, -7, -8, -11, 3, 6, 7, 10], 239 [-3, -5, -8, -11, 2, 4, 7, 10], 240 [-2, -6, -8, -10, 1, 5, 7, 9], 241 [-2, -5, -8, -10, 1, 4, 7, 9], 242 [-2, -4, -8, -10, 1, 3, 7, 9], 243 [-2, -5, -7, -10, 1, 4, 6, 9], 244 [-3, -4, -7, -10, 2, 3, 6, 9], 245 [-1, -2, -3, -10, 0, 1, 2, 9], 246 [-4, -6, -8, -9, 3, 5, 7, 8], 247 [-3, -5, -7, -9, 2, 4, 6, 8] 248 ]; 249 250 var multiplier = getBits64(src, 52, 55); 251 var tableNdx = getBits64(src, 48, 51); 252 var baseCodeword = getBits64(src, 56, 63); 253 254 if (signedMode) { 255 if (baseCodeword > 127) 256 baseCodeword -= 256; 257 if (baseCodeword == -128) 258 baseCodeword = -127; 259 } 260 261 var pixelNdx = 0; 262 for (var x = 0; x < ETC2_BLOCK_WIDTH; x++) { 263 for (var y = 0; y < ETC2_BLOCK_HEIGHT; y++) { 264 var dstOffset = (y * ETC2_BLOCK_WIDTH + x); 265 var pixelBitNdx = 45 - 3 * pixelNdx; 266 var modifierNdx = (getBit64(src, pixelBitNdx + 2) << 2) | (getBit64(src, pixelBitNdx + 1) << 1) | getBit64(src, pixelBitNdx); 267 var modifier = modifierTable[tableNdx][modifierNdx]; 268 269 if (signedMode) { 270 if (multiplier != 0) 271 dst[dstOffset] = deMath.clamp(baseCodeword * 8 + multiplier * modifier * 8, -1023, 1023); 272 else 273 dst[dstOffset] = deMath.clamp(baseCodeword * 8 + modifier, -1023, 1023); 274 } else { 275 if (multiplier != 0) 276 dst[dstOffset] = deMath.clamp(baseCodeword * 8 + 4 + multiplier * modifier * 8, 0, 2047); 277 else 278 dst[dstOffset] = deMath.clamp(baseCodeword * 8 + 4 + modifier, 0, 2047); 279 } 280 pixelNdx++; 281 } 282 } 283 }; 284 285 var decompressEAC_R11 = function(/*const tcu::PixelBufferAccess&*/ dst, width, height, src, signedMode) { 286 /** @const */ var numBlocksX = tcuCompressedTexture.divRoundUp(width, 4); 287 /** @const */ var numBlocksY = tcuCompressedTexture.divRoundUp(height, 4); 288 var dstPtr; 289 var dstRowPitch = dst.getRowPitch(); 290 var dstPixelSize = ETC2_UNCOMPRESSED_PIXEL_SIZE_R11; 291 var uncompressedBlockArray = new ArrayBuffer(ETC2_UNCOMPRESSED_BLOCK_SIZE_R11); 292 var uncompressedBlock16; 293 if (signedMode) { 294 dstPtr = new Int16Array(dst.m_data); 295 uncompressedBlock16 = new Int16Array(uncompressedBlockArray); 296 } else { 297 dstPtr = new Uint16Array(dst.m_data); 298 uncompressedBlock16 = new Uint16Array(uncompressedBlockArray); 299 } 300 301 for (var blockY = 0; blockY < numBlocksY; blockY++) { 302 for (var blockX = 0; blockX < numBlocksX; blockX++) { 303 /*const deUint64*/ var compressedBlock = get64BitBlock(src, blockY * numBlocksX + blockX); 304 305 // Decompress. 306 decompressEAC11Block(uncompressedBlock16, compressedBlock, signedMode); 307 308 // Write to dst. 309 var baseX = blockX * ETC2_BLOCK_WIDTH; 310 var baseY = blockY * ETC2_BLOCK_HEIGHT; 311 for (var y = 0; y < Math.min(ETC2_BLOCK_HEIGHT, height - baseY); y++) { 312 for (var x = 0; x < Math.min(ETC2_BLOCK_WIDTH, width - baseX); x++) { 313 DE_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_R11 == 2); 314 315 if (signedMode) { 316 var srcIndex = y * ETC2_BLOCK_WIDTH + x; 317 var dstIndex = (baseY + y) * dstRowPitch / dstPixelSize + baseX + x; 318 319 dstPtr[dstIndex] = extend11To16WithSign(uncompressedBlock16[srcIndex]); 320 } else { 321 var srcIndex = y * ETC2_BLOCK_WIDTH + x; 322 var dstIndex = (baseY + y) * dstRowPitch / dstPixelSize + baseX + x; 323 324 dstPtr[dstIndex] = extend11To16(uncompressedBlock16[srcIndex]); 325 } 326 } 327 } 328 } 329 } 330 }; 331 332 var decompressEAC_RG11 = function(/*const tcu::PixelBufferAccess&*/ dst, width, height, src, signedMode) { 333 /** @const */ var numBlocksX = tcuCompressedTexture.divRoundUp(width, 4); 334 /** @const */ var numBlocksY = tcuCompressedTexture.divRoundUp(height, 4); 335 var dstPtr; 336 var dstRowPitch = dst.getRowPitch(); 337 var dstPixelSize = ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11; 338 var uncompressedBlockArrayR = new ArrayBuffer(ETC2_UNCOMPRESSED_BLOCK_SIZE_R11); 339 var uncompressedBlockArrayG = new ArrayBuffer(ETC2_UNCOMPRESSED_BLOCK_SIZE_R11); 340 var uncompressedBlockR16; 341 var uncompressedBlockG16; 342 if (signedMode) { 343 dstPtr = new Int16Array(dst.m_data); 344 uncompressedBlockR16 = new Int16Array(uncompressedBlockArrayR); 345 uncompressedBlockG16 = new Int16Array(uncompressedBlockArrayG); 346 } else { 347 dstPtr = new Uint16Array(dst.m_data); 348 uncompressedBlockR16 = new Uint16Array(uncompressedBlockArrayR); 349 uncompressedBlockG16 = new Uint16Array(uncompressedBlockArrayG); 350 } 351 352 for (var blockY = 0; blockY < numBlocksY; blockY++) { 353 for (var blockX = 0; blockX < numBlocksX; blockX++) { 354 /*const deUint64*/ var compressedBlockR = get128BitBlockStart(src, blockY * numBlocksX + blockX); 355 /*const deUint64*/ var compressedBlockG = get128BitBlockEnd(src, blockY * numBlocksX + blockX); 356 357 // Decompress. 358 decompressEAC11Block(uncompressedBlockR16, compressedBlockR, signedMode); 359 decompressEAC11Block(uncompressedBlockG16, compressedBlockG, signedMode); 360 361 // Write to dst. 362 var baseX = blockX * ETC2_BLOCK_WIDTH; 363 var baseY = blockY * ETC2_BLOCK_HEIGHT; 364 for (var y = 0; y < Math.min(ETC2_BLOCK_HEIGHT, height - baseY); y++) { 365 for (var x = 0; x < Math.min(ETC2_BLOCK_WIDTH, width - baseX); x++) { 366 DE_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11 == 4); 367 368 if (signedMode) { 369 var srcIndex = y * ETC2_BLOCK_WIDTH + x; 370 var dstIndex = 2 * ((baseY + y) * dstRowPitch / dstPixelSize + baseX + x); 371 372 dstPtr[dstIndex] = extend11To16WithSign(uncompressedBlockR16[srcIndex]); 373 dstPtr[dstIndex + 1] = extend11To16WithSign(uncompressedBlockG16[srcIndex]); 374 } else { 375 var srcIndex = y * ETC2_BLOCK_WIDTH + x; 376 var dstIndex = 2 * ((baseY + y) * dstRowPitch / dstPixelSize + baseX + x); 377 378 dstPtr[dstIndex] = extend11To16(uncompressedBlockR16[srcIndex]); 379 dstPtr[dstIndex + 1] = extend11To16(uncompressedBlockG16[srcIndex]); 380 } 381 } 382 } 383 } 384 } 385 }; 386 387 // if alphaMode is true, do PUNCHTHROUGH and store alpha to alphaDst; otherwise do ordinary ETC2 RGB8. 388 /** 389 * @param {Uint8Array} dst Destination array 390 * @param {Uint8Array} src Source array 391 * @param {Uint8Array} alphaDst Optional Alpha output channel 392 */ 393 var decompressETC2Block = function(dst, src, alphaDst, alphaMode) { 394 /** 395 * enum 396 */ 397 var Etc2Mode = { 398 MODE_INDIVIDUAL: 0, 399 MODE_DIFFERENTIAL: 1, 400 MODE_T: 2, 401 MODE_H: 3, 402 MODE_PLANAR: 4 403 }; 404 405 var diffOpaqueBit = getBit64(src, 33); 406 var selBR = getBits64(src, 59, 63); // 5 bits. 407 var selBG = getBits64(src, 51, 55); 408 var selBB = getBits64(src, 43, 47); 409 var selDR = extendSigned3To8(getBits64(src, 56, 58)); // 3 bits. 410 var selDG = extendSigned3To8(getBits64(src, 48, 50)); 411 var selDB = extendSigned3To8(getBits64(src, 40, 42)); 412 413 var mode; 414 415 if (!alphaMode && diffOpaqueBit == 0) 416 mode = Etc2Mode.MODE_INDIVIDUAL; 417 else if (!deMath.deInRange32(selBR + selDR, 0, 31)) 418 mode = Etc2Mode.MODE_T; 419 else if (!deMath.deInRange32(selBG + selDG, 0, 31)) 420 mode = Etc2Mode.MODE_H; 421 else if (!deMath.deInRange32(selBB + selDB, 0, 31)) 422 mode = Etc2Mode.MODE_PLANAR; 423 else 424 mode = Etc2Mode.MODE_DIFFERENTIAL; 425 426 if (mode == Etc2Mode.MODE_INDIVIDUAL || mode == Etc2Mode.MODE_DIFFERENTIAL) { 427 // Individual and differential modes have some steps in common, handle them here. 428 var modifierTable = [ 429 // 00 01 10 11 430 [2, 8, -2, -8], 431 [5, 17, -5, -17], 432 [9, 29, -9, -29], 433 [13, 42, -13, -42], 434 [18, 60, -18, -60], 435 [24, 80, -24, -80], 436 [33, 106, -33, -106], 437 [47, 183, -47, -183] 438 ]; 439 440 var flipBit = getBit64(src, 32); 441 var table = [getBits64(src, 37, 39), getBits64(src, 34, 36)]; 442 var baseR = []; 443 var baseG = []; 444 var baseB = []; 445 446 if (mode == Etc2Mode.MODE_INDIVIDUAL) { 447 // Individual mode, initial values. 448 baseR[0] = extend4To8(getBits64(src, 60, 63)); 449 baseR[1] = extend4To8(getBits64(src, 56, 59)); 450 baseG[0] = extend4To8(getBits64(src, 52, 55)); 451 baseG[1] = extend4To8(getBits64(src, 48, 51)); 452 baseB[0] = extend4To8(getBits64(src, 44, 47)); 453 baseB[1] = extend4To8(getBits64(src, 40, 43)); 454 } else { 455 // Differential mode, initial values. 456 baseR[0] = extend5To8(selBR); 457 baseG[0] = extend5To8(selBG); 458 baseB[0] = extend5To8(selBB); 459 460 baseR[1] = extend5To8((selBR + selDR)); 461 baseG[1] = extend5To8((selBG + selDG)); 462 baseB[1] = extend5To8((selBB + selDB)); 463 } 464 465 // Write final pixels for individual or differential mode. 466 var pixelNdx = 0; 467 for (var x = 0; x < ETC2_BLOCK_WIDTH; x++) { 468 for (var y = 0; y < ETC2_BLOCK_HEIGHT; y++, pixelNdx++) { 469 var dstOffset = (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8; 470 var subBlock = ((flipBit ? y : x) >= 2) ? 1 : 0; 471 var tableNdx = table[subBlock]; 472 var modifierNdx = (getBit64(src, 16 + pixelNdx) << 1) | getBit64(src, pixelNdx); 473 var alphaDstOffset = (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; // Only needed for PUNCHTHROUGH version. 474 475 // If doing PUNCHTHROUGH version (alphaMode), opaque bit may affect colors. 476 if (alphaMode && diffOpaqueBit == 0 && modifierNdx == 2) { 477 dst[dstOffset + 0] = 0; 478 dst[dstOffset + 1] = 0; 479 dst[dstOffset + 2] = 0; 480 alphaDst[alphaDstOffset] = 0; 481 } else { 482 var modifier; 483 484 // PUNCHTHROUGH version and opaque bit may also affect modifiers. 485 if (alphaMode && diffOpaqueBit == 0 && (modifierNdx == 0 || modifierNdx == 2)) 486 modifier = 0; 487 else 488 modifier = modifierTable[tableNdx][modifierNdx]; 489 490 dst[dstOffset + 0] = deMath.clamp(baseR[subBlock] + modifier, 0, 255); 491 dst[dstOffset + 1] = deMath.clamp(baseG[subBlock] + modifier, 0, 255); 492 dst[dstOffset + 2] = deMath.clamp(baseB[subBlock] + modifier, 0, 255); 493 494 if (alphaMode) 495 alphaDst[alphaDstOffset] = 255; 496 } 497 } 498 } 499 } else if (mode == Etc2Mode.MODE_T || mode == Etc2Mode.MODE_H) { 500 // T and H modes have some steps in common, handle them here. 501 var distTable = [3, 6, 11, 16, 23, 32, 41, 64]; 502 503 var paintR = []; 504 var paintG = []; 505 var paintB = []; 506 507 if (mode == Etc2Mode.MODE_T) { 508 // T mode, calculate paint values. 509 var R1a = getBits64(src, 59, 60); 510 var R1b = getBits64(src, 56, 57); 511 var G1 = getBits64(src, 52, 55); 512 var B1 = getBits64(src, 48, 51); 513 var R2 = getBits64(src, 44, 47); 514 var G2 = getBits64(src, 40, 43); 515 var B2 = getBits64(src, 36, 39); 516 var distNdx = (getBits64(src, 34, 35) << 1) | getBit64(src, 32); 517 var dist = distTable[distNdx]; 518 519 paintR[0] = extend4To8((R1a << 2) | R1b); 520 paintG[0] = extend4To8(G1); 521 paintB[0] = extend4To8(B1); 522 paintR[2] = extend4To8(R2); 523 paintG[2] = extend4To8(G2); 524 paintB[2] = extend4To8(B2); 525 paintR[1] = deMath.clamp(paintR[2] + dist, 0, 255); 526 paintG[1] = deMath.clamp(paintG[2] + dist, 0, 255); 527 paintB[1] = deMath.clamp(paintB[2] + dist, 0, 255); 528 paintR[3] = deMath.clamp(paintR[2] - dist, 0, 255); 529 paintG[3] = deMath.clamp(paintG[2] - dist, 0, 255); 530 paintB[3] = deMath.clamp(paintB[2] - dist, 0, 255); 531 } else { 532 // H mode, calculate paint values. 533 var R1 = getBits64(src, 59, 62); 534 var G1a = getBits64(src, 56, 58); 535 var G1b = getBit64(src, 52); 536 var B1a = getBit64(src, 51); 537 var B1b = getBits64(src, 47, 49); 538 var R2 = getBits64(src, 43, 46); 539 var G2 = getBits64(src, 39, 42); 540 var B2 = getBits64(src, 35, 38); 541 var baseR = []; 542 var baseG = []; 543 var baseB = []; 544 var baseValue = []; 545 var distNdx; 546 var dist; 547 548 baseR[0] = extend4To8(R1); 549 baseG[0] = extend4To8((G1a << 1) | G1b); 550 baseB[0] = extend4To8((B1a << 3) | B1b); 551 baseR[1] = extend4To8(R2); 552 baseG[1] = extend4To8(G2); 553 baseB[1] = extend4To8(B2); 554 baseValue[0] = ((baseR[0]) << 16) | ((baseG[0]) << 8) | baseB[0]; 555 baseValue[1] = ((baseR[1]) << 16) | ((baseG[1]) << 8) | baseB[1]; 556 distNdx = (getBit64(src, 34) << 2) | (getBit64(src, 32) << 1); 557 if (baseValue[0] >= baseValue[1]) 558 distNdx += 1; 559 dist = distTable[distNdx]; 560 561 paintR[0] = deMath.clamp(baseR[0] + dist, 0, 255); 562 paintG[0] = deMath.clamp(baseG[0] + dist, 0, 255); 563 paintB[0] = deMath.clamp(baseB[0] + dist, 0, 255); 564 paintR[1] = deMath.clamp(baseR[0] - dist, 0, 255); 565 paintG[1] = deMath.clamp(baseG[0] - dist, 0, 255); 566 paintB[1] = deMath.clamp(baseB[0] - dist, 0, 255); 567 paintR[2] = deMath.clamp(baseR[1] + dist, 0, 255); 568 paintG[2] = deMath.clamp(baseG[1] + dist, 0, 255); 569 paintB[2] = deMath.clamp(baseB[1] + dist, 0, 255); 570 paintR[3] = deMath.clamp(baseR[1] - dist, 0, 255); 571 paintG[3] = deMath.clamp(baseG[1] - dist, 0, 255); 572 paintB[3] = deMath.clamp(baseB[1] - dist, 0, 255); 573 } 574 575 // Write final pixels for T or H mode. 576 var pixelNdx = 0; 577 for (var x = 0; x < ETC2_BLOCK_WIDTH; x++) { 578 for (var y = 0; y < ETC2_BLOCK_HEIGHT; y++, pixelNdx++) { 579 var dstOffset = (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8; 580 var paintNdx = (getBit64(src, 16 + pixelNdx) << 1) | getBit64(src, pixelNdx); 581 var alphaDstOffset = (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; // Only needed for PUNCHTHROUGH version. 582 583 if (alphaMode && diffOpaqueBit == 0 && paintNdx == 2) { 584 dst[dstOffset + 0] = 0; 585 dst[dstOffset + 1] = 0; 586 dst[dstOffset + 2] = 0; 587 alphaDst[alphaDstOffset] = 0; 588 } else { 589 dst[dstOffset + 0] = deMath.clamp(paintR[paintNdx], 0, 255); 590 dst[dstOffset + 1] = deMath.clamp(paintG[paintNdx], 0, 255); 591 dst[dstOffset + 2] = deMath.clamp(paintB[paintNdx], 0, 255); 592 593 if (alphaMode) 594 alphaDst[alphaDstOffset] = 255; 595 } 596 } 597 } 598 } else { 599 // Planar mode. 600 var GO1 = getBit64(src, 56); 601 var GO2 = getBits64(src, 49, 54); 602 var BO1 = getBit64(src, 48); 603 var BO2 = getBits64(src, 43, 44); 604 var BO3 = getBits64(src, 39, 41); 605 var RH1 = getBits64(src, 34, 38); 606 var RH2 = getBit64(src, 32); 607 var RO = extend6To8(getBits64(src, 57, 62)); 608 var GO = extend7To8((GO1 << 6) | GO2); 609 var BO = extend6To8((BO1 << 5) | (BO2 << 3) | BO3); 610 var RH = extend6To8((RH1 << 1) | RH2); 611 var GH = extend7To8(getBits64(src, 25, 31)); 612 var BH = extend6To8(getBits64(src, 19, 24)); 613 var RV = extend6To8(getBits64(src, 13, 18)); 614 var GV = extend7To8(getBits64(src, 6, 12)); 615 var BV = extend6To8(getBits64(src, 0, 5)); 616 617 // Write final pixels for planar mode. 618 for (var y = 0; y < 4; y++) { 619 for (var x = 0; x < 4; x++) { 620 var dstOffset = (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8; 621 var unclampedR = (x * (RH - RO) + y * (RV - RO) + 4 * RO + 2) / 4; 622 var unclampedG = (x * (GH - GO) + y * (GV - GO) + 4 * GO + 2) / 4; 623 var unclampedB = (x * (BH - BO) + y * (BV - BO) + 4 * BO + 2) / 4; 624 var alphaDstOffset = (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; // Only needed for PUNCHTHROUGH version. 625 626 dst[dstOffset + 0] = deMath.clamp(unclampedR, 0, 255); 627 dst[dstOffset + 1] = deMath.clamp(unclampedG, 0, 255); 628 dst[dstOffset + 2] = deMath.clamp(unclampedB, 0, 255); 629 630 if (alphaMode) 631 alphaDst[alphaDstOffset] = 255; 632 } 633 } 634 } 635 }; 636 637 var decompressEAC8Block = function(dst, src) { 638 var modifierTable = [ 639 [-3, -6, -9, -15, 2, 5, 8, 14], 640 [-3, -7, -10, -13, 2, 6, 9, 12], 641 [-2, -5, -8, -13, 1, 4, 7, 12], 642 [-2, -4, -6, -13, 1, 3, 5, 12], 643 [-3, -6, -8, -12, 2, 5, 7, 11], 644 [-3, -7, -9, -11, 2, 6, 8, 10], 645 [-4, -7, -8, -11, 3, 6, 7, 10], 646 [-3, -5, -8, -11, 2, 4, 7, 10], 647 [-2, -6, -8, -10, 1, 5, 7, 9], 648 [-2, -5, -8, -10, 1, 4, 7, 9], 649 [-2, -4, -8, -10, 1, 3, 7, 9], 650 [-2, -5, -7, -10, 1, 4, 6, 9], 651 [-3, -4, -7, -10, 2, 3, 6, 9], 652 [-1, -2, -3, -10, 0, 1, 2, 9], 653 [-4, -6, -8, -9, 3, 5, 7, 8], 654 [-3, -5, -7, -9, 2, 4, 6, 8] 655 ]; 656 657 var baseCodeword = getBits64(src, 56, 63); 658 var multiplier = getBits64(src, 52, 55); 659 var tableNdx = getBits64(src, 48, 51); 660 661 var pixelNdx = 0; 662 for (var x = 0; x < ETC2_BLOCK_WIDTH; x++) { 663 for (var y = 0; y < ETC2_BLOCK_HEIGHT; y++, pixelNdx++) { 664 var dstOffset = (y * ETC2_BLOCK_WIDTH + x); 665 var pixelBitNdx = 45 - 3 * pixelNdx; 666 var modifierNdx = (getBit64(src, pixelBitNdx + 2) << 2) | (getBit64(src, pixelBitNdx + 1) << 1) | getBit64(src, pixelBitNdx); 667 var modifier = modifierTable[tableNdx][modifierNdx]; 668 669 dst[dstOffset] = deMath.clamp(baseCodeword + multiplier * modifier, 0, 255); 670 } 671 } 672 }; 673 674 var decompressETC2 = function(/*const tcu::PixelBufferAccess&*/ dst, width, height, src) { 675 var numBlocksX = tcuCompressedTexture.divRoundUp(width, 4); 676 var numBlocksY = tcuCompressedTexture.divRoundUp(height, 4); 677 var dstPtr = new Uint8Array(dst.m_data); 678 var dstRowPitch = dst.getRowPitch(); 679 var dstPixelSize = ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8; 680 var uncompressedBlockArray = new ArrayBuffer(ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8); 681 var uncompressedBlock = new Uint8Array(uncompressedBlockArray); 682 683 for (var blockY = 0; blockY < numBlocksY; blockY++) { 684 for (var blockX = 0; blockX < numBlocksX; blockX++) { 685 var compressedBlock = get64BitBlock(src, blockY * numBlocksX + blockX); 686 687 // Decompress. 688 decompressETC2Block(uncompressedBlock, compressedBlock, null, false); 689 690 // Write to dst. 691 var baseX = blockX * ETC2_BLOCK_WIDTH; 692 var baseY = blockY * ETC2_BLOCK_HEIGHT; 693 for (var y = 0; y < Math.min(ETC2_BLOCK_HEIGHT, height - baseY); y++) { 694 for (var x = 0; x < Math.min(ETC2_BLOCK_WIDTH, width - baseX); x++) { 695 var srcIndex = (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8; 696 var dstIndex = (baseY + y) * dstRowPitch + (baseX + x) * dstPixelSize; 697 698 for (var i = 0; i < ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8; i++) 699 dstPtr[dstIndex + i] = uncompressedBlock[srcIndex + i]; 700 } 701 } 702 } 703 } 704 }; 705 706 var decompressETC2_EAC_RGBA8 = function(/*const tcu::PixelBufferAccess&*/ dst, width, height, src) { 707 var numBlocksX = tcuCompressedTexture.divRoundUp(width, 4); 708 var numBlocksY = tcuCompressedTexture.divRoundUp(height, 4); 709 var dstPtr = new Uint8Array(dst.m_data); 710 var dstRowPitch = dst.getRowPitch(); 711 var dstPixelSize = ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8; 712 var uncompressedBlockArray = new ArrayBuffer(ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8); 713 var uncompressedBlock = new Uint8Array(uncompressedBlockArray); 714 var uncompressedBlockAlphaArray = new ArrayBuffer(ETC2_UNCOMPRESSED_BLOCK_SIZE_A8); 715 var uncompressedBlockAlpha = new Uint8Array(uncompressedBlockAlphaArray); 716 717 for (var blockY = 0; blockY < numBlocksY; blockY++) { 718 for (var blockX = 0; blockX < numBlocksX; blockX++) { 719 var compressedBlockAlpha = get128BitBlockStart(src, blockY * numBlocksX + blockX); 720 var compressedBlockRGB = get128BitBlockEnd(src, blockY * numBlocksX + blockX); 721 722 // Decompress. 723 decompressETC2Block(uncompressedBlock, compressedBlockRGB, null, false); 724 decompressEAC8Block(uncompressedBlockAlpha, compressedBlockAlpha); 725 726 // Write to dst. 727 var baseX = blockX * ETC2_BLOCK_WIDTH; 728 var baseY = blockY * ETC2_BLOCK_HEIGHT; 729 for (var y = 0; y < Math.min(ETC2_BLOCK_HEIGHT, height - baseY); y++) { 730 for (var x = 0; x < Math.min(ETC2_BLOCK_WIDTH, width - baseX); x++) { 731 var srcIndex = (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8; 732 var srcAlphaIndex = (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; 733 var dstIndex = (baseY + y) * dstRowPitch + (baseX + x) * dstPixelSize; 734 735 for (var i = 0; i < ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8 - 1; i++) 736 dstPtr[dstIndex + i] = uncompressedBlock[srcIndex + i]; 737 dstPtr[dstIndex + ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8 - 1] = uncompressedBlockAlpha[srcAlphaIndex]; 738 739 } 740 } 741 } 742 } 743 }; 744 745 var decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1 = function(/*const tcu::PixelBufferAccess&*/ dst, width, height, src) { 746 var numBlocksX = tcuCompressedTexture.divRoundUp(width, 4); 747 var numBlocksY = tcuCompressedTexture.divRoundUp(height, 4); 748 var dstPtr = new Uint8Array(dst.m_data); 749 var dstRowPitch = dst.getRowPitch(); 750 var dstPixelSize = ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8; 751 var uncompressedBlockArray = new ArrayBuffer(ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8); 752 var uncompressedBlock = new Uint8Array(uncompressedBlockArray); 753 var uncompressedBlockAlphaArray = new ArrayBuffer(ETC2_UNCOMPRESSED_BLOCK_SIZE_A8); 754 var uncompressedBlockAlpha = new Uint8Array(uncompressedBlockAlphaArray); 755 756 for (var blockY = 0; blockY < numBlocksY; blockY++) { 757 for (var blockX = 0; blockX < numBlocksX; blockX++) { 758 var compressedBlock = get64BitBlock(src, blockY * numBlocksX + blockX); 759 760 // Decompress. 761 decompressETC2Block(uncompressedBlock, compressedBlock, uncompressedBlockAlpha, true); 762 763 // Write to dst. 764 var baseX = blockX * ETC2_BLOCK_WIDTH; 765 var baseY = blockY * ETC2_BLOCK_HEIGHT; 766 for (var y = 0; y < Math.min(ETC2_BLOCK_HEIGHT, height - baseY); y++) { 767 for (var x = 0; x < Math.min(ETC2_BLOCK_WIDTH, width - baseX); x++) { 768 var srcIndex = (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8; 769 var srcAlphaIndex = (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; 770 var dstIndex = (baseY + y) * dstRowPitch + (baseX + x) * dstPixelSize; 771 772 for (var i = 0; i < ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8 - 1; i++) 773 dstPtr[dstIndex + i] = uncompressedBlock[srcIndex + i]; 774 dstPtr[dstIndex + ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8 - 1] = uncompressedBlockAlpha[srcAlphaIndex]; 775 776 } 777 } 778 } 779 } 780 }; 781 782 return { 783 decompressEAC_R11: decompressEAC_R11, 784 decompressEAC_RG11: decompressEAC_RG11, 785 decompressETC2: decompressETC2, 786 decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1: decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1, 787 decompressETC2_EAC_RGBA8: decompressETC2_EAC_RGBA8 788 }; 789 790 }(); 791 792 /** 793 * @constructor 794 * @param {tcuCompressedTexture.Format} format 795 * @param {number} width 796 * @param {number} height 797 * @param {number=} depth 798 */ 799 tcuCompressedTexture.CompressedTexture = function(format, width, height, depth) { 800 depth = depth === undefined ? 1 : depth; 801 this.setStorage(format, width, height, depth); 802 /** @type {Uint8Array} */ this.m_data; 803 }; 804 805 /** 806 * @return {number} 807 */ 808 tcuCompressedTexture.CompressedTexture.prototype.getDataSize = function() { 809 return this.m_data.length; 810 }; 811 812 /** 813 * @return {Uint8Array} 814 */ 815 tcuCompressedTexture.CompressedTexture.prototype.getData = function() { 816 return this.m_data; 817 }; 818 819 /** 820 * @return {number} 821 */ 822 tcuCompressedTexture.CompressedTexture.prototype.getWidth = function() { 823 return this.m_width; 824 }; 825 826 /** 827 * @return {number} 828 */ 829 tcuCompressedTexture.CompressedTexture.prototype.getHeight = function() { 830 return this.m_height; 831 }; 832 833 /** 834 * @return {tcuCompressedTexture.Format} 835 */ 836 tcuCompressedTexture.CompressedTexture.prototype.getFormat = function() { 837 return this.m_format; 838 }; 839 840 tcuCompressedTexture.CompressedTexture.prototype.setStorage = function(format, width, height, depth) { 841 depth = depth === undefined ? 1 : depth; 842 this.m_format = format; 843 this.m_width = width; 844 this.m_height = height; 845 this.m_depth = depth; 846 847 if (tcuCompressedTexture.isEtcFormat(this.m_format)) { 848 DE_ASSERT(this.m_depth == 1); 849 850 var blockSizeMultiplier = 0; // How many 64-bit parts each compressed block contains. 851 852 switch (this.m_format) { 853 case tcuCompressedTexture.Format.ETC1_RGB8: blockSizeMultiplier = 1; break; 854 case tcuCompressedTexture.Format.EAC_R11: blockSizeMultiplier = 1; break; 855 case tcuCompressedTexture.Format.EAC_SIGNED_R11: blockSizeMultiplier = 1; break; 856 case tcuCompressedTexture.Format.EAC_RG11: blockSizeMultiplier = 2; break; 857 case tcuCompressedTexture.Format.EAC_SIGNED_RG11: blockSizeMultiplier = 2; break; 858 case tcuCompressedTexture.Format.ETC2_RGB8: blockSizeMultiplier = 1; break; 859 case tcuCompressedTexture.Format.ETC2_SRGB8: blockSizeMultiplier = 1; break; 860 case tcuCompressedTexture.Format.ETC2_RGB8_PUNCHTHROUGH_ALPHA1: blockSizeMultiplier = 1; break; 861 case tcuCompressedTexture.Format.ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: blockSizeMultiplier = 1; break; 862 case tcuCompressedTexture.Format.ETC2_EAC_RGBA8: blockSizeMultiplier = 2; break; 863 case tcuCompressedTexture.Format.ETC2_EAC_SRGB8_ALPHA8: blockSizeMultiplier = 2; break; 864 865 default: 866 throw new Error('Unsupported format ' + format); 867 break; 868 } 869 870 this.m_array = new ArrayBuffer(blockSizeMultiplier * 8 * tcuCompressedTexture.divRoundUp(this.m_width, 4) * tcuCompressedTexture.divRoundUp(this.m_height, 4)); 871 this.m_data = new Uint8Array(this.m_array); 872 } 873 // else if (isASTCFormat(this.m_format)) 874 // { 875 // if (this.m_depth > 1) 876 // throw tcu::InternalError("3D ASTC textures not currently supported"); 877 878 // const IVec3 blockSize = getASTCBlockSize(this.m_format); 879 // this.m_data.resize(ASTC_BLOCK_SIZE_BYTES * tcuCompressedTexture.divRoundUp(this.m_width, blockSize[0]) * tcuCompressedTexture.divRoundUp(this.m_height, blockSize[1]) * tcuCompressedTexture.divRoundUp(this.m_depth, blockSize[2])); 880 // } 881 // else 882 // { 883 // DE_ASSERT(this.m_format == FORMAT_LAST); 884 // DE_ASSERT(this.m_width == 0 && this.m_height == 0 && this.m_depth == 0); 885 // this.m_data.resize(0); 886 // } 887 }; 888 889 /*--------------------------------------------------------------------*//*! 890 * \brief Get uncompressed texture format 891 *//*--------------------------------------------------------------------*/ 892 tcuCompressedTexture.CompressedTexture.prototype.getUncompressedFormat = function() { 893 if (tcuCompressedTexture.isEtcFormat(this.m_format)) { 894 switch (this.m_format) { 895 case tcuCompressedTexture.Format.ETC1_RGB8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNORM_INT8); 896 case tcuCompressedTexture.Format.EAC_R11: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.UNORM_INT16); 897 case tcuCompressedTexture.Format.EAC_SIGNED_R11: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.SNORM_INT16); 898 case tcuCompressedTexture.Format.EAC_RG11: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.UNORM_INT16); 899 case tcuCompressedTexture.Format.EAC_SIGNED_RG11: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.SNORM_INT16); 900 case tcuCompressedTexture.Format.ETC2_RGB8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNORM_INT8); 901 case tcuCompressedTexture.Format.ETC2_SRGB8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.sRGB, tcuTexture.ChannelType.UNORM_INT8); 902 case tcuCompressedTexture.Format.ETC2_RGB8_PUNCHTHROUGH_ALPHA1: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8); 903 case tcuCompressedTexture.Format.ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.sRGBA, tcuTexture.ChannelType.UNORM_INT8); 904 case tcuCompressedTexture.Format.ETC2_EAC_RGBA8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8); 905 case tcuCompressedTexture.Format.ETC2_EAC_SRGB8_ALPHA8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.sRGBA, tcuTexture.ChannelType.UNORM_INT8); 906 default: 907 throw new Error('Unsupported format ' + this.m_format); 908 } 909 } 910 // else if (isASTCFormat(m_format)) 911 // { 912 // if (isASTCSRGBFormat(m_format)) 913 // return TextureFormat(tcuTexture.ChannelType.sRGBA, tcuTexture.ChannelType.UNORM_INT8); 914 // else 915 // return TextureFormat(tcuTexture.ChannelType.RGBA, tcuTexture.ChannelType.HALF_FLOAT); 916 // } 917 // else 918 // { 919 // DE_ASSERT(false); 920 // return TextureFormat(); 921 // } 922 }; 923 924 /** 925 * Decode to uncompressed pixel data 926 * @param {tcuTexture.PixelBufferAccess} dst Destination buffer 927 */ 928 tcuCompressedTexture.CompressedTexture.prototype.decompress = function(dst) { 929 DE_ASSERT(dst.getWidth() == this.m_width && dst.getHeight() == this.m_height && dst.getDepth() == 1); 930 var format = this.getUncompressedFormat(); 931 if (dst.getFormat().order != format.order || dst.getFormat().type != format.type) 932 throw new Error('Formats do not match.'); 933 934 if (tcuCompressedTexture.isEtcFormat(this.m_format)) { 935 switch (this.m_format) { 936 // case tcuCompressedTexture.Format.ETC1_RGB8: decompressETC1 (dst, this.m_width, this.m_height, this.m_data); break; 937 case tcuCompressedTexture.Format.EAC_R11: tcuCompressedTexture.etcDecompressInternal.decompressEAC_R11(dst, this.m_width, this.m_height, this.m_array, false); break; 938 case tcuCompressedTexture.Format.EAC_SIGNED_R11: tcuCompressedTexture.etcDecompressInternal.decompressEAC_R11(dst, this.m_width, this.m_height, this.m_array, true); break; 939 case tcuCompressedTexture.Format.EAC_RG11: tcuCompressedTexture.etcDecompressInternal.decompressEAC_RG11(dst, this.m_width, this.m_height, this.m_array, false); break; 940 case tcuCompressedTexture.Format.EAC_SIGNED_RG11: tcuCompressedTexture.etcDecompressInternal.decompressEAC_RG11(dst, this.m_width, this.m_height, this.m_array, true); break; 941 case tcuCompressedTexture.Format.ETC2_RGB8: tcuCompressedTexture.etcDecompressInternal.decompressETC2(dst, this.m_width, this.m_height, this.m_array); break; 942 case tcuCompressedTexture.Format.ETC2_SRGB8: tcuCompressedTexture.etcDecompressInternal.decompressETC2(dst, this.m_width, this.m_height, this.m_array); break; 943 case tcuCompressedTexture.Format.ETC2_RGB8_PUNCHTHROUGH_ALPHA1: tcuCompressedTexture.etcDecompressInternal.decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1(dst, this.m_width, this.m_height, this.m_array); break; 944 case tcuCompressedTexture.Format.ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: tcuCompressedTexture.etcDecompressInternal.decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1(dst, this.m_width, this.m_height, this.m_array); break; 945 case tcuCompressedTexture.Format.ETC2_EAC_RGBA8: tcuCompressedTexture.etcDecompressInternal.decompressETC2_EAC_RGBA8(dst, this.m_width, this.m_height, this.m_array); break; 946 case tcuCompressedTexture.Format.ETC2_EAC_SRGB8_ALPHA8: tcuCompressedTexture.etcDecompressInternal.decompressETC2_EAC_RGBA8(dst, this.m_width, this.m_height, this.m_array); break; 947 948 default: 949 throw new Error('Unsupported format ' + this.m_format); 950 break; 951 } 952 } 953 // else if (isASTCFormat(m_format)) 954 // { 955 // const tcu::IVec3 blockSize = getASTCBlockSize(m_format); 956 // const bool isSRGBFormat = isASTCSRGBFormat(m_format); 957 958 // if (blockSize[2] > 1) 959 // throw tcu::InternalError("3D ASTC textures not currently supported"); 960 961 // decompressASTC(dst, m_width, m_height, &m_data[0], blockSize[0], blockSize[1], isSRGBFormat, isSRGBFormat || params.isASTCModeLDR); 962 // } /**/ 963 else 964 throw new Error('Unsupported format ' + this.m_format); 965 }; 966 967 });