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