X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Futil%2Fu_pack_color.h;h=36252738d68227df7db9a6ce15f8f919d4d4fb53;hb=9baa45f78b8ca7d66280e36009b6a685055d7cd6;hp=c5fd7a6783e256977b25c60d66c6b63d885a47a6;hpb=2689dd304c6d644b04c941e6da63e466be5de0d6;p=mesa.git diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index c5fd7a6783e..36252738d68 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -37,16 +37,24 @@ #include "pipe/p_compiler.h" #include "pipe/p_format.h" +#include "util/u_debug.h" #include "util/u_format.h" #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; + ushort h[4]; /* half float */ float f[4]; + double d[4]; }; /** @@ -57,32 +65,32 @@ 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; } return; - case PIPE_FORMAT_X8B8G8R8_UNORM: + case PIPE_FORMAT_XBGR8888_UNORM: { uc->ui = (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; } return; - case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_BGRX8888_UNORM: { uc->ui = (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; } return; - case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_XRGB8888_UNORM: { uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff; } @@ -115,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: @@ -158,7 +166,7 @@ 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; *r = (ubyte) ((p >> 24) & 0xff); @@ -167,7 +175,7 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc, *a = (ubyte) ((p >> 0) & 0xff); } return; - case PIPE_FORMAT_X8B8G8R8_UNORM: + case PIPE_FORMAT_XBGR8888_UNORM: { uint p = uc->ui; *r = (ubyte) ((p >> 24) & 0xff); @@ -176,7 +184,7 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc, *a = (ubyte) 0xff; } return; - case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_BGRA8888_UNORM: { uint p = uc->ui; *r = (ubyte) ((p >> 16) & 0xff); @@ -185,7 +193,7 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc, *a = (ubyte) ((p >> 24) & 0xff); } return; - case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_BGRX8888_UNORM: { uint p = uc->ui; *r = (ubyte) ((p >> 16) & 0xff); @@ -194,7 +202,7 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc, *a = (ubyte) 0xff; } return; - case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_ARGB8888_UNORM: { uint p = uc->ui; *r = (ubyte) ((p >> 8) & 0xff); @@ -203,7 +211,7 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc, *a = (ubyte) ((p >> 0) & 0xff); } return; - case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_XRGB8888_UNORM: { uint p = uc->ui; *r = (ubyte) ((p >> 8) & 0xff); @@ -322,6 +330,8 @@ 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 util_pack_color(const float rgba[4], enum pipe_format format, union util_color *uc) @@ -340,32 +350,32 @@ 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; } return; - case PIPE_FORMAT_X8B8G8R8_UNORM: + case PIPE_FORMAT_XBGR8888_UNORM: { uc->ui = (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; } return; - case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_BGRX8888_UNORM: { uc->ui = (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; } return; - case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_XRGB8888_UNORM: { uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff; } @@ -387,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: @@ -424,13 +434,93 @@ 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 uint32_t +util_pack_mask_z(enum pipe_format format, uint32_t z) +{ + switch (format) { + case PIPE_FORMAT_Z16_UNORM: + return z & 0xffff; + case PIPE_FORMAT_Z32_UNORM: + case PIPE_FORMAT_Z32_FLOAT: + return z; + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + case PIPE_FORMAT_Z24X8_UNORM: + return z & 0xffffff; + case PIPE_FORMAT_S8_UINT_Z24_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: + return (z & 0xffffff) << 8; + case PIPE_FORMAT_S8_UINT: + return 0; + default: + debug_print_format("gallium: unhandled format in util_pack_mask_z()", format); + assert(0); + return 0; + } +} + + +static INLINE uint64_t +util_pack64_mask_z(enum pipe_format format, uint32_t z) +{ + switch (format) { + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + return z; + default: + return util_pack_mask_z(format, z); + } +} + + +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_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: + 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; @@ -438,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_Z24S8_UNORM: + 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_S8Z24_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_UNORM: + 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: @@ -465,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_Z24S8_UNORM: - packed |= s << 24; + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + packed |= (uint32_t)s << 24; break; - case PIPE_FORMAT_S8Z24_UNORM: + case PIPE_FORMAT_S8_UINT_Z24_UNORM: packed |= s; break; - case PIPE_FORMAT_S8_UNORM: + case PIPE_FORMAT_S8_UINT: packed |= s; break; default: @@ -494,6 +603,24 @@ 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 */