Path: blob/21.2-virgl/src/util/format/u_format.h
7099 views
/**************************************************************************1*2* Copyright 2009-2010 VMware, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/262728#ifndef U_FORMAT_H29#define U_FORMAT_H303132#include "pipe/p_format.h"33#include "pipe/p_defines.h"34#include "util/u_debug.h"3536union pipe_color_union;37struct pipe_screen;383940#ifdef __cplusplus41extern "C" {42#endif434445/**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 down49* in flags inside util_format_block that said exactly what we want.50*/51enum util_format_layout {52/**53* Formats with util_format_block::width == util_format_block::height == 154* that can be described as an ordinary data structure.55*/56UTIL_FORMAT_LAYOUT_PLAIN,5758/**59* Formats with sub-sampled channels.60*61* This is for formats like YVYU where there is less than one sample per62* pixel.63*/64UTIL_FORMAT_LAYOUT_SUBSAMPLED,6566/**67* S3 Texture Compression formats.68*/69UTIL_FORMAT_LAYOUT_S3TC,7071/**72* Red-Green Texture Compression formats.73*/74UTIL_FORMAT_LAYOUT_RGTC,7576/**77* Ericsson Texture Compression78*/79UTIL_FORMAT_LAYOUT_ETC,8081/**82* BC6/7 Texture Compression83*/84UTIL_FORMAT_LAYOUT_BPTC,8586UTIL_FORMAT_LAYOUT_ASTC,8788UTIL_FORMAT_LAYOUT_ATC,8990/** Formats with 2 or more planes. */91UTIL_FORMAT_LAYOUT_PLANAR2,92UTIL_FORMAT_LAYOUT_PLANAR3,9394UTIL_FORMAT_LAYOUT_FXT1 = 10,9596/**97* Everything else that doesn't fit in any of the above layouts.98*/99UTIL_FORMAT_LAYOUT_OTHER,100};101102103struct util_format_block104{105/** Block width in pixels */106unsigned width;107108/** Block height in pixels */109unsigned height;110111/** Block depth in pixels */112unsigned depth;113114/** Block size in bits */115unsigned bits;116};117118119enum util_format_type {120UTIL_FORMAT_TYPE_VOID = 0,121UTIL_FORMAT_TYPE_UNSIGNED = 1,122UTIL_FORMAT_TYPE_SIGNED = 2,123UTIL_FORMAT_TYPE_FIXED = 3,124UTIL_FORMAT_TYPE_FLOAT = 4125};126127128enum util_format_colorspace {129UTIL_FORMAT_COLORSPACE_RGB = 0,130UTIL_FORMAT_COLORSPACE_SRGB = 1,131UTIL_FORMAT_COLORSPACE_YUV = 2,132UTIL_FORMAT_COLORSPACE_ZS = 3133};134135136struct util_format_channel_description137{138unsigned type:5; /**< UTIL_FORMAT_TYPE_x */139unsigned normalized:1;140unsigned pure_integer:1;141unsigned size:9; /**< bits per channel */142unsigned shift:16; /** number of bits from lsb */143};144145146struct util_format_description147{148enum pipe_format format;149150const char *name;151152/**153* Short name, striped of the prefix, lower case.154*/155const char *short_name;156157/**158* Pixel block dimensions.159*/160struct util_format_block block;161162enum util_format_layout layout;163164/**165* The number of channels.166*/167unsigned nr_channels:3;168169/**170* Whether all channels have the same number of (whole) bytes and type.171*/172unsigned is_array:1;173174/**175* Whether the pixel format can be described as a bitfield structure.176*177* In particular:178* - pixel depth must be 8, 16, or 32 bits;179* - all channels must be unsigned, signed, or void180*/181unsigned is_bitmask:1;182183/**184* Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID).185*/186unsigned is_mixed:1;187188/**189* Whether the format contains UNORM channels190*/191unsigned is_unorm:1;192193/**194* Whether the format contains SNORM channels195*/196unsigned is_snorm:1;197198/**199* Input channel description, in the order XYZW.200*201* Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats.202*203* If each channel is accessed as an individual N-byte value, X is always204* at the lowest address in memory, Y is always next, and so on. For all205* currently-defined formats, the N-byte value has native endianness.206*207* If instead a group of channels is accessed as a single N-byte value,208* the order of the channels within that value depends on endianness.209* For big-endian targets, X is the most significant subvalue,210* otherwise it is the least significant one.211*212* For example, if X is 8 bits and Y is 24 bits, the memory order is:213*214* 0 1 2 3215* little-endian: X Yl Ym Yu (l = lower, m = middle, u = upper)216* big-endian: X Yu Ym Yl217*218* If X is 5 bits, Y is 5 bits, Z is 5 bits and W is 1 bit, the layout is:219*220* 0 1221* msb lsb msb lsb222* little-endian: YYYXXXXX WZZZZZYY223* big-endian: XXXXXYYY YYZZZZZW224*/225struct util_format_channel_description channel[4];226227/**228* Output channel swizzle.229*230* The order is either:231* - RGBA232* - YUV(A)233* - ZS234* depending on the colorspace.235*/236unsigned char swizzle[4];237238/**239* Colorspace transformation.240*/241enum util_format_colorspace colorspace;242};243244struct util_format_pack_description {245/**246* Pack pixel blocks from R8G8B8A8_UNORM.247* Note: strides are in bytes.248*249* Only defined for non-depth-stencil formats.250*/251void252(*pack_rgba_8unorm)(uint8_t *restrict dst, unsigned dst_stride,253const uint8_t *restrict src, unsigned src_stride,254unsigned width, unsigned height);255256/**257* Pack pixel blocks from R32G32B32A32_FLOAT.258* Note: strides are in bytes.259*260* Only defined for non-depth-stencil formats.261*/262void263(*pack_rgba_float)(uint8_t *restrict dst, unsigned dst_stride,264const float *restrict src, unsigned src_stride,265unsigned width, unsigned height);266267/**268* Pack pixels from Z32_FLOAT.269* Note: strides are in bytes.270*271* Only defined for depth formats.272*/273void274(*pack_z_32unorm)(uint8_t *restrict dst, unsigned dst_stride,275const uint32_t *restrict src, unsigned src_stride,276unsigned width, unsigned height);277278/**279* Pack pixels from Z32_FLOAT.280* Note: strides are in bytes.281*282* Only defined for depth formats.283*/284void285(*pack_z_float)(uint8_t *restrict dst, unsigned dst_stride,286const float *restrict src, unsigned src_stride,287unsigned width, unsigned height);288289/**290* Pack pixels from S8_UINT.291* Note: strides are in bytes.292*293* Only defined for stencil formats.294*/295void296(*pack_s_8uint)(uint8_t *restrict dst, unsigned dst_stride,297const uint8_t *restrict src, unsigned src_stride,298unsigned width, unsigned height);299300void301(*pack_rgba_uint)(uint8_t *restrict dst, unsigned dst_stride,302const uint32_t *restrict src, unsigned src_stride,303unsigned width, unsigned height);304305void306(*pack_rgba_sint)(uint8_t *restrict dst, unsigned dst_stride,307const int32_t *restrict src, unsigned src_stride,308unsigned width, unsigned height);309};310311312struct util_format_unpack_description {313/**314* Unpack pixel blocks to R8G8B8A8_UNORM.315* Note: strides are in bytes.316*317* Only defined for non-block non-depth-stencil formats.318*/319void320(*unpack_rgba_8unorm)(uint8_t *restrict dst, const uint8_t *restrict src,321unsigned width);322323/**324* Unpack pixel blocks to R8G8B8A8_UNORM.325* Note: strides are in bytes.326*327* Only defined for block non-depth-stencil formats.328*/329void330(*unpack_rgba_8unorm_rect)(uint8_t *restrict dst, unsigned dst_stride,331const uint8_t *restrict src, unsigned src_stride,332unsigned width, unsigned height);333334/**335* Fetch a single pixel (i, j) from a block.336*337* XXX: Only defined for a very few select formats.338*/339void340(*fetch_rgba_8unorm)(uint8_t *restrict dst,341const uint8_t *restrict src,342unsigned i, unsigned j);343344/**345* Unpack pixel blocks to R32G32B32A32_UINT/_INT_FLOAT based on whether the346* type is pure uint, int, or other.347*348* Note: strides are in bytes.349*350* Only defined for non-block non-depth-stencil formats.351*/352void353(*unpack_rgba)(void *restrict dst, const uint8_t *restrict src,354unsigned width);355356/**357* Unpack pixel blocks to R32G32B32A32_UINT/_INT_FLOAT based on whether the358* type is pure uint, int, or other.359*360* Note: strides are in bytes.361*362* Only defined for block non-depth-stencil formats.363*/364void365(*unpack_rgba_rect)(void *restrict dst, unsigned dst_stride,366const uint8_t *restrict src, unsigned src_stride,367unsigned width, unsigned height);368369/**370* Unpack pixels to Z32_UNORM.371* Note: strides are in bytes.372*373* Only defined for depth formats.374*/375void376(*unpack_z_32unorm)(uint32_t *restrict dst, unsigned dst_stride,377const uint8_t *restrict src, unsigned src_stride,378unsigned width, unsigned height);379380/**381* Unpack pixels to Z32_FLOAT.382* Note: strides are in bytes.383*384* Only defined for depth formats.385*/386void387(*unpack_z_float)(float *restrict dst, unsigned dst_stride,388const uint8_t *restrict src, unsigned src_stride,389unsigned width, unsigned height);390391/**392* Unpack pixels to S8_UINT.393* Note: strides are in bytes.394*395* Only defined for stencil formats.396*/397void398(*unpack_s_8uint)(uint8_t *restrict dst, unsigned dst_stride,399const uint8_t *restrict src, unsigned src_stride,400unsigned width, unsigned height);401};402403typedef void (*util_format_fetch_rgba_func_ptr)(void *restrict dst, const uint8_t *restrict src,404unsigned i, unsigned j);405406/* Silence warnings triggered by sharing function/struct names */407#ifdef __GNUC__408#pragma GCC diagnostic push409#pragma GCC diagnostic ignored "-Wshadow"410#endif411const struct util_format_description *412util_format_description(enum pipe_format format) ATTRIBUTE_CONST;413414const struct util_format_pack_description *415util_format_pack_description(enum pipe_format format) ATTRIBUTE_CONST;416417/* Lookup with CPU detection for choosing optimized paths. */418const struct util_format_unpack_description *419util_format_unpack_description(enum pipe_format format) ATTRIBUTE_CONST;420421/* Codegenned table of CPU-agnostic unpack code. */422const struct util_format_unpack_description *423util_format_unpack_description_generic(enum pipe_format format) ATTRIBUTE_CONST;424425const struct util_format_unpack_description *426util_format_unpack_description_neon(enum pipe_format format) ATTRIBUTE_CONST;427428#ifdef __GNUC__429#pragma GCC diagnostic pop430#endif431432/**433* Returns a function to fetch a single pixel (i, j) from a block.434*435* Only defined for non-depth-stencil and non-integer formats.436*/437util_format_fetch_rgba_func_ptr438util_format_fetch_rgba_func(enum pipe_format format) ATTRIBUTE_CONST;439440/*441* Format query functions.442*/443444static inline const char *445util_format_name(enum pipe_format format)446{447const struct util_format_description *desc = util_format_description(format);448449assert(desc);450if (!desc) {451return "PIPE_FORMAT_???";452}453454return desc->name;455}456457static inline const char *458util_format_short_name(enum pipe_format format)459{460const struct util_format_description *desc = util_format_description(format);461462assert(desc);463if (!desc) {464return "???";465}466467return desc->short_name;468}469470/**471* Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info.472*/473static inline boolean474util_format_is_plain(enum pipe_format format)475{476const struct util_format_description *desc = util_format_description(format);477478if (!format) {479return FALSE;480}481482return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE;483}484485static inline boolean486util_format_is_compressed(enum pipe_format format)487{488const struct util_format_description *desc = util_format_description(format);489490assert(desc);491if (!desc) {492return FALSE;493}494495switch (desc->layout) {496case UTIL_FORMAT_LAYOUT_S3TC:497case UTIL_FORMAT_LAYOUT_RGTC:498case UTIL_FORMAT_LAYOUT_ETC:499case UTIL_FORMAT_LAYOUT_BPTC:500case UTIL_FORMAT_LAYOUT_ASTC:501case UTIL_FORMAT_LAYOUT_ATC:502case UTIL_FORMAT_LAYOUT_FXT1:503/* XXX add other formats in the future */504return TRUE;505default:506return FALSE;507}508}509510static inline boolean511util_format_is_s3tc(enum pipe_format format)512{513const struct util_format_description *desc = util_format_description(format);514515assert(desc);516if (!desc) {517return FALSE;518}519520return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE;521}522523static inline boolean524util_format_is_etc(enum pipe_format format)525{526const struct util_format_description *desc = util_format_description(format);527528assert(desc);529if (!desc) {530return FALSE;531}532533return desc->layout == UTIL_FORMAT_LAYOUT_ETC ? TRUE : FALSE;534}535536static inline boolean537util_format_is_srgb(enum pipe_format format)538{539const struct util_format_description *desc = util_format_description(format);540return desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB;541}542543static inline boolean544util_format_has_depth(const struct util_format_description *desc)545{546return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&547desc->swizzle[0] != PIPE_SWIZZLE_NONE;548}549550static inline boolean551util_format_has_stencil(const struct util_format_description *desc)552{553return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&554desc->swizzle[1] != PIPE_SWIZZLE_NONE;555}556557static inline boolean558util_format_is_depth_or_stencil(enum pipe_format format)559{560const struct util_format_description *desc = util_format_description(format);561562assert(desc);563if (!desc) {564return FALSE;565}566567return util_format_has_depth(desc) ||568util_format_has_stencil(desc);569}570571static inline boolean572util_format_is_depth_and_stencil(enum pipe_format format)573{574const struct util_format_description *desc = util_format_description(format);575576assert(desc);577if (!desc) {578return FALSE;579}580581return util_format_has_depth(desc) &&582util_format_has_stencil(desc);583}584585/**586* For depth-stencil formats, return the equivalent depth-only format.587*/588static inline enum pipe_format589util_format_get_depth_only(enum pipe_format format)590{591switch (format) {592case PIPE_FORMAT_Z24_UNORM_S8_UINT:593return PIPE_FORMAT_Z24X8_UNORM;594595case PIPE_FORMAT_S8_UINT_Z24_UNORM:596return PIPE_FORMAT_X8Z24_UNORM;597598case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:599return PIPE_FORMAT_Z32_FLOAT;600601default:602return format;603}604}605606static inline boolean607util_format_is_yuv(enum pipe_format format)608{609const struct util_format_description *desc = util_format_description(format);610611assert(desc);612if (!desc) {613return FALSE;614}615616return desc->colorspace == UTIL_FORMAT_COLORSPACE_YUV;617}618619/**620* Calculates the depth format type based upon the incoming format description.621*/622static inline unsigned623util_get_depth_format_type(const struct util_format_description *desc)624{625unsigned depth_channel = desc->swizzle[0];626if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&627depth_channel != PIPE_SWIZZLE_NONE) {628return desc->channel[depth_channel].type;629} else {630return UTIL_FORMAT_TYPE_VOID;631}632}633634635/**636* Calculates the MRD for the depth format. MRD is used in depth bias637* for UNORM and unbound depth buffers. When the depth buffer is floating638* point, the depth bias calculation does not use the MRD. However, the639* default MRD will be 1.0 / ((1 << 24) - 1).640*/641double642util_get_depth_format_mrd(const struct util_format_description *desc);643644645/**646* Return whether this is an RGBA, Z, S, or combined ZS format.647* Useful for initializing pipe_blit_info::mask.648*/649static inline unsigned650util_format_get_mask(enum pipe_format format)651{652const struct util_format_description *desc =653util_format_description(format);654655if (!desc)656return 0;657658if (util_format_has_depth(desc)) {659if (util_format_has_stencil(desc)) {660return PIPE_MASK_ZS;661} else {662return PIPE_MASK_Z;663}664} else {665if (util_format_has_stencil(desc)) {666return PIPE_MASK_S;667} else {668return PIPE_MASK_RGBA;669}670}671}672673/**674* Give the RGBA colormask of the channels that can be represented in this675* format.676*677* That is, the channels whose values are preserved.678*/679static inline unsigned680util_format_colormask(const struct util_format_description *desc)681{682unsigned colormask;683unsigned chan;684685switch (desc->colorspace) {686case UTIL_FORMAT_COLORSPACE_RGB:687case UTIL_FORMAT_COLORSPACE_SRGB:688case UTIL_FORMAT_COLORSPACE_YUV:689colormask = 0;690for (chan = 0; chan < 4; ++chan) {691if (desc->swizzle[chan] < 4) {692colormask |= (1 << chan);693}694}695return colormask;696case UTIL_FORMAT_COLORSPACE_ZS:697return 0;698default:699assert(0);700return 0;701}702}703704705/**706* Checks if color mask covers every channel for the specified format707*708* @param desc a format description to check colormask with709* @param colormask a bit mask for channels, matches format of PIPE_MASK_RGBA710*/711static inline boolean712util_format_colormask_full(const struct util_format_description *desc, unsigned colormask)713{714return (~colormask & util_format_colormask(desc)) == 0;715}716717718boolean719util_format_is_float(enum pipe_format format) ATTRIBUTE_CONST;720721722boolean723util_format_has_alpha(enum pipe_format format) ATTRIBUTE_CONST;724725boolean726util_format_has_alpha1(enum pipe_format format) ATTRIBUTE_CONST;727728boolean729util_format_is_luminance(enum pipe_format format) ATTRIBUTE_CONST;730731boolean732util_format_is_alpha(enum pipe_format format) ATTRIBUTE_CONST;733734boolean735util_format_is_luminance_alpha(enum pipe_format format) ATTRIBUTE_CONST;736737738boolean739util_format_is_intensity(enum pipe_format format) ATTRIBUTE_CONST;740741boolean742util_format_is_subsampled_422(enum pipe_format format) ATTRIBUTE_CONST;743744boolean745util_format_is_pure_integer(enum pipe_format format) ATTRIBUTE_CONST;746747boolean748util_format_is_pure_sint(enum pipe_format format) ATTRIBUTE_CONST;749750boolean751util_format_is_pure_uint(enum pipe_format format) ATTRIBUTE_CONST;752753boolean754util_format_is_snorm(enum pipe_format format) ATTRIBUTE_CONST;755756boolean757util_format_is_unorm(enum pipe_format format) ATTRIBUTE_CONST;758759boolean760util_format_is_snorm8(enum pipe_format format) ATTRIBUTE_CONST;761762boolean763util_format_is_scaled(enum pipe_format format) ATTRIBUTE_CONST;764/**765* Check if the src format can be blitted to the destination format with766* a simple memcpy. For example, blitting from RGBA to RGBx is OK, but not767* the reverse.768*/769boolean770util_is_format_compatible(const struct util_format_description *src_desc,771const struct util_format_description *dst_desc) ATTRIBUTE_CONST;772773/**774* Whether this format is a rgab8 variant.775*776* That is, any format that matches the777*778* PIPE_FORMAT_?8?8?8?8_UNORM779*/780static inline boolean781util_format_is_rgba8_variant(const struct util_format_description *desc)782{783unsigned chan;784785if(desc->block.width != 1 ||786desc->block.height != 1 ||787desc->block.bits != 32)788return FALSE;789790for(chan = 0; chan < 4; ++chan) {791if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED &&792desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID)793return FALSE;794if(desc->channel[chan].type == UTIL_FORMAT_TYPE_UNSIGNED &&795!desc->channel[chan].normalized)796return FALSE;797if(desc->channel[chan].size != 8)798return FALSE;799}800801return TRUE;802}803804805static inline bool806util_format_is_rgbx_or_bgrx(enum pipe_format format)807{808const struct util_format_description *desc = util_format_description(format);809return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&810desc->nr_channels == 4 &&811(desc->swizzle[0] == PIPE_SWIZZLE_X || desc->swizzle[0] == PIPE_SWIZZLE_Z) &&812desc->swizzle[1] == PIPE_SWIZZLE_Y &&813(desc->swizzle[2] == PIPE_SWIZZLE_Z || desc->swizzle[2] == PIPE_SWIZZLE_X) &&814desc->swizzle[3] == PIPE_SWIZZLE_1;815}816817/**818* Return total bits needed for the pixel format per block.819*/820static inline uint821util_format_get_blocksizebits(enum pipe_format format)822{823const struct util_format_description *desc = util_format_description(format);824825assert(desc);826if (!desc) {827return 0;828}829830return desc->block.bits;831}832833/**834* Return bytes per block (not pixel) for the given format.835*/836static inline uint837util_format_get_blocksize(enum pipe_format format)838{839uint bits = util_format_get_blocksizebits(format);840uint bytes = bits / 8;841842assert(bits % 8 == 0);843assert(bytes > 0);844if (bytes == 0) {845bytes = 1;846}847848return bytes;849}850851static inline uint852util_format_get_blockwidth(enum pipe_format format)853{854const struct util_format_description *desc = util_format_description(format);855856assert(desc);857if (!desc) {858return 1;859}860861return desc->block.width;862}863864static inline uint865util_format_get_blockheight(enum pipe_format format)866{867const struct util_format_description *desc = util_format_description(format);868869assert(desc);870if (!desc) {871return 1;872}873874return desc->block.height;875}876877static inline uint878util_format_get_blockdepth(enum pipe_format format)879{880const struct util_format_description *desc = util_format_description(format);881882assert(desc);883if (!desc) {884return 1;885}886887return desc->block.depth;888}889890static inline unsigned891util_format_get_nblocksx(enum pipe_format format,892unsigned x)893{894unsigned blockwidth = util_format_get_blockwidth(format);895return (x + blockwidth - 1) / blockwidth;896}897898static inline unsigned899util_format_get_nblocksy(enum pipe_format format,900unsigned y)901{902unsigned blockheight = util_format_get_blockheight(format);903return (y + blockheight - 1) / blockheight;904}905906static inline unsigned907util_format_get_nblocksz(enum pipe_format format,908unsigned z)909{910unsigned blockdepth = util_format_get_blockdepth(format);911return (z + blockdepth - 1) / blockdepth;912}913914static inline unsigned915util_format_get_nblocks(enum pipe_format format,916unsigned width,917unsigned height)918{919assert(util_format_get_blockdepth(format) == 1);920return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height);921}922923static inline size_t924util_format_get_stride(enum pipe_format format,925unsigned width)926{927return (size_t)util_format_get_nblocksx(format, width) * util_format_get_blocksize(format);928}929930static inline size_t931util_format_get_2d_size(enum pipe_format format,932size_t stride,933unsigned height)934{935return util_format_get_nblocksy(format, height) * stride;936}937938static inline uint939util_format_get_component_bits(enum pipe_format format,940enum util_format_colorspace colorspace,941uint component)942{943const struct util_format_description *desc = util_format_description(format);944enum util_format_colorspace desc_colorspace;945946assert(format);947if (!format) {948return 0;949}950951assert(component < 4);952953/* Treat RGB and SRGB as equivalent. */954if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {955colorspace = UTIL_FORMAT_COLORSPACE_RGB;956}957if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {958desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB;959} else {960desc_colorspace = desc->colorspace;961}962963if (desc_colorspace != colorspace) {964return 0;965}966967switch (desc->swizzle[component]) {968case PIPE_SWIZZLE_X:969return desc->channel[0].size;970case PIPE_SWIZZLE_Y:971return desc->channel[1].size;972case PIPE_SWIZZLE_Z:973return desc->channel[2].size;974case PIPE_SWIZZLE_W:975return desc->channel[3].size;976default:977return 0;978}979}980981/**982* Given a linear RGB colorspace format, return the corresponding SRGB983* format, or PIPE_FORMAT_NONE if none.984*/985static inline enum pipe_format986util_format_srgb(enum pipe_format format)987{988if (util_format_is_srgb(format))989return format;990991switch (format) {992case PIPE_FORMAT_L8_UNORM:993return PIPE_FORMAT_L8_SRGB;994case PIPE_FORMAT_R8_UNORM:995return PIPE_FORMAT_R8_SRGB;996case PIPE_FORMAT_L8A8_UNORM:997return PIPE_FORMAT_L8A8_SRGB;998case PIPE_FORMAT_R8G8_UNORM:999return PIPE_FORMAT_R8G8_SRGB;1000case PIPE_FORMAT_R8G8B8_UNORM:1001return PIPE_FORMAT_R8G8B8_SRGB;1002case PIPE_FORMAT_B8G8R8_UNORM:1003return PIPE_FORMAT_B8G8R8_SRGB;1004case PIPE_FORMAT_A8B8G8R8_UNORM:1005return PIPE_FORMAT_A8B8G8R8_SRGB;1006case PIPE_FORMAT_X8B8G8R8_UNORM:1007return PIPE_FORMAT_X8B8G8R8_SRGB;1008case PIPE_FORMAT_B8G8R8A8_UNORM:1009return PIPE_FORMAT_B8G8R8A8_SRGB;1010case PIPE_FORMAT_B8G8R8X8_UNORM:1011return PIPE_FORMAT_B8G8R8X8_SRGB;1012case PIPE_FORMAT_A8R8G8B8_UNORM:1013return PIPE_FORMAT_A8R8G8B8_SRGB;1014case PIPE_FORMAT_X8R8G8B8_UNORM:1015return PIPE_FORMAT_X8R8G8B8_SRGB;1016case PIPE_FORMAT_R8G8B8A8_UNORM:1017return PIPE_FORMAT_R8G8B8A8_SRGB;1018case PIPE_FORMAT_R8G8B8X8_UNORM:1019return PIPE_FORMAT_R8G8B8X8_SRGB;1020case PIPE_FORMAT_DXT1_RGB:1021return PIPE_FORMAT_DXT1_SRGB;1022case PIPE_FORMAT_DXT1_RGBA:1023return PIPE_FORMAT_DXT1_SRGBA;1024case PIPE_FORMAT_DXT3_RGBA:1025return PIPE_FORMAT_DXT3_SRGBA;1026case PIPE_FORMAT_DXT5_RGBA:1027return PIPE_FORMAT_DXT5_SRGBA;1028case PIPE_FORMAT_R5G6B5_UNORM:1029return PIPE_FORMAT_R5G6B5_SRGB;1030case PIPE_FORMAT_B5G6R5_UNORM:1031return PIPE_FORMAT_B5G6R5_SRGB;1032case PIPE_FORMAT_BPTC_RGBA_UNORM:1033return PIPE_FORMAT_BPTC_SRGBA;1034case PIPE_FORMAT_ETC2_RGB8:1035return PIPE_FORMAT_ETC2_SRGB8;1036case PIPE_FORMAT_ETC2_RGB8A1:1037return PIPE_FORMAT_ETC2_SRGB8A1;1038case PIPE_FORMAT_ETC2_RGBA8:1039return PIPE_FORMAT_ETC2_SRGBA8;1040case PIPE_FORMAT_ASTC_4x4:1041return PIPE_FORMAT_ASTC_4x4_SRGB;1042case PIPE_FORMAT_ASTC_5x4:1043return PIPE_FORMAT_ASTC_5x4_SRGB;1044case PIPE_FORMAT_ASTC_5x5:1045return PIPE_FORMAT_ASTC_5x5_SRGB;1046case PIPE_FORMAT_ASTC_6x5:1047return PIPE_FORMAT_ASTC_6x5_SRGB;1048case PIPE_FORMAT_ASTC_6x6:1049return PIPE_FORMAT_ASTC_6x6_SRGB;1050case PIPE_FORMAT_ASTC_8x5:1051return PIPE_FORMAT_ASTC_8x5_SRGB;1052case PIPE_FORMAT_ASTC_8x6:1053return PIPE_FORMAT_ASTC_8x6_SRGB;1054case PIPE_FORMAT_ASTC_8x8:1055return PIPE_FORMAT_ASTC_8x8_SRGB;1056case PIPE_FORMAT_ASTC_10x5:1057return PIPE_FORMAT_ASTC_10x5_SRGB;1058case PIPE_FORMAT_ASTC_10x6:1059return PIPE_FORMAT_ASTC_10x6_SRGB;1060case PIPE_FORMAT_ASTC_10x8:1061return PIPE_FORMAT_ASTC_10x8_SRGB;1062case PIPE_FORMAT_ASTC_10x10:1063return PIPE_FORMAT_ASTC_10x10_SRGB;1064case PIPE_FORMAT_ASTC_12x10:1065return PIPE_FORMAT_ASTC_12x10_SRGB;1066case PIPE_FORMAT_ASTC_12x12:1067return PIPE_FORMAT_ASTC_12x12_SRGB;1068case PIPE_FORMAT_ASTC_3x3x3:1069return PIPE_FORMAT_ASTC_3x3x3_SRGB;1070case PIPE_FORMAT_ASTC_4x3x3:1071return PIPE_FORMAT_ASTC_4x3x3_SRGB;1072case PIPE_FORMAT_ASTC_4x4x3:1073return PIPE_FORMAT_ASTC_4x4x3_SRGB;1074case PIPE_FORMAT_ASTC_4x4x4:1075return PIPE_FORMAT_ASTC_4x4x4_SRGB;1076case PIPE_FORMAT_ASTC_5x4x4:1077return PIPE_FORMAT_ASTC_5x4x4_SRGB;1078case PIPE_FORMAT_ASTC_5x5x4:1079return PIPE_FORMAT_ASTC_5x5x4_SRGB;1080case PIPE_FORMAT_ASTC_5x5x5:1081return PIPE_FORMAT_ASTC_5x5x5_SRGB;1082case PIPE_FORMAT_ASTC_6x5x5:1083return PIPE_FORMAT_ASTC_6x5x5_SRGB;1084case PIPE_FORMAT_ASTC_6x6x5:1085return PIPE_FORMAT_ASTC_6x6x5_SRGB;1086case PIPE_FORMAT_ASTC_6x6x6:1087return PIPE_FORMAT_ASTC_6x6x6_SRGB;10881089default:1090return PIPE_FORMAT_NONE;1091}1092}10931094/**1095* Given an sRGB format, return the corresponding linear colorspace format.1096* For non sRGB formats, return the format unchanged.1097*/1098static inline enum pipe_format1099util_format_linear(enum pipe_format format)1100{1101switch (format) {1102case PIPE_FORMAT_L8_SRGB:1103return PIPE_FORMAT_L8_UNORM;1104case PIPE_FORMAT_R8_SRGB:1105return PIPE_FORMAT_R8_UNORM;1106case PIPE_FORMAT_L8A8_SRGB:1107return PIPE_FORMAT_L8A8_UNORM;1108case PIPE_FORMAT_R8G8_SRGB:1109return PIPE_FORMAT_R8G8_UNORM;1110case PIPE_FORMAT_R8G8B8_SRGB:1111return PIPE_FORMAT_R8G8B8_UNORM;1112case PIPE_FORMAT_B8G8R8_SRGB:1113return PIPE_FORMAT_B8G8R8_UNORM;1114case PIPE_FORMAT_A8B8G8R8_SRGB:1115return PIPE_FORMAT_A8B8G8R8_UNORM;1116case PIPE_FORMAT_X8B8G8R8_SRGB:1117return PIPE_FORMAT_X8B8G8R8_UNORM;1118case PIPE_FORMAT_B8G8R8A8_SRGB:1119return PIPE_FORMAT_B8G8R8A8_UNORM;1120case PIPE_FORMAT_B8G8R8X8_SRGB:1121return PIPE_FORMAT_B8G8R8X8_UNORM;1122case PIPE_FORMAT_A8R8G8B8_SRGB:1123return PIPE_FORMAT_A8R8G8B8_UNORM;1124case PIPE_FORMAT_X8R8G8B8_SRGB:1125return PIPE_FORMAT_X8R8G8B8_UNORM;1126case PIPE_FORMAT_R8G8B8A8_SRGB:1127return PIPE_FORMAT_R8G8B8A8_UNORM;1128case PIPE_FORMAT_R8G8B8X8_SRGB:1129return PIPE_FORMAT_R8G8B8X8_UNORM;1130case PIPE_FORMAT_DXT1_SRGB:1131return PIPE_FORMAT_DXT1_RGB;1132case PIPE_FORMAT_DXT1_SRGBA:1133return PIPE_FORMAT_DXT1_RGBA;1134case PIPE_FORMAT_DXT3_SRGBA:1135return PIPE_FORMAT_DXT3_RGBA;1136case PIPE_FORMAT_DXT5_SRGBA:1137return PIPE_FORMAT_DXT5_RGBA;1138case PIPE_FORMAT_R5G6B5_SRGB:1139return PIPE_FORMAT_R5G6B5_UNORM;1140case PIPE_FORMAT_B5G6R5_SRGB:1141return PIPE_FORMAT_B5G6R5_UNORM;1142case PIPE_FORMAT_BPTC_SRGBA:1143return PIPE_FORMAT_BPTC_RGBA_UNORM;1144case PIPE_FORMAT_ETC2_SRGB8:1145return PIPE_FORMAT_ETC2_RGB8;1146case PIPE_FORMAT_ETC2_SRGB8A1:1147return PIPE_FORMAT_ETC2_RGB8A1;1148case PIPE_FORMAT_ETC2_SRGBA8:1149return PIPE_FORMAT_ETC2_RGBA8;1150case PIPE_FORMAT_ASTC_4x4_SRGB:1151return PIPE_FORMAT_ASTC_4x4;1152case PIPE_FORMAT_ASTC_5x4_SRGB:1153return PIPE_FORMAT_ASTC_5x4;1154case PIPE_FORMAT_ASTC_5x5_SRGB:1155return PIPE_FORMAT_ASTC_5x5;1156case PIPE_FORMAT_ASTC_6x5_SRGB:1157return PIPE_FORMAT_ASTC_6x5;1158case PIPE_FORMAT_ASTC_6x6_SRGB:1159return PIPE_FORMAT_ASTC_6x6;1160case PIPE_FORMAT_ASTC_8x5_SRGB:1161return PIPE_FORMAT_ASTC_8x5;1162case PIPE_FORMAT_ASTC_8x6_SRGB:1163return PIPE_FORMAT_ASTC_8x6;1164case PIPE_FORMAT_ASTC_8x8_SRGB:1165return PIPE_FORMAT_ASTC_8x8;1166case PIPE_FORMAT_ASTC_10x5_SRGB:1167return PIPE_FORMAT_ASTC_10x5;1168case PIPE_FORMAT_ASTC_10x6_SRGB:1169return PIPE_FORMAT_ASTC_10x6;1170case PIPE_FORMAT_ASTC_10x8_SRGB:1171return PIPE_FORMAT_ASTC_10x8;1172case PIPE_FORMAT_ASTC_10x10_SRGB:1173return PIPE_FORMAT_ASTC_10x10;1174case PIPE_FORMAT_ASTC_12x10_SRGB:1175return PIPE_FORMAT_ASTC_12x10;1176case PIPE_FORMAT_ASTC_12x12_SRGB:1177return PIPE_FORMAT_ASTC_12x12;1178case PIPE_FORMAT_ASTC_3x3x3_SRGB:1179return PIPE_FORMAT_ASTC_3x3x3;1180case PIPE_FORMAT_ASTC_4x3x3_SRGB:1181return PIPE_FORMAT_ASTC_4x3x3;1182case PIPE_FORMAT_ASTC_4x4x3_SRGB:1183return PIPE_FORMAT_ASTC_4x4x3;1184case PIPE_FORMAT_ASTC_4x4x4_SRGB:1185return PIPE_FORMAT_ASTC_4x4x4;1186case PIPE_FORMAT_ASTC_5x4x4_SRGB:1187return PIPE_FORMAT_ASTC_5x4x4;1188case PIPE_FORMAT_ASTC_5x5x4_SRGB:1189return PIPE_FORMAT_ASTC_5x5x4;1190case PIPE_FORMAT_ASTC_5x5x5_SRGB:1191return PIPE_FORMAT_ASTC_5x5x5;1192case PIPE_FORMAT_ASTC_6x5x5_SRGB:1193return PIPE_FORMAT_ASTC_6x5x5;1194case PIPE_FORMAT_ASTC_6x6x5_SRGB:1195return PIPE_FORMAT_ASTC_6x6x5;1196case PIPE_FORMAT_ASTC_6x6x6_SRGB:1197return PIPE_FORMAT_ASTC_6x6x6;1198default:1199assert(!util_format_is_srgb(format));1200return format;1201}1202}12031204/**1205* Given a depth-stencil format, return the corresponding stencil-only format.1206* For stencil-only formats, return the format unchanged.1207*/1208static inline enum pipe_format1209util_format_stencil_only(enum pipe_format format)1210{1211switch (format) {1212/* mask out the depth component */1213case PIPE_FORMAT_Z24_UNORM_S8_UINT:1214return PIPE_FORMAT_X24S8_UINT;1215case PIPE_FORMAT_S8_UINT_Z24_UNORM:1216return PIPE_FORMAT_S8X24_UINT;1217case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:1218return PIPE_FORMAT_X32_S8X24_UINT;12191220/* stencil only formats */1221case PIPE_FORMAT_X24S8_UINT:1222case PIPE_FORMAT_S8X24_UINT:1223case PIPE_FORMAT_X32_S8X24_UINT:1224case PIPE_FORMAT_S8_UINT:1225return format;12261227default:1228assert(0);1229return PIPE_FORMAT_NONE;1230}1231}12321233/**1234* Converts PIPE_FORMAT_*I* to PIPE_FORMAT_*R*.1235* This is identity for non-intensity formats.1236*/1237static inline enum pipe_format1238util_format_intensity_to_red(enum pipe_format format)1239{1240switch (format) {1241case PIPE_FORMAT_I8_UNORM:1242return PIPE_FORMAT_R8_UNORM;1243case PIPE_FORMAT_I8_SNORM:1244return PIPE_FORMAT_R8_SNORM;1245case PIPE_FORMAT_I16_UNORM:1246return PIPE_FORMAT_R16_UNORM;1247case PIPE_FORMAT_I16_SNORM:1248return PIPE_FORMAT_R16_SNORM;1249case PIPE_FORMAT_I16_FLOAT:1250return PIPE_FORMAT_R16_FLOAT;1251case PIPE_FORMAT_I32_FLOAT:1252return PIPE_FORMAT_R32_FLOAT;1253case PIPE_FORMAT_I8_UINT:1254return PIPE_FORMAT_R8_UINT;1255case PIPE_FORMAT_I8_SINT:1256return PIPE_FORMAT_R8_SINT;1257case PIPE_FORMAT_I16_UINT:1258return PIPE_FORMAT_R16_UINT;1259case PIPE_FORMAT_I16_SINT:1260return PIPE_FORMAT_R16_SINT;1261case PIPE_FORMAT_I32_UINT:1262return PIPE_FORMAT_R32_UINT;1263case PIPE_FORMAT_I32_SINT:1264return PIPE_FORMAT_R32_SINT;1265default:1266assert(!util_format_is_intensity(format));1267return format;1268}1269}12701271/**1272* Converts PIPE_FORMAT_*L* to PIPE_FORMAT_*R*.1273* This is identity for non-luminance formats.1274*/1275static inline enum pipe_format1276util_format_luminance_to_red(enum pipe_format format)1277{1278switch (format) {1279case PIPE_FORMAT_L8_UNORM:1280return PIPE_FORMAT_R8_UNORM;1281case PIPE_FORMAT_L8_SNORM:1282return PIPE_FORMAT_R8_SNORM;1283case PIPE_FORMAT_L16_UNORM:1284return PIPE_FORMAT_R16_UNORM;1285case PIPE_FORMAT_L16_SNORM:1286return PIPE_FORMAT_R16_SNORM;1287case PIPE_FORMAT_L16_FLOAT:1288return PIPE_FORMAT_R16_FLOAT;1289case PIPE_FORMAT_L32_FLOAT:1290return PIPE_FORMAT_R32_FLOAT;1291case PIPE_FORMAT_L8_UINT:1292return PIPE_FORMAT_R8_UINT;1293case PIPE_FORMAT_L8_SINT:1294return PIPE_FORMAT_R8_SINT;1295case PIPE_FORMAT_L16_UINT:1296return PIPE_FORMAT_R16_UINT;1297case PIPE_FORMAT_L16_SINT:1298return PIPE_FORMAT_R16_SINT;1299case PIPE_FORMAT_L32_UINT:1300return PIPE_FORMAT_R32_UINT;1301case PIPE_FORMAT_L32_SINT:1302return PIPE_FORMAT_R32_SINT;13031304case PIPE_FORMAT_LATC1_UNORM:1305return PIPE_FORMAT_RGTC1_UNORM;1306case PIPE_FORMAT_LATC1_SNORM:1307return PIPE_FORMAT_RGTC1_SNORM;13081309case PIPE_FORMAT_L4A4_UNORM:1310return PIPE_FORMAT_R4A4_UNORM;13111312case PIPE_FORMAT_L8A8_UNORM:1313return PIPE_FORMAT_R8A8_UNORM;1314case PIPE_FORMAT_L8A8_SNORM:1315return PIPE_FORMAT_R8A8_SNORM;1316case PIPE_FORMAT_L16A16_UNORM:1317return PIPE_FORMAT_R16A16_UNORM;1318case PIPE_FORMAT_L16A16_SNORM:1319return PIPE_FORMAT_R16A16_SNORM;1320case PIPE_FORMAT_L16A16_FLOAT:1321return PIPE_FORMAT_R16A16_FLOAT;1322case PIPE_FORMAT_L32A32_FLOAT:1323return PIPE_FORMAT_R32A32_FLOAT;1324case PIPE_FORMAT_L8A8_UINT:1325return PIPE_FORMAT_R8A8_UINT;1326case PIPE_FORMAT_L8A8_SINT:1327return PIPE_FORMAT_R8A8_SINT;1328case PIPE_FORMAT_L16A16_UINT:1329return PIPE_FORMAT_R16A16_UINT;1330case PIPE_FORMAT_L16A16_SINT:1331return PIPE_FORMAT_R16A16_SINT;1332case PIPE_FORMAT_L32A32_UINT:1333return PIPE_FORMAT_R32A32_UINT;1334case PIPE_FORMAT_L32A32_SINT:1335return PIPE_FORMAT_R32A32_SINT;13361337/* We don't have compressed red-alpha variants for these. */1338case PIPE_FORMAT_LATC2_UNORM:1339case PIPE_FORMAT_LATC2_SNORM:1340return PIPE_FORMAT_NONE;13411342default:1343assert(!util_format_is_luminance(format) &&1344!util_format_is_luminance_alpha(format));1345return format;1346}1347}13481349static inline unsigned1350util_format_get_num_planes(enum pipe_format format)1351{1352switch (util_format_description(format)->layout) {1353case UTIL_FORMAT_LAYOUT_PLANAR3:1354return 3;1355case UTIL_FORMAT_LAYOUT_PLANAR2:1356return 2;1357default:1358return 1;1359}1360}13611362static inline enum pipe_format1363util_format_get_plane_format(enum pipe_format format, unsigned plane)1364{1365switch (format) {1366case PIPE_FORMAT_YV12:1367case PIPE_FORMAT_YV16:1368case PIPE_FORMAT_IYUV:1369case PIPE_FORMAT_Y8_U8_V8_422_UNORM:1370case PIPE_FORMAT_Y8_U8_V8_444_UNORM:1371return PIPE_FORMAT_R8_UNORM;1372case PIPE_FORMAT_NV12:1373case PIPE_FORMAT_Y8_U8V8_422_UNORM:1374return !plane ? PIPE_FORMAT_R8_UNORM : PIPE_FORMAT_RG88_UNORM;1375case PIPE_FORMAT_NV21:1376return !plane ? PIPE_FORMAT_R8_UNORM : PIPE_FORMAT_GR88_UNORM;1377case PIPE_FORMAT_Y16_U16_V16_420_UNORM:1378case PIPE_FORMAT_Y16_U16_V16_422_UNORM:1379case PIPE_FORMAT_Y16_U16_V16_444_UNORM:1380return PIPE_FORMAT_R16_UNORM;1381case PIPE_FORMAT_P010:1382case PIPE_FORMAT_P012:1383case PIPE_FORMAT_P016:1384case PIPE_FORMAT_Y16_U16V16_422_UNORM:1385return !plane ? PIPE_FORMAT_R16_UNORM : PIPE_FORMAT_R16G16_UNORM;1386default:1387return format;1388}1389}13901391static inline unsigned1392util_format_get_plane_width(enum pipe_format format, unsigned plane,1393unsigned width)1394{1395switch (format) {1396case PIPE_FORMAT_YV12:1397case PIPE_FORMAT_YV16:1398case PIPE_FORMAT_IYUV:1399case PIPE_FORMAT_NV12:1400case PIPE_FORMAT_NV21:1401case PIPE_FORMAT_P010:1402case PIPE_FORMAT_P012:1403case PIPE_FORMAT_P016:1404case PIPE_FORMAT_Y8_U8_V8_422_UNORM:1405case PIPE_FORMAT_Y8_U8V8_422_UNORM:1406case PIPE_FORMAT_Y16_U16_V16_420_UNORM:1407case PIPE_FORMAT_Y16_U16_V16_422_UNORM:1408case PIPE_FORMAT_Y16_U16V16_422_UNORM:1409return !plane ? width : (width + 1) / 2;1410default:1411return width;1412}1413}14141415static inline unsigned1416util_format_get_plane_height(enum pipe_format format, unsigned plane,1417unsigned height)1418{1419switch (format) {1420case PIPE_FORMAT_YV12:1421case PIPE_FORMAT_IYUV:1422case PIPE_FORMAT_NV12:1423case PIPE_FORMAT_NV21:1424case PIPE_FORMAT_P010:1425case PIPE_FORMAT_P012:1426case PIPE_FORMAT_P016:1427case PIPE_FORMAT_Y16_U16_V16_420_UNORM:1428return !plane ? height : (height + 1) / 2;1429case PIPE_FORMAT_YV16:1430default:1431return height;1432}1433}14341435/**1436* Return the number of components stored.1437* Formats with block size != 1x1 will always have 1 component (the block).1438*/1439static inline unsigned1440util_format_get_nr_components(enum pipe_format format)1441{1442const struct util_format_description *desc = util_format_description(format);1443return desc->nr_channels;1444}14451446/**1447* Return the index of the first non-void channel1448* -1 if no non-void channels1449*/1450static inline int1451util_format_get_first_non_void_channel(enum pipe_format format)1452{1453const struct util_format_description *desc = util_format_description(format);1454int i;14551456for (i = 0; i < 4; i++)1457if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID)1458break;14591460if (i == 4)1461return -1;14621463return i;1464}14651466/**1467* Whether this format is any 8-bit UNORM variant. Looser than1468* util_is_rgba8_variant (also includes alpha textures, for instance).1469*/14701471static inline bool1472util_format_is_unorm8(const struct util_format_description *desc)1473{1474int c = util_format_get_first_non_void_channel(desc->format);14751476if (c == -1)1477return false;14781479return desc->is_unorm && desc->is_array && desc->channel[c].size == 8;1480}14811482static inline void1483util_format_unpack_z_float(enum pipe_format format, float *dst,1484const void *src, unsigned w)1485{1486const struct util_format_unpack_description *desc =1487util_format_unpack_description(format);14881489desc->unpack_z_float(dst, 0, (const uint8_t *)src, 0, w, 1);1490}14911492static inline void1493util_format_unpack_z_32unorm(enum pipe_format format, uint32_t *dst,1494const void *src, unsigned w)1495{1496const struct util_format_unpack_description *desc =1497util_format_unpack_description(format);14981499desc->unpack_z_32unorm(dst, 0, (const uint8_t *)src, 0, w, 1);1500}15011502static inline void1503util_format_unpack_s_8uint(enum pipe_format format, uint8_t *dst,1504const void *src, unsigned w)1505{1506const struct util_format_unpack_description *desc =1507util_format_unpack_description(format);15081509desc->unpack_s_8uint(dst, 0, (const uint8_t *)src, 0, w, 1);1510}15111512/**1513* Unpacks a row of color data to 32-bit RGBA, either integers for pure1514* integer formats (sign-extended for signed data), or 32-bit floats.1515*/1516static inline void1517util_format_unpack_rgba(enum pipe_format format, void *dst,1518const void *src, unsigned w)1519{1520const struct util_format_unpack_description *desc =1521util_format_unpack_description(format);15221523desc->unpack_rgba(dst, (const uint8_t *)src, w);1524}15251526static inline void1527util_format_pack_z_float(enum pipe_format format, void *dst,1528const float *src, unsigned w)1529{1530const struct util_format_pack_description *desc =1531util_format_pack_description(format);15321533desc->pack_z_float((uint8_t *)dst, 0, src, 0, w, 1);1534}15351536static inline void1537util_format_pack_z_32unorm(enum pipe_format format, void *dst,1538const uint32_t *src, unsigned w)1539{1540const struct util_format_pack_description *desc =1541util_format_pack_description(format);15421543desc->pack_z_32unorm((uint8_t *)dst, 0, src, 0, w, 1);1544}15451546static inline void1547util_format_pack_s_8uint(enum pipe_format format, void *dst,1548const uint8_t *src, unsigned w)1549{1550const struct util_format_pack_description *desc =1551util_format_pack_description(format);15521553desc->pack_s_8uint((uint8_t *)dst, 0, src, 0, w, 1);1554}15551556/**1557* Packs a row of color data from 32-bit RGBA, either integers for pure1558* integer formats, or 32-bit floats. Values are clamped to the packed1559* representation's range.1560*/1561static inline void1562util_format_pack_rgba(enum pipe_format format, void *dst,1563const void *src, unsigned w)1564{1565const struct util_format_pack_description *desc =1566util_format_pack_description(format);15671568if (util_format_is_pure_uint(format))1569desc->pack_rgba_uint((uint8_t *)dst, 0, (const uint32_t *)src, 0, w, 1);1570else if (util_format_is_pure_sint(format))1571desc->pack_rgba_sint((uint8_t *)dst, 0, (const int32_t *)src, 0, w, 1);1572else1573desc->pack_rgba_float((uint8_t *)dst, 0, (const float *)src, 0, w, 1);1574}15751576/*1577* Format access functions for subrectangles1578*/15791580void1581util_format_read_4(enum pipe_format format,1582void *dst, unsigned dst_stride,1583const void *src, unsigned src_stride,1584unsigned x, unsigned y, unsigned w, unsigned h);15851586void1587util_format_write_4(enum pipe_format format,1588const void *src, unsigned src_stride,1589void *dst, unsigned dst_stride,1590unsigned x, unsigned y, unsigned w, unsigned h);15911592void1593util_format_read_4ub(enum pipe_format format,1594uint8_t *dst, unsigned dst_stride,1595const void *src, unsigned src_stride,1596unsigned x, unsigned y, unsigned w, unsigned h);15971598void1599util_format_write_4ub(enum pipe_format format,1600const uint8_t *src, unsigned src_stride,1601void *dst, unsigned dst_stride,1602unsigned x, unsigned y, unsigned w, unsigned h);16031604void1605util_format_unpack_rgba_rect(enum pipe_format format,1606void *dst, unsigned dst_stride,1607const void *src, unsigned src_stride,1608unsigned w, unsigned h);16091610void1611util_format_unpack_rgba_8unorm_rect(enum pipe_format format,1612void *dst, unsigned dst_stride,1613const void *src, unsigned src_stride,1614unsigned w, unsigned h);16151616/*1617* Generic format conversion;1618*/16191620boolean1621util_format_fits_8unorm(const struct util_format_description *format_desc) ATTRIBUTE_CONST;16221623boolean1624util_format_translate(enum pipe_format dst_format,1625void *dst, unsigned dst_stride,1626unsigned dst_x, unsigned dst_y,1627enum pipe_format src_format,1628const void *src, unsigned src_stride,1629unsigned src_x, unsigned src_y,1630unsigned width, unsigned height);16311632boolean1633util_format_translate_3d(enum pipe_format dst_format,1634void *dst, unsigned dst_stride,1635unsigned dst_slice_stride,1636unsigned dst_x, unsigned dst_y,1637unsigned dst_z,1638enum pipe_format src_format,1639const void *src, unsigned src_stride,1640unsigned src_slice_stride,1641unsigned src_x, unsigned src_y,1642unsigned src_z, unsigned width,1643unsigned height, unsigned depth);16441645/*1646* Swizzle operations.1647*/16481649/* Compose two sets of swizzles.1650* If V is a 4D vector and the function parameters represent functions that1651* swizzle vector components, this holds:1652* swz2(swz1(V)) = dst(V)1653*/1654void util_format_compose_swizzles(const unsigned char swz1[4],1655const unsigned char swz2[4],1656unsigned char dst[4]);16571658/* Apply the swizzle provided in \param swz (which is one of PIPE_SWIZZLE_x)1659* to \param src and store the result in \param dst.1660* \param is_integer determines the value written for PIPE_SWIZZLE_1.1661*/1662void util_format_apply_color_swizzle(union pipe_color_union *dst,1663const union pipe_color_union *src,1664const unsigned char swz[4],1665const boolean is_integer);16661667void pipe_swizzle_4f(float *dst, const float *src,1668const unsigned char swz[4]);16691670void util_format_unswizzle_4f(float *dst, const float *src,1671const unsigned char swz[4]);16721673enum pipe_format1674util_format_snorm8_to_sint8(enum pipe_format format) ATTRIBUTE_CONST;167516761677extern void1678util_copy_rect(ubyte * dst, enum pipe_format format,1679unsigned dst_stride, unsigned dst_x, unsigned dst_y,1680unsigned width, unsigned height, const ubyte * src,1681int src_stride, unsigned src_x, unsigned src_y);16821683/**1684* If the format is RGB, return BGR. If the format is BGR, return RGB.1685* This may fail by returning PIPE_FORMAT_NONE.1686*/1687enum pipe_format1688util_format_rgb_to_bgr(enum pipe_format format);16891690#ifdef __cplusplus1691} // extern "C" {1692#endif16931694#endif /* ! U_FORMAT_H */169516961697