X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Futil%2Fu_format.h;h=fe348aa55c8f6b67a33e063d5842d269a4e44655;hb=9eccae671ef9a49162783090b7d0052272386a74;hp=156d5cf978ad5993121bcd5db94f56d6457f8cf5;hpb=bc2ceb97f1b0f3536b75165c26d9fbd190494fb3;p=mesa.git diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h index 156d5cf978a..fe348aa55c8 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 @@ -74,10 +78,19 @@ enum util_format_layout { */ UTIL_FORMAT_LAYOUT_ETC = 6, + /** + * BC6/7 Texture Compression + */ + UTIL_FORMAT_LAYOUT_BPTC = 7, + + UTIL_FORMAT_LAYOUT_ASTC = 8, + + UTIL_FORMAT_LAYOUT_ATC = 9, + /** * Everything else that doesn't fit in any of the above layouts. */ - UTIL_FORMAT_LAYOUT_OTHER = 7 + UTIL_FORMAT_LAYOUT_OTHER = 10 }; @@ -103,18 +116,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, - UTIL_FORMAT_SWIZZLE_MAX = 7 /**< Number of enums counter (must be last) */ -}; - - enum util_format_colorspace { UTIL_FORMAT_COLORSPACE_RGB = 0, UTIL_FORMAT_COLORSPACE_SRGB = 1, @@ -129,6 +130,7 @@ struct util_format_channel_description unsigned normalized:1; unsigned pure_integer:1; unsigned size:9; /**< bits per channel */ + unsigned shift:16; /** number of bits from lsb */ }; @@ -175,9 +177,41 @@ struct util_format_description unsigned is_mixed:1; /** - * Input channel description. + * Whether the format contains UNORM channels + */ + unsigned is_unorm:1; + + /** + * Whether the format contains SNORM channels + */ + unsigned is_snorm:1; + + /** + * 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]; @@ -334,13 +368,13 @@ struct util_format_description * Only defined for INT formats. */ void - (*unpack_rgba_uint)(unsigned *dst, unsigned dst_stride, + (*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 unsigned *src, unsigned src_stride, + const uint32_t *src, unsigned src_stride, unsigned width, unsigned height); /** @@ -350,13 +384,13 @@ struct util_format_description * Only defined for INT formats. */ void - (*unpack_rgba_sint)(signed *dst, unsigned dst_stride, + (*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 int *src, unsigned src_stride, + const int32_t *src, unsigned src_stride, unsigned width, unsigned height); /** @@ -393,7 +427,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); @@ -406,7 +440,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); @@ -422,7 +456,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); @@ -434,7 +468,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); @@ -447,6 +481,10 @@ 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: + case UTIL_FORMAT_LAYOUT_ATC: /* XXX add other formats in the future */ return TRUE; default: @@ -454,7 +492,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); @@ -467,28 +505,41 @@ 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_etc(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + + assert(desc); + if (!desc) { + return FALSE; + } + + return desc->layout == UTIL_FORMAT_LAYOUT_ETC ? TRUE : FALSE; +} + +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 +static inline boolean util_format_has_depth(const struct util_format_description *desc) { return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS && - desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE; + desc->swizzle[0] != PIPE_SWIZZLE_NONE; } -static INLINE boolean +static inline boolean util_format_has_stencil(const struct util_format_description *desc) { return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS && - desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE; + desc->swizzle[1] != PIPE_SWIZZLE_NONE; } -static INLINE boolean +static inline boolean util_format_is_depth_or_stencil(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); @@ -502,7 +553,7 @@ util_format_is_depth_or_stencil(enum pipe_format format) 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); @@ -516,6 +567,93 @@ util_format_is_depth_and_stencil(enum pipe_format format) util_format_has_stencil(desc); } +/** + * For depth-stencil formats, return the equivalent depth-only format. + */ +static inline boolean +util_format_get_depth_only(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + return PIPE_FORMAT_Z24X8_UNORM; + + case PIPE_FORMAT_S8_UINT_Z24_UNORM: + return PIPE_FORMAT_X8Z24_UNORM; + + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + return PIPE_FORMAT_Z32_FLOAT; + + default: + return format; + } +} + +static inline boolean +util_format_is_yuv(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + + assert(desc); + if (!desc) { + return FALSE; + } + + return desc->colorspace == UTIL_FORMAT_COLORSPACE_YUV; +} + +/** + * 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 @@ -523,7 +661,7 @@ util_format_is_depth_and_stencil(enum pipe_format 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; @@ -555,7 +693,7 @@ util_format_colormask(const struct util_format_description *desc) * @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 +static inline boolean util_format_colormask_full(const struct util_format_description *desc, unsigned colormask) { return (~colormask & util_format_colormask(desc)) == 0; @@ -573,6 +711,8 @@ 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); @@ -581,6 +721,9 @@ 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); @@ -590,6 +733,15 @@ 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_unorm(enum pipe_format format); + +boolean +util_format_is_snorm8(enum pipe_format format); + /** * 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 @@ -599,13 +751,6 @@ boolean util_is_format_compatible(const struct util_format_description *src_desc, const struct util_format_description *dst_desc); -/** - * Whether the format is supported by Gallium for the given bindings. - * This covers S3TC textures and floating-point render targets. - */ -boolean -util_format_is_supported(enum pipe_format format, unsigned bind); - /** * Whether this format is a rgab8 variant. * @@ -613,7 +758,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; @@ -627,6 +772,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; } @@ -634,11 +782,10 @@ util_format_is_rgba8_variant(const struct util_format_description *desc) return TRUE; } - /** * 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); @@ -654,17 +801,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); @@ -677,7 +829,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); @@ -690,7 +842,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) { @@ -698,7 +850,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) { @@ -706,7 +858,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) @@ -714,14 +866,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) @@ -729,7 +881,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) @@ -759,13 +911,13 @@ 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; @@ -776,12 +928,17 @@ util_format_get_component_bits(enum pipe_format format, * 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; + case PIPE_FORMAT_R8_UNORM: + return PIPE_FORMAT_R8_SRGB; case PIPE_FORMAT_L8A8_UNORM: return PIPE_FORMAT_L8A8_SRGB; case PIPE_FORMAT_R8G8B8_UNORM: @@ -798,6 +955,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: @@ -806,6 +967,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; } @@ -815,12 +1009,14 @@ 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) { case PIPE_FORMAT_L8_SRGB: return PIPE_FORMAT_L8_UNORM; + case PIPE_FORMAT_R8_SRGB: + return PIPE_FORMAT_R8_UNORM; case PIPE_FORMAT_L8A8_SRGB: return PIPE_FORMAT_L8A8_UNORM; case PIPE_FORMAT_R8G8B8_SRGB: @@ -837,6 +1033,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: @@ -845,6 +1045,38 @@ 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; } @@ -854,7 +1086,7 @@ util_format_linear(enum pipe_format 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 +static inline enum pipe_format util_format_stencil_only(enum pipe_format format) { switch (format) { @@ -879,11 +1111,127 @@ util_format_stencil_only(enum pipe_format format) } } +/** + * 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; + } +} + /** * 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); @@ -894,7 +1242,7 @@ util_format_get_nr_components(enum pipe_format format) * Return the index of the first non-void channel * -1 if no non-void channels */ -static INLINE int +static inline int util_format_get_first_non_void_channel(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); @@ -910,6 +1258,22 @@ util_format_get_first_non_void_channel(enum pipe_format format) return i; } +/** + * Whether this format is any 8-bit UNORM variant. Looser than + * util_is_rgba8_variant (also includes alpha textures, for instance). + */ + +static inline bool +util_format_is_unorm8(const struct util_format_description *desc) +{ + int c = util_format_get_first_non_void_channel(desc->format); + + if (c == -1) + return false; + + return desc->is_unorm && desc->is_array && desc->channel[c].size == 8; +} + /* * Format access functions. */ @@ -969,7 +1333,7 @@ util_format_write_4i(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, @@ -978,6 +1342,19 @@ 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. */ @@ -991,12 +1368,24 @@ void util_format_compose_swizzles(const unsigned char swz1[4], const unsigned char swz2[4], unsigned char dst[4]); -void util_format_swizzle_4f(float *dst, const float *src, +/* 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]); +enum pipe_format +util_format_snorm8_to_sint8(enum pipe_format format); + #ifdef __cplusplus } // extern "C" { #endif