X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Futil%2Fu_pack_color.h;h=f9f41609b44b1f0ae4e29ac8ec9ad658e539f186;hb=70c272004f727457e852ba5f2498754b07a7d995;hp=5f113f742b113060701f150074a86a94b1a79c87;hpb=443a7e4e9a360acbc3e662c098be436f180bf81d;p=mesa.git diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 5f113f742b1..f9f41609b44 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2008 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,7 +18,7 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -42,50 +42,57 @@ #include "util/u_math.h" - +/** + * Helper union for packing pixel values. + * Will often contain values in formats which are too complex to be described + * in simple terms, hence might just effectively contain a number of bytes. + * Must be big enough to hold data for all formats (currently 256 bits). + */ union util_color { ubyte ub; ushort us; - uint ui; + uint ui[4]; + ushort h[4]; /* half float */ float f[4]; + double d[4]; }; /** * Pack ubyte R,G,B,A into dest pixel. */ -static INLINE void +static inline void util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, enum pipe_format format, union util_color *uc) { switch (format) { - case PIPE_FORMAT_A8B8G8R8_UNORM: + case PIPE_FORMAT_ABGR8888_UNORM: { - uc->ui = (r << 24) | (g << 16) | (b << 8) | a; + uc->ui[0] = (r << 24) | (g << 16) | (b << 8) | a; } return; - case PIPE_FORMAT_X8B8G8R8_UNORM: + case PIPE_FORMAT_XBGR8888_UNORM: { - uc->ui = (r << 24) | (g << 16) | (b << 8) | 0xff; + uc->ui[0] = (r << 24) | (g << 16) | (b << 8) | 0xff; } return; - case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_BGRA8888_UNORM: { - uc->ui = (a << 24) | (r << 16) | (g << 8) | b; + uc->ui[0] = (a << 24) | (r << 16) | (g << 8) | b; } return; - case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_BGRX8888_UNORM: { - uc->ui = (0xff << 24) | (r << 16) | (g << 8) | b; + uc->ui[0] = (0xff << 24) | (r << 16) | (g << 8) | b; } return; - case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_ARGB8888_UNORM: { - uc->ui = (b << 24) | (g << 16) | (r << 8) | a; + uc->ui[0] = (b << 24) | (g << 16) | (r << 8) | a; } return; - case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_XRGB8888_UNORM: { - uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff; + uc->ui[0] = (b << 24) | (g << 16) | (r << 8) | 0xff; } return; case PIPE_FORMAT_B5G6R5_UNORM: @@ -116,7 +123,7 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, case PIPE_FORMAT_L8_UNORM: case PIPE_FORMAT_I8_UNORM: { - uc->ub = a; + uc->ub = r; } return; case PIPE_FORMAT_R32G32B32A32_FLOAT: @@ -154,59 +161,59 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, /** * Unpack RGBA from a packed pixel, returning values as ubytes in [0,255]. */ -static INLINE void +static inline void util_unpack_color_ub(enum pipe_format format, union util_color *uc, ubyte *r, ubyte *g, ubyte *b, ubyte *a) { switch (format) { - case PIPE_FORMAT_A8B8G8R8_UNORM: + case PIPE_FORMAT_ABGR8888_UNORM: { - uint p = uc->ui; + uint p = uc->ui[0]; *r = (ubyte) ((p >> 24) & 0xff); *g = (ubyte) ((p >> 16) & 0xff); *b = (ubyte) ((p >> 8) & 0xff); *a = (ubyte) ((p >> 0) & 0xff); } return; - case PIPE_FORMAT_X8B8G8R8_UNORM: + case PIPE_FORMAT_XBGR8888_UNORM: { - uint p = uc->ui; + uint p = uc->ui[0]; *r = (ubyte) ((p >> 24) & 0xff); *g = (ubyte) ((p >> 16) & 0xff); *b = (ubyte) ((p >> 8) & 0xff); *a = (ubyte) 0xff; } return; - case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_BGRA8888_UNORM: { - uint p = uc->ui; + uint p = uc->ui[0]; *r = (ubyte) ((p >> 16) & 0xff); *g = (ubyte) ((p >> 8) & 0xff); *b = (ubyte) ((p >> 0) & 0xff); *a = (ubyte) ((p >> 24) & 0xff); } return; - case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_BGRX8888_UNORM: { - uint p = uc->ui; + uint p = uc->ui[0]; *r = (ubyte) ((p >> 16) & 0xff); *g = (ubyte) ((p >> 8) & 0xff); *b = (ubyte) ((p >> 0) & 0xff); *a = (ubyte) 0xff; } return; - case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_ARGB8888_UNORM: { - uint p = uc->ui; + uint p = uc->ui[0]; *r = (ubyte) ((p >> 8) & 0xff); *g = (ubyte) ((p >> 16) & 0xff); *b = (ubyte) ((p >> 24) & 0xff); *a = (ubyte) ((p >> 0) & 0xff); } return; - case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_XRGB8888_UNORM: { - uint p = uc->ui; + uint p = uc->ui[0]; *r = (ubyte) ((p >> 8) & 0xff); *g = (ubyte) ((p >> 16) & 0xff); *b = (ubyte) ((p >> 24) & 0xff); @@ -323,8 +330,10 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc, /** * Note rgba outside [0,1] will be clamped for int pixel formats. + * This will not work (and might not really be useful with float input) + * for pure integer formats (which lack the pack_rgba_float function). */ -static INLINE void +static inline void util_pack_color(const float rgba[4], enum pipe_format format, union util_color *uc) { ubyte r = 0; @@ -341,34 +350,34 @@ util_pack_color(const float rgba[4], enum pipe_format format, union util_color * } switch (format) { - case PIPE_FORMAT_A8B8G8R8_UNORM: + case PIPE_FORMAT_ABGR8888_UNORM: { - uc->ui = (r << 24) | (g << 16) | (b << 8) | a; + uc->ui[0] = (r << 24) | (g << 16) | (b << 8) | a; } return; - case PIPE_FORMAT_X8B8G8R8_UNORM: + case PIPE_FORMAT_XBGR8888_UNORM: { - uc->ui = (r << 24) | (g << 16) | (b << 8) | 0xff; + uc->ui[0] = (r << 24) | (g << 16) | (b << 8) | 0xff; } return; - case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_BGRA8888_UNORM: { - uc->ui = (a << 24) | (r << 16) | (g << 8) | b; + uc->ui[0] = (a << 24) | (r << 16) | (g << 8) | b; } return; - case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_BGRX8888_UNORM: { - uc->ui = (0xff << 24) | (r << 16) | (g << 8) | b; + uc->ui[0] = (0xffu << 24) | (r << 16) | (g << 8) | b; } return; - case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_ARGB8888_UNORM: { - uc->ui = (b << 24) | (g << 16) | (r << 8) | a; + uc->ui[0] = (b << 24) | (g << 16) | (r << 8) | a; } return; - case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_XRGB8888_UNORM: { - uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff; + uc->ui[0] = (b << 24) | (g << 16) | (r << 8) | 0xff; } return; case PIPE_FORMAT_B5G6R5_UNORM: @@ -388,7 +397,7 @@ util_pack_color(const float rgba[4], enum pipe_format format, union util_color * return; case PIPE_FORMAT_B4G4R4A4_UNORM: { - uc->ub = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4); + uc->us = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4); } return; case PIPE_FORMAT_A8_UNORM: @@ -428,8 +437,8 @@ util_pack_color(const float rgba[4], enum pipe_format format, union util_color * /* Integer versions of util_pack_z and util_pack_z_stencil - useful for * constructing clear masks. */ -static INLINE uint -util_pack_uint_z(enum pipe_format format, unsigned z) +static inline uint32_t +util_pack_mask_z(enum pipe_format format, uint32_t z) { switch (format) { case PIPE_FORMAT_Z16_UNORM: @@ -437,48 +446,81 @@ util_pack_uint_z(enum pipe_format format, unsigned z) case PIPE_FORMAT_Z32_UNORM: case PIPE_FORMAT_Z32_FLOAT: return z; - case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + case PIPE_FORMAT_Z24_UNORM_S8_UINT: case PIPE_FORMAT_Z24X8_UNORM: return z & 0xffffff; - case PIPE_FORMAT_S8_USCALED_Z24_UNORM: + case PIPE_FORMAT_S8_UINT_Z24_UNORM: case PIPE_FORMAT_X8Z24_UNORM: return (z & 0xffffff) << 8; - case PIPE_FORMAT_S8_USCALED: + case PIPE_FORMAT_S8_UINT: return 0; default: - debug_print_format("gallium: unhandled format in util_pack_z()", format); + debug_print_format("gallium: unhandled format in util_pack_mask_z()", format); assert(0); return 0; } } -static INLINE uint -util_pack_uint_z_stencil(enum pipe_format format, double z, uint s) + +static inline uint64_t +util_pack64_mask_z(enum pipe_format format, uint32_t z) { - unsigned packed = util_pack_uint_z(format, z); + switch (format) { + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + return z; + default: + return util_pack_mask_z(format, z); + } +} - s &= 0xff; + +static inline uint32_t +util_pack_mask_z_stencil(enum pipe_format format, uint32_t z, uint8_t s) +{ + uint32_t packed = util_pack_mask_z(format, z); switch (format) { - case PIPE_FORMAT_Z24_UNORM_S8_USCALED: - return packed | (s << 24); - case PIPE_FORMAT_S8_USCALED_Z24_UNORM: - return packed | s; - case PIPE_FORMAT_S8_USCALED: - return packed | s; + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + packed |= (uint32_t)s << 24; + break; + case PIPE_FORMAT_S8_UINT_Z24_UNORM: + packed |= s; + break; + case PIPE_FORMAT_S8_UINT: + packed |= s; + break; default: - return packed; + break; } + + return packed; } +static inline uint64_t +util_pack64_mask_z_stencil(enum pipe_format format, uint32_t z, uint8_t s) +{ + uint64_t packed; + + switch (format) { + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + packed = util_pack64_mask_z(format, z); + packed |= (uint64_t)s << 32ull; + return packed; + default: + return util_pack_mask_z_stencil(format, z, s); + } +} + /** * Note: it's assumed that z is in [0,1] */ -static INLINE uint +static inline uint32_t util_pack_z(enum pipe_format format, double z) { + union fi fui; + if (z == 0.0) return 0; @@ -486,25 +528,26 @@ util_pack_z(enum pipe_format format, double z) case PIPE_FORMAT_Z16_UNORM: if (z == 1.0) return 0xffff; - return (uint) (z * 0xffff); + return (uint32_t) lrint(z * 0xffff); case PIPE_FORMAT_Z32_UNORM: /* special-case to avoid overflow */ if (z == 1.0) return 0xffffffff; - return (uint) (z * 0xffffffff); + return (uint32_t) llrint(z * 0xffffffff); case PIPE_FORMAT_Z32_FLOAT: - return (uint)z; - case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + fui.f = (float)z; + return fui.ui; + case PIPE_FORMAT_Z24_UNORM_S8_UINT: case PIPE_FORMAT_Z24X8_UNORM: if (z == 1.0) return 0xffffff; - return (uint) (z * 0xffffff); - case PIPE_FORMAT_S8_USCALED_Z24_UNORM: + return (uint32_t) lrint(z * 0xffffff); + case PIPE_FORMAT_S8_UINT_Z24_UNORM: case PIPE_FORMAT_X8Z24_UNORM: if (z == 1.0) return 0xffffff00; - return ((uint) (z * 0xffffff)) << 8; - case PIPE_FORMAT_S8_USCALED: + return ((uint32_t) lrint(z * 0xffffff)) << 8; + case PIPE_FORMAT_S8_UINT: /* this case can get it via util_pack_z_stencil() */ return 0; default: @@ -513,25 +556,43 @@ util_pack_z(enum pipe_format format, double z) return 0; } } + + +static inline uint64_t +util_pack64_z(enum pipe_format format, double z) +{ + union fi fui; + + if (z == 0) + return 0; + + switch (format) { + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + fui.f = (float)z; + return fui.ui; + default: + return util_pack_z(format, z); + } +} /** * Pack Z and/or stencil values into a 32-bit value described by format. * Note: it's assumed that z is in [0,1] and s in [0,255] */ -static INLINE uint -util_pack_z_stencil(enum pipe_format format, double z, uint s) +static inline uint32_t +util_pack_z_stencil(enum pipe_format format, double z, uint8_t s) { - unsigned packed = util_pack_z(format, z); + uint32_t packed = util_pack_z(format, z); switch (format) { - case PIPE_FORMAT_Z24_UNORM_S8_USCALED: - packed |= s << 24; + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + packed |= (uint32_t)s << 24; break; - case PIPE_FORMAT_S8_USCALED_Z24_UNORM: + case PIPE_FORMAT_S8_UINT_Z24_UNORM: packed |= s; break; - case PIPE_FORMAT_S8_USCALED: + case PIPE_FORMAT_S8_UINT: packed |= s; break; default: @@ -542,10 +603,28 @@ util_pack_z_stencil(enum pipe_format format, double z, uint s) } +static inline uint64_t +util_pack64_z_stencil(enum pipe_format format, double z, uint8_t s) +{ + uint64_t packed; + + switch (format) { + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + packed = util_pack64_z(format, z); + packed |= (uint64_t)s << 32ull; + break; + default: + return util_pack_z_stencil(format, z, s); + } + + return packed; +} + + /** * Pack 4 ubytes into a 4-byte word */ -static INLINE unsigned +static inline unsigned pack_ub4(ubyte b0, ubyte b1, ubyte b2, ubyte b3) { return ((((unsigned int)b0) << 0) | @@ -558,7 +637,7 @@ pack_ub4(ubyte b0, ubyte b1, ubyte b2, ubyte b3) /** * Pack/convert 4 floats into one 4-byte word. */ -static INLINE unsigned +static inline unsigned pack_ui32_float4(float a, float b, float c, float d) { return pack_ub4( float_to_ubyte(a),