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