Home | History | Annotate | Download | only in util
      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 "util/u_debug.h"
     35 
     36 #ifdef __cplusplus
     37 extern "C" {
     38 #endif
     39 
     40 
     41 /**
     42  * Describe how to pack/unpack pixels into/from the prescribed format.
     43  *
     44  * XXX: This could be renamed to something like util_format_pack, or broke down
     45  * in flags inside util_format_block that said exactly what we want.
     46  */
     47 enum util_format_layout {
     48    /**
     49     * Formats with util_format_block::width == util_format_block::height == 1
     50     * that can be described as an ordinary data structure.
     51     */
     52    UTIL_FORMAT_LAYOUT_PLAIN = 0,
     53 
     54    /**
     55     * Formats with sub-sampled channels.
     56     *
     57     * This is for formats like YVYU where there is less than one sample per
     58     * pixel.
     59     */
     60    UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3,
     61 
     62    /**
     63     * S3 Texture Compression formats.
     64     */
     65    UTIL_FORMAT_LAYOUT_S3TC = 4,
     66 
     67    /**
     68     * Red-Green Texture Compression formats.
     69     */
     70    UTIL_FORMAT_LAYOUT_RGTC = 5,
     71 
     72    /**
     73     * Ericsson Texture Compression
     74     */
     75    UTIL_FORMAT_LAYOUT_ETC = 6,
     76 
     77    /**
     78     * Everything else that doesn't fit in any of the above layouts.
     79     */
     80    UTIL_FORMAT_LAYOUT_OTHER = 7
     81 };
     82 
     83 
     84 struct util_format_block
     85 {
     86    /** Block width in pixels */
     87    unsigned width;
     88 
     89    /** Block height in pixels */
     90    unsigned height;
     91 
     92    /** Block size in bits */
     93    unsigned bits;
     94 };
     95 
     96 
     97 enum util_format_type {
     98    UTIL_FORMAT_TYPE_VOID = 0,
     99    UTIL_FORMAT_TYPE_UNSIGNED = 1,
    100    UTIL_FORMAT_TYPE_SIGNED = 2,
    101    UTIL_FORMAT_TYPE_FIXED = 3,
    102    UTIL_FORMAT_TYPE_FLOAT = 4
    103 };
    104 
    105 
    106 enum util_format_swizzle {
    107    UTIL_FORMAT_SWIZZLE_X = 0,
    108    UTIL_FORMAT_SWIZZLE_Y = 1,
    109    UTIL_FORMAT_SWIZZLE_Z = 2,
    110    UTIL_FORMAT_SWIZZLE_W = 3,
    111    UTIL_FORMAT_SWIZZLE_0 = 4,
    112    UTIL_FORMAT_SWIZZLE_1 = 5,
    113    UTIL_FORMAT_SWIZZLE_NONE = 6,
    114    UTIL_FORMAT_SWIZZLE_MAX = 7  /**< Number of enums counter (must be last) */
    115 };
    116 
    117 
    118 enum util_format_colorspace {
    119    UTIL_FORMAT_COLORSPACE_RGB = 0,
    120    UTIL_FORMAT_COLORSPACE_SRGB = 1,
    121    UTIL_FORMAT_COLORSPACE_YUV = 2,
    122    UTIL_FORMAT_COLORSPACE_ZS = 3
    123 };
    124 
    125 
    126 struct util_format_channel_description
    127 {
    128    unsigned type:5;        /**< UTIL_FORMAT_TYPE_x */
    129    unsigned normalized:1;
    130    unsigned pure_integer:1;
    131    unsigned size:9;        /**< bits per channel */
    132 };
    133 
    134 
    135 struct util_format_description
    136 {
    137    enum pipe_format format;
    138 
    139    const char *name;
    140 
    141    /**
    142     * Short name, striped of the prefix, lower case.
    143     */
    144    const char *short_name;
    145 
    146    /**
    147     * Pixel block dimensions.
    148     */
    149    struct util_format_block block;
    150 
    151    enum util_format_layout layout;
    152 
    153    /**
    154     * The number of channels.
    155     */
    156    unsigned nr_channels:3;
    157 
    158    /**
    159     * Whether all channels have the same number of (whole) bytes.
    160     */
    161    unsigned is_array:1;
    162 
    163    /**
    164     * Whether the pixel format can be described as a bitfield structure.
    165     *
    166     * In particular:
    167     * - pixel depth must be 8, 16, or 32 bits;
    168     * - all channels must be unsigned, signed, or void
    169     */
    170    unsigned is_bitmask:1;
    171 
    172    /**
    173     * Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID).
    174     */
    175    unsigned is_mixed:1;
    176 
    177    /**
    178     * Input channel description.
    179     *
    180     * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats.
    181     */
    182    struct util_format_channel_description channel[4];
    183 
    184    /**
    185     * Output channel swizzle.
    186     *
    187     * The order is either:
    188     * - RGBA
    189     * - YUV(A)
    190     * - ZS
    191     * depending on the colorspace.
    192     */
    193    unsigned char swizzle[4];
    194 
    195    /**
    196     * Colorspace transformation.
    197     */
    198    enum util_format_colorspace colorspace;
    199 
    200    /**
    201     * Unpack pixel blocks to R8G8B8A8_UNORM.
    202     * Note: strides are in bytes.
    203     *
    204     * Only defined for non-depth-stencil formats.
    205     */
    206    void
    207    (*unpack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride,
    208                          const uint8_t *src, unsigned src_stride,
    209                          unsigned width, unsigned height);
    210 
    211    /**
    212     * Pack pixel blocks from R8G8B8A8_UNORM.
    213     * Note: strides are in bytes.
    214     *
    215     * Only defined for non-depth-stencil formats.
    216     */
    217    void
    218    (*pack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride,
    219                        const uint8_t *src, unsigned src_stride,
    220                        unsigned width, unsigned height);
    221 
    222    /**
    223     * Fetch a single pixel (i, j) from a block.
    224     *
    225     * XXX: Only defined for a very few select formats.
    226     */
    227    void
    228    (*fetch_rgba_8unorm)(uint8_t *dst,
    229                         const uint8_t *src,
    230                         unsigned i, unsigned j);
    231 
    232    /**
    233     * Unpack pixel blocks to R32G32B32A32_FLOAT.
    234     * Note: strides are in bytes.
    235     *
    236     * Only defined for non-depth-stencil formats.
    237     */
    238    void
    239    (*unpack_rgba_float)(float *dst, unsigned dst_stride,
    240                         const uint8_t *src, unsigned src_stride,
    241                         unsigned width, unsigned height);
    242 
    243    /**
    244     * Pack pixel blocks from R32G32B32A32_FLOAT.
    245     * Note: strides are in bytes.
    246     *
    247     * Only defined for non-depth-stencil formats.
    248     */
    249    void
    250    (*pack_rgba_float)(uint8_t *dst, unsigned dst_stride,
    251                       const float *src, unsigned src_stride,
    252                       unsigned width, unsigned height);
    253 
    254    /**
    255     * Fetch a single pixel (i, j) from a block.
    256     *
    257     * Only defined for non-depth-stencil and non-integer formats.
    258     */
    259    void
    260    (*fetch_rgba_float)(float *dst,
    261                        const uint8_t *src,
    262                        unsigned i, unsigned j);
    263 
    264    /**
    265     * Unpack pixels to Z32_UNORM.
    266     * Note: strides are in bytes.
    267     *
    268     * Only defined for depth formats.
    269     */
    270    void
    271    (*unpack_z_32unorm)(uint32_t *dst, unsigned dst_stride,
    272                        const uint8_t *src, unsigned src_stride,
    273                        unsigned width, unsigned height);
    274 
    275    /**
    276     * Pack pixels from Z32_FLOAT.
    277     * Note: strides are in bytes.
    278     *
    279     * Only defined for depth formats.
    280     */
    281    void
    282    (*pack_z_32unorm)(uint8_t *dst, unsigned dst_stride,
    283                      const uint32_t *src, unsigned src_stride,
    284                      unsigned width, unsigned height);
    285 
    286    /**
    287     * Unpack pixels to Z32_FLOAT.
    288     * Note: strides are in bytes.
    289     *
    290     * Only defined for depth formats.
    291     */
    292    void
    293    (*unpack_z_float)(float *dst, unsigned dst_stride,
    294                      const uint8_t *src, unsigned src_stride,
    295                      unsigned width, unsigned height);
    296 
    297    /**
    298     * Pack pixels from Z32_FLOAT.
    299     * Note: strides are in bytes.
    300     *
    301     * Only defined for depth formats.
    302     */
    303    void
    304    (*pack_z_float)(uint8_t *dst, unsigned dst_stride,
    305                    const float *src, unsigned src_stride,
    306                    unsigned width, unsigned height);
    307 
    308    /**
    309     * Unpack pixels to S8_UINT.
    310     * Note: strides are in bytes.
    311     *
    312     * Only defined for stencil formats.
    313     */
    314    void
    315    (*unpack_s_8uint)(uint8_t *dst, unsigned dst_stride,
    316                      const uint8_t *src, unsigned src_stride,
    317                      unsigned width, unsigned height);
    318 
    319    /**
    320     * Pack pixels from S8_UINT.
    321     * Note: strides are in bytes.
    322     *
    323     * Only defined for stencil formats.
    324     */
    325    void
    326    (*pack_s_8uint)(uint8_t *dst, unsigned dst_stride,
    327                    const uint8_t *src, unsigned src_stride,
    328                    unsigned width, unsigned height);
    329 
    330   /**
    331     * Unpack pixel blocks to R32G32B32A32_UINT.
    332     * Note: strides are in bytes.
    333     *
    334     * Only defined for INT formats.
    335     */
    336    void
    337    (*unpack_rgba_uint)(unsigned *dst, unsigned dst_stride,
    338                        const uint8_t *src, unsigned src_stride,
    339                        unsigned width, unsigned height);
    340 
    341    void
    342    (*pack_rgba_uint)(uint8_t *dst, unsigned dst_stride,
    343                      const unsigned *src, unsigned src_stride,
    344                      unsigned width, unsigned height);
    345 
    346   /**
    347     * Unpack pixel blocks to R32G32B32A32_SINT.
    348     * Note: strides are in bytes.
    349     *
    350     * Only defined for INT formats.
    351     */
    352    void
    353    (*unpack_rgba_sint)(signed *dst, unsigned dst_stride,
    354                        const uint8_t *src, unsigned src_stride,
    355                        unsigned width, unsigned height);
    356 
    357    void
    358    (*pack_rgba_sint)(uint8_t *dst, unsigned dst_stride,
    359                      const int *src, unsigned src_stride,
    360                      unsigned width, unsigned height);
    361 
    362    /**
    363     * Fetch a single pixel (i, j) from a block.
    364     *
    365     * Only defined for unsigned (pure) integer formats.
    366     */
    367    void
    368    (*fetch_rgba_uint)(uint32_t *dst,
    369                       const uint8_t *src,
    370                       unsigned i, unsigned j);
    371 
    372    /**
    373     * Fetch a single pixel (i, j) from a block.
    374     *
    375     * Only defined for signed (pure) integer formats.
    376     */
    377    void
    378    (*fetch_rgba_sint)(int32_t *dst,
    379                       const uint8_t *src,
    380                       unsigned i, unsigned j);
    381 };
    382 
    383 
    384 extern const struct util_format_description
    385 util_format_description_table[];
    386 
    387 
    388 const struct util_format_description *
    389 util_format_description(enum pipe_format format);
    390 
    391 
    392 /*
    393  * Format query functions.
    394  */
    395 
    396 static INLINE const char *
    397 util_format_name(enum pipe_format format)
    398 {
    399    const struct util_format_description *desc = util_format_description(format);
    400 
    401    assert(desc);
    402    if (!desc) {
    403       return "PIPE_FORMAT_???";
    404    }
    405 
    406    return desc->name;
    407 }
    408 
    409 static INLINE const char *
    410 util_format_short_name(enum pipe_format format)
    411 {
    412    const struct util_format_description *desc = util_format_description(format);
    413 
    414    assert(desc);
    415    if (!desc) {
    416       return "???";
    417    }
    418 
    419    return desc->short_name;
    420 }
    421 
    422 /**
    423  * Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info.
    424  */
    425 static INLINE boolean
    426 util_format_is_plain(enum pipe_format format)
    427 {
    428    const struct util_format_description *desc = util_format_description(format);
    429 
    430    if (!format) {
    431       return FALSE;
    432    }
    433 
    434    return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE;
    435 }
    436 
    437 static INLINE boolean
    438 util_format_is_compressed(enum pipe_format format)
    439 {
    440    const struct util_format_description *desc = util_format_description(format);
    441 
    442    assert(desc);
    443    if (!desc) {
    444       return FALSE;
    445    }
    446 
    447    switch (desc->layout) {
    448    case UTIL_FORMAT_LAYOUT_S3TC:
    449    case UTIL_FORMAT_LAYOUT_RGTC:
    450       /* XXX add other formats in the future */
    451       return TRUE;
    452    default:
    453       return FALSE;
    454    }
    455 }
    456 
    457 static INLINE boolean
    458 util_format_is_s3tc(enum pipe_format format)
    459 {
    460    const struct util_format_description *desc = util_format_description(format);
    461 
    462    assert(desc);
    463    if (!desc) {
    464       return FALSE;
    465    }
    466 
    467    return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE;
    468 }
    469 
    470 static INLINE boolean
    471 util_format_is_srgb(enum pipe_format format)
    472 {
    473    const struct util_format_description *desc = util_format_description(format);
    474    return desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB;
    475 }
    476 
    477 static INLINE boolean
    478 util_format_has_depth(const struct util_format_description *desc)
    479 {
    480    return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
    481           desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE;
    482 }
    483 
    484 static INLINE boolean
    485 util_format_has_stencil(const struct util_format_description *desc)
    486 {
    487    return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
    488           desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE;
    489 }
    490 
    491 static INLINE boolean
    492 util_format_is_depth_or_stencil(enum pipe_format format)
    493 {
    494    const struct util_format_description *desc = util_format_description(format);
    495 
    496    assert(desc);
    497    if (!desc) {
    498       return FALSE;
    499    }
    500 
    501    return util_format_has_depth(desc) ||
    502           util_format_has_stencil(desc);
    503 }
    504 
    505 static INLINE boolean
    506 util_format_is_depth_and_stencil(enum pipe_format format)
    507 {
    508    const struct util_format_description *desc = util_format_description(format);
    509 
    510    assert(desc);
    511    if (!desc) {
    512       return FALSE;
    513    }
    514 
    515    return util_format_has_depth(desc) &&
    516           util_format_has_stencil(desc);
    517 }
    518 
    519 
    520 /**
    521  * Give the RGBA colormask of the channels that can be represented in this
    522  * format.
    523  *
    524  * That is, the channels whose values are preserved.
    525  */
    526 static INLINE unsigned
    527 util_format_colormask(const struct util_format_description *desc)
    528 {
    529    unsigned colormask;
    530    unsigned chan;
    531 
    532    switch (desc->colorspace) {
    533    case UTIL_FORMAT_COLORSPACE_RGB:
    534    case UTIL_FORMAT_COLORSPACE_SRGB:
    535    case UTIL_FORMAT_COLORSPACE_YUV:
    536       colormask = 0;
    537       for (chan = 0; chan < 4; ++chan) {
    538          if (desc->swizzle[chan] < 4) {
    539             colormask |= (1 << chan);
    540          }
    541       }
    542       return colormask;
    543    case UTIL_FORMAT_COLORSPACE_ZS:
    544       return 0;
    545    default:
    546       assert(0);
    547       return 0;
    548    }
    549 }
    550 
    551 
    552 /**
    553  * Checks if color mask covers every channel for the specified format
    554  *
    555  * @param desc       a format description to check colormask with
    556  * @param colormask  a bit mask for channels, matches format of PIPE_MASK_RGBA
    557  */
    558 static INLINE boolean
    559 util_format_colormask_full(const struct util_format_description *desc, unsigned colormask)
    560 {
    561    return (~colormask & util_format_colormask(desc)) == 0;
    562 }
    563 
    564 
    565 boolean
    566 util_format_is_float(enum pipe_format format);
    567 
    568 
    569 boolean
    570 util_format_is_rgb_no_alpha(enum pipe_format format);
    571 
    572 
    573 boolean
    574 util_format_is_luminance(enum pipe_format format);
    575 
    576 
    577 boolean
    578 util_format_is_luminance_alpha(enum pipe_format format);
    579 
    580 
    581 boolean
    582 util_format_is_intensity(enum pipe_format format);
    583 
    584 boolean
    585 util_format_is_pure_integer(enum pipe_format format);
    586 
    587 boolean
    588 util_format_is_pure_sint(enum pipe_format format);
    589 
    590 boolean
    591 util_format_is_pure_uint(enum pipe_format format);
    592 
    593 /**
    594  * Whether the format is a simple array format where all channels
    595  * are of the same type and can be loaded from memory as a vector
    596  */
    597 boolean
    598 util_format_is_array(const struct util_format_description *desc);
    599 
    600 /**
    601  * Check if the src format can be blitted to the destination format with
    602  * a simple memcpy.  For example, blitting from RGBA to RGBx is OK, but not
    603  * the reverse.
    604  */
    605 boolean
    606 util_is_format_compatible(const struct util_format_description *src_desc,
    607                           const struct util_format_description *dst_desc);
    608 
    609 /**
    610  * Whether the format is supported by Gallium for the given bindings.
    611  * This covers S3TC textures and floating-point render targets.
    612  */
    613 boolean
    614 util_format_is_supported(enum pipe_format format, unsigned bind);
    615 
    616 /**
    617  * Whether this format is a rgab8 variant.
    618  *
    619  * That is, any format that matches the
    620  *
    621  *   PIPE_FORMAT_?8?8?8?8_UNORM
    622  */
    623 static INLINE boolean
    624 util_format_is_rgba8_variant(const struct util_format_description *desc)
    625 {
    626    unsigned chan;
    627 
    628    if(desc->block.width != 1 ||
    629       desc->block.height != 1 ||
    630       desc->block.bits != 32)
    631       return FALSE;
    632 
    633    for(chan = 0; chan < 4; ++chan) {
    634       if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED &&
    635          desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID)
    636          return FALSE;
    637       if(desc->channel[chan].size != 8)
    638          return FALSE;
    639    }
    640 
    641    return TRUE;
    642 }
    643 
    644 
    645 /**
    646  * Return total bits needed for the pixel format per block.
    647  */
    648 static INLINE uint
    649 util_format_get_blocksizebits(enum pipe_format format)
    650 {
    651    const struct util_format_description *desc = util_format_description(format);
    652 
    653    assert(desc);
    654    if (!desc) {
    655       return 0;
    656    }
    657 
    658    return desc->block.bits;
    659 }
    660 
    661 /**
    662  * Return bytes per block (not pixel) for the given format.
    663  */
    664 static INLINE uint
    665 util_format_get_blocksize(enum pipe_format format)
    666 {
    667    uint bits = util_format_get_blocksizebits(format);
    668 
    669    assert(bits % 8 == 0);
    670 
    671    return bits / 8;
    672 }
    673 
    674 static INLINE uint
    675 util_format_get_blockwidth(enum pipe_format format)
    676 {
    677    const struct util_format_description *desc = util_format_description(format);
    678 
    679    assert(desc);
    680    if (!desc) {
    681       return 1;
    682    }
    683 
    684    return desc->block.width;
    685 }
    686 
    687 static INLINE uint
    688 util_format_get_blockheight(enum pipe_format format)
    689 {
    690    const struct util_format_description *desc = util_format_description(format);
    691 
    692    assert(desc);
    693    if (!desc) {
    694       return 1;
    695    }
    696 
    697    return desc->block.height;
    698 }
    699 
    700 static INLINE unsigned
    701 util_format_get_nblocksx(enum pipe_format format,
    702                          unsigned x)
    703 {
    704    unsigned blockwidth = util_format_get_blockwidth(format);
    705    return (x + blockwidth - 1) / blockwidth;
    706 }
    707 
    708 static INLINE unsigned
    709 util_format_get_nblocksy(enum pipe_format format,
    710                          unsigned y)
    711 {
    712    unsigned blockheight = util_format_get_blockheight(format);
    713    return (y + blockheight - 1) / blockheight;
    714 }
    715 
    716 static INLINE unsigned
    717 util_format_get_nblocks(enum pipe_format format,
    718                         unsigned width,
    719                         unsigned height)
    720 {
    721    return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height);
    722 }
    723 
    724 static INLINE size_t
    725 util_format_get_stride(enum pipe_format format,
    726                        unsigned width)
    727 {
    728    return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format);
    729 }
    730 
    731 static INLINE size_t
    732 util_format_get_2d_size(enum pipe_format format,
    733                         size_t stride,
    734                         unsigned height)
    735 {
    736    return util_format_get_nblocksy(format, height) * stride;
    737 }
    738 
    739 static INLINE uint
    740 util_format_get_component_bits(enum pipe_format format,
    741                                enum util_format_colorspace colorspace,
    742                                uint component)
    743 {
    744    const struct util_format_description *desc = util_format_description(format);
    745    enum util_format_colorspace desc_colorspace;
    746 
    747    assert(format);
    748    if (!format) {
    749       return 0;
    750    }
    751 
    752    assert(component < 4);
    753 
    754    /* Treat RGB and SRGB as equivalent. */
    755    if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
    756       colorspace = UTIL_FORMAT_COLORSPACE_RGB;
    757    }
    758    if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
    759       desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB;
    760    } else {
    761       desc_colorspace = desc->colorspace;
    762    }
    763 
    764    if (desc_colorspace != colorspace) {
    765       return 0;
    766    }
    767 
    768    switch (desc->swizzle[component]) {
    769    case UTIL_FORMAT_SWIZZLE_X:
    770       return desc->channel[0].size;
    771    case UTIL_FORMAT_SWIZZLE_Y:
    772       return desc->channel[1].size;
    773    case UTIL_FORMAT_SWIZZLE_Z:
    774       return desc->channel[2].size;
    775    case UTIL_FORMAT_SWIZZLE_W:
    776       return desc->channel[3].size;
    777    default:
    778       return 0;
    779    }
    780 }
    781 
    782 static INLINE boolean
    783 util_format_has_alpha(enum pipe_format format)
    784 {
    785    const struct util_format_description *desc = util_format_description(format);
    786 
    787    assert(format);
    788    if (!format) {
    789       return FALSE;
    790    }
    791 
    792    switch (desc->colorspace) {
    793    case UTIL_FORMAT_COLORSPACE_RGB:
    794    case UTIL_FORMAT_COLORSPACE_SRGB:
    795       return desc->swizzle[3] != UTIL_FORMAT_SWIZZLE_1;
    796    case UTIL_FORMAT_COLORSPACE_YUV:
    797       return FALSE;
    798    case UTIL_FORMAT_COLORSPACE_ZS:
    799       return FALSE;
    800    default:
    801       assert(0);
    802       return FALSE;
    803    }
    804 }
    805 
    806 /**
    807  * Given a linear RGB colorspace format, return the corresponding SRGB
    808  * format, or PIPE_FORMAT_NONE if none.
    809  */
    810 static INLINE enum pipe_format
    811 util_format_srgb(enum pipe_format format)
    812 {
    813    switch (format) {
    814    case PIPE_FORMAT_L8_UNORM:
    815       return PIPE_FORMAT_L8_SRGB;
    816    case PIPE_FORMAT_L8A8_UNORM:
    817       return PIPE_FORMAT_L8A8_SRGB;
    818    case PIPE_FORMAT_R8G8B8_UNORM:
    819       return PIPE_FORMAT_R8G8B8_SRGB;
    820    case PIPE_FORMAT_A8B8G8R8_UNORM:
    821       return PIPE_FORMAT_A8B8G8R8_SRGB;
    822    case PIPE_FORMAT_X8B8G8R8_UNORM:
    823       return PIPE_FORMAT_X8B8G8R8_SRGB;
    824    case PIPE_FORMAT_B8G8R8A8_UNORM:
    825       return PIPE_FORMAT_B8G8R8A8_SRGB;
    826    case PIPE_FORMAT_B8G8R8X8_UNORM:
    827       return PIPE_FORMAT_B8G8R8X8_SRGB;
    828    case PIPE_FORMAT_A8R8G8B8_UNORM:
    829       return PIPE_FORMAT_A8R8G8B8_SRGB;
    830    case PIPE_FORMAT_X8R8G8B8_UNORM:
    831       return PIPE_FORMAT_X8R8G8B8_SRGB;
    832    case PIPE_FORMAT_DXT1_RGB:
    833       return PIPE_FORMAT_DXT1_SRGB;
    834    case PIPE_FORMAT_DXT1_RGBA:
    835       return PIPE_FORMAT_DXT1_SRGBA;
    836    case PIPE_FORMAT_DXT3_RGBA:
    837       return PIPE_FORMAT_DXT3_SRGBA;
    838    case PIPE_FORMAT_DXT5_RGBA:
    839       return PIPE_FORMAT_DXT5_SRGBA;
    840    default:
    841       return PIPE_FORMAT_NONE;
    842    }
    843 }
    844 
    845 /**
    846  * Given an sRGB format, return the corresponding linear colorspace format.
    847  * For non sRGB formats, return the format unchanged.
    848  */
    849 static INLINE enum pipe_format
    850 util_format_linear(enum pipe_format format)
    851 {
    852    switch (format) {
    853    case PIPE_FORMAT_L8_SRGB:
    854       return PIPE_FORMAT_L8_UNORM;
    855    case PIPE_FORMAT_L8A8_SRGB:
    856       return PIPE_FORMAT_L8A8_UNORM;
    857    case PIPE_FORMAT_R8G8B8_SRGB:
    858       return PIPE_FORMAT_R8G8B8_UNORM;
    859    case PIPE_FORMAT_A8B8G8R8_SRGB:
    860       return PIPE_FORMAT_A8B8G8R8_UNORM;
    861    case PIPE_FORMAT_X8B8G8R8_SRGB:
    862       return PIPE_FORMAT_X8B8G8R8_UNORM;
    863    case PIPE_FORMAT_B8G8R8A8_SRGB:
    864       return PIPE_FORMAT_B8G8R8A8_UNORM;
    865    case PIPE_FORMAT_B8G8R8X8_SRGB:
    866       return PIPE_FORMAT_B8G8R8X8_UNORM;
    867    case PIPE_FORMAT_A8R8G8B8_SRGB:
    868       return PIPE_FORMAT_A8R8G8B8_UNORM;
    869    case PIPE_FORMAT_X8R8G8B8_SRGB:
    870       return PIPE_FORMAT_X8R8G8B8_UNORM;
    871    case PIPE_FORMAT_DXT1_SRGB:
    872       return PIPE_FORMAT_DXT1_RGB;
    873    case PIPE_FORMAT_DXT1_SRGBA:
    874       return PIPE_FORMAT_DXT1_RGBA;
    875    case PIPE_FORMAT_DXT3_SRGBA:
    876       return PIPE_FORMAT_DXT3_RGBA;
    877    case PIPE_FORMAT_DXT5_SRGBA:
    878       return PIPE_FORMAT_DXT5_RGBA;
    879    default:
    880       return format;
    881    }
    882 }
    883 
    884 /**
    885  * Given a depth-stencil format, return the corresponding stencil-only format.
    886  * For stencil-only formats, return the format unchanged.
    887  */
    888 static INLINE enum pipe_format
    889 util_format_stencil_only(enum pipe_format format)
    890 {
    891    switch (format) {
    892    /* mask out the depth component */
    893    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
    894       return PIPE_FORMAT_X24S8_UINT;
    895    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
    896       return PIPE_FORMAT_S8X24_UINT;
    897    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
    898       return PIPE_FORMAT_X32_S8X24_UINT;
    899 
    900    /* stencil only formats */
    901    case PIPE_FORMAT_X24S8_UINT:
    902    case PIPE_FORMAT_S8X24_UINT:
    903    case PIPE_FORMAT_X32_S8X24_UINT:
    904    case PIPE_FORMAT_S8_UINT:
    905       return format;
    906 
    907    default:
    908       assert(0);
    909       return PIPE_FORMAT_NONE;
    910    }
    911 }
    912 
    913 /**
    914  * Return the number of components stored.
    915  * Formats with block size != 1x1 will always have 1 component (the block).
    916  */
    917 static INLINE unsigned
    918 util_format_get_nr_components(enum pipe_format format)
    919 {
    920    const struct util_format_description *desc = util_format_description(format);
    921    return desc->nr_channels;
    922 }
    923 
    924 /**
    925  * Return the index of the first non-void channel
    926  * -1 if no non-void channels
    927  */
    928 static INLINE int
    929 util_format_get_first_non_void_channel(enum pipe_format format)
    930 {
    931    const struct util_format_description *desc = util_format_description(format);
    932    int i;
    933 
    934    for (i = 0; i < 4; i++)
    935       if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID)
    936          break;
    937 
    938    if (i == 4)
    939        return -1;
    940 
    941    return i;
    942 }
    943 
    944 /*
    945  * Format access functions.
    946  */
    947 
    948 void
    949 util_format_read_4f(enum pipe_format format,
    950                     float *dst, unsigned dst_stride,
    951                     const void *src, unsigned src_stride,
    952                     unsigned x, unsigned y, unsigned w, unsigned h);
    953 
    954 void
    955 util_format_write_4f(enum pipe_format format,
    956                      const float *src, unsigned src_stride,
    957                      void *dst, unsigned dst_stride,
    958                      unsigned x, unsigned y, unsigned w, unsigned h);
    959 
    960 void
    961 util_format_read_4ub(enum pipe_format format,
    962                      uint8_t *dst, unsigned dst_stride,
    963                      const void *src, unsigned src_stride,
    964                      unsigned x, unsigned y, unsigned w, unsigned h);
    965 
    966 void
    967 util_format_write_4ub(enum pipe_format format,
    968                       const uint8_t *src, unsigned src_stride,
    969                       void *dst, unsigned dst_stride,
    970                       unsigned x, unsigned y, unsigned w, unsigned h);
    971 
    972 void
    973 util_format_read_4ui(enum pipe_format format,
    974                      unsigned *dst, unsigned dst_stride,
    975                      const void *src, unsigned src_stride,
    976                      unsigned x, unsigned y, unsigned w, unsigned h);
    977 
    978 void
    979 util_format_write_4ui(enum pipe_format format,
    980                       const unsigned int *src, unsigned src_stride,
    981                       void *dst, unsigned dst_stride,
    982                       unsigned x, unsigned y, unsigned w, unsigned h);
    983 
    984 void
    985 util_format_read_4i(enum pipe_format format,
    986                     int *dst, unsigned dst_stride,
    987                     const void *src, unsigned src_stride,
    988                     unsigned x, unsigned y, unsigned w, unsigned h);
    989 
    990 void
    991 util_format_write_4i(enum pipe_format format,
    992                      const int *src, unsigned src_stride,
    993                      void *dst, unsigned dst_stride,
    994                      unsigned x, unsigned y, unsigned w, unsigned h);
    995 
    996 /*
    997  * Generic format conversion;
    998  */
    999 
   1000 boolean
   1001 util_format_fits_8unorm(const struct util_format_description *format_desc);
   1002 
   1003 void
   1004 util_format_translate(enum pipe_format dst_format,
   1005                       void *dst, unsigned dst_stride,
   1006                       unsigned dst_x, unsigned dst_y,
   1007                       enum pipe_format src_format,
   1008                       const void *src, unsigned src_stride,
   1009                       unsigned src_x, unsigned src_y,
   1010                       unsigned width, unsigned height);
   1011 
   1012 /*
   1013  * Swizzle operations.
   1014  */
   1015 
   1016 /* Compose two sets of swizzles.
   1017  * If V is a 4D vector and the function parameters represent functions that
   1018  * swizzle vector components, this holds:
   1019  *     swz2(swz1(V)) = dst(V)
   1020  */
   1021 void util_format_compose_swizzles(const unsigned char swz1[4],
   1022                                   const unsigned char swz2[4],
   1023                                   unsigned char dst[4]);
   1024 
   1025 void util_format_swizzle_4f(float *dst, const float *src,
   1026                             const unsigned char swz[4]);
   1027 
   1028 void util_format_unswizzle_4f(float *dst, const float *src,
   1029                               const unsigned char swz[4]);
   1030 
   1031 #ifdef __cplusplus
   1032 } // extern "C" {
   1033 #endif
   1034 
   1035 #endif /* ! U_FORMAT_H */
   1036