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