2 * Copyright (C) 2011 LunarG, Inc.
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:
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
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.
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
41 #include "texcompress.h"
42 #include "texcompress_etc.h"
46 #include "format_unpack.h"
47 #include "util/format_srgb.h"
52 uint64_t pixel_indices
[2];
53 const int *modifier_tables
[2];
61 uint8_t base_colors
[3][3];
62 uint8_t paint_colors
[4][3];
63 uint8_t base_codeword
;
68 static const int etc2_distance_table
[8] = {
69 3, 6, 11, 16, 23, 32, 41, 64 };
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},
90 static const int etc2_modifier_tables_non_opaque
[8][4] = {
101 /* define etc1_parse_block and etc. */
102 #define UINT8_TYPE GLubyte
104 #include "texcompress_etc_tmp.h"
109 _mesa_texstore_etc1_rgb8(UNUSED_TEXSTORE_PARAMS
)
111 /* GL_ETC1_RGB8_OES is only valid in glCompressedTexImage2D */
119 * Decode texture data in format `MESA_FORMAT_ETC1_RGB8` to
120 * `MESA_FORMAT_ABGR8888`.
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.
133 * \param src_width in pixels
134 * \param src_height in pixels
135 * \param dst_stride in bytes
138 _mesa_etc1_unpack_rgba8888(uint8_t *dst_row
,
140 const uint8_t *src_row
,
145 etc1_unpack_rgba8888(dst_row
, dst_stride
,
147 src_width
, src_height
);
151 etc2_base_color1_t_mode(const uint8_t *in
, GLuint index
)
153 uint8_t R1a
= 0, x
= 0;
154 /* base col 1 = extend_4to8bits( (R1a << 2) | R1b, G1, B1) */
157 R1a
= (in
[0] >> 3) & 0x3;
158 x
= ((R1a
<< 2) | (in
[0] & 0x3));
161 x
= ((in
[1] >> 4) & 0xf);
170 return ((x
<< 4) | (x
& 0xf));
174 etc2_base_color2_t_mode(const uint8_t *in
, GLuint index
)
177 /*extend 4to8bits(R2, G2, B2)*/
180 x
= ((in
[2] >> 4) & 0xf );
186 x
= ((in
[3] >> 4) & 0xf);
192 return ((x
<< 4) | (x
& 0xf));
196 etc2_base_color1_h_mode(const uint8_t *in
, GLuint index
)
199 /* base col 1 = extend 4to8bits(R1, (G1a << 1) | G1b, (B1a << 3) | B1b) */
202 x
= ((in
[0] >> 3) & 0xf);
205 x
= (((in
[0] & 0x7) << 1) | ((in
[1] >> 4) & 0x1));
209 (((in
[1] & 0x3) << 1) | ((in
[2] >> 7) & 0x1)));
215 return ((x
<< 4) | (x
& 0xf));
219 etc2_base_color2_h_mode(const uint8_t *in
, GLuint index
)
222 /* base col 2 = extend 4to8bits(R2, G2, B2) */
225 x
= ((in
[2] >> 3) & 0xf );
228 x
= (((in
[2] & 0x7) << 1) | ((in
[3] >> 7) & 0x1));
231 x
= ((in
[3] >> 3) & 0xf);
237 return ((x
<< 4) | (x
& 0xf));
241 etc2_base_color_o_planar(const uint8_t *in
, GLuint index
)
246 tmp
= ((in
[0] >> 1) & 0x3f); /* RO */
247 return ((tmp
<< 2) | (tmp
>> 4));
249 tmp
= (((in
[0] & 0x1) << 6) | /* GO1 */
250 ((in
[1] >> 1) & 0x3f)); /* GO2 */
251 return ((tmp
<< 1) | (tmp
>> 6));
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));
264 etc2_base_color_h_planar(const uint8_t *in
, GLuint index
)
269 tmp
= (((in
[3] & 0x7c) >> 1) | /* RH1 */
270 (in
[3] & 0x1)); /* RH2 */
271 return ((tmp
<< 2) | (tmp
>> 4));
273 tmp
= (in
[4] >> 1) & 0x7f; /* GH */
274 return ((tmp
<< 1) | (tmp
>> 6));
276 tmp
= (((in
[4] & 0x1) << 5) |
277 ((in
[5] >> 3) & 0x1f)); /* BH */
278 return ((tmp
<< 2) | (tmp
>> 4));
286 etc2_base_color_v_planar(const uint8_t *in
, GLuint index
)
291 tmp
= (((in
[5] & 0x7) << 0x3) |
292 ((in
[6] >> 5) & 0x7)); /* RV */
293 return ((tmp
<< 2) | (tmp
>> 4));
295 tmp
= (((in
[6] & 0x1f) << 2) |
296 ((in
[7] >> 6) & 0x3)); /* GV */
297 return ((tmp
<< 1) | (tmp
>> 6));
299 tmp
= in
[7] & 0x3f; /* BV */
300 return ((tmp
<< 2) | (tmp
>> 4));
308 etc2_get_pixel_index(const struct etc2_block
*block
, int x
, int y
)
310 int bit
= ((3 - y
) + (3 - x
) * 4) * 3;
311 int idx
= (block
->pixel_indices
[1] >> bit
) & 0x7;
316 etc2_clamp(int color
)
318 /* CLAMP(color, 0, 255) */
319 return (uint8_t) CLAMP(color
, 0, 255);
323 etc2_clamp2(int color
)
325 /* CLAMP(color, 0, 2047) */
326 return (GLushort
) CLAMP(color
, 0, 2047);
330 etc2_clamp3(int color
)
332 /* CLAMP(color, -1023, 1023) */
333 return (GLshort
) CLAMP(color
, -1023, 1023);
337 etc2_rgb8_parse_block(struct etc2_block
*block
,
339 GLboolean punchthrough_alpha
)
342 GLboolean diffbit
= false;
343 static const int lookup
[8] = { 0, 1, 2, 3, -4, -3, -2, -1 };
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];
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;
356 if (punchthrough_alpha
)
357 block
->opaque
= src
[3] & 0x2;
359 diffbit
= src
[3] & 0x2;
361 if (!diffbit
&& !punchthrough_alpha
) {
362 /* individual mode */
363 block
->is_ind_mode
= true;
365 for (i
= 0; i
< 3; i
++) {
366 /* Texture decode algorithm is same for individual mode in etc1
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
]);
373 else if (R_plus_dR
< 0 || R_plus_dR
> 31){
375 block
->is_t_mode
= true;
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
);
383 etc2_distance_table
[(((src
[3] >> 2) & 0x3) << 1) |
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
] +
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
] -
395 else if (G_plus_dG
< 0 || G_plus_dG
> 31){
396 int base_color_1_value
, base_color_2_value
;
399 block
->is_h_mode
= true;
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
);
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];
414 etc2_distance_table
[(src
[3] & 0x4) |
415 ((src
[3] & 0x1) << 1) |
416 (base_color_1_value
>= base_color_2_value
)];
418 for (i
= 0; i
< 3; i
++) {
419 block
->paint_colors
[0][i
] = etc2_clamp(block
->base_colors
[0][i
] +
421 block
->paint_colors
[1][i
] = etc2_clamp(block
->base_colors
[0][i
] -
423 block
->paint_colors
[2][i
] = etc2_clamp(block
->base_colors
[1][i
] +
425 block
->paint_colors
[3][i
] = etc2_clamp(block
->base_colors
[1][i
] -
429 else if (B_plus_dB
< 0 || B_plus_dB
> 31) {
431 block
->is_planar_mode
= true;
433 /* opaque bit must be set in planar mode */
434 block
->opaque
= true;
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
);
442 else if (diffbit
|| punchthrough_alpha
) {
443 /* differential mode */
444 block
->is_diff_mode
= true;
446 for (i
= 0; i
< 3; i
++) {
447 /* Texture decode algorithm is same for differential mode in etc1
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
]);
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;
459 /* Use same modifier tables as for etc1 textures if opaque bit is set
460 * or if non punchthrough texture format
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
];
469 block
->flipped
= (src
[3] & 0x1);
472 block
->pixel_indices
[0] =
473 (src
[4] << 24) | (src
[5] << 16) | (src
[6] << 8) | src
[7];
477 etc2_rgb8_fetch_texel(const struct etc2_block
*block
,
478 int x
, int y
, uint8_t *dst
,
479 GLboolean punchthrough_alpha
)
481 const uint8_t *base_color
;
482 int modifier
, bit
, idx
, blk
;
484 /* get pixel index */
486 idx
= ((block
->pixel_indices
[0] >> (15 + bit
)) & 0x2) |
487 ((block
->pixel_indices
[0] >> (bit
)) & 0x1);
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;
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
];
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
);
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;
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];
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)
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;
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;
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;
543 dst
[0] = etc2_clamp(red
);
544 dst
[1] = etc2_clamp(green
);
545 dst
[2] = etc2_clamp(blue
);
547 /* check for punchthrough_alpha format */
548 if (punchthrough_alpha
)
552 unreachable("unhandled block mode");
556 etc2_alpha8_fetch_texel(const struct etc2_block
*block
,
557 int x
, int y
, uint8_t *dst
)
559 int modifier
, alpha
, idx
;
560 /* get pixel index */
561 idx
= etc2_get_pixel_index(block
, x
, y
);
562 modifier
= etc2_modifier_tables
[block
->table_index
][idx
];
563 alpha
= block
->base_codeword
+ modifier
* block
->multiplier
;
564 dst
[3] = etc2_clamp(alpha
);
568 etc2_r11_fetch_texel(const struct etc2_block
*block
,
569 int x
, int y
, uint8_t *dst
)
573 /* Get pixel index */
574 idx
= etc2_get_pixel_index(block
, x
, y
);
575 modifier
= etc2_modifier_tables
[block
->table_index
][idx
];
577 if (block
->multiplier
!= 0)
578 /* clamp2(base codeword × 8 + 4 + modifier × multiplier × 8) */
579 color
= etc2_clamp2(((block
->base_codeword
<< 3) | 0x4) +
580 ((modifier
* block
->multiplier
) << 3));
582 color
= etc2_clamp2(((block
->base_codeword
<< 3) | 0x4) + modifier
);
584 /* Extend 11 bits color value to 16 bits. OpenGL ES 3.0 specification
585 * allows extending the color value to any number of bits. But, an
586 * implementation is not allowed to truncate the 11-bit value to less than
589 color
= (color
<< 5) | (color
>> 6);
590 ((GLushort
*)dst
)[0] = color
;
594 etc2_signed_r11_fetch_texel(const struct etc2_block
*block
,
595 int x
, int y
, uint8_t *dst
)
599 GLbyte base_codeword
= (GLbyte
) block
->base_codeword
;
601 if (base_codeword
== -128)
602 base_codeword
= -127;
604 /* Get pixel index */
605 idx
= etc2_get_pixel_index(block
, x
, y
);
606 modifier
= etc2_modifier_tables
[block
->table_index
][idx
];
608 if (block
->multiplier
!= 0)
609 /* clamp3(base codeword × 8 + modifier × multiplier × 8) */
610 color
= etc2_clamp3((base_codeword
<< 3) +
611 ((modifier
* block
->multiplier
) << 3));
613 color
= etc2_clamp3((base_codeword
<< 3) + modifier
);
615 /* Extend 11 bits color value to 16 bits. OpenGL ES 3.0 specification
616 * allows extending the color value to any number of bits. But, an
617 * implementation is not allowed to truncate the 11-bit value to less than
618 * 11 bits. A negative 11-bit value must first be made positive before bit
619 * replication, and then made negative again
622 color
= (color
<< 5) | (color
>> 5);
625 color
= (color
<< 5) | (color
>> 5);
628 ((GLshort
*)dst
)[0] = color
;
632 etc2_alpha8_parse_block(struct etc2_block
*block
, const uint8_t *src
)
634 block
->base_codeword
= src
[0];
635 block
->multiplier
= (src
[1] >> 4) & 0xf;
636 block
->table_index
= src
[1] & 0xf;
637 block
->pixel_indices
[1] = (((uint64_t)src
[2] << 40) |
638 ((uint64_t)src
[3] << 32) |
639 ((uint64_t)src
[4] << 24) |
640 ((uint64_t)src
[5] << 16) |
641 ((uint64_t)src
[6] << 8) |
646 etc2_r11_parse_block(struct etc2_block
*block
, const uint8_t *src
)
648 /* Parsing logic remains same as for etc2_alpha8_parse_block */
649 etc2_alpha8_parse_block(block
, src
);
653 etc2_rgba8_parse_block(struct etc2_block
*block
, const uint8_t *src
)
655 /* RGB component is parsed the same way as for MESA_FORMAT_ETC2_RGB8 */
656 etc2_rgb8_parse_block(block
, src
+ 8,
657 false /* punchthrough_alpha */);
658 /* Parse Alpha component */
659 etc2_alpha8_parse_block(block
, src
);
663 etc2_rgba8_fetch_texel(const struct etc2_block
*block
,
664 int x
, int y
, uint8_t *dst
)
666 etc2_rgb8_fetch_texel(block
, x
, y
, dst
,
667 false /* punchthrough_alpha */);
668 etc2_alpha8_fetch_texel(block
, x
, y
, dst
);
672 etc2_unpack_rgb8(uint8_t *dst_row
,
674 const uint8_t *src_row
,
679 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 4;
680 struct etc2_block block
;
683 for (y
= 0; y
< height
; y
+= bh
) {
684 const uint8_t *src
= src_row
;
686 * Destination texture may not be a multiple of four texels in
687 * height. Compute a safe height to avoid writing outside the texture.
689 const unsigned h
= MIN2(bh
, height
- y
);
691 for (x
= 0; x
< width
; x
+= bw
) {
693 * Destination texture may not be a multiple of four texels in
694 * width. Compute a safe width to avoid writing outside the texture.
696 const unsigned w
= MIN2(bw
, width
- x
);
698 etc2_rgb8_parse_block(&block
, src
,
699 false /* punchthrough_alpha */);
701 for (j
= 0; j
< h
; j
++) {
702 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
703 for (i
= 0; i
< w
; i
++) {
704 etc2_rgb8_fetch_texel(&block
, i
, j
, dst
,
705 false /* punchthrough_alpha */);
714 src_row
+= src_stride
;
719 etc2_unpack_srgb8(uint8_t *dst_row
,
721 const uint8_t *src_row
,
727 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 4;
728 struct etc2_block block
;
732 for (y
= 0; y
< height
; y
+= bh
) {
733 const uint8_t *src
= src_row
;
734 const unsigned h
= MIN2(bh
, height
- y
);
736 for (x
= 0; x
< width
; x
+= bw
) {
737 const unsigned w
= MIN2(bw
, width
- x
);
738 etc2_rgb8_parse_block(&block
, src
,
739 false /* punchthrough_alpha */);
742 for (j
= 0; j
< h
; j
++) {
743 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
744 for (i
= 0; i
< w
; i
++) {
745 etc2_rgb8_fetch_texel(&block
, i
, j
, dst
,
746 false /* punchthrough_alpha */);
749 /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */
762 src_row
+= src_stride
;
767 etc2_unpack_rgba8(uint8_t *dst_row
,
769 const uint8_t *src_row
,
774 /* If internalformat is COMPRESSED_RGBA8_ETC2_EAC, each 4 × 4 block of
775 * RGBA8888 information is compressed to 128 bits. To decode a block, the
776 * two 64-bit integers int64bitAlpha and int64bitColor are calculated.
778 const unsigned bw
= 4, bh
= 4, bs
= 16, comps
= 4;
779 struct etc2_block block
;
782 for (y
= 0; y
< height
; y
+= bh
) {
783 const uint8_t *src
= src_row
;
784 const unsigned h
= MIN2(bh
, height
- y
);
786 for (x
= 0; x
< width
; x
+= bw
) {
787 const unsigned w
= MIN2(bw
, width
- x
);
788 etc2_rgba8_parse_block(&block
, src
);
790 for (j
= 0; j
< h
; j
++) {
791 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
792 for (i
= 0; i
< w
; i
++) {
793 etc2_rgba8_fetch_texel(&block
, i
, j
, dst
);
800 src_row
+= src_stride
;
805 etc2_unpack_srgb8_alpha8(uint8_t *dst_row
,
807 const uint8_t *src_row
,
813 /* If internalformat is COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, each 4 × 4 block
814 * of RGBA8888 information is compressed to 128 bits. To decode a block, the
815 * two 64-bit integers int64bitAlpha and int64bitColor are calculated.
817 const unsigned bw
= 4, bh
= 4, bs
= 16, comps
= 4;
818 struct etc2_block block
;
822 for (y
= 0; y
< height
; y
+= bh
) {
823 const unsigned h
= MIN2(bh
, height
- y
);
824 const uint8_t *src
= src_row
;
826 for (x
= 0; x
< width
; x
+= bw
) {
827 const unsigned w
= MIN2(bw
, width
- x
);
828 etc2_rgba8_parse_block(&block
, src
);
830 for (j
= 0; j
< h
; j
++) {
831 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
832 for (i
= 0; i
< w
; i
++) {
833 etc2_rgba8_fetch_texel(&block
, i
, j
, dst
);
836 /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */
849 src_row
+= src_stride
;
854 etc2_unpack_r11(uint8_t *dst_row
,
856 const uint8_t *src_row
,
861 /* If internalformat is COMPRESSED_R11_EAC, each 4 × 4 block of
862 color information is compressed to 64 bits.
864 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 1, comp_size
= 2;
865 struct etc2_block block
;
868 for (y
= 0; y
< height
; y
+= bh
) {
869 const unsigned h
= MIN2(bh
, height
- y
);
870 const uint8_t *src
= src_row
;
872 for (x
= 0; x
< width
; x
+= bw
) {
873 const unsigned w
= MIN2(bw
, width
- x
);
874 etc2_r11_parse_block(&block
, src
);
876 for (j
= 0; j
< h
; j
++) {
877 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
* comp_size
;
878 for (i
= 0; i
< w
; i
++) {
879 etc2_r11_fetch_texel(&block
, i
, j
, dst
);
880 dst
+= comps
* comp_size
;
886 src_row
+= src_stride
;
891 etc2_unpack_rg11(uint8_t *dst_row
,
893 const uint8_t *src_row
,
898 /* If internalformat is COMPRESSED_RG11_EAC, each 4 × 4 block of
899 RG color information is compressed to 128 bits.
901 const unsigned bw
= 4, bh
= 4, bs
= 16, comps
= 2, comp_size
= 2;
902 struct etc2_block block
;
905 for (y
= 0; y
< height
; y
+= bh
) {
906 const unsigned h
= MIN2(bh
, height
- y
);
907 const uint8_t *src
= src_row
;
909 for (x
= 0; x
< width
; x
+= bw
) {
910 const unsigned w
= MIN2(bw
, width
- x
);
912 etc2_r11_parse_block(&block
, src
);
914 for (j
= 0; j
< h
; j
++) {
915 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+
916 x
* comps
* comp_size
;
917 for (i
= 0; i
< w
; i
++) {
918 etc2_r11_fetch_texel(&block
, i
, j
, dst
);
919 dst
+= comps
* comp_size
;
922 /* green component */
923 etc2_r11_parse_block(&block
, src
+ 8);
925 for (j
= 0; j
< h
; j
++) {
926 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+
927 x
* comps
* comp_size
;
928 for (i
= 0; i
< w
; i
++) {
929 etc2_r11_fetch_texel(&block
, i
, j
, dst
+ comp_size
);
930 dst
+= comps
* comp_size
;
936 src_row
+= src_stride
;
941 etc2_unpack_signed_r11(uint8_t *dst_row
,
943 const uint8_t *src_row
,
948 /* If internalformat is COMPRESSED_SIGNED_R11_EAC, each 4 × 4 block of
949 red color information is compressed to 64 bits.
951 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 1, comp_size
= 2;
952 struct etc2_block block
;
955 for (y
= 0; y
< height
; y
+= bh
) {
956 const unsigned h
= MIN2(bh
, height
- y
);
957 const uint8_t *src
= src_row
;
959 for (x
= 0; x
< width
; x
+= bw
) {
960 const unsigned w
= MIN2(bw
, width
- x
);
961 etc2_r11_parse_block(&block
, src
);
963 for (j
= 0; j
< h
; j
++) {
964 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+
965 x
* comps
* comp_size
;
966 for (i
= 0; i
< w
; i
++) {
967 etc2_signed_r11_fetch_texel(&block
, i
, j
, dst
);
968 dst
+= comps
* comp_size
;
974 src_row
+= src_stride
;
979 etc2_unpack_signed_rg11(uint8_t *dst_row
,
981 const uint8_t *src_row
,
986 /* If internalformat is COMPRESSED_SIGNED_RG11_EAC, each 4 × 4 block of
987 RG color information is compressed to 128 bits.
989 const unsigned bw
= 4, bh
= 4, bs
= 16, comps
= 2, comp_size
= 2;
990 struct etc2_block block
;
993 for (y
= 0; y
< height
; y
+= bh
) {
994 const unsigned h
= MIN2(bh
, height
- y
);
995 const uint8_t *src
= src_row
;
997 for (x
= 0; x
< width
; x
+= bw
) {
998 const unsigned w
= MIN2(bw
, width
- x
);
1000 etc2_r11_parse_block(&block
, src
);
1002 for (j
= 0; j
< h
; j
++) {
1003 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+
1004 x
* comps
* comp_size
;
1005 for (i
= 0; i
< w
; i
++) {
1006 etc2_signed_r11_fetch_texel(&block
, i
, j
, dst
);
1007 dst
+= comps
* comp_size
;
1010 /* green component */
1011 etc2_r11_parse_block(&block
, src
+ 8);
1013 for (j
= 0; j
< h
; j
++) {
1014 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+
1015 x
* comps
* comp_size
;
1016 for (i
= 0; i
< w
; i
++) {
1017 etc2_signed_r11_fetch_texel(&block
, i
, j
, dst
+ comp_size
);
1018 dst
+= comps
* comp_size
;
1024 src_row
+= src_stride
;
1029 etc2_unpack_rgb8_punchthrough_alpha1(uint8_t *dst_row
,
1030 unsigned dst_stride
,
1031 const uint8_t *src_row
,
1032 unsigned src_stride
,
1036 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 4;
1037 struct etc2_block block
;
1038 unsigned x
, y
, i
, j
;
1040 for (y
= 0; y
< height
; y
+= bh
) {
1041 const unsigned h
= MIN2(bh
, height
- y
);
1042 const uint8_t *src
= src_row
;
1044 for (x
= 0; x
< width
; x
+= bw
) {
1045 const unsigned w
= MIN2(bw
, width
- x
);
1046 etc2_rgb8_parse_block(&block
, src
,
1047 true /* punchthrough_alpha */);
1048 for (j
= 0; j
< h
; j
++) {
1049 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
1050 for (i
= 0; i
< w
; i
++) {
1051 etc2_rgb8_fetch_texel(&block
, i
, j
, dst
,
1052 true /* punchthrough_alpha */);
1060 src_row
+= src_stride
;
1065 etc2_unpack_srgb8_punchthrough_alpha1(uint8_t *dst_row
,
1066 unsigned dst_stride
,
1067 const uint8_t *src_row
,
1068 unsigned src_stride
,
1073 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 4;
1074 struct etc2_block block
;
1075 unsigned x
, y
, i
, j
;
1078 for (y
= 0; y
< height
; y
+= bh
) {
1079 const unsigned h
= MIN2(bh
, height
- y
);
1080 const uint8_t *src
= src_row
;
1082 for (x
= 0; x
< width
; x
+= bw
) {
1083 const unsigned w
= MIN2(bw
, width
- x
);
1084 etc2_rgb8_parse_block(&block
, src
,
1085 true /* punchthrough_alpha */);
1086 for (j
= 0; j
< h
; j
++) {
1087 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
1088 for (i
= 0; i
< w
; i
++) {
1089 etc2_rgb8_fetch_texel(&block
, i
, j
, dst
,
1090 true /* punchthrough_alpha */);
1093 /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */
1107 src_row
+= src_stride
;
1111 /* ETC2 texture formats are valid in glCompressedTexImage2D and
1112 * glCompressedTexSubImage2D functions */
1114 _mesa_texstore_etc2_rgb8(UNUSED_TEXSTORE_PARAMS
)
1122 _mesa_texstore_etc2_srgb8(UNUSED_TEXSTORE_PARAMS
)
1130 _mesa_texstore_etc2_rgba8_eac(UNUSED_TEXSTORE_PARAMS
)
1138 _mesa_texstore_etc2_srgb8_alpha8_eac(UNUSED_TEXSTORE_PARAMS
)
1146 _mesa_texstore_etc2_r11_eac(UNUSED_TEXSTORE_PARAMS
)
1154 _mesa_texstore_etc2_signed_r11_eac(UNUSED_TEXSTORE_PARAMS
)
1162 _mesa_texstore_etc2_rg11_eac(UNUSED_TEXSTORE_PARAMS
)
1170 _mesa_texstore_etc2_signed_rg11_eac(UNUSED_TEXSTORE_PARAMS
)
1178 _mesa_texstore_etc2_rgb8_punchthrough_alpha1(UNUSED_TEXSTORE_PARAMS
)
1186 _mesa_texstore_etc2_srgb8_punchthrough_alpha1(UNUSED_TEXSTORE_PARAMS
)
1195 * Decode texture data in any one of following formats:
1196 * `MESA_FORMAT_ETC2_RGB8`
1197 * `MESA_FORMAT_ETC2_SRGB8`
1198 * `MESA_FORMAT_ETC2_RGBA8_EAC`
1199 * `MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC`
1200 * `MESA_FORMAT_ETC2_R11_EAC`
1201 * `MESA_FORMAT_ETC2_RG11_EAC`
1202 * `MESA_FORMAT_ETC2_SIGNED_R11_EAC`
1203 * `MESA_FORMAT_ETC2_SIGNED_RG11_EAC`
1204 * `MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1`
1205 * `MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1`
1207 * The size of the source data must be a multiple of the ETC2 block size
1208 * even if the texture image's dimensions are not aligned to 4.
1210 * \param src_width in pixels
1211 * \param src_height in pixels
1212 * \param dst_stride in bytes
1216 _mesa_unpack_etc2_format(uint8_t *dst_row
,
1217 unsigned dst_stride
,
1218 const uint8_t *src_row
,
1219 unsigned src_stride
,
1221 unsigned src_height
,
1225 if (format
== MESA_FORMAT_ETC2_RGB8
)
1226 etc2_unpack_rgb8(dst_row
, dst_stride
,
1227 src_row
, src_stride
,
1228 src_width
, src_height
);
1229 else if (format
== MESA_FORMAT_ETC2_SRGB8
)
1230 etc2_unpack_srgb8(dst_row
, dst_stride
,
1231 src_row
, src_stride
,
1232 src_width
, src_height
, bgra
);
1233 else if (format
== MESA_FORMAT_ETC2_RGBA8_EAC
)
1234 etc2_unpack_rgba8(dst_row
, dst_stride
,
1235 src_row
, src_stride
,
1236 src_width
, src_height
);
1237 else if (format
== MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC
)
1238 etc2_unpack_srgb8_alpha8(dst_row
, dst_stride
,
1239 src_row
, src_stride
,
1240 src_width
, src_height
, bgra
);
1241 else if (format
== MESA_FORMAT_ETC2_R11_EAC
)
1242 etc2_unpack_r11(dst_row
, dst_stride
,
1243 src_row
, src_stride
,
1244 src_width
, src_height
);
1245 else if (format
== MESA_FORMAT_ETC2_RG11_EAC
)
1246 etc2_unpack_rg11(dst_row
, dst_stride
,
1247 src_row
, src_stride
,
1248 src_width
, src_height
);
1249 else if (format
== MESA_FORMAT_ETC2_SIGNED_R11_EAC
)
1250 etc2_unpack_signed_r11(dst_row
, dst_stride
,
1251 src_row
, src_stride
,
1252 src_width
, src_height
);
1253 else if (format
== MESA_FORMAT_ETC2_SIGNED_RG11_EAC
)
1254 etc2_unpack_signed_rg11(dst_row
, dst_stride
,
1255 src_row
, src_stride
,
1256 src_width
, src_height
);
1257 else if (format
== MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1
)
1258 etc2_unpack_rgb8_punchthrough_alpha1(dst_row
, dst_stride
,
1259 src_row
, src_stride
,
1260 src_width
, src_height
);
1261 else if (format
== MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1
)
1262 etc2_unpack_srgb8_punchthrough_alpha1(dst_row
, dst_stride
,
1263 src_row
, src_stride
,
1264 src_width
, src_height
, bgra
);
1270 fetch_etc1_rgb8(const GLubyte
*map
,
1271 GLint rowStride
, GLint i
, GLint j
,
1274 struct etc1_block block
;
1278 src
= map
+ (((rowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
1280 etc1_parse_block(&block
, src
);
1281 etc1_fetch_texel(&block
, i
% 4, j
% 4, dst
);
1283 texel
[RCOMP
] = UBYTE_TO_FLOAT(dst
[0]);
1284 texel
[GCOMP
] = UBYTE_TO_FLOAT(dst
[1]);
1285 texel
[BCOMP
] = UBYTE_TO_FLOAT(dst
[2]);
1286 texel
[ACOMP
] = 1.0f
;
1291 fetch_etc2_rgb8(const GLubyte
*map
,
1292 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
1294 struct etc2_block block
;
1298 src
= map
+ (((rowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
1300 etc2_rgb8_parse_block(&block
, src
,
1301 false /* punchthrough_alpha */);
1302 etc2_rgb8_fetch_texel(&block
, i
% 4, j
% 4, dst
,
1303 false /* punchthrough_alpha */);
1305 texel
[RCOMP
] = UBYTE_TO_FLOAT(dst
[0]);
1306 texel
[GCOMP
] = UBYTE_TO_FLOAT(dst
[1]);
1307 texel
[BCOMP
] = UBYTE_TO_FLOAT(dst
[2]);
1308 texel
[ACOMP
] = 1.0f
;
1312 fetch_etc2_srgb8(const GLubyte
*map
,
1313 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
1315 struct etc2_block block
;
1319 src
= map
+ (((rowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
1321 etc2_rgb8_parse_block(&block
, src
,
1322 false /* punchthrough_alpha */);
1323 etc2_rgb8_fetch_texel(&block
, i
% 4, j
% 4, dst
,
1324 false /* punchthrough_alpha */);
1326 texel
[RCOMP
] = util_format_srgb_8unorm_to_linear_float(dst
[0]);
1327 texel
[GCOMP
] = util_format_srgb_8unorm_to_linear_float(dst
[1]);
1328 texel
[BCOMP
] = util_format_srgb_8unorm_to_linear_float(dst
[2]);
1329 texel
[ACOMP
] = 1.0f
;
1333 fetch_etc2_rgba8_eac(const GLubyte
*map
,
1334 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
1336 struct etc2_block block
;
1340 src
= map
+ (((rowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
1342 etc2_rgba8_parse_block(&block
, src
);
1343 etc2_rgba8_fetch_texel(&block
, i
% 4, j
% 4, dst
);
1345 texel
[RCOMP
] = UBYTE_TO_FLOAT(dst
[0]);
1346 texel
[GCOMP
] = UBYTE_TO_FLOAT(dst
[1]);
1347 texel
[BCOMP
] = UBYTE_TO_FLOAT(dst
[2]);
1348 texel
[ACOMP
] = UBYTE_TO_FLOAT(dst
[3]);
1352 fetch_etc2_srgb8_alpha8_eac(const GLubyte
*map
,
1353 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
1355 struct etc2_block block
;
1359 src
= map
+ (((rowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
1361 etc2_rgba8_parse_block(&block
, src
);
1362 etc2_rgba8_fetch_texel(&block
, i
% 4, j
% 4, dst
);
1364 texel
[RCOMP
] = util_format_srgb_8unorm_to_linear_float(dst
[0]);
1365 texel
[GCOMP
] = util_format_srgb_8unorm_to_linear_float(dst
[1]);
1366 texel
[BCOMP
] = util_format_srgb_8unorm_to_linear_float(dst
[2]);
1367 texel
[ACOMP
] = UBYTE_TO_FLOAT(dst
[3]);
1371 fetch_etc2_r11_eac(const GLubyte
*map
,
1372 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
1374 struct etc2_block block
;
1378 src
= map
+ (((rowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
1380 etc2_r11_parse_block(&block
, src
);
1381 etc2_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)&dst
);
1383 texel
[RCOMP
] = USHORT_TO_FLOAT(dst
);
1384 texel
[GCOMP
] = 0.0f
;
1385 texel
[BCOMP
] = 0.0f
;
1386 texel
[ACOMP
] = 1.0f
;
1390 fetch_etc2_rg11_eac(const GLubyte
*map
,
1391 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
1393 struct etc2_block block
;
1397 src
= map
+ (((rowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
1400 etc2_r11_parse_block(&block
, src
);
1401 etc2_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)dst
);
1403 /* green component */
1404 etc2_r11_parse_block(&block
, src
+ 8);
1405 etc2_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)(dst
+ 1));
1407 texel
[RCOMP
] = USHORT_TO_FLOAT(dst
[0]);
1408 texel
[GCOMP
] = USHORT_TO_FLOAT(dst
[1]);
1409 texel
[BCOMP
] = 0.0f
;
1410 texel
[ACOMP
] = 1.0f
;
1414 fetch_etc2_signed_r11_eac(const GLubyte
*map
,
1415 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
1417 struct etc2_block block
;
1421 src
= map
+ (((rowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
1423 etc2_r11_parse_block(&block
, src
);
1424 etc2_signed_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)&dst
);
1426 texel
[RCOMP
] = SHORT_TO_FLOAT(dst
);
1427 texel
[GCOMP
] = 0.0f
;
1428 texel
[BCOMP
] = 0.0f
;
1429 texel
[ACOMP
] = 1.0f
;
1433 fetch_etc2_signed_rg11_eac(const GLubyte
*map
,
1434 GLint rowStride
, GLint i
, GLint j
, GLfloat
*texel
)
1436 struct etc2_block block
;
1440 src
= map
+ (((rowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
1443 etc2_r11_parse_block(&block
, src
);
1444 etc2_signed_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)dst
);
1446 /* green component */
1447 etc2_r11_parse_block(&block
, src
+ 8);
1448 etc2_signed_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)(dst
+ 1));
1450 texel
[RCOMP
] = SHORT_TO_FLOAT(dst
[0]);
1451 texel
[GCOMP
] = SHORT_TO_FLOAT(dst
[1]);
1452 texel
[BCOMP
] = 0.0f
;
1453 texel
[ACOMP
] = 1.0f
;
1457 fetch_etc2_rgb8_punchthrough_alpha1(const GLubyte
*map
,
1458 GLint rowStride
, GLint i
, GLint j
,
1461 struct etc2_block block
;
1465 src
= map
+ (((rowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
1467 etc2_rgb8_parse_block(&block
, src
,
1468 true /* punchthrough alpha */);
1469 etc2_rgb8_fetch_texel(&block
, i
% 4, j
% 4, dst
,
1470 true /* punchthrough alpha */);
1471 texel
[RCOMP
] = UBYTE_TO_FLOAT(dst
[0]);
1472 texel
[GCOMP
] = UBYTE_TO_FLOAT(dst
[1]);
1473 texel
[BCOMP
] = UBYTE_TO_FLOAT(dst
[2]);
1474 texel
[ACOMP
] = UBYTE_TO_FLOAT(dst
[3]);
1478 fetch_etc2_srgb8_punchthrough_alpha1(const GLubyte
*map
,
1480 GLint i
, GLint j
, GLfloat
*texel
)
1482 struct etc2_block block
;
1486 src
= map
+ (((rowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
1488 etc2_rgb8_parse_block(&block
, src
,
1489 true /* punchthrough alpha */);
1490 etc2_rgb8_fetch_texel(&block
, i
% 4, j
% 4, dst
,
1491 true /* punchthrough alpha */);
1492 texel
[RCOMP
] = util_format_srgb_8unorm_to_linear_float(dst
[0]);
1493 texel
[GCOMP
] = util_format_srgb_8unorm_to_linear_float(dst
[1]);
1494 texel
[BCOMP
] = util_format_srgb_8unorm_to_linear_float(dst
[2]);
1495 texel
[ACOMP
] = UBYTE_TO_FLOAT(dst
[3]);
1499 compressed_fetch_func
1500 _mesa_get_etc_fetch_func(mesa_format format
)
1503 case MESA_FORMAT_ETC1_RGB8
:
1504 return fetch_etc1_rgb8
;
1505 case MESA_FORMAT_ETC2_RGB8
:
1506 return fetch_etc2_rgb8
;
1507 case MESA_FORMAT_ETC2_SRGB8
:
1508 return fetch_etc2_srgb8
;
1509 case MESA_FORMAT_ETC2_RGBA8_EAC
:
1510 return fetch_etc2_rgba8_eac
;
1511 case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC
:
1512 return fetch_etc2_srgb8_alpha8_eac
;
1513 case MESA_FORMAT_ETC2_R11_EAC
:
1514 return fetch_etc2_r11_eac
;
1515 case MESA_FORMAT_ETC2_RG11_EAC
:
1516 return fetch_etc2_rg11_eac
;
1517 case MESA_FORMAT_ETC2_SIGNED_R11_EAC
:
1518 return fetch_etc2_signed_r11_eac
;
1519 case MESA_FORMAT_ETC2_SIGNED_RG11_EAC
:
1520 return fetch_etc2_signed_rg11_eac
;
1521 case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1
:
1522 return fetch_etc2_rgb8_punchthrough_alpha1
;
1523 case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1
:
1524 return fetch_etc2_srgb8_punchthrough_alpha1
;