Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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