Subversion Repositories Kolibri OS

Rev

Rev 4358 | Go to most recent revision | Blame | Last modification | View Log | RSS feed

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