1/* 2 * Copyright (C) 2011 LunarG, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24/** 25 * \file texcompress_etc.c 26 * GL_OES_compressed_ETC1_RGB8_texture support. 27 * Supported ETC2 texture formats are: 28 * GL_COMPRESSED_RGB8_ETC2 29 * GL_COMPRESSED_SRGB8_ETC2 30 * GL_COMPRESSED_RGBA8_ETC2_EAC 31 * GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 32 * GL_COMPRESSED_R11_EAC 33 * GL_COMPRESSED_RG11_EAC 34 * GL_COMPRESSED_SIGNED_R11_EAC 35 * GL_COMPRESSED_SIGNED_RG11_EAC 36 * MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1 37 * MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1 38 */ 39 40#include <stdbool.h> 41#include "texcompress.h" 42#include "texcompress_etc.h" 43#include "texstore.h" 44#include "config.h" 45#include "macros.h" 46#include "format_unpack.h" 47#include "util/format_srgb.h" 48 49 50struct etc2_block { 51 int distance; 52 uint64_t pixel_indices[2]; 53 const int *modifier_tables[2]; 54 bool flipped; 55 bool opaque; 56 bool is_ind_mode; 57 bool is_diff_mode; 58 bool is_t_mode; 59 bool is_h_mode; 60 bool is_planar_mode; 61 uint8_t base_colors[3][3]; 62 uint8_t paint_colors[4][3]; 63 uint8_t base_codeword; 64 uint8_t multiplier; 65 uint8_t table_index; 66}; 67 68static const int etc2_distance_table[8] = { 69 3, 6, 11, 16, 23, 32, 41, 64 }; 70 71static const int etc2_modifier_tables[16][8] = { 72 { -3, -6, -9, -15, 2, 5, 8, 14}, 73 { -3, -7, -10, -13, 2, 6, 9, 12}, 74 { -2, -5, -8, -13, 1, 4, 7, 12}, 75 { -2, -4, -6, -13, 1, 3, 5, 12}, 76 { -3, -6, -8, -12, 2, 5, 7, 11}, 77 { -3, -7, -9, -11, 2, 6, 8, 10}, 78 { -4, -7, -8, -11, 3, 6, 7, 10}, 79 { -3, -5, -8, -11, 2, 4, 7, 10}, 80 { -2, -6, -8, -10, 1, 5, 7, 9}, 81 { -2, -5, -8, -10, 1, 4, 7, 9}, 82 { -2, -4, -8, -10, 1, 3, 7, 9}, 83 { -2, -5, -7, -10, 1, 4, 6, 9}, 84 { -3, -4, -7, -10, 2, 3, 6, 9}, 85 { -1, -2, -3, -10, 0, 1, 2, 9}, 86 { -4, -6, -8, -9, 3, 5, 7, 8}, 87 { -3, -5, -7, -9, 2, 4, 6, 8}, 88}; 89 90static const int etc2_modifier_tables_non_opaque[8][4] = { 91 { 0, 8, 0, -8}, 92 { 0, 17, 0, -17}, 93 { 0, 29, 0, -29}, 94 { 0, 42, 0, -42}, 95 { 0, 60, 0, -60}, 96 { 0, 80, 0, -80}, 97 { 0, 106, 0, -106}, 98 { 0, 183, 0, -183} 99}; 100 101/* define etc1_parse_block and etc. */ 102#define UINT8_TYPE GLubyte 103#define TAG(x) x 104#include "texcompress_etc_tmp.h" 105#undef TAG 106#undef UINT8_TYPE 107 108GLboolean 109_mesa_texstore_etc1_rgb8(UNUSED_TEXSTORE_PARAMS) 110{ 111 /* GL_ETC1_RGB8_OES is only valid in glCompressedTexImage2D */ 112 assert(0); 113 114 return GL_FALSE; 115} 116 117 118/** 119 * Decode texture data in format `MESA_FORMAT_ETC1_RGB8` to 120 * `MESA_FORMAT_ABGR8888`. 121 * 122 * The size of the source data must be a multiple of the ETC1 block size, 123 * which is 8, even if the texture image's dimensions are not aligned to 4. 124 * From the GL_OES_compressed_ETC1_RGB8_texture spec: 125 * The texture is described as a number of 4x4 pixel blocks. If the 126 * texture (or a particular mip-level) is smaller than 4 pixels in 127 * any dimension (such as a 2x2 or a 8x1 texture), the texture is 128 * found in the upper left part of the block(s), and the rest of the 129 * pixels are not used. For instance, a texture of size 4x2 will be 130 * placed in the upper half of a 4x4 block, and the lower half of the 131 * pixels in the block will not be accessed. 132 * 133 * \param src_width in pixels 134 * \param src_height in pixels 135 * \param dst_stride in bytes 136 */ 137void 138_mesa_etc1_unpack_rgba8888(uint8_t *dst_row, 139 unsigned dst_stride, 140 const uint8_t *src_row, 141 unsigned src_stride, 142 unsigned src_width, 143 unsigned src_height) 144{ 145 etc1_unpack_rgba8888(dst_row, dst_stride, 146 src_row, src_stride, 147 src_width, src_height); 148} 149 150static uint8_t 151etc2_base_color1_t_mode(const uint8_t *in, GLuint index) 152{ 153 uint8_t R1a = 0, x = 0; 154 /* base col 1 = extend_4to8bits( (R1a << 2) | R1b, G1, B1) */ 155 switch(index) { 156 case 0: 157 R1a = (in[0] >> 3) & 0x3; 158 x = ((R1a << 2) | (in[0] & 0x3)); 159 break; 160 case 1: 161 x = ((in[1] >> 4) & 0xf); 162 break; 163 case 2: 164 x = (in[1] & 0xf); 165 break; 166 default: 167 /* invalid index */ 168 break; 169 } 170 return ((x << 4) | (x & 0xf)); 171} 172 173static uint8_t 174etc2_base_color2_t_mode(const uint8_t *in, GLuint index) 175{ 176 uint8_t x = 0; 177 /*extend 4to8bits(R2, G2, B2)*/ 178 switch(index) { 179 case 0: 180 x = ((in[2] >> 4) & 0xf ); 181 break; 182 case 1: 183 x = (in[2] & 0xf); 184 break; 185 case 2: 186 x = ((in[3] >> 4) & 0xf); 187 break; 188 default: 189 /* invalid index */ 190 break; 191 } 192 return ((x << 4) | (x & 0xf)); 193} 194 195static uint8_t 196etc2_base_color1_h_mode(const uint8_t *in, GLuint index) 197{ 198 uint8_t x = 0; 199 /* base col 1 = extend 4to8bits(R1, (G1a << 1) | G1b, (B1a << 3) | B1b) */ 200 switch(index) { 201 case 0: 202 x = ((in[0] >> 3) & 0xf); 203 break; 204 case 1: 205 x = (((in[0] & 0x7) << 1) | ((in[1] >> 4) & 0x1)); 206 break; 207 case 2: 208 x = ((in[1] & 0x8) | 209 (((in[1] & 0x3) << 1) | ((in[2] >> 7) & 0x1))); 210 break; 211 default: 212 /* invalid index */ 213 break; 214 } 215 return ((x << 4) | (x & 0xf)); 216} 217 218static uint8_t 219etc2_base_color2_h_mode(const uint8_t *in, GLuint index) 220{ 221 uint8_t x = 0; 222 /* base col 2 = extend 4to8bits(R2, G2, B2) */ 223 switch(index) { 224 case 0: 225 x = ((in[2] >> 3) & 0xf ); 226 break; 227 case 1: 228 x = (((in[2] & 0x7) << 1) | ((in[3] >> 7) & 0x1)); 229 break; 230 case 2: 231 x = ((in[3] >> 3) & 0xf); 232 break; 233 default: 234 /* invalid index */ 235 break; 236 } 237 return ((x << 4) | (x & 0xf)); 238} 239 240static uint8_t 241etc2_base_color_o_planar(const uint8_t *in, GLuint index) 242{ 243 GLuint tmp; 244 switch(index) { 245 case 0: 246 tmp = ((in[0] >> 1) & 0x3f); /* RO */ 247 return ((tmp << 2) | (tmp >> 4)); 248 case 1: 249 tmp = (((in[0] & 0x1) << 6) | /* GO1 */ 250 ((in[1] >> 1) & 0x3f)); /* GO2 */ 251 return ((tmp << 1) | (tmp >> 6)); 252 case 2: 253 tmp = (((in[1] & 0x1) << 5) | /* BO1 */ 254 (in[2] & 0x18) | /* BO2 */ 255 (((in[2] & 0x3) << 1) | ((in[3] >> 7) & 0x1))); /* BO3 */ 256 return ((tmp << 2) | (tmp >> 4)); 257 default: 258 /* invalid index */ 259 return 0; 260 } 261} 262 263static uint8_t 264etc2_base_color_h_planar(const uint8_t *in, GLuint index) 265{ 266 GLuint tmp; 267 switch(index) { 268 case 0: 269 tmp = (((in[3] & 0x7c) >> 1) | /* RH1 */ 270 (in[3] & 0x1)); /* RH2 */ 271 return ((tmp << 2) | (tmp >> 4)); 272 case 1: 273 tmp = (in[4] >> 1) & 0x7f; /* GH */ 274 return ((tmp << 1) | (tmp >> 6)); 275 case 2: 276 tmp = (((in[4] & 0x1) << 5) | 277 ((in[5] >> 3) & 0x1f)); /* BH */ 278 return ((tmp << 2) | (tmp >> 4)); 279 default: 280 /* invalid index */ 281 return 0; 282 } 283} 284 285static uint8_t 286etc2_base_color_v_planar(const uint8_t *in, GLuint index) 287{ 288 GLuint tmp; 289 switch(index) { 290 case 0: 291 tmp = (((in[5] & 0x7) << 0x3) | 292 ((in[6] >> 5) & 0x7)); /* RV */ 293 return ((tmp << 2) | (tmp >> 4)); 294 case 1: 295 tmp = (((in[6] & 0x1f) << 2) | 296 ((in[7] >> 6) & 0x3)); /* GV */ 297 return ((tmp << 1) | (tmp >> 6)); 298 case 2: 299 tmp = in[7] & 0x3f; /* BV */ 300 return ((tmp << 2) | (tmp >> 4)); 301 default: 302 /* invalid index */ 303 return 0; 304 } 305} 306 307static GLint 308etc2_get_pixel_index(const struct etc2_block *block, int x, int y) 309{ 310 int bit = ((3 - y) + (3 - x) * 4) * 3; 311 int idx = (block->pixel_indices[1] >> bit) & 0x7; 312 return idx; 313} 314 315static uint8_t 316etc2_clamp(int color) 317{ 318 /* CLAMP(color, 0, 255) */ 319 return (uint8_t) CLAMP(color, 0, 255); 320} 321 322static GLushort 323etc2_clamp2(int color) 324{ 325 /* CLAMP(color, 0, 2047) */ 326 return (GLushort) CLAMP(color, 0, 2047); 327} 328 329static GLshort 330etc2_clamp3(int color) 331{ 332 /* CLAMP(color, -1023, 1023) */ 333 return (GLshort) CLAMP(color, -1023, 1023); 334} 335 336static void 337etc2_rgb8_parse_block(struct etc2_block *block, 338 const uint8_t *src, 339 GLboolean punchthrough_alpha) 340{ 341 unsigned i; 342 GLboolean diffbit = false; 343 static const int lookup[8] = { 0, 1, 2, 3, -4, -3, -2, -1 }; 344 345 const int R_plus_dR = (src[0] >> 3) + lookup[src[0] & 0x7]; 346 const int G_plus_dG = (src[1] >> 3) + lookup[src[1] & 0x7]; 347 const int B_plus_dB = (src[2] >> 3) + lookup[src[2] & 0x7]; 348 349 /* Reset the mode flags */ 350 block->is_ind_mode = false; 351 block->is_diff_mode = false; 352 block->is_t_mode = false; 353 block->is_h_mode = false; 354 block->is_planar_mode = false; 355 356 if (punchthrough_alpha) 357 block->opaque = src[3] & 0x2; 358 else 359 diffbit = src[3] & 0x2; 360 361 if (!diffbit && !punchthrough_alpha) { 362 /* individual mode */ 363 block->is_ind_mode = true; 364 365 for (i = 0; i < 3; i++) { 366 /* Texture decode algorithm is same for individual mode in etc1 367 * & etc2. 368 */ 369 block->base_colors[0][i] = etc1_base_color_ind_hi(src[i]); 370 block->base_colors[1][i] = etc1_base_color_ind_lo(src[i]); 371 } 372 } 373 else if (R_plus_dR < 0 || R_plus_dR > 31){ 374 /* T mode */ 375 block->is_t_mode = true; 376 377 for(i = 0; i < 3; i++) { 378 block->base_colors[0][i] = etc2_base_color1_t_mode(src, i); 379 block->base_colors[1][i] = etc2_base_color2_t_mode(src, i); 380 } 381 /* pick distance */ 382 block->distance = 383 etc2_distance_table[(((src[3] >> 2) & 0x3) << 1) | 384 (src[3] & 0x1)]; 385 386 for (i = 0; i < 3; i++) { 387 block->paint_colors[0][i] = etc2_clamp(block->base_colors[0][i]); 388 block->paint_colors[1][i] = etc2_clamp(block->base_colors[1][i] + 389 block->distance); 390 block->paint_colors[2][i] = etc2_clamp(block->base_colors[1][i]); 391 block->paint_colors[3][i] = etc2_clamp(block->base_colors[1][i] - 392 block->distance); 393 } 394 } 395 else if (G_plus_dG < 0 || G_plus_dG > 31){ 396 int base_color_1_value, base_color_2_value; 397 398 /* H mode */ 399 block->is_h_mode = true; 400 401 for(i = 0; i < 3; i++) { 402 block->base_colors[0][i] = etc2_base_color1_h_mode(src, i); 403 block->base_colors[1][i] = etc2_base_color2_h_mode(src, i); 404 } 405 406 base_color_1_value = (block->base_colors[0][0] << 16) + 407 (block->base_colors[0][1] << 8) + 408 block->base_colors[0][2]; 409 base_color_2_value = (block->base_colors[1][0] << 16) + 410 (block->base_colors[1][1] << 8) + 411 block->base_colors[1][2]; 412 /* pick distance */ 413 block->distance = 414 etc2_distance_table[(src[3] & 0x4) | 415 ((src[3] & 0x1) << 1) | 416 (base_color_1_value >= base_color_2_value)]; 417 418 for (i = 0; i < 3; i++) { 419 block->paint_colors[0][i] = etc2_clamp(block->base_colors[0][i] + 420 block->distance); 421 block->paint_colors[1][i] = etc2_clamp(block->base_colors[0][i] - 422 block->distance); 423 block->paint_colors[2][i] = etc2_clamp(block->base_colors[1][i] + 424 block->distance); 425 block->paint_colors[3][i] = etc2_clamp(block->base_colors[1][i] - 426 block->distance); 427 } 428 } 429 else if (B_plus_dB < 0 || B_plus_dB > 31) { 430 /* Planar mode */ 431 block->is_planar_mode = true; 432 433 /* opaque bit must be set in planar mode */ 434 block->opaque = true; 435 436 for (i = 0; i < 3; i++) { 437 block->base_colors[0][i] = etc2_base_color_o_planar(src, i); 438 block->base_colors[1][i] = etc2_base_color_h_planar(src, i); 439 block->base_colors[2][i] = etc2_base_color_v_planar(src, i); 440 } 441 } 442 else if (diffbit || punchthrough_alpha) { 443 /* differential mode */ 444 block->is_diff_mode = true; 445 446 for (i = 0; i < 3; i++) { 447 /* Texture decode algorithm is same for differential mode in etc1 448 * & etc2. 449 */ 450 block->base_colors[0][i] = etc1_base_color_diff_hi(src[i]); 451 block->base_colors[1][i] = etc1_base_color_diff_lo(src[i]); 452 } 453 } 454 455 if (block->is_ind_mode || block->is_diff_mode) { 456 int table1_idx = (src[3] >> 5) & 0x7; 457 int table2_idx = (src[3] >> 2) & 0x7; 458 459 /* Use same modifier tables as for etc1 textures if opaque bit is set 460 * or if non punchthrough texture format 461 */ 462 block->modifier_tables[0] = (!punchthrough_alpha || block->opaque) ? 463 etc1_modifier_tables[table1_idx] : 464 etc2_modifier_tables_non_opaque[table1_idx]; 465 block->modifier_tables[1] = (!punchthrough_alpha || block->opaque) ? 466 etc1_modifier_tables[table2_idx] : 467 etc2_modifier_tables_non_opaque[table2_idx]; 468 469 block->flipped = (src[3] & 0x1); 470 } 471 472 block->pixel_indices[0] = 473 (src[4] << 24) | (src[5] << 16) | (src[6] << 8) | src[7]; 474} 475 476static void 477etc2_rgb8_fetch_texel(const struct etc2_block *block, 478 int x, int y, uint8_t *dst, 479 GLboolean punchthrough_alpha) 480{ 481 const uint8_t *base_color; 482 int modifier, bit, idx, blk; 483 484 /* get pixel index */ 485 bit = y + x * 4; 486 idx = ((block->pixel_indices[0] >> (15 + bit)) & 0x2) | 487 ((block->pixel_indices[0] >> (bit)) & 0x1); 488 489 if (block->is_ind_mode || block->is_diff_mode) { 490 /* check for punchthrough_alpha format */ 491 if (punchthrough_alpha) { 492 if (!block->opaque && idx == 2) { 493 dst[0] = dst[1] = dst[2] = dst[3] = 0; 494 return; 495 } 496 else 497 dst[3] = 255; 498 } 499 500 /* Use pixel index and subblock to get the modifier */ 501 blk = (block->flipped) ? (y >= 2) : (x >= 2); 502 base_color = block->base_colors[blk]; 503 modifier = block->modifier_tables[blk][idx]; 504 505 dst[0] = etc2_clamp(base_color[0] + modifier); 506 dst[1] = etc2_clamp(base_color[1] + modifier); 507 dst[2] = etc2_clamp(base_color[2] + modifier); 508 } 509 else if (block->is_t_mode || block->is_h_mode) { 510 /* check for punchthrough_alpha format */ 511 if (punchthrough_alpha) { 512 if (!block->opaque && idx == 2) { 513 dst[0] = dst[1] = dst[2] = dst[3] = 0; 514 return; 515 } 516 else 517 dst[3] = 255; 518 } 519 520 /* Use pixel index to pick one of the paint colors */ 521 dst[0] = block->paint_colors[idx][0]; 522 dst[1] = block->paint_colors[idx][1]; 523 dst[2] = block->paint_colors[idx][2]; 524 } 525 else if (block->is_planar_mode) { 526 /* {R(x, y) = clamp255((x × (RH − RO) + y × (RV − RO) + 4 × RO + 2) >> 2) 527 * {G(x, y) = clamp255((x × (GH − GO) + y × (GV − GO) + 4 × GO + 2) >> 2) 528 * {B(x, y) = clamp255((x × (BH − BO) + y × (BV − BO) + 4 × BO + 2) >> 2) 529 */ 530 int red, green, blue; 531 red = (x * (block->base_colors[1][0] - block->base_colors[0][0]) + 532 y * (block->base_colors[2][0] - block->base_colors[0][0]) + 533 4 * block->base_colors[0][0] + 2) >> 2; 534 535 green = (x * (block->base_colors[1][1] - block->base_colors[0][1]) + 536 y * (block->base_colors[2][1] - block->base_colors[0][1]) + 537 4 * block->base_colors[0][1] + 2) >> 2; 538 539 blue = (x * (block->base_colors[1][2] - block->base_colors[0][2]) + 540 y * (block->base_colors[2][2] - block->base_colors[0][2]) + 541 4 * block->base_colors[0][2] + 2) >> 2; 542 543 dst[0] = etc2_clamp(red); 544 dst[1] = etc2_clamp(green); 545 dst[2] = etc2_clamp(blue); 546 547 /* check for punchthrough_alpha format */ 548 if (punchthrough_alpha) 549 dst[3] = 255; 550 } 551 else 552 unreachable("unhandled block mode"); 553} 554 555static void 556etc2_alpha8_fetch_texel(const struct etc2_block *block, 557 int x, int y, uint8_t *dst) 558{ 559 int modifier, alpha, idx; 560 /* get pixel index */ 561 idx = etc2_get_pixel_index(block, x, y); 562 modifier = etc2_modifier_tables[block->table_index][idx]; 563 alpha = block->base_codeword + modifier * block->multiplier; 564 dst[3] = etc2_clamp(alpha); 565} 566 567static void 568etc2_r11_fetch_texel(const struct etc2_block *block, 569 int x, int y, uint8_t *dst) 570{ 571 GLint modifier, idx; 572 GLshort color; 573 /* Get pixel index */ 574 idx = etc2_get_pixel_index(block, x, y); 575 modifier = etc2_modifier_tables[block->table_index][idx]; 576 577 if (block->multiplier != 0) 578 /* clamp2(base codeword × 8 + 4 + modifier × multiplier × 8) */ 579 color = etc2_clamp2(((block->base_codeword << 3) | 0x4) + 580 ((modifier * block->multiplier) << 3)); 581 else 582 color = etc2_clamp2(((block->base_codeword << 3) | 0x4) + modifier); 583 584 /* Extend 11 bits color value to 16 bits. OpenGL ES 3.0 specification 585 * allows extending the color value to any number of bits. But, an 586 * implementation is not allowed to truncate the 11-bit value to less than 587 * 11 bits." 588 */ 589 color = (color << 5) | (color >> 6); 590 ((GLushort *)dst)[0] = color; 591} 592 593static void 594etc2_signed_r11_fetch_texel(const struct etc2_block *block, 595 int x, int y, uint8_t *dst) 596{ 597 GLint modifier, idx; 598 GLshort color; 599 GLbyte base_codeword = (GLbyte) block->base_codeword; 600 601 if (base_codeword == -128) 602 base_codeword = -127; 603 604 /* Get pixel index */ 605 idx = etc2_get_pixel_index(block, x, y); 606 modifier = etc2_modifier_tables[block->table_index][idx]; 607 608 if (block->multiplier != 0) 609 /* clamp3(base codeword × 8 + modifier × multiplier × 8) */ 610 color = etc2_clamp3((base_codeword << 3) + 611 ((modifier * block->multiplier) << 3)); 612 else 613 color = etc2_clamp3((base_codeword << 3) + modifier); 614 615 /* Extend 11 bits color value to 16 bits. OpenGL ES 3.0 specification 616 * allows extending the color value to any number of bits. But, an 617 * implementation is not allowed to truncate the 11-bit value to less than 618 * 11 bits. A negative 11-bit value must first be made positive before bit 619 * replication, and then made negative again 620 */ 621 if (color >= 0) 622 color = (color << 5) | (color >> 5); 623 else { 624 color = -color; 625 color = (color << 5) | (color >> 5); 626 color = -color; 627 } 628 ((GLshort *)dst)[0] = color; 629} 630 631static void 632etc2_alpha8_parse_block(struct etc2_block *block, const uint8_t *src) 633{ 634 block->base_codeword = src[0]; 635 block->multiplier = (src[1] >> 4) & 0xf; 636 block->table_index = src[1] & 0xf; 637 block->pixel_indices[1] = (((uint64_t)src[2] << 40) | 638 ((uint64_t)src[3] << 32) | 639 ((uint64_t)src[4] << 24) | 640 ((uint64_t)src[5] << 16) | 641 ((uint64_t)src[6] << 8) | 642 ((uint64_t)src[7])); 643} 644 645static void 646etc2_r11_parse_block(struct etc2_block *block, const uint8_t *src) 647{ 648 /* Parsing logic remains same as for etc2_alpha8_parse_block */ 649 etc2_alpha8_parse_block(block, src); 650} 651 652static void 653etc2_rgba8_parse_block(struct etc2_block *block, const uint8_t *src) 654{ 655 /* RGB component is parsed the same way as for MESA_FORMAT_ETC2_RGB8 */ 656 etc2_rgb8_parse_block(block, src + 8, 657 false /* punchthrough_alpha */); 658 /* Parse Alpha component */ 659 etc2_alpha8_parse_block(block, src); 660} 661 662static void 663etc2_rgba8_fetch_texel(const struct etc2_block *block, 664 int x, int y, uint8_t *dst) 665{ 666 etc2_rgb8_fetch_texel(block, x, y, dst, 667 false /* punchthrough_alpha */); 668 etc2_alpha8_fetch_texel(block, x, y, dst); 669} 670 671static void 672etc2_unpack_rgb8(uint8_t *dst_row, 673 unsigned dst_stride, 674 const uint8_t *src_row, 675 unsigned src_stride, 676 unsigned width, 677 unsigned height) 678{ 679 const unsigned bw = 4, bh = 4, bs = 8, comps = 4; 680 struct etc2_block block; 681 unsigned x, y, i, j; 682 683 for (y = 0; y < height; y += bh) { 684 const uint8_t *src = src_row; 685 /* 686 * Destination texture may not be a multiple of four texels in 687 * height. Compute a safe height to avoid writing outside the texture. 688 */ 689 const unsigned h = MIN2(bh, height - y); 690 691 for (x = 0; x < width; x+= bw) { 692 /* 693 * Destination texture may not be a multiple of four texels in 694 * width. Compute a safe width to avoid writing outside the texture. 695 */ 696 const unsigned w = MIN2(bw, width - x); 697 698 etc2_rgb8_parse_block(&block, src, 699 false /* punchthrough_alpha */); 700 701 for (j = 0; j < h; j++) { 702 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; 703 for (i = 0; i < w; i++) { 704 etc2_rgb8_fetch_texel(&block, i, j, dst, 705 false /* punchthrough_alpha */); 706 dst[3] = 255; 707 dst += comps; 708 } 709 } 710 711 src += bs; 712 } 713 714 src_row += src_stride; 715 } 716} 717 718static void 719etc2_unpack_srgb8(uint8_t *dst_row, 720 unsigned dst_stride, 721 const uint8_t *src_row, 722 unsigned src_stride, 723 unsigned width, 724 unsigned height, 725 bool bgra) 726{ 727 const unsigned bw = 4, bh = 4, bs = 8, comps = 4; 728 struct etc2_block block; 729 unsigned x, y, i, j; 730 uint8_t tmp; 731 732 for (y = 0; y < height; y += bh) { 733 const uint8_t *src = src_row; 734 const unsigned h = MIN2(bh, height - y); 735 736 for (x = 0; x < width; x+= bw) { 737 const unsigned w = MIN2(bw, width - x); 738 etc2_rgb8_parse_block(&block, src, 739 false /* punchthrough_alpha */); 740 741 742 for (j = 0; j < h; j++) { 743 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; 744 for (i = 0; i < w; i++) { 745 etc2_rgb8_fetch_texel(&block, i, j, dst, 746 false /* punchthrough_alpha */); 747 748 if (bgra) { 749 /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */ 750 tmp = dst[0]; 751 dst[0] = dst[2]; 752 dst[2] = tmp; 753 } 754 dst[3] = 255; 755 756 dst += comps; 757 } 758 } 759 src += bs; 760 } 761 762 src_row += src_stride; 763 } 764} 765 766static void 767etc2_unpack_rgba8(uint8_t *dst_row, 768 unsigned dst_stride, 769 const uint8_t *src_row, 770 unsigned src_stride, 771 unsigned width, 772 unsigned height) 773{ 774 /* If internalformat is COMPRESSED_RGBA8_ETC2_EAC, each 4 × 4 block of 775 * RGBA8888 information is compressed to 128 bits. To decode a block, the 776 * two 64-bit integers int64bitAlpha and int64bitColor are calculated. 777 */ 778 const unsigned bw = 4, bh = 4, bs = 16, comps = 4; 779 struct etc2_block block; 780 unsigned x, y, i, j; 781 782 for (y = 0; y < height; y += bh) { 783 const uint8_t *src = src_row; 784 const unsigned h = MIN2(bh, height - y); 785 786 for (x = 0; x < width; x+= bw) { 787 const unsigned w = MIN2(bw, width - x); 788 etc2_rgba8_parse_block(&block, src); 789 790 for (j = 0; j < h; j++) { 791 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; 792 for (i = 0; i < w; i++) { 793 etc2_rgba8_fetch_texel(&block, i, j, dst); 794 dst += comps; 795 } 796 } 797 src += bs; 798 } 799 800 src_row += src_stride; 801 } 802} 803 804static void 805etc2_unpack_srgb8_alpha8(uint8_t *dst_row, 806 unsigned dst_stride, 807 const uint8_t *src_row, 808 unsigned src_stride, 809 unsigned width, 810 unsigned height, 811 bool bgra) 812{ 813 /* If internalformat is COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, each 4 × 4 block 814 * of RGBA8888 information is compressed to 128 bits. To decode a block, the 815 * two 64-bit integers int64bitAlpha and int64bitColor are calculated. 816 */ 817 const unsigned bw = 4, bh = 4, bs = 16, comps = 4; 818 struct etc2_block block; 819 unsigned x, y, i, j; 820 uint8_t tmp; 821 822 for (y = 0; y < height; y += bh) { 823 const unsigned h = MIN2(bh, height - y); 824 const uint8_t *src = src_row; 825 826 for (x = 0; x < width; x+= bw) { 827 const unsigned w = MIN2(bw, width - x); 828 etc2_rgba8_parse_block(&block, src); 829 830 for (j = 0; j < h; j++) { 831 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; 832 for (i = 0; i < w; i++) { 833 etc2_rgba8_fetch_texel(&block, i, j, dst); 834 835 if (bgra) { 836 /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */ 837 tmp = dst[0]; 838 dst[0] = dst[2]; 839 dst[2] = tmp; 840 dst[3] = dst[3]; 841 } 842 843 dst += comps; 844 } 845 } 846 src += bs; 847 } 848 849 src_row += src_stride; 850 } 851} 852 853static void 854etc2_unpack_r11(uint8_t *dst_row, 855 unsigned dst_stride, 856 const uint8_t *src_row, 857 unsigned src_stride, 858 unsigned width, 859 unsigned height) 860{ 861 /* If internalformat is COMPRESSED_R11_EAC, each 4 × 4 block of 862 color information is compressed to 64 bits. 863 */ 864 const unsigned bw = 4, bh = 4, bs = 8, comps = 1, comp_size = 2; 865 struct etc2_block block; 866 unsigned x, y, i, j; 867 868 for (y = 0; y < height; y += bh) { 869 const unsigned h = MIN2(bh, height - y); 870 const uint8_t *src = src_row; 871 872 for (x = 0; x < width; x+= bw) { 873 const unsigned w = MIN2(bw, width - x); 874 etc2_r11_parse_block(&block, src); 875 876 for (j = 0; j < h; j++) { 877 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size; 878 for (i = 0; i < w; i++) { 879 etc2_r11_fetch_texel(&block, i, j, dst); 880 dst += comps * comp_size; 881 } 882 } 883 src += bs; 884 } 885 886 src_row += src_stride; 887 } 888} 889 890static void 891etc2_unpack_rg11(uint8_t *dst_row, 892 unsigned dst_stride, 893 const uint8_t *src_row, 894 unsigned src_stride, 895 unsigned width, 896 unsigned height) 897{ 898 /* If internalformat is COMPRESSED_RG11_EAC, each 4 × 4 block of 899 RG color information is compressed to 128 bits. 900 */ 901 const unsigned bw = 4, bh = 4, bs = 16, comps = 2, comp_size = 2; 902 struct etc2_block block; 903 unsigned x, y, i, j; 904 905 for (y = 0; y < height; y += bh) { 906 const unsigned h = MIN2(bh, height - y); 907 const uint8_t *src = src_row; 908 909 for (x = 0; x < width; x+= bw) { 910 const unsigned w = MIN2(bw, width - x); 911 /* red component */ 912 etc2_r11_parse_block(&block, src); 913 914 for (j = 0; j < h; j++) { 915 uint8_t *dst = dst_row + (y + j) * dst_stride + 916 x * comps * comp_size; 917 for (i = 0; i < w; i++) { 918 etc2_r11_fetch_texel(&block, i, j, dst); 919 dst += comps * comp_size; 920 } 921 } 922 /* green component */ 923 etc2_r11_parse_block(&block, src + 8); 924 925 for (j = 0; j < h; j++) { 926 uint8_t *dst = dst_row + (y + j) * dst_stride + 927 x * comps * comp_size; 928 for (i = 0; i < w; i++) { 929 etc2_r11_fetch_texel(&block, i, j, dst + comp_size); 930 dst += comps * comp_size; 931 } 932 } 933 src += bs; 934 } 935 936 src_row += src_stride; 937 } 938} 939 940static void 941etc2_unpack_signed_r11(uint8_t *dst_row, 942 unsigned dst_stride, 943 const uint8_t *src_row, 944 unsigned src_stride, 945 unsigned width, 946 unsigned height) 947{ 948 /* If internalformat is COMPRESSED_SIGNED_R11_EAC, each 4 × 4 block of 949 red color information is compressed to 64 bits. 950 */ 951 const unsigned bw = 4, bh = 4, bs = 8, comps = 1, comp_size = 2; 952 struct etc2_block block; 953 unsigned x, y, i, j; 954 955 for (y = 0; y < height; y += bh) { 956 const unsigned h = MIN2(bh, height - y); 957 const uint8_t *src = src_row; 958 959 for (x = 0; x < width; x+= bw) { 960 const unsigned w = MIN2(bw, width - x); 961 etc2_r11_parse_block(&block, src); 962 963 for (j = 0; j < h; j++) { 964 uint8_t *dst = dst_row + (y + j) * dst_stride + 965 x * comps * comp_size; 966 for (i = 0; i < w; i++) { 967 etc2_signed_r11_fetch_texel(&block, i, j, dst); 968 dst += comps * comp_size; 969 } 970 } 971 src += bs; 972 } 973 974 src_row += src_stride; 975 } 976} 977 978static void 979etc2_unpack_signed_rg11(uint8_t *dst_row, 980 unsigned dst_stride, 981 const uint8_t *src_row, 982 unsigned src_stride, 983 unsigned width, 984 unsigned height) 985{ 986 /* If internalformat is COMPRESSED_SIGNED_RG11_EAC, each 4 × 4 block of 987 RG color information is compressed to 128 bits. 988 */ 989 const unsigned bw = 4, bh = 4, bs = 16, comps = 2, comp_size = 2; 990 struct etc2_block block; 991 unsigned x, y, i, j; 992 993 for (y = 0; y < height; y += bh) { 994 const unsigned h = MIN2(bh, height - y); 995 const uint8_t *src = src_row; 996 997 for (x = 0; x < width; x+= bw) { 998 const unsigned w = MIN2(bw, width - x); 999 /* red component */ 1000 etc2_r11_parse_block(&block, src); 1001 1002 for (j = 0; j < h; j++) { 1003 uint8_t *dst = dst_row + (y + j) * dst_stride + 1004 x * comps * comp_size; 1005 for (i = 0; i < w; i++) { 1006 etc2_signed_r11_fetch_texel(&block, i, j, dst); 1007 dst += comps * comp_size; 1008 } 1009 } 1010 /* green component */ 1011 etc2_r11_parse_block(&block, src + 8); 1012 1013 for (j = 0; j < h; j++) { 1014 uint8_t *dst = dst_row + (y + j) * dst_stride + 1015 x * comps * comp_size; 1016 for (i = 0; i < w; i++) { 1017 etc2_signed_r11_fetch_texel(&block, i, j, dst + comp_size); 1018 dst += comps * comp_size; 1019 } 1020 } 1021 src += bs; 1022 } 1023 1024 src_row += src_stride; 1025 } 1026} 1027 1028static void 1029etc2_unpack_rgb8_punchthrough_alpha1(uint8_t *dst_row, 1030 unsigned dst_stride, 1031 const uint8_t *src_row, 1032 unsigned src_stride, 1033 unsigned width, 1034 unsigned height) 1035{ 1036 const unsigned bw = 4, bh = 4, bs = 8, comps = 4; 1037 struct etc2_block block; 1038 unsigned x, y, i, j; 1039 1040 for (y = 0; y < height; y += bh) { 1041 const unsigned h = MIN2(bh, height - y); 1042 const uint8_t *src = src_row; 1043 1044 for (x = 0; x < width; x+= bw) { 1045 const unsigned w = MIN2(bw, width - x); 1046 etc2_rgb8_parse_block(&block, src, 1047 true /* punchthrough_alpha */); 1048 for (j = 0; j < h; j++) { 1049 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; 1050 for (i = 0; i < w; i++) { 1051 etc2_rgb8_fetch_texel(&block, i, j, dst, 1052 true /* punchthrough_alpha */); 1053 dst += comps; 1054 } 1055 } 1056 1057 src += bs; 1058 } 1059 1060 src_row += src_stride; 1061 } 1062} 1063 1064static void 1065etc2_unpack_srgb8_punchthrough_alpha1(uint8_t *dst_row, 1066 unsigned dst_stride, 1067 const uint8_t *src_row, 1068 unsigned src_stride, 1069 unsigned width, 1070 unsigned height, 1071 bool bgra) 1072{ 1073 const unsigned bw = 4, bh = 4, bs = 8, comps = 4; 1074 struct etc2_block block; 1075 unsigned x, y, i, j; 1076 uint8_t tmp; 1077 1078 for (y = 0; y < height; y += bh) { 1079 const unsigned h = MIN2(bh, height - y); 1080 const uint8_t *src = src_row; 1081 1082 for (x = 0; x < width; x+= bw) { 1083 const unsigned w = MIN2(bw, width - x); 1084 etc2_rgb8_parse_block(&block, src, 1085 true /* punchthrough_alpha */); 1086 for (j = 0; j < h; j++) { 1087 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; 1088 for (i = 0; i < w; i++) { 1089 etc2_rgb8_fetch_texel(&block, i, j, dst, 1090 true /* punchthrough_alpha */); 1091 1092 if (bgra) { 1093 /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */ 1094 tmp = dst[0]; 1095 dst[0] = dst[2]; 1096 dst[2] = tmp; 1097 dst[3] = dst[3]; 1098 } 1099 1100 dst += comps; 1101 } 1102 } 1103 1104 src += bs; 1105 } 1106 1107 src_row += src_stride; 1108 } 1109} 1110 1111/* ETC2 texture formats are valid in glCompressedTexImage2D and 1112 * glCompressedTexSubImage2D functions */ 1113GLboolean 1114_mesa_texstore_etc2_rgb8(UNUSED_TEXSTORE_PARAMS) 1115{ 1116 assert(0); 1117 1118 return GL_FALSE; 1119} 1120 1121GLboolean 1122_mesa_texstore_etc2_srgb8(UNUSED_TEXSTORE_PARAMS) 1123{ 1124 assert(0); 1125 1126 return GL_FALSE; 1127} 1128 1129GLboolean 1130_mesa_texstore_etc2_rgba8_eac(UNUSED_TEXSTORE_PARAMS) 1131{ 1132 assert(0); 1133 1134 return GL_FALSE; 1135} 1136 1137GLboolean 1138_mesa_texstore_etc2_srgb8_alpha8_eac(UNUSED_TEXSTORE_PARAMS) 1139{ 1140 assert(0); 1141 1142 return GL_FALSE; 1143} 1144 1145GLboolean 1146_mesa_texstore_etc2_r11_eac(UNUSED_TEXSTORE_PARAMS) 1147{ 1148 assert(0); 1149 1150 return GL_FALSE; 1151} 1152 1153GLboolean 1154_mesa_texstore_etc2_signed_r11_eac(UNUSED_TEXSTORE_PARAMS) 1155{ 1156 assert(0); 1157 1158 return GL_FALSE; 1159} 1160 1161GLboolean 1162_mesa_texstore_etc2_rg11_eac(UNUSED_TEXSTORE_PARAMS) 1163{ 1164 assert(0); 1165 1166 return GL_FALSE; 1167} 1168 1169GLboolean 1170_mesa_texstore_etc2_signed_rg11_eac(UNUSED_TEXSTORE_PARAMS) 1171{ 1172 assert(0); 1173 1174 return GL_FALSE; 1175} 1176 1177GLboolean 1178_mesa_texstore_etc2_rgb8_punchthrough_alpha1(UNUSED_TEXSTORE_PARAMS) 1179{ 1180 assert(0); 1181 1182 return GL_FALSE; 1183} 1184 1185GLboolean 1186_mesa_texstore_etc2_srgb8_punchthrough_alpha1(UNUSED_TEXSTORE_PARAMS) 1187{ 1188 assert(0); 1189 1190 return GL_FALSE; 1191} 1192 1193 1194/** 1195 * Decode texture data in any one of following formats: 1196 * `MESA_FORMAT_ETC2_RGB8` 1197 * `MESA_FORMAT_ETC2_SRGB8` 1198 * `MESA_FORMAT_ETC2_RGBA8_EAC` 1199 * `MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC` 1200 * `MESA_FORMAT_ETC2_R11_EAC` 1201 * `MESA_FORMAT_ETC2_RG11_EAC` 1202 * `MESA_FORMAT_ETC2_SIGNED_R11_EAC` 1203 * `MESA_FORMAT_ETC2_SIGNED_RG11_EAC` 1204 * `MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1` 1205 * `MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1` 1206 * 1207 * The size of the source data must be a multiple of the ETC2 block size 1208 * even if the texture image's dimensions are not aligned to 4. 1209 * 1210 * \param src_width in pixels 1211 * \param src_height in pixels 1212 * \param dst_stride in bytes 1213 */ 1214 1215void 1216_mesa_unpack_etc2_format(uint8_t *dst_row, 1217 unsigned dst_stride, 1218 const uint8_t *src_row, 1219 unsigned src_stride, 1220 unsigned src_width, 1221 unsigned src_height, 1222 mesa_format format, 1223 bool bgra) 1224{ 1225 if (format == MESA_FORMAT_ETC2_RGB8) 1226 etc2_unpack_rgb8(dst_row, dst_stride, 1227 src_row, src_stride, 1228 src_width, src_height); 1229 else if (format == MESA_FORMAT_ETC2_SRGB8) 1230 etc2_unpack_srgb8(dst_row, dst_stride, 1231 src_row, src_stride, 1232 src_width, src_height, bgra); 1233 else if (format == MESA_FORMAT_ETC2_RGBA8_EAC) 1234 etc2_unpack_rgba8(dst_row, dst_stride, 1235 src_row, src_stride, 1236 src_width, src_height); 1237 else if (format == MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC) 1238 etc2_unpack_srgb8_alpha8(dst_row, dst_stride, 1239 src_row, src_stride, 1240 src_width, src_height, bgra); 1241 else if (format == MESA_FORMAT_ETC2_R11_EAC) 1242 etc2_unpack_r11(dst_row, dst_stride, 1243 src_row, src_stride, 1244 src_width, src_height); 1245 else if (format == MESA_FORMAT_ETC2_RG11_EAC) 1246 etc2_unpack_rg11(dst_row, dst_stride, 1247 src_row, src_stride, 1248 src_width, src_height); 1249 else if (format == MESA_FORMAT_ETC2_SIGNED_R11_EAC) 1250 etc2_unpack_signed_r11(dst_row, dst_stride, 1251 src_row, src_stride, 1252 src_width, src_height); 1253 else if (format == MESA_FORMAT_ETC2_SIGNED_RG11_EAC) 1254 etc2_unpack_signed_rg11(dst_row, dst_stride, 1255 src_row, src_stride, 1256 src_width, src_height); 1257 else if (format == MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1) 1258 etc2_unpack_rgb8_punchthrough_alpha1(dst_row, dst_stride, 1259 src_row, src_stride, 1260 src_width, src_height); 1261 else if (format == MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1) 1262 etc2_unpack_srgb8_punchthrough_alpha1(dst_row, dst_stride, 1263 src_row, src_stride, 1264 src_width, src_height, bgra); 1265} 1266 1267 1268 1269static void 1270fetch_etc1_rgb8(const GLubyte *map, 1271 GLint rowStride, GLint i, GLint j, 1272 GLfloat *texel) 1273{ 1274 struct etc1_block block; 1275 GLubyte dst[3]; 1276 const GLubyte *src; 1277 1278 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; 1279 1280 etc1_parse_block(&block, src); 1281 etc1_fetch_texel(&block, i % 4, j % 4, dst); 1282 1283 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]); 1284 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]); 1285 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]); 1286 texel[ACOMP] = 1.0f; 1287} 1288 1289 1290static void 1291fetch_etc2_rgb8(const GLubyte *map, 1292 GLint rowStride, GLint i, GLint j, GLfloat *texel) 1293{ 1294 struct etc2_block block; 1295 uint8_t dst[3]; 1296 const uint8_t *src; 1297 1298 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; 1299 1300 etc2_rgb8_parse_block(&block, src, 1301 false /* punchthrough_alpha */); 1302 etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst, 1303 false /* punchthrough_alpha */); 1304 1305 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]); 1306 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]); 1307 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]); 1308 texel[ACOMP] = 1.0f; 1309} 1310 1311static void 1312fetch_etc2_srgb8(const GLubyte *map, 1313 GLint rowStride, GLint i, GLint j, GLfloat *texel) 1314{ 1315 struct etc2_block block; 1316 uint8_t dst[3]; 1317 const uint8_t *src; 1318 1319 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; 1320 1321 etc2_rgb8_parse_block(&block, src, 1322 false /* punchthrough_alpha */); 1323 etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst, 1324 false /* punchthrough_alpha */); 1325 1326 texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]); 1327 texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]); 1328 texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]); 1329 texel[ACOMP] = 1.0f; 1330} 1331 1332static void 1333fetch_etc2_rgba8_eac(const GLubyte *map, 1334 GLint rowStride, GLint i, GLint j, GLfloat *texel) 1335{ 1336 struct etc2_block block; 1337 uint8_t dst[4]; 1338 const uint8_t *src; 1339 1340 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; 1341 1342 etc2_rgba8_parse_block(&block, src); 1343 etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst); 1344 1345 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]); 1346 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]); 1347 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]); 1348 texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]); 1349} 1350 1351static void 1352fetch_etc2_srgb8_alpha8_eac(const GLubyte *map, 1353 GLint rowStride, GLint i, GLint j, GLfloat *texel) 1354{ 1355 struct etc2_block block; 1356 uint8_t dst[4]; 1357 const uint8_t *src; 1358 1359 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; 1360 1361 etc2_rgba8_parse_block(&block, src); 1362 etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst); 1363 1364 texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]); 1365 texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]); 1366 texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]); 1367 texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]); 1368} 1369 1370static void 1371fetch_etc2_r11_eac(const GLubyte *map, 1372 GLint rowStride, GLint i, GLint j, GLfloat *texel) 1373{ 1374 struct etc2_block block; 1375 GLushort dst; 1376 const uint8_t *src; 1377 1378 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; 1379 1380 etc2_r11_parse_block(&block, src); 1381 etc2_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)&dst); 1382 1383 texel[RCOMP] = USHORT_TO_FLOAT(dst); 1384 texel[GCOMP] = 0.0f; 1385 texel[BCOMP] = 0.0f; 1386 texel[ACOMP] = 1.0f; 1387} 1388 1389static void 1390fetch_etc2_rg11_eac(const GLubyte *map, 1391 GLint rowStride, GLint i, GLint j, GLfloat *texel) 1392{ 1393 struct etc2_block block; 1394 GLushort dst[2]; 1395 const uint8_t *src; 1396 1397 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; 1398 1399 /* red component */ 1400 etc2_r11_parse_block(&block, src); 1401 etc2_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)dst); 1402 1403 /* green component */ 1404 etc2_r11_parse_block(&block, src + 8); 1405 etc2_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)(dst + 1)); 1406 1407 texel[RCOMP] = USHORT_TO_FLOAT(dst[0]); 1408 texel[GCOMP] = USHORT_TO_FLOAT(dst[1]); 1409 texel[BCOMP] = 0.0f; 1410 texel[ACOMP] = 1.0f; 1411} 1412 1413static void 1414fetch_etc2_signed_r11_eac(const GLubyte *map, 1415 GLint rowStride, GLint i, GLint j, GLfloat *texel) 1416{ 1417 struct etc2_block block; 1418 GLushort dst; 1419 const uint8_t *src; 1420 1421 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; 1422 1423 etc2_r11_parse_block(&block, src); 1424 etc2_signed_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)&dst); 1425 1426 texel[RCOMP] = SHORT_TO_FLOAT(dst); 1427 texel[GCOMP] = 0.0f; 1428 texel[BCOMP] = 0.0f; 1429 texel[ACOMP] = 1.0f; 1430} 1431 1432static void 1433fetch_etc2_signed_rg11_eac(const GLubyte *map, 1434 GLint rowStride, GLint i, GLint j, GLfloat *texel) 1435{ 1436 struct etc2_block block; 1437 GLushort dst[2]; 1438 const uint8_t *src; 1439 1440 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; 1441 1442 /* red component */ 1443 etc2_r11_parse_block(&block, src); 1444 etc2_signed_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)dst); 1445 1446 /* green component */ 1447 etc2_r11_parse_block(&block, src + 8); 1448 etc2_signed_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)(dst + 1)); 1449 1450 texel[RCOMP] = SHORT_TO_FLOAT(dst[0]); 1451 texel[GCOMP] = SHORT_TO_FLOAT(dst[1]); 1452 texel[BCOMP] = 0.0f; 1453 texel[ACOMP] = 1.0f; 1454} 1455 1456static void 1457fetch_etc2_rgb8_punchthrough_alpha1(const GLubyte *map, 1458 GLint rowStride, GLint i, GLint j, 1459 GLfloat *texel) 1460{ 1461 struct etc2_block block; 1462 uint8_t dst[4]; 1463 const uint8_t *src; 1464 1465 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; 1466 1467 etc2_rgb8_parse_block(&block, src, 1468 true /* punchthrough alpha */); 1469 etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst, 1470 true /* punchthrough alpha */); 1471 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]); 1472 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]); 1473 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]); 1474 texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]); 1475} 1476 1477static void 1478fetch_etc2_srgb8_punchthrough_alpha1(const GLubyte *map, 1479 GLint rowStride, 1480 GLint i, GLint j, GLfloat *texel) 1481{ 1482 struct etc2_block block; 1483 uint8_t dst[4]; 1484 const uint8_t *src; 1485 1486 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; 1487 1488 etc2_rgb8_parse_block(&block, src, 1489 true /* punchthrough alpha */); 1490 etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst, 1491 true /* punchthrough alpha */); 1492 texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]); 1493 texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]); 1494 texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]); 1495 texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]); 1496} 1497 1498 1499compressed_fetch_func 1500_mesa_get_etc_fetch_func(mesa_format format) 1501{ 1502 switch (format) { 1503 case MESA_FORMAT_ETC1_RGB8: 1504 return fetch_etc1_rgb8; 1505 case MESA_FORMAT_ETC2_RGB8: 1506 return fetch_etc2_rgb8; 1507 case MESA_FORMAT_ETC2_SRGB8: 1508 return fetch_etc2_srgb8; 1509 case MESA_FORMAT_ETC2_RGBA8_EAC: 1510 return fetch_etc2_rgba8_eac; 1511 case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC: 1512 return fetch_etc2_srgb8_alpha8_eac; 1513 case MESA_FORMAT_ETC2_R11_EAC: 1514 return fetch_etc2_r11_eac; 1515 case MESA_FORMAT_ETC2_RG11_EAC: 1516 return fetch_etc2_rg11_eac; 1517 case MESA_FORMAT_ETC2_SIGNED_R11_EAC: 1518 return fetch_etc2_signed_r11_eac; 1519 case MESA_FORMAT_ETC2_SIGNED_RG11_EAC: 1520 return fetch_etc2_signed_rg11_eac; 1521 case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: 1522 return fetch_etc2_rgb8_punchthrough_alpha1; 1523 case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: 1524 return fetch_etc2_srgb8_punchthrough_alpha1; 1525 default: 1526 return NULL; 1527 } 1528} 1529