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
37 #include "mfeatures.h"
38 #include "texcompress.h"
39 #include "texcompress_etc.h"
42 #include "swrast/s_context.h"
43 #include "format_unpack.h"
47 uint64_t pixel_indices
[2];
48 const int *modifier_tables
[2];
55 uint8_t base_colors
[3][3];
56 uint8_t paint_colors
[4][3];
57 uint8_t base_codeword
;
62 static const int etc2_distance_table
[8] = {
63 3, 6, 11, 16, 23, 32, 41, 64 };
65 static const int etc2_modifier_tables
[16][8] = {
66 { -3, -6, -9, -15, 2, 5, 8, 14},
67 { -3, -7, -10, -13, 2, 6, 9, 12},
68 { -2, -5, -8, -13, 1, 4, 7, 12},
69 { -2, -4, -6, -13, 1, 3, 5, 12},
70 { -3, -6, -8, -12, 2, 5, 7, 11},
71 { -3, -7, -9, -11, 2, 6, 8, 10},
72 { -4, -7, -8, -11, 3, 6, 7, 10},
73 { -3, -5, -8, -11, 2, 4, 7, 10},
74 { -2, -6, -8, -10, 1, 5, 7, 9},
75 { -2, -5, -8, -10, 1, 4, 7, 9},
76 { -2, -4, -8, -10, 1, 3, 7, 9},
77 { -2, -5, -7, -10, 1, 4, 6, 9},
78 { -3, -4, -7, -10, 2, 3, 6, 9},
79 { -1, -2, -3, -10, 0, 1, 2, 9},
80 { -4, -6, -8, -9, 3, 5, 7, 8},
81 { -3, -5, -7, -9, 2, 4, 6, 8},
84 /* define etc1_parse_block and etc. */
85 #define UINT8_TYPE GLubyte
87 #include "texcompress_etc_tmp.h"
92 _mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS
)
94 /* GL_ETC1_RGB8_OES is only valid in glCompressedTexImage2D */
101 _mesa_fetch_texel_2d_f_etc1_rgb8(const struct swrast_texture_image
*texImage
,
102 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
104 struct etc1_block block
;
108 src
= (const GLubyte
*) texImage
->Map
+
109 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
111 etc1_parse_block(&block
, src
);
112 etc1_fetch_texel(&block
, i
% 4, j
% 4, dst
);
114 texel
[RCOMP
] = UBYTE_TO_FLOAT(dst
[0]);
115 texel
[GCOMP
] = UBYTE_TO_FLOAT(dst
[1]);
116 texel
[BCOMP
] = UBYTE_TO_FLOAT(dst
[2]);
121 * Decode texture data in format `MESA_FORMAT_ETC1_RGB8` to
122 * `MESA_FORMAT_ABGR8888`.
124 * The size of the source data must be a multiple of the ETC1 block size,
125 * which is 8, even if the texture image's dimensions are not aligned to 4.
126 * From the GL_OES_compressed_ETC1_RGB8_texture spec:
127 * The texture is described as a number of 4x4 pixel blocks. If the
128 * texture (or a particular mip-level) is smaller than 4 pixels in
129 * any dimension (such as a 2x2 or a 8x1 texture), the texture is
130 * found in the upper left part of the block(s), and the rest of the
131 * pixels are not used. For instance, a texture of size 4x2 will be
132 * placed in the upper half of a 4x4 block, and the lower half of the
133 * pixels in the block will not be accessed.
135 * \param src_width in pixels
136 * \param src_height in pixels
137 * \param dst_stride in bytes
140 _mesa_etc1_unpack_rgba8888(uint8_t *dst_row
,
142 const uint8_t *src_row
,
147 etc1_unpack_rgba8888(dst_row
, dst_stride
,
149 src_width
, src_height
);
153 etc2_base_color1_t_mode(const uint8_t *in
, GLuint index
)
155 uint8_t R1a
= 0, x
= 0;
156 /* base col 1 = extend_4to8bits( (R1a << 2) | R1b, G1, B1) */
159 R1a
= (in
[0] >> 3) & 0x3;
160 x
= ((R1a
<< 2) | (in
[0] & 0x3));
163 x
= ((in
[1] >> 4) & 0xf);
172 return ((x
<< 4) | (x
& 0xf));
176 etc2_base_color2_t_mode(const uint8_t *in
, GLuint index
)
179 /*extend 4to8bits(R2, G2, B2)*/
182 x
= ((in
[2] >> 4) & 0xf );
188 x
= ((in
[3] >> 4) & 0xf);
194 return ((x
<< 4) | (x
& 0xf));
198 etc2_base_color1_h_mode(const uint8_t *in
, GLuint index
)
201 /* base col 1 = extend 4to8bits(R1, (G1a << 1) | G1b, (B1a << 3) | B1b) */
204 x
= ((in
[0] >> 3) & 0xf);
207 x
= (((in
[0] & 0x7) << 1) | ((in
[1] >> 4) & 0x1));
211 (((in
[1] & 0x3) << 1) | ((in
[2] >> 7) & 0x1)));
217 return ((x
<< 4) | (x
& 0xf));
221 etc2_base_color2_h_mode(const uint8_t *in
, GLuint index
)
224 /* base col 2 = extend 4to8bits(R2, G2, B2) */
227 x
= ((in
[2] >> 3) & 0xf );
230 x
= (((in
[2] & 0x7) << 1) | ((in
[3] >> 7) & 0x1));
233 x
= ((in
[3] >> 3) & 0xf);
239 return ((x
<< 4) | (x
& 0xf));
243 etc2_base_color_o_planar(const uint8_t *in
, GLuint index
)
248 tmp
= ((in
[0] >> 1) & 0x3f); /* RO */
249 return ((tmp
<< 2) | (tmp
>> 4));
251 tmp
= (((in
[0] & 0x1) << 6) | /* GO1 */
252 ((in
[1] >> 1) & 0x3f)); /* GO2 */
253 return ((tmp
<< 1) | (tmp
>> 6));
255 tmp
= (((in
[1] & 0x1) << 5) | /* BO1 */
256 (in
[2] & 0x18) | /* BO2 */
257 (((in
[2] & 0x3) << 1) | ((in
[3] >> 7) & 0x1))); /* BO3 */
258 return ((tmp
<< 2) | (tmp
>> 4));
266 etc2_base_color_h_planar(const uint8_t *in
, GLuint index
)
271 tmp
= (((in
[3] & 0x7c) >> 1) | /* RH1 */
272 (in
[3] & 0x1)); /* RH2 */
273 return ((tmp
<< 2) | (tmp
>> 4));
275 tmp
= (in
[4] >> 1) & 0x7f; /* GH */
276 return ((tmp
<< 1) | (tmp
>> 6));
278 tmp
= (((in
[4] & 0x1) << 5) |
279 ((in
[5] >> 3) & 0x1f)); /* BH */
280 return ((tmp
<< 2) | (tmp
>> 4));
288 etc2_base_color_v_planar(const uint8_t *in
, GLuint index
)
293 tmp
= (((in
[5] & 0x7) << 0x3) |
294 ((in
[6] >> 5) & 0x7)); /* RV */
295 return ((tmp
<< 2) | (tmp
>> 4));
297 tmp
= (((in
[6] & 0x1f) << 2) |
298 ((in
[7] >> 6) & 0x3)); /* GV */
299 return ((tmp
<< 1) | (tmp
>> 6));
301 tmp
= in
[7] & 0x3f; /* BV */
302 return ((tmp
<< 2) | (tmp
>> 4));
310 etc2_get_pixel_index(const struct etc2_block
*block
, int x
, int y
)
312 int bit
= ((3 - y
) + (3 - x
) * 4) * 3;
313 int idx
= (block
->pixel_indices
[1] >> bit
) & 0x7;
318 etc2_clamp(int color
)
320 /* CLAMP(color, 0, 255) */
321 return (uint8_t) CLAMP(color
, 0, 255);
325 etc2_clamp2(int color
)
327 /* CLAMP(color, 0, 2047) */
328 return (GLushort
) CLAMP(color
, 0, 2047);
332 etc2_rgb8_parse_block(struct etc2_block
*block
, const uint8_t *src
)
335 GLboolean diffbit
= src
[3] & 0x2;
336 static const int lookup
[8] = { 0, 1, 2, 3, -4, -3, -2, -1 };
338 const int R_plus_dR
= (src
[0] >> 3) + lookup
[src
[0] & 0x7];
339 const int G_plus_dG
= (src
[1] >> 3) + lookup
[src
[1] & 0x7];
340 const int B_plus_dB
= (src
[2] >> 3) + lookup
[src
[2] & 0x7];
342 /* Reset the mode flags */
343 block
->is_ind_mode
= false;
344 block
->is_diff_mode
= false;
345 block
->is_t_mode
= false;
346 block
->is_h_mode
= false;
347 block
->is_planar_mode
= false;
350 /* individual mode */
351 block
->is_ind_mode
= true;
353 for (i
= 0; i
< 3; i
++) {
354 /* Texture decode algorithm is same for individual mode in etc1
357 block
->base_colors
[0][i
] = etc1_base_color_ind_hi(src
[i
]);
358 block
->base_colors
[1][i
] = etc1_base_color_ind_lo(src
[i
]);
361 else if (R_plus_dR
< 0 || R_plus_dR
> 31){
363 block
->is_t_mode
= true;
365 for(i
= 0; i
< 3; i
++) {
366 block
->base_colors
[0][i
] = etc2_base_color1_t_mode(src
, i
);
367 block
->base_colors
[1][i
] = etc2_base_color2_t_mode(src
, i
);
371 etc2_distance_table
[(((src
[3] >> 2) & 0x3) << 1) |
374 for (i
= 0; i
< 3; i
++) {
375 block
->paint_colors
[0][i
] = etc2_clamp(block
->base_colors
[0][i
]);
376 block
->paint_colors
[1][i
] = etc2_clamp(block
->base_colors
[1][i
] +
378 block
->paint_colors
[2][i
] = etc2_clamp(block
->base_colors
[1][i
]);
379 block
->paint_colors
[3][i
] = etc2_clamp(block
->base_colors
[1][i
] -
383 else if (G_plus_dG
< 0 || G_plus_dG
> 31){
385 block
->is_h_mode
= true;
386 int base_color_1_value
, base_color_2_value
;
388 for(i
= 0; i
< 3; i
++) {
389 block
->base_colors
[0][i
] = etc2_base_color1_h_mode(src
, i
);
390 block
->base_colors
[1][i
] = etc2_base_color2_h_mode(src
, i
);
393 base_color_1_value
= (block
->base_colors
[0][0] << 16) +
394 (block
->base_colors
[0][1] << 8) +
395 block
->base_colors
[0][2];
396 base_color_2_value
= (block
->base_colors
[1][0] << 16) +
397 (block
->base_colors
[1][1] << 8) +
398 block
->base_colors
[1][2];
401 etc2_distance_table
[(src
[3] & 0x4) |
402 ((src
[3] & 0x1) << 1) |
403 (base_color_1_value
>= base_color_2_value
)];
405 for (i
= 0; i
< 3; i
++) {
406 block
->paint_colors
[0][i
] = etc2_clamp(block
->base_colors
[0][i
] +
408 block
->paint_colors
[1][i
] = etc2_clamp(block
->base_colors
[0][i
] -
410 block
->paint_colors
[2][i
] = etc2_clamp(block
->base_colors
[1][i
] +
412 block
->paint_colors
[3][i
] = etc2_clamp(block
->base_colors
[1][i
] -
416 else if (B_plus_dB
< 0 || B_plus_dB
> 31){
418 block
->is_planar_mode
= true;
420 for (i
= 0; i
< 3; i
++) {
421 block
->base_colors
[0][i
] = etc2_base_color_o_planar(src
, i
);
422 block
->base_colors
[1][i
] = etc2_base_color_h_planar(src
, i
);
423 block
->base_colors
[2][i
] = etc2_base_color_v_planar(src
, i
);
427 /* differential mode */
428 block
->is_diff_mode
= true;
430 for (i
= 0; i
< 3; i
++) {
431 /* Texture decode algorithm is same for differential mode in etc1
434 block
->base_colors
[0][i
] = etc1_base_color_diff_hi(src
[i
]);
435 block
->base_colors
[1][i
] = etc1_base_color_diff_lo(src
[i
]);
439 if (block
->is_ind_mode
|| block
->is_diff_mode
) {
440 /* pick modifier tables. same for etc1 & etc2 textures */
441 block
->modifier_tables
[0] = etc1_modifier_tables
[(src
[3] >> 5) & 0x7];
442 block
->modifier_tables
[1] = etc1_modifier_tables
[(src
[3] >> 2) & 0x7];
443 block
->flipped
= (src
[3] & 0x1);
446 block
->pixel_indices
[0] =
447 (src
[4] << 24) | (src
[5] << 16) | (src
[6] << 8) | src
[7];
451 etc2_rgb8_fetch_texel(const struct etc2_block
*block
,
452 int x
, int y
, uint8_t *dst
)
454 const uint8_t *base_color
;
455 int modifier
, bit
, idx
, blk
;
457 /* get pixel index */
459 idx
= ((block
->pixel_indices
[0] >> (15 + bit
)) & 0x2) |
460 ((block
->pixel_indices
[0] >> (bit
)) & 0x1);
462 if (block
->is_ind_mode
|| block
->is_diff_mode
) {
463 /* Use pixel index and subblock to get the modifier */
464 blk
= (block
->flipped
) ? (y
>= 2) : (x
>= 2);
465 base_color
= block
->base_colors
[blk
];
466 modifier
= block
->modifier_tables
[blk
][idx
];
468 dst
[0] = etc2_clamp(base_color
[0] + modifier
);
469 dst
[1] = etc2_clamp(base_color
[1] + modifier
);
470 dst
[2] = etc2_clamp(base_color
[2] + modifier
);
472 else if (block
->is_t_mode
|| block
->is_h_mode
) {
473 /* Use pixel index to pick one of the paint colors */
474 dst
[0] = block
->paint_colors
[idx
][0];
475 dst
[1] = block
->paint_colors
[idx
][1];
476 dst
[2] = block
->paint_colors
[idx
][2];
478 else if (block
->is_planar_mode
) {
479 /* {R(x, y) = clamp255((x × (RH − RO) + y × (RV − RO) + 4 × RO + 2) >> 2)
480 * {G(x, y) = clamp255((x × (GH − GO) + y × (GV − GO) + 4 × GO + 2) >> 2)
481 * {B(x, y) = clamp255((x × (BH − BO) + y × (BV − BO) + 4 × BO + 2) >> 2)
483 int red
, green
, blue
;
484 red
= (x
* (block
->base_colors
[1][0] - block
->base_colors
[0][0]) +
485 y
* (block
->base_colors
[2][0] - block
->base_colors
[0][0]) +
486 4 * block
->base_colors
[0][0] + 2) >> 2;
488 green
= (x
* (block
->base_colors
[1][1] - block
->base_colors
[0][1]) +
489 y
* (block
->base_colors
[2][1] - block
->base_colors
[0][1]) +
490 4 * block
->base_colors
[0][1] + 2) >> 2;
492 blue
= (x
* (block
->base_colors
[1][2] - block
->base_colors
[0][2]) +
493 y
* (block
->base_colors
[2][2] - block
->base_colors
[0][2]) +
494 4 * block
->base_colors
[0][2] + 2) >> 2;
496 dst
[0] = etc2_clamp(red
);
497 dst
[1] = etc2_clamp(green
);
498 dst
[2] = etc2_clamp(blue
);
503 etc2_alpha8_fetch_texel(const struct etc2_block
*block
,
504 int x
, int y
, uint8_t *dst
)
506 int modifier
, alpha
, idx
;
507 /* get pixel index */
508 idx
= etc2_get_pixel_index(block
, x
, y
);
509 modifier
= etc2_modifier_tables
[block
->table_index
][idx
];
510 alpha
= block
->base_codeword
+ modifier
* block
->multiplier
;
511 dst
[3] = etc2_clamp(alpha
);
515 etc2_r11_fetch_texel(const struct etc2_block
*block
,
516 int x
, int y
, uint8_t *dst
)
520 /* Get pixel index */
521 idx
= etc2_get_pixel_index(block
, x
, y
);
522 modifier
= etc2_modifier_tables
[block
->table_index
][idx
];
524 if (block
->multiplier
!= 0)
525 /* clamp2(base codeword × 8 + 4 + modifier × multiplier × 8) */
526 color
= etc2_clamp2(((block
->base_codeword
<< 3) | 0x4) +
527 ((modifier
* block
->multiplier
) << 3));
529 color
= etc2_clamp2(((block
->base_codeword
<< 3) | 0x4) + modifier
);
531 /* Extend 11 bits color value to 16 bits. OpenGL ES 3.0 specification
532 * allows extending the color value to any number of bits. But, an
533 * implementation is not allowed to truncate the 11-bit value to less than
536 color
= (color
<< 5) | (color
>> 6);
537 ((GLushort
*)dst
)[0] = color
;
541 etc2_alpha8_parse_block(struct etc2_block
*block
, const uint8_t *src
)
543 block
->base_codeword
= src
[0];
544 block
->multiplier
= (src
[1] >> 4) & 0xf;
545 block
->table_index
= src
[1] & 0xf;
546 block
->pixel_indices
[1] = (((uint64_t)src
[2] << 40) |
547 ((uint64_t)src
[3] << 32) |
548 ((uint64_t)src
[4] << 24) |
549 ((uint64_t)src
[5] << 16) |
550 ((uint64_t)src
[6] << 8) |
555 etc2_r11_parse_block(struct etc2_block
*block
, const uint8_t *src
)
557 /* Parsing logic remains same as for etc2_alpha8_parse_block */
558 etc2_alpha8_parse_block(block
, src
);
562 etc2_rgba8_parse_block(struct etc2_block
*block
, const uint8_t *src
)
564 /* RGB component is parsed the same way as for MESA_FORMAT_ETC2_RGB8 */
565 etc2_rgb8_parse_block(block
, src
+ 8);
567 /* Parse Alpha component */
568 etc2_alpha8_parse_block(block
, src
);
572 etc2_rgba8_fetch_texel(const struct etc2_block
*block
,
573 int x
, int y
, uint8_t *dst
)
575 etc2_rgb8_fetch_texel(block
, x
, y
, dst
);
576 etc2_alpha8_fetch_texel(block
, x
, y
, dst
);
580 etc2_unpack_rgb8(uint8_t *dst_row
,
582 const uint8_t *src_row
,
587 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 4;
588 struct etc2_block block
;
591 for (y
= 0; y
< height
; y
+= bh
) {
592 const uint8_t *src
= src_row
;
594 for (x
= 0; x
< width
; x
+= bw
) {
595 etc2_rgb8_parse_block(&block
, src
);
597 for (j
= 0; j
< bh
; j
++) {
598 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
599 for (i
= 0; i
< bw
; i
++) {
600 etc2_rgb8_fetch_texel(&block
, i
, j
, dst
);
609 src_row
+= src_stride
;
614 etc2_unpack_srgb8(uint8_t *dst_row
,
616 const uint8_t *src_row
,
621 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 4;
622 struct etc2_block block
;
626 for (y
= 0; y
< height
; y
+= bh
) {
627 const uint8_t *src
= src_row
;
629 for (x
= 0; x
< width
; x
+= bw
) {
630 etc2_rgb8_parse_block(&block
, src
);
632 for (j
= 0; j
< bh
; j
++) {
633 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
634 for (i
= 0; i
< bw
; i
++) {
635 etc2_rgb8_fetch_texel(&block
, i
, j
, dst
);
636 /* Convert to MESA_FORMAT_SARGB8 */
648 src_row
+= src_stride
;
653 etc2_unpack_rgba8(uint8_t *dst_row
,
655 const uint8_t *src_row
,
660 /* If internalformat is COMPRESSED_RGBA8_ETC2_EAC, each 4 × 4 block of
661 * RGBA8888 information is compressed to 128 bits. To decode a block, the
662 * two 64-bit integers int64bitAlpha and int64bitColor are calculated.
664 const unsigned bw
= 4, bh
= 4, bs
= 16, comps
= 4;
665 struct etc2_block block
;
668 for (y
= 0; y
< height
; y
+= bh
) {
669 const uint8_t *src
= src_row
;
671 for (x
= 0; x
< width
; x
+= bw
) {
672 etc2_rgba8_parse_block(&block
, src
);
674 for (j
= 0; j
< bh
; j
++) {
675 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
676 for (i
= 0; i
< bw
; i
++) {
677 etc2_rgba8_fetch_texel(&block
, i
, j
, dst
);
684 src_row
+= src_stride
;
689 etc2_unpack_srgb8_alpha8(uint8_t *dst_row
,
691 const uint8_t *src_row
,
696 /* If internalformat is COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, each 4 × 4 block
697 * of RGBA8888 information is compressed to 128 bits. To decode a block, the
698 * two 64-bit integers int64bitAlpha and int64bitColor are calculated.
700 const unsigned bw
= 4, bh
= 4, bs
= 16, comps
= 4;
701 struct etc2_block block
;
705 for (y
= 0; y
< height
; y
+= bh
) {
706 const uint8_t *src
= src_row
;
708 for (x
= 0; x
< width
; x
+= bw
) {
709 etc2_rgba8_parse_block(&block
, src
);
711 for (j
= 0; j
< bh
; j
++) {
712 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
713 for (i
= 0; i
< bw
; i
++) {
714 etc2_rgba8_fetch_texel(&block
, i
, j
, dst
);
716 /* Convert to MESA_FORMAT_SARGB8 */
728 src_row
+= src_stride
;
733 etc2_unpack_r11(uint8_t *dst_row
,
735 const uint8_t *src_row
,
740 /* If internalformat is COMPRESSED_R11_EAC, each 4 × 4 block of
741 color information is compressed to 64 bits.
743 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 1, comp_size
= 2;
744 struct etc2_block block
;
747 for (y
= 0; y
< height
; y
+= bh
) {
748 const uint8_t *src
= src_row
;
750 for (x
= 0; x
< width
; x
+= bw
) {
751 etc2_r11_parse_block(&block
, src
);
753 for (j
= 0; j
< bh
; j
++) {
754 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
* comp_size
;
755 for (i
= 0; i
< bw
; i
++) {
756 etc2_r11_fetch_texel(&block
, i
, j
, dst
);
757 dst
+= comps
* comp_size
;
763 src_row
+= src_stride
;
768 etc2_unpack_rg11(uint8_t *dst_row
,
770 const uint8_t *src_row
,
775 /* If internalformat is COMPRESSED_RG11_EAC, each 4 × 4 block of
776 RG color information is compressed to 128 bits.
778 const unsigned bw
= 4, bh
= 4, bs
= 16, comps
= 2, comp_size
= 2;
779 struct etc2_block block
;
782 for (y
= 0; y
< height
; y
+= bh
) {
783 const uint8_t *src
= src_row
;
785 for (x
= 0; x
< width
; x
+= bw
) {
787 etc2_r11_parse_block(&block
, src
);
789 for (j
= 0; j
< bh
; j
++) {
790 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+
791 x
* comps
* comp_size
;
792 for (i
= 0; i
< bw
; i
++) {
793 etc2_r11_fetch_texel(&block
, i
, j
, dst
);
794 dst
+= comps
* comp_size
;
797 /* green component */
798 etc2_r11_parse_block(&block
, src
+ 8);
800 for (j
= 0; j
< bh
; j
++) {
801 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+
802 x
* comps
* comp_size
;
803 for (i
= 0; i
< bw
; i
++) {
804 etc2_r11_fetch_texel(&block
, i
, j
, dst
+ comp_size
);
805 dst
+= comps
* comp_size
;
811 src_row
+= src_stride
;
815 /* ETC2 texture formats are valid in glCompressedTexImage2D and
816 * glCompressedTexSubImage2D functions */
818 _mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS
)
826 _mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS
)
834 _mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS
)
842 _mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS
)
850 _mesa_texstore_etc2_r11_eac(TEXSTORE_PARAMS
)
858 _mesa_texstore_etc2_rg11_eac(TEXSTORE_PARAMS
)
866 _mesa_fetch_texel_2d_f_etc2_rgb8(const struct swrast_texture_image
*texImage
,
867 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
869 struct etc2_block block
;
873 src
= texImage
->Map
+
874 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
876 etc2_rgb8_parse_block(&block
, src
);
877 etc2_rgb8_fetch_texel(&block
, i
% 4, j
% 4, dst
);
879 texel
[RCOMP
] = UBYTE_TO_FLOAT(dst
[0]);
880 texel
[GCOMP
] = UBYTE_TO_FLOAT(dst
[1]);
881 texel
[BCOMP
] = UBYTE_TO_FLOAT(dst
[2]);
886 _mesa_fetch_texel_2d_f_etc2_srgb8(const struct swrast_texture_image
*texImage
,
887 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
889 struct etc2_block block
;
893 src
= texImage
->Map
+
894 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
896 etc2_rgb8_parse_block(&block
, src
);
897 etc2_rgb8_fetch_texel(&block
, i
% 4, j
% 4, dst
);
899 texel
[RCOMP
] = _mesa_nonlinear_to_linear(dst
[0]);
900 texel
[GCOMP
] = _mesa_nonlinear_to_linear(dst
[1]);
901 texel
[BCOMP
] = _mesa_nonlinear_to_linear(dst
[2]);
906 _mesa_fetch_texel_2d_f_etc2_rgba8_eac(const struct swrast_texture_image
*texImage
,
907 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
909 struct etc2_block block
;
913 src
= texImage
->Map
+
914 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
916 etc2_rgba8_parse_block(&block
, src
);
917 etc2_rgba8_fetch_texel(&block
, i
% 4, j
% 4, dst
);
919 texel
[RCOMP
] = UBYTE_TO_FLOAT(dst
[0]);
920 texel
[GCOMP
] = UBYTE_TO_FLOAT(dst
[1]);
921 texel
[BCOMP
] = UBYTE_TO_FLOAT(dst
[2]);
922 texel
[ACOMP
] = UBYTE_TO_FLOAT(dst
[3]);
926 _mesa_fetch_texel_2d_f_etc2_srgb8_alpha8_eac(const struct
927 swrast_texture_image
*texImage
,
929 GLint k
, GLfloat
*texel
)
931 struct etc2_block block
;
935 src
= texImage
->Map
+
936 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
938 etc2_rgba8_parse_block(&block
, src
);
939 etc2_rgba8_fetch_texel(&block
, i
% 4, j
% 4, dst
);
941 texel
[RCOMP
] = _mesa_nonlinear_to_linear(dst
[0]);
942 texel
[GCOMP
] = _mesa_nonlinear_to_linear(dst
[1]);
943 texel
[BCOMP
] = _mesa_nonlinear_to_linear(dst
[2]);
944 texel
[ACOMP
] = UBYTE_TO_FLOAT(dst
[3]);
948 _mesa_fetch_texel_2d_f_etc2_r11_eac(const struct swrast_texture_image
*texImage
,
949 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
951 struct etc2_block block
;
955 src
= texImage
->Map
+
956 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
958 etc2_r11_parse_block(&block
, src
);
959 etc2_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)&dst
);
961 texel
[RCOMP
] = USHORT_TO_FLOAT(dst
);
968 _mesa_fetch_texel_2d_f_etc2_rg11_eac(const struct
969 swrast_texture_image
*texImage
,
971 GLint k
, GLfloat
*texel
)
973 struct etc2_block block
;
977 src
= texImage
->Map
+
978 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
981 etc2_r11_parse_block(&block
, src
);
982 etc2_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)dst
);
984 /* green component */
985 etc2_r11_parse_block(&block
, src
+ 8);
986 etc2_r11_fetch_texel(&block
, i
% 4, j
% 4, (uint8_t *)(dst
+ 1));
988 texel
[RCOMP
] = USHORT_TO_FLOAT(dst
[0]);
989 texel
[GCOMP
] = USHORT_TO_FLOAT(dst
[1]);
995 * Decode texture data in any one of following formats:
996 * `MESA_FORMAT_ETC2_RGB8`
997 * `MESA_FORMAT_ETC2_SRGB8`
998 * `MESA_FORMAT_ETC2_RGBA8_EAC`
999 * `MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC`
1000 * `MESA_FORMAT_ETC2_R11_EAC`
1001 * `MESA_FORMAT_ETC2_RG11_EAC`
1003 * The size of the source data must be a multiple of the ETC2 block size
1004 * even if the texture image's dimensions are not aligned to 4.
1006 * \param src_width in pixels
1007 * \param src_height in pixels
1008 * \param dst_stride in bytes
1012 _mesa_unpack_etc2_format(uint8_t *dst_row
,
1013 unsigned dst_stride
,
1014 const uint8_t *src_row
,
1015 unsigned src_stride
,
1017 unsigned src_height
,
1020 if (format
== MESA_FORMAT_ETC2_RGB8
)
1021 etc2_unpack_rgb8(dst_row
, dst_stride
,
1022 src_row
, src_stride
,
1023 src_width
, src_height
);
1024 else if (format
== MESA_FORMAT_ETC2_SRGB8
)
1025 etc2_unpack_srgb8(dst_row
, dst_stride
,
1026 src_row
, src_stride
,
1027 src_width
, src_height
);
1028 else if (format
== MESA_FORMAT_ETC2_RGBA8_EAC
)
1029 etc2_unpack_rgba8(dst_row
, dst_stride
,
1030 src_row
, src_stride
,
1031 src_width
, src_height
);
1032 else if (format
== MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC
)
1033 etc2_unpack_srgb8_alpha8(dst_row
, dst_stride
,
1034 src_row
, src_stride
,
1035 src_width
, src_height
);
1036 else if (format
== MESA_FORMAT_ETC2_R11_EAC
)
1037 etc2_unpack_r11(dst_row
, dst_stride
,
1038 src_row
, src_stride
,
1039 src_width
, src_height
);
1040 else if (format
== MESA_FORMAT_ETC2_RG11_EAC
)
1041 etc2_unpack_rg11(dst_row
, dst_stride
,
1042 src_row
, src_stride
,
1043 src_width
, src_height
);