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 "mfeatures.h"
42 #include "texcompress.h"
43 #include "texcompress_etc.h"
46 #include "swrast/s_context.h"
47 #include "format_unpack.h"
51 uint64_t pixel_indices
[2];
52 const int *modifier_tables
[2];
60 uint8_t base_colors
[3][3];
61 uint8_t paint_colors
[4][3];
62 uint8_t base_codeword
;
67 static const int etc2_distance_table
[8] = {
68 3, 6, 11, 16, 23, 32, 41, 64 };
70 static const int etc2_modifier_tables
[16][8] = {
71 { -3, -6, -9, -15, 2, 5, 8, 14},
72 { -3, -7, -10, -13, 2, 6, 9, 12},
73 { -2, -5, -8, -13, 1, 4, 7, 12},
74 { -2, -4, -6, -13, 1, 3, 5, 12},
75 { -3, -6, -8, -12, 2, 5, 7, 11},
76 { -3, -7, -9, -11, 2, 6, 8, 10},
77 { -4, -7, -8, -11, 3, 6, 7, 10},
78 { -3, -5, -8, -11, 2, 4, 7, 10},
79 { -2, -6, -8, -10, 1, 5, 7, 9},
80 { -2, -5, -8, -10, 1, 4, 7, 9},
81 { -2, -4, -8, -10, 1, 3, 7, 9},
82 { -2, -5, -7, -10, 1, 4, 6, 9},
83 { -3, -4, -7, -10, 2, 3, 6, 9},
84 { -1, -2, -3, -10, 0, 1, 2, 9},
85 { -4, -6, -8, -9, 3, 5, 7, 8},
86 { -3, -5, -7, -9, 2, 4, 6, 8},
89 static const int etc2_modifier_tables_non_opaque
[8][4] = {
100 /* define etc1_parse_block and etc. */
101 #define UINT8_TYPE GLubyte
103 #include "texcompress_etc_tmp.h"
108 _mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS
)
110 /* GL_ETC1_RGB8_OES is only valid in glCompressedTexImage2D */
117 _mesa_fetch_texel_2d_f_etc1_rgb8(const struct swrast_texture_image
*texImage
,
118 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
120 struct etc1_block block
;
124 src
= (const GLubyte
*) texImage
->Map
+
125 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
127 etc1_parse_block(&block
, src
);
128 etc1_fetch_texel(&block
, i
% 4, j
% 4, dst
);
130 texel
[RCOMP
] = UBYTE_TO_FLOAT(dst
[0]);
131 texel
[GCOMP
] = UBYTE_TO_FLOAT(dst
[1]);
132 texel
[BCOMP
] = UBYTE_TO_FLOAT(dst
[2]);
137 * Decode texture data in format `MESA_FORMAT_ETC1_RGB8` to
138 * `MESA_FORMAT_ABGR8888`.
140 * The size of the source data must be a multiple of the ETC1 block size,
141 * which is 8, even if the texture image's dimensions are not aligned to 4.
142 * From the GL_OES_compressed_ETC1_RGB8_texture spec:
143 * The texture is described as a number of 4x4 pixel blocks. If the
144 * texture (or a particular mip-level) is smaller than 4 pixels in
145 * any dimension (such as a 2x2 or a 8x1 texture), the texture is
146 * found in the upper left part of the block(s), and the rest of the
147 * pixels are not used. For instance, a texture of size 4x2 will be
148 * placed in the upper half of a 4x4 block, and the lower half of the
149 * pixels in the block will not be accessed.
151 * \param src_width in pixels
152 * \param src_height in pixels
153 * \param dst_stride in bytes
156 _mesa_etc1_unpack_rgba8888(uint8_t *dst_row
,
158 const uint8_t *src_row
,
163 etc1_unpack_rgba8888(dst_row
, dst_stride
,
165 src_width
, src_height
);
169 etc2_base_color1_t_mode(const uint8_t *in
, GLuint index
)
171 uint8_t R1a
= 0, x
= 0;
172 /* base col 1 = extend_4to8bits( (R1a << 2) | R1b, G1, B1) */
175 R1a
= (in
[0] >> 3) & 0x3;
176 x
= ((R1a
<< 2) | (in
[0] & 0x3));
179 x
= ((in
[1] >> 4) & 0xf);
188 return ((x
<< 4) | (x
& 0xf));
192 etc2_base_color2_t_mode(const uint8_t *in
, GLuint index
)
195 /*extend 4to8bits(R2, G2, B2)*/
198 x
= ((in
[2] >> 4) & 0xf );
204 x
= ((in
[3] >> 4) & 0xf);
210 return ((x
<< 4) | (x
& 0xf));
214 etc2_base_color1_h_mode(const uint8_t *in
, GLuint index
)
217 /* base col 1 = extend 4to8bits(R1, (G1a << 1) | G1b, (B1a << 3) | B1b) */
220 x
= ((in
[0] >> 3) & 0xf);
223 x
= (((in
[0] & 0x7) << 1) | ((in
[1] >> 4) & 0x1));
227 (((in
[1] & 0x3) << 1) | ((in
[2] >> 7) & 0x1)));
233 return ((x
<< 4) | (x
& 0xf));
237 etc2_base_color2_h_mode(const uint8_t *in
, GLuint index
)
240 /* base col 2 = extend 4to8bits(R2, G2, B2) */
243 x
= ((in
[2] >> 3) & 0xf );
246 x
= (((in
[2] & 0x7) << 1) | ((in
[3] >> 7) & 0x1));
249 x
= ((in
[3] >> 3) & 0xf);
255 return ((x
<< 4) | (x
& 0xf));
259 etc2_base_color_o_planar(const uint8_t *in
, GLuint index
)
264 tmp
= ((in
[0] >> 1) & 0x3f); /* RO */
265 return ((tmp
<< 2) | (tmp
>> 4));
267 tmp
= (((in
[0] & 0x1) << 6) | /* GO1 */
268 ((in
[1] >> 1) & 0x3f)); /* GO2 */
269 return ((tmp
<< 1) | (tmp
>> 6));
271 tmp
= (((in
[1] & 0x1) << 5) | /* BO1 */
272 (in
[2] & 0x18) | /* BO2 */
273 (((in
[2] & 0x3) << 1) | ((in
[3] >> 7) & 0x1))); /* BO3 */
274 return ((tmp
<< 2) | (tmp
>> 4));
282 etc2_base_color_h_planar(const uint8_t *in
, GLuint index
)
287 tmp
= (((in
[3] & 0x7c) >> 1) | /* RH1 */
288 (in
[3] & 0x1)); /* RH2 */
289 return ((tmp
<< 2) | (tmp
>> 4));
291 tmp
= (in
[4] >> 1) & 0x7f; /* GH */
292 return ((tmp
<< 1) | (tmp
>> 6));
294 tmp
= (((in
[4] & 0x1) << 5) |
295 ((in
[5] >> 3) & 0x1f)); /* BH */
296 return ((tmp
<< 2) | (tmp
>> 4));
304 etc2_base_color_v_planar(const uint8_t *in
, GLuint index
)
309 tmp
= (((in
[5] & 0x7) << 0x3) |
310 ((in
[6] >> 5) & 0x7)); /* RV */
311 return ((tmp
<< 2) | (tmp
>> 4));
313 tmp
= (((in
[6] & 0x1f) << 2) |
314 ((in
[7] >> 6) & 0x3)); /* GV */
315 return ((tmp
<< 1) | (tmp
>> 6));
317 tmp
= in
[7] & 0x3f; /* BV */
318 return ((tmp
<< 2) | (tmp
>> 4));
326 etc2_get_pixel_index(const struct etc2_block
*block
, int x
, int y
)
328 int bit
= ((3 - y
) + (3 - x
) * 4) * 3;
329 int idx
= (block
->pixel_indices
[1] >> bit
) & 0x7;
334 etc2_clamp(int color
)
336 /* CLAMP(color, 0, 255) */
337 return (uint8_t) CLAMP(color
, 0, 255);
341 etc2_clamp2(int color
)
343 /* CLAMP(color, 0, 2047) */
344 return (GLushort
) CLAMP(color
, 0, 2047);
348 etc2_clamp3(int color
)
350 /* CLAMP(color, -1023, 1023) */
351 return (GLshort
) CLAMP(color
, -1023, 1023);
355 etc2_rgb8_parse_block(struct etc2_block
*block
,
357 GLboolean punchthrough_alpha
)
360 GLboolean diffbit
= false;
361 static const int lookup
[8] = { 0, 1, 2, 3, -4, -3, -2, -1 };
363 const int R_plus_dR
= (src
[0] >> 3) + lookup
[src
[0] & 0x7];
364 const int G_plus_dG
= (src
[1] >> 3) + lookup
[src
[1] & 0x7];
365 const int B_plus_dB
= (src
[2] >> 3) + lookup
[src
[2] & 0x7];
367 /* Reset the mode flags */
368 block
->is_ind_mode
= false;
369 block
->is_diff_mode
= false;
370 block
->is_t_mode
= false;
371 block
->is_h_mode
= false;
372 block
->is_planar_mode
= false;
374 if (punchthrough_alpha
)
375 block
->opaque
= src
[3] & 0x2;
377 diffbit
= src
[3] & 0x2;
379 if (!diffbit
&& !punchthrough_alpha
) {
380 /* individual mode */
381 block
->is_ind_mode
= true;
383 for (i
= 0; i
< 3; i
++) {
384 /* Texture decode algorithm is same for individual mode in etc1
387 block
->base_colors
[0][i
] = etc1_base_color_ind_hi(src
[i
]);
388 block
->base_colors
[1][i
] = etc1_base_color_ind_lo(src
[i
]);
391 else if (R_plus_dR
< 0 || R_plus_dR
> 31){
393 block
->is_t_mode
= true;
395 for(i
= 0; i
< 3; i
++) {
396 block
->base_colors
[0][i
] = etc2_base_color1_t_mode(src
, i
);
397 block
->base_colors
[1][i
] = etc2_base_color2_t_mode(src
, i
);
401 etc2_distance_table
[(((src
[3] >> 2) & 0x3) << 1) |
404 for (i
= 0; i
< 3; i
++) {
405 block
->paint_colors
[0][i
] = etc2_clamp(block
->base_colors
[0][i
]);
406 block
->paint_colors
[1][i
] = etc2_clamp(block
->base_colors
[1][i
] +
408 block
->paint_colors
[2][i
] = etc2_clamp(block
->base_colors
[1][i
]);
409 block
->paint_colors
[3][i
] = etc2_clamp(block
->base_colors
[1][i
] -
413 else if (G_plus_dG
< 0 || G_plus_dG
> 31){
414 int base_color_1_value
, base_color_2_value
;
417 block
->is_h_mode
= true;
419 for(i
= 0; i
< 3; i
++) {
420 block
->base_colors
[0][i
] = etc2_base_color1_h_mode(src
, i
);
421 block
->base_colors
[1][i
] = etc2_base_color2_h_mode(src
, i
);
424 base_color_1_value
= (block
->base_colors
[0][0] << 16) +
425 (block
->base_colors
[0][1] << 8) +
426 block
->base_colors
[0][2];
427 base_color_2_value
= (block
->base_colors
[1][0] << 16) +
428 (block
->base_colors
[1][1] << 8) +
429 block
->base_colors
[1][2];
432 etc2_distance_table
[(src
[3] & 0x4) |
433 ((src
[3] & 0x1) << 1) |
434 (base_color_1_value
>= base_color_2_value
)];
436 for (i
= 0; i
< 3; i
++) {
437 block
->paint_colors
[0][i
] = etc2_clamp(block
->base_colors
[0][i
] +
439 block
->paint_colors
[1][i
] = etc2_clamp(block
->base_colors
[0][i
] -
441 block
->paint_colors
[2][i
] = etc2_clamp(block
->base_colors
[1][i
] +
443 block
->paint_colors
[3][i
] = etc2_clamp(block
->base_colors
[1][i
] -
447 else if (B_plus_dB
< 0 || B_plus_dB
> 31) {
449 block
->is_planar_mode
= true;
451 /* opaque bit must be set in planar mode */
453 block
->opaque
= true;
455 for (i
= 0; i
< 3; i
++) {
456 block
->base_colors
[0][i
] = etc2_base_color_o_planar(src
, i
);
457 block
->base_colors
[1][i
] = etc2_base_color_h_planar(src
, i
);
458 block
->base_colors
[2][i
] = etc2_base_color_v_planar(src
, i
);
461 else if (diffbit
|| punchthrough_alpha
) {
462 /* differential mode */
463 block
->is_diff_mode
= true;
465 for (i
= 0; i
< 3; i
++) {
466 /* Texture decode algorithm is same for differential mode in etc1
469 block
->base_colors
[0][i
] = etc1_base_color_diff_hi(src
[i
]);
470 block
->base_colors
[1][i
] = etc1_base_color_diff_lo(src
[i
]);
474 if (block
->is_ind_mode
|| block
->is_diff_mode
) {
475 int table1_idx
= (src
[3] >> 5) & 0x7;
476 int table2_idx
= (src
[3] >> 2) & 0x7;
478 /* Use same modifier tables as for etc1 textures if opaque bit is set
479 * or if non punchthrough texture format
481 block
->modifier_tables
[0] = (block
->opaque
|| !punchthrough_alpha
) ?
482 etc1_modifier_tables
[table1_idx
] :
483 etc2_modifier_tables_non_opaque
[table1_idx
];
484 block
->modifier_tables
[1] = (block
->opaque
|| !punchthrough_alpha
) ?
485 etc1_modifier_tables
[table2_idx
] :
486 etc2_modifier_tables_non_opaque
[table2_idx
];
488 block
->flipped
= (src
[3] & 0x1);
491 block
->pixel_indices
[0] =
492 (src
[4] << 24) | (src
[5] << 16) | (src
[6] << 8) | src
[7];
496 etc2_rgb8_fetch_texel(const struct etc2_block
*block
,
497 int x
, int y
, uint8_t *dst
,
498 GLboolean punchthrough_alpha
)
500 const uint8_t *base_color
;
501 int modifier
, bit
, idx
, blk
;
503 /* get pixel index */
505 idx
= ((block
->pixel_indices
[0] >> (15 + bit
)) & 0x2) |
506 ((block
->pixel_indices
[0] >> (bit
)) & 0x1);
508 if (block
->is_ind_mode
|| block
->is_diff_mode
) {
509 /* check for punchthrough_alpha format */
510 if (punchthrough_alpha
) {
511 if (!block
->opaque
&& idx
== 2) {
512 dst
[0] = dst
[1] = dst
[2] = dst
[3] = 0;
519 /* Use pixel index and subblock to get the modifier */
520 blk
= (block
->flipped
) ? (y
>= 2) : (x
>= 2);
521 base_color
= block
->base_colors
[blk
];
522 modifier
= block
->modifier_tables
[blk
][idx
];
524 dst
[0] = etc2_clamp(base_color
[0] + modifier
);
525 dst
[1] = etc2_clamp(base_color
[1] + modifier
);
526 dst
[2] = etc2_clamp(base_color
[2] + modifier
);
528 else if (block
->is_t_mode
|| block
->is_h_mode
) {
529 /* check for punchthrough_alpha format */
530 if (punchthrough_alpha
) {
531 if (!block
->opaque
&& idx
== 2) {
532 dst
[0] = dst
[1] = dst
[2] = dst
[3] = 0;
539 /* Use pixel index to pick one of the paint colors */
540 dst
[0] = block
->paint_colors
[idx
][0];
541 dst
[1] = block
->paint_colors
[idx
][1];
542 dst
[2] = block
->paint_colors
[idx
][2];
544 else if (block
->is_planar_mode
) {
545 /* {R(x, y) = clamp255((x × (RH − RO) + y × (RV − RO) + 4 × RO + 2) >> 2)
546 * {G(x, y) = clamp255((x × (GH − GO) + y × (GV − GO) + 4 × GO + 2) >> 2)
547 * {B(x, y) = clamp255((x × (BH − BO) + y × (BV − BO) + 4 × BO + 2) >> 2)
549 int red
, green
, blue
;
550 red
= (x
* (block
->base_colors
[1][0] - block
->base_colors
[0][0]) +
551 y
* (block
->base_colors
[2][0] - block
->base_colors
[0][0]) +
552 4 * block
->base_colors
[0][0] + 2) >> 2;
554 green
= (x
* (block
->base_colors
[1][1] - block
->base_colors
[0][1]) +
555 y
* (block
->base_colors
[2][1] - block
->base_colors
[0][1]) +
556 4 * block
->base_colors
[0][1] + 2) >> 2;
558 blue
= (x
* (block
->base_colors
[1][2] - block
->base_colors
[0][2]) +
559 y
* (block
->base_colors
[2][2] - block
->base_colors
[0][2]) +
560 4 * block
->base_colors
[0][2] + 2) >> 2;
562 dst
[0] = etc2_clamp(red
);
563 dst
[1] = etc2_clamp(green
);
564 dst
[2] = etc2_clamp(blue
);
566 /* check for punchthrough_alpha format */
567 if (punchthrough_alpha
)
573 etc2_alpha8_fetch_texel(const struct etc2_block
*block
,
574 int x
, int y
, uint8_t *dst
)
576 int modifier
, alpha
, idx
;
577 /* get pixel index */
578 idx
= etc2_get_pixel_index(block
, x
, y
);
579 modifier
= etc2_modifier_tables
[block
->table_index
][idx
];
580 alpha
= block
->base_codeword
+ modifier
* block
->multiplier
;
581 dst
[3] = etc2_clamp(alpha
);
585 etc2_r11_fetch_texel(const struct etc2_block
*block
,
586 int x
, int y
, uint8_t *dst
)
590 /* Get pixel index */
591 idx
= etc2_get_pixel_index(block
, x
, y
);
592 modifier
= etc2_modifier_tables
[block
->table_index
][idx
];
594 if (block
->multiplier
!= 0)
595 /* clamp2(base codeword × 8 + 4 + modifier × multiplier × 8) */
596 color
= etc2_clamp2(((block
->base_codeword
<< 3) | 0x4) +
597 ((modifier
* block
->multiplier
) << 3));
599 color
= etc2_clamp2(((block
->base_codeword
<< 3) | 0x4) + modifier
);
601 /* Extend 11 bits color value to 16 bits. OpenGL ES 3.0 specification
602 * allows extending the color value to any number of bits. But, an
603 * implementation is not allowed to truncate the 11-bit value to less than
606 color
= (color
<< 5) | (color
>> 6);
607 ((GLushort
*)dst
)[0] = color
;
611 etc2_signed_r11_fetch_texel(const struct etc2_block
*block
,
612 int x
, int y
, uint8_t *dst
)
616 GLbyte base_codeword
= (GLbyte
) block
->base_codeword
;
618 if (base_codeword
== -128)
619 base_codeword
= -127;
621 /* Get pixel index */
622 idx
= etc2_get_pixel_index(block
, x
, y
);
623 modifier
= etc2_modifier_tables
[block
->table_index
][idx
];
625 if (block
->multiplier
!= 0)
626 /* clamp3(base codeword × 8 + modifier × multiplier × 8) */
627 color
= etc2_clamp3((base_codeword
<< 3) +
628 ((modifier
* block
->multiplier
) << 3));
630 color
= etc2_clamp3((base_codeword
<< 3) + modifier
);
632 /* Extend 11 bits color value to 16 bits. OpenGL ES 3.0 specification
633 * allows extending the color value to any number of bits. But, an
634 * implementation is not allowed to truncate the 11-bit value to less than
635 * 11 bits. A negative 11-bit value must first be made positive before bit
636 * replication, and then made negative again
639 color
= (color
<< 5) | (color
>> 5);
642 color
= (color
<< 5) | (color
>> 5);
645 ((GLshort
*)dst
)[0] = color
;
649 etc2_alpha8_parse_block(struct etc2_block
*block
, const uint8_t *src
)
651 block
->base_codeword
= src
[0];
652 block
->multiplier
= (src
[1] >> 4) & 0xf;
653 block
->table_index
= src
[1] & 0xf;
654 block
->pixel_indices
[1] = (((uint64_t)src
[2] << 40) |
655 ((uint64_t)src
[3] << 32) |
656 ((uint64_t)src
[4] << 24) |
657 ((uint64_t)src
[5] << 16) |
658 ((uint64_t)src
[6] << 8) |
663 etc2_r11_parse_block(struct etc2_block
*block
, const uint8_t *src
)
665 /* Parsing logic remains same as for etc2_alpha8_parse_block */
666 etc2_alpha8_parse_block(block
, src
);
670 etc2_rgba8_parse_block(struct etc2_block
*block
, const uint8_t *src
)
672 /* RGB component is parsed the same way as for MESA_FORMAT_ETC2_RGB8 */
673 etc2_rgb8_parse_block(block
, src
+ 8,
674 false /* punchthrough_alpha */);
675 /* Parse Alpha component */
676 etc2_alpha8_parse_block(block
, src
);
680 etc2_rgba8_fetch_texel(const struct etc2_block
*block
,
681 int x
, int y
, uint8_t *dst
)
683 etc2_rgb8_fetch_texel(block
, x
, y
, dst
,
684 false /* punchthrough_alpha */);
685 etc2_alpha8_fetch_texel(block
, x
, y
, dst
);
689 etc2_unpack_rgb8(uint8_t *dst_row
,
691 const uint8_t *src_row
,
696 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 4;
697 struct etc2_block block
;
700 for (y
= 0; y
< height
; y
+= bh
) {
701 const uint8_t *src
= src_row
;
703 for (x
= 0; x
< width
; x
+= bw
) {
704 etc2_rgb8_parse_block(&block
, src
,
705 false /* punchthrough_alpha */);
707 for (j
= 0; j
< bh
; j
++) {
708 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
709 for (i
= 0; i
< bw
; i
++) {
710 etc2_rgb8_fetch_texel(&block
, i
, j
, dst
,
711 false /* punchthrough_alpha */);
720 src_row
+= src_stride
;
725 etc2_unpack_srgb8(uint8_t *dst_row
,
727 const uint8_t *src_row
,
732 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 4;
733 struct etc2_block block
;
737 for (y
= 0; y
< height
; y
+= bh
) {
738 const uint8_t *src
= src_row
;
740 for (x
= 0; x
< width
; x
+= bw
) {
741 etc2_rgb8_parse_block(&block
, src
,
742 false /* punchthrough_alpha */);
744 for (j
= 0; j
< bh
; j
++) {
745 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
746 for (i
= 0; i
< bw
; i
++) {
747 etc2_rgb8_fetch_texel(&block
, i
, j
, dst
,
748 false /* punchthrough_alpha */);
749 /* Convert to MESA_FORMAT_SARGB8 */
761 src_row
+= src_stride
;
766 etc2_unpack_rgba8(uint8_t *dst_row
,
768 const uint8_t *src_row
,
773 /* If internalformat is COMPRESSED_RGBA8_ETC2_EAC, each 4 × 4 block of
774 * RGBA8888 information is compressed to 128 bits. To decode a block, the
775 * two 64-bit integers int64bitAlpha and int64bitColor are calculated.
777 const unsigned bw
= 4, bh
= 4, bs
= 16, comps
= 4;
778 struct etc2_block block
;
781 for (y
= 0; y
< height
; y
+= bh
) {
782 const uint8_t *src
= src_row
;
784 for (x
= 0; x
< width
; x
+= bw
) {
785 etc2_rgba8_parse_block(&block
, src
);
787 for (j
= 0; j
< bh
; j
++) {
788 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
789 for (i
= 0; i
< bw
; i
++) {
790 etc2_rgba8_fetch_texel(&block
, i
, j
, dst
);
797 src_row
+= src_stride
;
802 etc2_unpack_srgb8_alpha8(uint8_t *dst_row
,
804 const uint8_t *src_row
,
809 /* If internalformat is COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, each 4 × 4 block
810 * of RGBA8888 information is compressed to 128 bits. To decode a block, the
811 * two 64-bit integers int64bitAlpha and int64bitColor are calculated.
813 const unsigned bw
= 4, bh
= 4, bs
= 16, comps
= 4;
814 struct etc2_block block
;
818 for (y
= 0; y
< height
; y
+= bh
) {
819 const uint8_t *src
= src_row
;
821 for (x
= 0; x
< width
; x
+= bw
) {
822 etc2_rgba8_parse_block(&block
, src
);
824 for (j
= 0; j
< bh
; j
++) {
825 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
826 for (i
= 0; i
< bw
; i
++) {
827 etc2_rgba8_fetch_texel(&block
, i
, j
, dst
);
829 /* Convert to MESA_FORMAT_SARGB8 */
841 src_row
+= src_stride
;
846 etc2_unpack_r11(uint8_t *dst_row
,
848 const uint8_t *src_row
,
853 /* If internalformat is COMPRESSED_R11_EAC, each 4 × 4 block of
854 color information is compressed to 64 bits.
856 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 1, comp_size
= 2;
857 struct etc2_block block
;
860 for (y
= 0; y
< height
; y
+= bh
) {
861 const uint8_t *src
= src_row
;
863 for (x
= 0; x
< width
; x
+= bw
) {
864 etc2_r11_parse_block(&block
, src
);
866 for (j
= 0; j
< bh
; j
++) {
867 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
* comp_size
;
868 for (i
= 0; i
< bw
; i
++) {
869 etc2_r11_fetch_texel(&block
, i
, j
, dst
);
870 dst
+= comps
* comp_size
;
876 src_row
+= src_stride
;
881 etc2_unpack_rg11(uint8_t *dst_row
,
883 const uint8_t *src_row
,
888 /* If internalformat is COMPRESSED_RG11_EAC, each 4 × 4 block of
889 RG color information is compressed to 128 bits.
891 const unsigned bw
= 4, bh
= 4, bs
= 16, comps
= 2, comp_size
= 2;
892 struct etc2_block block
;
895 for (y
= 0; y
< height
; y
+= bh
) {
896 const uint8_t *src
= src_row
;
898 for (x
= 0; x
< width
; x
+= bw
) {
900 etc2_r11_parse_block(&block
, src
);
902 for (j
= 0; j
< bh
; j
++) {
903 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+
904 x
* comps
* comp_size
;
905 for (i
= 0; i
< bw
; i
++) {
906 etc2_r11_fetch_texel(&block
, i
, j
, dst
);
907 dst
+= comps
* comp_size
;
910 /* green component */
911 etc2_r11_parse_block(&block
, src
+ 8);
913 for (j
= 0; j
< bh
; j
++) {
914 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+
915 x
* comps
* comp_size
;
916 for (i
= 0; i
< bw
; i
++) {
917 etc2_r11_fetch_texel(&block
, i
, j
, dst
+ comp_size
);
918 dst
+= comps
* comp_size
;
924 src_row
+= src_stride
;
929 etc2_unpack_signed_r11(uint8_t *dst_row
,
931 const uint8_t *src_row
,
936 /* If internalformat is COMPRESSED_SIGNED_R11_EAC, each 4 × 4 block of
937 red color information is compressed to 64 bits.
939 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 1, comp_size
= 2;
940 struct etc2_block block
;
943 for (y
= 0; y
< height
; y
+= bh
) {
944 const uint8_t *src
= src_row
;
946 for (x
= 0; x
< width
; x
+= bw
) {
947 etc2_r11_parse_block(&block
, src
);
949 for (j
= 0; j
< bh
; j
++) {
950 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+
951 x
* comps
* comp_size
;
952 for (i
= 0; i
< bw
; i
++) {
953 etc2_signed_r11_fetch_texel(&block
, i
, j
, dst
);
954 dst
+= comps
* comp_size
;
960 src_row
+= src_stride
;
965 etc2_unpack_signed_rg11(uint8_t *dst_row
,
967 const uint8_t *src_row
,
972 /* If internalformat is COMPRESSED_SIGNED_RG11_EAC, each 4 × 4 block of
973 RG color information is compressed to 128 bits.
975 const unsigned bw
= 4, bh
= 4, bs
= 16, comps
= 2, comp_size
= 2;
976 struct etc2_block block
;
979 for (y
= 0; y
< height
; y
+= bh
) {
980 const uint8_t *src
= src_row
;
982 for (x
= 0; x
< width
; x
+= bw
) {
984 etc2_r11_parse_block(&block
, src
);
986 for (j
= 0; j
< bh
; j
++) {
987 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+
988 x
* comps
* comp_size
;
989 for (i
= 0; i
< bw
; i
++) {
990 etc2_signed_r11_fetch_texel(&block
, i
, j
, dst
);
991 dst
+= comps
* comp_size
;
994 /* green component */
995 etc2_r11_parse_block(&block
, src
+ 8);
997 for (j
= 0; j
< bh
; j
++) {
998 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+
999 x
* comps
* comp_size
;
1000 for (i
= 0; i
< bw
; i
++) {
1001 etc2_signed_r11_fetch_texel(&block
, i
, j
, dst
+ comp_size
);
1002 dst
+= comps
* comp_size
;
1008 src_row
+= src_stride
;
1013 etc2_unpack_rgb8_punchthrough_alpha1(uint8_t *dst_row
,
1014 unsigned dst_stride
,
1015 const uint8_t *src_row
,
1016 unsigned src_stride
,
1020 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 4;
1021 struct etc2_block block
;
1022 unsigned x
, y
, i
, j
;
1024 for (y
= 0; y
< height
; y
+= bh
) {
1025 const uint8_t *src
= src_row
;
1027 for (x
= 0; x
< width
; x
+= bw
) {
1028 etc2_rgb8_parse_block(&block
, src
,
1029 true /* punchthrough_alpha */);
1030 for (j
= 0; j
< bh
; j
++) {
1031 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
1032 for (i
= 0; i
< bw
; i
++) {
1033 etc2_rgb8_fetch_texel(&block
, i
, j
, dst
,
1034 true /* punchthrough_alpha */);
1042 src_row
+= src_stride
;
1047 etc2_unpack_srgb8_punchthrough_alpha1(uint8_t *dst_row
,
1048 unsigned dst_stride
,
1049 const uint8_t *src_row
,
1050 unsigned src_stride
,
1054 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 4;
1055 struct etc2_block block
;
1056 unsigned x
, y
, i
, j
;
1059 for (y
= 0; y
< height
; y
+= bh
) {
1060 const uint8_t *src
= src_row
;
1062 for (x
= 0; x
< width
; x
+= bw
) {
1063 etc2_rgb8_parse_block(&block
, src
,
1064 true /* punchthrough_alpha */);
1065 for (j
= 0; j
< bh
; j
++) {
1066 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
1067 for (i
= 0; i
< bw
; i
++) {
1068 etc2_rgb8_fetch_texel(&block
, i
, j
, dst
,
1069 true /* punchthrough_alpha */);
1070 /* Convert to MESA_FORMAT_SARGB8 */
1083 src_row
+= src_stride
;
1087 /* ETC2 texture formats are valid in glCompressedTexImage2D and
1088 * glCompressedTexSubImage2D functions */
1090 _mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS
)
1098 _mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS
)
1106 _mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS
)
1114 _mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS
)
1122 _mesa_texstore_etc2_r11_eac(TEXSTORE_PARAMS
)
1130 _mesa_texstore_etc2_signed_r11_eac(TEXSTORE_PARAMS
)
1138 _mesa_texstore_etc2_rg11_eac(TEXSTORE_PARAMS
)
1146 _mesa_texstore_etc2_signed_rg11_eac(TEXSTORE_PARAMS
)
1154 _mesa_texstore_etc2_rgb8_punchthrough_alpha1(TEXSTORE_PARAMS
)
1162 _mesa_texstore_etc2_srgb8_punchthrough_alpha1(TEXSTORE_PARAMS
)
1170 _mesa_fetch_texel_2d_f_etc2_rgb8(const struct swrast_texture_image
*texImage
,
1171 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
1173 struct etc2_block block
;
1177 src
= texImage
->Map
+
1178 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
1180 etc2_rgb8_parse_block(&block
, src
,
1181 false /* punchthrough_alpha */);
1182 etc2_rgb8_fetch_texel(&block
, i
% 4, j
% 4, dst
,
1183 false /* punchthrough_alpha */);
1185 texel
[RCOMP
] = UBYTE_TO_FLOAT(dst
[0]);
1186 texel
[GCOMP
] = UBYTE_TO_FLOAT(dst
[1]);
1187 texel
[BCOMP
] = UBYTE_TO_FLOAT(dst
[2]);
1188 texel
[ACOMP
] = 1.0f
;
1192 _mesa_fetch_texel_2d_f_etc2_srgb8(const struct swrast_texture_image
*texImage
,
1193 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
1195 struct etc2_block block
;
1199 src
= texImage
->Map
+
1200 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
1202 etc2_rgb8_parse_block(&block
, src
,
1203 false /* punchthrough_alpha */);
1204 etc2_rgb8_fetch_texel(&block
, i
% 4, j
% 4, dst
,
1205 false /* punchthrough_alpha */);
1207 texel
[RCOMP
] = _mesa_nonlinear_to_linear(dst
[0]);
1208 texel
[GCOMP
] = _mesa_nonlinear_to_linear(dst
[1]);
1209 texel
[BCOMP
] = _mesa_nonlinear_to_linear(dst
[2]);
1210 texel
[ACOMP
] = 1.0f
;
1214 _mesa_fetch_texel_2d_f_etc2_rgba8_eac(const struct swrast_texture_image
*texImage
,
1215 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
1217 struct etc2_block block
;
1221 src
= texImage
->Map
+
1222 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
1224 etc2_rgba8_parse_block(&block
, src
);
1225 etc2_rgba8_fetch_texel(&block
, i
% 4, j
% 4, dst
);
1227 texel
[RCOMP
] = UBYTE_TO_FLOAT(dst
[0]);
1228 texel
[GCOMP
] = UBYTE_TO_FLOAT(dst
[1]);
1229 texel
[BCOMP
] = UBYTE_TO_FLOAT(dst
[2]);
1230 texel
[ACOMP
] = UBYTE_TO_FLOAT(dst
[3]);
1234 _mesa_fetch_texel_2d_f_etc2_srgb8_alpha8_eac(const struct
1235 swrast_texture_image
*texImage
,
1237 GLint k
, GLfloat
*texel
)
1239 struct etc2_block block
;
1243 src
= texImage
->Map
+
1244 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
1246 etc2_rgba8_parse_block(&block
, src
);
1247 etc2_rgba8_fetch_texel(&block
, i
% 4, j
% 4, dst
);
1249 texel
[RCOMP
] = _mesa_nonlinear_to_linear(dst
[0]);
1250 texel
[GCOMP
] = _mesa_nonlinear_to_linear(dst
[1]);
1251 texel
[BCOMP
] = _mesa_nonlinear_to_linear(dst
[2]);
1252 texel
[ACOMP
] = UBYTE_TO_FLOAT(dst
[3]);
1256 _mesa_fetch_texel_2d_f_etc2_r11_eac(const struct swrast_texture_image
*texImage
,
1257 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
1259 struct etc2_block block
;
1263 src
= texImage
->Map
+
1264 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
1266 etc2_r11_parse_block(&block
, src
);
1267 etc2_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)&dst
);
1269 texel
[RCOMP
] = USHORT_TO_FLOAT(dst
);
1270 texel
[GCOMP
] = 0.0f
;
1271 texel
[BCOMP
] = 0.0f
;
1272 texel
[ACOMP
] = 1.0f
;
1276 _mesa_fetch_texel_2d_f_etc2_rg11_eac(const struct
1277 swrast_texture_image
*texImage
,
1279 GLint k
, GLfloat
*texel
)
1281 struct etc2_block block
;
1285 src
= texImage
->Map
+
1286 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
1289 etc2_r11_parse_block(&block
, src
);
1290 etc2_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)dst
);
1292 /* green component */
1293 etc2_r11_parse_block(&block
, src
+ 8);
1294 etc2_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)(dst
+ 1));
1296 texel
[RCOMP
] = USHORT_TO_FLOAT(dst
[0]);
1297 texel
[GCOMP
] = USHORT_TO_FLOAT(dst
[1]);
1298 texel
[BCOMP
] = 0.0f
;
1299 texel
[ACOMP
] = 1.0f
;
1303 _mesa_fetch_texel_2d_f_etc2_signed_r11_eac(const struct swrast_texture_image
*texImage
,
1304 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
1306 struct etc2_block block
;
1310 src
= texImage
->Map
+
1311 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
1313 etc2_r11_parse_block(&block
, src
);
1314 etc2_signed_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)&dst
);
1316 texel
[RCOMP
] = SHORT_TO_FLOAT(dst
);
1317 texel
[GCOMP
] = 0.0f
;
1318 texel
[BCOMP
] = 0.0f
;
1319 texel
[ACOMP
] = 1.0f
;
1323 _mesa_fetch_texel_2d_f_etc2_signed_rg11_eac(const struct swrast_texture_image
*texImage
,
1324 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
1326 struct etc2_block block
;
1330 src
= texImage
->Map
+
1331 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
1334 etc2_r11_parse_block(&block
, src
);
1335 etc2_signed_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)dst
);
1337 /* green component */
1338 etc2_r11_parse_block(&block
, src
+ 8);
1339 etc2_signed_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)(dst
+ 1));
1341 texel
[RCOMP
] = SHORT_TO_FLOAT(dst
[0]);
1342 texel
[GCOMP
] = SHORT_TO_FLOAT(dst
[1]);
1343 texel
[BCOMP
] = 0.0f
;
1344 texel
[ACOMP
] = 1.0f
;
1348 _mesa_fetch_texel_2d_f_etc2_rgb8_punchthrough_alpha1(
1349 const struct swrast_texture_image
*texImage
,
1351 GLint k
, GLfloat
*texel
)
1353 struct etc2_block block
;
1357 src
= texImage
->Map
+
1358 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
1360 etc2_rgb8_parse_block(&block
, src
,
1361 true /* punchthrough alpha */);
1362 etc2_rgb8_fetch_texel(&block
, i
% 4, j
% 4, dst
,
1363 true /* punchthrough alpha */);
1364 texel
[RCOMP
] = UBYTE_TO_FLOAT(dst
[0]);
1365 texel
[GCOMP
] = UBYTE_TO_FLOAT(dst
[1]);
1366 texel
[BCOMP
] = UBYTE_TO_FLOAT(dst
[2]);
1367 texel
[ACOMP
] = UBYTE_TO_FLOAT(dst
[3]);
1371 _mesa_fetch_texel_2d_f_etc2_srgb8_punchthrough_alpha1(
1372 const struct swrast_texture_image
*texImage
,
1374 GLint k
, GLfloat
*texel
)
1376 struct etc2_block block
;
1380 src
= texImage
->Map
+
1381 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
1383 etc2_rgb8_parse_block(&block
, src
,
1384 true /* punchthrough alpha */);
1385 etc2_rgb8_fetch_texel(&block
, i
% 4, j
% 4, dst
,
1386 true /* punchthrough alpha */);
1387 texel
[RCOMP
] = _mesa_nonlinear_to_linear(dst
[0]);
1388 texel
[GCOMP
] = _mesa_nonlinear_to_linear(dst
[1]);
1389 texel
[BCOMP
] = _mesa_nonlinear_to_linear(dst
[2]);
1390 texel
[ACOMP
] = UBYTE_TO_FLOAT(dst
[3]);
1394 * Decode texture data in any one of following formats:
1395 * `MESA_FORMAT_ETC2_RGB8`
1396 * `MESA_FORMAT_ETC2_SRGB8`
1397 * `MESA_FORMAT_ETC2_RGBA8_EAC`
1398 * `MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC`
1399 * `MESA_FORMAT_ETC2_R11_EAC`
1400 * `MESA_FORMAT_ETC2_RG11_EAC`
1401 * `MESA_FORMAT_ETC2_SIGNED_R11_EAC`
1402 * `MESA_FORMAT_ETC2_SIGNED_RG11_EAC`
1403 * `MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1`
1404 * `MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1`
1406 * The size of the source data must be a multiple of the ETC2 block size
1407 * even if the texture image's dimensions are not aligned to 4.
1409 * \param src_width in pixels
1410 * \param src_height in pixels
1411 * \param dst_stride in bytes
1415 _mesa_unpack_etc2_format(uint8_t *dst_row
,
1416 unsigned dst_stride
,
1417 const uint8_t *src_row
,
1418 unsigned src_stride
,
1420 unsigned src_height
,
1423 if (format
== MESA_FORMAT_ETC2_RGB8
)
1424 etc2_unpack_rgb8(dst_row
, dst_stride
,
1425 src_row
, src_stride
,
1426 src_width
, src_height
);
1427 else if (format
== MESA_FORMAT_ETC2_SRGB8
)
1428 etc2_unpack_srgb8(dst_row
, dst_stride
,
1429 src_row
, src_stride
,
1430 src_width
, src_height
);
1431 else if (format
== MESA_FORMAT_ETC2_RGBA8_EAC
)
1432 etc2_unpack_rgba8(dst_row
, dst_stride
,
1433 src_row
, src_stride
,
1434 src_width
, src_height
);
1435 else if (format
== MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC
)
1436 etc2_unpack_srgb8_alpha8(dst_row
, dst_stride
,
1437 src_row
, src_stride
,
1438 src_width
, src_height
);
1439 else if (format
== MESA_FORMAT_ETC2_R11_EAC
)
1440 etc2_unpack_r11(dst_row
, dst_stride
,
1441 src_row
, src_stride
,
1442 src_width
, src_height
);
1443 else if (format
== MESA_FORMAT_ETC2_RG11_EAC
)
1444 etc2_unpack_rg11(dst_row
, dst_stride
,
1445 src_row
, src_stride
,
1446 src_width
, src_height
);
1447 else if (format
== MESA_FORMAT_ETC2_SIGNED_R11_EAC
)
1448 etc2_unpack_signed_r11(dst_row
, dst_stride
,
1449 src_row
, src_stride
,
1450 src_width
, src_height
);
1451 else if (format
== MESA_FORMAT_ETC2_SIGNED_RG11_EAC
)
1452 etc2_unpack_signed_rg11(dst_row
, dst_stride
,
1453 src_row
, src_stride
,
1454 src_width
, src_height
);
1455 else if (format
== MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1
)
1456 etc2_unpack_rgb8_punchthrough_alpha1(dst_row
, dst_stride
,
1457 src_row
, src_stride
,
1458 src_width
, src_height
);
1459 else if (format
== MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1
)
1460 etc2_unpack_srgb8_punchthrough_alpha1(dst_row
, dst_stride
,
1461 src_row
, src_stride
,
1462 src_width
, src_height
);