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
35 #include "mfeatures.h"
36 #include "texcompress.h"
37 #include "texcompress_etc.h"
40 #include "swrast/s_context.h"
41 #include "format_unpack.h"
45 uint64_t pixel_indices
[2];
46 const int *modifier_tables
[2];
53 uint8_t base_colors
[3][3];
54 uint8_t paint_colors
[4][3];
55 uint8_t base_codeword
;
60 static const int etc2_distance_table
[8] = {
61 3, 6, 11, 16, 23, 32, 41, 64 };
63 static const int etc2_modifier_tables
[16][8] = {
64 { -3, -6, -9, -15, 2, 5, 8, 14},
65 { -3, -7, -10, -13, 2, 6, 9, 12},
66 { -2, -5, -8, -13, 1, 4, 7, 12},
67 { -2, -4, -6, -13, 1, 3, 5, 12},
68 { -3, -6, -8, -12, 2, 5, 7, 11},
69 { -3, -7, -9, -11, 2, 6, 8, 10},
70 { -4, -7, -8, -11, 3, 6, 7, 10},
71 { -3, -5, -8, -11, 2, 4, 7, 10},
72 { -2, -6, -8, -10, 1, 5, 7, 9},
73 { -2, -5, -8, -10, 1, 4, 7, 9},
74 { -2, -4, -8, -10, 1, 3, 7, 9},
75 { -2, -5, -7, -10, 1, 4, 6, 9},
76 { -3, -4, -7, -10, 2, 3, 6, 9},
77 { -1, -2, -3, -10, 0, 1, 2, 9},
78 { -4, -6, -8, -9, 3, 5, 7, 8},
79 { -3, -5, -7, -9, 2, 4, 6, 8},
82 /* define etc1_parse_block and etc. */
83 #define UINT8_TYPE GLubyte
85 #include "texcompress_etc_tmp.h"
90 _mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS
)
92 /* GL_ETC1_RGB8_OES is only valid in glCompressedTexImage2D */
99 _mesa_fetch_texel_2d_f_etc1_rgb8(const struct swrast_texture_image
*texImage
,
100 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
102 struct etc1_block block
;
106 src
= (const GLubyte
*) texImage
->Map
+
107 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
109 etc1_parse_block(&block
, src
);
110 etc1_fetch_texel(&block
, i
% 4, j
% 4, dst
);
112 texel
[RCOMP
] = UBYTE_TO_FLOAT(dst
[0]);
113 texel
[GCOMP
] = UBYTE_TO_FLOAT(dst
[1]);
114 texel
[BCOMP
] = UBYTE_TO_FLOAT(dst
[2]);
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_clamp(int color
)
310 /* CLAMP(color, 0, 255) */
311 return (uint8_t) CLAMP(color
, 0, 255);
315 etc2_rgb8_parse_block(struct etc2_block
*block
, const uint8_t *src
)
318 GLboolean diffbit
= src
[3] & 0x2;
319 static const int lookup
[8] = { 0, 1, 2, 3, -4, -3, -2, -1 };
321 const int R_plus_dR
= (src
[0] >> 3) + lookup
[src
[0] & 0x7];
322 const int G_plus_dG
= (src
[1] >> 3) + lookup
[src
[1] & 0x7];
323 const int B_plus_dB
= (src
[2] >> 3) + lookup
[src
[2] & 0x7];
325 /* Reset the mode flags */
326 block
->is_ind_mode
= false;
327 block
->is_diff_mode
= false;
328 block
->is_t_mode
= false;
329 block
->is_h_mode
= false;
330 block
->is_planar_mode
= false;
333 /* individual mode */
334 block
->is_ind_mode
= true;
336 for (i
= 0; i
< 3; i
++) {
337 /* Texture decode algorithm is same for individual mode in etc1
340 block
->base_colors
[0][i
] = etc1_base_color_ind_hi(src
[i
]);
341 block
->base_colors
[1][i
] = etc1_base_color_ind_lo(src
[i
]);
344 else if (R_plus_dR
< 0 || R_plus_dR
> 31){
346 block
->is_t_mode
= true;
348 for(i
= 0; i
< 3; i
++) {
349 block
->base_colors
[0][i
] = etc2_base_color1_t_mode(src
, i
);
350 block
->base_colors
[1][i
] = etc2_base_color2_t_mode(src
, i
);
354 etc2_distance_table
[(((src
[3] >> 2) & 0x3) << 1) |
357 for (i
= 0; i
< 3; i
++) {
358 block
->paint_colors
[0][i
] = etc2_clamp(block
->base_colors
[0][i
]);
359 block
->paint_colors
[1][i
] = etc2_clamp(block
->base_colors
[1][i
] +
361 block
->paint_colors
[2][i
] = etc2_clamp(block
->base_colors
[1][i
]);
362 block
->paint_colors
[3][i
] = etc2_clamp(block
->base_colors
[1][i
] -
366 else if (G_plus_dG
< 0 || G_plus_dG
> 31){
368 block
->is_h_mode
= true;
369 int base_color_1_value
, base_color_2_value
;
371 for(i
= 0; i
< 3; i
++) {
372 block
->base_colors
[0][i
] = etc2_base_color1_h_mode(src
, i
);
373 block
->base_colors
[1][i
] = etc2_base_color2_h_mode(src
, i
);
376 base_color_1_value
= (block
->base_colors
[0][0] << 16) +
377 (block
->base_colors
[0][1] << 8) +
378 block
->base_colors
[0][2];
379 base_color_2_value
= (block
->base_colors
[1][0] << 16) +
380 (block
->base_colors
[1][1] << 8) +
381 block
->base_colors
[1][2];
384 etc2_distance_table
[(src
[3] & 0x4) |
385 ((src
[3] & 0x1) << 1) |
386 (base_color_1_value
>= base_color_2_value
)];
388 for (i
= 0; i
< 3; i
++) {
389 block
->paint_colors
[0][i
] = etc2_clamp(block
->base_colors
[0][i
] +
391 block
->paint_colors
[1][i
] = etc2_clamp(block
->base_colors
[0][i
] -
393 block
->paint_colors
[2][i
] = etc2_clamp(block
->base_colors
[1][i
] +
395 block
->paint_colors
[3][i
] = etc2_clamp(block
->base_colors
[1][i
] -
399 else if (B_plus_dB
< 0 || B_plus_dB
> 31){
401 block
->is_planar_mode
= true;
403 for (i
= 0; i
< 3; i
++) {
404 block
->base_colors
[0][i
] = etc2_base_color_o_planar(src
, i
);
405 block
->base_colors
[1][i
] = etc2_base_color_h_planar(src
, i
);
406 block
->base_colors
[2][i
] = etc2_base_color_v_planar(src
, i
);
410 /* differential mode */
411 block
->is_diff_mode
= true;
413 for (i
= 0; i
< 3; i
++) {
414 /* Texture decode algorithm is same for differential mode in etc1
417 block
->base_colors
[0][i
] = etc1_base_color_diff_hi(src
[i
]);
418 block
->base_colors
[1][i
] = etc1_base_color_diff_lo(src
[i
]);
422 if (block
->is_ind_mode
|| block
->is_diff_mode
) {
423 /* pick modifier tables. same for etc1 & etc2 textures */
424 block
->modifier_tables
[0] = etc1_modifier_tables
[(src
[3] >> 5) & 0x7];
425 block
->modifier_tables
[1] = etc1_modifier_tables
[(src
[3] >> 2) & 0x7];
426 block
->flipped
= (src
[3] & 0x1);
429 block
->pixel_indices
[0] =
430 (src
[4] << 24) | (src
[5] << 16) | (src
[6] << 8) | src
[7];
434 etc2_rgb8_fetch_texel(const struct etc2_block
*block
,
435 int x
, int y
, uint8_t *dst
)
437 const uint8_t *base_color
;
438 int modifier
, bit
, idx
, blk
;
440 /* get pixel index */
442 idx
= ((block
->pixel_indices
[0] >> (15 + bit
)) & 0x2) |
443 ((block
->pixel_indices
[0] >> (bit
)) & 0x1);
445 if (block
->is_ind_mode
|| block
->is_diff_mode
) {
446 /* Use pixel index and subblock to get the modifier */
447 blk
= (block
->flipped
) ? (y
>= 2) : (x
>= 2);
448 base_color
= block
->base_colors
[blk
];
449 modifier
= block
->modifier_tables
[blk
][idx
];
451 dst
[0] = etc2_clamp(base_color
[0] + modifier
);
452 dst
[1] = etc2_clamp(base_color
[1] + modifier
);
453 dst
[2] = etc2_clamp(base_color
[2] + modifier
);
455 else if (block
->is_t_mode
|| block
->is_h_mode
) {
456 /* Use pixel index to pick one of the paint colors */
457 dst
[0] = block
->paint_colors
[idx
][0];
458 dst
[1] = block
->paint_colors
[idx
][1];
459 dst
[2] = block
->paint_colors
[idx
][2];
461 else if (block
->is_planar_mode
) {
462 /* {R(x, y) = clamp255((x × (RH − RO) + y × (RV − RO) + 4 × RO + 2) >> 2)
463 * {G(x, y) = clamp255((x × (GH − GO) + y × (GV − GO) + 4 × GO + 2) >> 2)
464 * {B(x, y) = clamp255((x × (BH − BO) + y × (BV − BO) + 4 × BO + 2) >> 2)
466 int red
, green
, blue
;
467 red
= (x
* (block
->base_colors
[1][0] - block
->base_colors
[0][0]) +
468 y
* (block
->base_colors
[2][0] - block
->base_colors
[0][0]) +
469 4 * block
->base_colors
[0][0] + 2) >> 2;
471 green
= (x
* (block
->base_colors
[1][1] - block
->base_colors
[0][1]) +
472 y
* (block
->base_colors
[2][1] - block
->base_colors
[0][1]) +
473 4 * block
->base_colors
[0][1] + 2) >> 2;
475 blue
= (x
* (block
->base_colors
[1][2] - block
->base_colors
[0][2]) +
476 y
* (block
->base_colors
[2][2] - block
->base_colors
[0][2]) +
477 4 * block
->base_colors
[0][2] + 2) >> 2;
479 dst
[0] = etc2_clamp(red
);
480 dst
[1] = etc2_clamp(green
);
481 dst
[2] = etc2_clamp(blue
);
486 etc2_alpha8_fetch_texel(const struct etc2_block
*block
,
487 int x
, int y
, uint8_t *dst
)
489 int modifier
, alpha
, bit
, idx
;
490 /* get pixel index */
491 bit
= ((3 - y
) + (3 - x
) * 4) * 3;
492 idx
= (block
->pixel_indices
[1] >> bit
) & 0x7;
493 modifier
= etc2_modifier_tables
[block
->table_index
][idx
];
494 alpha
= block
->base_codeword
+ modifier
* block
->multiplier
;
495 dst
[3] = etc2_clamp(alpha
);
499 etc2_alpha8_parse_block(struct etc2_block
*block
, const uint8_t *src
)
501 block
->base_codeword
= src
[0];
502 block
->multiplier
= (src
[1] >> 4) & 0xf;
503 block
->table_index
= src
[1] & 0xf;
504 block
->pixel_indices
[1] = (((uint64_t)src
[2] << 40) |
505 ((uint64_t)src
[3] << 32) |
506 ((uint64_t)src
[4] << 24) |
507 ((uint64_t)src
[5] << 16) |
508 ((uint64_t)src
[6] << 8) |
513 etc2_rgba8_parse_block(struct etc2_block
*block
, const uint8_t *src
)
515 /* RGB component is parsed the same way as for MESA_FORMAT_ETC2_RGB8 */
516 etc2_rgb8_parse_block(block
, src
+ 8);
518 /* Parse Alpha component */
519 etc2_alpha8_parse_block(block
, src
);
523 etc2_rgba8_fetch_texel(const struct etc2_block
*block
,
524 int x
, int y
, uint8_t *dst
)
526 etc2_rgb8_fetch_texel(block
, x
, y
, dst
);
527 etc2_alpha8_fetch_texel(block
, x
, y
, dst
);
531 etc2_unpack_rgb8(uint8_t *dst_row
,
533 const uint8_t *src_row
,
538 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 4;
539 struct etc2_block block
;
542 for (y
= 0; y
< height
; y
+= bh
) {
543 const uint8_t *src
= src_row
;
545 for (x
= 0; x
< width
; x
+= bw
) {
546 etc2_rgb8_parse_block(&block
, src
);
548 for (j
= 0; j
< bh
; j
++) {
549 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
550 for (i
= 0; i
< bw
; i
++) {
551 etc2_rgb8_fetch_texel(&block
, i
, j
, dst
);
560 src_row
+= src_stride
;
565 etc2_unpack_srgb8(uint8_t *dst_row
,
567 const uint8_t *src_row
,
572 const unsigned bw
= 4, bh
= 4, bs
= 8, comps
= 4;
573 struct etc2_block block
;
577 for (y
= 0; y
< height
; y
+= bh
) {
578 const uint8_t *src
= src_row
;
580 for (x
= 0; x
< width
; x
+= bw
) {
581 etc2_rgb8_parse_block(&block
, src
);
583 for (j
= 0; j
< bh
; j
++) {
584 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
585 for (i
= 0; i
< bw
; i
++) {
586 etc2_rgb8_fetch_texel(&block
, i
, j
, dst
);
587 /* Convert to MESA_FORMAT_SARGB8 */
599 src_row
+= src_stride
;
604 etc2_unpack_rgba8(uint8_t *dst_row
,
606 const uint8_t *src_row
,
611 /* If internalformat is COMPRESSED_RGBA8_ETC2_EAC, each 4 × 4 block of
612 * RGBA8888 information is compressed to 128 bits. To decode a block, the
613 * two 64-bit integers int64bitAlpha and int64bitColor are calculated.
615 const unsigned bw
= 4, bh
= 4, bs
= 16, comps
= 4;
616 struct etc2_block block
;
619 for (y
= 0; y
< height
; y
+= bh
) {
620 const uint8_t *src
= src_row
;
622 for (x
= 0; x
< width
; x
+= bw
) {
623 etc2_rgba8_parse_block(&block
, src
);
625 for (j
= 0; j
< bh
; j
++) {
626 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
627 for (i
= 0; i
< bw
; i
++) {
628 etc2_rgba8_fetch_texel(&block
, i
, j
, dst
);
635 src_row
+= src_stride
;
640 etc2_unpack_srgb8_alpha8(uint8_t *dst_row
,
642 const uint8_t *src_row
,
647 /* If internalformat is COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, each 4 × 4 block
648 * of RGBA8888 information is compressed to 128 bits. To decode a block, the
649 * two 64-bit integers int64bitAlpha and int64bitColor are calculated.
651 const unsigned bw
= 4, bh
= 4, bs
= 16, comps
= 4;
652 struct etc2_block block
;
656 for (y
= 0; y
< height
; y
+= bh
) {
657 const uint8_t *src
= src_row
;
659 for (x
= 0; x
< width
; x
+= bw
) {
660 etc2_rgba8_parse_block(&block
, src
);
662 for (j
= 0; j
< bh
; j
++) {
663 uint8_t *dst
= dst_row
+ (y
+ j
) * dst_stride
+ x
* comps
;
664 for (i
= 0; i
< bw
; i
++) {
665 etc2_rgba8_fetch_texel(&block
, i
, j
, dst
);
667 /* Convert to MESA_FORMAT_SARGB8 */
679 src_row
+= src_stride
;
683 /* ETC2 texture formats are valid in glCompressedTexImage2D and
684 * glCompressedTexSubImage2D functions */
686 _mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS
)
694 _mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS
)
702 _mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS
)
710 _mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS
)
718 _mesa_fetch_texel_2d_f_etc2_rgb8(const struct swrast_texture_image
*texImage
,
719 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
721 struct etc2_block block
;
725 src
= texImage
->Map
+
726 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
728 etc2_rgb8_parse_block(&block
, src
);
729 etc2_rgb8_fetch_texel(&block
, i
% 4, j
% 4, dst
);
731 texel
[RCOMP
] = UBYTE_TO_FLOAT(dst
[0]);
732 texel
[GCOMP
] = UBYTE_TO_FLOAT(dst
[1]);
733 texel
[BCOMP
] = UBYTE_TO_FLOAT(dst
[2]);
738 _mesa_fetch_texel_2d_f_etc2_srgb8(const struct swrast_texture_image
*texImage
,
739 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
741 struct etc2_block block
;
745 src
= texImage
->Map
+
746 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 8;
748 etc2_rgb8_parse_block(&block
, src
);
749 etc2_rgb8_fetch_texel(&block
, i
% 4, j
% 4, dst
);
751 texel
[RCOMP
] = _mesa_nonlinear_to_linear(dst
[0]);
752 texel
[GCOMP
] = _mesa_nonlinear_to_linear(dst
[1]);
753 texel
[BCOMP
] = _mesa_nonlinear_to_linear(dst
[2]);
758 _mesa_fetch_texel_2d_f_etc2_rgba8_eac(const struct swrast_texture_image
*texImage
,
759 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
761 struct etc2_block block
;
765 src
= texImage
->Map
+
766 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
768 etc2_rgba8_parse_block(&block
, src
);
769 etc2_rgba8_fetch_texel(&block
, i
% 4, j
% 4, dst
);
771 texel
[RCOMP
] = UBYTE_TO_FLOAT(dst
[0]);
772 texel
[GCOMP
] = UBYTE_TO_FLOAT(dst
[1]);
773 texel
[BCOMP
] = UBYTE_TO_FLOAT(dst
[2]);
774 texel
[ACOMP
] = UBYTE_TO_FLOAT(dst
[3]);
778 _mesa_fetch_texel_2d_f_etc2_srgb8_alpha8_eac(const struct
779 swrast_texture_image
*texImage
,
781 GLint k
, GLfloat
*texel
)
783 struct etc2_block block
;
787 src
= texImage
->Map
+
788 (((texImage
->RowStride
+ 3) / 4) * (j
/ 4) + (i
/ 4)) * 16;
790 etc2_rgba8_parse_block(&block
, src
);
791 etc2_rgba8_fetch_texel(&block
, i
% 4, j
% 4, dst
);
793 texel
[RCOMP
] = _mesa_nonlinear_to_linear(dst
[0]);
794 texel
[GCOMP
] = _mesa_nonlinear_to_linear(dst
[1]);
795 texel
[BCOMP
] = _mesa_nonlinear_to_linear(dst
[2]);
796 texel
[ACOMP
] = UBYTE_TO_FLOAT(dst
[3]);
800 * Decode texture data in any one of following formats:
801 * `MESA_FORMAT_ETC2_RGB8`
802 * `MESA_FORMAT_ETC2_SRGB8`
803 * `MESA_FORMAT_ETC2_RGBA8_EAC`
804 * `MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC`
806 * The size of the source data must be a multiple of the ETC2 block size
807 * even if the texture image's dimensions are not aligned to 4.
809 * \param src_width in pixels
810 * \param src_height in pixels
811 * \param dst_stride in bytes
815 _mesa_unpack_etc2_format(uint8_t *dst_row
,
817 const uint8_t *src_row
,
823 if (format
== MESA_FORMAT_ETC2_RGB8
)
824 etc2_unpack_rgb8(dst_row
, dst_stride
,
826 src_width
, src_height
);
827 else if (format
== MESA_FORMAT_ETC2_SRGB8
)
828 etc2_unpack_srgb8(dst_row
, dst_stride
,
830 src_width
, src_height
);
831 else if (format
== MESA_FORMAT_ETC2_RGBA8_EAC
)
832 etc2_unpack_rgba8(dst_row
, dst_stride
,
834 src_width
, src_height
);
835 else if (format
== MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC
)
836 etc2_unpack_srgb8_alpha8(dst_row
, dst_stride
,
838 src_width
, src_height
);