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} 552 553static void 554etc2_alpha8_fetch_texel(const struct etc2_block *block, 555 int x, int y, uint8_t *dst) 556{ 557 int modifier, alpha, idx; 558 /* get pixel index */ 559 idx = etc2_get_pixel_index(block, x, y); 560 modifier = etc2_modifier_tables[block->table_index][idx]; 561 alpha = block->base_codeword + modifier * block->multiplier; 562 dst[3] = etc2_clamp(alpha); 563} 564 565static void 566etc2_r11_fetch_texel(const struct etc2_block *block, 567 int x, int y, uint8_t *dst) 568{ 569 GLint modifier, idx; 570 GLshort color; 571 /* Get pixel index */ 572 idx = etc2_get_pixel_index(block, x, y); 573 modifier = etc2_modifier_tables[block->table_index][idx]; 574 575 if (block->multiplier != 0) 576 /* clamp2(base codeword × 8 + 4 + modifier × multiplier × 8) */ 577 color = etc2_clamp2(((block->base_codeword << 3) | 0x4) + 578 ((modifier * block->multiplier) << 3)); 579 else 580 color = etc2_clamp2(((block->base_codeword << 3) | 0x4) + modifier); 581 582 /* Extend 11 bits color value to 16 bits. OpenGL ES 3.0 specification 583 * allows extending the color value to any number of bits. But, an 584 * implementation is not allowed to truncate the 11-bit value to less than 585 * 11 bits." 586 */ 587 color = (color << 5) | (color >> 6); 588 ((GLushort *)dst)[0] = color; 589} 590 591static void 592etc2_signed_r11_fetch_texel(const struct etc2_block *block, 593 int x, int y, uint8_t *dst) 594{ 595 GLint modifier, idx; 596 GLshort color; 597 GLbyte base_codeword = (GLbyte) block->base_codeword; 598 599 if (base_codeword == -128) 600 base_codeword = -127; 601 602 /* Get pixel index */ 603 idx = etc2_get_pixel_index(block, x, y); 604 modifier = etc2_modifier_tables[block->table_index][idx]; 605 606 if (block->multiplier != 0) 607 /* clamp3(base codeword × 8 + modifier × multiplier × 8) */ 608 color = etc2_clamp3((base_codeword << 3) + 609 ((modifier * block->multiplier) << 3)); 610 else 611 color = etc2_clamp3((base_codeword << 3) + modifier); 612 613 /* Extend 11 bits color value to 16 bits. OpenGL ES 3.0 specification 614 * allows extending the color value to any number of bits. But, an 615 * implementation is not allowed to truncate the 11-bit value to less than 616 * 11 bits. A negative 11-bit value must first be made positive before bit 617 * replication, and then made negative again 618 */ 619 if (color >= 0) 620 color = (color << 5) | (color >> 5); 621 else { 622 color = -color; 623 color = (color << 5) | (color >> 5); 624 color = -color; 625 } 626 ((GLshort *)dst)[0] = color; 627} 628 629static void 630etc2_alpha8_parse_block(struct etc2_block *block, const uint8_t *src) 631{ 632 block->base_codeword = src[0]; 633 block->multiplier = (src[1] >> 4) & 0xf; 634 block->table_index = src[1] & 0xf; 635 block->pixel_indices[1] = (((uint64_t)src[2] << 40) | 636 ((uint64_t)src[3] << 32) | 637 ((uint64_t)src[4] << 24) | 638 ((uint64_t)src[5] << 16) | 639 ((uint64_t)src[6] << 8) | 640 ((uint64_t)src[7])); 641} 642 643static void 644etc2_r11_parse_block(struct etc2_block *block, const uint8_t *src) 645{ 646 /* Parsing logic remains same as for etc2_alpha8_parse_block */ 647 etc2_alpha8_parse_block(block, src); 648} 649 650static void 651etc2_rgba8_parse_block(struct etc2_block *block, const uint8_t *src) 652{ 653 /* RGB component is parsed the same way as for MESA_FORMAT_ETC2_RGB8 */ 654 etc2_rgb8_parse_block(block, src + 8, 655 false /* punchthrough_alpha */); 656 /* Parse Alpha component */ 657 etc2_alpha8_parse_block(block, src); 658} 659 660static void 661etc2_rgba8_fetch_texel(const struct etc2_block *block, 662 int x, int y, uint8_t *dst) 663{ 664 etc2_rgb8_fetch_texel(block, x, y, dst, 665 false /* punchthrough_alpha */); 666 etc2_alpha8_fetch_texel(block, x, y, dst); 667} 668 669static void 670etc2_unpack_rgb8(uint8_t *dst_row, 671 unsigned dst_stride, 672 const uint8_t *src_row, 673 unsigned src_stride, 674 unsigned width, 675 unsigned height) 676{ 677 const unsigned bw = 4, bh = 4, bs = 8, comps = 4; 678 struct etc2_block block; 679 unsigned x, y, i, j; 680 681 for (y = 0; y < height; y += bh) { 682 const uint8_t *src = src_row; 683 /* 684 * Destination texture may not be a multiple of four texels in 685 * height. Compute a safe height to avoid writing outside the texture. 686 */ 687 const unsigned h = MIN2(bh, height - y); 688 689 for (x = 0; x < width; x+= bw) { 690 /* 691 * Destination texture may not be a multiple of four texels in 692 * width. Compute a safe width to avoid writing outside the texture. 693 */ 694 const unsigned w = MIN2(bw, width - x); 695 696 etc2_rgb8_parse_block(&block, src, 697 false /* punchthrough_alpha */); 698 699 for (j = 0; j < h; j++) { 700 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; 701 for (i = 0; i < w; i++) { 702 etc2_rgb8_fetch_texel(&block, i, j, dst, 703 false /* punchthrough_alpha */); 704 dst[3] = 255; 705 dst += comps; 706 } 707 } 708 709 src += bs; 710 } 711 712 src_row += src_stride; 713 } 714} 715 716static void 717etc2_unpack_srgb8(uint8_t *dst_row, 718 unsigned dst_stride, 719 const uint8_t *src_row, 720 unsigned src_stride, 721 unsigned width, 722 unsigned height, 723 bool bgra) 724{ 725 const unsigned bw = 4, bh = 4, bs = 8, comps = 4; 726 struct etc2_block block; 727 unsigned x, y, i, j; 728 uint8_t tmp; 729 730 for (y = 0; y < height; y += bh) { 731 const uint8_t *src = src_row; 732 const unsigned h = MIN2(bh, height - y); 733 734 for (x = 0; x < width; x+= bw) { 735 const unsigned w = MIN2(bw, width - x); 736 etc2_rgb8_parse_block(&block, src, 737 false /* punchthrough_alpha */); 738 739 740 for (j = 0; j < h; j++) { 741 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; 742 for (i = 0; i < w; i++) { 743 etc2_rgb8_fetch_texel(&block, i, j, dst, 744 false /* punchthrough_alpha */); 745 746 if (bgra) { 747 /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */ 748 tmp = dst[0]; 749 dst[0] = dst[2]; 750 dst[2] = tmp; 751 dst[3] = 255; 752 } 753 754 dst += comps; 755 } 756 } 757 src += bs; 758 } 759 760 src_row += src_stride; 761 } 762} 763 764static void 765etc2_unpack_rgba8(uint8_t *dst_row, 766 unsigned dst_stride, 767 const uint8_t *src_row, 768 unsigned src_stride, 769 unsigned width, 770 unsigned height) 771{ 772 /* If internalformat is COMPRESSED_RGBA8_ETC2_EAC, each 4 × 4 block of 773 * RGBA8888 information is compressed to 128 bits. To decode a block, the 774 * two 64-bit integers int64bitAlpha and int64bitColor are calculated. 775 */ 776 const unsigned bw = 4, bh = 4, bs = 16, comps = 4; 777 struct etc2_block block; 778 unsigned x, y, i, j; 779 780 for (y = 0; y < height; y += bh) { 781 const uint8_t *src = src_row; 782 const unsigned h = MIN2(bh, height - y); 783 784 for (x = 0; x < width; x+= bw) { 785 const unsigned w = MIN2(bw, width - x); 786 etc2_rgba8_parse_block(&block, src); 787 788 for (j = 0; j < h; j++) { 789 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; 790 for (i = 0; i < w; i++) { 791 etc2_rgba8_fetch_texel(&block, i, j, dst); 792 dst += comps; 793 } 794 } 795 src += bs; 796 } 797 798 src_row += src_stride; 799 } 800} 801 802static void 803etc2_unpack_srgb8_alpha8(uint8_t *dst_row, 804 unsigned dst_stride, 805 const uint8_t *src_row, 806 unsigned src_stride, 807 unsigned width, 808 unsigned height, 809 bool bgra) 810{ 811 /* If internalformat is COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, each 4 × 4 block 812 * of RGBA8888 information is compressed to 128 bits. To decode a block, the 813 * two 64-bit integers int64bitAlpha and int64bitColor are calculated. 814 */ 815 const unsigned bw = 4, bh = 4, bs = 16, comps = 4; 816 struct etc2_block block; 817 unsigned x, y, i, j; 818 uint8_t tmp; 819 820 for (y = 0; y < height; y += bh) { 821 const unsigned h = MIN2(bh, height - y); 822 const uint8_t *src = src_row; 823 824 for (x = 0; x < width; x+= bw) { 825 const unsigned w = MIN2(bw, width - x); 826 etc2_rgba8_parse_block(&block, src); 827 828 for (j = 0; j < h; j++) { 829 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; 830 for (i = 0; i < w; i++) { 831 etc2_rgba8_fetch_texel(&block, i, j, dst); 832 833 if (bgra) { 834 /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */ 835 tmp = dst[0]; 836 dst[0] = dst[2]; 837 dst[2] = tmp; 838 dst[3] = dst[3]; 839 } 840 841 dst += comps; 842 } 843 } 844 src += bs; 845 } 846 847 src_row += src_stride; 848 } 849} 850 851static void 852etc2_unpack_r11(uint8_t *dst_row, 853 unsigned dst_stride, 854 const uint8_t *src_row, 855 unsigned src_stride, 856 unsigned width, 857 unsigned height) 858{ 859 /* If internalformat is COMPRESSED_R11_EAC, each 4 × 4 block of 860 color information is compressed to 64 bits. 861 */ 862 const unsigned bw = 4, bh = 4, bs = 8, comps = 1, comp_size = 2; 863 struct etc2_block block; 864 unsigned x, y, i, j; 865 866 for (y = 0; y < height; y += bh) { 867 const unsigned h = MIN2(bh, height - y); 868 const uint8_t *src = src_row; 869 870 for (x = 0; x < width; x+= bw) { 871 const unsigned w = MIN2(bw, width - x); 872 etc2_r11_parse_block(&block, src); 873 874 for (j = 0; j < h; j++) { 875 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size; 876 for (i = 0; i < w; i++) { 877 etc2_r11_fetch_texel(&block, i, j, dst); 878 dst += comps * comp_size; 879 } 880 } 881 src += bs; 882 } 883 884 src_row += src_stride; 885 } 886} 887 888static void 889etc2_unpack_rg11(uint8_t *dst_row, 890 unsigned dst_stride, 891 const uint8_t *src_row, 892 unsigned src_stride, 893 unsigned width, 894 unsigned height) 895{ 896 /* If internalformat is COMPRESSED_RG11_EAC, each 4 × 4 block of 897 RG color information is compressed to 128 bits. 898 */ 899 const unsigned bw = 4, bh = 4, bs = 16, comps = 2, comp_size = 2; 900 struct etc2_block block; 901 unsigned x, y, i, j; 902 903 for (y = 0; y < height; y += bh) { 904 const unsigned h = MIN2(bh, height - y); 905 const uint8_t *src = src_row; 906 907 for (x = 0; x < width; x+= bw) { 908 const unsigned w = MIN2(bw, width - x); 909 /* red component */ 910 etc2_r11_parse_block(&block, src); 911 912 for (j = 0; j < h; j++) { 913 uint8_t *dst = dst_row + (y + j) * dst_stride + 914 x * comps * comp_size; 915 for (i = 0; i < w; i++) { 916 etc2_r11_fetch_texel(&block, i, j, dst); 917 dst += comps * comp_size; 918 } 919 } 920 /* green component */ 921 etc2_r11_parse_block(&block, src + 8); 922 923 for (j = 0; j < h; j++) { 924 uint8_t *dst = dst_row + (y + j) * dst_stride + 925 x * comps * comp_size; 926 for (i = 0; i < w; i++) { 927 etc2_r11_fetch_texel(&block, i, j, dst + comp_size); 928 dst += comps * comp_size; 929 } 930 } 931 src += bs; 932 } 933 934 src_row += src_stride; 935 } 936} 937 938static void 939etc2_unpack_signed_r11(uint8_t *dst_row, 940 unsigned dst_stride, 941 const uint8_t *src_row, 942 unsigned src_stride, 943 unsigned width, 944 unsigned height) 945{ 946 /* If internalformat is COMPRESSED_SIGNED_R11_EAC, each 4 × 4 block of 947 red color information is compressed to 64 bits. 948 */ 949 const unsigned bw = 4, bh = 4, bs = 8, comps = 1, comp_size = 2; 950 struct etc2_block block; 951 unsigned x, y, i, j; 952 953 for (y = 0; y < height; y += bh) { 954 const unsigned h = MIN2(bh, height - y); 955 const uint8_t *src = src_row; 956 957 for (x = 0; x < width; x+= bw) { 958 const unsigned w = MIN2(bw, width - x); 959 etc2_r11_parse_block(&block, src); 960 961 for (j = 0; j < h; j++) { 962 uint8_t *dst = dst_row + (y + j) * dst_stride + 963 x * comps * comp_size; 964 for (i = 0; i < w; i++) { 965 etc2_signed_r11_fetch_texel(&block, i, j, dst); 966 dst += comps * comp_size; 967 } 968 } 969 src += bs; 970 } 971 972 src_row += src_stride; 973 } 974} 975 976static void 977etc2_unpack_signed_rg11(uint8_t *dst_row, 978 unsigned dst_stride, 979 const uint8_t *src_row, 980 unsigned src_stride, 981 unsigned width, 982 unsigned height) 983{ 984 /* If internalformat is COMPRESSED_SIGNED_RG11_EAC, each 4 × 4 block of 985 RG color information is compressed to 128 bits. 986 */ 987 const unsigned bw = 4, bh = 4, bs = 16, comps = 2, comp_size = 2; 988 struct etc2_block block; 989 unsigned x, y, i, j; 990 991 for (y = 0; y < height; y += bh) { 992 const unsigned h = MIN2(bh, height - y); 993 const uint8_t *src = src_row; 994 995 for (x = 0; x < width; x+= bw) { 996 const unsigned w = MIN2(bw, width - x); 997 /* red component */ 998 etc2_r11_parse_block(&block, src); 999 1000 for (j = 0; j < h; j++) { 1001 uint8_t *dst = dst_row + (y + j) * dst_stride + 1002 x * comps * comp_size; 1003 for (i = 0; i < w; i++) { 1004 etc2_signed_r11_fetch_texel(&block, i, j, dst); 1005 dst += comps * comp_size; 1006 } 1007 } 1008 /* green component */ 1009 etc2_r11_parse_block(&block, src + 8); 1010 1011 for (j = 0; j < h; j++) { 1012 uint8_t *dst = dst_row + (y + j) * dst_stride + 1013 x * comps * comp_size; 1014 for (i = 0; i < w; i++) { 1015 etc2_signed_r11_fetch_texel(&block, i, j, dst + comp_size); 1016 dst += comps * comp_size; 1017 } 1018 } 1019 src += bs; 1020 } 1021 1022 src_row += src_stride; 1023 } 1024} 1025 1026static void 1027etc2_unpack_rgb8_punchthrough_alpha1(uint8_t *dst_row, 1028 unsigned dst_stride, 1029 const uint8_t *src_row, 1030 unsigned src_stride, 1031 unsigned width, 1032 unsigned height) 1033{ 1034 const unsigned bw = 4, bh = 4, bs = 8, comps = 4; 1035 struct etc2_block block; 1036 unsigned x, y, i, j; 1037 1038 for (y = 0; y < height; y += bh) { 1039 const unsigned h = MIN2(bh, height - y); 1040 const uint8_t *src = src_row; 1041 1042 for (x = 0; x < width; x+= bw) { 1043 const unsigned w = MIN2(bw, width - x); 1044 etc2_rgb8_parse_block(&block, src, 1045 true /* punchthrough_alpha */); 1046 for (j = 0; j < h; j++) { 1047 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; 1048 for (i = 0; i < w; i++) { 1049 etc2_rgb8_fetch_texel(&block, i, j, dst, 1050 true /* punchthrough_alpha */); 1051 dst += comps; 1052 } 1053 } 1054 1055 src += bs; 1056 } 1057 1058 src_row += src_stride; 1059 } 1060} 1061 1062static void 1063etc2_unpack_srgb8_punchthrough_alpha1(uint8_t *dst_row, 1064 unsigned dst_stride, 1065 const uint8_t *src_row, 1066 unsigned src_stride, 1067 unsigned width, 1068 unsigned height, 1069 bool bgra) 1070{ 1071 const unsigned bw = 4, bh = 4, bs = 8, comps = 4; 1072 struct etc2_block block; 1073 unsigned x, y, i, j; 1074 uint8_t tmp; 1075 1076 for (y = 0; y < height; y += bh) { 1077 const unsigned h = MIN2(bh, height - y); 1078 const uint8_t *src = src_row; 1079 1080 for (x = 0; x < width; x+= bw) { 1081 const unsigned w = MIN2(bw, width - x); 1082 etc2_rgb8_parse_block(&block, src, 1083 true /* punchthrough_alpha */); 1084 for (j = 0; j < h; j++) { 1085 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; 1086 for (i = 0; i < w; i++) { 1087 etc2_rgb8_fetch_texel(&block, i, j, dst, 1088 true /* punchthrough_alpha */); 1089 1090 if (bgra) { 1091 /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */ 1092 tmp = dst[0]; 1093 dst[0] = dst[2]; 1094 dst[2] = tmp; 1095 dst[3] = dst[3]; 1096 } 1097 1098 dst += comps; 1099 } 1100 } 1101 1102 src += bs; 1103 } 1104 1105 src_row += src_stride; 1106 } 1107} 1108 1109/* ETC2 texture formats are valid in glCompressedTexImage2D and 1110 * glCompressedTexSubImage2D functions */ 1111GLboolean 1112_mesa_texstore_etc2_rgb8(UNUSED_TEXSTORE_PARAMS) 1113{ 1114 assert(0); 1115 1116 return GL_FALSE; 1117} 1118 1119GLboolean 1120_mesa_texstore_etc2_srgb8(UNUSED_TEXSTORE_PARAMS) 1121{ 1122 assert(0); 1123 1124 return GL_FALSE; 1125} 1126 1127GLboolean 1128_mesa_texstore_etc2_rgba8_eac(UNUSED_TEXSTORE_PARAMS) 1129{ 1130 assert(0); 1131 1132 return GL_FALSE; 1133} 1134 1135GLboolean 1136_mesa_texstore_etc2_srgb8_alpha8_eac(UNUSED_TEXSTORE_PARAMS) 1137{ 1138 assert(0); 1139 1140 return GL_FALSE; 1141} 1142 1143GLboolean 1144_mesa_texstore_etc2_r11_eac(UNUSED_TEXSTORE_PARAMS) 1145{ 1146 assert(0); 1147 1148 return GL_FALSE; 1149} 1150 1151GLboolean 1152_mesa_texstore_etc2_signed_r11_eac(UNUSED_TEXSTORE_PARAMS) 1153{ 1154 assert(0); 1155 1156 return GL_FALSE; 1157} 1158 1159GLboolean 1160_mesa_texstore_etc2_rg11_eac(UNUSED_TEXSTORE_PARAMS) 1161{ 1162 assert(0); 1163 1164 return GL_FALSE; 1165} 1166 1167GLboolean 1168_mesa_texstore_etc2_signed_rg11_eac(UNUSED_TEXSTORE_PARAMS) 1169{ 1170 assert(0); 1171 1172 return GL_FALSE; 1173} 1174 1175GLboolean 1176_mesa_texstore_etc2_rgb8_punchthrough_alpha1(UNUSED_TEXSTORE_PARAMS) 1177{ 1178 assert(0); 1179 1180 return GL_FALSE; 1181} 1182 1183GLboolean 1184_mesa_texstore_etc2_srgb8_punchthrough_alpha1(UNUSED_TEXSTORE_PARAMS) 1185{ 1186 assert(0); 1187 1188 return GL_FALSE; 1189} 1190 1191 1192/** 1193 * Decode texture data in any one of following formats: 1194 * `MESA_FORMAT_ETC2_RGB8` 1195 * `MESA_FORMAT_ETC2_SRGB8` 1196 * `MESA_FORMAT_ETC2_RGBA8_EAC` 1197 * `MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC` 1198 * `MESA_FORMAT_ETC2_R11_EAC` 1199 * `MESA_FORMAT_ETC2_RG11_EAC` 1200 * `MESA_FORMAT_ETC2_SIGNED_R11_EAC` 1201 * `MESA_FORMAT_ETC2_SIGNED_RG11_EAC` 1202 * `MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1` 1203 * `MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1` 1204 * 1205 * The size of the source data must be a multiple of the ETC2 block size 1206 * even if the texture image's dimensions are not aligned to 4. 1207 * 1208 * \param src_width in pixels 1209 * \param src_height in pixels 1210 * \param dst_stride in bytes 1211 */ 1212 1213void 1214_mesa_unpack_etc2_format(uint8_t *dst_row, 1215 unsigned dst_stride, 1216 const uint8_t *src_row, 1217 unsigned src_stride, 1218 unsigned src_width, 1219 unsigned src_height, 1220 mesa_format format, 1221 bool bgra) 1222{ 1223 if (format == MESA_FORMAT_ETC2_RGB8) 1224 etc2_unpack_rgb8(dst_row, dst_stride, 1225 src_row, src_stride, 1226 src_width, src_height); 1227 else if (format == MESA_FORMAT_ETC2_SRGB8) 1228 etc2_unpack_srgb8(dst_row, dst_stride, 1229 src_row, src_stride, 1230 src_width, src_height, bgra); 1231 else if (format == MESA_FORMAT_ETC2_RGBA8_EAC) 1232 etc2_unpack_rgba8(dst_row, dst_stride, 1233 src_row, src_stride, 1234 src_width, src_height); 1235 else if (format == MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC) 1236 etc2_unpack_srgb8_alpha8(dst_row, dst_stride, 1237 src_row, src_stride, 1238 src_width, src_height, bgra); 1239 else if (format == MESA_FORMAT_ETC2_R11_EAC) 1240 etc2_unpack_r11(dst_row, dst_stride, 1241 src_row, src_stride, 1242 src_width, src_height); 1243 else if (format == MESA_FORMAT_ETC2_RG11_EAC) 1244 etc2_unpack_rg11(dst_row, dst_stride, 1245 src_row, src_stride, 1246 src_width, src_height); 1247 else if (format == MESA_FORMAT_ETC2_SIGNED_R11_EAC) 1248 etc2_unpack_signed_r11(dst_row, dst_stride, 1249 src_row, src_stride, 1250 src_width, src_height); 1251 else if (format == MESA_FORMAT_ETC2_SIGNED_RG11_EAC) 1252 etc2_unpack_signed_rg11(dst_row, dst_stride, 1253 src_row, src_stride, 1254 src_width, src_height); 1255 else if (format == MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1) 1256 etc2_unpack_rgb8_punchthrough_alpha1(dst_row, dst_stride, 1257 src_row, src_stride, 1258 src_width, src_height); 1259 else if (format == MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1) 1260 etc2_unpack_srgb8_punchthrough_alpha1(dst_row, dst_stride, 1261 src_row, src_stride, 1262 src_width, src_height, bgra); 1263} 1264 1265 1266 1267static void 1268fetch_etc1_rgb8(const GLubyte *map, 1269 GLint rowStride, GLint i, GLint j, 1270 GLfloat *texel) 1271{ 1272 struct etc1_block block; 1273 GLubyte dst[3]; 1274 const GLubyte *src; 1275 1276 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; 1277 1278 etc1_parse_block(&block, src); 1279 etc1_fetch_texel(&block, i % 4, j % 4, dst); 1280 1281 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]); 1282 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]); 1283 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]); 1284 texel[ACOMP] = 1.0f; 1285} 1286 1287 1288static void 1289fetch_etc2_rgb8(const GLubyte *map, 1290 GLint rowStride, GLint i, GLint j, GLfloat *texel) 1291{ 1292 struct etc2_block block; 1293 uint8_t dst[3]; 1294 const uint8_t *src; 1295 1296 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; 1297 1298 etc2_rgb8_parse_block(&block, src, 1299 false /* punchthrough_alpha */); 1300 etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst, 1301 false /* punchthrough_alpha */); 1302 1303 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]); 1304 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]); 1305 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]); 1306 texel[ACOMP] = 1.0f; 1307} 1308 1309static void 1310fetch_etc2_srgb8(const GLubyte *map, 1311 GLint rowStride, GLint i, GLint j, GLfloat *texel) 1312{ 1313 struct etc2_block block; 1314 uint8_t dst[3]; 1315 const uint8_t *src; 1316 1317 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; 1318 1319 etc2_rgb8_parse_block(&block, src, 1320 false /* punchthrough_alpha */); 1321 etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst, 1322 false /* punchthrough_alpha */); 1323 1324 texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]); 1325 texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]); 1326 texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]); 1327 texel[ACOMP] = 1.0f; 1328} 1329 1330static void 1331fetch_etc2_rgba8_eac(const GLubyte *map, 1332 GLint rowStride, GLint i, GLint j, GLfloat *texel) 1333{ 1334 struct etc2_block block; 1335 uint8_t dst[4]; 1336 const uint8_t *src; 1337 1338 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; 1339 1340 etc2_rgba8_parse_block(&block, src); 1341 etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst); 1342 1343 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]); 1344 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]); 1345 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]); 1346 texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]); 1347} 1348 1349static void 1350fetch_etc2_srgb8_alpha8_eac(const GLubyte *map, 1351 GLint rowStride, GLint i, GLint j, GLfloat *texel) 1352{ 1353 struct etc2_block block; 1354 uint8_t dst[4]; 1355 const uint8_t *src; 1356 1357 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; 1358 1359 etc2_rgba8_parse_block(&block, src); 1360 etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst); 1361 1362 texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]); 1363 texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]); 1364 texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]); 1365 texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]); 1366} 1367 1368static void 1369fetch_etc2_r11_eac(const GLubyte *map, 1370 GLint rowStride, GLint i, GLint j, GLfloat *texel) 1371{ 1372 struct etc2_block block; 1373 GLushort dst; 1374 const uint8_t *src; 1375 1376 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; 1377 1378 etc2_r11_parse_block(&block, src); 1379 etc2_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)&dst); 1380 1381 texel[RCOMP] = USHORT_TO_FLOAT(dst); 1382 texel[GCOMP] = 0.0f; 1383 texel[BCOMP] = 0.0f; 1384 texel[ACOMP] = 1.0f; 1385} 1386 1387static void 1388fetch_etc2_rg11_eac(const GLubyte *map, 1389 GLint rowStride, GLint i, GLint j, GLfloat *texel) 1390{ 1391 struct etc2_block block; 1392 GLushort dst[2]; 1393 const uint8_t *src; 1394 1395 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; 1396 1397 /* red component */ 1398 etc2_r11_parse_block(&block, src); 1399 etc2_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)dst); 1400 1401 /* green component */ 1402 etc2_r11_parse_block(&block, src + 8); 1403 etc2_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)(dst + 1)); 1404 1405 texel[RCOMP] = USHORT_TO_FLOAT(dst[0]); 1406 texel[GCOMP] = USHORT_TO_FLOAT(dst[1]); 1407 texel[BCOMP] = 0.0f; 1408 texel[ACOMP] = 1.0f; 1409} 1410 1411static void 1412fetch_etc2_signed_r11_eac(const GLubyte *map, 1413 GLint rowStride, GLint i, GLint j, GLfloat *texel) 1414{ 1415 struct etc2_block block; 1416 GLushort dst; 1417 const uint8_t *src; 1418 1419 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; 1420 1421 etc2_r11_parse_block(&block, src); 1422 etc2_signed_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)&dst); 1423 1424 texel[RCOMP] = SHORT_TO_FLOAT(dst); 1425 texel[GCOMP] = 0.0f; 1426 texel[BCOMP] = 0.0f; 1427 texel[ACOMP] = 1.0f; 1428} 1429 1430static void 1431fetch_etc2_signed_rg11_eac(const GLubyte *map, 1432 GLint rowStride, GLint i, GLint j, GLfloat *texel) 1433{ 1434 struct etc2_block block; 1435 GLushort dst[2]; 1436 const uint8_t *src; 1437 1438 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; 1439 1440 /* red component */ 1441 etc2_r11_parse_block(&block, src); 1442 etc2_signed_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)dst); 1443 1444 /* green component */ 1445 etc2_r11_parse_block(&block, src + 8); 1446 etc2_signed_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)(dst + 1)); 1447 1448 texel[RCOMP] = SHORT_TO_FLOAT(dst[0]); 1449 texel[GCOMP] = SHORT_TO_FLOAT(dst[1]); 1450 texel[BCOMP] = 0.0f; 1451 texel[ACOMP] = 1.0f; 1452} 1453 1454static void 1455fetch_etc2_rgb8_punchthrough_alpha1(const GLubyte *map, 1456 GLint rowStride, GLint i, GLint j, 1457 GLfloat *texel) 1458{ 1459 struct etc2_block block; 1460 uint8_t dst[4]; 1461 const uint8_t *src; 1462 1463 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; 1464 1465 etc2_rgb8_parse_block(&block, src, 1466 true /* punchthrough alpha */); 1467 etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst, 1468 true /* punchthrough alpha */); 1469 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]); 1470 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]); 1471 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]); 1472 texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]); 1473} 1474 1475static void 1476fetch_etc2_srgb8_punchthrough_alpha1(const GLubyte *map, 1477 GLint rowStride, 1478 GLint i, GLint j, GLfloat *texel) 1479{ 1480 struct etc2_block block; 1481 uint8_t dst[4]; 1482 const uint8_t *src; 1483 1484 src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; 1485 1486 etc2_rgb8_parse_block(&block, src, 1487 true /* punchthrough alpha */); 1488 etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst, 1489 true /* punchthrough alpha */); 1490 texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]); 1491 texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]); 1492 texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]); 1493 texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]); 1494} 1495 1496 1497compressed_fetch_func 1498_mesa_get_etc_fetch_func(mesa_format format) 1499{ 1500 switch (format) { 1501 case MESA_FORMAT_ETC1_RGB8: 1502 return fetch_etc1_rgb8; 1503 case MESA_FORMAT_ETC2_RGB8: 1504 return fetch_etc2_rgb8; 1505 case MESA_FORMAT_ETC2_SRGB8: 1506 return fetch_etc2_srgb8; 1507 case MESA_FORMAT_ETC2_RGBA8_EAC: 1508 return fetch_etc2_rgba8_eac; 1509 case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC: 1510 return fetch_etc2_srgb8_alpha8_eac; 1511 case MESA_FORMAT_ETC2_R11_EAC: 1512 return fetch_etc2_r11_eac; 1513 case MESA_FORMAT_ETC2_RG11_EAC: 1514 return fetch_etc2_rg11_eac; 1515 case MESA_FORMAT_ETC2_SIGNED_R11_EAC: 1516 return fetch_etc2_signed_r11_eac; 1517 case MESA_FORMAT_ETC2_SIGNED_RG11_EAC: 1518 return fetch_etc2_signed_rg11_eac; 1519 case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: 1520 return fetch_etc2_rgb8_punchthrough_alpha1; 1521 case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: 1522 return fetch_etc2_srgb8_punchthrough_alpha1; 1523 default: 1524 return NULL; 1525 } 1526} 1527