mesa: Add decoding functions for GL_COMPRESSED_RGBA8_ETC2_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 */
32
33 #include <stdbool.h>
34 #include "mfeatures.h"
35 #include "texcompress.h"
36 #include "texcompress_etc.h"
37 #include "texstore.h"
38 #include "macros.h"
39 #include "swrast/s_context.h"
40 #include "format_unpack.h"
41
42 struct etc2_block {
43 int distance;
44 uint64_t pixel_indices[2];
45 const int *modifier_tables[2];
46 bool flipped;
47 bool is_ind_mode;
48 bool is_diff_mode;
49 bool is_t_mode;
50 bool is_h_mode;
51 bool is_planar_mode;
52 uint8_t base_colors[3][3];
53 uint8_t paint_colors[4][3];
54 uint8_t base_codeword;
55 uint8_t multiplier;
56 uint8_t table_index;
57 };
58
59 static const int etc2_distance_table[8] = {
60 3, 6, 11, 16, 23, 32, 41, 64 };
61
62 static const int etc2_modifier_tables[16][8] = {
63 { -3, -6, -9, -15, 2, 5, 8, 14},
64 { -3, -7, -10, -13, 2, 6, 9, 12},
65 { -2, -5, -8, -13, 1, 4, 7, 12},
66 { -2, -4, -6, -13, 1, 3, 5, 12},
67 { -3, -6, -8, -12, 2, 5, 7, 11},
68 { -3, -7, -9, -11, 2, 6, 8, 10},
69 { -4, -7, -8, -11, 3, 6, 7, 10},
70 { -3, -5, -8, -11, 2, 4, 7, 10},
71 { -2, -6, -8, -10, 1, 5, 7, 9},
72 { -2, -5, -8, -10, 1, 4, 7, 9},
73 { -2, -4, -8, -10, 1, 3, 7, 9},
74 { -2, -5, -7, -10, 1, 4, 6, 9},
75 { -3, -4, -7, -10, 2, 3, 6, 9},
76 { -1, -2, -3, -10, 0, 1, 2, 9},
77 { -4, -6, -8, -9, 3, 5, 7, 8},
78 { -3, -5, -7, -9, 2, 4, 6, 8},
79 };
80
81 /* define etc1_parse_block and etc. */
82 #define UINT8_TYPE GLubyte
83 #define TAG(x) x
84 #include "texcompress_etc_tmp.h"
85 #undef TAG
86 #undef UINT8_TYPE
87
88 GLboolean
89 _mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS)
90 {
91 /* GL_ETC1_RGB8_OES is only valid in glCompressedTexImage2D */
92 ASSERT(0);
93
94 return GL_FALSE;
95 }
96
97 void
98 _mesa_fetch_texel_2d_f_etc1_rgb8(const struct swrast_texture_image *texImage,
99 GLint i, GLint j, GLint k, GLfloat *texel)
100 {
101 struct etc1_block block;
102 GLubyte dst[3];
103 const GLubyte *src;
104
105 src = (const GLubyte *) texImage->Map +
106 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
107
108 etc1_parse_block(&block, src);
109 etc1_fetch_texel(&block, i % 4, j % 4, dst);
110
111 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]);
112 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]);
113 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]);
114 texel[ACOMP] = 1.0f;
115 }
116
117 /**
118 * Decode texture data in format `MESA_FORMAT_ETC1_RGB8` to
119 * `MESA_FORMAT_ABGR8888`.
120 *
121 * The size of the source data must be a multiple of the ETC1 block size,
122 * which is 8, even if the texture image's dimensions are not aligned to 4.
123 * From the GL_OES_compressed_ETC1_RGB8_texture spec:
124 * The texture is described as a number of 4x4 pixel blocks. If the
125 * texture (or a particular mip-level) is smaller than 4 pixels in
126 * any dimension (such as a 2x2 or a 8x1 texture), the texture is
127 * found in the upper left part of the block(s), and the rest of the
128 * pixels are not used. For instance, a texture of size 4x2 will be
129 * placed in the upper half of a 4x4 block, and the lower half of the
130 * pixels in the block will not be accessed.
131 *
132 * \param src_width in pixels
133 * \param src_height in pixels
134 * \param dst_stride in bytes
135 */
136 void
137 _mesa_etc1_unpack_rgba8888(uint8_t *dst_row,
138 unsigned dst_stride,
139 const uint8_t *src_row,
140 unsigned src_stride,
141 unsigned src_width,
142 unsigned src_height)
143 {
144 etc1_unpack_rgba8888(dst_row, dst_stride,
145 src_row, src_stride,
146 src_width, src_height);
147 }
148
149 static uint8_t
150 etc2_base_color1_t_mode(const uint8_t *in, GLuint index)
151 {
152 uint8_t R1a = 0, x = 0;
153 /* base col 1 = extend_4to8bits( (R1a << 2) | R1b, G1, B1) */
154 switch(index) {
155 case 0:
156 R1a = (in[0] >> 3) & 0x3;
157 x = ((R1a << 2) | (in[0] & 0x3));
158 break;
159 case 1:
160 x = ((in[1] >> 4) & 0xf);
161 break;
162 case 2:
163 x = (in[1] & 0xf);
164 break;
165 default:
166 /* invalid index */
167 break;
168 }
169 return ((x << 4) | (x & 0xf));
170 }
171
172 static uint8_t
173 etc2_base_color2_t_mode(const uint8_t *in, GLuint index)
174 {
175 uint8_t x = 0;
176 /*extend 4to8bits(R2, G2, B2)*/
177 switch(index) {
178 case 0:
179 x = ((in[2] >> 4) & 0xf );
180 break;
181 case 1:
182 x = (in[2] & 0xf);
183 break;
184 case 2:
185 x = ((in[3] >> 4) & 0xf);
186 break;
187 default:
188 /* invalid index */
189 break;
190 }
191 return ((x << 4) | (x & 0xf));
192 }
193
194 static uint8_t
195 etc2_base_color1_h_mode(const uint8_t *in, GLuint index)
196 {
197 uint8_t x = 0;
198 /* base col 1 = extend 4to8bits(R1, (G1a << 1) | G1b, (B1a << 3) | B1b) */
199 switch(index) {
200 case 0:
201 x = ((in[0] >> 3) & 0xf);
202 break;
203 case 1:
204 x = (((in[0] & 0x7) << 1) | ((in[1] >> 4) & 0x1));
205 break;
206 case 2:
207 x = ((in[1] & 0x8) |
208 (((in[1] & 0x3) << 1) | ((in[2] >> 7) & 0x1)));
209 break;
210 default:
211 /* invalid index */
212 break;
213 }
214 return ((x << 4) | (x & 0xf));
215 }
216
217 static uint8_t
218 etc2_base_color2_h_mode(const uint8_t *in, GLuint index)
219 {
220 uint8_t x = 0;
221 /* base col 2 = extend 4to8bits(R2, G2, B2) */
222 switch(index) {
223 case 0:
224 x = ((in[2] >> 3) & 0xf );
225 break;
226 case 1:
227 x = (((in[2] & 0x7) << 1) | ((in[3] >> 7) & 0x1));
228 break;
229 case 2:
230 x = ((in[3] >> 3) & 0xf);
231 break;
232 default:
233 /* invalid index */
234 break;
235 }
236 return ((x << 4) | (x & 0xf));
237 }
238
239 static uint8_t
240 etc2_base_color_o_planar(const uint8_t *in, GLuint index)
241 {
242 GLuint tmp;
243 switch(index) {
244 case 0:
245 tmp = ((in[0] >> 1) & 0x3f); /* RO */
246 return ((tmp << 2) | (tmp >> 4));
247 case 1:
248 tmp = (((in[0] & 0x1) << 6) | /* GO1 */
249 ((in[1] >> 1) & 0x3f)); /* GO2 */
250 return ((tmp << 1) | (tmp >> 6));
251 case 2:
252 tmp = (((in[1] & 0x1) << 5) | /* BO1 */
253 (in[2] & 0x18) | /* BO2 */
254 (((in[2] & 0x3) << 1) | ((in[3] >> 7) & 0x1))); /* BO3 */
255 return ((tmp << 2) | (tmp >> 4));
256 default:
257 /* invalid index */
258 return 0;
259 }
260 }
261
262 static uint8_t
263 etc2_base_color_h_planar(const uint8_t *in, GLuint index)
264 {
265 GLuint tmp;
266 switch(index) {
267 case 0:
268 tmp = (((in[3] & 0x7c) >> 1) | /* RH1 */
269 (in[3] & 0x1)); /* RH2 */
270 return ((tmp << 2) | (tmp >> 4));
271 case 1:
272 tmp = (in[4] >> 1) & 0x7f; /* GH */
273 return ((tmp << 1) | (tmp >> 6));
274 case 2:
275 tmp = (((in[4] & 0x1) << 5) |
276 ((in[5] >> 3) & 0x1f)); /* BH */
277 return ((tmp << 2) | (tmp >> 4));
278 default:
279 /* invalid index */
280 return 0;
281 }
282 }
283
284 static uint8_t
285 etc2_base_color_v_planar(const uint8_t *in, GLuint index)
286 {
287 GLuint tmp;
288 switch(index) {
289 case 0:
290 tmp = (((in[5] & 0x7) << 0x3) |
291 ((in[6] >> 5) & 0x7)); /* RV */
292 return ((tmp << 2) | (tmp >> 4));
293 case 1:
294 tmp = (((in[6] & 0x1f) << 2) |
295 ((in[7] >> 6) & 0x3)); /* GV */
296 return ((tmp << 1) | (tmp >> 6));
297 case 2:
298 tmp = in[7] & 0x3f; /* BV */
299 return ((tmp << 2) | (tmp >> 4));
300 default:
301 /* invalid index */
302 return 0;
303 }
304 }
305
306 static uint8_t
307 etc2_clamp(int color)
308 {
309 /* CLAMP(color, 0, 255) */
310 return (uint8_t) CLAMP(color, 0, 255);
311 }
312
313 static void
314 etc2_rgb8_parse_block(struct etc2_block *block, const uint8_t *src)
315 {
316 unsigned i;
317 GLboolean diffbit = src[3] & 0x2;
318 static const int lookup[8] = { 0, 1, 2, 3, -4, -3, -2, -1 };
319
320 const int R_plus_dR = (src[0] >> 3) + lookup[src[0] & 0x7];
321 const int G_plus_dG = (src[1] >> 3) + lookup[src[1] & 0x7];
322 const int B_plus_dB = (src[2] >> 3) + lookup[src[2] & 0x7];
323
324 /* Reset the mode flags */
325 block->is_ind_mode = false;
326 block->is_diff_mode = false;
327 block->is_t_mode = false;
328 block->is_h_mode = false;
329 block->is_planar_mode = false;
330
331 if (!diffbit) {
332 /* individual mode */
333 block->is_ind_mode = true;
334
335 for (i = 0; i < 3; i++) {
336 /* Texture decode algorithm is same for individual mode in etc1
337 * & etc2.
338 */
339 block->base_colors[0][i] = etc1_base_color_ind_hi(src[i]);
340 block->base_colors[1][i] = etc1_base_color_ind_lo(src[i]);
341 }
342 }
343 else if (R_plus_dR < 0 || R_plus_dR > 31){
344 /* T mode */
345 block->is_t_mode = true;
346
347 for(i = 0; i < 3; i++) {
348 block->base_colors[0][i] = etc2_base_color1_t_mode(src, i);
349 block->base_colors[1][i] = etc2_base_color2_t_mode(src, i);
350 }
351 /* pick distance */
352 block->distance =
353 etc2_distance_table[(((src[3] >> 2) & 0x3) << 1) |
354 (src[3] & 0x1)];
355
356 for (i = 0; i < 3; i++) {
357 block->paint_colors[0][i] = etc2_clamp(block->base_colors[0][i]);
358 block->paint_colors[1][i] = etc2_clamp(block->base_colors[1][i] +
359 block->distance);
360 block->paint_colors[2][i] = etc2_clamp(block->base_colors[1][i]);
361 block->paint_colors[3][i] = etc2_clamp(block->base_colors[1][i] -
362 block->distance);
363 }
364 }
365 else if (G_plus_dG < 0 || G_plus_dG > 31){
366 /* H mode */
367 block->is_h_mode = true;
368 int base_color_1_value, base_color_2_value;
369
370 for(i = 0; i < 3; i++) {
371 block->base_colors[0][i] = etc2_base_color1_h_mode(src, i);
372 block->base_colors[1][i] = etc2_base_color2_h_mode(src, i);
373 }
374
375 base_color_1_value = (block->base_colors[0][0] << 16) +
376 (block->base_colors[0][1] << 8) +
377 block->base_colors[0][2];
378 base_color_2_value = (block->base_colors[1][0] << 16) +
379 (block->base_colors[1][1] << 8) +
380 block->base_colors[1][2];
381 /* pick distance */
382 block->distance =
383 etc2_distance_table[(src[3] & 0x4) |
384 ((src[3] & 0x1) << 1) |
385 (base_color_1_value >= base_color_2_value)];
386
387 for (i = 0; i < 3; i++) {
388 block->paint_colors[0][i] = etc2_clamp(block->base_colors[0][i] +
389 block->distance);
390 block->paint_colors[1][i] = etc2_clamp(block->base_colors[0][i] -
391 block->distance);
392 block->paint_colors[2][i] = etc2_clamp(block->base_colors[1][i] +
393 block->distance);
394 block->paint_colors[3][i] = etc2_clamp(block->base_colors[1][i] -
395 block->distance);
396 }
397 }
398 else if (B_plus_dB < 0 || B_plus_dB > 31){
399 /* Planar mode */
400 block->is_planar_mode = true;
401
402 for (i = 0; i < 3; i++) {
403 block->base_colors[0][i] = etc2_base_color_o_planar(src, i);
404 block->base_colors[1][i] = etc2_base_color_h_planar(src, i);
405 block->base_colors[2][i] = etc2_base_color_v_planar(src, i);
406 }
407 }
408 else if (diffbit) {
409 /* differential mode */
410 block->is_diff_mode = true;
411
412 for (i = 0; i < 3; i++) {
413 /* Texture decode algorithm is same for differential mode in etc1
414 * & etc2.
415 */
416 block->base_colors[0][i] = etc1_base_color_diff_hi(src[i]);
417 block->base_colors[1][i] = etc1_base_color_diff_lo(src[i]);
418 }
419 }
420
421 if (block->is_ind_mode || block->is_diff_mode) {
422 /* pick modifier tables. same for etc1 & etc2 textures */
423 block->modifier_tables[0] = etc1_modifier_tables[(src[3] >> 5) & 0x7];
424 block->modifier_tables[1] = etc1_modifier_tables[(src[3] >> 2) & 0x7];
425 block->flipped = (src[3] & 0x1);
426 }
427
428 block->pixel_indices[0] =
429 (src[4] << 24) | (src[5] << 16) | (src[6] << 8) | src[7];
430 }
431
432 static void
433 etc2_rgb8_fetch_texel(const struct etc2_block *block,
434 int x, int y, uint8_t *dst)
435 {
436 const uint8_t *base_color;
437 int modifier, bit, idx, blk;
438
439 /* get pixel index */
440 bit = y + x * 4;
441 idx = ((block->pixel_indices[0] >> (15 + bit)) & 0x2) |
442 ((block->pixel_indices[0] >> (bit)) & 0x1);
443
444 if (block->is_ind_mode || block->is_diff_mode) {
445 /* Use pixel index and subblock to get the modifier */
446 blk = (block->flipped) ? (y >= 2) : (x >= 2);
447 base_color = block->base_colors[blk];
448 modifier = block->modifier_tables[blk][idx];
449
450 dst[0] = etc2_clamp(base_color[0] + modifier);
451 dst[1] = etc2_clamp(base_color[1] + modifier);
452 dst[2] = etc2_clamp(base_color[2] + modifier);
453 }
454 else if (block->is_t_mode || block->is_h_mode) {
455 /* Use pixel index to pick one of the paint colors */
456 dst[0] = block->paint_colors[idx][0];
457 dst[1] = block->paint_colors[idx][1];
458 dst[2] = block->paint_colors[idx][2];
459 }
460 else if (block->is_planar_mode) {
461 /* {R(x, y) = clamp255((x × (RH − RO) + y × (RV − RO) + 4 × RO + 2) >> 2)
462 * {G(x, y) = clamp255((x × (GH − GO) + y × (GV − GO) + 4 × GO + 2) >> 2)
463 * {B(x, y) = clamp255((x × (BH − BO) + y × (BV − BO) + 4 × BO + 2) >> 2)
464 */
465 int red, green, blue;
466 red = (x * (block->base_colors[1][0] - block->base_colors[0][0]) +
467 y * (block->base_colors[2][0] - block->base_colors[0][0]) +
468 4 * block->base_colors[0][0] + 2) >> 2;
469
470 green = (x * (block->base_colors[1][1] - block->base_colors[0][1]) +
471 y * (block->base_colors[2][1] - block->base_colors[0][1]) +
472 4 * block->base_colors[0][1] + 2) >> 2;
473
474 blue = (x * (block->base_colors[1][2] - block->base_colors[0][2]) +
475 y * (block->base_colors[2][2] - block->base_colors[0][2]) +
476 4 * block->base_colors[0][2] + 2) >> 2;
477
478 dst[0] = etc2_clamp(red);
479 dst[1] = etc2_clamp(green);
480 dst[2] = etc2_clamp(blue);
481 }
482 }
483
484 static void
485 etc2_alpha8_fetch_texel(const struct etc2_block *block,
486 int x, int y, uint8_t *dst)
487 {
488 int modifier, alpha, bit, idx;
489 /* get pixel index */
490 bit = ((3 - y) + (3 - x) * 4) * 3;
491 idx = (block->pixel_indices[1] >> bit) & 0x7;
492 modifier = etc2_modifier_tables[block->table_index][idx];
493 alpha = block->base_codeword + modifier * block->multiplier;
494 dst[3] = etc2_clamp(alpha);
495 }
496
497 static void
498 etc2_alpha8_parse_block(struct etc2_block *block, const uint8_t *src)
499 {
500 block->base_codeword = src[0];
501 block->multiplier = (src[1] >> 4) & 0xf;
502 block->table_index = src[1] & 0xf;
503 block->pixel_indices[1] = (((uint64_t)src[2] << 40) |
504 ((uint64_t)src[3] << 32) |
505 ((uint64_t)src[4] << 24) |
506 ((uint64_t)src[5] << 16) |
507 ((uint64_t)src[6] << 8) |
508 ((uint64_t)src[7]));
509 }
510
511 static void
512 etc2_rgba8_parse_block(struct etc2_block *block, const uint8_t *src)
513 {
514 /* RGB component is parsed the same way as for MESA_FORMAT_ETC2_RGB8 */
515 etc2_rgb8_parse_block(block, src + 8);
516
517 /* Parse Alpha component */
518 etc2_alpha8_parse_block(block, src);
519 }
520
521 static void
522 etc2_rgba8_fetch_texel(const struct etc2_block *block,
523 int x, int y, uint8_t *dst)
524 {
525 etc2_rgb8_fetch_texel(block, x, y, dst);
526 etc2_alpha8_fetch_texel(block, x, y, dst);
527 }
528
529 static void
530 etc2_unpack_rgb8(uint8_t *dst_row,
531 unsigned dst_stride,
532 const uint8_t *src_row,
533 unsigned src_stride,
534 unsigned width,
535 unsigned height)
536 {
537 const unsigned bw = 4, bh = 4, bs = 8, comps = 4;
538 struct etc2_block block;
539 unsigned x, y, i, j;
540
541 for (y = 0; y < height; y += bh) {
542 const uint8_t *src = src_row;
543
544 for (x = 0; x < width; x+= bw) {
545 etc2_rgb8_parse_block(&block, src);
546
547 for (j = 0; j < bh; j++) {
548 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
549 for (i = 0; i < bw; i++) {
550 etc2_rgb8_fetch_texel(&block, i, j, dst);
551 dst[3] = 255;
552 dst += comps;
553 }
554 }
555
556 src += bs;
557 }
558
559 src_row += src_stride;
560 }
561 }
562
563 static void
564 etc2_unpack_srgb8(uint8_t *dst_row,
565 unsigned dst_stride,
566 const uint8_t *src_row,
567 unsigned src_stride,
568 unsigned width,
569 unsigned height)
570 {
571 const unsigned bw = 4, bh = 4, bs = 8, comps = 4;
572 struct etc2_block block;
573 unsigned x, y, i, j;
574 uint8_t tmp;
575
576 for (y = 0; y < height; y += bh) {
577 const uint8_t *src = src_row;
578
579 for (x = 0; x < width; x+= bw) {
580 etc2_rgb8_parse_block(&block, src);
581
582 for (j = 0; j < bh; j++) {
583 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
584 for (i = 0; i < bw; i++) {
585 etc2_rgb8_fetch_texel(&block, i, j, dst);
586 /* Convert to MESA_FORMAT_SARGB8 */
587 tmp = dst[0];
588 dst[0] = dst[2];
589 dst[2] = tmp;
590 dst[3] = 255;
591
592 dst += comps;
593 }
594 }
595 src += bs;
596 }
597
598 src_row += src_stride;
599 }
600 }
601
602 static void
603 etc2_unpack_rgba8(uint8_t *dst_row,
604 unsigned dst_stride,
605 const uint8_t *src_row,
606 unsigned src_stride,
607 unsigned width,
608 unsigned height)
609 {
610 /* If internalformat is COMPRESSED_RGBA8_ETC2_EAC, each 4 × 4 block of
611 * RGBA8888 information is compressed to 128 bits. To decode a block, the
612 * two 64-bit integers int64bitAlpha and int64bitColor are calculated.
613 */
614 const unsigned bw = 4, bh = 4, bs = 16, comps = 4;
615 struct etc2_block block;
616 unsigned x, y, i, j;
617
618 for (y = 0; y < height; y += bh) {
619 const uint8_t *src = src_row;
620
621 for (x = 0; x < width; x+= bw) {
622 etc2_rgba8_parse_block(&block, src);
623
624 for (j = 0; j < bh; j++) {
625 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
626 for (i = 0; i < bw; i++) {
627 etc2_rgba8_fetch_texel(&block, i, j, dst);
628 dst += comps;
629 }
630 }
631 src += bs;
632 }
633
634 src_row += src_stride;
635 }
636 }
637
638 /* ETC2 texture formats are valid in glCompressedTexImage2D and
639 * glCompressedTexSubImage2D functions */
640 GLboolean
641 _mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS)
642 {
643 ASSERT(0);
644
645 return GL_FALSE;
646 }
647
648 GLboolean
649 _mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS)
650 {
651 ASSERT(0);
652
653 return GL_FALSE;
654 }
655
656 GLboolean
657 _mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS)
658 {
659 ASSERT(0);
660
661 return GL_FALSE;
662 }
663
664 void
665 _mesa_fetch_texel_2d_f_etc2_rgb8(const struct swrast_texture_image *texImage,
666 GLint i, GLint j, GLint k, GLfloat *texel)
667 {
668 struct etc2_block block;
669 uint8_t dst[3];
670 const uint8_t *src;
671
672 src = texImage->Map +
673 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
674
675 etc2_rgb8_parse_block(&block, src);
676 etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst);
677
678 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]);
679 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]);
680 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]);
681 texel[ACOMP] = 1.0f;
682 }
683
684 void
685 _mesa_fetch_texel_2d_f_etc2_srgb8(const struct swrast_texture_image *texImage,
686 GLint i, GLint j, GLint k, GLfloat *texel)
687 {
688 struct etc2_block block;
689 uint8_t dst[3];
690 const uint8_t *src;
691
692 src = texImage->Map +
693 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
694
695 etc2_rgb8_parse_block(&block, src);
696 etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst);
697
698 texel[RCOMP] = _mesa_nonlinear_to_linear(dst[0]);
699 texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]);
700 texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]);
701 texel[ACOMP] = 1.0f;
702 }
703
704 void
705 _mesa_fetch_texel_2d_f_etc2_rgba8_eac(const struct swrast_texture_image *texImage,
706 GLint i, GLint j, GLint k, GLfloat *texel)
707 {
708 struct etc2_block block;
709 uint8_t dst[4];
710 const uint8_t *src;
711
712 src = texImage->Map +
713 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16;
714
715 etc2_rgba8_parse_block(&block, src);
716 etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst);
717
718 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]);
719 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]);
720 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]);
721 texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]);
722 }
723
724 /**
725 * Decode texture data in any one of following formats:
726 * `MESA_FORMAT_ETC2_RGB8`
727 * `MESA_FORMAT_ETC2_SRGB8`
728 * `MESA_FORMAT_ETC2_RGBA8_EAC`
729 *
730 * The size of the source data must be a multiple of the ETC2 block size
731 * even if the texture image's dimensions are not aligned to 4.
732 *
733 * \param src_width in pixels
734 * \param src_height in pixels
735 * \param dst_stride in bytes
736 */
737
738 void
739 _mesa_unpack_etc2_format(uint8_t *dst_row,
740 unsigned dst_stride,
741 const uint8_t *src_row,
742 unsigned src_stride,
743 unsigned src_width,
744 unsigned src_height,
745 gl_format format)
746 {
747 if (format == MESA_FORMAT_ETC2_RGB8)
748 etc2_unpack_rgb8(dst_row, dst_stride,
749 src_row, src_stride,
750 src_width, src_height);
751 else if (format == MESA_FORMAT_ETC2_SRGB8)
752 etc2_unpack_srgb8(dst_row, dst_stride,
753 src_row, src_stride,
754 src_width, src_height);
755 else if (format == MESA_FORMAT_ETC2_RGBA8_EAC)
756 etc2_unpack_rgba8(dst_row, dst_stride,
757 src_row, src_stride,
758 src_width, src_height);
759 }