glsl: Fix round64 conversion function
authorSagar Ghuge <sagar.ghuge@intel.com>
Mon, 24 Jun 2019 22:10:53 +0000 (15:10 -0700)
committerSagar Ghuge <sagar.ghuge@intel.com>
Tue, 25 Jun 2019 22:19:10 +0000 (15:19 -0700)
Fix round64 function to handle round to nearest even cases specially
with positive and negative numbers with fraction part 0.5.

v2: 1) Simplify unused bits (Elie Tournier)

Fixes:
   KHR-GL45.gpu_shader_fp64.builtin.round_dvec2
   KHR-GL45.gpu_shader_fp64.builtin.round_dvec3
   KHR-GL45.gpu_shader_fp64.builtin.round_dvec4
   KHR-GL45.gpu_shader_fp64.builtin.roundeven_double
   KHR-GL45.gpu_shader_fp64.builtin.roundeven_dvec2
   KHR-GL45.gpu_shader_fp64.builtin.roundeven_dvec3
   KHR-GL45.gpu_shader_fp64.builtin.roundeven_dvec4

Signed-off-by: Sagar Ghuge <sagar.ghuge@intel.com>
Reviewed-by: Elie Tournier <elie.tournier@collabora.com>
Acked-by: Anuj Phogat <anuj.phogat@gmail.com>
src/compiler/glsl/float64.glsl

index babfad20e9c6b03fe74e70c2c7e7a1c70aa9593c..0433d925a3958289e040781c094c63e5b1f4334e 100644 (file)
@@ -1693,17 +1693,22 @@ __fround64(uint64_t __a)
 
    if (unbiasedExp < 20) {
       if (unbiasedExp < 0) {
+         if ((aHi & 0x80000000u) != 0u && aLo == 0u) {
+            return 0;
+         }
          aHi &= 0x80000000u;
-         if (unbiasedExp == -1 && aLo != 0u)
-            aHi |= (1023u << 20);
+         if ((a.y & 0x000FFFFFu) == 0u && a.x == 0u) {
+            aLo = 0u;
+            return packUint2x32(uvec2(aLo, aHi));
+         }
+         aHi = mix(aHi, (aHi | 0x3FF00000u), unbiasedExp == -1);
          aLo = 0u;
       } else {
          uint maskExp = 0x000FFFFFu >> unbiasedExp;
-         /* a is an integral value */
-         if (((aHi & maskExp) == 0u) && (aLo == 0u))
-            return __a;
-
+         uint lastBit = maskExp + 1;
          aHi += 0x00080000u >> unbiasedExp;
+         if ((aHi & maskExp) == 0u)
+            aHi &= ~lastBit;
          aHi &= ~maskExp;
          aLo = 0u;
       }
@@ -1720,9 +1725,7 @@ __fround64(uint64_t __a)
       aLo &= ~maskExp;
    }
 
-   a.x = aLo;
-   a.y = aHi;
-   return packUint2x32(a);
+   return packUint2x32(uvec2(aLo, aHi));
 }
 
 uint64_t