Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2010 VMware, Inc.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28. /**
  29.  * @file
  30.  * Pixel format accessor functions.
  31.  *
  32.  * @author Jose Fonseca <jfonseca@vmware.com>
  33.  */
  34.  
  35. #include "u_math.h"
  36. #include "u_memory.h"
  37. #include "u_format.h"
  38. #include "u_format_s3tc.h"
  39. #include "u_surface.h"
  40.  
  41. #include "pipe/p_defines.h"
  42.  
  43.  
  44. boolean
  45. util_format_is_float(enum pipe_format format)
  46. {
  47.    const struct util_format_description *desc = util_format_description(format);
  48.    unsigned i;
  49.  
  50.    assert(desc);
  51.    if (!desc) {
  52.       return FALSE;
  53.    }
  54.  
  55.    i = util_format_get_first_non_void_channel(format);
  56.    if (i == -1) {
  57.       return FALSE;
  58.    }
  59.  
  60.    return desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT ? TRUE : FALSE;
  61. }
  62.  
  63.  
  64. /** Test if the format contains RGB, but not alpha */
  65. boolean
  66. util_format_has_alpha(enum pipe_format format)
  67. {
  68.    const struct util_format_description *desc =
  69.       util_format_description(format);
  70.  
  71.    return (desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
  72.            desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
  73.           desc->swizzle[3] != UTIL_FORMAT_SWIZZLE_1;
  74. }
  75.  
  76.  
  77. boolean
  78. util_format_is_luminance(enum pipe_format format)
  79. {
  80.    const struct util_format_description *desc =
  81.       util_format_description(format);
  82.  
  83.    if ((desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
  84.         desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
  85.        desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_X &&
  86.        desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_X &&
  87.        desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_X &&
  88.        desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_1) {
  89.       return TRUE;
  90.    }
  91.    return FALSE;
  92. }
  93.  
  94. boolean
  95. util_format_is_alpha(enum pipe_format format)
  96. {
  97.    const struct util_format_description *desc =
  98.       util_format_description(format);
  99.  
  100.    if ((desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
  101.         desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
  102.        desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_0 &&
  103.        desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_0 &&
  104.        desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_0 &&
  105.        desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_X) {
  106.       return TRUE;
  107.    }
  108.    return FALSE;
  109. }
  110.  
  111. boolean
  112. util_format_is_pure_integer(enum pipe_format format)
  113. {
  114.    const struct util_format_description *desc = util_format_description(format);
  115.    int i;
  116.  
  117.    /* Find the first non-void channel. */
  118.    i = util_format_get_first_non_void_channel(format);
  119.    if (i == -1)
  120.       return FALSE;
  121.  
  122.    return desc->channel[i].pure_integer ? TRUE : FALSE;
  123. }
  124.  
  125. boolean
  126. util_format_is_pure_sint(enum pipe_format format)
  127. {
  128.    const struct util_format_description *desc = util_format_description(format);
  129.    int i;
  130.  
  131.    i = util_format_get_first_non_void_channel(format);
  132.    if (i == -1)
  133.       return FALSE;
  134.  
  135.    return (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED && desc->channel[i].pure_integer) ? TRUE : FALSE;
  136. }
  137.  
  138. boolean
  139. util_format_is_pure_uint(enum pipe_format format)
  140. {
  141.    const struct util_format_description *desc = util_format_description(format);
  142.    int i;
  143.  
  144.    i = util_format_get_first_non_void_channel(format);
  145.    if (i == -1)
  146.       return FALSE;
  147.  
  148.    return (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED && desc->channel[i].pure_integer) ? TRUE : FALSE;
  149. }
  150.  
  151. /**
  152.  * Returns true if all non-void channels are normalized signed.
  153.  */
  154. boolean
  155. util_format_is_snorm(enum pipe_format format)
  156. {
  157.    const struct util_format_description *desc = util_format_description(format);
  158.    int i;
  159.  
  160.    if (desc->is_mixed)
  161.       return FALSE;
  162.  
  163.    i = util_format_get_first_non_void_channel(format);
  164.    if (i == -1)
  165.       return FALSE;
  166.  
  167.    return desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED &&
  168.           !desc->channel[i].pure_integer &&
  169.           desc->channel[i].normalized;
  170. }
  171.  
  172. boolean
  173. util_format_is_luminance_alpha(enum pipe_format format)
  174. {
  175.    const struct util_format_description *desc =
  176.       util_format_description(format);
  177.  
  178.    if ((desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
  179.         desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
  180.        desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_X &&
  181.        desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_X &&
  182.        desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_X &&
  183.        desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_Y) {
  184.       return TRUE;
  185.    }
  186.    return FALSE;
  187. }
  188.  
  189.  
  190. boolean
  191. util_format_is_intensity(enum pipe_format format)
  192. {
  193.    const struct util_format_description *desc =
  194.       util_format_description(format);
  195.  
  196.    if ((desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
  197.         desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
  198.        desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_X &&
  199.        desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_X &&
  200.        desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_X &&
  201.        desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_X) {
  202.       return TRUE;
  203.    }
  204.    return FALSE;
  205. }
  206.  
  207. boolean
  208. util_format_is_subsampled_422(enum pipe_format format)
  209. {
  210.    const struct util_format_description *desc =
  211.       util_format_description(format);
  212.  
  213.    return desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED &&
  214.       desc->block.width == 2 &&
  215.       desc->block.height == 1 &&
  216.       desc->block.bits == 32;
  217. }
  218.  
  219. boolean
  220. util_format_is_supported(enum pipe_format format, unsigned bind)
  221. {
  222.    if (util_format_is_s3tc(format) && !util_format_s3tc_enabled) {
  223.       return FALSE;
  224.    }
  225.  
  226. #ifndef TEXTURE_FLOAT_ENABLED
  227.    if ((bind & PIPE_BIND_RENDER_TARGET) &&
  228.        format != PIPE_FORMAT_R9G9B9E5_FLOAT &&
  229.        format != PIPE_FORMAT_R11G11B10_FLOAT &&
  230.        util_format_is_float(format)) {
  231.       return FALSE;
  232.    }
  233. #endif
  234.  
  235.    return TRUE;
  236. }
  237.  
  238.  
  239. /**
  240.  * Calculates the MRD for the depth format. MRD is used in depth bias
  241.  * for UNORM and unbound depth buffers. When the depth buffer is floating
  242.  * point, the depth bias calculation does not use the MRD. However, the
  243.  * default MRD will be 1.0 / ((1 << 24) - 1).
  244.  */
  245. double
  246. util_get_depth_format_mrd(const struct util_format_description *desc)
  247. {
  248.    /*
  249.     * Depth buffer formats without a depth component OR scenarios
  250.     * without a bound depth buffer default to D24.
  251.     */
  252.    double mrd = 1.0 / ((1 << 24) - 1);
  253.    unsigned depth_channel;
  254.  
  255.    assert(desc);
  256.  
  257.    /*
  258.     * Some depth formats do not store the depth component in the first
  259.     * channel, detect the format and adjust the depth channel. Get the
  260.     * swizzled depth component channel.
  261.     */
  262.    depth_channel = desc->swizzle[0];
  263.  
  264.    if (desc->channel[depth_channel].type == UTIL_FORMAT_TYPE_UNSIGNED &&
  265.        desc->channel[depth_channel].normalized) {
  266.       int depth_bits;
  267.  
  268.       depth_bits = desc->channel[depth_channel].size;
  269.       mrd = 1.0 / ((1ULL << depth_bits) - 1);
  270.    }
  271.  
  272.    return mrd;
  273. }
  274.  
  275.  
  276. void
  277. util_format_read_4f(enum pipe_format format,
  278.                     float *dst, unsigned dst_stride,
  279.                     const void *src, unsigned src_stride,
  280.                     unsigned x, unsigned y, unsigned w, unsigned h)
  281. {
  282.    const struct util_format_description *format_desc;
  283.    const uint8_t *src_row;
  284.    float *dst_row;
  285.  
  286.    format_desc = util_format_description(format);
  287.  
  288.    assert(x % format_desc->block.width == 0);
  289.    assert(y % format_desc->block.height == 0);
  290.  
  291.    src_row = (const uint8_t *)src + y*src_stride + x*(format_desc->block.bits/8);
  292.    dst_row = dst;
  293.  
  294.    format_desc->unpack_rgba_float(dst_row, dst_stride, src_row, src_stride, w, h);
  295. }
  296.  
  297.  
  298. void
  299. util_format_write_4f(enum pipe_format format,
  300.                      const float *src, unsigned src_stride,
  301.                      void *dst, unsigned dst_stride,
  302.                      unsigned x, unsigned y, unsigned w, unsigned h)
  303. {
  304.    const struct util_format_description *format_desc;
  305.    uint8_t *dst_row;
  306.    const float *src_row;
  307.  
  308.    format_desc = util_format_description(format);
  309.  
  310.    assert(x % format_desc->block.width == 0);
  311.    assert(y % format_desc->block.height == 0);
  312.  
  313.    dst_row = (uint8_t *)dst + y*dst_stride + x*(format_desc->block.bits/8);
  314.    src_row = src;
  315.  
  316.    format_desc->pack_rgba_float(dst_row, dst_stride, src_row, src_stride, w, h);
  317. }
  318.  
  319.  
  320. void
  321. util_format_read_4ub(enum pipe_format format, uint8_t *dst, unsigned dst_stride, const void *src, unsigned src_stride, unsigned x, unsigned y, unsigned w, unsigned h)
  322. {
  323.    const struct util_format_description *format_desc;
  324.    const uint8_t *src_row;
  325.    uint8_t *dst_row;
  326.  
  327.    format_desc = util_format_description(format);
  328.  
  329.    assert(x % format_desc->block.width == 0);
  330.    assert(y % format_desc->block.height == 0);
  331.  
  332.    src_row = (const uint8_t *)src + y*src_stride + x*(format_desc->block.bits/8);
  333.    dst_row = dst;
  334.  
  335.    format_desc->unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, w, h);
  336. }
  337.  
  338.  
  339. void
  340. util_format_write_4ub(enum pipe_format format, const uint8_t *src, unsigned src_stride, void *dst, unsigned dst_stride, unsigned x, unsigned y, unsigned w, unsigned h)
  341. {
  342.    const struct util_format_description *format_desc;
  343.    uint8_t *dst_row;
  344.    const uint8_t *src_row;
  345.  
  346.    format_desc = util_format_description(format);
  347.  
  348.    assert(x % format_desc->block.width == 0);
  349.    assert(y % format_desc->block.height == 0);
  350.  
  351.    dst_row = (uint8_t *)dst + y*dst_stride + x*(format_desc->block.bits/8);
  352.    src_row = src;
  353.  
  354.    format_desc->pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, w, h);
  355. }
  356.  
  357. void
  358. util_format_read_4ui(enum pipe_format format,
  359.                      unsigned *dst, unsigned dst_stride,
  360.                      const void *src, unsigned src_stride,
  361.                      unsigned x, unsigned y, unsigned w, unsigned h)
  362. {
  363.    const struct util_format_description *format_desc;
  364.    const uint8_t *src_row;
  365.    uint32_t *dst_row;
  366.  
  367.    format_desc = util_format_description(format);
  368.  
  369.    assert(x % format_desc->block.width == 0);
  370.    assert(y % format_desc->block.height == 0);
  371.  
  372.    src_row = (const uint8_t *)src + y*src_stride + x*(format_desc->block.bits/8);
  373.    dst_row = dst;
  374.  
  375.    format_desc->unpack_rgba_uint(dst_row, dst_stride, src_row, src_stride, w, h);
  376. }
  377.  
  378. void
  379. util_format_write_4ui(enum pipe_format format,
  380.                       const unsigned int *src, unsigned src_stride,
  381.                       void *dst, unsigned dst_stride,
  382.                       unsigned x, unsigned y, unsigned w, unsigned h)
  383. {
  384.    const struct util_format_description *format_desc;
  385.    uint8_t *dst_row;
  386.    const uint32_t *src_row;
  387.  
  388.    format_desc = util_format_description(format);
  389.  
  390.    assert(x % format_desc->block.width == 0);
  391.    assert(y % format_desc->block.height == 0);
  392.  
  393.    dst_row = (uint8_t *)dst + y*dst_stride + x*(format_desc->block.bits/8);
  394.    src_row = src;
  395.  
  396.    format_desc->pack_rgba_uint(dst_row, dst_stride, src_row, src_stride, w, h);
  397. }
  398.  
  399. void
  400. util_format_read_4i(enum pipe_format format,
  401.                     int *dst, unsigned dst_stride,
  402.                     const void *src, unsigned src_stride,
  403.                     unsigned x, unsigned y, unsigned w, unsigned h)
  404. {
  405.    const struct util_format_description *format_desc;
  406.    const uint8_t *src_row;
  407.    int32_t *dst_row;
  408.  
  409.    format_desc = util_format_description(format);
  410.  
  411.    assert(x % format_desc->block.width == 0);
  412.    assert(y % format_desc->block.height == 0);
  413.  
  414.    src_row = (const uint8_t *)src + y*src_stride + x*(format_desc->block.bits/8);
  415.    dst_row = dst;
  416.  
  417.    format_desc->unpack_rgba_sint(dst_row, dst_stride, src_row, src_stride, w, h);
  418. }
  419.  
  420. void
  421. util_format_write_4i(enum pipe_format format,
  422.                       const int *src, unsigned src_stride,
  423.                       void *dst, unsigned dst_stride,
  424.                       unsigned x, unsigned y, unsigned w, unsigned h)
  425. {
  426.    const struct util_format_description *format_desc;
  427.    uint8_t *dst_row;
  428.    const int32_t *src_row;
  429.  
  430.    format_desc = util_format_description(format);
  431.  
  432.    assert(x % format_desc->block.width == 0);
  433.    assert(y % format_desc->block.height == 0);
  434.  
  435.    dst_row = (uint8_t *)dst + y*dst_stride + x*(format_desc->block.bits/8);
  436.    src_row = src;
  437.  
  438.    format_desc->pack_rgba_sint(dst_row, dst_stride, src_row, src_stride, w, h);
  439. }
  440.  
  441. boolean
  442. util_is_format_compatible(const struct util_format_description *src_desc,
  443.                           const struct util_format_description *dst_desc)
  444. {
  445.    unsigned chan;
  446.  
  447.    if (src_desc->format == dst_desc->format) {
  448.       return TRUE;
  449.    }
  450.  
  451.    if (src_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN ||
  452.        dst_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
  453.       return FALSE;
  454.    }
  455.  
  456.    if (src_desc->block.bits != dst_desc->block.bits ||
  457.        src_desc->nr_channels != dst_desc->nr_channels ||
  458.        src_desc->colorspace != dst_desc->colorspace) {
  459.       return FALSE;
  460.    }
  461.  
  462.    for (chan = 0; chan < 4; ++chan) {
  463.       if (src_desc->channel[chan].size !=
  464.           dst_desc->channel[chan].size) {
  465.          return FALSE;
  466.       }
  467.    }
  468.  
  469.    for (chan = 0; chan < 4; ++chan) {
  470.       enum util_format_swizzle swizzle = dst_desc->swizzle[chan];
  471.  
  472.       if (swizzle < 4) {
  473.          if (src_desc->swizzle[chan] != swizzle) {
  474.             return FALSE;
  475.          }
  476.          if ((src_desc->channel[swizzle].type !=
  477.               dst_desc->channel[swizzle].type) ||
  478.              (src_desc->channel[swizzle].normalized !=
  479.               dst_desc->channel[swizzle].normalized)) {
  480.             return FALSE;
  481.          }
  482.       }
  483.    }
  484.  
  485.    return TRUE;
  486. }
  487.  
  488.  
  489. boolean
  490. util_format_fits_8unorm(const struct util_format_description *format_desc)
  491. {
  492.    unsigned chan;
  493.  
  494.    /*
  495.     * After linearized sRGB values require more than 8bits.
  496.     */
  497.  
  498.    if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
  499.       return FALSE;
  500.    }
  501.  
  502.    switch (format_desc->layout) {
  503.  
  504.    case UTIL_FORMAT_LAYOUT_S3TC:
  505.       /*
  506.        * These are straight forward.
  507.        */
  508.       return TRUE;
  509.    case UTIL_FORMAT_LAYOUT_RGTC:
  510.       if (format_desc->format == PIPE_FORMAT_RGTC1_SNORM ||
  511.           format_desc->format == PIPE_FORMAT_RGTC2_SNORM ||
  512.           format_desc->format == PIPE_FORMAT_LATC1_SNORM ||
  513.           format_desc->format == PIPE_FORMAT_LATC2_SNORM)
  514.          return FALSE;
  515.       return TRUE;
  516.    case UTIL_FORMAT_LAYOUT_BPTC:
  517.       if (format_desc->format == PIPE_FORMAT_BPTC_RGBA_UNORM)
  518.          return TRUE;
  519.       return FALSE;
  520.  
  521.    case UTIL_FORMAT_LAYOUT_PLAIN:
  522.       /*
  523.        * For these we can find a generic rule.
  524.        */
  525.  
  526.       for (chan = 0; chan < format_desc->nr_channels; ++chan) {
  527.          switch (format_desc->channel[chan].type) {
  528.          case UTIL_FORMAT_TYPE_VOID:
  529.             break;
  530.          case UTIL_FORMAT_TYPE_UNSIGNED:
  531.             if (!format_desc->channel[chan].normalized ||
  532.                 format_desc->channel[chan].size > 8) {
  533.                return FALSE;
  534.             }
  535.             break;
  536.          default:
  537.             return FALSE;
  538.          }
  539.       }
  540.       return TRUE;
  541.  
  542.    default:
  543.       /*
  544.        * Handle all others on a case by case basis.
  545.        */
  546.  
  547.       switch (format_desc->format) {
  548.       case PIPE_FORMAT_R1_UNORM:
  549.       case PIPE_FORMAT_UYVY:
  550.       case PIPE_FORMAT_YUYV:
  551.       case PIPE_FORMAT_R8G8_B8G8_UNORM:
  552.       case PIPE_FORMAT_G8R8_G8B8_UNORM:
  553.          return TRUE;
  554.  
  555.       default:
  556.          return FALSE;
  557.       }
  558.    }
  559. }
  560.  
  561.  
  562. boolean
  563. util_format_translate(enum pipe_format dst_format,
  564.                       void *dst, unsigned dst_stride,
  565.                       unsigned dst_x, unsigned dst_y,
  566.                       enum pipe_format src_format,
  567.                       const void *src, unsigned src_stride,
  568.                       unsigned src_x, unsigned src_y,
  569.                       unsigned width, unsigned height)
  570. {
  571.    const struct util_format_description *dst_format_desc;
  572.    const struct util_format_description *src_format_desc;
  573.    uint8_t *dst_row;
  574.    const uint8_t *src_row;
  575.    unsigned x_step, y_step;
  576.    unsigned dst_step;
  577.    unsigned src_step;
  578.  
  579.    dst_format_desc = util_format_description(dst_format);
  580.    src_format_desc = util_format_description(src_format);
  581.  
  582.    if (util_is_format_compatible(src_format_desc, dst_format_desc)) {
  583.       /*
  584.        * Trivial case.
  585.        */
  586.  
  587.       util_copy_rect(dst, dst_format, dst_stride,  dst_x, dst_y,
  588.                      width, height, src, (int)src_stride,
  589.                      src_x, src_y);
  590.       return TRUE;
  591.    }
  592.  
  593.    assert(dst_x % dst_format_desc->block.width == 0);
  594.    assert(dst_y % dst_format_desc->block.height == 0);
  595.    assert(src_x % src_format_desc->block.width == 0);
  596.    assert(src_y % src_format_desc->block.height == 0);
  597.  
  598.    dst_row = (uint8_t *)dst + dst_y*dst_stride + dst_x*(dst_format_desc->block.bits/8);
  599.    src_row = (const uint8_t *)src + src_y*src_stride + src_x*(src_format_desc->block.bits/8);
  600.  
  601.    /*
  602.     * This works because all pixel formats have pixel blocks with power of two
  603.     * sizes.
  604.     */
  605.  
  606.    y_step = MAX2(dst_format_desc->block.height, src_format_desc->block.height);
  607.    x_step = MAX2(dst_format_desc->block.width, src_format_desc->block.width);
  608.    assert(y_step % dst_format_desc->block.height == 0);
  609.    assert(y_step % src_format_desc->block.height == 0);
  610.  
  611.    dst_step = y_step / dst_format_desc->block.height * dst_stride;
  612.    src_step = y_step / src_format_desc->block.height * src_stride;
  613.  
  614.    /*
  615.     * TODO: double formats will loose precision
  616.     * TODO: Add a special case for formats that are mere swizzles of each other
  617.     */
  618.  
  619.    if (src_format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS ||
  620.        dst_format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
  621.       float *tmp_z = NULL;
  622.       uint8_t *tmp_s = NULL;
  623.  
  624.       assert(x_step == 1);
  625.       assert(y_step == 1);
  626.  
  627.       if (src_format_desc->unpack_z_float &&
  628.           dst_format_desc->pack_z_float) {
  629.          tmp_z = MALLOC(width * sizeof *tmp_z);
  630.       }
  631.  
  632.       if (src_format_desc->unpack_s_8uint &&
  633.           dst_format_desc->pack_s_8uint) {
  634.          tmp_s = MALLOC(width * sizeof *tmp_s);
  635.       }
  636.  
  637.       while (height--) {
  638.          if (tmp_z) {
  639.             src_format_desc->unpack_z_float(tmp_z, 0, src_row, src_stride, width, 1);
  640.             dst_format_desc->pack_z_float(dst_row, dst_stride, tmp_z, 0, width, 1);
  641.          }
  642.  
  643.          if (tmp_s) {
  644.             src_format_desc->unpack_s_8uint(tmp_s, 0, src_row, src_stride, width, 1);
  645.             dst_format_desc->pack_s_8uint(dst_row, dst_stride, tmp_s, 0, width, 1);
  646.          }
  647.  
  648.          dst_row += dst_step;
  649.          src_row += src_step;
  650.       }
  651.  
  652.       FREE(tmp_s);
  653.  
  654.       FREE(tmp_z);
  655.  
  656.       return TRUE;
  657.    }
  658.  
  659.    if (util_format_fits_8unorm(src_format_desc) ||
  660.        util_format_fits_8unorm(dst_format_desc)) {
  661.       unsigned tmp_stride;
  662.       uint8_t *tmp_row;
  663.  
  664.       if (!src_format_desc->unpack_rgba_8unorm ||
  665.           !dst_format_desc->pack_rgba_8unorm) {
  666.          return FALSE;
  667.       }
  668.  
  669.       tmp_stride = MAX2(width, x_step) * 4 * sizeof *tmp_row;
  670.       tmp_row = MALLOC(y_step * tmp_stride);
  671.       if (!tmp_row)
  672.          return FALSE;
  673.  
  674.       while (height >= y_step) {
  675.          src_format_desc->unpack_rgba_8unorm(tmp_row, tmp_stride, src_row, src_stride, width, y_step);
  676.          dst_format_desc->pack_rgba_8unorm(dst_row, dst_stride, tmp_row, tmp_stride, width, y_step);
  677.  
  678.          dst_row += dst_step;
  679.          src_row += src_step;
  680.          height -= y_step;
  681.       }
  682.  
  683.       if (height) {
  684.          src_format_desc->unpack_rgba_8unorm(tmp_row, tmp_stride, src_row, src_stride, width, height);
  685.          dst_format_desc->pack_rgba_8unorm(dst_row, dst_stride, tmp_row, tmp_stride, width, height);
  686.       }
  687.  
  688.       FREE(tmp_row);
  689.    }
  690.    else {
  691.       unsigned tmp_stride;
  692.       float *tmp_row;
  693.  
  694.       if (!src_format_desc->unpack_rgba_float ||
  695.           !dst_format_desc->pack_rgba_float) {
  696.          return FALSE;
  697.       }
  698.  
  699.       tmp_stride = MAX2(width, x_step) * 4 * sizeof *tmp_row;
  700.       tmp_row = MALLOC(y_step * tmp_stride);
  701.       if (!tmp_row)
  702.          return FALSE;
  703.  
  704.       while (height >= y_step) {
  705.          src_format_desc->unpack_rgba_float(tmp_row, tmp_stride, src_row, src_stride, width, y_step);
  706.          dst_format_desc->pack_rgba_float(dst_row, dst_stride, tmp_row, tmp_stride, width, y_step);
  707.  
  708.          dst_row += dst_step;
  709.          src_row += src_step;
  710.          height -= y_step;
  711.       }
  712.  
  713.       if (height) {
  714.          src_format_desc->unpack_rgba_float(tmp_row, tmp_stride, src_row, src_stride, width, height);
  715.          dst_format_desc->pack_rgba_float(dst_row, dst_stride, tmp_row, tmp_stride, width, height);
  716.       }
  717.  
  718.       FREE(tmp_row);
  719.    }
  720.    return TRUE;
  721. }
  722.  
  723. void util_format_compose_swizzles(const unsigned char swz1[4],
  724.                                   const unsigned char swz2[4],
  725.                                   unsigned char dst[4])
  726. {
  727.    unsigned i;
  728.  
  729.    for (i = 0; i < 4; i++) {
  730.       dst[i] = swz2[i] <= UTIL_FORMAT_SWIZZLE_W ?
  731.                swz1[swz2[i]] : swz2[i];
  732.    }
  733. }
  734.  
  735. void util_format_apply_color_swizzle(union pipe_color_union *dst,
  736.                                      const union pipe_color_union *src,
  737.                                      const unsigned char swz[4],
  738.                                      const boolean is_integer)
  739. {
  740.    unsigned c;
  741.  
  742.    if (is_integer) {
  743.       for (c = 0; c < 4; ++c) {
  744.          switch (swz[c]) {
  745.          case PIPE_SWIZZLE_RED:   dst->ui[c] = src->ui[0]; break;
  746.          case PIPE_SWIZZLE_GREEN: dst->ui[c] = src->ui[1]; break;
  747.          case PIPE_SWIZZLE_BLUE:  dst->ui[c] = src->ui[2]; break;
  748.          case PIPE_SWIZZLE_ALPHA: dst->ui[c] = src->ui[3]; break;
  749.          default:
  750.             dst->ui[c] = (swz[c] == PIPE_SWIZZLE_ONE) ? 1 : 0;
  751.             break;
  752.          }
  753.       }
  754.    } else {
  755.       for (c = 0; c < 4; ++c) {
  756.          switch (swz[c]) {
  757.          case PIPE_SWIZZLE_RED:   dst->f[c] = src->f[0]; break;
  758.          case PIPE_SWIZZLE_GREEN: dst->f[c] = src->f[1]; break;
  759.          case PIPE_SWIZZLE_BLUE:  dst->f[c] = src->f[2]; break;
  760.          case PIPE_SWIZZLE_ALPHA: dst->f[c] = src->f[3]; break;
  761.          default:
  762.             dst->f[c] = (swz[c] == PIPE_SWIZZLE_ONE) ? 1.0f : 0.0f;
  763.             break;
  764.          }
  765.       }
  766.    }
  767. }
  768.  
  769. void util_format_swizzle_4f(float *dst, const float *src,
  770.                             const unsigned char swz[4])
  771. {
  772.    unsigned i;
  773.  
  774.    for (i = 0; i < 4; i++) {
  775.       if (swz[i] <= UTIL_FORMAT_SWIZZLE_W)
  776.          dst[i] = src[swz[i]];
  777.       else if (swz[i] == UTIL_FORMAT_SWIZZLE_0)
  778.          dst[i] = 0;
  779.       else if (swz[i] == UTIL_FORMAT_SWIZZLE_1)
  780.          dst[i] = 1;
  781.    }
  782. }
  783.  
  784. void util_format_unswizzle_4f(float *dst, const float *src,
  785.                               const unsigned char swz[4])
  786. {
  787.    unsigned i;
  788.  
  789.    for (i = 0; i < 4; i++) {
  790.       switch (swz[i]) {
  791.       case UTIL_FORMAT_SWIZZLE_X:
  792.          dst[0] = src[i];
  793.          break;
  794.       case UTIL_FORMAT_SWIZZLE_Y:
  795.          dst[1] = src[i];
  796.          break;
  797.       case UTIL_FORMAT_SWIZZLE_Z:
  798.          dst[2] = src[i];
  799.          break;
  800.       case UTIL_FORMAT_SWIZZLE_W:
  801.          dst[3] = src[i];
  802.          break;
  803.       }
  804.    }
  805. }
  806.