X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Futil%2Fu_format.h;h=d0557785f93b9263a370836695f14221a16f565f;hb=1fec0498503ca8f4ebb96dc2cb712893eaaa281b;hp=bb3ed72e93256500ccac6fa98a3e62f7e6fb9e16;hpb=fa31b1095eeea97695125ad5770239805bed37da;p=mesa.git diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h index bb3ed72e932..d0557785f93 100644 --- a/src/gallium/auxiliary/util/u_format.h +++ b/src/gallium/auxiliary/util/u_format.h @@ -31,8 +31,12 @@ #include "pipe/p_format.h" +#include "pipe/p_defines.h" #include "util/u_debug.h" +union pipe_color_union; + + #ifdef __cplusplus extern "C" { #endif @@ -54,7 +58,7 @@ enum util_format_layout { /** * Formats with sub-sampled channels. * - * This is for formats like YV12 where there is less than one sample per + * This is for formats like YVYU where there is less than one sample per * pixel. */ UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3, @@ -69,10 +73,25 @@ enum util_format_layout { */ UTIL_FORMAT_LAYOUT_RGTC = 5, + /** + * Ericsson Texture Compression + */ + UTIL_FORMAT_LAYOUT_ETC = 6, + + /** + * BC6/7 Texture Compression + */ + UTIL_FORMAT_LAYOUT_BPTC = 7, + + /** + * ASTC + */ + UTIL_FORMAT_LAYOUT_ASTC = 8, + /** * Everything else that doesn't fit in any of the above layouts. */ - UTIL_FORMAT_LAYOUT_OTHER = 6 + UTIL_FORMAT_LAYOUT_OTHER = 9 }; @@ -98,17 +117,6 @@ enum util_format_type { }; -enum util_format_swizzle { - UTIL_FORMAT_SWIZZLE_X = 0, - UTIL_FORMAT_SWIZZLE_Y = 1, - UTIL_FORMAT_SWIZZLE_Z = 2, - UTIL_FORMAT_SWIZZLE_W = 3, - UTIL_FORMAT_SWIZZLE_0 = 4, - UTIL_FORMAT_SWIZZLE_1 = 5, - UTIL_FORMAT_SWIZZLE_NONE = 6 -}; - - enum util_format_colorspace { UTIL_FORMAT_COLORSPACE_RGB = 0, UTIL_FORMAT_COLORSPACE_SRGB = 1, @@ -119,9 +127,11 @@ enum util_format_colorspace { struct util_format_channel_description { - unsigned type:6; + unsigned type:5; /**< UTIL_FORMAT_TYPE_x */ unsigned normalized:1; - unsigned size:9; + unsigned pure_integer:1; + unsigned size:9; /**< bits per channel */ + unsigned shift:16; /** number of bits from lsb */ }; @@ -149,7 +159,7 @@ struct util_format_description unsigned nr_channels:3; /** - * Whether all channels have the same number of (whole) bytes. + * Whether all channels have the same number of (whole) bytes and type. */ unsigned is_array:1; @@ -168,9 +178,31 @@ struct util_format_description unsigned is_mixed:1; /** - * Input channel description. + * Input channel description, in the order XYZW. * * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats. + * + * If each channel is accessed as an individual N-byte value, X is always + * at the lowest address in memory, Y is always next, and so on. For all + * currently-defined formats, the N-byte value has native endianness. + * + * If instead a group of channels is accessed as a single N-byte value, + * the order of the channels within that value depends on endianness. + * For big-endian targets, X is the most significant subvalue, + * otherwise it is the least significant one. + * + * For example, if X is 8 bits and Y is 24 bits, the memory order is: + * + * 0 1 2 3 + * little-endian: X Yl Ym Yu (l = lower, m = middle, u = upper) + * big-endian: X Yu Ym Yl + * + * If X is 5 bits, Y is 5 bits, Z is 5 bits and W is 1 bit, the layout is: + * + * 0 1 + * msb lsb msb lsb + * little-endian: YYYXXXXX WZZZZZYY + * big-endian: XXXXXYYY YYZZZZZW */ struct util_format_channel_description channel[4]; @@ -247,7 +279,7 @@ struct util_format_description /** * Fetch a single pixel (i, j) from a block. * - * Only defined for non-depth-stencil formats. + * Only defined for non-depth-stencil and non-integer formats. */ void (*fetch_rgba_float)(float *dst, @@ -299,27 +331,78 @@ struct util_format_description unsigned width, unsigned height); /** - * Unpack pixels to S8_USCALED. + * Unpack pixels to S8_UINT. * Note: strides are in bytes. * * Only defined for stencil formats. */ void - (*unpack_s_8uscaled)(uint8_t *dst, unsigned dst_stride, - const uint8_t *src, unsigned src_stride, - unsigned width, unsigned height); + (*unpack_s_8uint)(uint8_t *dst, unsigned dst_stride, + const uint8_t *src, unsigned src_stride, + unsigned width, unsigned height); /** - * Pack pixels from S8_USCALED. + * Pack pixels from S8_UINT. * Note: strides are in bytes. * * Only defined for stencil formats. */ void - (*pack_s_8uscaled)(uint8_t *dst, unsigned dst_stride, - const uint8_t *src, unsigned src_stride, - unsigned width, unsigned height); + (*pack_s_8uint)(uint8_t *dst, unsigned dst_stride, + const uint8_t *src, unsigned src_stride, + unsigned width, unsigned height); + + /** + * Unpack pixel blocks to R32G32B32A32_UINT. + * Note: strides are in bytes. + * + * Only defined for INT formats. + */ + void + (*unpack_rgba_uint)(uint32_t *dst, unsigned dst_stride, + const uint8_t *src, unsigned src_stride, + unsigned width, unsigned height); + + void + (*pack_rgba_uint)(uint8_t *dst, unsigned dst_stride, + const uint32_t *src, unsigned src_stride, + unsigned width, unsigned height); + + /** + * Unpack pixel blocks to R32G32B32A32_SINT. + * Note: strides are in bytes. + * + * Only defined for INT formats. + */ + void + (*unpack_rgba_sint)(int32_t *dst, unsigned dst_stride, + const uint8_t *src, unsigned src_stride, + unsigned width, unsigned height); + + void + (*pack_rgba_sint)(uint8_t *dst, unsigned dst_stride, + const int32_t *src, unsigned src_stride, + unsigned width, unsigned height); + + /** + * Fetch a single pixel (i, j) from a block. + * + * Only defined for unsigned (pure) integer formats. + */ + void + (*fetch_rgba_uint)(uint32_t *dst, + const uint8_t *src, + unsigned i, unsigned j); + /** + * Fetch a single pixel (i, j) from a block. + * + * Only defined for signed (pure) integer formats. + */ + void + (*fetch_rgba_sint)(int32_t *dst, + const uint8_t *src, + unsigned i, unsigned j); }; @@ -335,7 +418,7 @@ util_format_description(enum pipe_format format); * Format query functions. */ -static INLINE const char * +static inline const char * util_format_name(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); @@ -348,7 +431,7 @@ util_format_name(enum pipe_format format) return desc->name; } -static INLINE const char * +static inline const char * util_format_short_name(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); @@ -364,7 +447,7 @@ util_format_short_name(enum pipe_format format) /** * Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info. */ -static INLINE boolean +static inline boolean util_format_is_plain(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); @@ -376,7 +459,7 @@ util_format_is_plain(enum pipe_format format) return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE; } -static INLINE boolean +static inline boolean util_format_is_compressed(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); @@ -389,6 +472,9 @@ util_format_is_compressed(enum pipe_format format) switch (desc->layout) { case UTIL_FORMAT_LAYOUT_S3TC: case UTIL_FORMAT_LAYOUT_RGTC: + case UTIL_FORMAT_LAYOUT_ETC: + case UTIL_FORMAT_LAYOUT_BPTC: + case UTIL_FORMAT_LAYOUT_ASTC: /* XXX add other formats in the future */ return TRUE; default: @@ -396,7 +482,7 @@ util_format_is_compressed(enum pipe_format format) } } -static INLINE boolean +static inline boolean util_format_is_s3tc(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); @@ -409,7 +495,28 @@ util_format_is_s3tc(enum pipe_format format) return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE; } -static INLINE boolean +static inline boolean +util_format_is_srgb(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + return desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB; +} + +static inline boolean +util_format_has_depth(const struct util_format_description *desc) +{ + return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS && + desc->swizzle[0] != PIPE_SWIZZLE_NONE; +} + +static inline boolean +util_format_has_stencil(const struct util_format_description *desc) +{ + return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS && + desc->swizzle[1] != PIPE_SWIZZLE_NONE; +} + +static inline boolean util_format_is_depth_or_stencil(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); @@ -419,10 +526,11 @@ util_format_is_depth_or_stencil(enum pipe_format format) return FALSE; } - return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS ? TRUE : FALSE; + return util_format_has_depth(desc) || + util_format_has_stencil(desc); } -static INLINE boolean +static inline boolean util_format_is_depth_and_stencil(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); @@ -432,22 +540,72 @@ util_format_is_depth_and_stencil(enum pipe_format format) return FALSE; } - if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) { - return FALSE; - } + return util_format_has_depth(desc) && + util_format_has_stencil(desc); +} - return (desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE && - desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE) ? TRUE : FALSE; + +/** + * Calculates the depth format type based upon the incoming format description. + */ +static inline unsigned +util_get_depth_format_type(const struct util_format_description *desc) +{ + unsigned depth_channel = desc->swizzle[0]; + if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS && + depth_channel != PIPE_SWIZZLE_NONE) { + return desc->channel[depth_channel].type; + } else { + return UTIL_FORMAT_TYPE_VOID; + } } +/** + * Calculates the MRD for the depth format. MRD is used in depth bias + * for UNORM and unbound depth buffers. When the depth buffer is floating + * point, the depth bias calculation does not use the MRD. However, the + * default MRD will be 1.0 / ((1 << 24) - 1). + */ +double +util_get_depth_format_mrd(const struct util_format_description *desc); + + +/** + * Return whether this is an RGBA, Z, S, or combined ZS format. + * Useful for initializing pipe_blit_info::mask. + */ +static inline unsigned +util_format_get_mask(enum pipe_format format) +{ + const struct util_format_description *desc = + util_format_description(format); + + if (!desc) + return 0; + + if (util_format_has_depth(desc)) { + if (util_format_has_stencil(desc)) { + return PIPE_MASK_ZS; + } else { + return PIPE_MASK_Z; + } + } else { + if (util_format_has_stencil(desc)) { + return PIPE_MASK_S; + } else { + return PIPE_MASK_RGBA; + } + } +} + /** * Give the RGBA colormask of the channels that can be represented in this * format. * * That is, the channels whose values are preserved. */ -static INLINE unsigned +static inline unsigned util_format_colormask(const struct util_format_description *desc) { unsigned colormask; @@ -473,13 +631,62 @@ util_format_colormask(const struct util_format_description *desc) } +/** + * Checks if color mask covers every channel for the specified format + * + * @param desc a format description to check colormask with + * @param colormask a bit mask for channels, matches format of PIPE_MASK_RGBA + */ +static inline boolean +util_format_colormask_full(const struct util_format_description *desc, unsigned colormask) +{ + return (~colormask & util_format_colormask(desc)) == 0; +} + + boolean util_format_is_float(enum pipe_format format); +boolean +util_format_has_alpha(enum pipe_format format); + + +boolean +util_format_is_luminance(enum pipe_format format); + +boolean +util_format_is_alpha(enum pipe_format format); + +boolean +util_format_is_luminance_alpha(enum pipe_format format); + + +boolean +util_format_is_intensity(enum pipe_format format); + +boolean +util_format_is_subsampled_422(enum pipe_format format); + +boolean +util_format_is_pure_integer(enum pipe_format format); + +boolean +util_format_is_pure_sint(enum pipe_format format); + +boolean +util_format_is_pure_uint(enum pipe_format format); + +boolean +util_format_is_snorm(enum pipe_format format); + +boolean +util_format_is_snorm8(enum pipe_format format); + /** - * Whether the src format can be blitted to destation format with a simple - * memcpy. + * Check if the src format can be blitted to the destination format with + * a simple memcpy. For example, blitting from RGBA to RGBx is OK, but not + * the reverse. */ boolean util_is_format_compatible(const struct util_format_description *src_desc, @@ -499,7 +706,7 @@ util_format_is_supported(enum pipe_format format, unsigned bind); * * PIPE_FORMAT_?8?8?8?8_UNORM */ -static INLINE boolean +static inline boolean util_format_is_rgba8_variant(const struct util_format_description *desc) { unsigned chan; @@ -513,6 +720,9 @@ util_format_is_rgba8_variant(const struct util_format_description *desc) if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED && desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID) return FALSE; + if(desc->channel[chan].type == UTIL_FORMAT_TYPE_UNSIGNED && + !desc->channel[chan].normalized) + return FALSE; if(desc->channel[chan].size != 8) return FALSE; } @@ -524,7 +734,7 @@ util_format_is_rgba8_variant(const struct util_format_description *desc) /** * Return total bits needed for the pixel format per block. */ -static INLINE uint +static inline uint util_format_get_blocksizebits(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); @@ -540,17 +750,22 @@ util_format_get_blocksizebits(enum pipe_format format) /** * Return bytes per block (not pixel) for the given format. */ -static INLINE uint +static inline uint util_format_get_blocksize(enum pipe_format format) { uint bits = util_format_get_blocksizebits(format); + uint bytes = bits / 8; assert(bits % 8 == 0); + assert(bytes > 0); + if (bytes == 0) { + bytes = 1; + } - return bits / 8; + return bytes; } -static INLINE uint +static inline uint util_format_get_blockwidth(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); @@ -563,7 +778,7 @@ util_format_get_blockwidth(enum pipe_format format) return desc->block.width; } -static INLINE uint +static inline uint util_format_get_blockheight(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); @@ -576,7 +791,7 @@ util_format_get_blockheight(enum pipe_format format) return desc->block.height; } -static INLINE unsigned +static inline unsigned util_format_get_nblocksx(enum pipe_format format, unsigned x) { @@ -584,7 +799,7 @@ util_format_get_nblocksx(enum pipe_format format, return (x + blockwidth - 1) / blockwidth; } -static INLINE unsigned +static inline unsigned util_format_get_nblocksy(enum pipe_format format, unsigned y) { @@ -592,7 +807,7 @@ util_format_get_nblocksy(enum pipe_format format, return (y + blockheight - 1) / blockheight; } -static INLINE unsigned +static inline unsigned util_format_get_nblocks(enum pipe_format format, unsigned width, unsigned height) @@ -600,14 +815,14 @@ util_format_get_nblocks(enum pipe_format format, return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height); } -static INLINE size_t +static inline size_t util_format_get_stride(enum pipe_format format, unsigned width) { return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format); } -static INLINE size_t +static inline size_t util_format_get_2d_size(enum pipe_format format, size_t stride, unsigned height) @@ -615,7 +830,7 @@ util_format_get_2d_size(enum pipe_format format, return util_format_get_nblocksy(format, height) * stride; } -static INLINE uint +static inline uint util_format_get_component_bits(enum pipe_format format, enum util_format_colorspace colorspace, uint component) @@ -645,50 +860,29 @@ util_format_get_component_bits(enum pipe_format format, } switch (desc->swizzle[component]) { - case UTIL_FORMAT_SWIZZLE_X: + case PIPE_SWIZZLE_X: return desc->channel[0].size; - case UTIL_FORMAT_SWIZZLE_Y: + case PIPE_SWIZZLE_Y: return desc->channel[1].size; - case UTIL_FORMAT_SWIZZLE_Z: + case PIPE_SWIZZLE_Z: return desc->channel[2].size; - case UTIL_FORMAT_SWIZZLE_W: + case PIPE_SWIZZLE_W: return desc->channel[3].size; default: return 0; } } -static INLINE boolean -util_format_has_alpha(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - - assert(format); - if (!format) { - return FALSE; - } - - switch (desc->colorspace) { - case UTIL_FORMAT_COLORSPACE_RGB: - case UTIL_FORMAT_COLORSPACE_SRGB: - return desc->swizzle[3] != UTIL_FORMAT_SWIZZLE_1; - case UTIL_FORMAT_COLORSPACE_YUV: - return FALSE; - case UTIL_FORMAT_COLORSPACE_ZS: - return FALSE; - default: - assert(0); - return FALSE; - } -} - /** * Given a linear RGB colorspace format, return the corresponding SRGB * format, or PIPE_FORMAT_NONE if none. */ -static INLINE enum pipe_format +static inline enum pipe_format util_format_srgb(enum pipe_format format) { + if (util_format_is_srgb(format)) + return format; + switch (format) { case PIPE_FORMAT_L8_UNORM: return PIPE_FORMAT_L8_SRGB; @@ -708,6 +902,10 @@ util_format_srgb(enum pipe_format format) return PIPE_FORMAT_A8R8G8B8_SRGB; case PIPE_FORMAT_X8R8G8B8_UNORM: return PIPE_FORMAT_X8R8G8B8_SRGB; + case PIPE_FORMAT_R8G8B8A8_UNORM: + return PIPE_FORMAT_R8G8B8A8_SRGB; + case PIPE_FORMAT_R8G8B8X8_UNORM: + return PIPE_FORMAT_R8G8B8X8_SRGB; case PIPE_FORMAT_DXT1_RGB: return PIPE_FORMAT_DXT1_SRGB; case PIPE_FORMAT_DXT1_RGBA: @@ -716,6 +914,39 @@ util_format_srgb(enum pipe_format format) return PIPE_FORMAT_DXT3_SRGBA; case PIPE_FORMAT_DXT5_RGBA: return PIPE_FORMAT_DXT5_SRGBA; + case PIPE_FORMAT_B5G6R5_UNORM: + return PIPE_FORMAT_B5G6R5_SRGB; + case PIPE_FORMAT_BPTC_RGBA_UNORM: + return PIPE_FORMAT_BPTC_SRGBA; + case PIPE_FORMAT_ASTC_4x4: + return PIPE_FORMAT_ASTC_4x4_SRGB; + case PIPE_FORMAT_ASTC_5x4: + return PIPE_FORMAT_ASTC_5x4_SRGB; + case PIPE_FORMAT_ASTC_5x5: + return PIPE_FORMAT_ASTC_5x5_SRGB; + case PIPE_FORMAT_ASTC_6x5: + return PIPE_FORMAT_ASTC_6x5_SRGB; + case PIPE_FORMAT_ASTC_6x6: + return PIPE_FORMAT_ASTC_6x6_SRGB; + case PIPE_FORMAT_ASTC_8x5: + return PIPE_FORMAT_ASTC_8x5_SRGB; + case PIPE_FORMAT_ASTC_8x6: + return PIPE_FORMAT_ASTC_8x6_SRGB; + case PIPE_FORMAT_ASTC_8x8: + return PIPE_FORMAT_ASTC_8x8_SRGB; + case PIPE_FORMAT_ASTC_10x5: + return PIPE_FORMAT_ASTC_10x5_SRGB; + case PIPE_FORMAT_ASTC_10x6: + return PIPE_FORMAT_ASTC_10x6_SRGB; + case PIPE_FORMAT_ASTC_10x8: + return PIPE_FORMAT_ASTC_10x8_SRGB; + case PIPE_FORMAT_ASTC_10x10: + return PIPE_FORMAT_ASTC_10x10_SRGB; + case PIPE_FORMAT_ASTC_12x10: + return PIPE_FORMAT_ASTC_12x10_SRGB; + case PIPE_FORMAT_ASTC_12x12: + return PIPE_FORMAT_ASTC_12x12_SRGB; + default: return PIPE_FORMAT_NONE; } @@ -725,7 +956,7 @@ util_format_srgb(enum pipe_format format) * Given an sRGB format, return the corresponding linear colorspace format. * For non sRGB formats, return the format unchanged. */ -static INLINE enum pipe_format +static inline enum pipe_format util_format_linear(enum pipe_format format) { switch (format) { @@ -747,6 +978,10 @@ util_format_linear(enum pipe_format format) return PIPE_FORMAT_A8R8G8B8_UNORM; case PIPE_FORMAT_X8R8G8B8_SRGB: return PIPE_FORMAT_X8R8G8B8_UNORM; + case PIPE_FORMAT_R8G8B8A8_SRGB: + return PIPE_FORMAT_R8G8B8A8_UNORM; + case PIPE_FORMAT_R8G8B8X8_SRGB: + return PIPE_FORMAT_R8G8B8X8_UNORM; case PIPE_FORMAT_DXT1_SRGB: return PIPE_FORMAT_DXT1_RGB; case PIPE_FORMAT_DXT1_SRGBA: @@ -755,7 +990,184 @@ util_format_linear(enum pipe_format format) return PIPE_FORMAT_DXT3_RGBA; case PIPE_FORMAT_DXT5_SRGBA: return PIPE_FORMAT_DXT5_RGBA; + case PIPE_FORMAT_B5G6R5_SRGB: + return PIPE_FORMAT_B5G6R5_UNORM; + case PIPE_FORMAT_BPTC_SRGBA: + return PIPE_FORMAT_BPTC_RGBA_UNORM; + case PIPE_FORMAT_ASTC_4x4_SRGB: + return PIPE_FORMAT_ASTC_4x4; + case PIPE_FORMAT_ASTC_5x4_SRGB: + return PIPE_FORMAT_ASTC_5x4; + case PIPE_FORMAT_ASTC_5x5_SRGB: + return PIPE_FORMAT_ASTC_5x5; + case PIPE_FORMAT_ASTC_6x5_SRGB: + return PIPE_FORMAT_ASTC_6x5; + case PIPE_FORMAT_ASTC_6x6_SRGB: + return PIPE_FORMAT_ASTC_6x6; + case PIPE_FORMAT_ASTC_8x5_SRGB: + return PIPE_FORMAT_ASTC_8x5; + case PIPE_FORMAT_ASTC_8x6_SRGB: + return PIPE_FORMAT_ASTC_8x6; + case PIPE_FORMAT_ASTC_8x8_SRGB: + return PIPE_FORMAT_ASTC_8x8; + case PIPE_FORMAT_ASTC_10x5_SRGB: + return PIPE_FORMAT_ASTC_10x5; + case PIPE_FORMAT_ASTC_10x6_SRGB: + return PIPE_FORMAT_ASTC_10x6; + case PIPE_FORMAT_ASTC_10x8_SRGB: + return PIPE_FORMAT_ASTC_10x8; + case PIPE_FORMAT_ASTC_10x10_SRGB: + return PIPE_FORMAT_ASTC_10x10; + case PIPE_FORMAT_ASTC_12x10_SRGB: + return PIPE_FORMAT_ASTC_12x10; + case PIPE_FORMAT_ASTC_12x12_SRGB: + return PIPE_FORMAT_ASTC_12x12; + default: + return format; + } +} + +/** + * Given a depth-stencil format, return the corresponding stencil-only format. + * For stencil-only formats, return the format unchanged. + */ +static inline enum pipe_format +util_format_stencil_only(enum pipe_format format) +{ + switch (format) { + /* mask out the depth component */ + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + return PIPE_FORMAT_X24S8_UINT; + case PIPE_FORMAT_S8_UINT_Z24_UNORM: + return PIPE_FORMAT_S8X24_UINT; + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + return PIPE_FORMAT_X32_S8X24_UINT; + + /* stencil only formats */ + case PIPE_FORMAT_X24S8_UINT: + case PIPE_FORMAT_S8X24_UINT: + case PIPE_FORMAT_X32_S8X24_UINT: + case PIPE_FORMAT_S8_UINT: + return format; + + default: + assert(0); + return PIPE_FORMAT_NONE; + } +} + +/** + * Converts PIPE_FORMAT_*I* to PIPE_FORMAT_*R*. + * This is identity for non-intensity formats. + */ +static inline enum pipe_format +util_format_intensity_to_red(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_I8_UNORM: + return PIPE_FORMAT_R8_UNORM; + case PIPE_FORMAT_I8_SNORM: + return PIPE_FORMAT_R8_SNORM; + case PIPE_FORMAT_I16_UNORM: + return PIPE_FORMAT_R16_UNORM; + case PIPE_FORMAT_I16_SNORM: + return PIPE_FORMAT_R16_SNORM; + case PIPE_FORMAT_I16_FLOAT: + return PIPE_FORMAT_R16_FLOAT; + case PIPE_FORMAT_I32_FLOAT: + return PIPE_FORMAT_R32_FLOAT; + case PIPE_FORMAT_I8_UINT: + return PIPE_FORMAT_R8_UINT; + case PIPE_FORMAT_I8_SINT: + return PIPE_FORMAT_R8_SINT; + case PIPE_FORMAT_I16_UINT: + return PIPE_FORMAT_R16_UINT; + case PIPE_FORMAT_I16_SINT: + return PIPE_FORMAT_R16_SINT; + case PIPE_FORMAT_I32_UINT: + return PIPE_FORMAT_R32_UINT; + case PIPE_FORMAT_I32_SINT: + return PIPE_FORMAT_R32_SINT; + default: + assert(!util_format_is_intensity(format)); + return format; + } +} + +/** + * Converts PIPE_FORMAT_*L* to PIPE_FORMAT_*R*. + * This is identity for non-luminance formats. + */ +static inline enum pipe_format +util_format_luminance_to_red(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_L8_UNORM: + return PIPE_FORMAT_R8_UNORM; + case PIPE_FORMAT_L8_SNORM: + return PIPE_FORMAT_R8_SNORM; + case PIPE_FORMAT_L16_UNORM: + return PIPE_FORMAT_R16_UNORM; + case PIPE_FORMAT_L16_SNORM: + return PIPE_FORMAT_R16_SNORM; + case PIPE_FORMAT_L16_FLOAT: + return PIPE_FORMAT_R16_FLOAT; + case PIPE_FORMAT_L32_FLOAT: + return PIPE_FORMAT_R32_FLOAT; + case PIPE_FORMAT_L8_UINT: + return PIPE_FORMAT_R8_UINT; + case PIPE_FORMAT_L8_SINT: + return PIPE_FORMAT_R8_SINT; + case PIPE_FORMAT_L16_UINT: + return PIPE_FORMAT_R16_UINT; + case PIPE_FORMAT_L16_SINT: + return PIPE_FORMAT_R16_SINT; + case PIPE_FORMAT_L32_UINT: + return PIPE_FORMAT_R32_UINT; + case PIPE_FORMAT_L32_SINT: + return PIPE_FORMAT_R32_SINT; + + case PIPE_FORMAT_LATC1_UNORM: + return PIPE_FORMAT_RGTC1_UNORM; + case PIPE_FORMAT_LATC1_SNORM: + return PIPE_FORMAT_RGTC1_SNORM; + + case PIPE_FORMAT_L4A4_UNORM: + return PIPE_FORMAT_R4A4_UNORM; + + case PIPE_FORMAT_L8A8_UNORM: + return PIPE_FORMAT_R8A8_UNORM; + case PIPE_FORMAT_L8A8_SNORM: + return PIPE_FORMAT_R8A8_SNORM; + case PIPE_FORMAT_L16A16_UNORM: + return PIPE_FORMAT_R16A16_UNORM; + case PIPE_FORMAT_L16A16_SNORM: + return PIPE_FORMAT_R16A16_SNORM; + case PIPE_FORMAT_L16A16_FLOAT: + return PIPE_FORMAT_R16A16_FLOAT; + case PIPE_FORMAT_L32A32_FLOAT: + return PIPE_FORMAT_R32A32_FLOAT; + case PIPE_FORMAT_L8A8_UINT: + return PIPE_FORMAT_R8A8_UINT; + case PIPE_FORMAT_L8A8_SINT: + return PIPE_FORMAT_R8A8_SINT; + case PIPE_FORMAT_L16A16_UINT: + return PIPE_FORMAT_R16A16_UINT; + case PIPE_FORMAT_L16A16_SINT: + return PIPE_FORMAT_R16A16_SINT; + case PIPE_FORMAT_L32A32_UINT: + return PIPE_FORMAT_R32A32_UINT; + case PIPE_FORMAT_L32A32_SINT: + return PIPE_FORMAT_R32A32_SINT; + + /* We don't have compressed red-alpha variants for these. */ + case PIPE_FORMAT_LATC2_UNORM: + case PIPE_FORMAT_LATC2_SNORM: + return PIPE_FORMAT_NONE; + default: + assert(!util_format_is_luminance(format) && + !util_format_is_luminance_alpha(format)); return format; } } @@ -764,13 +1176,33 @@ util_format_linear(enum pipe_format format) * Return the number of components stored. * Formats with block size != 1x1 will always have 1 component (the block). */ -static INLINE unsigned +static inline unsigned util_format_get_nr_components(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); return desc->nr_channels; } +/** + * Return the index of the first non-void channel + * -1 if no non-void channels + */ +static inline int +util_format_get_first_non_void_channel(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + int i; + + for (i = 0; i < 4; i++) + if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) + break; + + if (i == 4) + return -1; + + return i; +} + /* * Format access functions. */ @@ -799,6 +1231,30 @@ util_format_write_4ub(enum pipe_format format, void *dst, unsigned dst_stride, unsigned x, unsigned y, unsigned w, unsigned h); +void +util_format_read_4ui(enum pipe_format format, + unsigned *dst, unsigned dst_stride, + const void *src, unsigned src_stride, + unsigned x, unsigned y, unsigned w, unsigned h); + +void +util_format_write_4ui(enum pipe_format format, + const unsigned int *src, unsigned src_stride, + void *dst, unsigned dst_stride, + unsigned x, unsigned y, unsigned w, unsigned h); + +void +util_format_read_4i(enum pipe_format format, + int *dst, unsigned dst_stride, + const void *src, unsigned src_stride, + unsigned x, unsigned y, unsigned w, unsigned h); + +void +util_format_write_4i(enum pipe_format format, + const int *src, unsigned src_stride, + void *dst, unsigned dst_stride, + unsigned x, unsigned y, unsigned w, unsigned h); + /* * Generic format conversion; */ @@ -806,7 +1262,7 @@ util_format_write_4ub(enum pipe_format format, boolean util_format_fits_8unorm(const struct util_format_description *format_desc); -void +boolean util_format_translate(enum pipe_format dst_format, void *dst, unsigned dst_stride, unsigned dst_x, unsigned dst_y, @@ -815,6 +1271,47 @@ util_format_translate(enum pipe_format dst_format, unsigned src_x, unsigned src_y, unsigned width, unsigned height); +boolean +util_format_translate_3d(enum pipe_format dst_format, + void *dst, unsigned dst_stride, + unsigned dst_slice_stride, + unsigned dst_x, unsigned dst_y, + unsigned dst_z, + enum pipe_format src_format, + const void *src, unsigned src_stride, + unsigned src_slice_stride, + unsigned src_x, unsigned src_y, + unsigned src_z, unsigned width, + unsigned height, unsigned depth); + +/* + * Swizzle operations. + */ + +/* Compose two sets of swizzles. + * If V is a 4D vector and the function parameters represent functions that + * swizzle vector components, this holds: + * swz2(swz1(V)) = dst(V) + */ +void util_format_compose_swizzles(const unsigned char swz1[4], + const unsigned char swz2[4], + unsigned char dst[4]); + +/* Apply the swizzle provided in \param swz (which is one of PIPE_SWIZZLE_x) + * to \param src and store the result in \param dst. + * \param is_integer determines the value written for PIPE_SWIZZLE_1. + */ +void util_format_apply_color_swizzle(union pipe_color_union *dst, + const union pipe_color_union *src, + const unsigned char swz[4], + const boolean is_integer); + +void pipe_swizzle_4f(float *dst, const float *src, + const unsigned char swz[4]); + +void util_format_unswizzle_4f(float *dst, const float *src, + const unsigned char swz[4]); + #ifdef __cplusplus } // extern "C" { #endif