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
_mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS)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
_mesa_etc1_unpack_rgba8888(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned src_width,unsigned src_height)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
etc2_base_color1_t_mode(const uint8_t * in,GLuint index)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
etc2_base_color2_t_mode(const uint8_t * in,GLuint index)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
etc2_base_color1_h_mode(const uint8_t * in,GLuint index)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
etc2_base_color2_h_mode(const uint8_t * in,GLuint index)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
etc2_base_color_o_planar(const uint8_t * in,GLuint index)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
etc2_base_color_h_planar(const uint8_t * in,GLuint index)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
etc2_base_color_v_planar(const uint8_t * in,GLuint index)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
etc2_get_pixel_index(const struct etc2_block * block,int x,int y)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
etc2_clamp(int color)315 etc2_clamp(int color)
316 {
317 /* CLAMP(color, 0, 255) */
318 return (uint8_t) CLAMP(color, 0, 255);
319 }
320
321 static GLushort
etc2_clamp2(int color)322 etc2_clamp2(int color)
323 {
324 /* CLAMP(color, 0, 2047) */
325 return (GLushort) CLAMP(color, 0, 2047);
326 }
327
328 static GLshort
etc2_clamp3(int color)329 etc2_clamp3(int color)
330 {
331 /* CLAMP(color, -1023, 1023) */
332 return (GLshort) CLAMP(color, -1023, 1023);
333 }
334
335 static void
etc2_rgb8_parse_block(struct etc2_block * block,const uint8_t * src,GLboolean punchthrough_alpha)336 etc2_rgb8_parse_block(struct etc2_block *block,
337 const uint8_t *src,
338 GLboolean punchthrough_alpha)
339 {
340 unsigned i;
341 GLboolean diffbit = false;
342 static const int lookup[8] = { 0, 1, 2, 3, -4, -3, -2, -1 };
343
344 const int R_plus_dR = (src[0] >> 3) + lookup[src[0] & 0x7];
345 const int G_plus_dG = (src[1] >> 3) + lookup[src[1] & 0x7];
346 const int B_plus_dB = (src[2] >> 3) + lookup[src[2] & 0x7];
347
348 /* Reset the mode flags */
349 block->is_ind_mode = false;
350 block->is_diff_mode = false;
351 block->is_t_mode = false;
352 block->is_h_mode = false;
353 block->is_planar_mode = false;
354
355 if (punchthrough_alpha)
356 block->opaque = src[3] & 0x2;
357 else
358 diffbit = src[3] & 0x2;
359
360 if (!diffbit && !punchthrough_alpha) {
361 /* individual mode */
362 block->is_ind_mode = true;
363
364 for (i = 0; i < 3; i++) {
365 /* Texture decode algorithm is same for individual mode in etc1
366 * & etc2.
367 */
368 block->base_colors[0][i] = etc1_base_color_ind_hi(src[i]);
369 block->base_colors[1][i] = etc1_base_color_ind_lo(src[i]);
370 }
371 }
372 else if (R_plus_dR < 0 || R_plus_dR > 31){
373 /* T mode */
374 block->is_t_mode = true;
375
376 for(i = 0; i < 3; i++) {
377 block->base_colors[0][i] = etc2_base_color1_t_mode(src, i);
378 block->base_colors[1][i] = etc2_base_color2_t_mode(src, i);
379 }
380 /* pick distance */
381 block->distance =
382 etc2_distance_table[(((src[3] >> 2) & 0x3) << 1) |
383 (src[3] & 0x1)];
384
385 for (i = 0; i < 3; i++) {
386 block->paint_colors[0][i] = etc2_clamp(block->base_colors[0][i]);
387 block->paint_colors[1][i] = etc2_clamp(block->base_colors[1][i] +
388 block->distance);
389 block->paint_colors[2][i] = etc2_clamp(block->base_colors[1][i]);
390 block->paint_colors[3][i] = etc2_clamp(block->base_colors[1][i] -
391 block->distance);
392 }
393 }
394 else if (G_plus_dG < 0 || G_plus_dG > 31){
395 int base_color_1_value, base_color_2_value;
396
397 /* H mode */
398 block->is_h_mode = true;
399
400 for(i = 0; i < 3; i++) {
401 block->base_colors[0][i] = etc2_base_color1_h_mode(src, i);
402 block->base_colors[1][i] = etc2_base_color2_h_mode(src, i);
403 }
404
405 base_color_1_value = (block->base_colors[0][0] << 16) +
406 (block->base_colors[0][1] << 8) +
407 block->base_colors[0][2];
408 base_color_2_value = (block->base_colors[1][0] << 16) +
409 (block->base_colors[1][1] << 8) +
410 block->base_colors[1][2];
411 /* pick distance */
412 block->distance =
413 etc2_distance_table[(src[3] & 0x4) |
414 ((src[3] & 0x1) << 1) |
415 (base_color_1_value >= base_color_2_value)];
416
417 for (i = 0; i < 3; i++) {
418 block->paint_colors[0][i] = etc2_clamp(block->base_colors[0][i] +
419 block->distance);
420 block->paint_colors[1][i] = etc2_clamp(block->base_colors[0][i] -
421 block->distance);
422 block->paint_colors[2][i] = etc2_clamp(block->base_colors[1][i] +
423 block->distance);
424 block->paint_colors[3][i] = etc2_clamp(block->base_colors[1][i] -
425 block->distance);
426 }
427 }
428 else if (B_plus_dB < 0 || B_plus_dB > 31) {
429 /* Planar mode */
430 block->is_planar_mode = true;
431
432 /* opaque bit must be set in planar mode */
433 block->opaque = true;
434
435 for (i = 0; i < 3; i++) {
436 block->base_colors[0][i] = etc2_base_color_o_planar(src, i);
437 block->base_colors[1][i] = etc2_base_color_h_planar(src, i);
438 block->base_colors[2][i] = etc2_base_color_v_planar(src, i);
439 }
440 }
441 else if (diffbit || punchthrough_alpha) {
442 /* differential mode */
443 block->is_diff_mode = true;
444
445 for (i = 0; i < 3; i++) {
446 /* Texture decode algorithm is same for differential mode in etc1
447 * & etc2.
448 */
449 block->base_colors[0][i] = etc1_base_color_diff_hi(src[i]);
450 block->base_colors[1][i] = etc1_base_color_diff_lo(src[i]);
451 }
452 }
453
454 if (block->is_ind_mode || block->is_diff_mode) {
455 int table1_idx = (src[3] >> 5) & 0x7;
456 int table2_idx = (src[3] >> 2) & 0x7;
457
458 /* Use same modifier tables as for etc1 textures if opaque bit is set
459 * or if non punchthrough texture format
460 */
461 block->modifier_tables[0] = (!punchthrough_alpha || block->opaque) ?
462 etc1_modifier_tables[table1_idx] :
463 etc2_modifier_tables_non_opaque[table1_idx];
464 block->modifier_tables[1] = (!punchthrough_alpha || block->opaque) ?
465 etc1_modifier_tables[table2_idx] :
466 etc2_modifier_tables_non_opaque[table2_idx];
467
468 block->flipped = (src[3] & 0x1);
469 }
470
471 block->pixel_indices[0] =
472 (src[4] << 24) | (src[5] << 16) | (src[6] << 8) | src[7];
473 }
474
475 static void
etc2_rgb8_fetch_texel(const struct etc2_block * block,int x,int y,uint8_t * dst,GLboolean punchthrough_alpha)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
etc2_alpha8_fetch_texel(const struct etc2_block * block,int x,int y,uint8_t * dst)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
etc2_r11_fetch_texel(const struct etc2_block * block,int x,int y,uint8_t * dst)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
etc2_signed_r11_fetch_texel(const struct etc2_block * block,int x,int y,uint8_t * dst)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
etc2_alpha8_parse_block(struct etc2_block * block,const uint8_t * src)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
etc2_r11_parse_block(struct etc2_block * block,const uint8_t * src)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
etc2_rgba8_parse_block(struct etc2_block * block,const uint8_t * src)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
etc2_rgba8_fetch_texel(const struct etc2_block * block,int x,int y,uint8_t * dst)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
etc2_unpack_rgb8(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)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
etc2_unpack_srgb8(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)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
etc2_unpack_rgba8(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)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
etc2_unpack_srgb8_alpha8(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)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
etc2_unpack_r11(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)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
etc2_unpack_rg11(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)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
etc2_unpack_signed_r11(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)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
etc2_unpack_signed_rg11(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)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
etc2_unpack_rgb8_punchthrough_alpha1(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)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
etc2_unpack_srgb8_punchthrough_alpha1(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)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
_mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS)1100 _mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS)
1101 {
1102 assert(0);
1103
1104 return GL_FALSE;
1105 }
1106
1107 GLboolean
_mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS)1108 _mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS)
1109 {
1110 assert(0);
1111
1112 return GL_FALSE;
1113 }
1114
1115 GLboolean
_mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS)1116 _mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS)
1117 {
1118 assert(0);
1119
1120 return GL_FALSE;
1121 }
1122
1123 GLboolean
_mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS)1124 _mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS)
1125 {
1126 assert(0);
1127
1128 return GL_FALSE;
1129 }
1130
1131 GLboolean
_mesa_texstore_etc2_r11_eac(TEXSTORE_PARAMS)1132 _mesa_texstore_etc2_r11_eac(TEXSTORE_PARAMS)
1133 {
1134 assert(0);
1135
1136 return GL_FALSE;
1137 }
1138
1139 GLboolean
_mesa_texstore_etc2_signed_r11_eac(TEXSTORE_PARAMS)1140 _mesa_texstore_etc2_signed_r11_eac(TEXSTORE_PARAMS)
1141 {
1142 assert(0);
1143
1144 return GL_FALSE;
1145 }
1146
1147 GLboolean
_mesa_texstore_etc2_rg11_eac(TEXSTORE_PARAMS)1148 _mesa_texstore_etc2_rg11_eac(TEXSTORE_PARAMS)
1149 {
1150 assert(0);
1151
1152 return GL_FALSE;
1153 }
1154
1155 GLboolean
_mesa_texstore_etc2_signed_rg11_eac(TEXSTORE_PARAMS)1156 _mesa_texstore_etc2_signed_rg11_eac(TEXSTORE_PARAMS)
1157 {
1158 assert(0);
1159
1160 return GL_FALSE;
1161 }
1162
1163 GLboolean
_mesa_texstore_etc2_rgb8_punchthrough_alpha1(TEXSTORE_PARAMS)1164 _mesa_texstore_etc2_rgb8_punchthrough_alpha1(TEXSTORE_PARAMS)
1165 {
1166 assert(0);
1167
1168 return GL_FALSE;
1169 }
1170
1171 GLboolean
_mesa_texstore_etc2_srgb8_punchthrough_alpha1(TEXSTORE_PARAMS)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
_mesa_unpack_etc2_format(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned src_width,unsigned src_height,mesa_format format)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
fetch_etc1_rgb8(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)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
fetch_etc2_rgb8(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)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
fetch_etc2_srgb8(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)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
fetch_etc2_rgba8_eac(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)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
fetch_etc2_srgb8_alpha8_eac(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)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
fetch_etc2_r11_eac(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)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
fetch_etc2_rg11_eac(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)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
fetch_etc2_signed_r11_eac(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)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
fetch_etc2_signed_rg11_eac(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)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
fetch_etc2_rgb8_punchthrough_alpha1(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)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
fetch_etc2_srgb8_punchthrough_alpha1(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)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
_mesa_get_etc_fetch_func(mesa_format format)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