u_format_s3tc.c revision bc2bc0306e4dd8c56bd66a8aabf2433f6689653d
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
38static void
39util_format_dxt1_rgb_fetch_stub(int src_stride,
40                                const uint8_t *src,
41                                int col, int row,
42                                uint8_t *dst)
43{
44   assert(0);
45}
46
47
48static void
49util_format_dxt1_rgba_fetch_stub(int src_stride,
50                                 const uint8_t *src,
51                                 int col, int row,
52                                 uint8_t *dst )
53{
54   assert(0);
55}
56
57
58static void
59util_format_dxt3_rgba_fetch_stub(int src_stride,
60                                 const uint8_t *src,
61                                 int col, int row,
62                                 uint8_t *dst )
63{
64   assert(0);
65}
66
67
68static void
69util_format_dxt5_rgba_fetch_stub(int src_stride,
70                                 const uint8_t *src,
71                                 int col, int row,
72                                 uint8_t *dst )
73{
74   assert(0);
75}
76
77
78static void
79util_format_dxtn_pack_stub(int src_comps,
80                           int width, int height,
81                           const uint8_t *src,
82                           enum util_format_dxtn dst_format,
83                           uint8_t *dst,
84                           int dst_stride)
85{
86   assert(0);
87}
88
89
90boolean util_format_s3tc_enabled = FALSE;
91
92util_format_dxtn_fetch_t util_format_dxt1_rgb_fetch = util_format_dxt1_rgb_fetch_stub;
93util_format_dxtn_fetch_t util_format_dxt1_rgba_fetch = util_format_dxt1_rgba_fetch_stub;
94util_format_dxtn_fetch_t util_format_dxt3_rgba_fetch = util_format_dxt3_rgba_fetch_stub;
95util_format_dxtn_fetch_t util_format_dxt5_rgba_fetch = util_format_dxt5_rgba_fetch_stub;
96
97util_format_dxtn_pack_t util_format_dxtn_pack = util_format_dxtn_pack_stub;
98
99
100void
101util_format_s3tc_init(void)
102{
103   static boolean first_time = TRUE;
104   struct util_dl_library *library = NULL;
105   util_dl_proc fetch_2d_texel_rgb_dxt1;
106   util_dl_proc fetch_2d_texel_rgba_dxt1;
107   util_dl_proc fetch_2d_texel_rgba_dxt3;
108   util_dl_proc fetch_2d_texel_rgba_dxt5;
109   util_dl_proc tx_compress_dxtn;
110
111   if (!first_time)
112      return;
113   first_time = FALSE;
114
115   if (util_format_s3tc_enabled)
116      return;
117
118   library = util_dl_open(DXTN_LIBNAME);
119   if (!library) {
120      debug_printf("couldn't open " DXTN_LIBNAME ", software DXTn "
121         "compression/decompression unavailable");
122      return;
123   }
124
125   fetch_2d_texel_rgb_dxt1 =
126         util_dl_get_proc_address(library, "fetch_2d_texel_rgb_dxt1");
127   fetch_2d_texel_rgba_dxt1 =
128         util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt1");
129   fetch_2d_texel_rgba_dxt3 =
130         util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt3");
131   fetch_2d_texel_rgba_dxt5 =
132         util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt5");
133   tx_compress_dxtn =
134         util_dl_get_proc_address(library, "tx_compress_dxtn");
135
136   if (!util_format_dxt1_rgb_fetch ||
137       !util_format_dxt1_rgba_fetch ||
138       !util_format_dxt3_rgba_fetch ||
139       !util_format_dxt5_rgba_fetch ||
140       !util_format_dxtn_pack) {
141      debug_printf("couldn't reference all symbols in " DXTN_LIBNAME
142                   ", software DXTn compression/decompression "
143                   "unavailable");
144      util_dl_close(library);
145      return;
146   }
147
148   util_format_dxt1_rgb_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgb_dxt1;
149   util_format_dxt1_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt1;
150   util_format_dxt3_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt3;
151   util_format_dxt5_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt5;
152   util_format_dxtn_pack = (util_format_dxtn_pack_t)tx_compress_dxtn;
153   util_format_s3tc_enabled = TRUE;
154   util_dl_close(library);
155}
156
157
158/*
159 * Pixel fetch.
160 */
161
162void
163util_format_dxt1_rgb_fetch_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
164{
165   util_format_dxt1_rgb_fetch(0, src, i, j, dst);
166}
167
168void
169util_format_dxt1_rgba_fetch_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
170{
171   util_format_dxt1_rgba_fetch(0, src, i, j, dst);
172}
173
174void
175util_format_dxt3_rgba_fetch_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
176{
177   util_format_dxt3_rgba_fetch(0, src, i, j, dst);
178}
179
180void
181util_format_dxt5_rgba_fetch_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
182{
183   util_format_dxt5_rgba_fetch(0, src, i, j, dst);
184}
185
186void
187util_format_dxt1_rgb_fetch_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
188{
189   uint8_t tmp[4];
190   util_format_dxt1_rgb_fetch(0, src, i, j, tmp);
191   dst[0] = ubyte_to_float(tmp[0]);
192   dst[1] = ubyte_to_float(tmp[1]);
193   dst[2] = ubyte_to_float(tmp[2]);
194   dst[3] = 1.0;
195}
196
197void
198util_format_dxt1_rgba_fetch_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
199{
200   uint8_t tmp[4];
201   util_format_dxt1_rgba_fetch(0, src, i, j, tmp);
202   dst[0] = ubyte_to_float(tmp[0]);
203   dst[1] = ubyte_to_float(tmp[1]);
204   dst[2] = ubyte_to_float(tmp[2]);
205   dst[3] = ubyte_to_float(tmp[3]);
206}
207
208void
209util_format_dxt3_rgba_fetch_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
210{
211   uint8_t tmp[4];
212   util_format_dxt3_rgba_fetch(0, src, i, j, tmp);
213   dst[0] = ubyte_to_float(tmp[0]);
214   dst[1] = ubyte_to_float(tmp[1]);
215   dst[2] = ubyte_to_float(tmp[2]);
216   dst[3] = ubyte_to_float(tmp[3]);
217}
218
219void
220util_format_dxt5_rgba_fetch_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
221{
222   uint8_t tmp[4];
223   util_format_dxt5_rgba_fetch(0, src, i, j, tmp);
224   dst[0] = ubyte_to_float(tmp[0]);
225   dst[1] = ubyte_to_float(tmp[1]);
226   dst[2] = ubyte_to_float(tmp[2]);
227   dst[3] = ubyte_to_float(tmp[3]);
228}
229
230
231/*
232 * Block decompression.
233 */
234
235void
236util_format_dxt1_rgb_unpack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
237{
238   unsigned x, y, i, j;
239   for(y = 0; y < height; y += 4) {
240      const uint8_t *src = src_row;
241      for(x = 0; x < width; x += 4) {
242         for(j = 0; j < 4; ++j) {
243            for(i = 0; i < 4; ++i) {
244               uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
245               util_format_dxt1_rgb_fetch(0, src, i, j, dst);
246            }
247         }
248         src += 8;
249      }
250      src_row += src_stride;
251   }
252}
253
254void
255util_format_dxt1_rgba_unpack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
256{
257   unsigned x, y, i, j;
258   for(y = 0; y < height; y += 4) {
259      const uint8_t *src = src_row;
260      for(x = 0; x < width; x += 4) {
261         for(j = 0; j < 4; ++j) {
262            for(i = 0; i < 4; ++i) {
263               uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
264               util_format_dxt1_rgba_fetch(0, src, i, j, dst);
265            }
266         }
267         src += 8;
268      }
269      src_row += src_stride;
270   }
271}
272
273void
274util_format_dxt3_rgba_unpack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
275{
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
292void
293util_format_dxt5_rgba_unpack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
294{
295   unsigned x, y, i, j;
296   for(y = 0; y < height; y += 4) {
297      const uint8_t *src = src_row;
298      for(x = 0; x < width; x += 4) {
299         for(j = 0; j < 4; ++j) {
300            for(i = 0; i < 4; ++i) {
301               uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
302               util_format_dxt5_rgba_fetch(0, src, i, j, dst);
303            }
304         }
305         src += 16;
306      }
307      src_row += src_stride;
308   }
309}
310
311void
312util_format_dxt1_rgb_unpack_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
313{
314   unsigned x, y, i, j;
315   for(y = 0; y < height; y += 4) {
316      const uint8_t *src = src_row;
317      for(x = 0; x < width; x += 4) {
318         for(j = 0; j < 4; ++j) {
319            for(i = 0; i < 4; ++i) {
320               float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
321               uint8_t tmp[4];
322               util_format_dxt1_rgb_fetch(0, src, i, j, tmp);
323               dst[0] = ubyte_to_float(tmp[0]);
324               dst[1] = ubyte_to_float(tmp[1]);
325               dst[2] = ubyte_to_float(tmp[2]);
326               dst[3] = 1.0;
327            }
328         }
329         src += 8;
330      }
331      src_row += src_stride;
332   }
333}
334
335void
336util_format_dxt1_rgba_unpack_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
337{
338   unsigned x, y, i, j;
339   for(y = 0; y < height; y += 4) {
340      const uint8_t *src = src_row;
341      for(x = 0; x < width; x += 4) {
342         for(j = 0; j < 4; ++j) {
343            for(i = 0; i < 4; ++i) {
344               float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
345               uint8_t tmp[4];
346               util_format_dxt1_rgba_fetch(0, src, i, j, tmp);
347               dst[0] = ubyte_to_float(tmp[0]);
348               dst[1] = ubyte_to_float(tmp[1]);
349               dst[2] = ubyte_to_float(tmp[2]);
350               dst[3] = ubyte_to_float(tmp[3]);
351            }
352         }
353         src += 8;
354      }
355      src_row += src_stride;
356   }
357}
358
359void
360util_format_dxt3_rgba_unpack_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
361{
362   unsigned x, y, i, j;
363   for(y = 0; y < height; y += 4) {
364      const uint8_t *src = src_row;
365      for(x = 0; x < width; x += 4) {
366         for(j = 0; j < 4; ++j) {
367            for(i = 0; i < 4; ++i) {
368               float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
369               uint8_t tmp[4];
370               util_format_dxt3_rgba_fetch(0, src, i, j, tmp);
371               dst[0] = ubyte_to_float(tmp[0]);
372               dst[1] = ubyte_to_float(tmp[1]);
373               dst[2] = ubyte_to_float(tmp[2]);
374               dst[3] = ubyte_to_float(tmp[3]);
375            }
376         }
377         src += 16;
378      }
379      src_row += src_stride;
380   }
381}
382
383void
384util_format_dxt5_rgba_unpack_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
385{
386   unsigned x, y, i, j;
387   for(y = 0; y < height; y += 4) {
388      const uint8_t *src = src_row;
389      for(x = 0; x < width; x += 4) {
390         for(j = 0; j < 4; ++j) {
391            for(i = 0; i < 4; ++i) {
392               float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
393               uint8_t tmp[4];
394               util_format_dxt5_rgba_fetch(0, src, i, j, tmp);
395               dst[0] = ubyte_to_float(tmp[0]);
396               dst[1] = ubyte_to_float(tmp[1]);
397               dst[2] = ubyte_to_float(tmp[2]);
398               dst[3] = ubyte_to_float(tmp[3]);
399            }
400         }
401         src += 16;
402      }
403      src_row += src_stride;
404   }
405}
406
407
408/*
409 * Block compression.
410 */
411
412void
413util_format_dxt1_rgb_pack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
414{
415   unsigned x, y, i, j, k;
416   for(y = 0; y < height; y += 4) {
417      const uint8_t *src = src_row;
418      uint8_t *dst = dst_row;
419      for(x = 0; x < width; x += 4) {
420         uint8_t tmp[4][4][3];
421         for(j = 0; j < 4; ++j) {
422            for(i = 0; i < 4; ++i) {
423               for(k = 0; k < 3; ++k) {
424                  tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + i*4 + k];
425               }
426            }
427         }
428         util_format_dxtn_pack(3, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGB, dst, dst_stride);
429         src += 4*4;
430         dst += 8;
431      }
432      src_row += src_stride;
433      dst_row += 4*dst_stride/sizeof(*dst_row);
434   }
435}
436
437void
438util_format_dxt1_rgba_pack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
439{
440   unsigned x, y, i, j, k;
441   for(y = 0; y < height; y += 4) {
442      const uint8_t *src = src_row;
443      uint8_t *dst = dst_row;
444      for(x = 0; x < width; x += 4) {
445         uint8_t tmp[4][4][4];
446         for(j = 0; j < 4; ++j) {
447            for(i = 0; i < 4; ++i) {
448               for(k = 0; k < 4; ++k) {
449                  tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + i*4 + k];
450               }
451            }
452         }
453         util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGBA, dst, dst_stride);
454         src += 4*4;
455         dst += 8;
456      }
457      src_row += src_stride;
458      dst_row += 4*dst_stride/sizeof(*dst_row);
459   }
460}
461
462void
463util_format_dxt3_rgba_pack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
464{
465   unsigned x, y, i, j, k;
466   for(y = 0; y < height; y += 4) {
467      const uint8_t *src = src_row;
468      uint8_t *dst = dst_row;
469      for(x = 0; x < width; x += 4) {
470         uint8_t tmp[4][4][4];
471         for(j = 0; j < 4; ++j) {
472            for(i = 0; i < 4; ++i) {
473               for(k = 0; k < 4; ++k) {
474                  tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + i*4 + k];
475               }
476            }
477         }
478         util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT3_RGBA, dst, dst_stride);
479         src += 4*4;
480         dst += 16;
481      }
482      src_row += src_stride;
483      dst_row += 4*dst_stride/sizeof(*dst_row);
484   }
485}
486
487void
488util_format_dxt5_rgba_pack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
489{
490   unsigned x, y, i, j, k;
491   for(y = 0; y < height; y += 4) {
492      const uint8_t *src = src_row;
493      uint8_t *dst = dst_row;
494      for(x = 0; x < width; x += 4) {
495         uint8_t tmp[4][4][4];
496         for(j = 0; j < 4; ++j) {
497            for(i = 0; i < 4; ++i) {
498               for(k = 0; k < 4; ++k) {
499                  tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + i*4 + k];
500               }
501            }
502         }
503         util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT5_RGBA, dst, dst_stride);
504         src += 4*4;
505         dst += 16;
506      }
507      src_row += src_stride;
508      dst_row += 4*dst_stride/sizeof(*dst_row);
509   }
510}
511
512void
513util_format_dxt1_rgb_pack_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
514{
515   unsigned x, y, i, j, k;
516   for(y = 0; y < height; y += 4) {
517      const float *src = src_row;
518      uint8_t *dst = dst_row;
519      for(x = 0; x < width; x += 4) {
520         uint8_t tmp[4][4][3];
521         for(j = 0; j < 4; ++j) {
522            for(i = 0; i < 4; ++i) {
523               for(k = 0; k < 3; ++k) {
524                  tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + i*4 + k]);
525               }
526            }
527         }
528         util_format_dxtn_pack(3, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGB, dst, dst_stride);
529         src += 4*4;
530         dst += 8;
531      }
532      src_row += src_stride;
533      dst_row += 4*dst_stride/sizeof(*dst_row);
534   }
535}
536
537void
538util_format_dxt1_rgba_pack_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
539{
540   unsigned x, y, i, j, k;
541   for(y = 0; y < height; y += 4) {
542      const float *src = src_row;
543      uint8_t *dst = dst_row;
544      for(x = 0; x < width; x += 4) {
545         uint8_t tmp[4][4][4];
546         for(j = 0; j < 4; ++j) {
547            for(i = 0; i < 4; ++i) {
548               for(k = 0; k < 4; ++k) {
549                  tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + i*4 + k]);
550               }
551            }
552         }
553         util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGBA, dst, dst_stride);
554         src += 4*4;
555         dst += 8;
556      }
557      src_row += src_stride;
558      dst_row += 4*dst_stride/sizeof(*dst_row);
559   }
560}
561
562void
563util_format_dxt3_rgba_pack_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
564{
565   unsigned x, y, i, j, k;
566   for(y = 0; y < height; y += 4) {
567      const float *src = src_row;
568      uint8_t *dst = dst_row;
569      for(x = 0; x < width; x += 4) {
570         uint8_t tmp[4][4][4];
571         for(j = 0; j < 4; ++j) {
572            for(i = 0; i < 4; ++i) {
573               for(k = 0; k < 4; ++k) {
574                  tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + i*4 + k]);
575               }
576            }
577         }
578         util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT3_RGBA, dst, dst_stride);
579         src += 4*4;
580         dst += 16;
581      }
582      src_row += src_stride;
583      dst_row += 4*dst_stride/sizeof(*dst_row);
584   }
585}
586
587void
588util_format_dxt5_rgba_pack_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
589{
590   unsigned x, y, i, j, k;
591   for(y = 0; y < height; y += 4) {
592      const float *src = src_row;
593      uint8_t *dst = dst_row;
594      for(x = 0; x < width; x += 4) {
595         uint8_t tmp[4][4][4];
596         for(j = 0; j < 4; ++j) {
597            for(i = 0; i < 4; ++i) {
598               for(k = 0; k < 4; ++k) {
599                  tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + i*4 + k]);
600               }
601            }
602         }
603         util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT5_RGBA, dst, dst_stride);
604         src += 4*4;
605         dst += 16;
606      }
607      src_row += src_stride;
608      dst_row += 4*dst_stride/sizeof(*dst_row);
609   }
610}
611
612
613/*
614 * SRGB variants.
615 *
616 * FIXME: shunts to RGB for now
617 */
618
619void
620util_format_dxt1_srgb_unpack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
621{
622   util_format_dxt1_rgb_unpack_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
623}
624
625void
626util_format_dxt1_srgb_pack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
627{
628   util_format_dxt1_rgb_pack_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
629}
630
631void
632util_format_dxt1_srgb_fetch_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
633{
634   util_format_dxt1_rgb_fetch_8unorm(dst, src, i, j);
635}
636
637void
638util_format_dxt1_srgba_unpack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
639{
640   util_format_dxt1_rgba_unpack_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
641}
642
643void
644util_format_dxt1_srgba_pack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
645{
646   util_format_dxt1_rgba_pack_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
647}
648
649void
650util_format_dxt1_srgba_fetch_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
651{
652   util_format_dxt1_rgba_fetch_8unorm(dst, src, i, j);
653}
654
655void
656util_format_dxt3_srgba_unpack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
657{
658   util_format_dxt3_rgba_unpack_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
659}
660
661void
662util_format_dxt3_srgba_pack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
663{
664   util_format_dxt3_rgba_pack_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
665}
666
667void
668util_format_dxt3_srgba_fetch_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
669{
670   util_format_dxt3_rgba_fetch_8unorm(dst, src, i, j);
671}
672
673void
674util_format_dxt5_srgba_unpack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
675{
676   util_format_dxt5_rgba_unpack_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
677}
678
679void
680util_format_dxt5_srgba_pack_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
681{
682   util_format_dxt5_rgba_pack_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
683}
684
685void
686util_format_dxt5_srgba_fetch_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
687{
688   util_format_dxt5_rgba_fetch_8unorm(dst, src, i, j);
689}
690
691void
692util_format_dxt1_srgb_unpack_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
693{
694   util_format_dxt1_rgb_unpack_float(dst_row, dst_stride, src_row, src_stride, width, height);
695}
696
697void
698util_format_dxt1_srgb_pack_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
699{
700   util_format_dxt1_rgb_pack_float(dst_row, dst_stride, src_row, src_stride, width, height);
701}
702
703void
704util_format_dxt1_srgb_fetch_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
705{
706   util_format_dxt1_rgb_fetch_float(dst, src, i, j);
707}
708
709void
710util_format_dxt1_srgba_unpack_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
711{
712   util_format_dxt1_rgba_unpack_float(dst_row, dst_stride, src_row, src_stride, width, height);
713}
714
715void
716util_format_dxt1_srgba_pack_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
717{
718   util_format_dxt1_rgba_pack_float(dst_row, dst_stride, src_row, src_stride, width, height);
719}
720
721void
722util_format_dxt1_srgba_fetch_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
723{
724   util_format_dxt1_rgba_fetch_float(dst, src, i, j);
725}
726
727void
728util_format_dxt3_srgba_unpack_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
729{
730   util_format_dxt3_rgba_unpack_float(dst_row, dst_stride, src_row, src_stride, width, height);
731}
732
733void
734util_format_dxt3_srgba_pack_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
735{
736   util_format_dxt3_rgba_pack_float(dst_row, dst_stride, src_row, src_stride, width, height);
737}
738
739void
740util_format_dxt3_srgba_fetch_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
741{
742   util_format_dxt3_rgba_fetch_float(dst, src, i, j);
743}
744
745void
746util_format_dxt5_srgba_unpack_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
747{
748   util_format_dxt5_rgba_unpack_float(dst_row, dst_stride, src_row, src_stride, width, height);
749}
750
751void
752util_format_dxt5_srgba_pack_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
753{
754   util_format_dxt5_rgba_pack_float(dst_row, dst_stride, src_row, src_stride, width, height);
755}
756
757void
758util_format_dxt5_srgba_fetch_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
759{
760   util_format_dxt5_rgba_fetch_float(dst, src, i, j);
761}
762
763