Subversion Repositories Kolibri OS

Rev

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.  
  115.    if (!first_time)
  116.       return;
  117.    first_time = FALSE;
  118.  
  119.    if (util_format_s3tc_enabled)
  120.       return;
  121.  
  122.    library = util_dl_open(DXTN_LIBNAME);
  123.    if (!library) {
  124.       debug_printf("couldn't open " DXTN_LIBNAME ", software DXTn "
  125.                    "compression/decompression unavailable\n");
  126.       return;
  127.    }
  128.  
  129.    fetch_2d_texel_rgb_dxt1 =
  130.          util_dl_get_proc_address(library, "fetch_2d_texel_rgb_dxt1");
  131.    fetch_2d_texel_rgba_dxt1 =
  132.          util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt1");
  133.    fetch_2d_texel_rgba_dxt3 =
  134.          util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt3");
  135.    fetch_2d_texel_rgba_dxt5 =
  136.          util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt5");
  137.    tx_compress_dxtn =
  138.          util_dl_get_proc_address(library, "tx_compress_dxtn");
  139.  
  140.    if (!util_format_dxt1_rgb_fetch ||
  141.        !util_format_dxt1_rgba_fetch ||
  142.        !util_format_dxt3_rgba_fetch ||
  143.        !util_format_dxt5_rgba_fetch ||
  144.        !util_format_dxtn_pack) {
  145.       debug_printf("couldn't reference all symbols in " DXTN_LIBNAME
  146.                    ", software DXTn compression/decompression "
  147.                    "unavailable\n");
  148.       util_dl_close(library);
  149.       return;
  150.    }
  151.  
  152.    util_format_dxt1_rgb_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgb_dxt1;
  153.    util_format_dxt1_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt1;
  154.    util_format_dxt3_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt3;
  155.    util_format_dxt5_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt5;
  156.    util_format_dxtn_pack = (util_format_dxtn_pack_t)tx_compress_dxtn;
  157.    util_format_s3tc_enabled = TRUE;
  158. }
  159.  
  160.  
  161. /*
  162.  * Pixel fetch.
  163.  */
  164.  
  165. void
  166. util_format_dxt1_rgb_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
  167. {
  168.    util_format_dxt1_rgb_fetch(0, src, i, j, dst);
  169. }
  170.  
  171. void
  172. util_format_dxt1_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
  173. {
  174.    util_format_dxt1_rgba_fetch(0, src, i, j, dst);
  175. }
  176.  
  177. void
  178. util_format_dxt3_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
  179. {
  180.    util_format_dxt3_rgba_fetch(0, src, i, j, dst);
  181. }
  182.  
  183. void
  184. util_format_dxt5_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
  185. {
  186.    util_format_dxt5_rgba_fetch(0, src, i, j, dst);
  187. }
  188.  
  189. void
  190. util_format_dxt1_rgb_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
  191. {
  192.    uint8_t tmp[4];
  193.    util_format_dxt1_rgb_fetch(0, src, i, j, tmp);
  194.    dst[0] = ubyte_to_float(tmp[0]);
  195.    dst[1] = ubyte_to_float(tmp[1]);
  196.    dst[2] = ubyte_to_float(tmp[2]);
  197.    dst[3] = 1.0;
  198. }
  199.  
  200. void
  201. util_format_dxt1_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
  202. {
  203.    uint8_t tmp[4];
  204.    util_format_dxt1_rgba_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] = ubyte_to_float(tmp[3]);
  209. }
  210.  
  211. void
  212. util_format_dxt3_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
  213. {
  214.    uint8_t tmp[4];
  215.    util_format_dxt3_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_dxt5_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
  224. {
  225.    uint8_t tmp[4];
  226.    util_format_dxt5_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.  
  234. /*
  235.  * Block decompression.
  236.  */
  237.  
  238. static INLINE void
  239. util_format_dxtn_rgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  240.                                         const uint8_t *src_row, unsigned src_stride,
  241.                                         unsigned width, unsigned height,
  242.                                         util_format_dxtn_fetch_t fetch,
  243.                                         unsigned block_size, boolean srgb)
  244. {
  245.    const unsigned bw = 4, bh = 4, comps = 4;
  246.    unsigned x, y, i, j;
  247.    for(y = 0; y < height; y += bh) {
  248.       const uint8_t *src = src_row;
  249.       for(x = 0; x < width; x += bw) {
  250.          for(j = 0; j < bh; ++j) {
  251.             for(i = 0; i < bw; ++i) {
  252.                uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
  253.                fetch(0, src, i, j, dst);
  254.                if (srgb) {
  255.                   dst[0] = util_format_srgb_to_linear_8unorm(dst[0]);
  256.                   dst[1] = util_format_srgb_to_linear_8unorm(dst[1]);
  257.                   dst[2] = util_format_srgb_to_linear_8unorm(dst[2]);
  258.                }
  259.             }
  260.          }
  261.          src += block_size;
  262.       }
  263.       src_row += src_stride;
  264.    }
  265. }
  266.  
  267. void
  268. util_format_dxt1_rgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  269.                                         const uint8_t *src_row, unsigned src_stride,
  270.                                         unsigned width, unsigned height)
  271. {
  272.    util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
  273.                                            src_row, src_stride,
  274.                                            width, height,
  275.                                            util_format_dxt1_rgb_fetch,
  276.                                            8, FALSE);
  277. }
  278.  
  279. void
  280. util_format_dxt1_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  281.                                          const uint8_t *src_row, unsigned src_stride,
  282.                                          unsigned width, unsigned height)
  283. {
  284.    util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
  285.                                            src_row, src_stride,
  286.                                            width, height,
  287.                                            util_format_dxt1_rgba_fetch,
  288.                                            8, FALSE);
  289. }
  290.  
  291. void
  292. util_format_dxt3_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  293.                                          const uint8_t *src_row, unsigned src_stride,
  294.                                          unsigned width, unsigned height)
  295. {
  296.    util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
  297.                                            src_row, src_stride,
  298.                                            width, height,
  299.                                            util_format_dxt3_rgba_fetch,
  300.                                            16, FALSE);
  301. }
  302.  
  303. void
  304. util_format_dxt5_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  305.                                          const uint8_t *src_row, unsigned src_stride,
  306.                                          unsigned width, unsigned height)
  307. {
  308.    util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
  309.                                            src_row, src_stride,
  310.                                            width, height,
  311.                                            util_format_dxt5_rgba_fetch,
  312.                                            16, FALSE);
  313. }
  314.  
  315. static INLINE void
  316. util_format_dxtn_rgb_unpack_rgba_float(float *dst_row, unsigned dst_stride,
  317.                                        const uint8_t *src_row, unsigned src_stride,
  318.                                        unsigned width, unsigned height,
  319.                                        util_format_dxtn_fetch_t fetch,
  320.                                        unsigned block_size, boolean srgb)
  321. {
  322.    unsigned x, y, i, j;
  323.    for(y = 0; y < height; y += 4) {
  324.       const uint8_t *src = src_row;
  325.       for(x = 0; x < width; x += 4) {
  326.          for(j = 0; j < 4; ++j) {
  327.             for(i = 0; i < 4; ++i) {
  328.                float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
  329.                uint8_t tmp[4];
  330.                fetch(0, src, i, j, tmp);
  331.                if (srgb) {
  332.                   dst[0] = util_format_srgb_8unorm_to_linear_float(tmp[0]);
  333.                   dst[1] = util_format_srgb_8unorm_to_linear_float(tmp[1]);
  334.                   dst[2] = util_format_srgb_8unorm_to_linear_float(tmp[2]);
  335.                }
  336.                else {
  337.                   dst[0] = ubyte_to_float(tmp[0]);
  338.                   dst[1] = ubyte_to_float(tmp[1]);
  339.                   dst[2] = ubyte_to_float(tmp[2]);
  340.                }
  341.                dst[3] = ubyte_to_float(tmp[3]);
  342.             }
  343.          }
  344.          src += block_size;
  345.       }
  346.       src_row += src_stride;
  347.    }
  348. }
  349.  
  350. void
  351. util_format_dxt1_rgb_unpack_rgba_float(float *dst_row, unsigned dst_stride,
  352.                                        const uint8_t *src_row, unsigned src_stride,
  353.                                        unsigned width, unsigned height)
  354. {
  355.    util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
  356.                                           src_row, src_stride,
  357.                                           width, height,
  358.                                           util_format_dxt1_rgb_fetch,
  359.                                           8, FALSE);
  360. }
  361.  
  362. void
  363. util_format_dxt1_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride,
  364.                                         const uint8_t *src_row, unsigned src_stride,
  365.                                         unsigned width, unsigned height)
  366. {
  367.    util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
  368.                                           src_row, src_stride,
  369.                                           width, height,
  370.                                           util_format_dxt1_rgba_fetch,
  371.                                           8, FALSE);
  372. }
  373.  
  374. void
  375. util_format_dxt3_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride,
  376.                                         const uint8_t *src_row, unsigned src_stride,
  377.                                         unsigned width, unsigned height)
  378. {
  379.    util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
  380.                                           src_row, src_stride,
  381.                                           width, height,
  382.                                           util_format_dxt3_rgba_fetch,
  383.                                           16, FALSE);
  384. }
  385.  
  386. void
  387. util_format_dxt5_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride,
  388.                                         const uint8_t *src_row, unsigned src_stride,
  389.                                         unsigned width, unsigned height)
  390. {
  391.    util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
  392.                                           src_row, src_stride,
  393.                                           width, height,
  394.                                           util_format_dxt5_rgba_fetch,
  395.                                           16, FALSE);
  396. }
  397.  
  398.  
  399. /*
  400.  * Block compression.
  401.  */
  402.  
  403. static INLINE void
  404. util_format_dxtn_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  405.                                   const uint8_t *src, unsigned src_stride,
  406.                                   unsigned width, unsigned height,
  407.                                   enum util_format_dxtn format,
  408.                                   unsigned block_size, boolean srgb)
  409. {
  410.    const unsigned bw = 4, bh = 4, comps = 4;
  411.    unsigned x, y, i, j, k;
  412.    for(y = 0; y < height; y += bh) {
  413.       uint8_t *dst = dst_row;
  414.       for(x = 0; x < width; x += bw) {
  415.          uint8_t tmp[4][4][4];  /* [bh][bw][comps] */
  416.          for(j = 0; j < bh; ++j) {
  417.             for(i = 0; i < bw; ++i) {
  418.                uint8_t src_tmp;
  419.                for(k = 0; k < 3; ++k) {
  420.                   src_tmp = src[(y + j)*src_stride/sizeof(*src) + (x+i)*comps + k];
  421.                   if (srgb) {
  422.                      tmp[j][i][k] = util_format_linear_to_srgb_8unorm(src_tmp);
  423.                   }
  424.                   else {
  425.                      tmp[j][i][k] = src_tmp;
  426.                   }
  427.                }
  428.                /* for sake of simplicity there's an unneeded 4th component for dxt1_rgb */
  429.                tmp[j][i][3] = src[(y + j)*src_stride/sizeof(*src) + (x+i)*comps + 3];
  430.             }
  431.          }
  432.          /* even for dxt1_rgb have 4 src comps */
  433.          util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], format, dst, 0);
  434.          dst += block_size;
  435.       }
  436.       dst_row += dst_stride / sizeof(*dst_row);
  437.    }
  438.  
  439. }
  440.  
  441. void
  442. util_format_dxt1_rgb_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  443.                                       const uint8_t *src, unsigned src_stride,
  444.                                       unsigned width, unsigned height)
  445. {
  446.    util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src, src_stride,
  447.                                      width, height, UTIL_FORMAT_DXT1_RGB,
  448.                                      8, FALSE);
  449. }
  450.  
  451. void
  452. util_format_dxt1_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  453.                                        const uint8_t *src, unsigned src_stride,
  454.                                        unsigned width, unsigned height)
  455. {
  456.    util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src, src_stride,
  457.                                      width, height, UTIL_FORMAT_DXT1_RGBA,
  458.                                      8, FALSE);
  459. }
  460.  
  461. void
  462. util_format_dxt3_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  463.                                        const uint8_t *src, unsigned src_stride,
  464.                                        unsigned width, unsigned height)
  465. {
  466.    util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src, src_stride,
  467.                                      width, height, UTIL_FORMAT_DXT3_RGBA,
  468.                                      16, FALSE);
  469. }
  470.  
  471. void
  472. util_format_dxt5_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
  473.                                        const uint8_t *src, unsigned src_stride,
  474.                                        unsigned width, unsigned height)
  475. {
  476.    util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src, src_stride,
  477.                                      width, height, UTIL_FORMAT_DXT5_RGBA,
  478.                                      16, FALSE);
  479. }
  480.  
  481. static INLINE void
  482. util_format_dxtn_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
  483.                                  const float *src, unsigned src_stride,
  484.                                  unsigned width, unsigned height,
  485.                                  enum util_format_dxtn format,
  486.                                  unsigned block_size, boolean srgb)
  487. {
  488.    unsigned x, y, i, j, k;
  489.    for(y = 0; y < height; y += 4) {
  490.       uint8_t *dst = dst_row;
  491.       for(x = 0; x < width; x += 4) {
  492.          uint8_t tmp[4][4][4];
  493.          for(j = 0; j < 4; ++j) {
  494.             for(i = 0; i < 4; ++i) {
  495.                float src_tmp;
  496.                for(k = 0; k < 3; ++k) {
  497.                   src_tmp = src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + k];
  498.                   if (srgb) {
  499.                      tmp[j][i][k] = util_format_linear_float_to_srgb_8unorm(src_tmp);
  500.                   }
  501.                   else {
  502.                      tmp[j][i][k] = float_to_ubyte(src_tmp);
  503.                   }
  504.                }
  505.                /* for sake of simplicity there's an unneeded 4th component for dxt1_rgb */
  506.                src_tmp = src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + 3];
  507.                tmp[j][i][3] = float_to_ubyte(src_tmp);
  508.             }
  509.          }
  510.          util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], format, dst, 0);
  511.          dst += block_size;
  512.       }
  513.       dst_row += 4*dst_stride/sizeof(*dst_row);
  514.    }
  515. }
  516.  
  517. void
  518. util_format_dxt1_rgb_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
  519.                                      const float *src, unsigned src_stride,
  520.                                      unsigned width, unsigned height)
  521. {
  522.    util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src, src_stride,
  523.                                     width, height, UTIL_FORMAT_DXT1_RGB,
  524.                                     8, FALSE);
  525. }
  526.  
  527. void
  528. util_format_dxt1_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
  529.                                       const float *src, unsigned src_stride,
  530.                                       unsigned width, unsigned height)
  531. {
  532.    util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src, src_stride,
  533.                                     width, height, UTIL_FORMAT_DXT1_RGBA,
  534.                                     8, FALSE);
  535. }
  536.  
  537. void
  538. util_format_dxt3_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
  539.                                       const float *src, unsigned src_stride,
  540.                                       unsigned width, unsigned height)
  541. {
  542.    util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src, src_stride,
  543.                                     width, height, UTIL_FORMAT_DXT3_RGBA,
  544.                                     16, FALSE);
  545. }
  546.  
  547. void
  548. util_format_dxt5_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
  549.                                       const float *src, unsigned src_stride,
  550.                                       unsigned width, unsigned height)
  551. {
  552.    util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src, src_stride,
  553.                                     width, height, UTIL_FORMAT_DXT5_RGBA,
  554.                                     16, FALSE);
  555. }
  556.  
  557.  
  558. /*
  559.  * SRGB variants.
  560.  */
  561.  
  562. void
  563. util_format_dxt1_srgb_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
  564. {
  565.    uint8_t tmp[4];
  566.    util_format_dxt1_rgb_fetch(0, src, i, j, tmp);
  567.    dst[0] = util_format_srgb_to_linear_8unorm(tmp[0]);
  568.    dst[1] = util_format_srgb_to_linear_8unorm(tmp[1]);
  569.    dst[2] = util_format_srgb_to_linear_8unorm(tmp[2]);
  570.    dst[3] = 255;
  571. }
  572.  
  573. void
  574. util_format_dxt1_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
  575. {
  576.    uint8_t tmp[4];
  577.    util_format_dxt1_rgba_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] = tmp[3];
  582. }
  583.  
  584. void
  585. util_format_dxt3_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
  586. {
  587.    uint8_t tmp[4];
  588.    util_format_dxt3_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_dxt5_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
  597. {
  598.    uint8_t tmp[4];
  599.    util_format_dxt5_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_dxt1_srgb_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
  608. {
  609.    uint8_t tmp[4];
  610.    util_format_dxt1_rgb_fetch(0, src, i, j, tmp);
  611.    dst[0] = util_format_srgb_8unorm_to_linear_float(tmp[0]);
  612.    dst[1] = util_format_srgb_8unorm_to_linear_float(tmp[1]);
  613.    dst[2] = util_format_srgb_8unorm_to_linear_float(tmp[2]);
  614.    dst[3] = 1.0f;
  615. }
  616.  
  617. void
  618. util_format_dxt1_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
  619. {
  620.    uint8_t tmp[4];
  621.    util_format_dxt1_rgba_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] = ubyte_to_float(tmp[3]);
  626. }
  627.  
  628. void
  629. util_format_dxt3_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
  630. {
  631.    uint8_t tmp[4];
  632.    util_format_dxt3_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_dxt5_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
  641. {
  642.    uint8_t tmp[4];
  643.    util_format_dxt5_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_dxt1_srgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
  652. {
  653.    util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
  654.                                            src_row, src_stride,
  655.                                            width, height,
  656.                                            util_format_dxt1_rgb_fetch,
  657.                                            8, TRUE);
  658. }
  659.  
  660. void
  661. 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)
  662. {
  663.    util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
  664.                                            src_row, src_stride,
  665.                                            width, height,
  666.                                            util_format_dxt1_rgba_fetch,
  667.                                            8, TRUE);
  668. }
  669.  
  670. void
  671. 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)
  672. {
  673.    util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
  674.                                            src_row, src_stride,
  675.                                            width, height,
  676.                                            util_format_dxt3_rgba_fetch,
  677.                                            16, TRUE);
  678. }
  679.  
  680. void
  681. 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)
  682. {
  683.    util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride,
  684.                                            src_row, src_stride,
  685.                                            width, height,
  686.                                            util_format_dxt5_rgba_fetch,
  687.                                            16, TRUE);
  688. }
  689.  
  690. void
  691. 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)
  692. {
  693.    util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
  694.                                           src_row, src_stride,
  695.                                           width, height,
  696.                                           util_format_dxt1_rgb_fetch,
  697.                                           8, TRUE);
  698. }
  699.  
  700. void
  701. 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)
  702. {
  703.    util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
  704.                                           src_row, src_stride,
  705.                                           width, height,
  706.                                           util_format_dxt1_rgba_fetch,
  707.                                           8, TRUE);
  708. }
  709.  
  710. void
  711. 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)
  712. {
  713.    util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
  714.                                           src_row, src_stride,
  715.                                           width, height,
  716.                                           util_format_dxt3_rgba_fetch,
  717.                                           16, TRUE);
  718. }
  719.  
  720. void
  721. 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)
  722. {
  723.    util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride,
  724.                                           src_row, src_stride,
  725.                                           width, height,
  726.                                           util_format_dxt5_rgba_fetch,
  727.                                           16, TRUE);
  728. }
  729.  
  730. void
  731. 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)
  732. {
  733.    util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride,
  734.                                      width, height, UTIL_FORMAT_DXT1_RGB,
  735.                                      8, TRUE);
  736. }
  737.  
  738. void
  739. 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)
  740. {
  741.    util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride,
  742.                                      width, height, UTIL_FORMAT_DXT1_RGBA,
  743.                                      8, TRUE);
  744. }
  745.  
  746. void
  747. 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)
  748. {
  749.    util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride,
  750.                                      width, height, UTIL_FORMAT_DXT3_RGBA,
  751.                                      16, TRUE);
  752. }
  753.  
  754. void
  755. 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)
  756. {
  757.    util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride,
  758.                                      width, height, UTIL_FORMAT_DXT5_RGBA,
  759.                                      16, TRUE);
  760. }
  761.  
  762. void
  763. 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)
  764. {
  765.    util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src_row, src_stride,
  766.                                     width, height, UTIL_FORMAT_DXT1_RGB,
  767.                                     8, TRUE);
  768. }
  769.  
  770. void
  771. 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)
  772. {
  773.    util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src_row, src_stride,
  774.                                     width, height, UTIL_FORMAT_DXT1_RGBA,
  775.                                     8, TRUE);
  776. }
  777.  
  778. void
  779. 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)
  780. {
  781.    util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src_row, src_stride,
  782.                                     width, height, UTIL_FORMAT_DXT3_RGBA,
  783.                                     16, TRUE);
  784. }
  785.  
  786. void
  787. 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)
  788. {
  789.    util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src_row, src_stride,
  790.                                     width, height, UTIL_FORMAT_DXT5_RGBA,
  791.                                     16, TRUE);
  792. }
  793.  
  794.