diff options
author | Elie Tournier <[email protected]> | 2017-08-11 14:29:48 +0100 |
---|---|---|
committer | Matt Turner <[email protected]> | 2019-01-09 16:42:40 -0800 |
commit | 3db81b5d9f7f6e475462ca4f9306678bcc9d495c (patch) | |
tree | b4e7baf324201e4c6796f71775f4336f67b50eb3 /src/compiler/glsl/float64.glsl | |
parent | 48891ab441f5cbf593b043b0e3a4f9168c9cd479 (diff) |
glsl: Add "built-in" functions to do round(fp64)
Signed-off-by: Elie Tournier <[email protected]>
Diffstat (limited to 'src/compiler/glsl/float64.glsl')
-rw-r--r-- | src/compiler/glsl/float64.glsl | 42 |
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); +} |