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