d704388d6306ea7a6a4b54e4efc11a72f1e1ba0e
[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 */
33
34 #include <stdbool.h>
35 #include "mfeatures.h"
36 #include "texcompress.h"
37 #include "texcompress_etc.h"
38 #include "texstore.h"
39 #include "macros.h"
40 #include "swrast/s_context.h"
41 #include "format_unpack.h"
42
43 struct etc2_block {
44 int distance;
45 uint64_t pixel_indices[2];
46 const int *modifier_tables[2];
47 bool flipped;
48 bool is_ind_mode;
49 bool is_diff_mode;
50 bool is_t_mode;
51 bool is_h_mode;
52 bool is_planar_mode;
53 uint8_t base_colors[3][3];
54 uint8_t paint_colors[4][3];
55 uint8_t base_codeword;
56 uint8_t multiplier;
57 uint8_t table_index;
58 };
59
60 static const int etc2_distance_table[8] = {
61 3, 6, 11, 16, 23, 32, 41, 64 };
62
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},
80 };
81
82 /* define etc1_parse_block and etc. */
83 #define UINT8_TYPE GLubyte
84 #define TAG(x) x
85 #include "texcompress_etc_tmp.h"
86 #undef TAG
87 #undef UINT8_TYPE
88
89 GLboolean
90 _mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS)
91 {
92 /* GL_ETC1_RGB8_OES is only valid in glCompressedTexImage2D */
93 ASSERT(0);
94
95 return GL_FALSE;
96 }
97
98 void
99 _mesa_fetch_texel_2d_f_etc1_rgb8(const struct swrast_texture_image *texImage,
100 GLint i, GLint j, GLint k, GLfloat *texel)
101 {
102 struct etc1_block block;
103 GLubyte dst[3];
104 const GLubyte *src;
105
106 src = (const GLubyte *) texImage->Map +
107 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
108
109 etc1_parse_block(&block, src);
110 etc1_fetch_texel(&block, i % 4, j % 4, dst);
111
112 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]);
113 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]);
114 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]);
115 texel[ACOMP] = 1.0f;
116 }
117
118 /**
119 * Decode texture data in format `MESA_FORMAT_ETC1_RGB8` to
120 * `MESA_FORMAT_ABGR8888`.
121 *
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.
132 *
133 * \param src_width in pixels
134 * \param src_height in pixels
135 * \param dst_stride in bytes
136 */
137 void
138 _mesa_etc1_unpack_rgba8888(uint8_t *dst_row,
139 unsigned dst_stride,
140 const uint8_t *src_row,
141 unsigned src_stride,
142 unsigned src_width,
143 unsigned src_height)
144 {
145 etc1_unpack_rgba8888(dst_row, dst_stride,
146 src_row, src_stride,
147 src_width, src_height);
148 }
149
150 static uint8_t
151 etc2_base_color1_t_mode(const uint8_t *in, GLuint index)
152 {
153 uint8_t R1a = 0, x = 0;
154 /* base col 1 = extend_4to8bits( (R1a << 2) | R1b, G1, B1) */
155 switch(index) {
156 case 0:
157 R1a = (in[0] >> 3) & 0x3;
158 x = ((R1a << 2) | (in[0] & 0x3));
159 break;
160 case 1:
161 x = ((in[1] >> 4) & 0xf);
162 break;
163 case 2:
164 x = (in[1] & 0xf);
165 break;
166 default:
167 /* invalid index */
168 break;
169 }
170 return ((x << 4) | (x & 0xf));
171 }
172
173 static uint8_t
174 etc2_base_color2_t_mode(const uint8_t *in, GLuint index)
175 {
176 uint8_t x = 0;
177 /*extend 4to8bits(R2, G2, B2)*/
178 switch(index) {
179 case 0:
180 x = ((in[2] >> 4) & 0xf );
181 break;
182 case 1:
183 x = (in[2] & 0xf);
184 break;
185 case 2:
186 x = ((in[3] >> 4) & 0xf);
187 break;
188 default:
189 /* invalid index */
190 break;
191 }
192 return ((x << 4) | (x & 0xf));
193 }
194
195 static uint8_t
196 etc2_base_color1_h_mode(const uint8_t *in, GLuint index)
197 {
198 uint8_t x = 0;
199 /* base col 1 = extend 4to8bits(R1, (G1a << 1) | G1b, (B1a << 3) | B1b) */
200 switch(index) {
201 case 0:
202 x = ((in[0] >> 3) & 0xf);
203 break;
204 case 1:
205 x = (((in[0] & 0x7) << 1) | ((in[1] >> 4) & 0x1));
206 break;
207 case 2:
208 x = ((in[1] & 0x8) |
209 (((in[1] & 0x3) << 1) | ((in[2] >> 7) & 0x1)));
210 break;
211 default:
212 /* invalid index */
213 break;
214 }
215 return ((x << 4) | (x & 0xf));
216 }
217
218 static uint8_t
219 etc2_base_color2_h_mode(const uint8_t *in, GLuint index)
220 {
221 uint8_t x = 0;
222 /* base col 2 = extend 4to8bits(R2, G2, B2) */
223 switch(index) {
224 case 0:
225 x = ((in[2] >> 3) & 0xf );
226 break;
227 case 1:
228 x = (((in[2] & 0x7) << 1) | ((in[3] >> 7) & 0x1));
229 break;
230 case 2:
231 x = ((in[3] >> 3) & 0xf);
232 break;
233 default:
234 /* invalid index */
235 break;
236 }
237 return ((x << 4) | (x & 0xf));
238 }
239
240 static uint8_t
241 etc2_base_color_o_planar(const uint8_t *in, GLuint index)
242 {
243 GLuint tmp;
244 switch(index) {
245 case 0:
246 tmp = ((in[0] >> 1) & 0x3f); /* RO */
247 return ((tmp << 2) | (tmp >> 4));
248 case 1:
249 tmp = (((in[0] & 0x1) << 6) | /* GO1 */
250 ((in[1] >> 1) & 0x3f)); /* GO2 */
251 return ((tmp << 1) | (tmp >> 6));
252 case 2:
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));
257 default:
258 /* invalid index */
259 return 0;
260 }
261 }
262
263 static uint8_t
264 etc2_base_color_h_planar(const uint8_t *in, GLuint index)
265 {
266 GLuint tmp;
267 switch(index) {
268 case 0:
269 tmp = (((in[3] & 0x7c) >> 1) | /* RH1 */
270 (in[3] & 0x1)); /* RH2 */
271 return ((tmp << 2) | (tmp >> 4));
272 case 1:
273 tmp = (in[4] >> 1) & 0x7f; /* GH */
274 return ((tmp << 1) | (tmp >> 6));
275 case 2:
276 tmp = (((in[4] & 0x1) << 5) |
277 ((in[5] >> 3) & 0x1f)); /* BH */
278 return ((tmp << 2) | (tmp >> 4));
279 default:
280 /* invalid index */
281 return 0;
282 }
283 }
284
285 static uint8_t
286 etc2_base_color_v_planar(const uint8_t *in, GLuint index)
287 {
288 GLuint tmp;
289 switch(index) {
290 case 0:
291 tmp = (((in[5] & 0x7) << 0x3) |
292 ((in[6] >> 5) & 0x7)); /* RV */
293 return ((tmp << 2) | (tmp >> 4));
294 case 1:
295 tmp = (((in[6] & 0x1f) << 2) |
296 ((in[7] >> 6) & 0x3)); /* GV */
297 return ((tmp << 1) | (tmp >> 6));
298 case 2:
299 tmp = in[7] & 0x3f; /* BV */
300 return ((tmp << 2) | (tmp >> 4));
301 default:
302 /* invalid index */
303 return 0;
304 }
305 }
306
307 static uint8_t
308 etc2_clamp(int color)
309 {
310 /* CLAMP(color, 0, 255) */
311 return (uint8_t) CLAMP(color, 0, 255);
312 }
313
314 static void
315 etc2_rgb8_parse_block(struct etc2_block *block, const uint8_t *src)
316 {
317 unsigned i;
318 GLboolean diffbit = src[3] & 0x2;
319 static const int lookup[8] = { 0, 1, 2, 3, -4, -3, -2, -1 };
320
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];
324
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;
331
332 if (!diffbit) {
333 /* individual mode */
334 block->is_ind_mode = true;
335
336 for (i = 0; i < 3; i++) {
337 /* Texture decode algorithm is same for individual mode in etc1
338 * & etc2.
339 */
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]);
342 }
343 }
344 else if (R_plus_dR < 0 || R_plus_dR > 31){
345 /* T mode */
346 block->is_t_mode = true;
347
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);
351 }
352 /* pick distance */
353 block->distance =
354 etc2_distance_table[(((src[3] >> 2) & 0x3) << 1) |
355 (src[3] & 0x1)];
356
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] +
360 block->distance);
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] -
363 block->distance);
364 }
365 }
366 else if (G_plus_dG < 0 || G_plus_dG > 31){
367 /* H mode */
368 block->is_h_mode = true;
369 int base_color_1_value, base_color_2_value;
370
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);
374 }
375
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];
382 /* pick distance */
383 block->distance =
384 etc2_distance_table[(src[3] & 0x4) |
385 ((src[3] & 0x1) << 1) |
386 (base_color_1_value >= base_color_2_value)];
387
388 for (i = 0; i < 3; i++) {
389 block->paint_colors[0][i] = etc2_clamp(block->base_colors[0][i] +
390 block->distance);
391 block->paint_colors[1][i] = etc2_clamp(block->base_colors[0][i] -
392 block->distance);
393 block->paint_colors[2][i] = etc2_clamp(block->base_colors[1][i] +
394 block->distance);
395 block->paint_colors[3][i] = etc2_clamp(block->base_colors[1][i] -
396 block->distance);
397 }
398 }
399 else if (B_plus_dB < 0 || B_plus_dB > 31){
400 /* Planar mode */
401 block->is_planar_mode = true;
402
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);
407 }
408 }
409 else if (diffbit) {
410 /* differential mode */
411 block->is_diff_mode = true;
412
413 for (i = 0; i < 3; i++) {
414 /* Texture decode algorithm is same for differential mode in etc1
415 * & etc2.
416 */
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]);
419 }
420 }
421
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);
427 }
428
429 block->pixel_indices[0] =
430 (src[4] << 24) | (src[5] << 16) | (src[6] << 8) | src[7];
431 }
432
433 static void
434 etc2_rgb8_fetch_texel(const struct etc2_block *block,
435 int x, int y, uint8_t *dst)
436 {
437 const uint8_t *base_color;
438 int modifier, bit, idx, blk;
439
440 /* get pixel index */
441 bit = y + x * 4;
442 idx = ((block->pixel_indices[0] >> (15 + bit)) & 0x2) |
443 ((block->pixel_indices[0] >> (bit)) & 0x1);
444
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];
450
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);
454 }
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];
460 }
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)
465 */
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;
470
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;
474
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;
478
479 dst[0] = etc2_clamp(red);
480 dst[1] = etc2_clamp(green);
481 dst[2] = etc2_clamp(blue);
482 }
483 }
484
485 static void
486 etc2_alpha8_fetch_texel(const struct etc2_block *block,
487 int x, int y, uint8_t *dst)
488 {
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);
496 }
497
498 static void
499 etc2_alpha8_parse_block(struct etc2_block *block, const uint8_t *src)
500 {
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) |
509 ((uint64_t)src[7]));
510 }
511
512 static void
513 etc2_rgba8_parse_block(struct etc2_block *block, const uint8_t *src)
514 {
515 /* RGB component is parsed the same way as for MESA_FORMAT_ETC2_RGB8 */
516 etc2_rgb8_parse_block(block, src + 8);
517
518 /* Parse Alpha component */
519 etc2_alpha8_parse_block(block, src);
520 }
521
522 static void
523 etc2_rgba8_fetch_texel(const struct etc2_block *block,
524 int x, int y, uint8_t *dst)
525 {
526 etc2_rgb8_fetch_texel(block, x, y, dst);
527 etc2_alpha8_fetch_texel(block, x, y, dst);
528 }
529
530 static void
531 etc2_unpack_rgb8(uint8_t *dst_row,
532 unsigned dst_stride,
533 const uint8_t *src_row,
534 unsigned src_stride,
535 unsigned width,
536 unsigned height)
537 {
538 const unsigned bw = 4, bh = 4, bs = 8, comps = 4;
539 struct etc2_block block;
540 unsigned x, y, i, j;
541
542 for (y = 0; y < height; y += bh) {
543 const uint8_t *src = src_row;
544
545 for (x = 0; x < width; x+= bw) {
546 etc2_rgb8_parse_block(&block, src);
547
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);
552 dst[3] = 255;
553 dst += comps;
554 }
555 }
556
557 src += bs;
558 }
559
560 src_row += src_stride;
561 }
562 }
563
564 static void
565 etc2_unpack_srgb8(uint8_t *dst_row,
566 unsigned dst_stride,
567 const uint8_t *src_row,
568 unsigned src_stride,
569 unsigned width,
570 unsigned height)
571 {
572 const unsigned bw = 4, bh = 4, bs = 8, comps = 4;
573 struct etc2_block block;
574 unsigned x, y, i, j;
575 uint8_t tmp;
576
577 for (y = 0; y < height; y += bh) {
578 const uint8_t *src = src_row;
579
580 for (x = 0; x < width; x+= bw) {
581 etc2_rgb8_parse_block(&block, src);
582
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 */
588 tmp = dst[0];
589 dst[0] = dst[2];
590 dst[2] = tmp;
591 dst[3] = 255;
592
593 dst += comps;
594 }
595 }
596 src += bs;
597 }
598
599 src_row += src_stride;
600 }
601 }
602
603 static void
604 etc2_unpack_rgba8(uint8_t *dst_row,
605 unsigned dst_stride,
606 const uint8_t *src_row,
607 unsigned src_stride,
608 unsigned width,
609 unsigned height)
610 {
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.
614 */
615 const unsigned bw = 4, bh = 4, bs = 16, comps = 4;
616 struct etc2_block block;
617 unsigned x, y, i, j;
618
619 for (y = 0; y < height; y += bh) {
620 const uint8_t *src = src_row;
621
622 for (x = 0; x < width; x+= bw) {
623 etc2_rgba8_parse_block(&block, src);
624
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);
629 dst += comps;
630 }
631 }
632 src += bs;
633 }
634
635 src_row += src_stride;
636 }
637 }
638
639 static void
640 etc2_unpack_srgb8_alpha8(uint8_t *dst_row,
641 unsigned dst_stride,
642 const uint8_t *src_row,
643 unsigned src_stride,
644 unsigned width,
645 unsigned height)
646 {
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.
650 */
651 const unsigned bw = 4, bh = 4, bs = 16, comps = 4;
652 struct etc2_block block;
653 unsigned x, y, i, j;
654 uint8_t tmp;
655
656 for (y = 0; y < height; y += bh) {
657 const uint8_t *src = src_row;
658
659 for (x = 0; x < width; x+= bw) {
660 etc2_rgba8_parse_block(&block, src);
661
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);
666
667 /* Convert to MESA_FORMAT_SARGB8 */
668 tmp = dst[0];
669 dst[0] = dst[2];
670 dst[2] = tmp;
671 dst[3] = dst[3];
672
673 dst += comps;
674 }
675 }
676 src += bs;
677 }
678
679 src_row += src_stride;
680 }
681 }
682
683 /* ETC2 texture formats are valid in glCompressedTexImage2D and
684 * glCompressedTexSubImage2D functions */
685 GLboolean
686 _mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS)
687 {
688 ASSERT(0);
689
690 return GL_FALSE;
691 }
692
693 GLboolean
694 _mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS)
695 {
696 ASSERT(0);
697
698 return GL_FALSE;
699 }
700
701 GLboolean
702 _mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS)
703 {
704 ASSERT(0);
705
706 return GL_FALSE;
707 }
708
709 GLboolean
710 _mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS)
711 {
712 ASSERT(0);
713
714 return GL_FALSE;
715 }
716
717 void
718 _mesa_fetch_texel_2d_f_etc2_rgb8(const struct swrast_texture_image *texImage,
719 GLint i, GLint j, GLint k, GLfloat *texel)
720 {
721 struct etc2_block block;
722 uint8_t dst[3];
723 const uint8_t *src;
724
725 src = texImage->Map +
726 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
727
728 etc2_rgb8_parse_block(&block, src);
729 etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst);
730
731 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]);
732 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]);
733 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]);
734 texel[ACOMP] = 1.0f;
735 }
736
737 void
738 _mesa_fetch_texel_2d_f_etc2_srgb8(const struct swrast_texture_image *texImage,
739 GLint i, GLint j, GLint k, GLfloat *texel)
740 {
741 struct etc2_block block;
742 uint8_t dst[3];
743 const uint8_t *src;
744
745 src = texImage->Map +
746 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
747
748 etc2_rgb8_parse_block(&block, src);
749 etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst);
750
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]);
754 texel[ACOMP] = 1.0f;
755 }
756
757 void
758 _mesa_fetch_texel_2d_f_etc2_rgba8_eac(const struct swrast_texture_image *texImage,
759 GLint i, GLint j, GLint k, GLfloat *texel)
760 {
761 struct etc2_block block;
762 uint8_t dst[4];
763 const uint8_t *src;
764
765 src = texImage->Map +
766 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16;
767
768 etc2_rgba8_parse_block(&block, src);
769 etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst);
770
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]);
775 }
776
777 void
778 _mesa_fetch_texel_2d_f_etc2_srgb8_alpha8_eac(const struct
779 swrast_texture_image *texImage,
780 GLint i, GLint j,
781 GLint k, GLfloat *texel)
782 {
783 struct etc2_block block;
784 uint8_t dst[4];
785 const uint8_t *src;
786
787 src = texImage->Map +
788 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16;
789
790 etc2_rgba8_parse_block(&block, src);
791 etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst);
792
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]);
797 }
798
799 /**
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`
805 *
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.
808 *
809 * \param src_width in pixels
810 * \param src_height in pixels
811 * \param dst_stride in bytes
812 */
813
814 void
815 _mesa_unpack_etc2_format(uint8_t *dst_row,
816 unsigned dst_stride,
817 const uint8_t *src_row,
818 unsigned src_stride,
819 unsigned src_width,
820 unsigned src_height,
821 gl_format format)
822 {
823 if (format == MESA_FORMAT_ETC2_RGB8)
824 etc2_unpack_rgb8(dst_row, dst_stride,
825 src_row, src_stride,
826 src_width, src_height);
827 else if (format == MESA_FORMAT_ETC2_SRGB8)
828 etc2_unpack_srgb8(dst_row, dst_stride,
829 src_row, src_stride,
830 src_width, src_height);
831 else if (format == MESA_FORMAT_ETC2_RGBA8_EAC)
832 etc2_unpack_rgba8(dst_row, dst_stride,
833 src_row, src_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,
837 src_row, src_stride,
838 src_width, src_height);
839 }