Subversion Repositories Kolibri OS

Rev

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. #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] = (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.        * 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.