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