Home | History | Annotate | Download | only in main
      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 
     49 struct 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 
     67 static const int etc2_distance_table[8] = {
     68    3, 6, 11, 16, 23, 32, 41, 64 };
     69 
     70 static 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 
     89 static 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 
    107 GLboolean
    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  */
    136 void
    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 
    149 static uint8_t
    150 etc2_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 
    172 static uint8_t
    173 etc2_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 
    194 static uint8_t
    195 etc2_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 
    217 static uint8_t
    218 etc2_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 
    239 static uint8_t
    240 etc2_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 
    262 static uint8_t
    263 etc2_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 
    284 static uint8_t
    285 etc2_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 
    306 static GLint
    307 etc2_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 
    314 static uint8_t
    315 etc2_clamp(int color)
    316 {
    317    /* CLAMP(color, 0, 255) */
    318    return (uint8_t) CLAMP(color, 0, 255);
    319 }
    320 
    321 static GLushort
    322 etc2_clamp2(int color)
    323 {
    324    /* CLAMP(color, 0, 2047) */
    325    return (GLushort) CLAMP(color, 0, 2047);
    326 }
    327 
    328 static GLshort
    329 etc2_clamp3(int color)
    330 {
    331    /* CLAMP(color, -1023, 1023) */
    332    return (GLshort) CLAMP(color, -1023, 1023);
    333 }
    334 
    335 static void
    336 etc2_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 
    475 static void
    476 etc2_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 
    552 static void
    553 etc2_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 
    564 static void
    565 etc2_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 
    590 static void
    591 etc2_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 
    628 static void
    629 etc2_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 
    642 static void
    643 etc2_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 
    649 static void
    650 etc2_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 
    659 static void
    660 etc2_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 
    668 static void
    669 etc2_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 
    715 static void
    716 etc2_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 
    759 static void
    760 etc2_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 
    797 static void
    798 etc2_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 
    843 static void
    844 etc2_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 
    880 static void
    881 etc2_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 
    930 static void
    931 etc2_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 
    968 static void
    969 etc2_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 
   1018 static void
   1019 etc2_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 
   1054 static void
   1055 etc2_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 */
   1099 GLboolean
   1100 _mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS)
   1101 {
   1102    assert(0);
   1103 
   1104    return GL_FALSE;
   1105 }
   1106 
   1107 GLboolean
   1108 _mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS)
   1109 {
   1110    assert(0);
   1111 
   1112    return GL_FALSE;
   1113 }
   1114 
   1115 GLboolean
   1116 _mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS)
   1117 {
   1118    assert(0);
   1119 
   1120    return GL_FALSE;
   1121 }
   1122 
   1123 GLboolean
   1124 _mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS)
   1125 {
   1126    assert(0);
   1127 
   1128    return GL_FALSE;
   1129 }
   1130 
   1131 GLboolean
   1132 _mesa_texstore_etc2_r11_eac(TEXSTORE_PARAMS)
   1133 {
   1134    assert(0);
   1135 
   1136    return GL_FALSE;
   1137 }
   1138 
   1139 GLboolean
   1140 _mesa_texstore_etc2_signed_r11_eac(TEXSTORE_PARAMS)
   1141 {
   1142    assert(0);
   1143 
   1144    return GL_FALSE;
   1145 }
   1146 
   1147 GLboolean
   1148 _mesa_texstore_etc2_rg11_eac(TEXSTORE_PARAMS)
   1149 {
   1150    assert(0);
   1151 
   1152    return GL_FALSE;
   1153 }
   1154 
   1155 GLboolean
   1156 _mesa_texstore_etc2_signed_rg11_eac(TEXSTORE_PARAMS)
   1157 {
   1158    assert(0);
   1159 
   1160    return GL_FALSE;
   1161 }
   1162 
   1163 GLboolean
   1164 _mesa_texstore_etc2_rgb8_punchthrough_alpha1(TEXSTORE_PARAMS)
   1165 {
   1166    assert(0);
   1167 
   1168    return GL_FALSE;
   1169 }
   1170 
   1171 GLboolean
   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 
   1201 void
   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 
   1254 static void
   1255 fetch_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 
   1275 static void
   1276 fetch_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 
   1296 static void
   1297 fetch_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 
   1317 static void
   1318 fetch_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 
   1336 static void
   1337 fetch_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 
   1355 static void
   1356 fetch_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 
   1374 static void
   1375 fetch_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 
   1398 static void
   1399 fetch_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 
   1417 static void
   1418 fetch_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 
   1441 static void
   1442 fetch_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 
   1462 static void
   1463 fetch_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 
   1484 compressed_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