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