8a5e6f0c43744452ed52d4bbfa2fa45c55dae2ea
[mesa.git] / src / gallium / auxiliary / util / u_format_s3tc.c
1 /**************************************************************************
2 *
3 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
4 * Copyright (c) 2008 VMware, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 **************************************************************************/
24
25 #include "u_dl.h"
26 #include "u_math.h"
27 #include "u_format.h"
28 #include "u_format_s3tc.h"
29
30
31 #if defined(_WIN32) || defined(WIN32)
32 #define DXTN_LIBNAME "dxtn.dll"
33 #else
34 #define DXTN_LIBNAME "libtxc_dxtn.so"
35 #endif
36
37 static void
38 util_format_dxt1_rgb_fetch_stub( int src_stride,
39 const uint8_t *src,
40 int col, int row,
41 uint8_t *dst )
42 {
43 util_format_s3tc_init();
44 util_format_dxt1_rgb_fetch(src_stride, src, col, row, dst);
45 }
46
47 static void
48 util_format_dxt1_rgba_fetch_stub( int src_stride,
49 const uint8_t *src,
50 int col, int row,
51 uint8_t *dst )
52 {
53 util_format_s3tc_init();
54 util_format_dxt1_rgba_fetch(src_stride, src, col, row, dst);
55 }
56
57 static void
58 util_format_dxt3_rgba_fetch_stub( int src_stride,
59 const uint8_t *src,
60 int col, int row,
61 uint8_t *dst )
62 {
63 util_format_s3tc_init();
64 util_format_dxt3_rgba_fetch(src_stride, src, col, row, dst);
65 }
66
67 static void
68 util_format_dxt5_rgba_fetch_stub( int src_stride,
69 const uint8_t *src,
70 int col, int row,
71 uint8_t *dst )
72 {
73 util_format_s3tc_init();
74 util_format_dxt5_rgba_fetch(src_stride, src, col, row, dst);
75 }
76
77 static
78 void util_format_dxtn_pack_stub( int src_comps,
79 int width, int height,
80 const uint8_t *src,
81 enum util_format_dxtn dst_format,
82 uint8_t *dst,
83 int dst_stride)
84 {
85 util_format_s3tc_init();
86 util_format_dxtn_pack_stub(src_comps, width, height, src, dst_format, dst, dst_stride);
87 }
88
89 boolean util_format_s3tc_enabled = FALSE;
90 boolean util_format_s3tc_inited = FALSE;
91
92 util_format_dxtn_fetch_t util_format_dxt1_rgb_fetch = util_format_dxt1_rgb_fetch_stub;
93 util_format_dxtn_fetch_t util_format_dxt1_rgba_fetch = util_format_dxt1_rgba_fetch_stub;
94 util_format_dxtn_fetch_t util_format_dxt3_rgba_fetch = util_format_dxt3_rgba_fetch_stub;
95 util_format_dxtn_fetch_t util_format_dxt5_rgba_fetch = util_format_dxt5_rgba_fetch_stub;
96
97 util_format_dxtn_pack_t util_format_dxtn_pack = util_format_dxtn_pack_stub;
98
99 static void
100 nop(void)
101 {}
102
103 #define is_nop(f) ((void*)(f) == (void*)nop)
104
105 static util_dl_proc
106 get_proc_address_or_nop(struct util_dl_library *library,
107 const char *procname)
108 {
109 if(library) {
110 util_dl_proc proc = util_dl_get_proc_address(library, procname);
111 if(proc)
112 return proc;
113 }
114 return (util_dl_proc)nop;
115 }
116
117 void
118 util_format_s3tc_do_init(void)
119 {
120 struct util_dl_library *library;
121
122 library = util_dl_open(DXTN_LIBNAME);
123 util_format_dxt1_rgb_fetch = (util_format_dxtn_fetch_t)
124 get_proc_address_or_nop(library, "fetch_2d_texel_rgb_dxt1");
125 util_format_dxt1_rgba_fetch = (util_format_dxtn_fetch_t)
126 get_proc_address_or_nop(library, "fetch_2d_texel_rgba_dxt1");
127 util_format_dxt3_rgba_fetch = (util_format_dxtn_fetch_t)
128 get_proc_address_or_nop(library, "fetch_2d_texel_rgba_dxt3");
129 util_format_dxt5_rgba_fetch = (util_format_dxtn_fetch_t)
130 get_proc_address_or_nop(library, "fetch_2d_texel_rgba_dxt5");
131 util_format_dxtn_pack = (util_format_dxtn_pack_t)
132 get_proc_address_or_nop(library, "tx_compress_dxtn");
133
134 if (!library)
135 debug_printf("couldn't open " DXTN_LIBNAME ", software DXTn "
136 "compression/decompression unavailable");
137 else {
138 if (!is_nop(util_format_dxt1_rgb_fetch) &&
139 !is_nop(util_format_dxt1_rgba_fetch) &&
140 !is_nop(util_format_dxt3_rgba_fetch) &&
141 !is_nop(util_format_dxt5_rgba_fetch) &&
142 !is_nop(util_format_dxtn_pack)) {
143 debug_printf("software DXTn compression/decompression available");
144 util_format_s3tc_enabled = TRUE;
145 } else
146 debug_printf("couldn't reference all symbols in "
147 DXTN_LIBNAME ", software DXTn compression/decompression "
148 "unavailable");
149 }
150 }
151
152
153 /*
154 * Pixel fetch.
155 */
156
157 void
158 util_format_dxt1_rgb_fetch_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
159 {
160 util_format_dxt1_rgb_fetch(0, src, i, j, dst);
161 }
162
163 void
164 util_format_dxt1_rgba_fetch_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
165 {
166 util_format_dxt1_rgba_fetch(0, src, i, j, dst);
167 }
168
169 void
170 util_format_dxt3_rgba_fetch_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
171 {
172 util_format_dxt3_rgba_fetch(0, src, i, j, dst);
173 }
174
175 void
176 util_format_dxt5_rgba_fetch_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
177 {
178 util_format_dxt5_rgba_fetch(0, src, i, j, dst);
179 }
180
181 void
182 util_format_dxt1_rgb_fetch_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
183 {
184 uint8_t tmp[4];
185 util_format_dxt1_rgb_fetch(0, src, i, j, tmp);
186 dst[0] = ubyte_to_float(tmp[0]);
187 dst[1] = ubyte_to_float(tmp[1]);
188 dst[2] = ubyte_to_float(tmp[2]);
189 dst[3] = 1.0;
190 }
191
192 void
193 util_format_dxt1_rgba_fetch_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
194 {
195 uint8_t tmp[4];
196 util_format_dxt1_rgba_fetch(0, src, i, j, tmp);
197 dst[0] = ubyte_to_float(tmp[0]);
198 dst[1] = ubyte_to_float(tmp[1]);
199 dst[2] = ubyte_to_float(tmp[2]);
200 dst[3] = ubyte_to_float(tmp[3]);
201 }
202
203 void
204 util_format_dxt3_rgba_fetch_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
205 {
206 uint8_t tmp[4];
207 util_format_dxt3_rgba_fetch(0, src, i, j, tmp);
208 dst[0] = ubyte_to_float(tmp[0]);
209 dst[1] = ubyte_to_float(tmp[1]);
210 dst[2] = ubyte_to_float(tmp[2]);
211 dst[3] = ubyte_to_float(tmp[3]);
212 }
213
214 void
215 util_format_dxt5_rgba_fetch_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
216 {
217 uint8_t tmp[4];
218 util_format_dxt5_rgba_fetch(0, src, i, j, tmp);
219 dst[0] = ubyte_to_float(tmp[0]);
220 dst[1] = ubyte_to_float(tmp[1]);
221 dst[2] = ubyte_to_float(tmp[2]);
222 dst[3] = ubyte_to_float(tmp[3]);
223 }
224
225
226 /*
227 * Block decompression.
228 */
229
230 void
231 util_format_dxt1_rgb_unpack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
232 {
233 if (!is_nop(util_format_dxt1_rgb_fetch)) {
234 unsigned x, y, i, j;
235 for(y = 0; y < height; y += 4) {
236 const uint8_t *src = src_row;
237 for(x = 0; x < width; x += 4) {
238 for(j = 0; j < 4; ++j) {
239 for(i = 0; i < 4; ++i) {
240 uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
241 util_format_dxt1_rgb_fetch(0, src, i, j, dst);
242 }
243 }
244 src += 8;
245 }
246 src_row += src_stride;
247 }
248 }
249 }
250
251 void
252 util_format_dxt1_rgba_unpack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
253 {
254 if (!is_nop(util_format_dxt1_rgba_fetch)) {
255 unsigned x, y, i, j;
256 for(y = 0; y < height; y += 4) {
257 const uint8_t *src = src_row;
258 for(x = 0; x < width; x += 4) {
259 for(j = 0; j < 4; ++j) {
260 for(i = 0; i < 4; ++i) {
261 uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
262 util_format_dxt1_rgba_fetch(0, src, i, j, dst);
263 }
264 }
265 src += 8;
266 }
267 src_row += src_stride;
268 }
269 }
270 }
271
272 void
273 util_format_dxt3_rgba_unpack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
274 {
275 if (!is_nop(util_format_dxt3_rgba_fetch)) {
276 unsigned x, y, i, j;
277 for(y = 0; y < height; y += 4) {
278 const uint8_t *src = src_row;
279 for(x = 0; x < width; x += 4) {
280 for(j = 0; j < 4; ++j) {
281 for(i = 0; i < 4; ++i) {
282 uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
283 util_format_dxt3_rgba_fetch(0, src, i, j, dst);
284 }
285 }
286 src += 16;
287 }
288 src_row += src_stride;
289 }
290 }
291 }
292
293 void
294 util_format_dxt5_rgba_unpack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
295 {
296 if (is_nop(util_format_dxt5_rgba_fetch)) {
297 unsigned x, y, i, j;
298 for(y = 0; y < height; y += 4) {
299 const uint8_t *src = src_row;
300 for(x = 0; x < width; x += 4) {
301 for(j = 0; j < 4; ++j) {
302 for(i = 0; i < 4; ++i) {
303 uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
304 util_format_dxt5_rgba_fetch(0, src, i, j, dst);
305 }
306 }
307 src += 16;
308 }
309 src_row += src_stride;
310 }
311 }
312 }
313
314 void
315 util_format_dxt1_rgb_unpack_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
316 {
317 if (is_nop(util_format_dxt1_rgb_fetch)) {
318 unsigned x, y, i, j;
319 for(y = 0; y < height; y += 4) {
320 const uint8_t *src = src_row;
321 for(x = 0; x < width; x += 4) {
322 for(j = 0; j < 4; ++j) {
323 for(i = 0; i < 4; ++i) {
324 float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
325 uint8_t tmp[4];
326 util_format_dxt1_rgb_fetch(0, src, i, j, tmp);
327 dst[0] = ubyte_to_float(tmp[0]);
328 dst[1] = ubyte_to_float(tmp[1]);
329 dst[2] = ubyte_to_float(tmp[2]);
330 dst[3] = 1.0;
331 }
332 }
333 src += 8;
334 }
335 src_row += src_stride;
336 }
337 }
338 }
339
340 void
341 util_format_dxt1_rgba_unpack_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
342 {
343 if (!is_nop(util_format_dxt1_rgba_fetch)) {
344 unsigned x, y, i, j;
345 for(y = 0; y < height; y += 4) {
346 const uint8_t *src = src_row;
347 for(x = 0; x < width; x += 4) {
348 for(j = 0; j < 4; ++j) {
349 for(i = 0; i < 4; ++i) {
350 float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
351 uint8_t tmp[4];
352 util_format_dxt1_rgba_fetch(0, src, i, j, tmp);
353 dst[0] = ubyte_to_float(tmp[0]);
354 dst[1] = ubyte_to_float(tmp[1]);
355 dst[2] = ubyte_to_float(tmp[2]);
356 dst[3] = ubyte_to_float(tmp[3]);
357 }
358 }
359 src += 8;
360 }
361 src_row += src_stride;
362 }
363 }
364 }
365
366 void
367 util_format_dxt3_rgba_unpack_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
368 {
369 if (!is_nop(util_format_dxt3_rgba_fetch)) {
370 unsigned x, y, i, j;
371 for(y = 0; y < height; y += 4) {
372 const uint8_t *src = src_row;
373 for(x = 0; x < width; x += 4) {
374 for(j = 0; j < 4; ++j) {
375 for(i = 0; i < 4; ++i) {
376 float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
377 uint8_t tmp[4];
378 util_format_dxt3_rgba_fetch(0, src, i, j, tmp);
379 dst[0] = ubyte_to_float(tmp[0]);
380 dst[1] = ubyte_to_float(tmp[1]);
381 dst[2] = ubyte_to_float(tmp[2]);
382 dst[3] = ubyte_to_float(tmp[3]);
383 }
384 }
385 src += 16;
386 }
387 src_row += src_stride;
388 }
389 }
390 }
391
392 void
393 util_format_dxt5_rgba_unpack_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
394 {
395 if (!is_nop(util_format_dxt5_rgba_fetch)) {
396 unsigned x, y, i, j;
397 for(y = 0; y < height; y += 4) {
398 const uint8_t *src = src_row;
399 for(x = 0; x < width; x += 4) {
400 for(j = 0; j < 4; ++j) {
401 for(i = 0; i < 4; ++i) {
402 float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
403 uint8_t tmp[4];
404 util_format_dxt5_rgba_fetch(0, src, i, j, tmp);
405 dst[0] = ubyte_to_float(tmp[0]);
406 dst[1] = ubyte_to_float(tmp[1]);
407 dst[2] = ubyte_to_float(tmp[2]);
408 dst[3] = ubyte_to_float(tmp[3]);
409 }
410 }
411 src += 16;
412 }
413 src_row += src_stride;
414 }
415 }
416 }
417
418
419 /*
420 * Block compression.
421 */
422
423 void
424 util_format_dxt1_rgb_pack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
425 {
426 if (!is_nop(util_format_dxtn_pack)) {
427 unsigned x, y, i, j, k;
428 for(y = 0; y < height; y += 4) {
429 const uint8_t *src = src_row;
430 uint8_t *dst = dst_row;
431 for(x = 0; x < width; x += 4) {
432 uint8_t tmp[4][4][3];
433 for(j = 0; j < 4; ++j) {
434 for(i = 0; i < 4; ++i) {
435 for(k = 0; k < 3; ++k) {
436 tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + i*4 + k];
437 }
438 }
439 }
440 util_format_dxtn_pack(3, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGB, dst, dst_stride);
441 src += 4*4;
442 dst += 8;
443 }
444 src_row += src_stride;
445 dst_row += 4*dst_stride/sizeof(*dst_row);
446 }
447 }
448 }
449
450 void
451 util_format_dxt1_rgba_pack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
452 {
453 if (!is_nop(util_format_dxtn_pack)) {
454 unsigned x, y, i, j, k;
455 for(y = 0; y < height; y += 4) {
456 const uint8_t *src = src_row;
457 uint8_t *dst = dst_row;
458 for(x = 0; x < width; x += 4) {
459 uint8_t tmp[4][4][4];
460 for(j = 0; j < 4; ++j) {
461 for(i = 0; i < 4; ++i) {
462 for(k = 0; k < 4; ++k) {
463 tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + i*4 + k];
464 }
465 }
466 }
467 util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGBA, dst, dst_stride);
468 src += 4*4;
469 dst += 8;
470 }
471 src_row += src_stride;
472 dst_row += 4*dst_stride/sizeof(*dst_row);
473 }
474 }
475 }
476
477 void
478 util_format_dxt3_rgba_pack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
479 {
480 if (!is_nop(util_format_dxtn_pack)) {
481 unsigned x, y, i, j, k;
482 for(y = 0; y < height; y += 4) {
483 const uint8_t *src = src_row;
484 uint8_t *dst = dst_row;
485 for(x = 0; x < width; x += 4) {
486 uint8_t tmp[4][4][4];
487 for(j = 0; j < 4; ++j) {
488 for(i = 0; i < 4; ++i) {
489 for(k = 0; k < 4; ++k) {
490 tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + i*4 + k];
491 }
492 }
493 }
494 util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT3_RGBA, dst, dst_stride);
495 src += 4*4;
496 dst += 16;
497 }
498 src_row += src_stride;
499 dst_row += 4*dst_stride/sizeof(*dst_row);
500 }
501 }
502 }
503
504 void
505 util_format_dxt5_rgba_pack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
506 {
507 if (!is_nop(util_format_dxtn_pack)) {
508 unsigned x, y, i, j, k;
509 for(y = 0; y < height; y += 4) {
510 const uint8_t *src = src_row;
511 uint8_t *dst = dst_row;
512 for(x = 0; x < width; x += 4) {
513 uint8_t tmp[4][4][4];
514 for(j = 0; j < 4; ++j) {
515 for(i = 0; i < 4; ++i) {
516 for(k = 0; k < 4; ++k) {
517 tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + i*4 + k];
518 }
519 }
520 }
521 util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT5_RGBA, dst, dst_stride);
522 src += 4*4;
523 dst += 16;
524 }
525 src_row += src_stride;
526 dst_row += 4*dst_stride/sizeof(*dst_row);
527 }
528 }
529 }
530
531 void
532 util_format_dxt1_rgb_pack_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
533 {
534 if (!is_nop(util_format_dxtn_pack)) {
535 unsigned x, y, i, j, k;
536 for(y = 0; y < height; y += 4) {
537 const float *src = src_row;
538 uint8_t *dst = dst_row;
539 for(x = 0; x < width; x += 4) {
540 uint8_t tmp[4][4][3];
541 for(j = 0; j < 4; ++j) {
542 for(i = 0; i < 4; ++i) {
543 for(k = 0; k < 3; ++k) {
544 tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + i*4 + k]);
545 }
546 }
547 }
548 util_format_dxtn_pack(3, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGB, dst, dst_stride);
549 src += 4*4;
550 dst += 8;
551 }
552 src_row += src_stride;
553 dst_row += 4*dst_stride/sizeof(*dst_row);
554 }
555 }
556 }
557
558 void
559 util_format_dxt1_rgba_pack_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
560 {
561 if (!is_nop(util_format_dxtn_pack)) {
562 unsigned x, y, i, j, k;
563 for(y = 0; y < height; y += 4) {
564 const float *src = src_row;
565 uint8_t *dst = dst_row;
566 for(x = 0; x < width; x += 4) {
567 uint8_t tmp[4][4][4];
568 for(j = 0; j < 4; ++j) {
569 for(i = 0; i < 4; ++i) {
570 for(k = 0; k < 4; ++k) {
571 tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + i*4 + k]);
572 }
573 }
574 }
575 util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGBA, dst, dst_stride);
576 src += 4*4;
577 dst += 8;
578 }
579 src_row += src_stride;
580 dst_row += 4*dst_stride/sizeof(*dst_row);
581 }
582 }
583 }
584
585 void
586 util_format_dxt3_rgba_pack_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
587 {
588 if (!is_nop(util_format_dxtn_pack)) {
589 unsigned x, y, i, j, k;
590 for(y = 0; y < height; y += 4) {
591 const float *src = src_row;
592 uint8_t *dst = dst_row;
593 for(x = 0; x < width; x += 4) {
594 uint8_t tmp[4][4][4];
595 for(j = 0; j < 4; ++j) {
596 for(i = 0; i < 4; ++i) {
597 for(k = 0; k < 4; ++k) {
598 tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + i*4 + k]);
599 }
600 }
601 }
602 util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT3_RGBA, dst, dst_stride);
603 src += 4*4;
604 dst += 16;
605 }
606 src_row += src_stride;
607 dst_row += 4*dst_stride/sizeof(*dst_row);
608 }
609 }
610 }
611
612 void
613 util_format_dxt5_rgba_pack_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
614 {
615 if (!is_nop(util_format_dxtn_pack)) {
616 unsigned x, y, i, j, k;
617 for(y = 0; y < height; y += 4) {
618 const float *src = src_row;
619 uint8_t *dst = dst_row;
620 for(x = 0; x < width; x += 4) {
621 uint8_t tmp[4][4][4];
622 for(j = 0; j < 4; ++j) {
623 for(i = 0; i < 4; ++i) {
624 for(k = 0; k < 4; ++k) {
625 tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + i*4 + k]);
626 }
627 }
628 }
629 util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT5_RGBA, dst, dst_stride);
630 src += 4*4;
631 dst += 16;
632 }
633 src_row += src_stride;
634 dst_row += 4*dst_stride/sizeof(*dst_row);
635 }
636 }
637 }
638
639
640 /*
641 * SRGB variants.
642 *
643 * FIXME: shunts to RGB for now
644 */
645
646 void
647 util_format_dxt1_srgb_unpack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
648 {
649 util_format_dxt1_rgb_unpack_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
650 }
651
652 void
653 util_format_dxt1_srgb_pack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
654 {
655 util_format_dxt1_rgb_pack_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
656 }
657
658 void
659 util_format_dxt1_srgb_fetch_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
660 {
661 util_format_dxt1_rgb_fetch_8unorm(dst, src, i, j);
662 }
663
664 void
665 util_format_dxt1_srgba_unpack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
666 {
667 util_format_dxt1_rgba_unpack_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
668 }
669
670 void
671 util_format_dxt1_srgba_pack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
672 {
673 util_format_dxt1_rgba_pack_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
674 }
675
676 void
677 util_format_dxt1_srgba_fetch_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
678 {
679 util_format_dxt1_rgba_fetch_8unorm(dst, src, i, j);
680 }
681
682 void
683 util_format_dxt3_srgba_unpack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
684 {
685 util_format_dxt3_rgba_unpack_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
686 }
687
688 void
689 util_format_dxt3_srgba_pack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
690 {
691 util_format_dxt3_rgba_pack_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
692 }
693
694 void
695 util_format_dxt3_srgba_fetch_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
696 {
697 util_format_dxt3_rgba_fetch_8unorm(dst, src, i, j);
698 }
699
700 void
701 util_format_dxt5_srgba_unpack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
702 {
703 util_format_dxt5_rgba_unpack_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
704 }
705
706 void
707 util_format_dxt5_srgba_pack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
708 {
709 util_format_dxt5_rgba_pack_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
710 }
711
712 void
713 util_format_dxt5_srgba_fetch_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
714 {
715 util_format_dxt5_rgba_fetch_8unorm(dst, src, i, j);
716 }
717
718 void
719 util_format_dxt1_srgb_unpack_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
720 {
721 util_format_dxt1_rgb_unpack_float(dst_row, dst_stride, src_row, src_stride, width, height);
722 }
723
724 void
725 util_format_dxt1_srgb_pack_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
726 {
727 util_format_dxt1_rgb_pack_float(dst_row, dst_stride, src_row, src_stride, width, height);
728 }
729
730 void
731 util_format_dxt1_srgb_fetch_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
732 {
733 util_format_dxt1_rgb_fetch_float(dst, src, i, j);
734 }
735
736 void
737 util_format_dxt1_srgba_unpack_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
738 {
739 util_format_dxt1_rgba_unpack_float(dst_row, dst_stride, src_row, src_stride, width, height);
740 }
741
742 void
743 util_format_dxt1_srgba_pack_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
744 {
745 util_format_dxt1_rgba_pack_float(dst_row, dst_stride, src_row, src_stride, width, height);
746 }
747
748 void
749 util_format_dxt1_srgba_fetch_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
750 {
751 util_format_dxt1_rgba_fetch_float(dst, src, i, j);
752 }
753
754 void
755 util_format_dxt3_srgba_unpack_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
756 {
757 util_format_dxt3_rgba_unpack_float(dst_row, dst_stride, src_row, src_stride, width, height);
758 }
759
760 void
761 util_format_dxt3_srgba_pack_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
762 {
763 util_format_dxt3_rgba_pack_float(dst_row, dst_stride, src_row, src_stride, width, height);
764 }
765
766 void
767 util_format_dxt3_srgba_fetch_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
768 {
769 util_format_dxt3_rgba_fetch_float(dst, src, i, j);
770 }
771
772 void
773 util_format_dxt5_srgba_unpack_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
774 {
775 util_format_dxt5_rgba_unpack_float(dst_row, dst_stride, src_row, src_stride, width, height);
776 }
777
778 void
779 util_format_dxt5_srgba_pack_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
780 {
781 util_format_dxt5_rgba_pack_float(dst_row, dst_stride, src_row, src_stride, width, height);
782 }
783
784 void
785 util_format_dxt5_srgba_fetch_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
786 {
787 util_format_dxt5_rgba_fetch_float(dst, src, i, j);
788 }
789