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