mesa: Add decoding functions for GL_COMPRESSED_RG11_EAC
[mesa.git] / src / mesa / main / texcompress_etc.c
1 /*
2 * Copyright (C) 2011 LunarG, Inc.
3 *
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:
10 *
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
13 * Software.
14 *
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.
22 */
23
24 /**
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 */
35
36 #include <stdbool.h>
37 #include "mfeatures.h"
38 #include "texcompress.h"
39 #include "texcompress_etc.h"
40 #include "texstore.h"
41 #include "macros.h"
42 #include "swrast/s_context.h"
43 #include "format_unpack.h"
44
45 struct etc2_block {
46 int distance;
47 uint64_t pixel_indices[2];
48 const int *modifier_tables[2];
49 bool flipped;
50 bool is_ind_mode;
51 bool is_diff_mode;
52 bool is_t_mode;
53 bool is_h_mode;
54 bool is_planar_mode;
55 uint8_t base_colors[3][3];
56 uint8_t paint_colors[4][3];
57 uint8_t base_codeword;
58 uint8_t multiplier;
59 uint8_t table_index;
60 };
61
62 static const int etc2_distance_table[8] = {
63 3, 6, 11, 16, 23, 32, 41, 64 };
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},
82 };
83
84 /* define etc1_parse_block and etc. */
85 #define UINT8_TYPE GLubyte
86 #define TAG(x) x
87 #include "texcompress_etc_tmp.h"
88 #undef TAG
89 #undef UINT8_TYPE
90
91 GLboolean
92 _mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS)
93 {
94 /* GL_ETC1_RGB8_OES is only valid in glCompressedTexImage2D */
95 ASSERT(0);
96
97 return GL_FALSE;
98 }
99
100 void
101 _mesa_fetch_texel_2d_f_etc1_rgb8(const struct swrast_texture_image *texImage,
102 GLint i, GLint j, GLint k, GLfloat *texel)
103 {
104 struct etc1_block block;
105 GLubyte dst[3];
106 const GLubyte *src;
107
108 src = (const GLubyte *) texImage->Map +
109 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
110
111 etc1_parse_block(&block, src);
112 etc1_fetch_texel(&block, i % 4, j % 4, dst);
113
114 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]);
115 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]);
116 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]);
117 texel[ACOMP] = 1.0f;
118 }
119
120 /**
121 * Decode texture data in format `MESA_FORMAT_ETC1_RGB8` to
122 * `MESA_FORMAT_ABGR8888`.
123 *
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.
134 *
135 * \param src_width in pixels
136 * \param src_height in pixels
137 * \param dst_stride in bytes
138 */
139 void
140 _mesa_etc1_unpack_rgba8888(uint8_t *dst_row,
141 unsigned dst_stride,
142 const uint8_t *src_row,
143 unsigned src_stride,
144 unsigned src_width,
145 unsigned src_height)
146 {
147 etc1_unpack_rgba8888(dst_row, dst_stride,
148 src_row, src_stride,
149 src_width, src_height);
150 }
151
152 static uint8_t
153 etc2_base_color1_t_mode(const uint8_t *in, GLuint index)
154 {
155 uint8_t R1a = 0, x = 0;
156 /* base col 1 = extend_4to8bits( (R1a << 2) | R1b, G1, B1) */
157 switch(index) {
158 case 0:
159 R1a = (in[0] >> 3) & 0x3;
160 x = ((R1a << 2) | (in[0] & 0x3));
161 break;
162 case 1:
163 x = ((in[1] >> 4) & 0xf);
164 break;
165 case 2:
166 x = (in[1] & 0xf);
167 break;
168 default:
169 /* invalid index */
170 break;
171 }
172 return ((x << 4) | (x & 0xf));
173 }
174
175 static uint8_t
176 etc2_base_color2_t_mode(const uint8_t *in, GLuint index)
177 {
178 uint8_t x = 0;
179 /*extend 4to8bits(R2, G2, B2)*/
180 switch(index) {
181 case 0:
182 x = ((in[2] >> 4) & 0xf );
183 break;
184 case 1:
185 x = (in[2] & 0xf);
186 break;
187 case 2:
188 x = ((in[3] >> 4) & 0xf);
189 break;
190 default:
191 /* invalid index */
192 break;
193 }
194 return ((x << 4) | (x & 0xf));
195 }
196
197 static uint8_t
198 etc2_base_color1_h_mode(const uint8_t *in, GLuint index)
199 {
200 uint8_t x = 0;
201 /* base col 1 = extend 4to8bits(R1, (G1a << 1) | G1b, (B1a << 3) | B1b) */
202 switch(index) {
203 case 0:
204 x = ((in[0] >> 3) & 0xf);
205 break;
206 case 1:
207 x = (((in[0] & 0x7) << 1) | ((in[1] >> 4) & 0x1));
208 break;
209 case 2:
210 x = ((in[1] & 0x8) |
211 (((in[1] & 0x3) << 1) | ((in[2] >> 7) & 0x1)));
212 break;
213 default:
214 /* invalid index */
215 break;
216 }
217 return ((x << 4) | (x & 0xf));
218 }
219
220 static uint8_t
221 etc2_base_color2_h_mode(const uint8_t *in, GLuint index)
222 {
223 uint8_t x = 0;
224 /* base col 2 = extend 4to8bits(R2, G2, B2) */
225 switch(index) {
226 case 0:
227 x = ((in[2] >> 3) & 0xf );
228 break;
229 case 1:
230 x = (((in[2] & 0x7) << 1) | ((in[3] >> 7) & 0x1));
231 break;
232 case 2:
233 x = ((in[3] >> 3) & 0xf);
234 break;
235 default:
236 /* invalid index */
237 break;
238 }
239 return ((x << 4) | (x & 0xf));
240 }
241
242 static uint8_t
243 etc2_base_color_o_planar(const uint8_t *in, GLuint index)
244 {
245 GLuint tmp;
246 switch(index) {
247 case 0:
248 tmp = ((in[0] >> 1) & 0x3f); /* RO */
249 return ((tmp << 2) | (tmp >> 4));
250 case 1:
251 tmp = (((in[0] & 0x1) << 6) | /* GO1 */
252 ((in[1] >> 1) & 0x3f)); /* GO2 */
253 return ((tmp << 1) | (tmp >> 6));
254 case 2:
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));
259 default:
260 /* invalid index */
261 return 0;
262 }
263 }
264
265 static uint8_t
266 etc2_base_color_h_planar(const uint8_t *in, GLuint index)
267 {
268 GLuint tmp;
269 switch(index) {
270 case 0:
271 tmp = (((in[3] & 0x7c) >> 1) | /* RH1 */
272 (in[3] & 0x1)); /* RH2 */
273 return ((tmp << 2) | (tmp >> 4));
274 case 1:
275 tmp = (in[4] >> 1) & 0x7f; /* GH */
276 return ((tmp << 1) | (tmp >> 6));
277 case 2:
278 tmp = (((in[4] & 0x1) << 5) |
279 ((in[5] >> 3) & 0x1f)); /* BH */
280 return ((tmp << 2) | (tmp >> 4));
281 default:
282 /* invalid index */
283 return 0;
284 }
285 }
286
287 static uint8_t
288 etc2_base_color_v_planar(const uint8_t *in, GLuint index)
289 {
290 GLuint tmp;
291 switch(index) {
292 case 0:
293 tmp = (((in[5] & 0x7) << 0x3) |
294 ((in[6] >> 5) & 0x7)); /* RV */
295 return ((tmp << 2) | (tmp >> 4));
296 case 1:
297 tmp = (((in[6] & 0x1f) << 2) |
298 ((in[7] >> 6) & 0x3)); /* GV */
299 return ((tmp << 1) | (tmp >> 6));
300 case 2:
301 tmp = in[7] & 0x3f; /* BV */
302 return ((tmp << 2) | (tmp >> 4));
303 default:
304 /* invalid index */
305 return 0;
306 }
307 }
308
309 static GLint
310 etc2_get_pixel_index(const struct etc2_block *block, int x, int y)
311 {
312 int bit = ((3 - y) + (3 - x) * 4) * 3;
313 int idx = (block->pixel_indices[1] >> bit) & 0x7;
314 return idx;
315 }
316
317 static uint8_t
318 etc2_clamp(int color)
319 {
320 /* CLAMP(color, 0, 255) */
321 return (uint8_t) CLAMP(color, 0, 255);
322 }
323
324 static GLushort
325 etc2_clamp2(int color)
326 {
327 /* CLAMP(color, 0, 2047) */
328 return (GLushort) CLAMP(color, 0, 2047);
329 }
330
331 static void
332 etc2_rgb8_parse_block(struct etc2_block *block, const uint8_t *src)
333 {
334 unsigned i;
335 GLboolean diffbit = src[3] & 0x2;
336 static const int lookup[8] = { 0, 1, 2, 3, -4, -3, -2, -1 };
337
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];
341
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;
348
349 if (!diffbit) {
350 /* individual mode */
351 block->is_ind_mode = true;
352
353 for (i = 0; i < 3; i++) {
354 /* Texture decode algorithm is same for individual mode in etc1
355 * & etc2.
356 */
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]);
359 }
360 }
361 else if (R_plus_dR < 0 || R_plus_dR > 31){
362 /* T mode */
363 block->is_t_mode = true;
364
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);
368 }
369 /* pick distance */
370 block->distance =
371 etc2_distance_table[(((src[3] >> 2) & 0x3) << 1) |
372 (src[3] & 0x1)];
373
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] +
377 block->distance);
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] -
380 block->distance);
381 }
382 }
383 else if (G_plus_dG < 0 || G_plus_dG > 31){
384 /* H mode */
385 block->is_h_mode = true;
386 int base_color_1_value, base_color_2_value;
387
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);
391 }
392
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];
399 /* pick distance */
400 block->distance =
401 etc2_distance_table[(src[3] & 0x4) |
402 ((src[3] & 0x1) << 1) |
403 (base_color_1_value >= base_color_2_value)];
404
405 for (i = 0; i < 3; i++) {
406 block->paint_colors[0][i] = etc2_clamp(block->base_colors[0][i] +
407 block->distance);
408 block->paint_colors[1][i] = etc2_clamp(block->base_colors[0][i] -
409 block->distance);
410 block->paint_colors[2][i] = etc2_clamp(block->base_colors[1][i] +
411 block->distance);
412 block->paint_colors[3][i] = etc2_clamp(block->base_colors[1][i] -
413 block->distance);
414 }
415 }
416 else if (B_plus_dB < 0 || B_plus_dB > 31){
417 /* Planar mode */
418 block->is_planar_mode = true;
419
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);
424 }
425 }
426 else if (diffbit) {
427 /* differential mode */
428 block->is_diff_mode = true;
429
430 for (i = 0; i < 3; i++) {
431 /* Texture decode algorithm is same for differential mode in etc1
432 * & etc2.
433 */
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]);
436 }
437 }
438
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);
444 }
445
446 block->pixel_indices[0] =
447 (src[4] << 24) | (src[5] << 16) | (src[6] << 8) | src[7];
448 }
449
450 static void
451 etc2_rgb8_fetch_texel(const struct etc2_block *block,
452 int x, int y, uint8_t *dst)
453 {
454 const uint8_t *base_color;
455 int modifier, bit, idx, blk;
456
457 /* get pixel index */
458 bit = y + x * 4;
459 idx = ((block->pixel_indices[0] >> (15 + bit)) & 0x2) |
460 ((block->pixel_indices[0] >> (bit)) & 0x1);
461
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];
467
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);
471 }
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];
477 }
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)
482 */
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;
487
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;
491
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;
495
496 dst[0] = etc2_clamp(red);
497 dst[1] = etc2_clamp(green);
498 dst[2] = etc2_clamp(blue);
499 }
500 }
501
502 static void
503 etc2_alpha8_fetch_texel(const struct etc2_block *block,
504 int x, int y, uint8_t *dst)
505 {
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);
512 }
513
514 static void
515 etc2_r11_fetch_texel(const struct etc2_block *block,
516 int x, int y, uint8_t *dst)
517 {
518 GLint modifier, idx;
519 GLshort color;
520 /* Get pixel index */
521 idx = etc2_get_pixel_index(block, x, y);
522 modifier = etc2_modifier_tables[block->table_index][idx];
523
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));
528 else
529 color = etc2_clamp2(((block->base_codeword << 3) | 0x4) + modifier);
530
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
534 * 11 bits."
535 */
536 color = (color << 5) | (color >> 6);
537 ((GLushort *)dst)[0] = color;
538 }
539
540 static void
541 etc2_alpha8_parse_block(struct etc2_block *block, const uint8_t *src)
542 {
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) |
551 ((uint64_t)src[7]));
552 }
553
554 static void
555 etc2_r11_parse_block(struct etc2_block *block, const uint8_t *src)
556 {
557 /* Parsing logic remains same as for etc2_alpha8_parse_block */
558 etc2_alpha8_parse_block(block, src);
559 }
560
561 static void
562 etc2_rgba8_parse_block(struct etc2_block *block, const uint8_t *src)
563 {
564 /* RGB component is parsed the same way as for MESA_FORMAT_ETC2_RGB8 */
565 etc2_rgb8_parse_block(block, src + 8);
566
567 /* Parse Alpha component */
568 etc2_alpha8_parse_block(block, src);
569 }
570
571 static void
572 etc2_rgba8_fetch_texel(const struct etc2_block *block,
573 int x, int y, uint8_t *dst)
574 {
575 etc2_rgb8_fetch_texel(block, x, y, dst);
576 etc2_alpha8_fetch_texel(block, x, y, dst);
577 }
578
579 static void
580 etc2_unpack_rgb8(uint8_t *dst_row,
581 unsigned dst_stride,
582 const uint8_t *src_row,
583 unsigned src_stride,
584 unsigned width,
585 unsigned height)
586 {
587 const unsigned bw = 4, bh = 4, bs = 8, comps = 4;
588 struct etc2_block block;
589 unsigned x, y, i, j;
590
591 for (y = 0; y < height; y += bh) {
592 const uint8_t *src = src_row;
593
594 for (x = 0; x < width; x+= bw) {
595 etc2_rgb8_parse_block(&block, src);
596
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);
601 dst[3] = 255;
602 dst += comps;
603 }
604 }
605
606 src += bs;
607 }
608
609 src_row += src_stride;
610 }
611 }
612
613 static void
614 etc2_unpack_srgb8(uint8_t *dst_row,
615 unsigned dst_stride,
616 const uint8_t *src_row,
617 unsigned src_stride,
618 unsigned width,
619 unsigned height)
620 {
621 const unsigned bw = 4, bh = 4, bs = 8, comps = 4;
622 struct etc2_block block;
623 unsigned x, y, i, j;
624 uint8_t tmp;
625
626 for (y = 0; y < height; y += bh) {
627 const uint8_t *src = src_row;
628
629 for (x = 0; x < width; x+= bw) {
630 etc2_rgb8_parse_block(&block, src);
631
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 */
637 tmp = dst[0];
638 dst[0] = dst[2];
639 dst[2] = tmp;
640 dst[3] = 255;
641
642 dst += comps;
643 }
644 }
645 src += bs;
646 }
647
648 src_row += src_stride;
649 }
650 }
651
652 static void
653 etc2_unpack_rgba8(uint8_t *dst_row,
654 unsigned dst_stride,
655 const uint8_t *src_row,
656 unsigned src_stride,
657 unsigned width,
658 unsigned height)
659 {
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.
663 */
664 const unsigned bw = 4, bh = 4, bs = 16, comps = 4;
665 struct etc2_block block;
666 unsigned x, y, i, j;
667
668 for (y = 0; y < height; y += bh) {
669 const uint8_t *src = src_row;
670
671 for (x = 0; x < width; x+= bw) {
672 etc2_rgba8_parse_block(&block, src);
673
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);
678 dst += comps;
679 }
680 }
681 src += bs;
682 }
683
684 src_row += src_stride;
685 }
686 }
687
688 static void
689 etc2_unpack_srgb8_alpha8(uint8_t *dst_row,
690 unsigned dst_stride,
691 const uint8_t *src_row,
692 unsigned src_stride,
693 unsigned width,
694 unsigned height)
695 {
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.
699 */
700 const unsigned bw = 4, bh = 4, bs = 16, comps = 4;
701 struct etc2_block block;
702 unsigned x, y, i, j;
703 uint8_t tmp;
704
705 for (y = 0; y < height; y += bh) {
706 const uint8_t *src = src_row;
707
708 for (x = 0; x < width; x+= bw) {
709 etc2_rgba8_parse_block(&block, src);
710
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);
715
716 /* Convert to MESA_FORMAT_SARGB8 */
717 tmp = dst[0];
718 dst[0] = dst[2];
719 dst[2] = tmp;
720 dst[3] = dst[3];
721
722 dst += comps;
723 }
724 }
725 src += bs;
726 }
727
728 src_row += src_stride;
729 }
730 }
731
732 static void
733 etc2_unpack_r11(uint8_t *dst_row,
734 unsigned dst_stride,
735 const uint8_t *src_row,
736 unsigned src_stride,
737 unsigned width,
738 unsigned height)
739 {
740 /* If internalformat is COMPRESSED_R11_EAC, each 4 × 4 block of
741 color information is compressed to 64 bits.
742 */
743 const unsigned bw = 4, bh = 4, bs = 8, comps = 1, comp_size = 2;
744 struct etc2_block block;
745 unsigned x, y, i, j;
746
747 for (y = 0; y < height; y += bh) {
748 const uint8_t *src = src_row;
749
750 for (x = 0; x < width; x+= bw) {
751 etc2_r11_parse_block(&block, src);
752
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;
758 }
759 }
760 src += bs;
761 }
762
763 src_row += src_stride;
764 }
765 }
766
767 static void
768 etc2_unpack_rg11(uint8_t *dst_row,
769 unsigned dst_stride,
770 const uint8_t *src_row,
771 unsigned src_stride,
772 unsigned width,
773 unsigned height)
774 {
775 /* If internalformat is COMPRESSED_RG11_EAC, each 4 × 4 block of
776 RG color information is compressed to 128 bits.
777 */
778 const unsigned bw = 4, bh = 4, bs = 16, comps = 2, comp_size = 2;
779 struct etc2_block block;
780 unsigned x, y, i, j;
781
782 for (y = 0; y < height; y += bh) {
783 const uint8_t *src = src_row;
784
785 for (x = 0; x < width; x+= bw) {
786 /* red component */
787 etc2_r11_parse_block(&block, src);
788
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;
795 }
796 }
797 /* green component */
798 etc2_r11_parse_block(&block, src + 8);
799
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;
806 }
807 }
808 src += bs;
809 }
810
811 src_row += src_stride;
812 }
813 }
814
815 /* ETC2 texture formats are valid in glCompressedTexImage2D and
816 * glCompressedTexSubImage2D functions */
817 GLboolean
818 _mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS)
819 {
820 ASSERT(0);
821
822 return GL_FALSE;
823 }
824
825 GLboolean
826 _mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS)
827 {
828 ASSERT(0);
829
830 return GL_FALSE;
831 }
832
833 GLboolean
834 _mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS)
835 {
836 ASSERT(0);
837
838 return GL_FALSE;
839 }
840
841 GLboolean
842 _mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS)
843 {
844 ASSERT(0);
845
846 return GL_FALSE;
847 }
848
849 GLboolean
850 _mesa_texstore_etc2_r11_eac(TEXSTORE_PARAMS)
851 {
852 ASSERT(0);
853
854 return GL_FALSE;
855 }
856
857 GLboolean
858 _mesa_texstore_etc2_rg11_eac(TEXSTORE_PARAMS)
859 {
860 ASSERT(0);
861
862 return GL_FALSE;
863 }
864
865 void
866 _mesa_fetch_texel_2d_f_etc2_rgb8(const struct swrast_texture_image *texImage,
867 GLint i, GLint j, GLint k, GLfloat *texel)
868 {
869 struct etc2_block block;
870 uint8_t dst[3];
871 const uint8_t *src;
872
873 src = texImage->Map +
874 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
875
876 etc2_rgb8_parse_block(&block, src);
877 etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst);
878
879 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]);
880 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]);
881 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]);
882 texel[ACOMP] = 1.0f;
883 }
884
885 void
886 _mesa_fetch_texel_2d_f_etc2_srgb8(const struct swrast_texture_image *texImage,
887 GLint i, GLint j, GLint k, GLfloat *texel)
888 {
889 struct etc2_block block;
890 uint8_t dst[3];
891 const uint8_t *src;
892
893 src = texImage->Map +
894 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
895
896 etc2_rgb8_parse_block(&block, src);
897 etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst);
898
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]);
902 texel[ACOMP] = 1.0f;
903 }
904
905 void
906 _mesa_fetch_texel_2d_f_etc2_rgba8_eac(const struct swrast_texture_image *texImage,
907 GLint i, GLint j, GLint k, GLfloat *texel)
908 {
909 struct etc2_block block;
910 uint8_t dst[4];
911 const uint8_t *src;
912
913 src = texImage->Map +
914 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16;
915
916 etc2_rgba8_parse_block(&block, src);
917 etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst);
918
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]);
923 }
924
925 void
926 _mesa_fetch_texel_2d_f_etc2_srgb8_alpha8_eac(const struct
927 swrast_texture_image *texImage,
928 GLint i, GLint j,
929 GLint k, GLfloat *texel)
930 {
931 struct etc2_block block;
932 uint8_t dst[4];
933 const uint8_t *src;
934
935 src = texImage->Map +
936 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16;
937
938 etc2_rgba8_parse_block(&block, src);
939 etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst);
940
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]);
945 }
946
947 void
948 _mesa_fetch_texel_2d_f_etc2_r11_eac(const struct swrast_texture_image *texImage,
949 GLint i, GLint j, GLint k, GLfloat *texel)
950 {
951 struct etc2_block block;
952 GLushort dst;
953 const uint8_t *src;
954
955 src = texImage->Map +
956 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
957
958 etc2_r11_parse_block(&block, src);
959 etc2_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)&dst);
960
961 texel[RCOMP] = USHORT_TO_FLOAT(dst);
962 texel[GCOMP] = 0.0f;
963 texel[BCOMP] = 0.0f;
964 texel[ACOMP] = 1.0f;
965 }
966
967 void
968 _mesa_fetch_texel_2d_f_etc2_rg11_eac(const struct
969 swrast_texture_image *texImage,
970 GLint i, GLint j,
971 GLint k, GLfloat *texel)
972 {
973 struct etc2_block block;
974 GLushort dst[2];
975 const uint8_t *src;
976
977 src = texImage->Map +
978 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16;
979
980 /* red component */
981 etc2_r11_parse_block(&block, src);
982 etc2_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)dst);
983
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));
987
988 texel[RCOMP] = USHORT_TO_FLOAT(dst[0]);
989 texel[GCOMP] = USHORT_TO_FLOAT(dst[1]);
990 texel[BCOMP] = 0.0f;
991 texel[ACOMP] = 1.0f;
992 }
993
994 /**
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`
1002 *
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.
1005 *
1006 * \param src_width in pixels
1007 * \param src_height in pixels
1008 * \param dst_stride in bytes
1009 */
1010
1011 void
1012 _mesa_unpack_etc2_format(uint8_t *dst_row,
1013 unsigned dst_stride,
1014 const uint8_t *src_row,
1015 unsigned src_stride,
1016 unsigned src_width,
1017 unsigned src_height,
1018 gl_format format)
1019 {
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);
1044 }