Home | History | Annotate | Line # | Download | only in format
      1 /**************************************************************************
      2  *
      3  * Copyright 2009-2010 VMware, Inc.
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial portions
     16  * of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
     22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  **************************************************************************/
     27 
     28 
     29 #ifndef U_FORMAT_H
     30 #define U_FORMAT_H
     31 
     32 
     33 #include "pipe/p_format.h"
     34 #include "pipe/p_defines.h"
     35 #include "util/u_debug.h"
     36 
     37 union pipe_color_union;
     38 struct pipe_screen;
     39 
     40 
     41 #ifdef __cplusplus
     42 extern "C" {
     43 #endif
     44 
     45 
     46 /**
     47  * Describe how to pack/unpack pixels into/from the prescribed format.
     48  *
     49  * XXX: This could be renamed to something like util_format_pack, or broke down
     50  * in flags inside util_format_block that said exactly what we want.
     51  */
     52 enum util_format_layout {
     53    /**
     54     * Formats with util_format_block::width == util_format_block::height == 1
     55     * that can be described as an ordinary data structure.
     56     */
     57    UTIL_FORMAT_LAYOUT_PLAIN,
     58 
     59    /**
     60     * Formats with sub-sampled channels.
     61     *
     62     * This is for formats like YVYU where there is less than one sample per
     63     * pixel.
     64     */
     65    UTIL_FORMAT_LAYOUT_SUBSAMPLED,
     66 
     67    /**
     68     * S3 Texture Compression formats.
     69     */
     70    UTIL_FORMAT_LAYOUT_S3TC,
     71 
     72    /**
     73     * Red-Green Texture Compression formats.
     74     */
     75    UTIL_FORMAT_LAYOUT_RGTC,
     76 
     77    /**
     78     * Ericsson Texture Compression
     79     */
     80    UTIL_FORMAT_LAYOUT_ETC,
     81 
     82    /**
     83     * BC6/7 Texture Compression
     84     */
     85    UTIL_FORMAT_LAYOUT_BPTC,
     86 
     87    UTIL_FORMAT_LAYOUT_ASTC,
     88 
     89    UTIL_FORMAT_LAYOUT_ATC,
     90 
     91    /** Formats with 2 or more planes. */
     92    UTIL_FORMAT_LAYOUT_PLANAR2,
     93    UTIL_FORMAT_LAYOUT_PLANAR3,
     94 
     95    UTIL_FORMAT_LAYOUT_FXT1 = 10,
     96 
     97    /**
     98     * Everything else that doesn't fit in any of the above layouts.
     99     */
    100    UTIL_FORMAT_LAYOUT_OTHER,
    101 };
    102 
    103 
    104 struct util_format_block
    105 {
    106    /** Block width in pixels */
    107    unsigned width;
    108 
    109    /** Block height in pixels */
    110    unsigned height;
    111 
    112    /** Block depth in pixels */
    113    unsigned depth;
    114 
    115    /** Block size in bits */
    116    unsigned bits;
    117 };
    118 
    119 
    120 enum util_format_type {
    121    UTIL_FORMAT_TYPE_VOID = 0,
    122    UTIL_FORMAT_TYPE_UNSIGNED = 1,
    123    UTIL_FORMAT_TYPE_SIGNED = 2,
    124    UTIL_FORMAT_TYPE_FIXED = 3,
    125    UTIL_FORMAT_TYPE_FLOAT = 4
    126 };
    127 
    128 
    129 enum util_format_colorspace {
    130    UTIL_FORMAT_COLORSPACE_RGB = 0,
    131    UTIL_FORMAT_COLORSPACE_SRGB = 1,
    132    UTIL_FORMAT_COLORSPACE_YUV = 2,
    133    UTIL_FORMAT_COLORSPACE_ZS = 3
    134 };
    135 
    136 
    137 struct util_format_channel_description
    138 {
    139    unsigned type:5;        /**< UTIL_FORMAT_TYPE_x */
    140    unsigned normalized:1;
    141    unsigned pure_integer:1;
    142    unsigned size:9;        /**< bits per channel */
    143    unsigned shift:16;      /** number of bits from lsb */
    144 };
    145 
    146 
    147 struct util_format_description
    148 {
    149    enum pipe_format format;
    150 
    151    const char *name;
    152 
    153    /**
    154     * Short name, striped of the prefix, lower case.
    155     */
    156    const char *short_name;
    157 
    158    /**
    159     * Pixel block dimensions.
    160     */
    161    struct util_format_block block;
    162 
    163    enum util_format_layout layout;
    164 
    165    /**
    166     * The number of channels.
    167     */
    168    unsigned nr_channels:3;
    169 
    170    /**
    171     * Whether all channels have the same number of (whole) bytes and type.
    172     */
    173    unsigned is_array:1;
    174 
    175    /**
    176     * Whether the pixel format can be described as a bitfield structure.
    177     *
    178     * In particular:
    179     * - pixel depth must be 8, 16, or 32 bits;
    180     * - all channels must be unsigned, signed, or void
    181     */
    182    unsigned is_bitmask:1;
    183 
    184    /**
    185     * Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID).
    186     */
    187    unsigned is_mixed:1;
    188 
    189    /**
    190     * Whether the format contains UNORM channels
    191     */
    192    unsigned is_unorm:1;
    193 
    194    /**
    195     * Whether the format contains SNORM channels
    196     */
    197    unsigned is_snorm:1;
    198 
    199    /**
    200     * Input channel description, in the order XYZW.
    201     *
    202     * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats.
    203     *
    204     * If each channel is accessed as an individual N-byte value, X is always
    205     * at the lowest address in memory, Y is always next, and so on.  For all
    206     * currently-defined formats, the N-byte value has native endianness.
    207     *
    208     * If instead a group of channels is accessed as a single N-byte value,
    209     * the order of the channels within that value depends on endianness.
    210     * For big-endian targets, X is the most significant subvalue,
    211     * otherwise it is the least significant one.
    212     *
    213     * For example, if X is 8 bits and Y is 24 bits, the memory order is:
    214     *
    215     *                 0  1  2  3
    216     *  little-endian: X  Yl Ym Yu    (l = lower, m = middle, u = upper)
    217     *  big-endian:    X  Yu Ym Yl
    218     *
    219     * If X is 5 bits, Y is 5 bits, Z is 5 bits and W is 1 bit, the layout is:
    220     *
    221     *                        0        1
    222     *                 msb  lsb msb  lsb
    223     *  little-endian: YYYXXXXX WZZZZZYY
    224     *  big-endian:    XXXXXYYY YYZZZZZW
    225     */
    226    struct util_format_channel_description channel[4];
    227 
    228    /**
    229     * Output channel swizzle.
    230     *
    231     * The order is either:
    232     * - RGBA
    233     * - YUV(A)
    234     * - ZS
    235     * depending on the colorspace.
    236     */
    237    unsigned char swizzle[4];
    238 
    239    /**
    240     * Colorspace transformation.
    241     */
    242    enum util_format_colorspace colorspace;
    243 };
    244 
    245 struct util_format_pack_description {
    246    /**
    247     * Pack pixel blocks from R8G8B8A8_UNORM.
    248     * Note: strides are in bytes.
    249     *
    250     * Only defined for non-depth-stencil formats.
    251     */
    252    void
    253    (*pack_rgba_8unorm)(uint8_t *restrict dst, unsigned dst_stride,
    254                        const uint8_t *restrict src, unsigned src_stride,
    255                        unsigned width, unsigned height);
    256 
    257    /**
    258     * Pack pixel blocks from R32G32B32A32_FLOAT.
    259     * Note: strides are in bytes.
    260     *
    261     * Only defined for non-depth-stencil formats.
    262     */
    263    void
    264    (*pack_rgba_float)(uint8_t *restrict dst, unsigned dst_stride,
    265                       const float *restrict src, unsigned src_stride,
    266                       unsigned width, unsigned height);
    267 
    268    /**
    269     * Pack pixels from Z32_FLOAT.
    270     * Note: strides are in bytes.
    271     *
    272     * Only defined for depth formats.
    273     */
    274    void
    275    (*pack_z_32unorm)(uint8_t *restrict dst, unsigned dst_stride,
    276                      const uint32_t *restrict src, unsigned src_stride,
    277                      unsigned width, unsigned height);
    278 
    279    /**
    280     * Pack pixels from Z32_FLOAT.
    281     * Note: strides are in bytes.
    282     *
    283     * Only defined for depth formats.
    284     */
    285    void
    286    (*pack_z_float)(uint8_t *restrict dst, unsigned dst_stride,
    287                    const float *restrict src, unsigned src_stride,
    288                    unsigned width, unsigned height);
    289 
    290    /**
    291     * Pack pixels from S8_UINT.
    292     * Note: strides are in bytes.
    293     *
    294     * Only defined for stencil formats.
    295     */
    296    void
    297    (*pack_s_8uint)(uint8_t *restrict dst, unsigned dst_stride,
    298                    const uint8_t *restrict src, unsigned src_stride,
    299                    unsigned width, unsigned height);
    300 
    301    void
    302    (*pack_rgba_uint)(uint8_t *restrict dst, unsigned dst_stride,
    303                      const uint32_t *restrict src, unsigned src_stride,
    304                      unsigned width, unsigned height);
    305 
    306    void
    307    (*pack_rgba_sint)(uint8_t *restrict dst, unsigned dst_stride,
    308                      const int32_t *restrict src, unsigned src_stride,
    309                      unsigned width, unsigned height);
    310 };
    311 
    312 
    313 struct util_format_unpack_description {
    314    /**
    315     * Unpack pixel blocks to R8G8B8A8_UNORM.
    316     * Note: strides are in bytes.
    317     *
    318     * Only defined for non-block non-depth-stencil formats.
    319     */
    320    void
    321    (*unpack_rgba_8unorm)(uint8_t *restrict dst, const uint8_t *restrict src,
    322                          unsigned width);
    323 
    324    /**
    325     * Unpack pixel blocks to R8G8B8A8_UNORM.
    326     * Note: strides are in bytes.
    327     *
    328     * Only defined for block non-depth-stencil formats.
    329     */
    330    void
    331    (*unpack_rgba_8unorm_rect)(uint8_t *restrict dst, unsigned dst_stride,
    332                          const uint8_t *restrict src, unsigned src_stride,
    333                          unsigned width, unsigned height);
    334 
    335    /**
    336     * Fetch a single pixel (i, j) from a block.
    337     *
    338     * XXX: Only defined for a very few select formats.
    339     */
    340    void
    341    (*fetch_rgba_8unorm)(uint8_t *restrict dst,
    342                         const uint8_t *restrict src,
    343                         unsigned i, unsigned j);
    344 
    345    /**
    346     * Unpack pixel blocks to R32G32B32A32_UINT/_INT_FLOAT based on whether the
    347     * type is pure uint, int, or other.
    348     *
    349     * Note: strides are in bytes.
    350     *
    351     * Only defined for non-block non-depth-stencil formats.
    352     */
    353    void
    354    (*unpack_rgba)(void *restrict dst, const uint8_t *restrict src,
    355                   unsigned width);
    356 
    357    /**
    358     * Unpack pixel blocks to R32G32B32A32_UINT/_INT_FLOAT based on whether the
    359     * type is pure uint, int, or other.
    360     *
    361     * Note: strides are in bytes.
    362     *
    363     * Only defined for block non-depth-stencil formats.
    364     */
    365    void
    366    (*unpack_rgba_rect)(void *restrict dst, unsigned dst_stride,
    367                   const uint8_t *restrict src, unsigned src_stride,
    368                   unsigned width, unsigned height);
    369 
    370    /**
    371     * Unpack pixels to Z32_UNORM.
    372     * Note: strides are in bytes.
    373     *
    374     * Only defined for depth formats.
    375     */
    376    void
    377    (*unpack_z_32unorm)(uint32_t *restrict dst, unsigned dst_stride,
    378                        const uint8_t *restrict src, unsigned src_stride,
    379                        unsigned width, unsigned height);
    380 
    381    /**
    382     * Unpack pixels to Z32_FLOAT.
    383     * Note: strides are in bytes.
    384     *
    385     * Only defined for depth formats.
    386     */
    387    void
    388    (*unpack_z_float)(float *restrict dst, unsigned dst_stride,
    389                      const uint8_t *restrict src, unsigned src_stride,
    390                      unsigned width, unsigned height);
    391 
    392    /**
    393     * Unpack pixels to S8_UINT.
    394     * Note: strides are in bytes.
    395     *
    396     * Only defined for stencil formats.
    397     */
    398    void
    399    (*unpack_s_8uint)(uint8_t *restrict dst, unsigned dst_stride,
    400                      const uint8_t *restrict src, unsigned src_stride,
    401                      unsigned width, unsigned height);
    402 };
    403 
    404 typedef void (*util_format_fetch_rgba_func_ptr)(void *restrict dst, const uint8_t *restrict src,
    405                                                 unsigned i, unsigned j);
    406 
    407 /* Silence warnings triggered by sharing function/struct names */
    408 #ifdef __GNUC__
    409 #pragma GCC diagnostic push
    410 #pragma GCC diagnostic ignored "-Wshadow"
    411 #endif
    412 const struct util_format_description *
    413 util_format_description(enum pipe_format format) ATTRIBUTE_CONST;
    414 
    415 const struct util_format_pack_description *
    416 util_format_pack_description(enum pipe_format format) ATTRIBUTE_CONST;
    417 
    418 /* Lookup with CPU detection for choosing optimized paths. */
    419 const struct util_format_unpack_description *
    420 util_format_unpack_description(enum pipe_format format) ATTRIBUTE_CONST;
    421 
    422 /* Codegenned table of CPU-agnostic unpack code. */
    423 const struct util_format_unpack_description *
    424 util_format_unpack_description_generic(enum pipe_format format) ATTRIBUTE_CONST;
    425 
    426 const struct util_format_unpack_description *
    427 util_format_unpack_description_neon(enum pipe_format format) ATTRIBUTE_CONST;
    428 
    429 #ifdef __GNUC__
    430 #pragma GCC diagnostic pop
    431 #endif
    432 
    433 /**
    434  * Returns a function to fetch a single pixel (i, j) from a block.
    435  *
    436  * Only defined for non-depth-stencil and non-integer formats.
    437  */
    438 util_format_fetch_rgba_func_ptr
    439 util_format_fetch_rgba_func(enum pipe_format format) ATTRIBUTE_CONST;
    440 
    441 /*
    442  * Format query functions.
    443  */
    444 
    445 static inline const char *
    446 util_format_name(enum pipe_format format)
    447 {
    448    const struct util_format_description *desc = util_format_description(format);
    449 
    450    assert(desc);
    451    if (!desc) {
    452       return "PIPE_FORMAT_???";
    453    }
    454 
    455    return desc->name;
    456 }
    457 
    458 static inline const char *
    459 util_format_short_name(enum pipe_format format)
    460 {
    461    const struct util_format_description *desc = util_format_description(format);
    462 
    463    assert(desc);
    464    if (!desc) {
    465       return "???";
    466    }
    467 
    468    return desc->short_name;
    469 }
    470 
    471 /**
    472  * Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info.
    473  */
    474 static inline boolean
    475 util_format_is_plain(enum pipe_format format)
    476 {
    477    const struct util_format_description *desc = util_format_description(format);
    478 
    479    if (!format) {
    480       return FALSE;
    481    }
    482 
    483    return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE;
    484 }
    485 
    486 static inline boolean
    487 util_format_is_compressed(enum pipe_format format)
    488 {
    489    const struct util_format_description *desc = util_format_description(format);
    490 
    491    assert(desc);
    492    if (!desc) {
    493       return FALSE;
    494    }
    495 
    496    switch (desc->layout) {
    497    case UTIL_FORMAT_LAYOUT_S3TC:
    498    case UTIL_FORMAT_LAYOUT_RGTC:
    499    case UTIL_FORMAT_LAYOUT_ETC:
    500    case UTIL_FORMAT_LAYOUT_BPTC:
    501    case UTIL_FORMAT_LAYOUT_ASTC:
    502    case UTIL_FORMAT_LAYOUT_ATC:
    503    case UTIL_FORMAT_LAYOUT_FXT1:
    504       /* XXX add other formats in the future */
    505       return TRUE;
    506    default:
    507       return FALSE;
    508    }
    509 }
    510 
    511 static inline boolean
    512 util_format_is_s3tc(enum pipe_format format)
    513 {
    514    const struct util_format_description *desc = util_format_description(format);
    515 
    516    assert(desc);
    517    if (!desc) {
    518       return FALSE;
    519    }
    520 
    521    return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE;
    522 }
    523 
    524 static inline boolean
    525 util_format_is_etc(enum pipe_format format)
    526 {
    527    const struct util_format_description *desc = util_format_description(format);
    528 
    529    assert(desc);
    530    if (!desc) {
    531       return FALSE;
    532    }
    533 
    534    return desc->layout == UTIL_FORMAT_LAYOUT_ETC ? TRUE : FALSE;
    535 }
    536 
    537 static inline boolean
    538 util_format_is_srgb(enum pipe_format format)
    539 {
    540    const struct util_format_description *desc = util_format_description(format);
    541    return desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB;
    542 }
    543 
    544 static inline boolean
    545 util_format_has_depth(const struct util_format_description *desc)
    546 {
    547    return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
    548           desc->swizzle[0] != PIPE_SWIZZLE_NONE;
    549 }
    550 
    551 static inline boolean
    552 util_format_has_stencil(const struct util_format_description *desc)
    553 {
    554    return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
    555           desc->swizzle[1] != PIPE_SWIZZLE_NONE;
    556 }
    557 
    558 static inline boolean
    559 util_format_is_depth_or_stencil(enum pipe_format format)
    560 {
    561    const struct util_format_description *desc = util_format_description(format);
    562 
    563    assert(desc);
    564    if (!desc) {
    565       return FALSE;
    566    }
    567 
    568    return util_format_has_depth(desc) ||
    569           util_format_has_stencil(desc);
    570 }
    571 
    572 static inline boolean
    573 util_format_is_depth_and_stencil(enum pipe_format format)
    574 {
    575    const struct util_format_description *desc = util_format_description(format);
    576 
    577    assert(desc);
    578    if (!desc) {
    579       return FALSE;
    580    }
    581 
    582    return util_format_has_depth(desc) &&
    583           util_format_has_stencil(desc);
    584 }
    585 
    586 /**
    587  * For depth-stencil formats, return the equivalent depth-only format.
    588  */
    589 static inline enum pipe_format
    590 util_format_get_depth_only(enum pipe_format format)
    591 {
    592    switch (format) {
    593    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
    594       return PIPE_FORMAT_Z24X8_UNORM;
    595 
    596    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
    597       return PIPE_FORMAT_X8Z24_UNORM;
    598 
    599    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
    600       return PIPE_FORMAT_Z32_FLOAT;
    601 
    602    default:
    603       return format;
    604    }
    605 }
    606 
    607 static inline boolean
    608 util_format_is_yuv(enum pipe_format format)
    609 {
    610    const struct util_format_description *desc = util_format_description(format);
    611 
    612    assert(desc);
    613    if (!desc) {
    614       return FALSE;
    615    }
    616 
    617    return desc->colorspace == UTIL_FORMAT_COLORSPACE_YUV;
    618 }
    619 
    620 /**
    621  * Calculates the depth format type based upon the incoming format description.
    622  */
    623 static inline unsigned
    624 util_get_depth_format_type(const struct util_format_description *desc)
    625 {
    626    unsigned depth_channel = desc->swizzle[0];
    627    if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
    628        depth_channel != PIPE_SWIZZLE_NONE) {
    629       return desc->channel[depth_channel].type;
    630    } else {
    631       return UTIL_FORMAT_TYPE_VOID;
    632    }
    633 }
    634 
    635 
    636 /**
    637  * Calculates the MRD for the depth format. MRD is used in depth bias
    638  * for UNORM and unbound depth buffers. When the depth buffer is floating
    639  * point, the depth bias calculation does not use the MRD. However, the
    640  * default MRD will be 1.0 / ((1 << 24) - 1).
    641  */
    642 double
    643 util_get_depth_format_mrd(const struct util_format_description *desc);
    644 
    645 
    646 /**
    647  * Return whether this is an RGBA, Z, S, or combined ZS format.
    648  * Useful for initializing pipe_blit_info::mask.
    649  */
    650 static inline unsigned
    651 util_format_get_mask(enum pipe_format format)
    652 {
    653    const struct util_format_description *desc =
    654       util_format_description(format);
    655 
    656    if (!desc)
    657       return 0;
    658 
    659    if (util_format_has_depth(desc)) {
    660       if (util_format_has_stencil(desc)) {
    661          return PIPE_MASK_ZS;
    662       } else {
    663          return PIPE_MASK_Z;
    664       }
    665    } else {
    666       if (util_format_has_stencil(desc)) {
    667          return PIPE_MASK_S;
    668       } else {
    669          return PIPE_MASK_RGBA;
    670       }
    671    }
    672 }
    673 
    674 /**
    675  * Give the RGBA colormask of the channels that can be represented in this
    676  * format.
    677  *
    678  * That is, the channels whose values are preserved.
    679  */
    680 static inline unsigned
    681 util_format_colormask(const struct util_format_description *desc)
    682 {
    683    unsigned colormask;
    684    unsigned chan;
    685 
    686    switch (desc->colorspace) {
    687    case UTIL_FORMAT_COLORSPACE_RGB:
    688    case UTIL_FORMAT_COLORSPACE_SRGB:
    689    case UTIL_FORMAT_COLORSPACE_YUV:
    690       colormask = 0;
    691       for (chan = 0; chan < 4; ++chan) {
    692          if (desc->swizzle[chan] < 4) {
    693             colormask |= (1 << chan);
    694          }
    695       }
    696       return colormask;
    697    case UTIL_FORMAT_COLORSPACE_ZS:
    698       return 0;
    699    default:
    700       assert(0);
    701       return 0;
    702    }
    703 }
    704 
    705 
    706 /**
    707  * Checks if color mask covers every channel for the specified format
    708  *
    709  * @param desc       a format description to check colormask with
    710  * @param colormask  a bit mask for channels, matches format of PIPE_MASK_RGBA
    711  */
    712 static inline boolean
    713 util_format_colormask_full(const struct util_format_description *desc, unsigned colormask)
    714 {
    715    return (~colormask & util_format_colormask(desc)) == 0;
    716 }
    717 
    718 
    719 boolean
    720 util_format_is_float(enum pipe_format format) ATTRIBUTE_CONST;
    721 
    722 
    723 boolean
    724 util_format_has_alpha(enum pipe_format format) ATTRIBUTE_CONST;
    725 
    726 boolean
    727 util_format_has_alpha1(enum pipe_format format) ATTRIBUTE_CONST;
    728 
    729 boolean
    730 util_format_is_luminance(enum pipe_format format) ATTRIBUTE_CONST;
    731 
    732 boolean
    733 util_format_is_alpha(enum pipe_format format) ATTRIBUTE_CONST;
    734 
    735 boolean
    736 util_format_is_luminance_alpha(enum pipe_format format) ATTRIBUTE_CONST;
    737 
    738 
    739 boolean
    740 util_format_is_intensity(enum pipe_format format) ATTRIBUTE_CONST;
    741 
    742 boolean
    743 util_format_is_subsampled_422(enum pipe_format format) ATTRIBUTE_CONST;
    744 
    745 boolean
    746 util_format_is_pure_integer(enum pipe_format format) ATTRIBUTE_CONST;
    747 
    748 boolean
    749 util_format_is_pure_sint(enum pipe_format format) ATTRIBUTE_CONST;
    750 
    751 boolean
    752 util_format_is_pure_uint(enum pipe_format format) ATTRIBUTE_CONST;
    753 
    754 boolean
    755 util_format_is_snorm(enum pipe_format format) ATTRIBUTE_CONST;
    756 
    757 boolean
    758 util_format_is_unorm(enum pipe_format format) ATTRIBUTE_CONST;
    759 
    760 boolean
    761 util_format_is_snorm8(enum pipe_format format) ATTRIBUTE_CONST;
    762 
    763 boolean
    764 util_format_is_scaled(enum pipe_format format) ATTRIBUTE_CONST;
    765 /**
    766  * Check if the src format can be blitted to the destination format with
    767  * a simple memcpy.  For example, blitting from RGBA to RGBx is OK, but not
    768  * the reverse.
    769  */
    770 boolean
    771 util_is_format_compatible(const struct util_format_description *src_desc,
    772                           const struct util_format_description *dst_desc) ATTRIBUTE_CONST;
    773 
    774 /**
    775  * Whether this format is a rgab8 variant.
    776  *
    777  * That is, any format that matches the
    778  *
    779  *   PIPE_FORMAT_?8?8?8?8_UNORM
    780  */
    781 static inline boolean
    782 util_format_is_rgba8_variant(const struct util_format_description *desc)
    783 {
    784    unsigned chan;
    785 
    786    if(desc->block.width != 1 ||
    787       desc->block.height != 1 ||
    788       desc->block.bits != 32)
    789       return FALSE;
    790 
    791    for(chan = 0; chan < 4; ++chan) {
    792       if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED &&
    793          desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID)
    794          return FALSE;
    795       if(desc->channel[chan].type == UTIL_FORMAT_TYPE_UNSIGNED &&
    796          !desc->channel[chan].normalized)
    797          return FALSE;
    798       if(desc->channel[chan].size != 8)
    799          return FALSE;
    800    }
    801 
    802    return TRUE;
    803 }
    804 
    805 
    806 static inline bool
    807 util_format_is_rgbx_or_bgrx(enum pipe_format format)
    808 {
    809    const struct util_format_description *desc = util_format_description(format);
    810    return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
    811           desc->nr_channels == 4 &&
    812           (desc->swizzle[0] == PIPE_SWIZZLE_X || desc->swizzle[0] == PIPE_SWIZZLE_Z) &&
    813           desc->swizzle[1] == PIPE_SWIZZLE_Y &&
    814           (desc->swizzle[2] == PIPE_SWIZZLE_Z || desc->swizzle[2] == PIPE_SWIZZLE_X) &&
    815           desc->swizzle[3] == PIPE_SWIZZLE_1;
    816 }
    817 
    818 /**
    819  * Return total bits needed for the pixel format per block.
    820  */
    821 static inline uint
    822 util_format_get_blocksizebits(enum pipe_format format)
    823 {
    824    const struct util_format_description *desc = util_format_description(format);
    825 
    826    assert(desc);
    827    if (!desc) {
    828       return 0;
    829    }
    830 
    831    return desc->block.bits;
    832 }
    833 
    834 /**
    835  * Return bytes per block (not pixel) for the given format.
    836  */
    837 static inline uint
    838 util_format_get_blocksize(enum pipe_format format)
    839 {
    840    uint bits = util_format_get_blocksizebits(format);
    841    uint bytes = bits / 8;
    842 
    843    assert(bits % 8 == 0);
    844    assert(bytes > 0);
    845    if (bytes == 0) {
    846       bytes = 1;
    847    }
    848 
    849    return bytes;
    850 }
    851 
    852 static inline uint
    853 util_format_get_blockwidth(enum pipe_format format)
    854 {
    855    const struct util_format_description *desc = util_format_description(format);
    856 
    857    assert(desc);
    858    if (!desc) {
    859       return 1;
    860    }
    861 
    862    return desc->block.width;
    863 }
    864 
    865 static inline uint
    866 util_format_get_blockheight(enum pipe_format format)
    867 {
    868    const struct util_format_description *desc = util_format_description(format);
    869 
    870    assert(desc);
    871    if (!desc) {
    872       return 1;
    873    }
    874 
    875    return desc->block.height;
    876 }
    877 
    878 static inline uint
    879 util_format_get_blockdepth(enum pipe_format format)
    880 {
    881    const struct util_format_description *desc = util_format_description(format);
    882 
    883    assert(desc);
    884    if (!desc) {
    885       return 1;
    886    }
    887 
    888    return desc->block.depth;
    889 }
    890 
    891 static inline unsigned
    892 util_format_get_nblocksx(enum pipe_format format,
    893                          unsigned x)
    894 {
    895    unsigned blockwidth = util_format_get_blockwidth(format);
    896    return (x + blockwidth - 1) / blockwidth;
    897 }
    898 
    899 static inline unsigned
    900 util_format_get_nblocksy(enum pipe_format format,
    901                          unsigned y)
    902 {
    903    unsigned blockheight = util_format_get_blockheight(format);
    904    return (y + blockheight - 1) / blockheight;
    905 }
    906 
    907 static inline unsigned
    908 util_format_get_nblocksz(enum pipe_format format,
    909                          unsigned z)
    910 {
    911    unsigned blockdepth = util_format_get_blockdepth(format);
    912    return (z + blockdepth - 1) / blockdepth;
    913 }
    914 
    915 static inline unsigned
    916 util_format_get_nblocks(enum pipe_format format,
    917                         unsigned width,
    918                         unsigned height)
    919 {
    920    assert(util_format_get_blockdepth(format) == 1);
    921    return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height);
    922 }
    923 
    924 static inline size_t
    925 util_format_get_stride(enum pipe_format format,
    926                        unsigned width)
    927 {
    928    return (size_t)util_format_get_nblocksx(format, width) * util_format_get_blocksize(format);
    929 }
    930 
    931 static inline size_t
    932 util_format_get_2d_size(enum pipe_format format,
    933                         size_t stride,
    934                         unsigned height)
    935 {
    936    return util_format_get_nblocksy(format, height) * stride;
    937 }
    938 
    939 static inline uint
    940 util_format_get_component_bits(enum pipe_format format,
    941                                enum util_format_colorspace colorspace,
    942                                uint component)
    943 {
    944    const struct util_format_description *desc = util_format_description(format);
    945    enum util_format_colorspace desc_colorspace;
    946 
    947    assert(format);
    948    if (!format) {
    949       return 0;
    950    }
    951 
    952    assert(component < 4);
    953 
    954    /* Treat RGB and SRGB as equivalent. */
    955    if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
    956       colorspace = UTIL_FORMAT_COLORSPACE_RGB;
    957    }
    958    if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
    959       desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB;
    960    } else {
    961       desc_colorspace = desc->colorspace;
    962    }
    963 
    964    if (desc_colorspace != colorspace) {
    965       return 0;
    966    }
    967 
    968    switch (desc->swizzle[component]) {
    969    case PIPE_SWIZZLE_X:
    970       return desc->channel[0].size;
    971    case PIPE_SWIZZLE_Y:
    972       return desc->channel[1].size;
    973    case PIPE_SWIZZLE_Z:
    974       return desc->channel[2].size;
    975    case PIPE_SWIZZLE_W:
    976       return desc->channel[3].size;
    977    default:
    978       return 0;
    979    }
    980 }
    981 
    982 /**
    983  * Given a linear RGB colorspace format, return the corresponding SRGB
    984  * format, or PIPE_FORMAT_NONE if none.
    985  */
    986 static inline enum pipe_format
    987 util_format_srgb(enum pipe_format format)
    988 {
    989    if (util_format_is_srgb(format))
    990       return format;
    991 
    992    switch (format) {
    993    case PIPE_FORMAT_L8_UNORM:
    994       return PIPE_FORMAT_L8_SRGB;
    995    case PIPE_FORMAT_R8_UNORM:
    996       return PIPE_FORMAT_R8_SRGB;
    997    case PIPE_FORMAT_L8A8_UNORM:
    998       return PIPE_FORMAT_L8A8_SRGB;
    999    case PIPE_FORMAT_R8G8_UNORM:
   1000       return PIPE_FORMAT_R8G8_SRGB;
   1001    case PIPE_FORMAT_R8G8B8_UNORM:
   1002       return PIPE_FORMAT_R8G8B8_SRGB;
   1003    case PIPE_FORMAT_B8G8R8_UNORM:
   1004       return PIPE_FORMAT_B8G8R8_SRGB;
   1005    case PIPE_FORMAT_A8B8G8R8_UNORM:
   1006       return PIPE_FORMAT_A8B8G8R8_SRGB;
   1007    case PIPE_FORMAT_X8B8G8R8_UNORM:
   1008       return PIPE_FORMAT_X8B8G8R8_SRGB;
   1009    case PIPE_FORMAT_B8G8R8A8_UNORM:
   1010       return PIPE_FORMAT_B8G8R8A8_SRGB;
   1011    case PIPE_FORMAT_B8G8R8X8_UNORM:
   1012       return PIPE_FORMAT_B8G8R8X8_SRGB;
   1013    case PIPE_FORMAT_A8R8G8B8_UNORM:
   1014       return PIPE_FORMAT_A8R8G8B8_SRGB;
   1015    case PIPE_FORMAT_X8R8G8B8_UNORM:
   1016       return PIPE_FORMAT_X8R8G8B8_SRGB;
   1017    case PIPE_FORMAT_R8G8B8A8_UNORM:
   1018       return PIPE_FORMAT_R8G8B8A8_SRGB;
   1019    case PIPE_FORMAT_R8G8B8X8_UNORM:
   1020       return PIPE_FORMAT_R8G8B8X8_SRGB;
   1021    case PIPE_FORMAT_DXT1_RGB:
   1022       return PIPE_FORMAT_DXT1_SRGB;
   1023    case PIPE_FORMAT_DXT1_RGBA:
   1024       return PIPE_FORMAT_DXT1_SRGBA;
   1025    case PIPE_FORMAT_DXT3_RGBA:
   1026       return PIPE_FORMAT_DXT3_SRGBA;
   1027    case PIPE_FORMAT_DXT5_RGBA:
   1028       return PIPE_FORMAT_DXT5_SRGBA;
   1029    case PIPE_FORMAT_R5G6B5_UNORM:
   1030       return PIPE_FORMAT_R5G6B5_SRGB;
   1031    case PIPE_FORMAT_B5G6R5_UNORM:
   1032       return PIPE_FORMAT_B5G6R5_SRGB;
   1033    case PIPE_FORMAT_BPTC_RGBA_UNORM:
   1034       return PIPE_FORMAT_BPTC_SRGBA;
   1035    case PIPE_FORMAT_ETC2_RGB8:
   1036       return PIPE_FORMAT_ETC2_SRGB8;
   1037    case PIPE_FORMAT_ETC2_RGB8A1:
   1038       return PIPE_FORMAT_ETC2_SRGB8A1;
   1039    case PIPE_FORMAT_ETC2_RGBA8:
   1040       return PIPE_FORMAT_ETC2_SRGBA8;
   1041    case PIPE_FORMAT_ASTC_4x4:
   1042       return PIPE_FORMAT_ASTC_4x4_SRGB;
   1043    case PIPE_FORMAT_ASTC_5x4:
   1044       return PIPE_FORMAT_ASTC_5x4_SRGB;
   1045    case PIPE_FORMAT_ASTC_5x5:
   1046       return PIPE_FORMAT_ASTC_5x5_SRGB;
   1047    case PIPE_FORMAT_ASTC_6x5:
   1048       return PIPE_FORMAT_ASTC_6x5_SRGB;
   1049    case PIPE_FORMAT_ASTC_6x6:
   1050       return PIPE_FORMAT_ASTC_6x6_SRGB;
   1051    case PIPE_FORMAT_ASTC_8x5:
   1052       return PIPE_FORMAT_ASTC_8x5_SRGB;
   1053    case PIPE_FORMAT_ASTC_8x6:
   1054       return PIPE_FORMAT_ASTC_8x6_SRGB;
   1055    case PIPE_FORMAT_ASTC_8x8:
   1056       return PIPE_FORMAT_ASTC_8x8_SRGB;
   1057    case PIPE_FORMAT_ASTC_10x5:
   1058       return PIPE_FORMAT_ASTC_10x5_SRGB;
   1059    case PIPE_FORMAT_ASTC_10x6:
   1060       return PIPE_FORMAT_ASTC_10x6_SRGB;
   1061    case PIPE_FORMAT_ASTC_10x8:
   1062       return PIPE_FORMAT_ASTC_10x8_SRGB;
   1063    case PIPE_FORMAT_ASTC_10x10:
   1064       return PIPE_FORMAT_ASTC_10x10_SRGB;
   1065    case PIPE_FORMAT_ASTC_12x10:
   1066       return PIPE_FORMAT_ASTC_12x10_SRGB;
   1067    case PIPE_FORMAT_ASTC_12x12:
   1068       return PIPE_FORMAT_ASTC_12x12_SRGB;
   1069    case PIPE_FORMAT_ASTC_3x3x3:
   1070       return PIPE_FORMAT_ASTC_3x3x3_SRGB;
   1071    case PIPE_FORMAT_ASTC_4x3x3:
   1072       return PIPE_FORMAT_ASTC_4x3x3_SRGB;
   1073    case PIPE_FORMAT_ASTC_4x4x3:
   1074       return PIPE_FORMAT_ASTC_4x4x3_SRGB;
   1075    case PIPE_FORMAT_ASTC_4x4x4:
   1076       return PIPE_FORMAT_ASTC_4x4x4_SRGB;
   1077    case PIPE_FORMAT_ASTC_5x4x4:
   1078       return PIPE_FORMAT_ASTC_5x4x4_SRGB;
   1079    case PIPE_FORMAT_ASTC_5x5x4:
   1080       return PIPE_FORMAT_ASTC_5x5x4_SRGB;
   1081    case PIPE_FORMAT_ASTC_5x5x5:
   1082       return PIPE_FORMAT_ASTC_5x5x5_SRGB;
   1083    case PIPE_FORMAT_ASTC_6x5x5:
   1084       return PIPE_FORMAT_ASTC_6x5x5_SRGB;
   1085    case PIPE_FORMAT_ASTC_6x6x5:
   1086       return PIPE_FORMAT_ASTC_6x6x5_SRGB;
   1087    case PIPE_FORMAT_ASTC_6x6x6:
   1088       return PIPE_FORMAT_ASTC_6x6x6_SRGB;
   1089 
   1090    default:
   1091       return PIPE_FORMAT_NONE;
   1092    }
   1093 }
   1094 
   1095 /**
   1096  * Given an sRGB format, return the corresponding linear colorspace format.
   1097  * For non sRGB formats, return the format unchanged.
   1098  */
   1099 static inline enum pipe_format
   1100 util_format_linear(enum pipe_format format)
   1101 {
   1102    switch (format) {
   1103    case PIPE_FORMAT_L8_SRGB:
   1104       return PIPE_FORMAT_L8_UNORM;
   1105    case PIPE_FORMAT_R8_SRGB:
   1106       return PIPE_FORMAT_R8_UNORM;
   1107    case PIPE_FORMAT_L8A8_SRGB:
   1108       return PIPE_FORMAT_L8A8_UNORM;
   1109    case PIPE_FORMAT_R8G8_SRGB:
   1110       return PIPE_FORMAT_R8G8_UNORM;
   1111    case PIPE_FORMAT_R8G8B8_SRGB:
   1112       return PIPE_FORMAT_R8G8B8_UNORM;
   1113    case PIPE_FORMAT_B8G8R8_SRGB:
   1114       return PIPE_FORMAT_B8G8R8_UNORM;
   1115    case PIPE_FORMAT_A8B8G8R8_SRGB:
   1116       return PIPE_FORMAT_A8B8G8R8_UNORM;
   1117    case PIPE_FORMAT_X8B8G8R8_SRGB:
   1118       return PIPE_FORMAT_X8B8G8R8_UNORM;
   1119    case PIPE_FORMAT_B8G8R8A8_SRGB:
   1120       return PIPE_FORMAT_B8G8R8A8_UNORM;
   1121    case PIPE_FORMAT_B8G8R8X8_SRGB:
   1122       return PIPE_FORMAT_B8G8R8X8_UNORM;
   1123    case PIPE_FORMAT_A8R8G8B8_SRGB:
   1124       return PIPE_FORMAT_A8R8G8B8_UNORM;
   1125    case PIPE_FORMAT_X8R8G8B8_SRGB:
   1126       return PIPE_FORMAT_X8R8G8B8_UNORM;
   1127    case PIPE_FORMAT_R8G8B8A8_SRGB:
   1128       return PIPE_FORMAT_R8G8B8A8_UNORM;
   1129    case PIPE_FORMAT_R8G8B8X8_SRGB:
   1130       return PIPE_FORMAT_R8G8B8X8_UNORM;
   1131    case PIPE_FORMAT_DXT1_SRGB:
   1132       return PIPE_FORMAT_DXT1_RGB;
   1133    case PIPE_FORMAT_DXT1_SRGBA:
   1134       return PIPE_FORMAT_DXT1_RGBA;
   1135    case PIPE_FORMAT_DXT3_SRGBA:
   1136       return PIPE_FORMAT_DXT3_RGBA;
   1137    case PIPE_FORMAT_DXT5_SRGBA:
   1138       return PIPE_FORMAT_DXT5_RGBA;
   1139    case PIPE_FORMAT_R5G6B5_SRGB:
   1140       return PIPE_FORMAT_R5G6B5_UNORM;
   1141    case PIPE_FORMAT_B5G6R5_SRGB:
   1142       return PIPE_FORMAT_B5G6R5_UNORM;
   1143    case PIPE_FORMAT_BPTC_SRGBA:
   1144       return PIPE_FORMAT_BPTC_RGBA_UNORM;
   1145    case PIPE_FORMAT_ETC2_SRGB8:
   1146       return PIPE_FORMAT_ETC2_RGB8;
   1147    case PIPE_FORMAT_ETC2_SRGB8A1:
   1148       return PIPE_FORMAT_ETC2_RGB8A1;
   1149    case PIPE_FORMAT_ETC2_SRGBA8:
   1150       return PIPE_FORMAT_ETC2_RGBA8;
   1151    case PIPE_FORMAT_ASTC_4x4_SRGB:
   1152       return PIPE_FORMAT_ASTC_4x4;
   1153    case PIPE_FORMAT_ASTC_5x4_SRGB:
   1154       return PIPE_FORMAT_ASTC_5x4;
   1155    case PIPE_FORMAT_ASTC_5x5_SRGB:
   1156       return PIPE_FORMAT_ASTC_5x5;
   1157    case PIPE_FORMAT_ASTC_6x5_SRGB:
   1158       return PIPE_FORMAT_ASTC_6x5;
   1159    case PIPE_FORMAT_ASTC_6x6_SRGB:
   1160       return PIPE_FORMAT_ASTC_6x6;
   1161    case PIPE_FORMAT_ASTC_8x5_SRGB:
   1162       return PIPE_FORMAT_ASTC_8x5;
   1163    case PIPE_FORMAT_ASTC_8x6_SRGB:
   1164       return PIPE_FORMAT_ASTC_8x6;
   1165    case PIPE_FORMAT_ASTC_8x8_SRGB:
   1166       return PIPE_FORMAT_ASTC_8x8;
   1167    case PIPE_FORMAT_ASTC_10x5_SRGB:
   1168       return PIPE_FORMAT_ASTC_10x5;
   1169    case PIPE_FORMAT_ASTC_10x6_SRGB:
   1170       return PIPE_FORMAT_ASTC_10x6;
   1171    case PIPE_FORMAT_ASTC_10x8_SRGB:
   1172       return PIPE_FORMAT_ASTC_10x8;
   1173    case PIPE_FORMAT_ASTC_10x10_SRGB:
   1174       return PIPE_FORMAT_ASTC_10x10;
   1175    case PIPE_FORMAT_ASTC_12x10_SRGB:
   1176       return PIPE_FORMAT_ASTC_12x10;
   1177    case PIPE_FORMAT_ASTC_12x12_SRGB:
   1178       return PIPE_FORMAT_ASTC_12x12;
   1179    case PIPE_FORMAT_ASTC_3x3x3_SRGB:
   1180       return PIPE_FORMAT_ASTC_3x3x3;
   1181    case PIPE_FORMAT_ASTC_4x3x3_SRGB:
   1182       return PIPE_FORMAT_ASTC_4x3x3;
   1183    case PIPE_FORMAT_ASTC_4x4x3_SRGB:
   1184       return PIPE_FORMAT_ASTC_4x4x3;
   1185    case PIPE_FORMAT_ASTC_4x4x4_SRGB:
   1186       return PIPE_FORMAT_ASTC_4x4x4;
   1187    case PIPE_FORMAT_ASTC_5x4x4_SRGB:
   1188       return PIPE_FORMAT_ASTC_5x4x4;
   1189    case PIPE_FORMAT_ASTC_5x5x4_SRGB:
   1190       return PIPE_FORMAT_ASTC_5x5x4;
   1191    case PIPE_FORMAT_ASTC_5x5x5_SRGB:
   1192       return PIPE_FORMAT_ASTC_5x5x5;
   1193    case PIPE_FORMAT_ASTC_6x5x5_SRGB:
   1194       return PIPE_FORMAT_ASTC_6x5x5;
   1195    case PIPE_FORMAT_ASTC_6x6x5_SRGB:
   1196       return PIPE_FORMAT_ASTC_6x6x5;
   1197    case PIPE_FORMAT_ASTC_6x6x6_SRGB:
   1198       return PIPE_FORMAT_ASTC_6x6x6;
   1199    default:
   1200       assert(!util_format_is_srgb(format));
   1201       return format;
   1202    }
   1203 }
   1204 
   1205 /**
   1206  * Given a depth-stencil format, return the corresponding stencil-only format.
   1207  * For stencil-only formats, return the format unchanged.
   1208  */
   1209 static inline enum pipe_format
   1210 util_format_stencil_only(enum pipe_format format)
   1211 {
   1212    switch (format) {
   1213    /* mask out the depth component */
   1214    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
   1215       return PIPE_FORMAT_X24S8_UINT;
   1216    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
   1217       return PIPE_FORMAT_S8X24_UINT;
   1218    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
   1219       return PIPE_FORMAT_X32_S8X24_UINT;
   1220 
   1221    /* stencil only formats */
   1222    case PIPE_FORMAT_X24S8_UINT:
   1223    case PIPE_FORMAT_S8X24_UINT:
   1224    case PIPE_FORMAT_X32_S8X24_UINT:
   1225    case PIPE_FORMAT_S8_UINT:
   1226       return format;
   1227 
   1228    default:
   1229       assert(0);
   1230       return PIPE_FORMAT_NONE;
   1231    }
   1232 }
   1233 
   1234 /**
   1235  * Converts PIPE_FORMAT_*I* to PIPE_FORMAT_*R*.
   1236  * This is identity for non-intensity formats.
   1237  */
   1238 static inline enum pipe_format
   1239 util_format_intensity_to_red(enum pipe_format format)
   1240 {
   1241    switch (format) {
   1242    case PIPE_FORMAT_I8_UNORM:
   1243       return PIPE_FORMAT_R8_UNORM;
   1244    case PIPE_FORMAT_I8_SNORM:
   1245       return PIPE_FORMAT_R8_SNORM;
   1246    case PIPE_FORMAT_I16_UNORM:
   1247       return PIPE_FORMAT_R16_UNORM;
   1248    case PIPE_FORMAT_I16_SNORM:
   1249       return PIPE_FORMAT_R16_SNORM;
   1250    case PIPE_FORMAT_I16_FLOAT:
   1251       return PIPE_FORMAT_R16_FLOAT;
   1252    case PIPE_FORMAT_I32_FLOAT:
   1253       return PIPE_FORMAT_R32_FLOAT;
   1254    case PIPE_FORMAT_I8_UINT:
   1255       return PIPE_FORMAT_R8_UINT;
   1256    case PIPE_FORMAT_I8_SINT:
   1257       return PIPE_FORMAT_R8_SINT;
   1258    case PIPE_FORMAT_I16_UINT:
   1259       return PIPE_FORMAT_R16_UINT;
   1260    case PIPE_FORMAT_I16_SINT:
   1261       return PIPE_FORMAT_R16_SINT;
   1262    case PIPE_FORMAT_I32_UINT:
   1263       return PIPE_FORMAT_R32_UINT;
   1264    case PIPE_FORMAT_I32_SINT:
   1265       return PIPE_FORMAT_R32_SINT;
   1266    default:
   1267       assert(!util_format_is_intensity(format));
   1268       return format;
   1269    }
   1270 }
   1271 
   1272 /**
   1273  * Converts PIPE_FORMAT_*L* to PIPE_FORMAT_*R*.
   1274  * This is identity for non-luminance formats.
   1275  */
   1276 static inline enum pipe_format
   1277 util_format_luminance_to_red(enum pipe_format format)
   1278 {
   1279    switch (format) {
   1280    case PIPE_FORMAT_L8_UNORM:
   1281       return PIPE_FORMAT_R8_UNORM;
   1282    case PIPE_FORMAT_L8_SNORM:
   1283       return PIPE_FORMAT_R8_SNORM;
   1284    case PIPE_FORMAT_L16_UNORM:
   1285       return PIPE_FORMAT_R16_UNORM;
   1286    case PIPE_FORMAT_L16_SNORM:
   1287       return PIPE_FORMAT_R16_SNORM;
   1288    case PIPE_FORMAT_L16_FLOAT:
   1289       return PIPE_FORMAT_R16_FLOAT;
   1290    case PIPE_FORMAT_L32_FLOAT:
   1291       return PIPE_FORMAT_R32_FLOAT;
   1292    case PIPE_FORMAT_L8_UINT:
   1293       return PIPE_FORMAT_R8_UINT;
   1294    case PIPE_FORMAT_L8_SINT:
   1295       return PIPE_FORMAT_R8_SINT;
   1296    case PIPE_FORMAT_L16_UINT:
   1297       return PIPE_FORMAT_R16_UINT;
   1298    case PIPE_FORMAT_L16_SINT:
   1299       return PIPE_FORMAT_R16_SINT;
   1300    case PIPE_FORMAT_L32_UINT:
   1301       return PIPE_FORMAT_R32_UINT;
   1302    case PIPE_FORMAT_L32_SINT:
   1303       return PIPE_FORMAT_R32_SINT;
   1304 
   1305    case PIPE_FORMAT_LATC1_UNORM:
   1306       return PIPE_FORMAT_RGTC1_UNORM;
   1307    case PIPE_FORMAT_LATC1_SNORM:
   1308       return PIPE_FORMAT_RGTC1_SNORM;
   1309 
   1310    case PIPE_FORMAT_L4A4_UNORM:
   1311       return PIPE_FORMAT_R4A4_UNORM;
   1312 
   1313    case PIPE_FORMAT_L8A8_UNORM:
   1314       return PIPE_FORMAT_R8A8_UNORM;
   1315    case PIPE_FORMAT_L8A8_SNORM:
   1316       return PIPE_FORMAT_R8A8_SNORM;
   1317    case PIPE_FORMAT_L16A16_UNORM:
   1318       return PIPE_FORMAT_R16A16_UNORM;
   1319    case PIPE_FORMAT_L16A16_SNORM:
   1320       return PIPE_FORMAT_R16A16_SNORM;
   1321    case PIPE_FORMAT_L16A16_FLOAT:
   1322       return PIPE_FORMAT_R16A16_FLOAT;
   1323    case PIPE_FORMAT_L32A32_FLOAT:
   1324       return PIPE_FORMAT_R32A32_FLOAT;
   1325    case PIPE_FORMAT_L8A8_UINT:
   1326       return PIPE_FORMAT_R8A8_UINT;
   1327    case PIPE_FORMAT_L8A8_SINT:
   1328       return PIPE_FORMAT_R8A8_SINT;
   1329    case PIPE_FORMAT_L16A16_UINT:
   1330       return PIPE_FORMAT_R16A16_UINT;
   1331    case PIPE_FORMAT_L16A16_SINT:
   1332       return PIPE_FORMAT_R16A16_SINT;
   1333    case PIPE_FORMAT_L32A32_UINT:
   1334       return PIPE_FORMAT_R32A32_UINT;
   1335    case PIPE_FORMAT_L32A32_SINT:
   1336       return PIPE_FORMAT_R32A32_SINT;
   1337 
   1338    /* We don't have compressed red-alpha variants for these. */
   1339    case PIPE_FORMAT_LATC2_UNORM:
   1340    case PIPE_FORMAT_LATC2_SNORM:
   1341       return PIPE_FORMAT_NONE;
   1342 
   1343    default:
   1344       assert(!util_format_is_luminance(format) &&
   1345 	     !util_format_is_luminance_alpha(format));
   1346       return format;
   1347    }
   1348 }
   1349 
   1350 static inline unsigned
   1351 util_format_get_num_planes(enum pipe_format format)
   1352 {
   1353    switch (util_format_description(format)->layout) {
   1354    case UTIL_FORMAT_LAYOUT_PLANAR3:
   1355       return 3;
   1356    case UTIL_FORMAT_LAYOUT_PLANAR2:
   1357       return 2;
   1358    default:
   1359       return 1;
   1360    }
   1361 }
   1362 
   1363 static inline enum pipe_format
   1364 util_format_get_plane_format(enum pipe_format format, unsigned plane)
   1365 {
   1366    switch (format) {
   1367    case PIPE_FORMAT_YV12:
   1368    case PIPE_FORMAT_YV16:
   1369    case PIPE_FORMAT_IYUV:
   1370    case PIPE_FORMAT_Y8_U8_V8_422_UNORM:
   1371    case PIPE_FORMAT_Y8_U8_V8_444_UNORM:
   1372       return PIPE_FORMAT_R8_UNORM;
   1373    case PIPE_FORMAT_NV12:
   1374    case PIPE_FORMAT_Y8_U8V8_422_UNORM:
   1375       return !plane ? PIPE_FORMAT_R8_UNORM : PIPE_FORMAT_RG88_UNORM;
   1376    case PIPE_FORMAT_NV21:
   1377       return !plane ? PIPE_FORMAT_R8_UNORM : PIPE_FORMAT_GR88_UNORM;
   1378    case PIPE_FORMAT_Y16_U16_V16_420_UNORM:
   1379    case PIPE_FORMAT_Y16_U16_V16_422_UNORM:
   1380    case PIPE_FORMAT_Y16_U16_V16_444_UNORM:
   1381       return PIPE_FORMAT_R16_UNORM;
   1382    case PIPE_FORMAT_P010:
   1383    case PIPE_FORMAT_P012:
   1384    case PIPE_FORMAT_P016:
   1385    case PIPE_FORMAT_Y16_U16V16_422_UNORM:
   1386       return !plane ? PIPE_FORMAT_R16_UNORM : PIPE_FORMAT_R16G16_UNORM;
   1387    default:
   1388       return format;
   1389    }
   1390 }
   1391 
   1392 static inline unsigned
   1393 util_format_get_plane_width(enum pipe_format format, unsigned plane,
   1394                             unsigned width)
   1395 {
   1396    switch (format) {
   1397    case PIPE_FORMAT_YV12:
   1398    case PIPE_FORMAT_YV16:
   1399    case PIPE_FORMAT_IYUV:
   1400    case PIPE_FORMAT_NV12:
   1401    case PIPE_FORMAT_NV21:
   1402    case PIPE_FORMAT_P010:
   1403    case PIPE_FORMAT_P012:
   1404    case PIPE_FORMAT_P016:
   1405    case PIPE_FORMAT_Y8_U8_V8_422_UNORM:
   1406    case PIPE_FORMAT_Y8_U8V8_422_UNORM:
   1407    case PIPE_FORMAT_Y16_U16_V16_420_UNORM:
   1408    case PIPE_FORMAT_Y16_U16_V16_422_UNORM:
   1409    case PIPE_FORMAT_Y16_U16V16_422_UNORM:
   1410       return !plane ? width : (width + 1) / 2;
   1411    default:
   1412       return width;
   1413    }
   1414 }
   1415 
   1416 static inline unsigned
   1417 util_format_get_plane_height(enum pipe_format format, unsigned plane,
   1418                              unsigned height)
   1419 {
   1420    switch (format) {
   1421    case PIPE_FORMAT_YV12:
   1422    case PIPE_FORMAT_IYUV:
   1423    case PIPE_FORMAT_NV12:
   1424    case PIPE_FORMAT_NV21:
   1425    case PIPE_FORMAT_P010:
   1426    case PIPE_FORMAT_P012:
   1427    case PIPE_FORMAT_P016:
   1428    case PIPE_FORMAT_Y16_U16_V16_420_UNORM:
   1429       return !plane ? height : (height + 1) / 2;
   1430    case PIPE_FORMAT_YV16:
   1431    default:
   1432       return height;
   1433    }
   1434 }
   1435 
   1436 /**
   1437  * Return the number of components stored.
   1438  * Formats with block size != 1x1 will always have 1 component (the block).
   1439  */
   1440 static inline unsigned
   1441 util_format_get_nr_components(enum pipe_format format)
   1442 {
   1443    const struct util_format_description *desc = util_format_description(format);
   1444    return desc->nr_channels;
   1445 }
   1446 
   1447 /**
   1448  * Return the index of the first non-void channel
   1449  * -1 if no non-void channels
   1450  */
   1451 static inline int
   1452 util_format_get_first_non_void_channel(enum pipe_format format)
   1453 {
   1454    const struct util_format_description *desc = util_format_description(format);
   1455    int i;
   1456 
   1457    for (i = 0; i < 4; i++)
   1458       if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID)
   1459          break;
   1460 
   1461    if (i == 4)
   1462        return -1;
   1463 
   1464    return i;
   1465 }
   1466 
   1467 /**
   1468  * Whether this format is any 8-bit UNORM variant. Looser than
   1469  * util_is_rgba8_variant (also includes alpha textures, for instance).
   1470  */
   1471 
   1472 static inline bool
   1473 util_format_is_unorm8(const struct util_format_description *desc)
   1474 {
   1475    int c = util_format_get_first_non_void_channel(desc->format);
   1476 
   1477    if (c == -1)
   1478       return false;
   1479 
   1480    return desc->is_unorm && desc->is_array && desc->channel[c].size == 8;
   1481 }
   1482 
   1483 static inline void
   1484 util_format_unpack_z_float(enum pipe_format format, float *dst,
   1485                            const void *src, unsigned w)
   1486 {
   1487    const struct util_format_unpack_description *desc =
   1488       util_format_unpack_description(format);
   1489 
   1490    desc->unpack_z_float(dst, 0, (const uint8_t *)src, 0, w, 1);
   1491 }
   1492 
   1493 static inline void
   1494 util_format_unpack_z_32unorm(enum pipe_format format, uint32_t *dst,
   1495                              const void *src, unsigned w)
   1496 {
   1497    const struct util_format_unpack_description *desc =
   1498       util_format_unpack_description(format);
   1499 
   1500    desc->unpack_z_32unorm(dst, 0, (const uint8_t *)src, 0, w, 1);
   1501 }
   1502 
   1503 static inline void
   1504 util_format_unpack_s_8uint(enum pipe_format format, uint8_t *dst,
   1505                            const void *src, unsigned w)
   1506 {
   1507    const struct util_format_unpack_description *desc =
   1508       util_format_unpack_description(format);
   1509 
   1510    desc->unpack_s_8uint(dst, 0, (const uint8_t *)src, 0, w, 1);
   1511 }
   1512 
   1513 /**
   1514  * Unpacks a row of color data to 32-bit RGBA, either integers for pure
   1515  * integer formats (sign-extended for signed data), or 32-bit floats.
   1516  */
   1517 static inline void
   1518 util_format_unpack_rgba(enum pipe_format format, void *dst,
   1519                         const void *src, unsigned w)
   1520 {
   1521    const struct util_format_unpack_description *desc =
   1522       util_format_unpack_description(format);
   1523 
   1524    desc->unpack_rgba(dst, (const uint8_t *)src, w);
   1525 }
   1526 
   1527 static inline void
   1528 util_format_pack_z_float(enum pipe_format format, void *dst,
   1529                          const float *src, unsigned w)
   1530 {
   1531    const struct util_format_pack_description *desc =
   1532       util_format_pack_description(format);
   1533 
   1534    desc->pack_z_float((uint8_t *)dst, 0, src, 0, w, 1);
   1535 }
   1536 
   1537 static inline void
   1538 util_format_pack_z_32unorm(enum pipe_format format, void *dst,
   1539                            const uint32_t *src, unsigned w)
   1540 {
   1541    const struct util_format_pack_description *desc =
   1542       util_format_pack_description(format);
   1543 
   1544    desc->pack_z_32unorm((uint8_t *)dst, 0, src, 0, w, 1);
   1545 }
   1546 
   1547 static inline void
   1548 util_format_pack_s_8uint(enum pipe_format format, void *dst,
   1549                          const uint8_t *src, unsigned w)
   1550 {
   1551    const struct util_format_pack_description *desc =
   1552       util_format_pack_description(format);
   1553 
   1554    desc->pack_s_8uint((uint8_t *)dst, 0, src, 0, w, 1);
   1555 }
   1556 
   1557 /**
   1558  * Packs a row of color data from 32-bit RGBA, either integers for pure
   1559  * integer formats, or 32-bit floats.  Values are clamped to the packed
   1560  * representation's range.
   1561  */
   1562 static inline void
   1563 util_format_pack_rgba(enum pipe_format format, void *dst,
   1564                         const void *src, unsigned w)
   1565 {
   1566    const struct util_format_pack_description *desc =
   1567       util_format_pack_description(format);
   1568 
   1569    if (util_format_is_pure_uint(format))
   1570       desc->pack_rgba_uint((uint8_t *)dst, 0, (const uint32_t *)src, 0, w, 1);
   1571    else if (util_format_is_pure_sint(format))
   1572       desc->pack_rgba_sint((uint8_t *)dst, 0, (const int32_t *)src, 0, w, 1);
   1573    else
   1574       desc->pack_rgba_float((uint8_t *)dst, 0, (const float *)src, 0, w, 1);
   1575 }
   1576 
   1577 /*
   1578  * Format access functions for subrectangles
   1579  */
   1580 
   1581 void
   1582 util_format_read_4(enum pipe_format format,
   1583                    void *dst, unsigned dst_stride,
   1584                    const void *src, unsigned src_stride,
   1585                    unsigned x, unsigned y, unsigned w, unsigned h);
   1586 
   1587 void
   1588 util_format_write_4(enum pipe_format format,
   1589                     const void *src, unsigned src_stride,
   1590                     void *dst, unsigned dst_stride,
   1591                     unsigned x, unsigned y, unsigned w, unsigned h);
   1592 
   1593 void
   1594 util_format_read_4ub(enum pipe_format format,
   1595                      uint8_t *dst, unsigned dst_stride,
   1596                      const void *src, unsigned src_stride,
   1597                      unsigned x, unsigned y, unsigned w, unsigned h);
   1598 
   1599 void
   1600 util_format_write_4ub(enum pipe_format format,
   1601                       const uint8_t *src, unsigned src_stride,
   1602                       void *dst, unsigned dst_stride,
   1603                       unsigned x, unsigned y, unsigned w, unsigned h);
   1604 
   1605 void
   1606 util_format_unpack_rgba_rect(enum pipe_format format,
   1607                              void *dst, unsigned dst_stride,
   1608                              const void *src, unsigned src_stride,
   1609                              unsigned w, unsigned h);
   1610 
   1611 void
   1612 util_format_unpack_rgba_8unorm_rect(enum pipe_format format,
   1613                                     void *dst, unsigned dst_stride,
   1614                                     const void *src, unsigned src_stride,
   1615                                     unsigned w, unsigned h);
   1616 
   1617 /*
   1618  * Generic format conversion;
   1619  */
   1620 
   1621 boolean
   1622 util_format_fits_8unorm(const struct util_format_description *format_desc) ATTRIBUTE_CONST;
   1623 
   1624 boolean
   1625 util_format_translate(enum pipe_format dst_format,
   1626                       void *dst, unsigned dst_stride,
   1627                       unsigned dst_x, unsigned dst_y,
   1628                       enum pipe_format src_format,
   1629                       const void *src, unsigned src_stride,
   1630                       unsigned src_x, unsigned src_y,
   1631                       unsigned width, unsigned height);
   1632 
   1633 boolean
   1634 util_format_translate_3d(enum pipe_format dst_format,
   1635                          void *dst, unsigned dst_stride,
   1636                          unsigned dst_slice_stride,
   1637                          unsigned dst_x, unsigned dst_y,
   1638                          unsigned dst_z,
   1639                          enum pipe_format src_format,
   1640                          const void *src, unsigned src_stride,
   1641                          unsigned src_slice_stride,
   1642                          unsigned src_x, unsigned src_y,
   1643                          unsigned src_z, unsigned width,
   1644                          unsigned height, unsigned depth);
   1645 
   1646 /*
   1647  * Swizzle operations.
   1648  */
   1649 
   1650 /* Compose two sets of swizzles.
   1651  * If V is a 4D vector and the function parameters represent functions that
   1652  * swizzle vector components, this holds:
   1653  *     swz2(swz1(V)) = dst(V)
   1654  */
   1655 void util_format_compose_swizzles(const unsigned char swz1[4],
   1656                                   const unsigned char swz2[4],
   1657                                   unsigned char dst[4]);
   1658 
   1659 /* Apply the swizzle provided in \param swz (which is one of PIPE_SWIZZLE_x)
   1660  * to \param src and store the result in \param dst.
   1661  * \param is_integer determines the value written for PIPE_SWIZZLE_1.
   1662  */
   1663 void util_format_apply_color_swizzle(union pipe_color_union *dst,
   1664                                      const union pipe_color_union *src,
   1665                                      const unsigned char swz[4],
   1666                                      const boolean is_integer);
   1667 
   1668 void pipe_swizzle_4f(float *dst, const float *src,
   1669                             const unsigned char swz[4]);
   1670 
   1671 void util_format_unswizzle_4f(float *dst, const float *src,
   1672                               const unsigned char swz[4]);
   1673 
   1674 enum pipe_format
   1675 util_format_snorm8_to_sint8(enum pipe_format format) ATTRIBUTE_CONST;
   1676 
   1677 
   1678 extern void
   1679 util_copy_rect(ubyte * dst, enum pipe_format format,
   1680                unsigned dst_stride, unsigned dst_x, unsigned dst_y,
   1681                unsigned width, unsigned height, const ubyte * src,
   1682                int src_stride, unsigned src_x, unsigned src_y);
   1683 
   1684 /**
   1685  * If the format is RGB, return BGR. If the format is BGR, return RGB.
   1686  * This may fail by returning PIPE_FORMAT_NONE.
   1687  */
   1688 enum pipe_format
   1689 util_format_rgb_to_bgr(enum pipe_format format);
   1690 
   1691 #ifdef __cplusplus
   1692 } // extern "C" {
   1693 #endif
   1694 
   1695 #endif /* ! U_FORMAT_H */
   1696