Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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