Subversion Repositories Kolibri OS

Rev

Rev 5063 | 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, boolean srgb)
  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.                if (srgb) {
  266.                   dst[0] = util_format_srgb_to_linear_8unorm(dst[0]);
  267.                   dst[1] = util_format_srgb_to_linear_8unorm(dst[1]);
  268.                   dst[2] = util_format_srgb_to_linear_8unorm(dst[2]);
  269.                }
  270.             }
  271.          }
  272.          src += block_size;
  273.       }
  274.       src_row += src_stride;
  275.    }
  276. }
  277.  
  278. void
  279. util_format_dxt1_rgb_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_rgb_fetch,
  287.                                            8, FALSE);
  288. }
  289.  
  290. void
  291. util_format_dxt1_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  292.                                          const uint8_t *src_row, unsigned src_stride,
  293.                                          unsigned width, unsigned height)
  294. {
  295.    util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
  296.                                            src_row, src_stride,
  297.                                            width, height,
  298.                                            util_format_dxt1_rgba_fetch,
  299.                                            8, FALSE);
  300. }
  301.  
  302. void
  303. util_format_dxt3_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  304.                                          const uint8_t *src_row, unsigned src_stride,
  305.                                          unsigned width, unsigned height)
  306. {
  307.    util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
  308.                                            src_row, src_stride,
  309.                                            width, height,
  310.                                            util_format_dxt3_rgba_fetch,
  311.                                            16, FALSE);
  312. }
  313.  
  314. void
  315. util_format_dxt5_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  316.                                          const uint8_t *src_row, unsigned src_stride,
  317.                                          unsigned width, unsigned height)
  318. {
  319.    util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
  320.                                            src_row, src_stride,
  321.                                            width, height,
  322.                                            util_format_dxt5_rgba_fetch,
  323.                                            16, FALSE);
  324. }
  325.  
  326. static INLINE void
  327. util_format_dxtn_rgb_unpack_rgba_float(float *dst_row, unsigned dst_stride,
  328.                                        const uint8_t *src_row, unsigned src_stride,
  329.                                        unsigned width, unsigned height,
  330.                                        util_format_dxtn_fetch_t fetch,
  331.                                        unsigned block_size, boolean srgb)
  332. {
  333.    unsigned x, y, i, j;
  334.    for(y = 0; y < height; y += 4) {
  335.       const uint8_t *src = src_row;
  336.       for(x = 0; x < width; x += 4) {
  337.          for(j = 0; j < 4; ++j) {
  338.             for(i = 0; i < 4; ++i) {
  339.                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
  340.                uint8_t tmp[4];
  341.                fetch(0, src, i, j, tmp);
  342.                if (srgb) {
  343.                   dst[0] = util_format_srgb_8unorm_to_linear_float(tmp[0]);
  344.                   dst[1] = util_format_srgb_8unorm_to_linear_float(tmp[1]);
  345.                   dst[2] = util_format_srgb_8unorm_to_linear_float(tmp[2]);
  346.                }
  347.                else {
  348.                dst[0] = ubyte_to_float(tmp[0]);
  349.                dst[1] = ubyte_to_float(tmp[1]);
  350.                dst[2] = ubyte_to_float(tmp[2]);
  351.                }
  352.                dst[3] = ubyte_to_float(tmp[3]);
  353.             }
  354.          }
  355.          src += block_size;
  356.       }
  357.       src_row += src_stride;
  358.    }
  359. }
  360.  
  361. void
  362. util_format_dxt1_rgb_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_dxt1_rgb_fetch,
  370.                                           8, FALSE);
  371. }
  372.  
  373. void
  374. util_format_dxt1_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride,
  375.                                         const uint8_t *src_row, unsigned src_stride,
  376.                                         unsigned width, unsigned height)
  377. {
  378.    util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
  379.                                           src_row, src_stride,
  380.                                           width, height,
  381.                                           util_format_dxt1_rgba_fetch,
  382.                                           8, FALSE);
  383. }
  384.  
  385. void
  386. util_format_dxt3_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride,
  387.                                         const uint8_t *src_row, unsigned src_stride,
  388.                                         unsigned width, unsigned height)
  389. {
  390.    util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
  391.                                           src_row, src_stride,
  392.                                           width, height,
  393.                                           util_format_dxt3_rgba_fetch,
  394.                                           16, FALSE);
  395. }
  396.  
  397. void
  398. util_format_dxt5_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride,
  399.                                         const uint8_t *src_row, unsigned src_stride,
  400.                                         unsigned width, unsigned height)
  401. {
  402.    util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
  403.                                           src_row, src_stride,
  404.                                           width, height,
  405.                                           util_format_dxt5_rgba_fetch,
  406.                                           16, FALSE);
  407. }
  408.  
  409.  
  410. /*
  411.  * Block compression.
  412.  */
  413.  
  414. static INLINE void
  415. util_format_dxtn_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  416.                                       const uint8_t *src, unsigned src_stride,
  417.                                   unsigned width, unsigned height,
  418.                                   enum util_format_dxtn format,
  419.                                   unsigned block_size, boolean srgb)
  420. {
  421.    const unsigned bw = 4, bh = 4, comps = 4;
  422.    unsigned x, y, i, j, k;
  423.    for(y = 0; y < height; y += bh) {
  424.       uint8_t *dst = dst_row;
  425.       for(x = 0; x < width; x += bw) {
  426.          uint8_t tmp[4][4][4];  /* [bh][bw][comps] */
  427.          for(j = 0; j < bh; ++j) {
  428.             for(i = 0; i < bw; ++i) {
  429.                uint8_t src_tmp;
  430.                for(k = 0; k < 3; ++k) {
  431.                   src_tmp = src[(y + j)*src_stride/sizeof(*src) + (x+i)*comps + k];
  432.                   if (srgb) {
  433.                      tmp[j][i][k] = util_format_linear_to_srgb_8unorm(src_tmp);
  434.                   }
  435.                   else {
  436.                      tmp[j][i][k] = src_tmp;
  437.                }
  438.             }
  439.                /* for sake of simplicity there's an unneeded 4th component for dxt1_rgb */
  440.                tmp[j][i][3] = src[(y + j)*src_stride/sizeof(*src) + (x+i)*comps + 3];
  441.             }
  442.          }
  443.          /* even for dxt1_rgb have 4 src comps */
  444.          util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], format, dst, 0);
  445.          dst += block_size;
  446.       }
  447.       dst_row += dst_stride / sizeof(*dst_row);
  448.    }
  449.  
  450. }
  451.  
  452. void
  453. util_format_dxt1_rgb_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  454.                                       const uint8_t *src, unsigned src_stride,
  455.                                       unsigned width, unsigned height)
  456. {
  457.    util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src, src_stride,
  458.                                      width, height, UTIL_FORMAT_DXT1_RGB,
  459.                                      8, FALSE);
  460. }
  461.  
  462. void
  463. util_format_dxt1_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  464.                                        const uint8_t *src, unsigned src_stride,
  465.                                        unsigned width, unsigned height)
  466. {
  467.    util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src, src_stride,
  468.                                      width, height, UTIL_FORMAT_DXT1_RGBA,
  469.                                      8, FALSE);
  470. }
  471.  
  472. void
  473. util_format_dxt3_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  474.                                        const uint8_t *src, unsigned src_stride,
  475.                                        unsigned width, unsigned height)
  476. {
  477.    util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src, src_stride,
  478.                                      width, height, UTIL_FORMAT_DXT3_RGBA,
  479.                                      16, FALSE);
  480. }
  481.  
  482. void
  483. util_format_dxt5_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  484.                                        const uint8_t *src, unsigned src_stride,
  485.                                        unsigned width, unsigned height)
  486. {
  487.    util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src, src_stride,
  488.                                      width, height, UTIL_FORMAT_DXT5_RGBA,
  489.                                      16, FALSE);
  490. }
  491.  
  492. static INLINE void
  493. util_format_dxtn_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
  494.                                      const float *src, unsigned src_stride,
  495.                                  unsigned width, unsigned height,
  496.                                  enum util_format_dxtn format,
  497.                                  unsigned block_size, boolean srgb)
  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][4];
  504.          for(j = 0; j < 4; ++j) {
  505.             for(i = 0; i < 4; ++i) {
  506.                float src_tmp;
  507.                for(k = 0; k < 3; ++k) {
  508.                   src_tmp = src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + k];
  509.                   if (srgb) {
  510.                      tmp[j][i][k] = util_format_linear_float_to_srgb_8unorm(src_tmp);
  511.                   }
  512.                   else {
  513.                      tmp[j][i][k] = float_to_ubyte(src_tmp);
  514.                }
  515.             }
  516.                /* for sake of simplicity there's an unneeded 4th component for dxt1_rgb */
  517.                src_tmp = src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + 3];
  518.                tmp[j][i][3] = float_to_ubyte(src_tmp);
  519.             }
  520.          }
  521.          util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], format, dst, 0);
  522.          dst += block_size;
  523.       }
  524.       dst_row += 4*dst_stride/sizeof(*dst_row);
  525.    }
  526. }
  527.  
  528. void
  529. util_format_dxt1_rgb_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
  530.                                      const float *src, unsigned src_stride,
  531.                                      unsigned width, unsigned height)
  532. {
  533.    util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src, src_stride,
  534.                                     width, height, UTIL_FORMAT_DXT1_RGB,
  535.                                     8, FALSE);
  536. }
  537.  
  538. void
  539. util_format_dxt1_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
  540.                                       const float *src, unsigned src_stride,
  541.                                       unsigned width, unsigned height)
  542. {
  543.    util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src, src_stride,
  544.                                     width, height, UTIL_FORMAT_DXT1_RGBA,
  545.                                     8, FALSE);
  546. }
  547.  
  548. void
  549. util_format_dxt3_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
  550.                                       const float *src, unsigned src_stride,
  551.                                       unsigned width, unsigned height)
  552. {
  553.    util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src, src_stride,
  554.                                     width, height, UTIL_FORMAT_DXT3_RGBA,
  555.                                     16, FALSE);
  556. }
  557.  
  558. void
  559. util_format_dxt5_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
  560.                                       const float *src, unsigned src_stride,
  561.                                       unsigned width, unsigned height)
  562. {
  563.    util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src, src_stride,
  564.                                     width, height, UTIL_FORMAT_DXT5_RGBA,
  565.                                     16, FALSE);
  566. }
  567.  
  568.  
  569. /*
  570.  * SRGB variants.
  571.  */
  572.  
  573. void
  574. util_format_dxt1_srgb_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
  575. {
  576.    uint8_t tmp[4];
  577.    util_format_dxt1_rgb_fetch(0, src, i, j, tmp);
  578.    dst[0] = util_format_srgb_to_linear_8unorm(tmp[0]);
  579.    dst[1] = util_format_srgb_to_linear_8unorm(tmp[1]);
  580.    dst[2] = util_format_srgb_to_linear_8unorm(tmp[2]);
  581.    dst[3] = 255;
  582. }
  583.  
  584. void
  585. util_format_dxt1_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
  586. {
  587.    uint8_t tmp[4];
  588.    util_format_dxt1_rgba_fetch(0, src, i, j, tmp);
  589.    dst[0] = util_format_srgb_to_linear_8unorm(tmp[0]);
  590.    dst[1] = util_format_srgb_to_linear_8unorm(tmp[1]);
  591.    dst[2] = util_format_srgb_to_linear_8unorm(tmp[2]);
  592.    dst[3] = tmp[3];
  593. }
  594.  
  595. void
  596. util_format_dxt3_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
  597. {
  598.    uint8_t tmp[4];
  599.    util_format_dxt3_rgba_fetch(0, src, i, j, tmp);
  600.    dst[0] = util_format_srgb_to_linear_8unorm(tmp[0]);
  601.    dst[1] = util_format_srgb_to_linear_8unorm(tmp[1]);
  602.    dst[2] = util_format_srgb_to_linear_8unorm(tmp[2]);
  603.    dst[3] = tmp[3];
  604. }
  605.  
  606. void
  607. util_format_dxt5_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
  608. {
  609.    uint8_t tmp[4];
  610.    util_format_dxt5_rgba_fetch(0, src, i, j, tmp);
  611.    dst[0] = util_format_srgb_to_linear_8unorm(tmp[0]);
  612.    dst[1] = util_format_srgb_to_linear_8unorm(tmp[1]);
  613.    dst[2] = util_format_srgb_to_linear_8unorm(tmp[2]);
  614.    dst[3] = tmp[3];
  615. }
  616.  
  617. void
  618. util_format_dxt1_srgb_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
  619. {
  620.    uint8_t tmp[4];
  621.    util_format_dxt1_rgb_fetch(0, src, i, j, tmp);
  622.    dst[0] = util_format_srgb_8unorm_to_linear_float(tmp[0]);
  623.    dst[1] = util_format_srgb_8unorm_to_linear_float(tmp[1]);
  624.    dst[2] = util_format_srgb_8unorm_to_linear_float(tmp[2]);
  625.    dst[3] = 1.0f;
  626. }
  627.  
  628. void
  629. util_format_dxt1_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
  630. {
  631.    uint8_t tmp[4];
  632.    util_format_dxt1_rgba_fetch(0, src, i, j, tmp);
  633.    dst[0] = util_format_srgb_8unorm_to_linear_float(tmp[0]);
  634.    dst[1] = util_format_srgb_8unorm_to_linear_float(tmp[1]);
  635.    dst[2] = util_format_srgb_8unorm_to_linear_float(tmp[2]);
  636.    dst[3] = ubyte_to_float(tmp[3]);
  637. }
  638.  
  639. void
  640. util_format_dxt3_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
  641. {
  642.    uint8_t tmp[4];
  643.    util_format_dxt3_rgba_fetch(0, src, i, j, tmp);
  644.    dst[0] = util_format_srgb_8unorm_to_linear_float(tmp[0]);
  645.    dst[1] = util_format_srgb_8unorm_to_linear_float(tmp[1]);
  646.    dst[2] = util_format_srgb_8unorm_to_linear_float(tmp[2]);
  647.    dst[3] = ubyte_to_float(tmp[3]);
  648. }
  649.  
  650. void
  651. util_format_dxt5_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
  652. {
  653.    uint8_t tmp[4];
  654.    util_format_dxt5_rgba_fetch(0, src, i, j, tmp);
  655.    dst[0] = util_format_srgb_8unorm_to_linear_float(tmp[0]);
  656.    dst[1] = util_format_srgb_8unorm_to_linear_float(tmp[1]);
  657.    dst[2] = util_format_srgb_8unorm_to_linear_float(tmp[2]);
  658.    dst[3] = ubyte_to_float(tmp[3]);
  659. }
  660.  
  661. void
  662. 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)
  663. {
  664.    util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
  665.                                            src_row, src_stride,
  666.                                            width, height,
  667.                                            util_format_dxt1_rgb_fetch,
  668.                                            8, TRUE);
  669. }
  670.  
  671. void
  672. 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)
  673. {
  674.    util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
  675.                                            src_row, src_stride,
  676.                                            width, height,
  677.                                            util_format_dxt1_rgba_fetch,
  678.                                            8, TRUE);
  679. }
  680.  
  681. void
  682. 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)
  683. {
  684.    util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
  685.                                            src_row, src_stride,
  686.                                            width, height,
  687.                                            util_format_dxt3_rgba_fetch,
  688.                                            16, TRUE);
  689. }
  690.  
  691. void
  692. 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)
  693. {
  694.    util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
  695.                                            src_row, src_stride,
  696.                                            width, height,
  697.                                            util_format_dxt5_rgba_fetch,
  698.                                            16, TRUE);
  699. }
  700.  
  701. void
  702. 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)
  703. {
  704.    util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
  705.                                           src_row, src_stride,
  706.                                           width, height,
  707.                                           util_format_dxt1_rgb_fetch,
  708.                                           8, TRUE);
  709. }
  710.  
  711. void
  712. 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)
  713. {
  714.    util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
  715.                                           src_row, src_stride,
  716.                                           width, height,
  717.                                           util_format_dxt1_rgba_fetch,
  718.                                           8, TRUE);
  719. }
  720.  
  721. void
  722. 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)
  723. {
  724.    util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
  725.                                           src_row, src_stride,
  726.                                           width, height,
  727.                                           util_format_dxt3_rgba_fetch,
  728.                                           16, TRUE);
  729. }
  730.  
  731. void
  732. 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)
  733. {
  734.    util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
  735.                                           src_row, src_stride,
  736.                                           width, height,
  737.                                           util_format_dxt5_rgba_fetch,
  738.                                           16, TRUE);
  739. }
  740.  
  741. void
  742. 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)
  743. {
  744.    util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride,
  745.                                      width, height, UTIL_FORMAT_DXT1_RGB,
  746.                                      8, TRUE);
  747. }
  748.  
  749. void
  750. 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)
  751. {
  752.    util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride,
  753.                                      width, height, UTIL_FORMAT_DXT1_RGBA,
  754.                                      8, TRUE);
  755. }
  756.  
  757. void
  758. 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)
  759. {
  760.    util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride,
  761.                                      width, height, UTIL_FORMAT_DXT3_RGBA,
  762.                                      16, TRUE);
  763. }
  764.  
  765. void
  766. 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)
  767. {
  768.    util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride,
  769.                                      width, height, UTIL_FORMAT_DXT5_RGBA,
  770.                                      16, TRUE);
  771. }
  772.  
  773. void
  774. 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)
  775. {
  776.    util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src_row, src_stride,
  777.                                     width, height, UTIL_FORMAT_DXT1_RGB,
  778.                                     8, TRUE);
  779. }
  780.  
  781. void
  782. 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)
  783. {
  784.    util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src_row, src_stride,
  785.                                     width, height, UTIL_FORMAT_DXT1_RGBA,
  786.                                     8, TRUE);
  787. }
  788.  
  789. void
  790. 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)
  791. {
  792.    util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src_row, src_stride,
  793.                                     width, height, UTIL_FORMAT_DXT3_RGBA,
  794.                                     16, TRUE);
  795. }
  796.  
  797. void
  798. 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)
  799. {
  800.    util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src_row, src_stride,
  801.                                     width, height, UTIL_FORMAT_DXT5_RGBA,
  802.                                     16, TRUE);
  803. }
  804.  
  805.