Subversion Repositories Kolibri OS

Rev

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