[Mesa-dev] [PATCH 4/6] util/rgb9e5: Get rid of the float754 union

Roland Scheidegger sroland at vmware.com
Wed Aug 3 23:57:09 UTC 2016


Am 03.08.2016 um 20:09 schrieb Jason Ekstrand:
> There are a number of reasons for this refactor.  First, format_rgb9e5.h is
> not something that a user would expect to define such a generic union.
> Second, defining it requires checking for endianness which is ugly.  Third,
> 90% of what we were doing with the union was float <-> uint32_t bitcasts
> and the remaining 10% can be done with a sinmple left-shift by 23.
simple

For the series:
Reviewed-by: Roland Scheidegger <sroland at vmware.com>



> 
> Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
> ---
>  src/util/format_rgb9e5.h | 69 +++++++++++++++++++-----------------------------
>  1 file changed, 27 insertions(+), 42 deletions(-)
> 
> diff --git a/src/util/format_rgb9e5.h b/src/util/format_rgb9e5.h
> index 644b9d8..2559e1e 100644
> --- a/src/util/format_rgb9e5.h
> +++ b/src/util/format_rgb9e5.h
> @@ -28,6 +28,7 @@
>  #define RGB9E5_H
>  
>  #include <assert.h>
> +#include <stdint.h>
>  
>  #include "c99_math.h"
>  
> @@ -41,59 +42,43 @@
>  #define MAX_RGB9E5_MANTISSA          (RGB9E5_MANTISSA_VALUES-1)
>  #define MAX_RGB9E5                   (((float)MAX_RGB9E5_MANTISSA)/RGB9E5_MANTISSA_VALUES * (1<<MAX_RGB9E5_EXP))
>  
> -typedef union {
> -   unsigned int raw;
> -   float value;
> -   struct {
> -#if defined(MESA_BIG_ENDIAN) || defined(PIPE_ARCH_BIG_ENDIAN)
> -      unsigned int negative:1;
> -      unsigned int biasedexponent:8;
> -      unsigned int mantissa:23;
> -#else
> -      unsigned int mantissa:23;
> -      unsigned int biasedexponent:8;
> -      unsigned int negative:1;
> -#endif
> -   } field;
> -} float754;
> -
>  static inline int rgb9e5_ClampRange(float x)
>  {
> -   float754 f;
> -   float754 max;
> -   f.value = x;
> -   max.value = MAX_RGB9E5;
> +   union { float f; uint32_t u; } f, max;
> +   f.f = x;
> +   max.f = MAX_RGB9E5;
>  
> -   if (f.raw > 0x7f800000)
> +   if (f.u > 0x7f800000)
>    /* catches neg, NaNs */
>        return 0;
> -   else if (f.raw >= max.raw)
> -      return max.raw;
> +   else if (f.u >= max.u)
> +      return max.u;
>     else
> -      return f.raw;
> +      return f.u;
>  }
>  
>  static inline unsigned int float3_to_rgb9e5(const float rgb[3])
>  {
>     int rm, gm, bm, exp_shared;
> -   float754 revdenom = {0};
> -   float754 rc, bc, gc, maxrgb;
> +   uint32_t revdenom_biasedexp;
> +   union { float f; uint32_t u; } rc, bc, gc, maxrgb, revdenom;
>  
> -   rc.raw = rgb9e5_ClampRange(rgb[0]);
> -   gc.raw = rgb9e5_ClampRange(rgb[1]);
> -   bc.raw = rgb9e5_ClampRange(rgb[2]);
> -   maxrgb.raw = MAX3(rc.raw, gc.raw, bc.raw);
> +   rc.u = rgb9e5_ClampRange(rgb[0]);
> +   gc.u = rgb9e5_ClampRange(rgb[1]);
> +   bc.u = rgb9e5_ClampRange(rgb[2]);
> +   maxrgb.u = MAX3(rc.u, gc.u, bc.u);
>  
>     /*
>      * Compared to what the spec suggests, instead of conditionally adjusting
>      * the exponent after the fact do it here by doing the equivalent of +0.5 -
>      * the int add will spill over into the exponent in this case.
>      */
> -   maxrgb.raw += maxrgb.raw & (1 << (23-9));
> -   exp_shared = MAX2((maxrgb.raw >> 23), -RGB9E5_EXP_BIAS - 1 + 127) +
> +   maxrgb.u += maxrgb.u & (1 << (23-9));
> +   exp_shared = MAX2((maxrgb.u >> 23), -RGB9E5_EXP_BIAS - 1 + 127) +
>                  1 + RGB9E5_EXP_BIAS - 127;
> -   revdenom.field.biasedexponent = 127 - (exp_shared - RGB9E5_EXP_BIAS -
> -                                          RGB9E5_MANTISSA_BITS) + 1;
> +   revdenom_biasedexp = 127 - (exp_shared - RGB9E5_EXP_BIAS -
> +                               RGB9E5_MANTISSA_BITS) + 1;
> +   revdenom.u = revdenom_biasedexp << 23;
>     assert(exp_shared <= RGB9E5_MAX_VALID_BIASED_EXP);
>  
>     /*
> @@ -102,9 +87,9 @@ static inline unsigned int float3_to_rgb9e5(const float rgb[3])
>      * We avoid the doubles ((int) rc * revdenom + 0.5) by doing the rounding
>      * ourselves (revdenom was adjusted by +1, above).
>      */
> -   rm = (int) (rc.value * revdenom.value);
> -   gm = (int) (gc.value * revdenom.value);
> -   bm = (int) (bc.value * revdenom.value);
> +   rm = (int) (rc.f * revdenom.f);
> +   gm = (int) (gc.f * revdenom.f);
> +   bm = (int) (bc.f * revdenom.f);
>     rm = (rm & 1) + (rm >> 1);
>     gm = (gm & 1) + (gm >> 1);
>     bm = (bm & 1) + (bm >> 1);
> @@ -122,14 +107,14 @@ static inline unsigned int float3_to_rgb9e5(const float rgb[3])
>  static inline void rgb9e5_to_float3(unsigned rgb, float retval[3])
>  {
>     int exponent;
> -   float754 scale = {0};
> +   union { float f; uint32_t u; } scale;
>  
>     exponent = (rgb >> 27) - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS;
> -   scale.field.biasedexponent = exponent + 127;
> +   scale.u = (exponent + 127) << 23;
>  
> -   retval[0] = ( rgb        & 0x1ff) * scale.value;
> -   retval[1] = ((rgb >> 9)  & 0x1ff) * scale.value;
> -   retval[2] = ((rgb >> 18) & 0x1ff) * scale.value;
> +   retval[0] = ( rgb        & 0x1ff) * scale.f;
> +   retval[1] = ((rgb >> 9)  & 0x1ff) * scale.f;
> +   retval[2] = ((rgb >> 18) & 0x1ff) * scale.f;
>  }
>  
>  #endif
> 



More information about the mesa-dev mailing list