Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 2014  Intel Corporation  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 "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. #include "format_utils.h"
  26. #include "glformats.h"
  27. #include "format_pack.h"
  28. #include "format_unpack.h"
  29.  
  30. const mesa_array_format RGBA32_FLOAT =
  31.    MESA_ARRAY_FORMAT(4, 1, 1, 1, 4, 0, 1, 2, 3);
  32.  
  33. const mesa_array_format RGBA8_UBYTE =
  34.    MESA_ARRAY_FORMAT(1, 0, 0, 1, 4, 0, 1, 2, 3);
  35.  
  36. const mesa_array_format RGBA32_UINT =
  37.    MESA_ARRAY_FORMAT(4, 0, 0, 0, 4, 0, 1, 2, 3);
  38.  
  39. const mesa_array_format RGBA32_INT =
  40.    MESA_ARRAY_FORMAT(4, 1, 0, 0, 4, 0, 1, 2, 3);
  41.  
  42. static void
  43. invert_swizzle(uint8_t dst[4], const uint8_t src[4])
  44. {
  45.    int i, j;
  46.  
  47.    dst[0] = MESA_FORMAT_SWIZZLE_NONE;
  48.    dst[1] = MESA_FORMAT_SWIZZLE_NONE;
  49.    dst[2] = MESA_FORMAT_SWIZZLE_NONE;
  50.    dst[3] = MESA_FORMAT_SWIZZLE_NONE;
  51.  
  52.    for (i = 0; i < 4; ++i)
  53.       for (j = 0; j < 4; ++j)
  54.          if (src[j] == i && dst[i] == MESA_FORMAT_SWIZZLE_NONE)
  55.             dst[i] = j;
  56. }
  57.  
  58. /* Takes a src to RGBA swizzle and applies a rebase swizzle to it. This
  59.  * is used when we need to rebase a format to match a different
  60.  * base internal format.
  61.  *
  62.  * The rebase swizzle can be NULL, which means that no rebase is necessary,
  63.  * in which case the src to RGBA swizzle is copied to the output without
  64.  * changes.
  65.  *
  66.  * The resulting rebased swizzle and well as the input swizzles are
  67.  * all 4-element swizzles, but the rebase swizzle can be NULL if no rebase
  68.  * is necessary.
  69.  */
  70. static void
  71. compute_rebased_rgba_component_mapping(uint8_t *src2rgba,
  72.                                        uint8_t *rebase_swizzle,
  73.                                        uint8_t *rebased_src2rgba)
  74. {
  75.    int i;
  76.  
  77.    if (rebase_swizzle) {
  78.       for (i = 0; i < 4; i++) {
  79.          if (rebase_swizzle[i] > MESA_FORMAT_SWIZZLE_W)
  80.             rebased_src2rgba[i] = rebase_swizzle[i];
  81.          else
  82.             rebased_src2rgba[i] = src2rgba[rebase_swizzle[i]];
  83.       }
  84.    } else {
  85.       /* No rebase needed, so src2rgba is all that we need */
  86.       memcpy(rebased_src2rgba, src2rgba, 4 * sizeof(uint8_t));
  87.    }
  88. }
  89.  
  90. /* Computes the final swizzle transform to apply from src to dst in a
  91.  * conversion that might involve a rebase swizzle.
  92.  *
  93.  * This is used to compute the swizzle transform to apply in conversions
  94.  * between array formats where we have a src2rgba swizzle, a rgba2dst swizzle
  95.  * and possibly, a rebase swizzle.
  96.  *
  97.  * The final swizzle transform to apply (src2dst) when a rebase swizzle is
  98.  * involved is: src -> rgba -> base -> rgba -> dst
  99.  */
  100. static void
  101. compute_src2dst_component_mapping(uint8_t *src2rgba, uint8_t *rgba2dst,
  102.                                   uint8_t *rebase_swizzle, uint8_t *src2dst)
  103. {
  104.    int i;
  105.  
  106.    if (!rebase_swizzle) {
  107.       for (i = 0; i < 4; i++) {
  108.          if (rgba2dst[i] > MESA_FORMAT_SWIZZLE_W) {
  109.             src2dst[i] = rgba2dst[i];
  110.          } else {
  111.             src2dst[i] = src2rgba[rgba2dst[i]];
  112.          }
  113.       }
  114.    } else {
  115.       for (i = 0; i < 4; i++) {
  116.          if (rgba2dst[i] > MESA_FORMAT_SWIZZLE_W) {
  117.             src2dst[i] = rgba2dst[i];
  118.          } else if (rebase_swizzle[rgba2dst[i]] > MESA_FORMAT_SWIZZLE_W) {
  119.             src2dst[i] = rebase_swizzle[rgba2dst[i]];
  120.          } else {
  121.             src2dst[i] = src2rgba[rebase_swizzle[rgba2dst[i]]];
  122.          }
  123.       }
  124.    }
  125. }
  126.  
  127. /**
  128.  * This function is used by clients of _mesa_format_convert to obtain
  129.  * the rebase swizzle to use in a format conversion based on the base
  130.  * format involved.
  131.  *
  132.  * \param baseFormat  the base internal format involved in the conversion.
  133.  * \param map  the rebase swizzle to consider
  134.  *
  135.  * This function computes 'map' as rgba -> baseformat -> rgba and returns true
  136.  * if the resulting swizzle transform is not the identity transform (thus, a
  137.  * rebase is needed). If the function returns false then a rebase swizzle
  138.  * is not necessary and the value of 'map' is undefined. In this situation
  139.  * clients of _mesa_format_convert should pass NULL in the 'rebase_swizzle'
  140.  * parameter.
  141.  */
  142. bool
  143. _mesa_compute_rgba2base2rgba_component_mapping(GLenum baseFormat, uint8_t *map)
  144. {
  145.    uint8_t rgba2base[6], base2rgba[6];
  146.    int i;
  147.  
  148.    switch (baseFormat) {
  149.    case GL_ALPHA:
  150.    case GL_RED:
  151.    case GL_GREEN:
  152.    case GL_BLUE:
  153.    case GL_RG:
  154.    case GL_RGB:
  155.    case GL_BGR:
  156.    case GL_RGBA:
  157.    case GL_BGRA:
  158.    case GL_ABGR_EXT:
  159.    case GL_LUMINANCE:
  160.    case GL_INTENSITY:
  161.    case GL_LUMINANCE_ALPHA:
  162.       {
  163.          bool needRebase = false;
  164.          _mesa_compute_component_mapping(GL_RGBA, baseFormat, rgba2base);
  165.          _mesa_compute_component_mapping(baseFormat, GL_RGBA, base2rgba);
  166.          for (i = 0; i < 4; i++) {
  167.             if (base2rgba[i] > MESA_FORMAT_SWIZZLE_W) {
  168.                map[i] = base2rgba[i];
  169.             } else {
  170.                map[i] = rgba2base[base2rgba[i]];
  171.             }
  172.             if (map[i] != i)
  173.                needRebase = true;
  174.          }
  175.          return needRebase;
  176.       }
  177.    default:
  178.       unreachable("Unexpected base format");
  179.    }
  180. }
  181.  
  182. /**
  183.  * This can be used to convert between most color formats.
  184.  *
  185.  * Limitations:
  186.  * - This function doesn't handle GL_COLOR_INDEX or YCBCR formats.
  187.  * - This function doesn't handle byte-swapping or transferOps, these should
  188.  *   be handled by the caller.
  189.  *
  190.  * \param void_dst  The address where converted color data will be stored.
  191.  *                  The caller must ensure that the buffer is large enough
  192.  *                  to hold the converted pixel data.
  193.  * \param dst_format  The destination color format. It can be a mesa_format
  194.  *                    or a mesa_array_format represented as an uint32_t.
  195.  * \param dst_stride  The stride of the destination format in bytes.
  196.  * \param void_src  The address of the source color data to convert.
  197.  * \param src_format  The source color format. It can be a mesa_format
  198.  *                    or a mesa_array_format represented as an uint32_t.
  199.  * \param src_stride  The stride of the source format in bytes.
  200.  * \param width  The width, in pixels, of the source image to convert.
  201.  * \param height  The height, in pixels, of the source image to convert.
  202.  * \param rebase_swizzle  A swizzle transform to apply during the conversion,
  203.  *                        typically used to match a different internal base
  204.  *                        format involved. NULL if no rebase transform is needed
  205.  *                        (i.e. the internal base format and the base format of
  206.  *                        the dst or the src -depending on whether we are doing
  207.  *                        an upload or a download respectively- are the same).
  208.  */
  209. void
  210. _mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride,
  211.                      void *void_src, uint32_t src_format, size_t src_stride,
  212.                      size_t width, size_t height, uint8_t *rebase_swizzle)
  213. {
  214.    uint8_t *dst = (uint8_t *)void_dst;
  215.    uint8_t *src = (uint8_t *)void_src;
  216.    mesa_array_format src_array_format, dst_array_format;
  217.    bool src_format_is_mesa_array_format, dst_format_is_mesa_array_format;
  218.    uint8_t src2dst[4], src2rgba[4], rgba2dst[4], dst2rgba[4];
  219.    uint8_t rebased_src2rgba[4];
  220.    enum mesa_array_format_datatype src_type = 0, dst_type = 0, common_type;
  221.    bool normalized, dst_integer, src_integer, is_signed;
  222.    int src_num_channels = 0, dst_num_channels = 0;
  223.    uint8_t (*tmp_ubyte)[4];
  224.    float (*tmp_float)[4];
  225.    uint32_t (*tmp_uint)[4];
  226.    int bits;
  227.    size_t row;
  228.  
  229.    if (_mesa_format_is_mesa_array_format(src_format)) {
  230.       src_format_is_mesa_array_format = true;
  231.       src_array_format = src_format;
  232.    } else {
  233.       assert(_mesa_is_format_color_format(src_format));
  234.       src_format_is_mesa_array_format = false;
  235.       src_array_format = _mesa_format_to_array_format(src_format);
  236.    }
  237.  
  238.    if (_mesa_format_is_mesa_array_format(dst_format)) {
  239.       dst_format_is_mesa_array_format = true;
  240.       dst_array_format = dst_format;
  241.    } else {
  242.       assert(_mesa_is_format_color_format(dst_format));
  243.       dst_format_is_mesa_array_format = false;
  244.       dst_array_format = _mesa_format_to_array_format(dst_format);
  245.    }
  246.  
  247.    /* First we see if we can implement the conversion with a direct pack
  248.     * or unpack.
  249.     *
  250.     * In this case we want to be careful when we need to apply a swizzle to
  251.     * match an internal base format, since in these cases a simple pack/unpack
  252.     * to the dst format from the src format may not match the requirements
  253.     * of the internal base format. For now we decide to be safe and
  254.     * avoid this path in these scenarios but in the future we may want to
  255.     * enable it for specific combinations that are known to work.
  256.     */
  257.    if (!rebase_swizzle) {
  258.       /* Handle the cases where we can directly unpack */
  259.       if (!src_format_is_mesa_array_format) {
  260.          if (dst_array_format == RGBA32_FLOAT) {
  261.             for (row = 0; row < height; ++row) {
  262.                _mesa_unpack_rgba_row(src_format, width,
  263.                                      src, (float (*)[4])dst);
  264.                src += src_stride;
  265.                dst += dst_stride;
  266.             }
  267.             return;
  268.          } else if (dst_array_format == RGBA8_UBYTE) {
  269.             assert(!_mesa_is_format_integer_color(src_format));
  270.             for (row = 0; row < height; ++row) {
  271.                _mesa_unpack_ubyte_rgba_row(src_format, width,
  272.                                            src, (uint8_t (*)[4])dst);
  273.                src += src_stride;
  274.                dst += dst_stride;
  275.             }
  276.             return;
  277.          } else if (dst_array_format == RGBA32_UINT &&
  278.                     _mesa_is_format_unsigned(src_format)) {
  279.             assert(_mesa_is_format_integer_color(src_format));
  280.             for (row = 0; row < height; ++row) {
  281.                _mesa_unpack_uint_rgba_row(src_format, width,
  282.                                           src, (uint32_t (*)[4])dst);
  283.                src += src_stride;
  284.                dst += dst_stride;
  285.             }
  286.             return;
  287.          }
  288.       }
  289.  
  290.       /* Handle the cases where we can directly pack */
  291.       if (!dst_format_is_mesa_array_format) {
  292.          if (src_array_format == RGBA32_FLOAT) {
  293.             for (row = 0; row < height; ++row) {
  294.                _mesa_pack_float_rgba_row(dst_format, width,
  295.                                          (const float (*)[4])src, dst);
  296.                src += src_stride;
  297.                dst += dst_stride;
  298.             }
  299.             return;
  300.          } else if (src_array_format == RGBA8_UBYTE) {
  301.             assert(!_mesa_is_format_integer_color(dst_format));
  302.             for (row = 0; row < height; ++row) {
  303.                _mesa_pack_ubyte_rgba_row(dst_format, width,
  304.                                          (const uint8_t (*)[4])src, dst);
  305.                src += src_stride;
  306.                dst += dst_stride;
  307.             }
  308.             return;
  309.          } else if (src_array_format == RGBA32_UINT &&
  310.                     _mesa_is_format_unsigned(dst_format)) {
  311.             assert(_mesa_is_format_integer_color(dst_format));
  312.             for (row = 0; row < height; ++row) {
  313.                _mesa_pack_uint_rgba_row(dst_format, width,
  314.                                         (const uint32_t (*)[4])src, dst);
  315.                src += src_stride;
  316.                dst += dst_stride;
  317.             }
  318.             return;
  319.          }
  320.       }
  321.    }
  322.  
  323.    /* Handle conversions between array formats */
  324.    normalized = false;
  325.    if (src_array_format) {
  326.       src_type = _mesa_array_format_get_datatype(src_array_format);
  327.  
  328.       src_num_channels = _mesa_array_format_get_num_channels(src_array_format);
  329.  
  330.       _mesa_array_format_get_swizzle(src_array_format, src2rgba);
  331.  
  332.       normalized = _mesa_array_format_is_normalized(src_array_format);
  333.    }
  334.  
  335.    if (dst_array_format) {
  336.       dst_type = _mesa_array_format_get_datatype(dst_array_format);
  337.  
  338.       dst_num_channels = _mesa_array_format_get_num_channels(dst_array_format);
  339.  
  340.       _mesa_array_format_get_swizzle(dst_array_format, dst2rgba);
  341.       invert_swizzle(rgba2dst, dst2rgba);
  342.  
  343.       normalized |= _mesa_array_format_is_normalized(dst_array_format);
  344.    }
  345.  
  346.    if (src_array_format && dst_array_format) {
  347.       assert(_mesa_array_format_is_normalized(src_array_format) ==
  348.              _mesa_array_format_is_normalized(dst_array_format));
  349.  
  350.       compute_src2dst_component_mapping(src2rgba, rgba2dst, rebase_swizzle,
  351.                                         src2dst);
  352.  
  353.       for (row = 0; row < height; ++row) {
  354.          _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels,
  355.                                    src, src_type, src_num_channels,
  356.                                    src2dst, normalized, width);
  357.          src += src_stride;
  358.          dst += dst_stride;
  359.       }
  360.       return;
  361.    }
  362.  
  363.    /* At this point, we're fresh out of fast-paths and we need to convert
  364.     * to float, uint32, or, if we're lucky, uint8.
  365.     */
  366.    dst_integer = false;
  367.    src_integer = false;
  368.  
  369.    if (src_array_format) {
  370.       if (!_mesa_array_format_is_float(src_array_format) &&
  371.           !_mesa_array_format_is_normalized(src_array_format))
  372.          src_integer = true;
  373.    } else {
  374.       switch (_mesa_get_format_datatype(src_format)) {
  375.       case GL_UNSIGNED_INT:
  376.       case GL_INT:
  377.          src_integer = true;
  378.          break;
  379.       }
  380.    }
  381.  
  382.    /* If the destination format is signed but the source is unsigned, then we
  383.     * don't loose any data by converting to a signed intermediate format above
  384.     * and beyond the precision that we loose in the conversion itself. If the
  385.     * destination is unsigned then, by using an unsigned intermediate format,
  386.     * we make the conversion function that converts from the source to the
  387.     * intermediate format take care of truncating at zero. The exception here
  388.     * is if the intermediate format is float, in which case the first
  389.     * conversion will leave it signed and the second conversion will truncate
  390.     * at zero.
  391.     */
  392.    is_signed = false;
  393.    if (dst_array_format) {
  394.       if (!_mesa_array_format_is_float(dst_array_format) &&
  395.           !_mesa_array_format_is_normalized(dst_array_format))
  396.          dst_integer = true;
  397.       is_signed = _mesa_array_format_is_signed(dst_array_format);
  398.       bits = 8 * _mesa_array_format_get_type_size(dst_array_format);
  399.    } else {
  400.       switch (_mesa_get_format_datatype(dst_format)) {
  401.       case GL_UNSIGNED_NORMALIZED:
  402.          is_signed = false;
  403.          break;
  404.       case GL_SIGNED_NORMALIZED:
  405.          is_signed = true;
  406.          break;
  407.       case GL_FLOAT:
  408.          is_signed = true;
  409.          break;
  410.       case GL_UNSIGNED_INT:
  411.          is_signed = false;
  412.          dst_integer = true;
  413.          break;
  414.       case GL_INT:
  415.          is_signed = true;
  416.          dst_integer = true;
  417.          break;
  418.       }
  419.       bits = _mesa_get_format_max_bits(dst_format);
  420.    }
  421.  
  422.    assert(src_integer == dst_integer);
  423.  
  424.    if (src_integer && dst_integer) {
  425.       tmp_uint = malloc(width * height * sizeof(*tmp_uint));
  426.  
  427.       /* The [un]packing functions for unsigned datatypes treat the 32-bit
  428.        * integer array as signed for signed formats and as unsigned for
  429.        * unsigned formats. This is a bit of a problem if we ever convert from
  430.        * a signed to an unsigned format because the unsigned packing function
  431.        * doesn't know that the input is signed and will treat it as unsigned
  432.        * and not do the trunctation. The thing that saves us here is that all
  433.        * of the packed formats are unsigned, so we can just always use
  434.        * _mesa_swizzle_and_convert for signed formats, which is aware of the
  435.        * truncation problem.
  436.        */
  437.       common_type = is_signed ? MESA_ARRAY_FORMAT_TYPE_INT :
  438.                                 MESA_ARRAY_FORMAT_TYPE_UINT;
  439.       if (src_array_format) {
  440.          compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle,
  441.                                                 rebased_src2rgba);
  442.          for (row = 0; row < height; ++row) {
  443.             _mesa_swizzle_and_convert(tmp_uint + row * width, common_type, 4,
  444.                                       src, src_type, src_num_channels,
  445.                                       rebased_src2rgba, normalized, width);
  446.             src += src_stride;
  447.          }
  448.       } else {
  449.          for (row = 0; row < height; ++row) {
  450.             _mesa_unpack_uint_rgba_row(src_format, width,
  451.                                        src, tmp_uint + row * width);
  452.             if (rebase_swizzle)
  453.                _mesa_swizzle_and_convert(tmp_uint + row * width, common_type, 4,
  454.                                          tmp_uint + row * width, common_type, 4,
  455.                                          rebase_swizzle, false, width);
  456.             src += src_stride;
  457.          }
  458.       }
  459.  
  460.       /* At this point, we have already done the truncation if the source is
  461.        * signed but the destination is unsigned, so no need to force the
  462.        * _mesa_swizzle_and_convert path.
  463.        */
  464.       if (dst_format_is_mesa_array_format) {
  465.          for (row = 0; row < height; ++row) {
  466.             _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels,
  467.                                       tmp_uint + row * width, common_type, 4,
  468.                                       rgba2dst, normalized, width);
  469.             dst += dst_stride;
  470.          }
  471.       } else {
  472.          for (row = 0; row < height; ++row) {
  473.             _mesa_pack_uint_rgba_row(dst_format, width,
  474.                                      (const uint32_t (*)[4])tmp_uint + row * width, dst);
  475.             dst += dst_stride;
  476.          }
  477.       }
  478.  
  479.       free(tmp_uint);
  480.    } else if (is_signed || bits > 8) {
  481.       tmp_float = malloc(width * height * sizeof(*tmp_float));
  482.  
  483.       if (src_format_is_mesa_array_format) {
  484.          compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle,
  485.                                                 rebased_src2rgba);
  486.          for (row = 0; row < height; ++row) {
  487.             _mesa_swizzle_and_convert(tmp_float + row * width,
  488.                                       MESA_ARRAY_FORMAT_TYPE_FLOAT, 4,
  489.                                       src, src_type, src_num_channels,
  490.                                       rebased_src2rgba, normalized, width);
  491.             src += src_stride;
  492.          }
  493.       } else {
  494.          for (row = 0; row < height; ++row) {
  495.             _mesa_unpack_rgba_row(src_format, width,
  496.                                   src, tmp_float + row * width);
  497.             if (rebase_swizzle)
  498.                _mesa_swizzle_and_convert(tmp_float + row * width,
  499.                                          MESA_ARRAY_FORMAT_TYPE_FLOAT, 4,
  500.                                          tmp_float + row * width,
  501.                                          MESA_ARRAY_FORMAT_TYPE_FLOAT, 4,
  502.                                          rebase_swizzle, normalized, width);
  503.             src += src_stride;
  504.          }
  505.       }
  506.  
  507.       if (dst_format_is_mesa_array_format) {
  508.          for (row = 0; row < height; ++row) {
  509.             _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels,
  510.                                       tmp_float + row * width,
  511.                                       MESA_ARRAY_FORMAT_TYPE_FLOAT, 4,
  512.                                       rgba2dst, normalized, width);
  513.             dst += dst_stride;
  514.          }
  515.       } else {
  516.          for (row = 0; row < height; ++row) {
  517.             _mesa_pack_float_rgba_row(dst_format, width,
  518.                                       (const float (*)[4])tmp_float + row * width, dst);
  519.             dst += dst_stride;
  520.          }
  521.       }
  522.  
  523.       free(tmp_float);
  524.    } else {
  525.       tmp_ubyte = malloc(width * height * sizeof(*tmp_ubyte));
  526.  
  527.       if (src_format_is_mesa_array_format) {
  528.          compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle,
  529.                                                 rebased_src2rgba);
  530.          for (row = 0; row < height; ++row) {
  531.             _mesa_swizzle_and_convert(tmp_ubyte + row * width,
  532.                                       MESA_ARRAY_FORMAT_TYPE_UBYTE, 4,
  533.                                       src, src_type, src_num_channels,
  534.                                       rebased_src2rgba, normalized, width);
  535.             src += src_stride;
  536.          }
  537.       } else {
  538.          for (row = 0; row < height; ++row) {
  539.             _mesa_unpack_ubyte_rgba_row(src_format, width,
  540.                                         src, tmp_ubyte + row * width);
  541.             if (rebase_swizzle)
  542.                _mesa_swizzle_and_convert(tmp_ubyte + row * width,
  543.                                          MESA_ARRAY_FORMAT_TYPE_UBYTE, 4,
  544.                                          tmp_ubyte + row * width,
  545.                                          MESA_ARRAY_FORMAT_TYPE_UBYTE, 4,
  546.                                          rebase_swizzle, normalized, width);
  547.             src += src_stride;
  548.          }
  549.       }
  550.  
  551.       if (dst_format_is_mesa_array_format) {
  552.          for (row = 0; row < height; ++row) {
  553.             _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels,
  554.                                       tmp_ubyte + row * width,
  555.                                       MESA_ARRAY_FORMAT_TYPE_UBYTE, 4,
  556.                                       rgba2dst, normalized, width);
  557.             dst += dst_stride;
  558.          }
  559.       } else {
  560.          for (row = 0; row < height; ++row) {
  561.             _mesa_pack_ubyte_rgba_row(dst_format, width,
  562.                                       (const uint8_t (*)[4])tmp_ubyte + row * width, dst);
  563.             dst += dst_stride;
  564.          }
  565.       }
  566.  
  567.       free(tmp_ubyte);
  568.    }
  569. }
  570.  
  571. static const uint8_t map_identity[7] = { 0, 1, 2, 3, 4, 5, 6 };
  572. static const uint8_t map_3210[7] = { 3, 2, 1, 0, 4, 5, 6 };
  573. static const uint8_t map_1032[7] = { 1, 0, 3, 2, 4, 5, 6 };
  574.  
  575. /**
  576.  * Describes a format as an array format, if possible
  577.  *
  578.  * A helper function for figuring out if a (possibly packed) format is
  579.  * actually an array format and, if so, what the array parameters are.
  580.  *
  581.  * \param[in]  format         the mesa format
  582.  * \param[out] type           the GL type of the array (GL_BYTE, etc.)
  583.  * \param[out] num_components the number of components in the array
  584.  * \param[out] swizzle        a swizzle describing how to get from the
  585.  *                            given format to RGBA
  586.  * \param[out] normalized     for integer formats, this represents whether
  587.  *                            the format is a normalized integer or a
  588.  *                            regular integer
  589.  * \return  true if this format is an array format, false otherwise
  590.  */
  591. bool
  592. _mesa_format_to_array(mesa_format format, GLenum *type, int *num_components,
  593.                       uint8_t swizzle[4], bool *normalized)
  594. {
  595.    int i;
  596.    GLuint format_components;
  597.    uint8_t packed_swizzle[4];
  598.    const uint8_t *endian;
  599.  
  600.    if (_mesa_is_format_compressed(format))
  601.       return false;
  602.  
  603.    *normalized = !_mesa_is_format_integer(format);
  604.  
  605.    _mesa_format_to_type_and_comps(format, type, &format_components);
  606.  
  607.    switch (_mesa_get_format_layout(format)) {
  608.    case MESA_FORMAT_LAYOUT_ARRAY:
  609.       *num_components = format_components;
  610.       _mesa_get_format_swizzle(format, swizzle);
  611.       return true;
  612.    case MESA_FORMAT_LAYOUT_PACKED:
  613.       switch (*type) {
  614.       case GL_UNSIGNED_BYTE:
  615.       case GL_BYTE:
  616.          if (_mesa_get_format_max_bits(format) != 8)
  617.             return false;
  618.          *num_components = _mesa_get_format_bytes(format);
  619.          switch (*num_components) {
  620.          case 1:
  621.             endian = map_identity;
  622.             break;
  623.          case 2:
  624.             endian = _mesa_little_endian() ? map_identity : map_1032;
  625.             break;
  626.          case 4:
  627.             endian = _mesa_little_endian() ? map_identity : map_3210;
  628.             break;
  629.          default:
  630.             endian = map_identity;
  631.             assert(!"Invalid number of components");
  632.          }
  633.          break;
  634.       case GL_UNSIGNED_SHORT:
  635.       case GL_SHORT:
  636.       case GL_HALF_FLOAT:
  637.          if (_mesa_get_format_max_bits(format) != 16)
  638.             return false;
  639.          *num_components = _mesa_get_format_bytes(format) / 2;
  640.          switch (*num_components) {
  641.          case 1:
  642.             endian = map_identity;
  643.             break;
  644.          case 2:
  645.             endian = _mesa_little_endian() ? map_identity : map_1032;
  646.             break;
  647.          default:
  648.             endian = map_identity;
  649.             assert(!"Invalid number of components");
  650.          }
  651.          break;
  652.       case GL_UNSIGNED_INT:
  653.       case GL_INT:
  654.       case GL_FLOAT:
  655.          /* This isn't packed.  At least not really. */
  656.          assert(format_components == 1);
  657.          if (_mesa_get_format_max_bits(format) != 32)
  658.             return false;
  659.          *num_components = format_components;
  660.          endian = map_identity;
  661.          break;
  662.       default:
  663.          return false;
  664.       }
  665.  
  666.       _mesa_get_format_swizzle(format, packed_swizzle);
  667.  
  668.       for (i = 0; i < 4; ++i)
  669.          swizzle[i] = endian[packed_swizzle[i]];
  670.  
  671.       return true;
  672.    case MESA_FORMAT_LAYOUT_OTHER:
  673.    default:
  674.       return false;
  675.    }
  676. }
  677.  
  678. /**
  679.  * Attempts to perform the given swizzle-and-convert operation with memcpy
  680.  *
  681.  * This function determines if the given swizzle-and-convert operation can
  682.  * be done with a simple memcpy and, if so, does the memcpy.  If not, it
  683.  * returns false and we fall back to the standard version below.
  684.  *
  685.  * The arguments are exactly the same as for _mesa_swizzle_and_convert
  686.  *
  687.  * \return  true if it successfully performed the swizzle-and-convert
  688.  *          operation with memcpy, false otherwise
  689.  */
  690. static bool
  691. swizzle_convert_try_memcpy(void *dst,
  692.                            enum mesa_array_format_datatype dst_type,
  693.                            int num_dst_channels,
  694.                            const void *src,
  695.                            enum mesa_array_format_datatype src_type,
  696.                            int num_src_channels,
  697.                            const uint8_t swizzle[4], bool normalized, int count)
  698. {
  699.    int i;
  700.  
  701.    if (src_type != dst_type)
  702.       return false;
  703.    if (num_src_channels != num_dst_channels)
  704.       return false;
  705.  
  706.    for (i = 0; i < num_dst_channels; ++i)
  707.       if (swizzle[i] != i && swizzle[i] != MESA_FORMAT_SWIZZLE_NONE)
  708.          return false;
  709.  
  710.    memcpy(dst, src, count * num_src_channels *
  711.           _mesa_array_format_datatype_get_size(src_type));
  712.  
  713.    return true;
  714. }
  715.  
  716. /**
  717.  * Represents a single instance of the standard swizzle-and-convert loop
  718.  *
  719.  * Any swizzle-and-convert operation simply loops through the pixels and
  720.  * performs the transformation operation one pixel at a time.  This macro
  721.  * embodies one instance of the conversion loop.  This way we can do all
  722.  * control flow outside of the loop and allow the compiler to unroll
  723.  * everything inside the loop.
  724.  *
  725.  * Note: This loop is carefully crafted for performance.  Be careful when
  726.  * changing it and run some benchmarks to ensure no performance regressions
  727.  * if you do.
  728.  *
  729.  * \param   DST_TYPE    the C datatype of the destination
  730.  * \param   DST_CHANS   the number of destination channels
  731.  * \param   SRC_TYPE    the C datatype of the source
  732.  * \param   SRC_CHANS   the number of source channels
  733.  * \param   CONV        an expression for converting from the source data,
  734.  *                      storred in the variable "src", to the destination
  735.  *                      format
  736.  */
  737. #define SWIZZLE_CONVERT_LOOP(DST_TYPE, DST_CHANS, SRC_TYPE, SRC_CHANS, CONV) \
  738.    do {                                           \
  739.       int s, j;                                   \
  740.       for (s = 0; s < count; ++s) {               \
  741.          for (j = 0; j < SRC_CHANS; ++j) {        \
  742.             SRC_TYPE src = typed_src[j];          \
  743.             tmp[j] = CONV;                        \
  744.          }                                        \
  745.                                                   \
  746.          typed_dst[0] = tmp[swizzle_x];           \
  747.          if (DST_CHANS > 1) {                     \
  748.             typed_dst[1] = tmp[swizzle_y];        \
  749.             if (DST_CHANS > 2) {                  \
  750.                typed_dst[2] = tmp[swizzle_z];     \
  751.                if (DST_CHANS > 3) {               \
  752.                   typed_dst[3] = tmp[swizzle_w];  \
  753.                }                                  \
  754.             }                                     \
  755.          }                                        \
  756.          typed_src += SRC_CHANS;                  \
  757.          typed_dst += DST_CHANS;                  \
  758.       }                                           \
  759.    } while (0)
  760.  
  761. /**
  762.  * Represents a single swizzle-and-convert operation
  763.  *
  764.  * This macro represents everything done in a single swizzle-and-convert
  765.  * operation.  The actual work is done by the SWIZZLE_CONVERT_LOOP macro.
  766.  * This macro acts as a wrapper that uses a nested switch to ensure that
  767.  * all looping parameters get unrolled.
  768.  *
  769.  * This macro makes assumptions about variables etc. in the calling
  770.  * function.  Changes to _mesa_swizzle_and_convert may require changes to
  771.  * this macro.
  772.  *
  773.  * \param   DST_TYPE    the C datatype of the destination
  774.  * \param   SRC_TYPE    the C datatype of the source
  775.  * \param   CONV        an expression for converting from the source data,
  776.  *                      storred in the variable "src", to the destination
  777.  *                      format
  778.  */
  779. #define SWIZZLE_CONVERT(DST_TYPE, SRC_TYPE, CONV)                 \
  780.    do {                                                           \
  781.       const uint8_t swizzle_x = swizzle[0];                       \
  782.       const uint8_t swizzle_y = swizzle[1];                       \
  783.       const uint8_t swizzle_z = swizzle[2];                       \
  784.       const uint8_t swizzle_w = swizzle[3];                       \
  785.       const SRC_TYPE *typed_src = void_src;                       \
  786.       DST_TYPE *typed_dst = void_dst;                             \
  787.       DST_TYPE tmp[7];                                            \
  788.       tmp[4] = 0;                                                 \
  789.       tmp[5] = one;                                               \
  790.       switch (num_dst_channels) {                                 \
  791.       case 1:                                                     \
  792.          switch (num_src_channels) {                              \
  793.          case 1:                                                  \
  794.             SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 1, CONV); \
  795.             break;                                                \
  796.          case 2:                                                  \
  797.             SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 2, CONV); \
  798.             break;                                                \
  799.          case 3:                                                  \
  800.             SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 3, CONV); \
  801.             break;                                                \
  802.          case 4:                                                  \
  803.             SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 4, CONV); \
  804.             break;                                                \
  805.          }                                                        \
  806.          break;                                                   \
  807.       case 2:                                                     \
  808.          switch (num_src_channels) {                              \
  809.          case 1:                                                  \
  810.             SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 1, CONV); \
  811.             break;                                                \
  812.          case 2:                                                  \
  813.             SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 2, CONV); \
  814.             break;                                                \
  815.          case 3:                                                  \
  816.             SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 3, CONV); \
  817.             break;                                                \
  818.          case 4:                                                  \
  819.             SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 4, CONV); \
  820.             break;                                                \
  821.          }                                                        \
  822.          break;                                                   \
  823.       case 3:                                                     \
  824.          switch (num_src_channels) {                              \
  825.          case 1:                                                  \
  826.             SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 1, CONV); \
  827.             break;                                                \
  828.          case 2:                                                  \
  829.             SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 2, CONV); \
  830.             break;                                                \
  831.          case 3:                                                  \
  832.             SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 3, CONV); \
  833.             break;                                                \
  834.          case 4:                                                  \
  835.             SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 4, CONV); \
  836.             break;                                                \
  837.          }                                                        \
  838.          break;                                                   \
  839.       case 4:                                                     \
  840.          switch (num_src_channels) {                              \
  841.          case 1:                                                  \
  842.             SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 1, CONV); \
  843.             break;                                                \
  844.          case 2:                                                  \
  845.             SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 2, CONV); \
  846.             break;                                                \
  847.          case 3:                                                  \
  848.             SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 3, CONV); \
  849.             break;                                                \
  850.          case 4:                                                  \
  851.             SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 4, CONV); \
  852.             break;                                                \
  853.          }                                                        \
  854.          break;                                                   \
  855.       }                                                           \
  856.    } while (0)
  857.  
  858.  
  859. static void
  860. convert_float(void *void_dst, int num_dst_channels,
  861.               const void *void_src, GLenum src_type, int num_src_channels,
  862.               const uint8_t swizzle[4], bool normalized, int count)
  863. {
  864.    const float one = 1.0f;
  865.  
  866.    switch (src_type) {
  867.    case MESA_ARRAY_FORMAT_TYPE_FLOAT:
  868.       SWIZZLE_CONVERT(float, float, src);
  869.       break;
  870.    case MESA_ARRAY_FORMAT_TYPE_HALF:
  871.       SWIZZLE_CONVERT(float, uint16_t, _mesa_half_to_float(src));
  872.       break;
  873.    case MESA_ARRAY_FORMAT_TYPE_UBYTE:
  874.       if (normalized) {
  875.          SWIZZLE_CONVERT(float, uint8_t, _mesa_unorm_to_float(src, 8));
  876.       } else {
  877.          SWIZZLE_CONVERT(float, uint8_t, src);
  878.       }
  879.       break;
  880.    case MESA_ARRAY_FORMAT_TYPE_BYTE:
  881.       if (normalized) {
  882.          SWIZZLE_CONVERT(float, int8_t, _mesa_snorm_to_float(src, 8));
  883.       } else {
  884.          SWIZZLE_CONVERT(float, int8_t, src);
  885.       }
  886.       break;
  887.    case MESA_ARRAY_FORMAT_TYPE_USHORT:
  888.       if (normalized) {
  889.          SWIZZLE_CONVERT(float, uint16_t, _mesa_unorm_to_float(src, 16));
  890.       } else {
  891.          SWIZZLE_CONVERT(float, uint16_t, src);
  892.       }
  893.       break;
  894.    case MESA_ARRAY_FORMAT_TYPE_SHORT:
  895.       if (normalized) {
  896.          SWIZZLE_CONVERT(float, int16_t, _mesa_snorm_to_float(src, 16));
  897.       } else {
  898.          SWIZZLE_CONVERT(float, int16_t, src);
  899.       }
  900.       break;
  901.    case MESA_ARRAY_FORMAT_TYPE_UINT:
  902.       if (normalized) {
  903.          SWIZZLE_CONVERT(float, uint32_t, _mesa_unorm_to_float(src, 32));
  904.       } else {
  905.          SWIZZLE_CONVERT(float, uint32_t, src);
  906.       }
  907.       break;
  908.    case MESA_ARRAY_FORMAT_TYPE_INT:
  909.       if (normalized) {
  910.          SWIZZLE_CONVERT(float, int32_t, _mesa_snorm_to_float(src, 32));
  911.       } else {
  912.          SWIZZLE_CONVERT(float, int32_t, src);
  913.       }
  914.       break;
  915.    default:
  916.       assert(!"Invalid channel type combination");
  917.    }
  918. }
  919.  
  920.  
  921. static void
  922. convert_half_float(void *void_dst, int num_dst_channels,
  923.                    const void *void_src, GLenum src_type, int num_src_channels,
  924.                    const uint8_t swizzle[4], bool normalized, int count)
  925. {
  926.    const uint16_t one = _mesa_float_to_half(1.0f);
  927.  
  928.    switch (src_type) {
  929.    case MESA_ARRAY_FORMAT_TYPE_FLOAT:
  930.       SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_half(src));
  931.       break;
  932.    case MESA_ARRAY_FORMAT_TYPE_HALF:
  933.       SWIZZLE_CONVERT(uint16_t, uint16_t, src);
  934.       break;
  935.    case MESA_ARRAY_FORMAT_TYPE_UBYTE:
  936.       if (normalized) {
  937.          SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_half(src, 8));
  938.       } else {
  939.          SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_float_to_half(src));
  940.       }
  941.       break;
  942.    case MESA_ARRAY_FORMAT_TYPE_BYTE:
  943.       if (normalized) {
  944.          SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_half(src, 8));
  945.       } else {
  946.          SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_float_to_half(src));
  947.       }
  948.       break;
  949.    case MESA_ARRAY_FORMAT_TYPE_USHORT:
  950.       if (normalized) {
  951.          SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_unorm_to_half(src, 16));
  952.       } else {
  953.          SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_float_to_half(src));
  954.       }
  955.       break;
  956.    case MESA_ARRAY_FORMAT_TYPE_SHORT:
  957.       if (normalized) {
  958.          SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_half(src, 16));
  959.       } else {
  960.          SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_float_to_half(src));
  961.       }
  962.       break;
  963.    case MESA_ARRAY_FORMAT_TYPE_UINT:
  964.       if (normalized) {
  965.          SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_half(src, 32));
  966.       } else {
  967.          SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_float_to_half(src));
  968.       }
  969.       break;
  970.    case MESA_ARRAY_FORMAT_TYPE_INT:
  971.       if (normalized) {
  972.          SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_half(src, 32));
  973.       } else {
  974.          SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_float_to_half(src));
  975.       }
  976.       break;
  977.    default:
  978.       assert(!"Invalid channel type combination");
  979.    }
  980. }
  981.  
  982. static void
  983. convert_ubyte(void *void_dst, int num_dst_channels,
  984.               const void *void_src, GLenum src_type, int num_src_channels,
  985.               const uint8_t swizzle[4], bool normalized, int count)
  986. {
  987.    const uint8_t one = normalized ? UINT8_MAX : 1;
  988.  
  989.    switch (src_type) {
  990.    case MESA_ARRAY_FORMAT_TYPE_FLOAT:
  991.       if (normalized) {
  992.          SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unorm(src, 8));
  993.       } else {
  994.          SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unsigned(src, 8));
  995.       }
  996.       break;
  997.    case MESA_ARRAY_FORMAT_TYPE_HALF:
  998.       if (normalized) {
  999.          SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unorm(src, 8));
  1000.       } else {
  1001.          SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unsigned(src, 8));
  1002.       }
  1003.       break;
  1004.    case MESA_ARRAY_FORMAT_TYPE_UBYTE:
  1005.       SWIZZLE_CONVERT(uint8_t, uint8_t, src);
  1006.       break;
  1007.    case MESA_ARRAY_FORMAT_TYPE_BYTE:
  1008.       if (normalized) {
  1009.          SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_snorm_to_unorm(src, 8, 8));
  1010.       } else {
  1011.          SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_signed_to_unsigned(src, 8));
  1012.       }
  1013.       break;
  1014.    case MESA_ARRAY_FORMAT_TYPE_USHORT:
  1015.       if (normalized) {
  1016.          SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unorm_to_unorm(src, 16, 8));
  1017.       } else {
  1018.          SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unsigned_to_unsigned(src, 8));
  1019.       }
  1020.       break;
  1021.    case MESA_ARRAY_FORMAT_TYPE_SHORT:
  1022.       if (normalized) {
  1023.          SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_snorm_to_unorm(src, 16, 8));
  1024.       } else {
  1025.          SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_signed_to_unsigned(src, 8));
  1026.       }
  1027.       break;
  1028.    case MESA_ARRAY_FORMAT_TYPE_UINT:
  1029.       if (normalized) {
  1030.          SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unorm_to_unorm(src, 32, 8));
  1031.       } else {
  1032.          SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unsigned_to_unsigned(src, 8));
  1033.       }
  1034.       break;
  1035.    case MESA_ARRAY_FORMAT_TYPE_INT:
  1036.       if (normalized) {
  1037.          SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_snorm_to_unorm(src, 32, 8));
  1038.       } else {
  1039.          SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_signed_to_unsigned(src, 8));
  1040.       }
  1041.       break;
  1042.    default:
  1043.       assert(!"Invalid channel type combination");
  1044.    }
  1045. }
  1046.  
  1047.  
  1048. static void
  1049. convert_byte(void *void_dst, int num_dst_channels,
  1050.              const void *void_src, GLenum src_type, int num_src_channels,
  1051.              const uint8_t swizzle[4], bool normalized, int count)
  1052. {
  1053.    const int8_t one = normalized ? INT8_MAX : 1;
  1054.  
  1055.    switch (src_type) {
  1056.    case MESA_ARRAY_FORMAT_TYPE_FLOAT:
  1057.       if (normalized) {
  1058.          SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_snorm(src, 8));
  1059.       } else {
  1060.          SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_signed(src, 8));
  1061.       }
  1062.       break;
  1063.    case MESA_ARRAY_FORMAT_TYPE_HALF:
  1064.       if (normalized) {
  1065.          SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_snorm(src, 8));
  1066.       } else {
  1067.          SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_signed(src, 8));
  1068.       }
  1069.       break;
  1070.    case MESA_ARRAY_FORMAT_TYPE_UBYTE:
  1071.       if (normalized) {
  1072.          SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 8));
  1073.       } else {
  1074.          SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unsigned_to_signed(src, 8));
  1075.       }
  1076.       break;
  1077.    case MESA_ARRAY_FORMAT_TYPE_BYTE:
  1078.       SWIZZLE_CONVERT(int8_t, int8_t, src);
  1079.       break;
  1080.    case MESA_ARRAY_FORMAT_TYPE_USHORT:
  1081.       if (normalized) {
  1082.          SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 8));
  1083.       } else {
  1084.          SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unsigned_to_signed(src, 8));
  1085.       }
  1086.       break;
  1087.    case MESA_ARRAY_FORMAT_TYPE_SHORT:
  1088.       if (normalized) {
  1089.          SWIZZLE_CONVERT(int8_t, int16_t, _mesa_snorm_to_snorm(src, 16, 8));
  1090.       } else {
  1091.          SWIZZLE_CONVERT(int8_t, int16_t, _mesa_signed_to_signed(src, 8));
  1092.       }
  1093.       break;
  1094.    case MESA_ARRAY_FORMAT_TYPE_UINT:
  1095.       if (normalized) {
  1096.          SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 8));
  1097.       } else {
  1098.          SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unsigned_to_signed(src, 8));
  1099.       }
  1100.       break;
  1101.    case MESA_ARRAY_FORMAT_TYPE_INT:
  1102.       if (normalized) {
  1103.          SWIZZLE_CONVERT(int8_t, int32_t, _mesa_snorm_to_snorm(src, 32, 8));
  1104.       } else {
  1105.          SWIZZLE_CONVERT(int8_t, int32_t, _mesa_signed_to_signed(src, 8));
  1106.       }
  1107.       break;
  1108.    default:
  1109.       assert(!"Invalid channel type combination");
  1110.    }
  1111. }
  1112.  
  1113.  
  1114. static void
  1115. convert_ushort(void *void_dst, int num_dst_channels,
  1116.                const void *void_src, GLenum src_type, int num_src_channels,
  1117.                const uint8_t swizzle[4], bool normalized, int count)
  1118. {
  1119.    const uint16_t one = normalized ? UINT16_MAX : 1;
  1120.    
  1121.    switch (src_type) {
  1122.    case MESA_ARRAY_FORMAT_TYPE_FLOAT:
  1123.       if (normalized) {
  1124.          SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unorm(src, 16));
  1125.       } else {
  1126.          SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unsigned(src, 16));
  1127.       }
  1128.       break;
  1129.    case MESA_ARRAY_FORMAT_TYPE_HALF:
  1130.       if (normalized) {
  1131.          SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unorm(src, 16));
  1132.       } else {
  1133.          SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unsigned(src, 16));
  1134.       }
  1135.       break;
  1136.    case MESA_ARRAY_FORMAT_TYPE_UBYTE:
  1137.       if (normalized) {
  1138.          SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_unorm(src, 8, 16));
  1139.       } else {
  1140.          SWIZZLE_CONVERT(uint16_t, uint8_t, src);
  1141.       }
  1142.       break;
  1143.    case MESA_ARRAY_FORMAT_TYPE_BYTE:
  1144.       if (normalized) {
  1145.          SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_unorm(src, 8, 16));
  1146.       } else {
  1147.          SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_signed_to_unsigned(src, 16));
  1148.       }
  1149.       break;
  1150.    case MESA_ARRAY_FORMAT_TYPE_USHORT:
  1151.       SWIZZLE_CONVERT(uint16_t, uint16_t, src);
  1152.       break;
  1153.    case MESA_ARRAY_FORMAT_TYPE_SHORT:
  1154.       if (normalized) {
  1155.          SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_unorm(src, 16, 16));
  1156.       } else {
  1157.          SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_signed_to_unsigned(src, 16));
  1158.       }
  1159.       break;
  1160.    case MESA_ARRAY_FORMAT_TYPE_UINT:
  1161.       if (normalized) {
  1162.          SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_unorm(src, 32, 16));
  1163.       } else {
  1164.          SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unsigned_to_unsigned(src, 16));
  1165.       }
  1166.       break;
  1167.    case MESA_ARRAY_FORMAT_TYPE_INT:
  1168.       if (normalized) {
  1169.          SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_unorm(src, 32, 16));
  1170.       } else {
  1171.          SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_signed_to_unsigned(src, 16));
  1172.       }
  1173.       break;
  1174.    default:
  1175.       assert(!"Invalid channel type combination");
  1176.    }
  1177. }
  1178.  
  1179.  
  1180. static void
  1181. convert_short(void *void_dst, int num_dst_channels,
  1182.               const void *void_src, GLenum src_type, int num_src_channels,
  1183.               const uint8_t swizzle[4], bool normalized, int count)
  1184. {
  1185.    const int16_t one = normalized ? INT16_MAX : 1;
  1186.  
  1187.    switch (src_type) {
  1188.    case MESA_ARRAY_FORMAT_TYPE_FLOAT:
  1189.       if (normalized) {
  1190.          SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_snorm(src, 16));
  1191.       } else {
  1192.          SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_signed(src, 16));
  1193.       }
  1194.       break;
  1195.    case MESA_ARRAY_FORMAT_TYPE_HALF:
  1196.       if (normalized) {
  1197.          SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_snorm(src, 16));
  1198.       } else {
  1199.          SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_signed(src, 16));
  1200.       }
  1201.       break;
  1202.    case MESA_ARRAY_FORMAT_TYPE_UBYTE:
  1203.       if (normalized) {
  1204.          SWIZZLE_CONVERT(int16_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 16));
  1205.       } else {
  1206.          SWIZZLE_CONVERT(int16_t, uint8_t, src);
  1207.       }
  1208.       break;
  1209.    case MESA_ARRAY_FORMAT_TYPE_BYTE:
  1210.       if (normalized) {
  1211.          SWIZZLE_CONVERT(int16_t, int8_t, _mesa_snorm_to_snorm(src, 8, 16));
  1212.       } else {
  1213.          SWIZZLE_CONVERT(int16_t, int8_t, src);
  1214.       }
  1215.       break;
  1216.    case MESA_ARRAY_FORMAT_TYPE_USHORT:
  1217.       if (normalized) {
  1218.          SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 16));
  1219.       } else {
  1220.          SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unsigned_to_signed(src, 16));
  1221.       }
  1222.       break;
  1223.    case MESA_ARRAY_FORMAT_TYPE_SHORT:
  1224.       SWIZZLE_CONVERT(int16_t, int16_t, src);
  1225.       break;
  1226.    case MESA_ARRAY_FORMAT_TYPE_UINT:
  1227.       if (normalized) {
  1228.          SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 16));
  1229.       } else {
  1230.          SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unsigned_to_signed(src, 16));
  1231.       }
  1232.       break;
  1233.    case MESA_ARRAY_FORMAT_TYPE_INT:
  1234.       if (normalized) {
  1235.          SWIZZLE_CONVERT(int16_t, int32_t, _mesa_snorm_to_snorm(src, 32, 16));
  1236.       } else {
  1237.          SWIZZLE_CONVERT(int16_t, int32_t, _mesa_signed_to_signed(src, 16));
  1238.       }
  1239.       break;
  1240.    default:
  1241.       assert(!"Invalid channel type combination");
  1242.    }
  1243. }
  1244.  
  1245. static void
  1246. convert_uint(void *void_dst, int num_dst_channels,
  1247.              const void *void_src, GLenum src_type, int num_src_channels,
  1248.              const uint8_t swizzle[4], bool normalized, int count)
  1249. {
  1250.    const uint32_t one = normalized ? UINT32_MAX : 1;
  1251.  
  1252.    switch (src_type) {
  1253.    case MESA_ARRAY_FORMAT_TYPE_FLOAT:
  1254.       if (normalized) {
  1255.          SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unorm(src, 32));
  1256.       } else {
  1257.          SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unsigned(src, 32));
  1258.       }
  1259.       break;
  1260.    case MESA_ARRAY_FORMAT_TYPE_HALF:
  1261.       if (normalized) {
  1262.          SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unorm(src, 32));
  1263.       } else {
  1264.          SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unsigned(src, 32));
  1265.       }
  1266.       break;
  1267.    case MESA_ARRAY_FORMAT_TYPE_UBYTE:
  1268.       if (normalized) {
  1269.          SWIZZLE_CONVERT(uint32_t, uint8_t, _mesa_unorm_to_unorm(src, 8, 32));
  1270.       } else {
  1271.          SWIZZLE_CONVERT(uint32_t, uint8_t, src);
  1272.       }
  1273.       break;
  1274.    case MESA_ARRAY_FORMAT_TYPE_BYTE:
  1275.       if (normalized) {
  1276.          SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_snorm_to_unorm(src, 8, 32));
  1277.       } else {
  1278.          SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_signed_to_unsigned(src, 32));
  1279.       }
  1280.       break;
  1281.    case MESA_ARRAY_FORMAT_TYPE_USHORT:
  1282.       if (normalized) {
  1283.          SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_unorm_to_unorm(src, 16, 32));
  1284.       } else {
  1285.          SWIZZLE_CONVERT(uint32_t, uint16_t, src);
  1286.       }
  1287.       break;
  1288.    case MESA_ARRAY_FORMAT_TYPE_SHORT:
  1289.       if (normalized) {
  1290.          SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_snorm_to_unorm(src, 16, 32));
  1291.       } else {
  1292.          SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_signed_to_unsigned(src, 32));
  1293.       }
  1294.       break;
  1295.    case MESA_ARRAY_FORMAT_TYPE_UINT:
  1296.       SWIZZLE_CONVERT(uint32_t, uint32_t, src);
  1297.       break;
  1298.    case MESA_ARRAY_FORMAT_TYPE_INT:
  1299.       if (normalized) {
  1300.          SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_snorm_to_unorm(src, 32, 32));
  1301.       } else {
  1302.          SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_signed_to_unsigned(src, 32));
  1303.       }
  1304.       break;
  1305.    default:
  1306.       assert(!"Invalid channel type combination");
  1307.    }
  1308. }
  1309.  
  1310.  
  1311. static void
  1312. convert_int(void *void_dst, int num_dst_channels,
  1313.             const void *void_src, GLenum src_type, int num_src_channels,
  1314.             const uint8_t swizzle[4], bool normalized, int count)
  1315. {
  1316.    const int32_t one = normalized ? INT32_MAX : 1;
  1317.  
  1318.    switch (src_type) {
  1319.    case MESA_ARRAY_FORMAT_TYPE_FLOAT:
  1320.       if (normalized) {
  1321.          SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_snorm(src, 32));
  1322.       } else {
  1323.          SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_signed(src, 32));
  1324.       }
  1325.       break;
  1326.    case MESA_ARRAY_FORMAT_TYPE_HALF:
  1327.       if (normalized) {
  1328.          SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_snorm(src, 32));
  1329.       } else {
  1330.          SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_signed(src, 32));
  1331.       }
  1332.       break;
  1333.    case MESA_ARRAY_FORMAT_TYPE_UBYTE:
  1334.       if (normalized) {
  1335.          SWIZZLE_CONVERT(int32_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 32));
  1336.       } else {
  1337.          SWIZZLE_CONVERT(int32_t, uint8_t, src);
  1338.       }
  1339.       break;
  1340.    case MESA_ARRAY_FORMAT_TYPE_BYTE:
  1341.       if (normalized) {
  1342.          SWIZZLE_CONVERT(int32_t, int8_t, _mesa_snorm_to_snorm(src, 8, 32));
  1343.       } else {
  1344.          SWIZZLE_CONVERT(int32_t, int8_t, src);
  1345.       }
  1346.       break;
  1347.    case MESA_ARRAY_FORMAT_TYPE_USHORT:
  1348.       if (normalized) {
  1349.          SWIZZLE_CONVERT(int32_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 32));
  1350.       } else {
  1351.          SWIZZLE_CONVERT(int32_t, uint16_t, src);
  1352.       }
  1353.       break;
  1354.    case MESA_ARRAY_FORMAT_TYPE_SHORT:
  1355.       if (normalized) {
  1356.          SWIZZLE_CONVERT(int32_t, int16_t, _mesa_snorm_to_snorm(src, 16, 32));
  1357.       } else {
  1358.          SWIZZLE_CONVERT(int32_t, int16_t, src);
  1359.       }
  1360.       break;
  1361.    case MESA_ARRAY_FORMAT_TYPE_UINT:
  1362.       if (normalized) {
  1363.          SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 32));
  1364.       } else {
  1365.          SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unsigned_to_signed(src, 32));
  1366.       }
  1367.       break;
  1368.    case MESA_ARRAY_FORMAT_TYPE_INT:
  1369.       SWIZZLE_CONVERT(int32_t, int32_t, src);
  1370.       break;
  1371.    default:
  1372.       assert(!"Invalid channel type combination");
  1373.    }
  1374. }
  1375.  
  1376.  
  1377. /**
  1378.  * Convert between array-based color formats.
  1379.  *
  1380.  * Most format conversion operations required by GL can be performed by
  1381.  * converting one channel at a time, shuffling the channels around, and
  1382.  * optionally filling missing channels with zeros and ones.  This function
  1383.  * does just that in a general, yet efficient, way.
  1384.  *
  1385.  * The swizzle parameter is an array of 4 numbers (see
  1386.  * _mesa_get_format_swizzle) that describes where each channel in the
  1387.  * destination should come from in the source.  If swizzle[i] < 4 then it
  1388.  * means that dst[i] = CONVERT(src[swizzle[i]]).  If swizzle[i] is
  1389.  * MESA_FORMAT_SWIZZLE_ZERO or MESA_FORMAT_SWIZZLE_ONE, the corresponding
  1390.  * dst[i] will be filled with the appropreate representation of zero or one
  1391.  * respectively.
  1392.  *
  1393.  * Under most circumstances, the source and destination images must be
  1394.  * different as no care is taken not to clobber one with the other.
  1395.  * However, if they have the same number of bits per pixel, it is safe to
  1396.  * do an in-place conversion.
  1397.  *
  1398.  * \param[out] dst               pointer to where the converted data should
  1399.  *                               be stored
  1400.  *
  1401.  * \param[in]  dst_type          the destination GL type of the converted
  1402.  *                               data (GL_BYTE, etc.)
  1403.  *
  1404.  * \param[in]  num_dst_channels  the number of channels in the converted
  1405.  *                               data
  1406.  *
  1407.  * \param[in]  src               pointer to the source data
  1408.  *
  1409.  * \param[in]  src_type          the GL type of the source data (GL_BYTE,
  1410.  *                               etc.)
  1411.  *
  1412.  * \param[in]  num_src_channels  the number of channels in the source data
  1413.  *                               (the number of channels total, not just
  1414.  *                               the number used)
  1415.  *
  1416.  * \param[in]  swizzle           describes how to get the destination data
  1417.  *                               from the source data.
  1418.  *
  1419.  * \param[in]  normalized        for integer types, this indicates whether
  1420.  *                               the data should be considered as integers
  1421.  *                               or as normalized integers;
  1422.  *
  1423.  * \param[in]  count             the number of pixels to convert
  1424.  */
  1425. void
  1426. _mesa_swizzle_and_convert(void *void_dst, enum mesa_array_format_datatype dst_type, int num_dst_channels,
  1427.                           const void *void_src, enum mesa_array_format_datatype src_type, int num_src_channels,
  1428.                           const uint8_t swizzle[4], bool normalized, int count)
  1429. {
  1430.    if (swizzle_convert_try_memcpy(void_dst, dst_type, num_dst_channels,
  1431.                                   void_src, src_type, num_src_channels,
  1432.                                   swizzle, normalized, count))
  1433.       return;
  1434.  
  1435.    switch (dst_type) {
  1436.    case MESA_ARRAY_FORMAT_TYPE_FLOAT:
  1437.       convert_float(void_dst, num_dst_channels, void_src, src_type,
  1438.                     num_src_channels, swizzle, normalized, count);
  1439.       break;
  1440.    case MESA_ARRAY_FORMAT_TYPE_HALF:
  1441.       convert_half_float(void_dst, num_dst_channels, void_src, src_type,
  1442.                     num_src_channels, swizzle, normalized, count);
  1443.       break;
  1444.    case MESA_ARRAY_FORMAT_TYPE_UBYTE:
  1445.       convert_ubyte(void_dst, num_dst_channels, void_src, src_type,
  1446.                     num_src_channels, swizzle, normalized, count);
  1447.       break;
  1448.    case MESA_ARRAY_FORMAT_TYPE_BYTE:
  1449.       convert_byte(void_dst, num_dst_channels, void_src, src_type,
  1450.                    num_src_channels, swizzle, normalized, count);
  1451.       break;
  1452.    case MESA_ARRAY_FORMAT_TYPE_USHORT:
  1453.       convert_ushort(void_dst, num_dst_channels, void_src, src_type,
  1454.                      num_src_channels, swizzle, normalized, count);
  1455.       break;
  1456.    case MESA_ARRAY_FORMAT_TYPE_SHORT:
  1457.       convert_short(void_dst, num_dst_channels, void_src, src_type,
  1458.                     num_src_channels, swizzle, normalized, count);
  1459.       break;
  1460.    case MESA_ARRAY_FORMAT_TYPE_UINT:
  1461.       convert_uint(void_dst, num_dst_channels, void_src, src_type,
  1462.                    num_src_channels, swizzle, normalized, count);
  1463.       break;
  1464.    case MESA_ARRAY_FORMAT_TYPE_INT:
  1465.       convert_int(void_dst, num_dst_channels, void_src, src_type,
  1466.                   num_src_channels, swizzle, normalized, count);
  1467.       break;
  1468.    default:
  1469.       assert(!"Invalid channel type");
  1470.    }
  1471. }
  1472.