• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  #elif defined(__APPLE__)
34  #define DXTN_LIBNAME "libtxc_dxtn.dylib"
35  #else
36  #define DXTN_LIBNAME "libtxc_dxtn.so"
37  #endif
38  
39  
40  static void
util_format_dxt1_rgb_fetch_stub(int src_stride,const uint8_t * src,int col,int row,uint8_t * dst)41  util_format_dxt1_rgb_fetch_stub(int src_stride,
42                                  const uint8_t *src,
43                                  int col, int row,
44                                  uint8_t *dst)
45  {
46     assert(0);
47  }
48  
49  
50  static void
util_format_dxt1_rgba_fetch_stub(int src_stride,const uint8_t * src,int col,int row,uint8_t * dst)51  util_format_dxt1_rgba_fetch_stub(int src_stride,
52                                   const uint8_t *src,
53                                   int col, int row,
54                                   uint8_t *dst )
55  {
56     assert(0);
57  }
58  
59  
60  static void
util_format_dxt3_rgba_fetch_stub(int src_stride,const uint8_t * src,int col,int row,uint8_t * dst)61  util_format_dxt3_rgba_fetch_stub(int src_stride,
62                                   const uint8_t *src,
63                                   int col, int row,
64                                   uint8_t *dst )
65  {
66     assert(0);
67  }
68  
69  
70  static void
util_format_dxt5_rgba_fetch_stub(int src_stride,const uint8_t * src,int col,int row,uint8_t * dst)71  util_format_dxt5_rgba_fetch_stub(int src_stride,
72                                   const uint8_t *src,
73                                   int col, int row,
74                                   uint8_t *dst )
75  {
76     assert(0);
77  }
78  
79  
80  static void
util_format_dxtn_pack_stub(int src_comps,int width,int height,const uint8_t * src,enum util_format_dxtn dst_format,uint8_t * dst,int dst_stride)81  util_format_dxtn_pack_stub(int src_comps,
82                             int width, int height,
83                             const uint8_t *src,
84                             enum util_format_dxtn dst_format,
85                             uint8_t *dst,
86                             int dst_stride)
87  {
88     assert(0);
89  }
90  
91  
92  boolean util_format_s3tc_enabled = FALSE;
93  
94  util_format_dxtn_fetch_t util_format_dxt1_rgb_fetch = util_format_dxt1_rgb_fetch_stub;
95  util_format_dxtn_fetch_t util_format_dxt1_rgba_fetch = util_format_dxt1_rgba_fetch_stub;
96  util_format_dxtn_fetch_t util_format_dxt3_rgba_fetch = util_format_dxt3_rgba_fetch_stub;
97  util_format_dxtn_fetch_t util_format_dxt5_rgba_fetch = util_format_dxt5_rgba_fetch_stub;
98  
99  util_format_dxtn_pack_t util_format_dxtn_pack = util_format_dxtn_pack_stub;
100  
101  
102  void
util_format_s3tc_init(void)103  util_format_s3tc_init(void)
104  {
105     static boolean first_time = TRUE;
106     struct util_dl_library *library = NULL;
107     util_dl_proc fetch_2d_texel_rgb_dxt1;
108     util_dl_proc fetch_2d_texel_rgba_dxt1;
109     util_dl_proc fetch_2d_texel_rgba_dxt3;
110     util_dl_proc fetch_2d_texel_rgba_dxt5;
111     util_dl_proc tx_compress_dxtn;
112  
113     if (!first_time)
114        return;
115     first_time = FALSE;
116  
117     if (util_format_s3tc_enabled)
118        return;
119  
120     library = util_dl_open(DXTN_LIBNAME);
121     if (!library) {
122        if (getenv("force_s3tc_enable") &&
123            !strcmp(getenv("force_s3tc_enable"), "true")) {
124           debug_printf("couldn't open " DXTN_LIBNAME ", enabling DXTn due to "
125              "force_s3tc_enable=true environment variable\n");
126           util_format_s3tc_enabled = TRUE;
127        } else {
128           debug_printf("couldn't open " DXTN_LIBNAME ", software DXTn "
129              "compression/decompression unavailable\n");
130        }
131        return;
132     }
133  
134     fetch_2d_texel_rgb_dxt1 =
135           util_dl_get_proc_address(library, "fetch_2d_texel_rgb_dxt1");
136     fetch_2d_texel_rgba_dxt1 =
137           util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt1");
138     fetch_2d_texel_rgba_dxt3 =
139           util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt3");
140     fetch_2d_texel_rgba_dxt5 =
141           util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt5");
142     tx_compress_dxtn =
143           util_dl_get_proc_address(library, "tx_compress_dxtn");
144  
145     if (!util_format_dxt1_rgb_fetch ||
146         !util_format_dxt1_rgba_fetch ||
147         !util_format_dxt3_rgba_fetch ||
148         !util_format_dxt5_rgba_fetch ||
149         !util_format_dxtn_pack) {
150        debug_printf("couldn't reference all symbols in " DXTN_LIBNAME
151                     ", software DXTn compression/decompression "
152                     "unavailable\n");
153        util_dl_close(library);
154        return;
155     }
156  
157     util_format_dxt1_rgb_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgb_dxt1;
158     util_format_dxt1_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt1;
159     util_format_dxt3_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt3;
160     util_format_dxt5_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt5;
161     util_format_dxtn_pack = (util_format_dxtn_pack_t)tx_compress_dxtn;
162     util_format_s3tc_enabled = TRUE;
163  }
164  
165  
166  /*
167   * Pixel fetch.
168   */
169  
170  void
util_format_dxt1_rgb_fetch_rgba_8unorm(uint8_t * dst,const uint8_t * src,unsigned i,unsigned j)171  util_format_dxt1_rgb_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
172  {
173     util_format_dxt1_rgb_fetch(0, src, i, j, dst);
174  }
175  
176  void
util_format_dxt1_rgba_fetch_rgba_8unorm(uint8_t * dst,const uint8_t * src,unsigned i,unsigned j)177  util_format_dxt1_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
178  {
179     util_format_dxt1_rgba_fetch(0, src, i, j, dst);
180  }
181  
182  void
util_format_dxt3_rgba_fetch_rgba_8unorm(uint8_t * dst,const uint8_t * src,unsigned i,unsigned j)183  util_format_dxt3_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
184  {
185     util_format_dxt3_rgba_fetch(0, src, i, j, dst);
186  }
187  
188  void
util_format_dxt5_rgba_fetch_rgba_8unorm(uint8_t * dst,const uint8_t * src,unsigned i,unsigned j)189  util_format_dxt5_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
190  {
191     util_format_dxt5_rgba_fetch(0, src, i, j, dst);
192  }
193  
194  void
util_format_dxt1_rgb_fetch_rgba_float(float * dst,const uint8_t * src,unsigned i,unsigned j)195  util_format_dxt1_rgb_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
196  {
197     uint8_t tmp[4];
198     util_format_dxt1_rgb_fetch(0, src, i, j, tmp);
199     dst[0] = ubyte_to_float(tmp[0]);
200     dst[1] = ubyte_to_float(tmp[1]);
201     dst[2] = ubyte_to_float(tmp[2]);
202     dst[3] = 1.0;
203  }
204  
205  void
util_format_dxt1_rgba_fetch_rgba_float(float * dst,const uint8_t * src,unsigned i,unsigned j)206  util_format_dxt1_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
207  {
208     uint8_t tmp[4];
209     util_format_dxt1_rgba_fetch(0, src, i, j, tmp);
210     dst[0] = ubyte_to_float(tmp[0]);
211     dst[1] = ubyte_to_float(tmp[1]);
212     dst[2] = ubyte_to_float(tmp[2]);
213     dst[3] = ubyte_to_float(tmp[3]);
214  }
215  
216  void
util_format_dxt3_rgba_fetch_rgba_float(float * dst,const uint8_t * src,unsigned i,unsigned j)217  util_format_dxt3_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
218  {
219     uint8_t tmp[4];
220     util_format_dxt3_rgba_fetch(0, src, i, j, tmp);
221     dst[0] = ubyte_to_float(tmp[0]);
222     dst[1] = ubyte_to_float(tmp[1]);
223     dst[2] = ubyte_to_float(tmp[2]);
224     dst[3] = ubyte_to_float(tmp[3]);
225  }
226  
227  void
util_format_dxt5_rgba_fetch_rgba_float(float * dst,const uint8_t * src,unsigned i,unsigned j)228  util_format_dxt5_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
229  {
230     uint8_t tmp[4];
231     util_format_dxt5_rgba_fetch(0, src, i, j, tmp);
232     dst[0] = ubyte_to_float(tmp[0]);
233     dst[1] = ubyte_to_float(tmp[1]);
234     dst[2] = ubyte_to_float(tmp[2]);
235     dst[3] = ubyte_to_float(tmp[3]);
236  }
237  
238  
239  /*
240   * Block decompression.
241   */
242  
243  static INLINE void
util_format_dxtn_rgb_unpack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height,util_format_dxtn_fetch_t fetch,unsigned block_size)244  util_format_dxtn_rgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
245                                          const uint8_t *src_row, unsigned src_stride,
246                                          unsigned width, unsigned height,
247                                          util_format_dxtn_fetch_t fetch,
248                                          unsigned block_size)
249  {
250     const unsigned bw = 4, bh = 4, comps = 4;
251     unsigned x, y, i, j;
252     for(y = 0; y < height; y += bh) {
253        const uint8_t *src = src_row;
254        for(x = 0; x < width; x += bw) {
255           for(j = 0; j < bh; ++j) {
256              for(i = 0; i < bw; ++i) {
257                 uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
258                 fetch(0, src, i, j, dst);
259              }
260           }
261           src += block_size;
262        }
263        src_row += src_stride;
264     }
265  }
266  
267  void
util_format_dxt1_rgb_unpack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)268  util_format_dxt1_rgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
269                                          const uint8_t *src_row, unsigned src_stride,
270                                          unsigned width, unsigned height)
271  {
272     util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
273                                             src_row, src_stride,
274                                             width, height,
275                                             util_format_dxt1_rgb_fetch, 8);
276  }
277  
278  void
util_format_dxt1_rgba_unpack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)279  util_format_dxt1_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
280                                           const uint8_t *src_row, unsigned src_stride,
281                                           unsigned width, unsigned height)
282  {
283     util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
284                                             src_row, src_stride,
285                                             width, height,
286                                             util_format_dxt1_rgba_fetch, 8);
287  }
288  
289  void
util_format_dxt3_rgba_unpack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)290  util_format_dxt3_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
291                                           const uint8_t *src_row, unsigned src_stride,
292                                           unsigned width, unsigned height)
293  {
294     util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
295                                             src_row, src_stride,
296                                             width, height,
297                                             util_format_dxt3_rgba_fetch, 16);
298  }
299  
300  void
util_format_dxt5_rgba_unpack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)301  util_format_dxt5_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
302                                           const uint8_t *src_row, unsigned src_stride,
303                                           unsigned width, unsigned height)
304  {
305     util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
306                                             src_row, src_stride,
307                                             width, height,
308                                             util_format_dxt5_rgba_fetch, 16);
309  }
310  
311  static INLINE void
util_format_dxtn_rgb_unpack_rgba_float(float * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height,util_format_dxtn_fetch_t fetch,unsigned block_size)312  util_format_dxtn_rgb_unpack_rgba_float(float *dst_row, unsigned dst_stride,
313                                         const uint8_t *src_row, unsigned src_stride,
314                                         unsigned width, unsigned height,
315                                         util_format_dxtn_fetch_t fetch,
316                                         unsigned block_size)
317  {
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                 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] = ubyte_to_float(tmp[3]);
331              }
332           }
333           src += block_size;
334        }
335        src_row += src_stride;
336     }
337  }
338  
339  void
util_format_dxt1_rgb_unpack_rgba_float(float * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)340  util_format_dxt1_rgb_unpack_rgba_float(float *dst_row, unsigned dst_stride,
341                                         const uint8_t *src_row, unsigned src_stride,
342                                         unsigned width, unsigned height)
343  {
344     util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
345                                            src_row, src_stride,
346                                            width, height,
347                                            util_format_dxt1_rgb_fetch, 8);
348  }
349  
350  void
util_format_dxt1_rgba_unpack_rgba_float(float * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)351  util_format_dxt1_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride,
352                                          const uint8_t *src_row, unsigned src_stride,
353                                          unsigned width, unsigned height)
354  {
355     util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
356                                            src_row, src_stride,
357                                            width, height,
358                                            util_format_dxt1_rgba_fetch, 8);
359  }
360  
361  void
util_format_dxt3_rgba_unpack_rgba_float(float * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)362  util_format_dxt3_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride,
363                                          const uint8_t *src_row, unsigned src_stride,
364                                          unsigned width, unsigned height)
365  {
366     util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
367                                            src_row, src_stride,
368                                            width, height,
369                                            util_format_dxt3_rgba_fetch, 16);
370  }
371  
372  void
util_format_dxt5_rgba_unpack_rgba_float(float * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)373  util_format_dxt5_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride,
374                                          const uint8_t *src_row, unsigned src_stride,
375                                          unsigned width, unsigned height)
376  {
377     util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
378                                            src_row, src_stride,
379                                            width, height,
380                                            util_format_dxt5_rgba_fetch, 16);
381  }
382  
383  
384  /*
385   * Block compression.
386   */
387  
388  void
util_format_dxt1_rgb_pack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src,unsigned src_stride,unsigned width,unsigned height)389  util_format_dxt1_rgb_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
390                                        const uint8_t *src, unsigned src_stride,
391                                        unsigned width, unsigned height)
392  {
393     const unsigned bw = 4, bh = 4, bytes_per_block = 8;
394     unsigned x, y, i, j, k;
395     for(y = 0; y < height; y += bh) {
396        uint8_t *dst = dst_row;
397        for(x = 0; x < width; x += bw) {
398           uint8_t tmp[4][4][3];  /* [bh][bw][comps] */
399           for(j = 0; j < bh; ++j) {
400              for(i = 0; i < bw; ++i) {
401                 for(k = 0; k < 3; ++k) {
402                    tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + (x + i)*4 + k];
403                 }
404              }
405           }
406           util_format_dxtn_pack(3, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGB, dst, 0);
407           dst += bytes_per_block;
408        }
409        dst_row += dst_stride / sizeof(*dst_row);
410     }
411  }
412  
413  void
util_format_dxt1_rgba_pack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src,unsigned src_stride,unsigned width,unsigned height)414  util_format_dxt1_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
415                                         const uint8_t *src, unsigned src_stride,
416                                         unsigned width, unsigned height)
417  {
418     const unsigned bw = 4, bh = 4, comps = 4, bytes_per_block = 8;
419     unsigned x, y, i, j, k;
420     for(y = 0; y < height; y += bh) {
421        uint8_t *dst = dst_row;
422        for(x = 0; x < width; x += bw) {
423           uint8_t tmp[4][4][4];  /* [bh][bw][comps] */
424           for(j = 0; j < bh; ++j) {
425              for(i = 0; i < bw; ++i) {
426                 for(k = 0; k < comps; ++k) {
427                    tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + (x + i)*comps + k];
428                 }
429              }
430           }
431           util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGBA, dst, 0);
432           dst += bytes_per_block;
433        }
434        dst_row += dst_stride / sizeof(*dst_row);
435     }
436  }
437  
438  void
util_format_dxt3_rgba_pack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src,unsigned src_stride,unsigned width,unsigned height)439  util_format_dxt3_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
440                                         const uint8_t *src, unsigned src_stride,
441                                         unsigned width, unsigned height)
442  {
443     const unsigned bw = 4, bh = 4, comps = 4, bytes_per_block = 16;
444     unsigned x, y, i, j, k;
445     for(y = 0; y < height; y += bh) {
446        uint8_t *dst = dst_row;
447        for(x = 0; x < width; x += bw) {
448           uint8_t tmp[4][4][4];  /* [bh][bw][comps] */
449           for(j = 0; j < bh; ++j) {
450              for(i = 0; i < bw; ++i) {
451                 for(k = 0; k < comps; ++k) {
452                    tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + (x + i)*comps + k];
453                 }
454              }
455           }
456           util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT3_RGBA, dst, 0);
457           dst += bytes_per_block;
458        }
459        dst_row += dst_stride / sizeof(*dst_row);
460     }
461  }
462  
463  void
util_format_dxt5_rgba_pack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src,unsigned src_stride,unsigned width,unsigned height)464  util_format_dxt5_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
465                                         const uint8_t *src, unsigned src_stride,
466                                         unsigned width, unsigned height)
467  {
468     const unsigned bw = 4, bh = 4, comps = 4, bytes_per_block = 16;
469     unsigned x, y, i, j, k;
470  
471     for(y = 0; y < height; y += bh) {
472        uint8_t *dst = dst_row;
473        for(x = 0; x < width; x += bw) {
474           uint8_t tmp[4][4][4];  /* [bh][bw][comps] */
475           for(j = 0; j < bh; ++j) {
476              for(i = 0; i < bw; ++i) {
477                 for(k = 0; k < comps; ++k) {
478                    tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + (x + i)*comps + k];
479                 }
480              }
481           }
482           util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT5_RGBA, dst, 0);
483           dst += bytes_per_block;
484        }
485        dst_row += dst_stride / sizeof(*dst_row);
486     }
487  }
488  
489  void
util_format_dxt1_rgb_pack_rgba_float(uint8_t * dst_row,unsigned dst_stride,const float * src,unsigned src_stride,unsigned width,unsigned height)490  util_format_dxt1_rgb_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
491                                       const float *src, unsigned src_stride,
492                                       unsigned width, unsigned height)
493  {
494     unsigned x, y, i, j, k;
495     for(y = 0; y < height; y += 4) {
496        uint8_t *dst = dst_row;
497        for(x = 0; x < width; x += 4) {
498           uint8_t tmp[4][4][3];
499           for(j = 0; j < 4; ++j) {
500              for(i = 0; i < 4; ++i) {
501                 for(k = 0; k < 3; ++k) {
502                    tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + k]);
503                 }
504              }
505           }
506           util_format_dxtn_pack(3, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGB, dst, 0);
507           dst += 8;
508        }
509        dst_row += 4*dst_stride/sizeof(*dst_row);
510     }
511  }
512  
513  void
util_format_dxt1_rgba_pack_rgba_float(uint8_t * dst_row,unsigned dst_stride,const float * src,unsigned src_stride,unsigned width,unsigned height)514  util_format_dxt1_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
515                                        const float *src, unsigned src_stride,
516                                        unsigned width, unsigned height)
517  {
518     unsigned x, y, i, j, k;
519     for(y = 0; y < height; y += 4) {
520        uint8_t *dst = dst_row;
521        for(x = 0; x < width; x += 4) {
522           uint8_t tmp[4][4][4];
523           for(j = 0; j < 4; ++j) {
524              for(i = 0; i < 4; ++i) {
525                 for(k = 0; k < 4; ++k) {
526                    tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + k]);
527                 }
528              }
529           }
530           util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGBA, dst, 0);
531           dst += 8;
532        }
533        dst_row += 4*dst_stride/sizeof(*dst_row);
534     }
535  }
536  
537  void
util_format_dxt3_rgba_pack_rgba_float(uint8_t * dst_row,unsigned dst_stride,const float * src,unsigned src_stride,unsigned width,unsigned height)538  util_format_dxt3_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
539                                        const float *src, unsigned src_stride,
540                                        unsigned width, unsigned height)
541  {
542     unsigned x, y, i, j, k;
543     for(y = 0; y < height; y += 4) {
544        uint8_t *dst = dst_row;
545        for(x = 0; x < width; x += 4) {
546           uint8_t tmp[4][4][4];
547           for(j = 0; j < 4; ++j) {
548              for(i = 0; i < 4; ++i) {
549                 for(k = 0; k < 4; ++k) {
550                    tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + k]);
551                 }
552              }
553           }
554           util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT3_RGBA, dst, 0);
555           dst += 16;
556        }
557        dst_row += 4*dst_stride/sizeof(*dst_row);
558     }
559  }
560  
561  void
util_format_dxt5_rgba_pack_rgba_float(uint8_t * dst_row,unsigned dst_stride,const float * src,unsigned src_stride,unsigned width,unsigned height)562  util_format_dxt5_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
563                                        const float *src, unsigned src_stride,
564                                        unsigned width, unsigned height)
565  {
566     unsigned x, y, i, j, k;
567     for(y = 0; y < height; y += 4) {
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) + (x+i)*4 + k]);
575                 }
576              }
577           }
578           util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT5_RGBA, dst, 0);
579           dst += 16;
580        }
581        dst_row += 4*dst_stride/sizeof(*dst_row);
582     }
583  }
584  
585  
586  /*
587   * SRGB variants.
588   *
589   * FIXME: shunts to RGB for now
590   */
591  
592  void
util_format_dxt1_srgb_unpack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)593  util_format_dxt1_srgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
594  {
595     util_format_dxt1_rgb_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
596  }
597  
598  void
util_format_dxt1_srgb_pack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)599  util_format_dxt1_srgb_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
600  {
601     util_format_dxt1_rgb_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
602  }
603  
604  void
util_format_dxt1_srgb_fetch_rgba_8unorm(uint8_t * dst,const uint8_t * src,unsigned i,unsigned j)605  util_format_dxt1_srgb_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
606  {
607     util_format_dxt1_rgb_fetch_rgba_8unorm(dst, src, i, j);
608  }
609  
610  void
util_format_dxt1_srgba_unpack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)611  util_format_dxt1_srgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
612  {
613     util_format_dxt1_rgba_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
614  }
615  
616  void
util_format_dxt1_srgba_pack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)617  util_format_dxt1_srgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
618  {
619     util_format_dxt1_rgba_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
620  }
621  
622  void
util_format_dxt1_srgba_fetch_rgba_8unorm(uint8_t * dst,const uint8_t * src,unsigned i,unsigned j)623  util_format_dxt1_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
624  {
625     util_format_dxt1_rgba_fetch_rgba_8unorm(dst, src, i, j);
626  }
627  
628  void
util_format_dxt3_srgba_unpack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)629  util_format_dxt3_srgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
630  {
631     util_format_dxt3_rgba_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
632  }
633  
634  void
util_format_dxt3_srgba_pack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)635  util_format_dxt3_srgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
636  {
637     util_format_dxt3_rgba_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
638  }
639  
640  void
util_format_dxt3_srgba_fetch_rgba_8unorm(uint8_t * dst,const uint8_t * src,unsigned i,unsigned j)641  util_format_dxt3_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
642  {
643     util_format_dxt3_rgba_fetch_rgba_8unorm(dst, src, i, j);
644  }
645  
646  void
util_format_dxt5_srgba_unpack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)647  util_format_dxt5_srgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
648  {
649     util_format_dxt5_rgba_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
650  }
651  
652  void
util_format_dxt5_srgba_pack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)653  util_format_dxt5_srgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
654  {
655     util_format_dxt5_rgba_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
656  }
657  
658  void
util_format_dxt5_srgba_fetch_rgba_8unorm(uint8_t * dst,const uint8_t * src,unsigned i,unsigned j)659  util_format_dxt5_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
660  {
661     util_format_dxt5_rgba_fetch_rgba_8unorm(dst, src, i, j);
662  }
663  
664  void
util_format_dxt1_srgb_unpack_rgba_float(float * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)665  util_format_dxt1_srgb_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
666  {
667     util_format_dxt1_rgb_unpack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height);
668  }
669  
670  void
util_format_dxt1_srgb_pack_rgba_float(uint8_t * dst_row,unsigned dst_stride,const float * src_row,unsigned src_stride,unsigned width,unsigned height)671  util_format_dxt1_srgb_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
672  {
673     util_format_dxt1_rgb_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height);
674  }
675  
676  void
util_format_dxt1_srgb_fetch_rgba_float(float * dst,const uint8_t * src,unsigned i,unsigned j)677  util_format_dxt1_srgb_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
678  {
679     util_format_dxt1_rgb_fetch_rgba_float(dst, src, i, j);
680  }
681  
682  void
util_format_dxt1_srgba_unpack_rgba_float(float * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)683  util_format_dxt1_srgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
684  {
685     util_format_dxt1_rgba_unpack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height);
686  }
687  
688  void
util_format_dxt1_srgba_pack_rgba_float(uint8_t * dst_row,unsigned dst_stride,const float * src_row,unsigned src_stride,unsigned width,unsigned height)689  util_format_dxt1_srgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
690  {
691     util_format_dxt1_rgba_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height);
692  }
693  
694  void
util_format_dxt1_srgba_fetch_rgba_float(float * dst,const uint8_t * src,unsigned i,unsigned j)695  util_format_dxt1_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
696  {
697     util_format_dxt1_rgba_fetch_rgba_float(dst, src, i, j);
698  }
699  
700  void
util_format_dxt3_srgba_unpack_rgba_float(float * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)701  util_format_dxt3_srgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
702  {
703     util_format_dxt3_rgba_unpack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height);
704  }
705  
706  void
util_format_dxt3_srgba_pack_rgba_float(uint8_t * dst_row,unsigned dst_stride,const float * src_row,unsigned src_stride,unsigned width,unsigned height)707  util_format_dxt3_srgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
708  {
709     util_format_dxt3_rgba_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height);
710  }
711  
712  void
util_format_dxt3_srgba_fetch_rgba_float(float * dst,const uint8_t * src,unsigned i,unsigned j)713  util_format_dxt3_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
714  {
715     util_format_dxt3_rgba_fetch_rgba_float(dst, src, i, j);
716  }
717  
718  void
util_format_dxt5_srgba_unpack_rgba_float(float * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)719  util_format_dxt5_srgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
720  {
721     util_format_dxt5_rgba_unpack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height);
722  }
723  
724  void
util_format_dxt5_srgba_pack_rgba_float(uint8_t * dst_row,unsigned dst_stride,const float * src_row,unsigned src_stride,unsigned width,unsigned height)725  util_format_dxt5_srgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
726  {
727     util_format_dxt5_rgba_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height);
728  }
729  
730  void
util_format_dxt5_srgba_fetch_rgba_float(float * dst,const uint8_t * src,unsigned i,unsigned j)731  util_format_dxt5_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
732  {
733     util_format_dxt5_rgba_fetch_rgba_float(dst, src, i, j);
734  }
735  
736