d5a623a464a415a062187977b0fab0b6b3d0f516
[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 * GL_COMPRESSED_SIGNED_R11_EAC
35 * GL_COMPRESSED_SIGNED_RG11_EAC
36 */
37
38 #include <stdbool.h>
39 #include "mfeatures.h"
40 #include "texcompress.h"
41 #include "texcompress_etc.h"
42 #include "texstore.h"
43 #include "macros.h"
44 #include "swrast/s_context.h"
45 #include "format_unpack.h"
46
47 struct etc2_block {
48 int distance;
49 uint64_t pixel_indices[2];
50 const int *modifier_tables[2];
51 bool flipped;
52 bool is_ind_mode;
53 bool is_diff_mode;
54 bool is_t_mode;
55 bool is_h_mode;
56 bool is_planar_mode;
57 uint8_t base_colors[3][3];
58 uint8_t paint_colors[4][3];
59 uint8_t base_codeword;
60 uint8_t multiplier;
61 uint8_t table_index;
62 };
63
64 static const int etc2_distance_table[8] = {
65 3, 6, 11, 16, 23, 32, 41, 64 };
66
67 static const int etc2_modifier_tables[16][8] = {
68 { -3, -6, -9, -15, 2, 5, 8, 14},
69 { -3, -7, -10, -13, 2, 6, 9, 12},
70 { -2, -5, -8, -13, 1, 4, 7, 12},
71 { -2, -4, -6, -13, 1, 3, 5, 12},
72 { -3, -6, -8, -12, 2, 5, 7, 11},
73 { -3, -7, -9, -11, 2, 6, 8, 10},
74 { -4, -7, -8, -11, 3, 6, 7, 10},
75 { -3, -5, -8, -11, 2, 4, 7, 10},
76 { -2, -6, -8, -10, 1, 5, 7, 9},
77 { -2, -5, -8, -10, 1, 4, 7, 9},
78 { -2, -4, -8, -10, 1, 3, 7, 9},
79 { -2, -5, -7, -10, 1, 4, 6, 9},
80 { -3, -4, -7, -10, 2, 3, 6, 9},
81 { -1, -2, -3, -10, 0, 1, 2, 9},
82 { -4, -6, -8, -9, 3, 5, 7, 8},
83 { -3, -5, -7, -9, 2, 4, 6, 8},
84 };
85
86 /* define etc1_parse_block and etc. */
87 #define UINT8_TYPE GLubyte
88 #define TAG(x) x
89 #include "texcompress_etc_tmp.h"
90 #undef TAG
91 #undef UINT8_TYPE
92
93 GLboolean
94 _mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS)
95 {
96 /* GL_ETC1_RGB8_OES is only valid in glCompressedTexImage2D */
97 ASSERT(0);
98
99 return GL_FALSE;
100 }
101
102 void
103 _mesa_fetch_texel_2d_f_etc1_rgb8(const struct swrast_texture_image *texImage,
104 GLint i, GLint j, GLint k, GLfloat *texel)
105 {
106 struct etc1_block block;
107 GLubyte dst[3];
108 const GLubyte *src;
109
110 src = (const GLubyte *) texImage->Map +
111 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
112
113 etc1_parse_block(&block, src);
114 etc1_fetch_texel(&block, i % 4, j % 4, dst);
115
116 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]);
117 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]);
118 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]);
119 texel[ACOMP] = 1.0f;
120 }
121
122 /**
123 * Decode texture data in format `MESA_FORMAT_ETC1_RGB8` to
124 * `MESA_FORMAT_ABGR8888`.
125 *
126 * The size of the source data must be a multiple of the ETC1 block size,
127 * which is 8, even if the texture image's dimensions are not aligned to 4.
128 * From the GL_OES_compressed_ETC1_RGB8_texture spec:
129 * The texture is described as a number of 4x4 pixel blocks. If the
130 * texture (or a particular mip-level) is smaller than 4 pixels in
131 * any dimension (such as a 2x2 or a 8x1 texture), the texture is
132 * found in the upper left part of the block(s), and the rest of the
133 * pixels are not used. For instance, a texture of size 4x2 will be
134 * placed in the upper half of a 4x4 block, and the lower half of the
135 * pixels in the block will not be accessed.
136 *
137 * \param src_width in pixels
138 * \param src_height in pixels
139 * \param dst_stride in bytes
140 */
141 void
142 _mesa_etc1_unpack_rgba8888(uint8_t *dst_row,
143 unsigned dst_stride,
144 const uint8_t *src_row,
145 unsigned src_stride,
146 unsigned src_width,
147 unsigned src_height)
148 {
149 etc1_unpack_rgba8888(dst_row, dst_stride,
150 src_row, src_stride,
151 src_width, src_height);
152 }
153
154 static uint8_t
155 etc2_base_color1_t_mode(const uint8_t *in, GLuint index)
156 {
157 uint8_t R1a = 0, x = 0;
158 /* base col 1 = extend_4to8bits( (R1a << 2) | R1b, G1, B1) */
159 switch(index) {
160 case 0:
161 R1a = (in[0] >> 3) & 0x3;
162 x = ((R1a << 2) | (in[0] & 0x3));
163 break;
164 case 1:
165 x = ((in[1] >> 4) & 0xf);
166 break;
167 case 2:
168 x = (in[1] & 0xf);
169 break;
170 default:
171 /* invalid index */
172 break;
173 }
174 return ((x << 4) | (x & 0xf));
175 }
176
177 static uint8_t
178 etc2_base_color2_t_mode(const uint8_t *in, GLuint index)
179 {
180 uint8_t x = 0;
181 /*extend 4to8bits(R2, G2, B2)*/
182 switch(index) {
183 case 0:
184 x = ((in[2] >> 4) & 0xf );
185 break;
186 case 1:
187 x = (in[2] & 0xf);
188 break;
189 case 2:
190 x = ((in[3] >> 4) & 0xf);
191 break;
192 default:
193 /* invalid index */
194 break;
195 }
196 return ((x << 4) | (x & 0xf));
197 }
198
199 static uint8_t
200 etc2_base_color1_h_mode(const uint8_t *in, GLuint index)
201 {
202 uint8_t x = 0;
203 /* base col 1 = extend 4to8bits(R1, (G1a << 1) | G1b, (B1a << 3) | B1b) */
204 switch(index) {
205 case 0:
206 x = ((in[0] >> 3) & 0xf);
207 break;
208 case 1:
209 x = (((in[0] & 0x7) << 1) | ((in[1] >> 4) & 0x1));
210 break;
211 case 2:
212 x = ((in[1] & 0x8) |
213 (((in[1] & 0x3) << 1) | ((in[2] >> 7) & 0x1)));
214 break;
215 default:
216 /* invalid index */
217 break;
218 }
219 return ((x << 4) | (x & 0xf));
220 }
221
222 static uint8_t
223 etc2_base_color2_h_mode(const uint8_t *in, GLuint index)
224 {
225 uint8_t x = 0;
226 /* base col 2 = extend 4to8bits(R2, G2, B2) */
227 switch(index) {
228 case 0:
229 x = ((in[2] >> 3) & 0xf );
230 break;
231 case 1:
232 x = (((in[2] & 0x7) << 1) | ((in[3] >> 7) & 0x1));
233 break;
234 case 2:
235 x = ((in[3] >> 3) & 0xf);
236 break;
237 default:
238 /* invalid index */
239 break;
240 }
241 return ((x << 4) | (x & 0xf));
242 }
243
244 static uint8_t
245 etc2_base_color_o_planar(const uint8_t *in, GLuint index)
246 {
247 GLuint tmp;
248 switch(index) {
249 case 0:
250 tmp = ((in[0] >> 1) & 0x3f); /* RO */
251 return ((tmp << 2) | (tmp >> 4));
252 case 1:
253 tmp = (((in[0] & 0x1) << 6) | /* GO1 */
254 ((in[1] >> 1) & 0x3f)); /* GO2 */
255 return ((tmp << 1) | (tmp >> 6));
256 case 2:
257 tmp = (((in[1] & 0x1) << 5) | /* BO1 */
258 (in[2] & 0x18) | /* BO2 */
259 (((in[2] & 0x3) << 1) | ((in[3] >> 7) & 0x1))); /* BO3 */
260 return ((tmp << 2) | (tmp >> 4));
261 default:
262 /* invalid index */
263 return 0;
264 }
265 }
266
267 static uint8_t
268 etc2_base_color_h_planar(const uint8_t *in, GLuint index)
269 {
270 GLuint tmp;
271 switch(index) {
272 case 0:
273 tmp = (((in[3] & 0x7c) >> 1) | /* RH1 */
274 (in[3] & 0x1)); /* RH2 */
275 return ((tmp << 2) | (tmp >> 4));
276 case 1:
277 tmp = (in[4] >> 1) & 0x7f; /* GH */
278 return ((tmp << 1) | (tmp >> 6));
279 case 2:
280 tmp = (((in[4] & 0x1) << 5) |
281 ((in[5] >> 3) & 0x1f)); /* BH */
282 return ((tmp << 2) | (tmp >> 4));
283 default:
284 /* invalid index */
285 return 0;
286 }
287 }
288
289 static uint8_t
290 etc2_base_color_v_planar(const uint8_t *in, GLuint index)
291 {
292 GLuint tmp;
293 switch(index) {
294 case 0:
295 tmp = (((in[5] & 0x7) << 0x3) |
296 ((in[6] >> 5) & 0x7)); /* RV */
297 return ((tmp << 2) | (tmp >> 4));
298 case 1:
299 tmp = (((in[6] & 0x1f) << 2) |
300 ((in[7] >> 6) & 0x3)); /* GV */
301 return ((tmp << 1) | (tmp >> 6));
302 case 2:
303 tmp = in[7] & 0x3f; /* BV */
304 return ((tmp << 2) | (tmp >> 4));
305 default:
306 /* invalid index */
307 return 0;
308 }
309 }
310
311 static GLint
312 etc2_get_pixel_index(const struct etc2_block *block, int x, int y)
313 {
314 int bit = ((3 - y) + (3 - x) * 4) * 3;
315 int idx = (block->pixel_indices[1] >> bit) & 0x7;
316 return idx;
317 }
318
319 static uint8_t
320 etc2_clamp(int color)
321 {
322 /* CLAMP(color, 0, 255) */
323 return (uint8_t) CLAMP(color, 0, 255);
324 }
325
326 static GLushort
327 etc2_clamp2(int color)
328 {
329 /* CLAMP(color, 0, 2047) */
330 return (GLushort) CLAMP(color, 0, 2047);
331 }
332
333 static GLshort
334 etc2_clamp3(int color)
335 {
336 /* CLAMP(color, -1023, 1023) */
337 return (GLshort) CLAMP(color, -1023, 1023);
338 }
339
340 static void
341 etc2_rgb8_parse_block(struct etc2_block *block, const uint8_t *src)
342 {
343 unsigned i;
344 GLboolean diffbit = src[3] & 0x2;
345 static const int lookup[8] = { 0, 1, 2, 3, -4, -3, -2, -1 };
346
347 const int R_plus_dR = (src[0] >> 3) + lookup[src[0] & 0x7];
348 const int G_plus_dG = (src[1] >> 3) + lookup[src[1] & 0x7];
349 const int B_plus_dB = (src[2] >> 3) + lookup[src[2] & 0x7];
350
351 /* Reset the mode flags */
352 block->is_ind_mode = false;
353 block->is_diff_mode = false;
354 block->is_t_mode = false;
355 block->is_h_mode = false;
356 block->is_planar_mode = false;
357
358 if (!diffbit) {
359 /* individual mode */
360 block->is_ind_mode = true;
361
362 for (i = 0; i < 3; i++) {
363 /* Texture decode algorithm is same for individual mode in etc1
364 * & etc2.
365 */
366 block->base_colors[0][i] = etc1_base_color_ind_hi(src[i]);
367 block->base_colors[1][i] = etc1_base_color_ind_lo(src[i]);
368 }
369 }
370 else if (R_plus_dR < 0 || R_plus_dR > 31){
371 /* T mode */
372 block->is_t_mode = true;
373
374 for(i = 0; i < 3; i++) {
375 block->base_colors[0][i] = etc2_base_color1_t_mode(src, i);
376 block->base_colors[1][i] = etc2_base_color2_t_mode(src, i);
377 }
378 /* pick distance */
379 block->distance =
380 etc2_distance_table[(((src[3] >> 2) & 0x3) << 1) |
381 (src[3] & 0x1)];
382
383 for (i = 0; i < 3; i++) {
384 block->paint_colors[0][i] = etc2_clamp(block->base_colors[0][i]);
385 block->paint_colors[1][i] = etc2_clamp(block->base_colors[1][i] +
386 block->distance);
387 block->paint_colors[2][i] = etc2_clamp(block->base_colors[1][i]);
388 block->paint_colors[3][i] = etc2_clamp(block->base_colors[1][i] -
389 block->distance);
390 }
391 }
392 else if (G_plus_dG < 0 || G_plus_dG > 31){
393 /* H mode */
394 block->is_h_mode = true;
395 int base_color_1_value, base_color_2_value;
396
397 for(i = 0; i < 3; i++) {
398 block->base_colors[0][i] = etc2_base_color1_h_mode(src, i);
399 block->base_colors[1][i] = etc2_base_color2_h_mode(src, i);
400 }
401
402 base_color_1_value = (block->base_colors[0][0] << 16) +
403 (block->base_colors[0][1] << 8) +
404 block->base_colors[0][2];
405 base_color_2_value = (block->base_colors[1][0] << 16) +
406 (block->base_colors[1][1] << 8) +
407 block->base_colors[1][2];
408 /* pick distance */
409 block->distance =
410 etc2_distance_table[(src[3] & 0x4) |
411 ((src[3] & 0x1) << 1) |
412 (base_color_1_value >= base_color_2_value)];
413
414 for (i = 0; i < 3; i++) {
415 block->paint_colors[0][i] = etc2_clamp(block->base_colors[0][i] +
416 block->distance);
417 block->paint_colors[1][i] = etc2_clamp(block->base_colors[0][i] -
418 block->distance);
419 block->paint_colors[2][i] = etc2_clamp(block->base_colors[1][i] +
420 block->distance);
421 block->paint_colors[3][i] = etc2_clamp(block->base_colors[1][i] -
422 block->distance);
423 }
424 }
425 else if (B_plus_dB < 0 || B_plus_dB > 31){
426 /* Planar mode */
427 block->is_planar_mode = true;
428
429 for (i = 0; i < 3; i++) {
430 block->base_colors[0][i] = etc2_base_color_o_planar(src, i);
431 block->base_colors[1][i] = etc2_base_color_h_planar(src, i);
432 block->base_colors[2][i] = etc2_base_color_v_planar(src, i);
433 }
434 }
435 else if (diffbit) {
436 /* differential mode */
437 block->is_diff_mode = true;
438
439 for (i = 0; i < 3; i++) {
440 /* Texture decode algorithm is same for differential mode in etc1
441 * & etc2.
442 */
443 block->base_colors[0][i] = etc1_base_color_diff_hi(src[i]);
444 block->base_colors[1][i] = etc1_base_color_diff_lo(src[i]);
445 }
446 }
447
448 if (block->is_ind_mode || block->is_diff_mode) {
449 /* pick modifier tables. same for etc1 & etc2 textures */
450 block->modifier_tables[0] = etc1_modifier_tables[(src[3] >> 5) & 0x7];
451 block->modifier_tables[1] = etc1_modifier_tables[(src[3] >> 2) & 0x7];
452 block->flipped = (src[3] & 0x1);
453 }
454
455 block->pixel_indices[0] =
456 (src[4] << 24) | (src[5] << 16) | (src[6] << 8) | src[7];
457 }
458
459 static void
460 etc2_rgb8_fetch_texel(const struct etc2_block *block,
461 int x, int y, uint8_t *dst)
462 {
463 const uint8_t *base_color;
464 int modifier, bit, idx, blk;
465
466 /* get pixel index */
467 bit = y + x * 4;
468 idx = ((block->pixel_indices[0] >> (15 + bit)) & 0x2) |
469 ((block->pixel_indices[0] >> (bit)) & 0x1);
470
471 if (block->is_ind_mode || block->is_diff_mode) {
472 /* Use pixel index and subblock to get the modifier */
473 blk = (block->flipped) ? (y >= 2) : (x >= 2);
474 base_color = block->base_colors[blk];
475 modifier = block->modifier_tables[blk][idx];
476
477 dst[0] = etc2_clamp(base_color[0] + modifier);
478 dst[1] = etc2_clamp(base_color[1] + modifier);
479 dst[2] = etc2_clamp(base_color[2] + modifier);
480 }
481 else if (block->is_t_mode || block->is_h_mode) {
482 /* Use pixel index to pick one of the paint colors */
483 dst[0] = block->paint_colors[idx][0];
484 dst[1] = block->paint_colors[idx][1];
485 dst[2] = block->paint_colors[idx][2];
486 }
487 else if (block->is_planar_mode) {
488 /* {R(x, y) = clamp255((x × (RH − RO) + y × (RV − RO) + 4 × RO + 2) >> 2)
489 * {G(x, y) = clamp255((x × (GH − GO) + y × (GV − GO) + 4 × GO + 2) >> 2)
490 * {B(x, y) = clamp255((x × (BH − BO) + y × (BV − BO) + 4 × BO + 2) >> 2)
491 */
492 int red, green, blue;
493 red = (x * (block->base_colors[1][0] - block->base_colors[0][0]) +
494 y * (block->base_colors[2][0] - block->base_colors[0][0]) +
495 4 * block->base_colors[0][0] + 2) >> 2;
496
497 green = (x * (block->base_colors[1][1] - block->base_colors[0][1]) +
498 y * (block->base_colors[2][1] - block->base_colors[0][1]) +
499 4 * block->base_colors[0][1] + 2) >> 2;
500
501 blue = (x * (block->base_colors[1][2] - block->base_colors[0][2]) +
502 y * (block->base_colors[2][2] - block->base_colors[0][2]) +
503 4 * block->base_colors[0][2] + 2) >> 2;
504
505 dst[0] = etc2_clamp(red);
506 dst[1] = etc2_clamp(green);
507 dst[2] = etc2_clamp(blue);
508 }
509 }
510
511 static void
512 etc2_alpha8_fetch_texel(const struct etc2_block *block,
513 int x, int y, uint8_t *dst)
514 {
515 int modifier, alpha, idx;
516 /* get pixel index */
517 idx = etc2_get_pixel_index(block, x, y);
518 modifier = etc2_modifier_tables[block->table_index][idx];
519 alpha = block->base_codeword + modifier * block->multiplier;
520 dst[3] = etc2_clamp(alpha);
521 }
522
523 static void
524 etc2_r11_fetch_texel(const struct etc2_block *block,
525 int x, int y, uint8_t *dst)
526 {
527 GLint modifier, idx;
528 GLshort color;
529 /* Get pixel index */
530 idx = etc2_get_pixel_index(block, x, y);
531 modifier = etc2_modifier_tables[block->table_index][idx];
532
533 if (block->multiplier != 0)
534 /* clamp2(base codeword × 8 + 4 + modifier × multiplier × 8) */
535 color = etc2_clamp2(((block->base_codeword << 3) | 0x4) +
536 ((modifier * block->multiplier) << 3));
537 else
538 color = etc2_clamp2(((block->base_codeword << 3) | 0x4) + modifier);
539
540 /* Extend 11 bits color value to 16 bits. OpenGL ES 3.0 specification
541 * allows extending the color value to any number of bits. But, an
542 * implementation is not allowed to truncate the 11-bit value to less than
543 * 11 bits."
544 */
545 color = (color << 5) | (color >> 6);
546 ((GLushort *)dst)[0] = color;
547 }
548
549 static void
550 etc2_signed_r11_fetch_texel(const struct etc2_block *block,
551 int x, int y, uint8_t *dst)
552 {
553 GLint modifier, idx;
554 GLshort color;
555 GLbyte base_codeword = (GLbyte) block->base_codeword;
556
557 if (base_codeword == -128)
558 base_codeword = -127;
559
560 /* Get pixel index */
561 idx = etc2_get_pixel_index(block, x, y);
562 modifier = etc2_modifier_tables[block->table_index][idx];
563
564 if (block->multiplier != 0)
565 /* clamp3(base codeword × 8 + modifier × multiplier × 8) */
566 color = etc2_clamp3((base_codeword << 3) +
567 ((modifier * block->multiplier) << 3));
568 else
569 color = etc2_clamp3((base_codeword << 3) + modifier);
570
571 /* Extend 11 bits color value to 16 bits. OpenGL ES 3.0 specification
572 * allows extending the color value to any number of bits. But, an
573 * implementation is not allowed to truncate the 11-bit value to less than
574 * 11 bits. A negative 11-bit value must first be made positive before bit
575 * replication, and then made negative again
576 */
577 if (color >= 0)
578 color = (color << 5) | (color >> 5);
579 else {
580 color = -color;
581 color = (color << 5) | (color >> 5);
582 color = -color;
583 }
584 ((GLshort *)dst)[0] = color;
585 }
586
587 static void
588 etc2_alpha8_parse_block(struct etc2_block *block, const uint8_t *src)
589 {
590 block->base_codeword = src[0];
591 block->multiplier = (src[1] >> 4) & 0xf;
592 block->table_index = src[1] & 0xf;
593 block->pixel_indices[1] = (((uint64_t)src[2] << 40) |
594 ((uint64_t)src[3] << 32) |
595 ((uint64_t)src[4] << 24) |
596 ((uint64_t)src[5] << 16) |
597 ((uint64_t)src[6] << 8) |
598 ((uint64_t)src[7]));
599 }
600
601 static void
602 etc2_r11_parse_block(struct etc2_block *block, const uint8_t *src)
603 {
604 /* Parsing logic remains same as for etc2_alpha8_parse_block */
605 etc2_alpha8_parse_block(block, src);
606 }
607
608 static void
609 etc2_rgba8_parse_block(struct etc2_block *block, const uint8_t *src)
610 {
611 /* RGB component is parsed the same way as for MESA_FORMAT_ETC2_RGB8 */
612 etc2_rgb8_parse_block(block, src + 8);
613
614 /* Parse Alpha component */
615 etc2_alpha8_parse_block(block, src);
616 }
617
618 static void
619 etc2_rgba8_fetch_texel(const struct etc2_block *block,
620 int x, int y, uint8_t *dst)
621 {
622 etc2_rgb8_fetch_texel(block, x, y, dst);
623 etc2_alpha8_fetch_texel(block, x, y, dst);
624 }
625
626 static void
627 etc2_unpack_rgb8(uint8_t *dst_row,
628 unsigned dst_stride,
629 const uint8_t *src_row,
630 unsigned src_stride,
631 unsigned width,
632 unsigned height)
633 {
634 const unsigned bw = 4, bh = 4, bs = 8, comps = 4;
635 struct etc2_block block;
636 unsigned x, y, i, j;
637
638 for (y = 0; y < height; y += bh) {
639 const uint8_t *src = src_row;
640
641 for (x = 0; x < width; x+= bw) {
642 etc2_rgb8_parse_block(&block, src);
643
644 for (j = 0; j < bh; j++) {
645 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
646 for (i = 0; i < bw; i++) {
647 etc2_rgb8_fetch_texel(&block, i, j, dst);
648 dst[3] = 255;
649 dst += comps;
650 }
651 }
652
653 src += bs;
654 }
655
656 src_row += src_stride;
657 }
658 }
659
660 static void
661 etc2_unpack_srgb8(uint8_t *dst_row,
662 unsigned dst_stride,
663 const uint8_t *src_row,
664 unsigned src_stride,
665 unsigned width,
666 unsigned height)
667 {
668 const unsigned bw = 4, bh = 4, bs = 8, comps = 4;
669 struct etc2_block block;
670 unsigned x, y, i, j;
671 uint8_t tmp;
672
673 for (y = 0; y < height; y += bh) {
674 const uint8_t *src = src_row;
675
676 for (x = 0; x < width; x+= bw) {
677 etc2_rgb8_parse_block(&block, src);
678
679 for (j = 0; j < bh; j++) {
680 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
681 for (i = 0; i < bw; i++) {
682 etc2_rgb8_fetch_texel(&block, i, j, dst);
683 /* Convert to MESA_FORMAT_SARGB8 */
684 tmp = dst[0];
685 dst[0] = dst[2];
686 dst[2] = tmp;
687 dst[3] = 255;
688
689 dst += comps;
690 }
691 }
692 src += bs;
693 }
694
695 src_row += src_stride;
696 }
697 }
698
699 static void
700 etc2_unpack_rgba8(uint8_t *dst_row,
701 unsigned dst_stride,
702 const uint8_t *src_row,
703 unsigned src_stride,
704 unsigned width,
705 unsigned height)
706 {
707 /* If internalformat is COMPRESSED_RGBA8_ETC2_EAC, each 4 × 4 block of
708 * RGBA8888 information is compressed to 128 bits. To decode a block, the
709 * two 64-bit integers int64bitAlpha and int64bitColor are calculated.
710 */
711 const unsigned bw = 4, bh = 4, bs = 16, comps = 4;
712 struct etc2_block block;
713 unsigned x, y, i, j;
714
715 for (y = 0; y < height; y += bh) {
716 const uint8_t *src = src_row;
717
718 for (x = 0; x < width; x+= bw) {
719 etc2_rgba8_parse_block(&block, src);
720
721 for (j = 0; j < bh; j++) {
722 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
723 for (i = 0; i < bw; i++) {
724 etc2_rgba8_fetch_texel(&block, i, j, dst);
725 dst += comps;
726 }
727 }
728 src += bs;
729 }
730
731 src_row += src_stride;
732 }
733 }
734
735 static void
736 etc2_unpack_srgb8_alpha8(uint8_t *dst_row,
737 unsigned dst_stride,
738 const uint8_t *src_row,
739 unsigned src_stride,
740 unsigned width,
741 unsigned height)
742 {
743 /* If internalformat is COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, each 4 × 4 block
744 * of RGBA8888 information is compressed to 128 bits. To decode a block, the
745 * two 64-bit integers int64bitAlpha and int64bitColor are calculated.
746 */
747 const unsigned bw = 4, bh = 4, bs = 16, comps = 4;
748 struct etc2_block block;
749 unsigned x, y, i, j;
750 uint8_t tmp;
751
752 for (y = 0; y < height; y += bh) {
753 const uint8_t *src = src_row;
754
755 for (x = 0; x < width; x+= bw) {
756 etc2_rgba8_parse_block(&block, src);
757
758 for (j = 0; j < bh; j++) {
759 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
760 for (i = 0; i < bw; i++) {
761 etc2_rgba8_fetch_texel(&block, i, j, dst);
762
763 /* Convert to MESA_FORMAT_SARGB8 */
764 tmp = dst[0];
765 dst[0] = dst[2];
766 dst[2] = tmp;
767 dst[3] = dst[3];
768
769 dst += comps;
770 }
771 }
772 src += bs;
773 }
774
775 src_row += src_stride;
776 }
777 }
778
779 static void
780 etc2_unpack_r11(uint8_t *dst_row,
781 unsigned dst_stride,
782 const uint8_t *src_row,
783 unsigned src_stride,
784 unsigned width,
785 unsigned height)
786 {
787 /* If internalformat is COMPRESSED_R11_EAC, each 4 × 4 block of
788 color information is compressed to 64 bits.
789 */
790 const unsigned bw = 4, bh = 4, bs = 8, comps = 1, comp_size = 2;
791 struct etc2_block block;
792 unsigned x, y, i, j;
793
794 for (y = 0; y < height; y += bh) {
795 const uint8_t *src = src_row;
796
797 for (x = 0; x < width; x+= bw) {
798 etc2_r11_parse_block(&block, src);
799
800 for (j = 0; j < bh; j++) {
801 uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size;
802 for (i = 0; i < bw; i++) {
803 etc2_r11_fetch_texel(&block, i, j, dst);
804 dst += comps * comp_size;
805 }
806 }
807 src += bs;
808 }
809
810 src_row += src_stride;
811 }
812 }
813
814 static void
815 etc2_unpack_rg11(uint8_t *dst_row,
816 unsigned dst_stride,
817 const uint8_t *src_row,
818 unsigned src_stride,
819 unsigned width,
820 unsigned height)
821 {
822 /* If internalformat is COMPRESSED_RG11_EAC, each 4 × 4 block of
823 RG color information is compressed to 128 bits.
824 */
825 const unsigned bw = 4, bh = 4, bs = 16, comps = 2, comp_size = 2;
826 struct etc2_block block;
827 unsigned x, y, i, j;
828
829 for (y = 0; y < height; y += bh) {
830 const uint8_t *src = src_row;
831
832 for (x = 0; x < width; x+= bw) {
833 /* red component */
834 etc2_r11_parse_block(&block, src);
835
836 for (j = 0; j < bh; j++) {
837 uint8_t *dst = dst_row + (y + j) * dst_stride +
838 x * comps * comp_size;
839 for (i = 0; i < bw; i++) {
840 etc2_r11_fetch_texel(&block, i, j, dst);
841 dst += comps * comp_size;
842 }
843 }
844 /* green component */
845 etc2_r11_parse_block(&block, src + 8);
846
847 for (j = 0; j < bh; j++) {
848 uint8_t *dst = dst_row + (y + j) * dst_stride +
849 x * comps * comp_size;
850 for (i = 0; i < bw; i++) {
851 etc2_r11_fetch_texel(&block, i, j, dst + comp_size);
852 dst += comps * comp_size;
853 }
854 }
855 src += bs;
856 }
857
858 src_row += src_stride;
859 }
860 }
861
862 static void
863 etc2_unpack_signed_r11(uint8_t *dst_row,
864 unsigned dst_stride,
865 const uint8_t *src_row,
866 unsigned src_stride,
867 unsigned width,
868 unsigned height)
869 {
870 /* If internalformat is COMPRESSED_SIGNED_R11_EAC, each 4 × 4 block of
871 red color information is compressed to 64 bits.
872 */
873 const unsigned bw = 4, bh = 4, bs = 8, comps = 1, comp_size = 2;
874 struct etc2_block block;
875 unsigned x, y, i, j;
876
877 for (y = 0; y < height; y += bh) {
878 const uint8_t *src = src_row;
879
880 for (x = 0; x < width; x+= bw) {
881 etc2_r11_parse_block(&block, src);
882
883 for (j = 0; j < bh; j++) {
884 uint8_t *dst = dst_row + (y + j) * dst_stride +
885 x * comps * comp_size;
886 for (i = 0; i < bw; i++) {
887 etc2_signed_r11_fetch_texel(&block, i, j, dst);
888 dst += comps * comp_size;
889 }
890 }
891 src += bs;
892 }
893
894 src_row += src_stride;
895 }
896 }
897
898 static void
899 etc2_unpack_signed_rg11(uint8_t *dst_row,
900 unsigned dst_stride,
901 const uint8_t *src_row,
902 unsigned src_stride,
903 unsigned width,
904 unsigned height)
905 {
906 /* If internalformat is COMPRESSED_SIGNED_RG11_EAC, each 4 × 4 block of
907 RG color information is compressed to 128 bits.
908 */
909 const unsigned bw = 4, bh = 4, bs = 16, comps = 2, comp_size = 2;
910 struct etc2_block block;
911 unsigned x, y, i, j;
912
913 for (y = 0; y < height; y += bh) {
914 const uint8_t *src = src_row;
915
916 for (x = 0; x < width; x+= bw) {
917 /* red component */
918 etc2_r11_parse_block(&block, src);
919
920 for (j = 0; j < bh; j++) {
921 uint8_t *dst = dst_row + (y + j) * dst_stride +
922 x * comps * comp_size;
923 for (i = 0; i < bw; i++) {
924 etc2_signed_r11_fetch_texel(&block, i, j, dst);
925 dst += comps * comp_size;
926 }
927 }
928 /* green component */
929 etc2_r11_parse_block(&block, src + 8);
930
931 for (j = 0; j < bh; j++) {
932 uint8_t *dst = dst_row + (y + j) * dst_stride +
933 x * comps * comp_size;
934 for (i = 0; i < bw; i++) {
935 etc2_signed_r11_fetch_texel(&block, i, j, dst + comp_size);
936 dst += comps * comp_size;
937 }
938 }
939 src += bs;
940 }
941
942 src_row += src_stride;
943 }
944 }
945
946 /* ETC2 texture formats are valid in glCompressedTexImage2D and
947 * glCompressedTexSubImage2D functions */
948 GLboolean
949 _mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS)
950 {
951 ASSERT(0);
952
953 return GL_FALSE;
954 }
955
956 GLboolean
957 _mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS)
958 {
959 ASSERT(0);
960
961 return GL_FALSE;
962 }
963
964 GLboolean
965 _mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS)
966 {
967 ASSERT(0);
968
969 return GL_FALSE;
970 }
971
972 GLboolean
973 _mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS)
974 {
975 ASSERT(0);
976
977 return GL_FALSE;
978 }
979
980 GLboolean
981 _mesa_texstore_etc2_r11_eac(TEXSTORE_PARAMS)
982 {
983 ASSERT(0);
984
985 return GL_FALSE;
986 }
987
988 GLboolean
989 _mesa_texstore_etc2_signed_r11_eac(TEXSTORE_PARAMS)
990 {
991 ASSERT(0);
992
993 return GL_FALSE;
994 }
995
996 GLboolean
997 _mesa_texstore_etc2_rg11_eac(TEXSTORE_PARAMS)
998 {
999 ASSERT(0);
1000
1001 return GL_FALSE;
1002 }
1003
1004 GLboolean
1005 _mesa_texstore_etc2_signed_rg11_eac(TEXSTORE_PARAMS)
1006 {
1007 ASSERT(0);
1008
1009 return GL_FALSE;
1010 }
1011
1012 void
1013 _mesa_fetch_texel_2d_f_etc2_rgb8(const struct swrast_texture_image *texImage,
1014 GLint i, GLint j, GLint k, GLfloat *texel)
1015 {
1016 struct etc2_block block;
1017 uint8_t dst[3];
1018 const uint8_t *src;
1019
1020 src = texImage->Map +
1021 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
1022
1023 etc2_rgb8_parse_block(&block, src);
1024 etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst);
1025
1026 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]);
1027 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]);
1028 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]);
1029 texel[ACOMP] = 1.0f;
1030 }
1031
1032 void
1033 _mesa_fetch_texel_2d_f_etc2_srgb8(const struct swrast_texture_image *texImage,
1034 GLint i, GLint j, GLint k, GLfloat *texel)
1035 {
1036 struct etc2_block block;
1037 uint8_t dst[3];
1038 const uint8_t *src;
1039
1040 src = texImage->Map +
1041 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
1042
1043 etc2_rgb8_parse_block(&block, src);
1044 etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst);
1045
1046 texel[RCOMP] = _mesa_nonlinear_to_linear(dst[0]);
1047 texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]);
1048 texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]);
1049 texel[ACOMP] = 1.0f;
1050 }
1051
1052 void
1053 _mesa_fetch_texel_2d_f_etc2_rgba8_eac(const struct swrast_texture_image *texImage,
1054 GLint i, GLint j, GLint k, GLfloat *texel)
1055 {
1056 struct etc2_block block;
1057 uint8_t dst[4];
1058 const uint8_t *src;
1059
1060 src = texImage->Map +
1061 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16;
1062
1063 etc2_rgba8_parse_block(&block, src);
1064 etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst);
1065
1066 texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]);
1067 texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]);
1068 texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]);
1069 texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]);
1070 }
1071
1072 void
1073 _mesa_fetch_texel_2d_f_etc2_srgb8_alpha8_eac(const struct
1074 swrast_texture_image *texImage,
1075 GLint i, GLint j,
1076 GLint k, GLfloat *texel)
1077 {
1078 struct etc2_block block;
1079 uint8_t dst[4];
1080 const uint8_t *src;
1081
1082 src = texImage->Map +
1083 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16;
1084
1085 etc2_rgba8_parse_block(&block, src);
1086 etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst);
1087
1088 texel[RCOMP] = _mesa_nonlinear_to_linear(dst[0]);
1089 texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]);
1090 texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]);
1091 texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]);
1092 }
1093
1094 void
1095 _mesa_fetch_texel_2d_f_etc2_r11_eac(const struct swrast_texture_image *texImage,
1096 GLint i, GLint j, GLint k, GLfloat *texel)
1097 {
1098 struct etc2_block block;
1099 GLushort dst;
1100 const uint8_t *src;
1101
1102 src = texImage->Map +
1103 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
1104
1105 etc2_r11_parse_block(&block, src);
1106 etc2_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)&dst);
1107
1108 texel[RCOMP] = USHORT_TO_FLOAT(dst);
1109 texel[GCOMP] = 0.0f;
1110 texel[BCOMP] = 0.0f;
1111 texel[ACOMP] = 1.0f;
1112 }
1113
1114 void
1115 _mesa_fetch_texel_2d_f_etc2_rg11_eac(const struct
1116 swrast_texture_image *texImage,
1117 GLint i, GLint j,
1118 GLint k, GLfloat *texel)
1119 {
1120 struct etc2_block block;
1121 GLushort dst[2];
1122 const uint8_t *src;
1123
1124 src = texImage->Map +
1125 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16;
1126
1127 /* red component */
1128 etc2_r11_parse_block(&block, src);
1129 etc2_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)dst);
1130
1131 /* green component */
1132 etc2_r11_parse_block(&block, src + 8);
1133 etc2_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)(dst + 1));
1134
1135 texel[RCOMP] = USHORT_TO_FLOAT(dst[0]);
1136 texel[GCOMP] = USHORT_TO_FLOAT(dst[1]);
1137 texel[BCOMP] = 0.0f;
1138 texel[ACOMP] = 1.0f;
1139 }
1140
1141 void
1142 _mesa_fetch_texel_2d_f_etc2_signed_r11_eac(const struct swrast_texture_image *texImage,
1143 GLint i, GLint j, GLint k, GLfloat *texel)
1144 {
1145 struct etc2_block block;
1146 GLushort dst;
1147 const uint8_t *src;
1148
1149 src = texImage->Map +
1150 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
1151
1152 etc2_r11_parse_block(&block, src);
1153 etc2_signed_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)&dst);
1154
1155 texel[RCOMP] = SHORT_TO_FLOAT(dst);
1156 texel[GCOMP] = 0.0f;
1157 texel[BCOMP] = 0.0f;
1158 texel[ACOMP] = 1.0f;
1159 }
1160
1161 void
1162 _mesa_fetch_texel_2d_f_etc2_signed_rg11_eac(const struct swrast_texture_image *texImage,
1163 GLint i, GLint j, GLint k, GLfloat *texel)
1164 {
1165 struct etc2_block block;
1166 GLushort dst[2];
1167 const uint8_t *src;
1168
1169 src = texImage->Map +
1170 (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16;
1171
1172 /* red component */
1173 etc2_r11_parse_block(&block, src);
1174 etc2_signed_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)dst);
1175
1176 /* green component */
1177 etc2_r11_parse_block(&block, src + 8);
1178 etc2_signed_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)(dst + 1));
1179
1180 texel[RCOMP] = SHORT_TO_FLOAT(dst[0]);
1181 texel[GCOMP] = SHORT_TO_FLOAT(dst[1]);
1182 texel[BCOMP] = 0.0f;
1183 texel[ACOMP] = 1.0f;
1184 }
1185
1186 /**
1187 * Decode texture data in any one of following formats:
1188 * `MESA_FORMAT_ETC2_RGB8`
1189 * `MESA_FORMAT_ETC2_SRGB8`
1190 * `MESA_FORMAT_ETC2_RGBA8_EAC`
1191 * `MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC`
1192 * `MESA_FORMAT_ETC2_R11_EAC`
1193 * `MESA_FORMAT_ETC2_RG11_EAC`
1194 * `MESA_FORMAT_ETC2_SIGNED_R11_EAC`
1195 * `MESA_FORMAT_ETC2_SIGNED_RG11_EAC`
1196 *
1197 * The size of the source data must be a multiple of the ETC2 block size
1198 * even if the texture image's dimensions are not aligned to 4.
1199 *
1200 * \param src_width in pixels
1201 * \param src_height in pixels
1202 * \param dst_stride in bytes
1203 */
1204
1205 void
1206 _mesa_unpack_etc2_format(uint8_t *dst_row,
1207 unsigned dst_stride,
1208 const uint8_t *src_row,
1209 unsigned src_stride,
1210 unsigned src_width,
1211 unsigned src_height,
1212 gl_format format)
1213 {
1214 if (format == MESA_FORMAT_ETC2_RGB8)
1215 etc2_unpack_rgb8(dst_row, dst_stride,
1216 src_row, src_stride,
1217 src_width, src_height);
1218 else if (format == MESA_FORMAT_ETC2_SRGB8)
1219 etc2_unpack_srgb8(dst_row, dst_stride,
1220 src_row, src_stride,
1221 src_width, src_height);
1222 else if (format == MESA_FORMAT_ETC2_RGBA8_EAC)
1223 etc2_unpack_rgba8(dst_row, dst_stride,
1224 src_row, src_stride,
1225 src_width, src_height);
1226 else if (format == MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC)
1227 etc2_unpack_srgb8_alpha8(dst_row, dst_stride,
1228 src_row, src_stride,
1229 src_width, src_height);
1230 else if (format == MESA_FORMAT_ETC2_R11_EAC)
1231 etc2_unpack_r11(dst_row, dst_stride,
1232 src_row, src_stride,
1233 src_width, src_height);
1234 else if (format == MESA_FORMAT_ETC2_RG11_EAC)
1235 etc2_unpack_rg11(dst_row, dst_stride,
1236 src_row, src_stride,
1237 src_width, src_height);
1238 else if (format == MESA_FORMAT_ETC2_SIGNED_R11_EAC)
1239 etc2_unpack_signed_r11(dst_row, dst_stride,
1240 src_row, src_stride,
1241 src_width, src_height);
1242 else if (format == MESA_FORMAT_ETC2_SIGNED_RG11_EAC)
1243 etc2_unpack_signed_rg11(dst_row, dst_stride,
1244 src_row, src_stride,
1245 src_width, src_height);
1246 }