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
39 #include "mfeatures.h"
40 #include "texcompress.h"
41 #include "texcompress_etc.h"
44 #include "swrast/s_context.h"
45 #include "format_unpack.h"
49 uint64_t pixel_indices
[2];
50 const int *modifier_tables
[2];
57 uint8_t base_colors
[3][3];
58 uint8_t paint_colors
[4][3];
59 uint8_t base_codeword
;
64 static const int etc2_distance_table
[8] = {
65 3, 6, 11, 16, 23, 32, 41, 64 };
67 static const int etc2_modifier_tables
[16][8] = {
68 { -3, -6, -9, -15, 2, 5, 8, 14},
69 { -3, -7, -10, -13, 2, 6, 9, 12},
70 { -2, -5, -8, -13, 1, 4, 7, 12},
71 { -2, -4, -6, -13, 1, 3, 5, 12},
72 { -3, -6, -8, -12, 2, 5, 7, 11},
73 { -3, -7, -9, -11, 2, 6, 8, 10},
74 { -4, -7, -8, -11, 3, 6, 7, 10},
75 { -3, -5, -8, -11, 2, 4, 7, 10},
76 { -2, -6, -8, -10, 1, 5, 7, 9},
77 { -2, -5, -8, -10, 1, 4, 7, 9},
78 { -2, -4, -8, -10, 1, 3, 7, 9},
79 { -2, -5, -7, -10, 1, 4, 6, 9},
80 { -3, -4, -7, -10, 2, 3, 6, 9},
81 { -1, -2, -3, -10, 0, 1, 2, 9},
82 { -4, -6, -8, -9, 3, 5, 7, 8},
83 { -3, -5, -7, -9, 2, 4, 6, 8},
86 /* define etc1_parse_block and etc. */
87 #define UINT8_TYPE GLubyte
89 #include "texcompress_etc_tmp.h"
94 _mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS
)
96 /* GL_ETC1_RGB8_OES is only valid in glCompressedTexImage2D */
103 _mesa_fetch_texel_2d_f_etc1_rgb8(const struct swrast_texture_image
*texImage
,
104 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
106 struct etc1_block block
;
110 src
= (const GLubyte
*) texImage
->Map
+
111 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
113 etc1_parse_block(&block
, src
);
114 etc1_fetch_texel(&block
, i
% 4, j
% 4, dst
);
116 texel
[RCOMP
] = UBYTE_TO_FLOAT(dst
[0]);
117 texel
[GCOMP
] = UBYTE_TO_FLOAT(dst
[1]);
118 texel
[BCOMP
] = UBYTE_TO_FLOAT(dst
[2]);
123 * Decode texture data in format `MESA_FORMAT_ETC1_RGB8` to
124 * `MESA_FORMAT_ABGR8888`.
126 * The size of the source data must be a multiple of the ETC1 block size,
127 * which is 8, even if the texture image's dimensions are not aligned to 4.
128 * From the GL_OES_compressed_ETC1_RGB8_texture spec:
129 * The texture is described as a number of 4x4 pixel blocks. If the
130 * texture (or a particular mip-level) is smaller than 4 pixels in
131 * any dimension (such as a 2x2 or a 8x1 texture), the texture is
132 * found in the upper left part of the block(s), and the rest of the
133 * pixels are not used. For instance, a texture of size 4x2 will be
134 * placed in the upper half of a 4x4 block, and the lower half of the
135 * pixels in the block will not be accessed.
137 * \param src_width in pixels
138 * \param src_height in pixels
139 * \param dst_stride in bytes
142 _mesa_etc1_unpack_rgba8888(uint8_t *dst_row
,
144 const uint8_t *src_row
,
149 etc1_unpack_rgba8888(dst_row
, dst_stride
,
151 src_width
, src_height
);
155 etc2_base_color1_t_mode(const uint8_t *in
, GLuint index
)
157 uint8_t R1a
= 0, x
= 0;
158 /* base col 1 = extend_4to8bits( (R1a << 2) | R1b, G1, B1) */
161 R1a
= (in
[0] >> 3) & 0x3;
162 x
= ((R1a
<< 2) | (in
[0] & 0x3));
165 x
= ((in
[1] >> 4) & 0xf);
174 return ((x
<< 4) | (x
& 0xf));
178 etc2_base_color2_t_mode(const uint8_t *in
, GLuint index
)
181 /*extend 4to8bits(R2, G2, B2)*/
184 x
= ((in
[2] >> 4) & 0xf );
190 x
= ((in
[3] >> 4) & 0xf);
196 return ((x
<< 4) | (x
& 0xf));
200 etc2_base_color1_h_mode(const uint8_t *in
, GLuint index
)
203 /* base col 1 = extend 4to8bits(R1, (G1a << 1) | G1b, (B1a << 3) | B1b) */
206 x
= ((in
[0] >> 3) & 0xf);
209 x
= (((in
[0] & 0x7) << 1) | ((in
[1] >> 4) & 0x1));
213 (((in
[1] & 0x3) << 1) | ((in
[2] >> 7) & 0x1)));
219 return ((x
<< 4) | (x
& 0xf));
223 etc2_base_color2_h_mode(const uint8_t *in
, GLuint index
)
226 /* base col 2 = extend 4to8bits(R2, G2, B2) */
229 x
= ((in
[2] >> 3) & 0xf );
232 x
= (((in
[2] & 0x7) << 1) | ((in
[3] >> 7) & 0x1));
235 x
= ((in
[3] >> 3) & 0xf);
241 return ((x
<< 4) | (x
& 0xf));
245 etc2_base_color_o_planar(const uint8_t *in
, GLuint index
)
250 tmp
= ((in
[0] >> 1) & 0x3f); /* RO */
251 return ((tmp
<< 2) | (tmp
>> 4));
253 tmp
= (((in
[0] & 0x1) << 6) | /* GO1 */
254 ((in
[1] >> 1) & 0x3f)); /* GO2 */
255 return ((tmp
<< 1) | (tmp
>> 6));
257 tmp
= (((in
[1] & 0x1) << 5) | /* BO1 */
258 (in
[2] & 0x18) | /* BO2 */
259 (((in
[2] & 0x3) << 1) | ((in
[3] >> 7) & 0x1))); /* BO3 */
260 return ((tmp
<< 2) | (tmp
>> 4));
268 etc2_base_color_h_planar(const uint8_t *in
, GLuint index
)
273 tmp
= (((in
[3] & 0x7c) >> 1) | /* RH1 */
274 (in
[3] & 0x1)); /* RH2 */
275 return ((tmp
<< 2) | (tmp
>> 4));
277 tmp
= (in
[4] >> 1) & 0x7f; /* GH */
278 return ((tmp
<< 1) | (tmp
>> 6));
280 tmp
= (((in
[4] & 0x1) << 5) |
281 ((in
[5] >> 3) & 0x1f)); /* BH */
282 return ((tmp
<< 2) | (tmp
>> 4));
290 etc2_base_color_v_planar(const uint8_t *in
, GLuint index
)
295 tmp
= (((in
[5] & 0x7) << 0x3) |
296 ((in
[6] >> 5) & 0x7)); /* RV */
297 return ((tmp
<< 2) | (tmp
>> 4));
299 tmp
= (((in
[6] & 0x1f) << 2) |
300 ((in
[7] >> 6) & 0x3)); /* GV */
301 return ((tmp
<< 1) | (tmp
>> 6));
303 tmp
= in
[7] & 0x3f; /* BV */
304 return ((tmp
<< 2) | (tmp
>> 4));
312 etc2_get_pixel_index(const struct etc2_block
*block
, int x
, int y
)
314 int bit
= ((3 - y
) + (3 - x
) * 4) * 3;
315 int idx
= (block
->pixel_indices
[1] >> bit
) & 0x7;
320 etc2_clamp(int color
)
322 /* CLAMP(color, 0, 255) */
323 return (uint8_t) CLAMP(color
, 0, 255);
327 etc2_clamp2(int color
)
329 /* CLAMP(color, 0, 2047) */
330 return (GLushort
) CLAMP(color
, 0, 2047);
334 etc2_clamp3(int color
)
336 /* CLAMP(color, -1023, 1023) */
337 return (GLshort
) CLAMP(color
, -1023, 1023);
341 etc2_rgb8_parse_block(struct etc2_block
*block
, const uint8_t *src
)
344 GLboolean diffbit
= src
[3] & 0x2;
345 static const int lookup
[8] = { 0, 1, 2, 3, -4, -3, -2, -1 };
347 const int R_plus_dR
= (src
[0] >> 3) + lookup
[src
[0] & 0x7];
348 const int G_plus_dG
= (src
[1] >> 3) + lookup
[src
[1] & 0x7];
349 const int B_plus_dB
= (src
[2] >> 3) + lookup
[src
[2] & 0x7];
351 /* Reset the mode flags */
352 block
->is_ind_mode
= false;
353 block
->is_diff_mode
= false;
354 block
->is_t_mode
= false;
355 block
->is_h_mode
= false;
356 block
->is_planar_mode
= false;
359 /* individual mode */
360 block
->is_ind_mode
= true;
362 for (i
= 0; i
< 3; i
++) {
363 /* Texture decode algorithm is same for individual mode in etc1
366 block
->base_colors
[0][i
] = etc1_base_color_ind_hi(src
[i
]);
367 block
->base_colors
[1][i
] = etc1_base_color_ind_lo(src
[i
]);
370 else if (R_plus_dR
< 0 || R_plus_dR
> 31){
372 block
->is_t_mode
= true;
374 for(i
= 0; i
< 3; i
++) {
375 block
->base_colors
[0][i
] = etc2_base_color1_t_mode(src
, i
);
376 block
->base_colors
[1][i
] = etc2_base_color2_t_mode(src
, i
);
380 etc2_distance_table
[(((src
[3] >> 2) & 0x3) << 1) |
383 for (i
= 0; i
< 3; i
++) {
384 block
->paint_colors
[0][i
] = etc2_clamp(block
->base_colors
[0][i
]);
385 block
->paint_colors
[1][i
] = etc2_clamp(block
->base_colors
[1][i
] +
387 block
->paint_colors
[2][i
] = etc2_clamp(block
->base_colors
[1][i
]);
388 block
->paint_colors
[3][i
] = etc2_clamp(block
->base_colors
[1][i
] -
392 else if (G_plus_dG
< 0 || G_plus_dG
> 31){
394 block
->is_h_mode
= true;
395 int base_color_1_value
, base_color_2_value
;
397 for(i
= 0; i
< 3; i
++) {
398 block
->base_colors
[0][i
] = etc2_base_color1_h_mode(src
, i
);
399 block
->base_colors
[1][i
] = etc2_base_color2_h_mode(src
, i
);
402 base_color_1_value
= (block
->base_colors
[0][0] << 16) +
403 (block
->base_colors
[0][1] << 8) +
404 block
->base_colors
[0][2];
405 base_color_2_value
= (block
->base_colors
[1][0] << 16) +
406 (block
->base_colors
[1][1] << 8) +
407 block
->base_colors
[1][2];
410 etc2_distance_table
[(src
[3] & 0x4) |
411 ((src
[3] & 0x1) << 1) |
412 (base_color_1_value
>= base_color_2_value
)];
414 for (i
= 0; i
< 3; i
++) {
415 block
->paint_colors
[0][i
] = etc2_clamp(block
->base_colors
[0][i
] +
417 block
->paint_colors
[1][i
] = etc2_clamp(block
->base_colors
[0][i
] -
419 block
->paint_colors
[2][i
] = etc2_clamp(block
->base_colors
[1][i
] +
421 block
->paint_colors
[3][i
] = etc2_clamp(block
->base_colors
[1][i
] -
425 else if (B_plus_dB
< 0 || B_plus_dB
> 31){
427 block
->is_planar_mode
= true;
429 for (i
= 0; i
< 3; i
++) {
430 block
->base_colors
[0][i
] = etc2_base_color_o_planar(src
, i
);
431 block
->base_colors
[1][i
] = etc2_base_color_h_planar(src
, i
);
432 block
->base_colors
[2][i
] = etc2_base_color_v_planar(src
, i
);
436 /* differential mode */
437 block
->is_diff_mode
= true;
439 for (i
= 0; i
< 3; i
++) {
440 /* Texture decode algorithm is same for differential mode in etc1
443 block
->base_colors
[0][i
] = etc1_base_color_diff_hi(src
[i
]);
444 block
->base_colors
[1][i
] = etc1_base_color_diff_lo(src
[i
]);
448 if (block
->is_ind_mode
|| block
->is_diff_mode
) {
449 /* pick modifier tables. same for etc1 & etc2 textures */
450 block
->modifier_tables
[0] = etc1_modifier_tables
[(src
[3] >> 5) & 0x7];
451 block
->modifier_tables
[1] = etc1_modifier_tables
[(src
[3] >> 2) & 0x7];
452 block
->flipped
= (src
[3] & 0x1);
455 block
->pixel_indices
[0] =
456 (src
[4] << 24) | (src
[5] << 16) | (src
[6] << 8) | src
[7];
460 etc2_rgb8_fetch_texel(const struct etc2_block
*block
,
461 int x
, int y
, uint8_t *dst
)
463 const uint8_t *base_color
;
464 int modifier
, bit
, idx
, blk
;
466 /* get pixel index */
468 idx
= ((block
->pixel_indices
[0] >> (15 + bit
)) & 0x2) |
469 ((block
->pixel_indices
[0] >> (bit
)) & 0x1);
471 if (block
->is_ind_mode
|| block
->is_diff_mode
) {
472 /* Use pixel index and subblock to get the modifier */
473 blk
= (block
->flipped
) ? (y
>= 2) : (x
>= 2);
474 base_color
= block
->base_colors
[blk
];
475 modifier
= block
->modifier_tables
[blk
][idx
];
477 dst
[0] = etc2_clamp(base_color
[0] + modifier
);
478 dst
[1] = etc2_clamp(base_color
[1] + modifier
);
479 dst
[2] = etc2_clamp(base_color
[2] + modifier
);
481 else if (block
->is_t_mode
|| block
->is_h_mode
) {
482 /* Use pixel index to pick one of the paint colors */
483 dst
[0] = block
->paint_colors
[idx
][0];
484 dst
[1] = block
->paint_colors
[idx
][1];
485 dst
[2] = block
->paint_colors
[idx
][2];
487 else if (block
->is_planar_mode
) {
488 /* {R(x, y) = clamp255((x × (RH − RO) + y × (RV − RO) + 4 × RO + 2) >> 2)
489 * {G(x, y) = clamp255((x × (GH − GO) + y × (GV − GO) + 4 × GO + 2) >> 2)
490 * {B(x, y) = clamp255((x × (BH − BO) + y × (BV − BO) + 4 × BO + 2) >> 2)
492 int red
, green
, blue
;
493 red
= (x
* (block
->base_colors
[1][0] - block
->base_colors
[0][0]) +
494 y
* (block
->base_colors
[2][0] - block
->base_colors
[0][0]) +
495 4 * block
->base_colors
[0][0] + 2) >> 2;
497 green
= (x
* (block
->base_colors
[1][1] - block
->base_colors
[0][1]) +
498 y
* (block
->base_colors
[2][1] - block
->base_colors
[0][1]) +
499 4 * block
->base_colors
[0][1] + 2) >> 2;
501 blue
= (x
* (block
->base_colors
[1][2] - block
->base_colors
[0][2]) +
502 y
* (block
->base_colors
[2][2] - block
->base_colors
[0][2]) +
503 4 * block
->base_colors
[0][2] + 2) >> 2;
505 dst
[0] = etc2_clamp(red
);
506 dst
[1] = etc2_clamp(green
);
507 dst
[2] = etc2_clamp(blue
);
512 etc2_alpha8_fetch_texel(const struct etc2_block
*block
,
513 int x
, int y
, uint8_t *dst
)
515 int modifier
, alpha
, idx
;
516 /* get pixel index */
517 idx
= etc2_get_pixel_index(block
, x
, y
);
518 modifier
= etc2_modifier_tables
[block
->table_index
][idx
];
519 alpha
= block
->base_codeword
+ modifier
* block
->multiplier
;
520 dst
[3] = etc2_clamp(alpha
);
524 etc2_r11_fetch_texel(const struct etc2_block
*block
,
525 int x
, int y
, uint8_t *dst
)
529 /* Get pixel index */
530 idx
= etc2_get_pixel_index(block
, x
, y
);
531 modifier
= etc2_modifier_tables
[block
->table_index
][idx
];
533 if (block
->multiplier
!= 0)
534 /* clamp2(base codeword × 8 + 4 + modifier × multiplier × 8) */
535 color
= etc2_clamp2(((block
->base_codeword
<< 3) | 0x4) +
536 ((modifier
* block
->multiplier
) << 3));
538 color
= etc2_clamp2(((block
->base_codeword
<< 3) | 0x4) + modifier
);
540 /* Extend 11 bits color value to 16 bits. OpenGL ES 3.0 specification
541 * allows extending the color value to any number of bits. But, an
542 * implementation is not allowed to truncate the 11-bit value to less than
545 color
= (color
<< 5) | (color
>> 6);
546 ((GLushort
*)dst
)[0] = color
;
550 etc2_signed_r11_fetch_texel(const struct etc2_block
*block
,
551 int x
, int y
, uint8_t *dst
)
555 GLbyte base_codeword
= (GLbyte
) block
->base_codeword
;
557 if (base_codeword
== -128)
558 base_codeword
= -127;
560 /* Get pixel index */
561 idx
= etc2_get_pixel_index(block
, x
, y
);
562 modifier
= etc2_modifier_tables
[block
->table_index
][idx
];
564 if (block
->multiplier
!= 0)
565 /* clamp3(base codeword × 8 + modifier × multiplier × 8) */
566 color
= etc2_clamp3((base_codeword
<< 3) +
567 ((modifier
* block
->multiplier
) << 3));
569 color
= etc2_clamp3((base_codeword
<< 3) + modifier
);
571 /* Extend 11 bits color value to 16 bits. OpenGL ES 3.0 specification
572 * allows extending the color value to any number of bits. But, an
573 * implementation is not allowed to truncate the 11-bit value to less than
574 * 11 bits. A negative 11-bit value must first be made positive before bit
575 * replication, and then made negative again
578 color
= (color
<< 5) | (color
>> 5);
581 color
= (color
<< 5) | (color
>> 5);
584 ((GLshort
*)dst
)[0] = color
;
588 etc2_alpha8_parse_block(struct etc2_block
*block
, const uint8_t *src
)
590 block
->base_codeword
= src
[0];
591 block
->multiplier
= (src
[1] >> 4) & 0xf;
592 block
->table_index
= src
[1] & 0xf;
593 block
->pixel_indices
[1] = (((uint64_t)src
[2] << 40) |
594 ((uint64_t)src
[3] << 32) |
595 ((uint64_t)src
[4] << 24) |
596 ((uint64_t)src
[5] << 16) |
597 ((uint64_t)src
[6] << 8) |
602 etc2_r11_parse_block(struct etc2_block
*block
, const uint8_t *src
)
604 /* Parsing logic remains same as for etc2_alpha8_parse_block */
605 etc2_alpha8_parse_block(block
, src
);
609 etc2_rgba8_parse_block(struct etc2_block
*block
, const uint8_t *src
)
611 /* RGB component is parsed the same way as for MESA_FORMAT_ETC2_RGB8 */
612 etc2_rgb8_parse_block(block
, src
+ 8);
614 /* Parse Alpha component */
615 etc2_alpha8_parse_block(block
, src
);
619 etc2_rgba8_fetch_texel(const struct etc2_block
*block
,
620 int x
, int y
, uint8_t *dst
)
622 etc2_rgb8_fetch_texel(block
, x
, y
, dst
);
623 etc2_alpha8_fetch_texel(block
, x
, y
, dst
);
627 etc2_unpack_rgb8(uint8_t *dst_row
,
629 const uint8_t *src_row
,
634 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 4;
635 struct etc2_block block
;
638 for (y
= 0; y
< height
; y
+= bh
) {
639 const uint8_t *src
= src_row
;
641 for (x
= 0; x
< width
; x
+= bw
) {
642 etc2_rgb8_parse_block(&block
, src
);
644 for (j
= 0; j
< bh
; j
++) {
645 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
646 for (i
= 0; i
< bw
; i
++) {
647 etc2_rgb8_fetch_texel(&block
, i
, j
, dst
);
656 src_row
+= src_stride
;
661 etc2_unpack_srgb8(uint8_t *dst_row
,
663 const uint8_t *src_row
,
668 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 4;
669 struct etc2_block block
;
673 for (y
= 0; y
< height
; y
+= bh
) {
674 const uint8_t *src
= src_row
;
676 for (x
= 0; x
< width
; x
+= bw
) {
677 etc2_rgb8_parse_block(&block
, src
);
679 for (j
= 0; j
< bh
; j
++) {
680 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
681 for (i
= 0; i
< bw
; i
++) {
682 etc2_rgb8_fetch_texel(&block
, i
, j
, dst
);
683 /* Convert to MESA_FORMAT_SARGB8 */
695 src_row
+= src_stride
;
700 etc2_unpack_rgba8(uint8_t *dst_row
,
702 const uint8_t *src_row
,
707 /* If internalformat is COMPRESSED_RGBA8_ETC2_EAC, each 4 × 4 block of
708 * RGBA8888 information is compressed to 128 bits. To decode a block, the
709 * two 64-bit integers int64bitAlpha and int64bitColor are calculated.
711 const unsigned bw
= 4, bh
= 4, bs
= 16, comps
= 4;
712 struct etc2_block block
;
715 for (y
= 0; y
< height
; y
+= bh
) {
716 const uint8_t *src
= src_row
;
718 for (x
= 0; x
< width
; x
+= bw
) {
719 etc2_rgba8_parse_block(&block
, src
);
721 for (j
= 0; j
< bh
; j
++) {
722 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
723 for (i
= 0; i
< bw
; i
++) {
724 etc2_rgba8_fetch_texel(&block
, i
, j
, dst
);
731 src_row
+= src_stride
;
736 etc2_unpack_srgb8_alpha8(uint8_t *dst_row
,
738 const uint8_t *src_row
,
743 /* If internalformat is COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, each 4 × 4 block
744 * of RGBA8888 information is compressed to 128 bits. To decode a block, the
745 * two 64-bit integers int64bitAlpha and int64bitColor are calculated.
747 const unsigned bw
= 4, bh
= 4, bs
= 16, comps
= 4;
748 struct etc2_block block
;
752 for (y
= 0; y
< height
; y
+= bh
) {
753 const uint8_t *src
= src_row
;
755 for (x
= 0; x
< width
; x
+= bw
) {
756 etc2_rgba8_parse_block(&block
, src
);
758 for (j
= 0; j
< bh
; j
++) {
759 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
760 for (i
= 0; i
< bw
; i
++) {
761 etc2_rgba8_fetch_texel(&block
, i
, j
, dst
);
763 /* Convert to MESA_FORMAT_SARGB8 */
775 src_row
+= src_stride
;
780 etc2_unpack_r11(uint8_t *dst_row
,
782 const uint8_t *src_row
,
787 /* If internalformat is COMPRESSED_R11_EAC, each 4 × 4 block of
788 color information is compressed to 64 bits.
790 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 1, comp_size
= 2;
791 struct etc2_block block
;
794 for (y
= 0; y
< height
; y
+= bh
) {
795 const uint8_t *src
= src_row
;
797 for (x
= 0; x
< width
; x
+= bw
) {
798 etc2_r11_parse_block(&block
, src
);
800 for (j
= 0; j
< bh
; j
++) {
801 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
* comp_size
;
802 for (i
= 0; i
< bw
; i
++) {
803 etc2_r11_fetch_texel(&block
, i
, j
, dst
);
804 dst
+= comps
* comp_size
;
810 src_row
+= src_stride
;
815 etc2_unpack_rg11(uint8_t *dst_row
,
817 const uint8_t *src_row
,
822 /* If internalformat is COMPRESSED_RG11_EAC, each 4 × 4 block of
823 RG color information is compressed to 128 bits.
825 const unsigned bw
= 4, bh
= 4, bs
= 16, comps
= 2, comp_size
= 2;
826 struct etc2_block block
;
829 for (y
= 0; y
< height
; y
+= bh
) {
830 const uint8_t *src
= src_row
;
832 for (x
= 0; x
< width
; x
+= bw
) {
834 etc2_r11_parse_block(&block
, src
);
836 for (j
= 0; j
< bh
; j
++) {
837 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+
838 x
* comps
* comp_size
;
839 for (i
= 0; i
< bw
; i
++) {
840 etc2_r11_fetch_texel(&block
, i
, j
, dst
);
841 dst
+= comps
* comp_size
;
844 /* green component */
845 etc2_r11_parse_block(&block
, src
+ 8);
847 for (j
= 0; j
< bh
; j
++) {
848 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+
849 x
* comps
* comp_size
;
850 for (i
= 0; i
< bw
; i
++) {
851 etc2_r11_fetch_texel(&block
, i
, j
, dst
+ comp_size
);
852 dst
+= comps
* comp_size
;
858 src_row
+= src_stride
;
863 etc2_unpack_signed_r11(uint8_t *dst_row
,
865 const uint8_t *src_row
,
870 /* If internalformat is COMPRESSED_SIGNED_R11_EAC, each 4 × 4 block of
871 red color information is compressed to 64 bits.
873 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 1, comp_size
= 2;
874 struct etc2_block block
;
877 for (y
= 0; y
< height
; y
+= bh
) {
878 const uint8_t *src
= src_row
;
880 for (x
= 0; x
< width
; x
+= bw
) {
881 etc2_r11_parse_block(&block
, src
);
883 for (j
= 0; j
< bh
; j
++) {
884 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+
885 x
* comps
* comp_size
;
886 for (i
= 0; i
< bw
; i
++) {
887 etc2_signed_r11_fetch_texel(&block
, i
, j
, dst
);
888 dst
+= comps
* comp_size
;
894 src_row
+= src_stride
;
899 etc2_unpack_signed_rg11(uint8_t *dst_row
,
901 const uint8_t *src_row
,
906 /* If internalformat is COMPRESSED_SIGNED_RG11_EAC, each 4 × 4 block of
907 RG color information is compressed to 128 bits.
909 const unsigned bw
= 4, bh
= 4, bs
= 16, comps
= 2, comp_size
= 2;
910 struct etc2_block block
;
913 for (y
= 0; y
< height
; y
+= bh
) {
914 const uint8_t *src
= src_row
;
916 for (x
= 0; x
< width
; x
+= bw
) {
918 etc2_r11_parse_block(&block
, src
);
920 for (j
= 0; j
< bh
; j
++) {
921 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+
922 x
* comps
* comp_size
;
923 for (i
= 0; i
< bw
; i
++) {
924 etc2_signed_r11_fetch_texel(&block
, i
, j
, dst
);
925 dst
+= comps
* comp_size
;
928 /* green component */
929 etc2_r11_parse_block(&block
, src
+ 8);
931 for (j
= 0; j
< bh
; j
++) {
932 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+
933 x
* comps
* comp_size
;
934 for (i
= 0; i
< bw
; i
++) {
935 etc2_signed_r11_fetch_texel(&block
, i
, j
, dst
+ comp_size
);
936 dst
+= comps
* comp_size
;
942 src_row
+= src_stride
;
946 /* ETC2 texture formats are valid in glCompressedTexImage2D and
947 * glCompressedTexSubImage2D functions */
949 _mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS
)
957 _mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS
)
965 _mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS
)
973 _mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS
)
981 _mesa_texstore_etc2_r11_eac(TEXSTORE_PARAMS
)
989 _mesa_texstore_etc2_signed_r11_eac(TEXSTORE_PARAMS
)
997 _mesa_texstore_etc2_rg11_eac(TEXSTORE_PARAMS
)
1005 _mesa_texstore_etc2_signed_rg11_eac(TEXSTORE_PARAMS
)
1013 _mesa_fetch_texel_2d_f_etc2_rgb8(const struct swrast_texture_image
*texImage
,
1014 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
1016 struct etc2_block block
;
1020 src
= texImage
->Map
+
1021 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
1023 etc2_rgb8_parse_block(&block
, src
);
1024 etc2_rgb8_fetch_texel(&block
, i
% 4, j
% 4, dst
);
1026 texel
[RCOMP
] = UBYTE_TO_FLOAT(dst
[0]);
1027 texel
[GCOMP
] = UBYTE_TO_FLOAT(dst
[1]);
1028 texel
[BCOMP
] = UBYTE_TO_FLOAT(dst
[2]);
1029 texel
[ACOMP
] = 1.0f
;
1033 _mesa_fetch_texel_2d_f_etc2_srgb8(const struct swrast_texture_image
*texImage
,
1034 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
1036 struct etc2_block block
;
1040 src
= texImage
->Map
+
1041 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
1043 etc2_rgb8_parse_block(&block
, src
);
1044 etc2_rgb8_fetch_texel(&block
, i
% 4, j
% 4, dst
);
1046 texel
[RCOMP
] = _mesa_nonlinear_to_linear(dst
[0]);
1047 texel
[GCOMP
] = _mesa_nonlinear_to_linear(dst
[1]);
1048 texel
[BCOMP
] = _mesa_nonlinear_to_linear(dst
[2]);
1049 texel
[ACOMP
] = 1.0f
;
1053 _mesa_fetch_texel_2d_f_etc2_rgba8_eac(const struct swrast_texture_image
*texImage
,
1054 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
1056 struct etc2_block block
;
1060 src
= texImage
->Map
+
1061 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
1063 etc2_rgba8_parse_block(&block
, src
);
1064 etc2_rgba8_fetch_texel(&block
, i
% 4, j
% 4, dst
);
1066 texel
[RCOMP
] = UBYTE_TO_FLOAT(dst
[0]);
1067 texel
[GCOMP
] = UBYTE_TO_FLOAT(dst
[1]);
1068 texel
[BCOMP
] = UBYTE_TO_FLOAT(dst
[2]);
1069 texel
[ACOMP
] = UBYTE_TO_FLOAT(dst
[3]);
1073 _mesa_fetch_texel_2d_f_etc2_srgb8_alpha8_eac(const struct
1074 swrast_texture_image
*texImage
,
1076 GLint k
, GLfloat
*texel
)
1078 struct etc2_block block
;
1082 src
= texImage
->Map
+
1083 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
1085 etc2_rgba8_parse_block(&block
, src
);
1086 etc2_rgba8_fetch_texel(&block
, i
% 4, j
% 4, dst
);
1088 texel
[RCOMP
] = _mesa_nonlinear_to_linear(dst
[0]);
1089 texel
[GCOMP
] = _mesa_nonlinear_to_linear(dst
[1]);
1090 texel
[BCOMP
] = _mesa_nonlinear_to_linear(dst
[2]);
1091 texel
[ACOMP
] = UBYTE_TO_FLOAT(dst
[3]);
1095 _mesa_fetch_texel_2d_f_etc2_r11_eac(const struct swrast_texture_image
*texImage
,
1096 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
1098 struct etc2_block block
;
1102 src
= texImage
->Map
+
1103 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
1105 etc2_r11_parse_block(&block
, src
);
1106 etc2_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)&dst
);
1108 texel
[RCOMP
] = USHORT_TO_FLOAT(dst
);
1109 texel
[GCOMP
] = 0.0f
;
1110 texel
[BCOMP
] = 0.0f
;
1111 texel
[ACOMP
] = 1.0f
;
1115 _mesa_fetch_texel_2d_f_etc2_rg11_eac(const struct
1116 swrast_texture_image
*texImage
,
1118 GLint k
, GLfloat
*texel
)
1120 struct etc2_block block
;
1124 src
= texImage
->Map
+
1125 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
1128 etc2_r11_parse_block(&block
, src
);
1129 etc2_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)dst
);
1131 /* green component */
1132 etc2_r11_parse_block(&block
, src
+ 8);
1133 etc2_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)(dst
+ 1));
1135 texel
[RCOMP
] = USHORT_TO_FLOAT(dst
[0]);
1136 texel
[GCOMP
] = USHORT_TO_FLOAT(dst
[1]);
1137 texel
[BCOMP
] = 0.0f
;
1138 texel
[ACOMP
] = 1.0f
;
1142 _mesa_fetch_texel_2d_f_etc2_signed_r11_eac(const struct swrast_texture_image
*texImage
,
1143 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
1145 struct etc2_block block
;
1149 src
= texImage
->Map
+
1150 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
1152 etc2_r11_parse_block(&block
, src
);
1153 etc2_signed_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)&dst
);
1155 texel
[RCOMP
] = SHORT_TO_FLOAT(dst
);
1156 texel
[GCOMP
] = 0.0f
;
1157 texel
[BCOMP
] = 0.0f
;
1158 texel
[ACOMP
] = 1.0f
;
1162 _mesa_fetch_texel_2d_f_etc2_signed_rg11_eac(const struct swrast_texture_image
*texImage
,
1163 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
1165 struct etc2_block block
;
1169 src
= texImage
->Map
+
1170 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
1173 etc2_r11_parse_block(&block
, src
);
1174 etc2_signed_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)dst
);
1176 /* green component */
1177 etc2_r11_parse_block(&block
, src
+ 8);
1178 etc2_signed_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)(dst
+ 1));
1180 texel
[RCOMP
] = SHORT_TO_FLOAT(dst
[0]);
1181 texel
[GCOMP
] = SHORT_TO_FLOAT(dst
[1]);
1182 texel
[BCOMP
] = 0.0f
;
1183 texel
[ACOMP
] = 1.0f
;
1187 * Decode texture data in any one of following formats:
1188 * `MESA_FORMAT_ETC2_RGB8`
1189 * `MESA_FORMAT_ETC2_SRGB8`
1190 * `MESA_FORMAT_ETC2_RGBA8_EAC`
1191 * `MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC`
1192 * `MESA_FORMAT_ETC2_R11_EAC`
1193 * `MESA_FORMAT_ETC2_RG11_EAC`
1194 * `MESA_FORMAT_ETC2_SIGNED_R11_EAC`
1195 * `MESA_FORMAT_ETC2_SIGNED_RG11_EAC`
1197 * The size of the source data must be a multiple of the ETC2 block size
1198 * even if the texture image's dimensions are not aligned to 4.
1200 * \param src_width in pixels
1201 * \param src_height in pixels
1202 * \param dst_stride in bytes
1206 _mesa_unpack_etc2_format(uint8_t *dst_row
,
1207 unsigned dst_stride
,
1208 const uint8_t *src_row
,
1209 unsigned src_stride
,
1211 unsigned src_height
,
1214 if (format
== MESA_FORMAT_ETC2_RGB8
)
1215 etc2_unpack_rgb8(dst_row
, dst_stride
,
1216 src_row
, src_stride
,
1217 src_width
, src_height
);
1218 else if (format
== MESA_FORMAT_ETC2_SRGB8
)
1219 etc2_unpack_srgb8(dst_row
, dst_stride
,
1220 src_row
, src_stride
,
1221 src_width
, src_height
);
1222 else if (format
== MESA_FORMAT_ETC2_RGBA8_EAC
)
1223 etc2_unpack_rgba8(dst_row
, dst_stride
,
1224 src_row
, src_stride
,
1225 src_width
, src_height
);
1226 else if (format
== MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC
)
1227 etc2_unpack_srgb8_alpha8(dst_row
, dst_stride
,
1228 src_row
, src_stride
,
1229 src_width
, src_height
);
1230 else if (format
== MESA_FORMAT_ETC2_R11_EAC
)
1231 etc2_unpack_r11(dst_row
, dst_stride
,
1232 src_row
, src_stride
,
1233 src_width
, src_height
);
1234 else if (format
== MESA_FORMAT_ETC2_RG11_EAC
)
1235 etc2_unpack_rg11(dst_row
, dst_stride
,
1236 src_row
, src_stride
,
1237 src_width
, src_height
);
1238 else if (format
== MESA_FORMAT_ETC2_SIGNED_R11_EAC
)
1239 etc2_unpack_signed_r11(dst_row
, dst_stride
,
1240 src_row
, src_stride
,
1241 src_width
, src_height
);
1242 else if (format
== MESA_FORMAT_ETC2_SIGNED_RG11_EAC
)
1243 etc2_unpack_signed_rg11(dst_row
, dst_stride
,
1244 src_row
, src_stride
,
1245 src_width
, src_height
);