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