summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorElie Tournier <tournier.elie@gmail.com>2017-08-11 14:29:48 +0100
committerMatt Turner <mattst88@gmail.com>2019-01-09 16:42:40 -0800
commit3db81b5d9f7f6e475462ca4f9306678bcc9d495c (patch)
treeb4e7baf324201e4c6796f71775f4336f67b50eb3 /src/compiler
parent48891ab441f5cbf593b043b0e3a4f9168c9cd479 (diff)
glsl: Add "built-in" functions to do round(fp64)
Signed-off-by: Elie Tournier <elie.tournier@collabora.com>
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/glsl/float64.glsl42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/compiler/glsl/float64.glsl b/src/compiler/glsl/float64.glsl
index 88209fc99f0..e09655e5055 100644
--- a/src/compiler/glsl/float64.glsl
+++ b/src/compiler/glsl/float64.glsl
@@ -1377,3 +1377,45 @@ __ftrunc64(uint64_t __a)
zHi = mix(zHi, a.y, unbiasedExp > 52);
return packUint2x32(uvec2(zLo, zHi));
}
+
+uint64_t
+__fround64(uint64_t __a)
+{
+ uvec2 a = unpackUint2x32(__a);
+ int unbiasedExp = __extractFloat64Exp(__a) - 1023;
+ uint aHi = a.y;
+ uint aLo = a.x;
+
+ if (unbiasedExp < 20) {
+ if (unbiasedExp < 0) {
+ aHi &= 0x80000000u;
+ if (unbiasedExp == -1 && aLo != 0u)
+ aHi |= (1023u << 20);
+ aLo = 0u;
+ } else {
+ uint maskExp = 0x000FFFFFu >> unbiasedExp;
+ /* a is an integral value */
+ if (((aHi & maskExp) == 0u) && (aLo == 0u))
+ return __a;
+
+ aHi += 0x00080000u >> unbiasedExp;
+ aHi &= ~maskExp;
+ aLo = 0u;
+ }
+ } else if (unbiasedExp > 51 || unbiasedExp == 1024) {
+ return __a;
+ } else {
+ uint maskExp = 0xFFFFFFFFu >> (unbiasedExp - 20);
+ if ((aLo & maskExp) == 0u)
+ return __a;
+ uint tmp = aLo + (1u << (51 - unbiasedExp));
+ if(tmp < aLo)
+ aHi += 1u;
+ aLo = tmp;
+ aLo &= ~maskExp;
+ }
+
+ a.x = aLo;
+ a.y = aHi;
+ return packUint2x32(a);
+}