gallium/util: Switch util_float_to_half to _mesa_float_to_half()'s impl.
authorEric Anholt <eric@anholt.net>
Thu, 27 Jun 2019 23:04:42 +0000 (16:04 -0700)
committerMarge Bot <eric+marge@anholt.net>
Tue, 17 Mar 2020 22:28:12 +0000 (22:28 +0000)
The util_float_to_half() implementation was much smaller, but when trying
to switch _mesa_float_to_half to it, many testcases
(dEQP-VK.spirv_assembly.instruction.graphics.opquantize.*,
piglit.spec.arb_shading_language_packing.*packhalf2x16) start failing on
Intel.  Replace the broken impl so that people don't have to debug it
later.

Acked-by: Michel Dänzer <mdaenzer@redhat.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3699>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3699>

src/gallium/auxiliary/util/u_half.h

index afce14f360315e591ba8a9d897d181effb6bf4f1..a107dcb74b14345c7944b9fd8eff3e1e719ac7cb 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "pipe/p_compiler.h"
 #include "util/u_math.h"
+#include "util/half_float.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -46,58 +47,7 @@ extern "C" {
 static inline uint16_t
 util_float_to_half(float f)
 {
-   uint32_t sign_mask  = 0x80000000;
-   uint32_t round_mask = ~0xfff;
-   uint32_t f32inf = 0xff << 23;
-   uint32_t f16inf = 0x1f << 23;
-   uint32_t sign;
-   union fi magic;
-   union fi f32;
-   uint16_t f16;
-
-   magic.ui = 0xf << 23;
-
-   f32.f = f;
-
-   /* Sign */
-   sign = f32.ui & sign_mask;
-   f32.ui ^= sign;
-
-   if (f32.ui == f32inf) {
-      /* Inf */
-      f16 = 0x7c00;
-   } else if (f32.ui > f32inf) {
-      /* NaN */
-      f16 = 0x7e00;
-   } else {
-      /* Number */
-      f32.ui &= round_mask;
-      f32.f  *= magic.f;
-      f32.ui -= round_mask;
-      /*
-       * XXX: The magic mul relies on denorms being available, otherwise
-       * all f16 denorms get flushed to zero - hence when this is used
-       * for tgsi_exec in softpipe we won't get f16 denorms.
-       */
-      /*
-       * Clamp to max finite value if overflowed.
-       * OpenGL has completely undefined rounding behavior for float to
-       * half-float conversions, and this matches what is mandated for float
-       * to fp11/fp10, which recommend round-to-nearest-finite too.
-       * (d3d10 is deeply unhappy about flushing such values to infinity, and
-       * while it also mandates round-to-zero it doesn't care nearly as much
-       * about that.)
-       */
-      if (f32.ui > f16inf)
-         f32.ui = f16inf - 1;
-
-      f16 = f32.ui >> 13;
-   }
-
-   /* Sign */
-   f16 |= sign >> 16;
-
-   return f16;
+   return _mesa_float_to_half(f);
 }
 
 static inline float