util/rgb9e5: Get rid of the float754 union
authorJason Ekstrand <jason.ekstrand@intel.com>
Wed, 3 Aug 2016 16:54:03 +0000 (09:54 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Fri, 5 Aug 2016 16:07:01 +0000 (09:07 -0700)
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.

Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
src/util/format_rgb9e5.h

index 644b9d888e3633185b4e5fddec1c69429369c14d..2559e1e7d1b08e095397d254739c3e75c7b436a8 100644 (file)
@@ -28,6 +28,7 @@
 #define RGB9E5_H
 
 #include <assert.h>
+#include <stdint.h>
 
 #include "c99_math.h"
 
 #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