diff options
author | Sagar Ghuge <[email protected]> | 2018-12-11 11:19:38 -0800 |
---|---|---|
committer | Matt Turner <[email protected]> | 2019-01-09 16:42:40 -0800 |
commit | 21e9bb2b3f306f29e6fe14157502f10c2daa44df (patch) | |
tree | 3933311afdc0d42150f1248b1b01cc3c88849a18 /src/compiler/glsl/float64.glsl | |
parent | 5a674fd7896f30d44d9300406b8732081d1584b6 (diff) |
glsl: Add utility function to round and pack int64_t value
Reviewed-by: Elie Tournier <[email protected]>
Signed-off-by: Sagar Ghuge <[email protected]>
Diffstat (limited to 'src/compiler/glsl/float64.glsl')
-rw-r--r-- | src/compiler/glsl/float64.glsl | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/compiler/glsl/float64.glsl b/src/compiler/glsl/float64.glsl index cf069fe6588..71ebbb8d907 100644 --- a/src/compiler/glsl/float64.glsl +++ b/src/compiler/glsl/float64.glsl @@ -483,6 +483,42 @@ __roundAndPackUInt64(uint zSign, uint zFrac0, uint zFrac1, uint zFrac2) (zSign !=0u && (zFrac0 | zFrac1) != 0u)); } +int64_t +__roundAndPackInt64(uint zSign, uint zFrac0, uint zFrac1, uint zFrac2) +{ + bool roundNearestEven; + bool increment; + int64_t default_NegNaN = -0x7FFFFFFFFFFFFFFEL; + int64_t default_PosNaN = 0xFFFFFFFFFFFFFFFFL; + + roundNearestEven = FLOAT_ROUNDING_MODE == FLOAT_ROUND_NEAREST_EVEN; + + if (zFrac2 >= 0x80000000u) + increment = false; + + if (!roundNearestEven) { + if (zSign != 0u) { + increment = ((FLOAT_ROUNDING_MODE == FLOAT_ROUND_DOWN) && + (zFrac2 != 0u)); + } else { + increment = (FLOAT_ROUNDING_MODE == FLOAT_ROUND_UP) && + (zFrac2 != 0u); + } + } + + if (increment) { + __add64(zFrac0, zFrac1, 0u, 1u, zFrac0, zFrac1); + if ((zFrac0 | zFrac1) != 0u) + zFrac1 &= ~(1u) + uint(zFrac2 == 0u) & uint(roundNearestEven); + } + + int64_t absZ = mix(int64_t(packUint2x32(uvec2(zFrac1, zFrac0))), + -int64_t(packUint2x32(uvec2(zFrac1, zFrac0))), + (zSign != 0u)); + int64_t nan = mix(default_PosNaN, default_NegNaN, bool(zSign)); + return mix(absZ, nan, bool(zSign ^ uint(absZ < 0)) && bool(absZ)); +} + /* Returns the number of leading 0 bits before the most-significant 1 bit of * `a'. If `a' is zero, 32 is returned. */ |