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