diff options
author | Nicolas Capens <capn@google.com> | 2018-01-11 21:19:34 -0500 |
---|---|---|
committer | Nicolas Capens <nicolascapens@google.com> | 2018-03-01 20:31:56 +0000 |
commit | 41bcdc786d73293eea620cf4a97903d3d400542e (patch) | |
tree | 2fa08a0332344eb2c4185f44d6ca7d03fed97eaa | |
parent | 749ac9c82b3b7c17df616beca7beb602a1c660c4 (diff) | |
download | swiftshader-41bcdc786d73293eea620cf4a97903d3d400542e.tar.gz |
Refactor exp2().
Change-Id: I491411ba77addcb514944717b19918e4d1b98898
Reviewed-on: https://swiftshader-review.googlesource.com/16228
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
-rw-r--r-- | src/Shader/ShaderCore.cpp | 47 |
1 files changed, 21 insertions, 26 deletions
diff --git a/src/Shader/ShaderCore.cpp b/src/Shader/ShaderCore.cpp index c76340472..883131c9f 100644 --- a/src/Shader/ShaderCore.cpp +++ b/src/Shader/ShaderCore.cpp @@ -114,35 +114,30 @@ namespace sw Float4 exponential2(RValue<Float4> x, bool pp) { - Float4 x0; - Float4 x1; - Int4 x2; - - x0 = x; + // This implementation is based on 2^(i + f) = 2^i * 2^f, + // where i is the integer part of x and f is the fraction. + // For 2^i we can put the integer part directly in the exponent of + // the IEEE-754 floating-point number. Clamp to prevent overflow + // past the representation of infinity. + Float4 x0 = x; x0 = Min(x0, As<Float4>(Int4(0x43010000))); // 129.00000e+0f x0 = Max(x0, As<Float4>(Int4(0xC2FDFFFF))); // -126.99999e+0f - x1 = x0; - x1 -= Float4(0.5f); - x2 = RoundInt(x1); - x1 = Float4(x2); - x2 += Int4(0x0000007F); // 127 - x2 = x2 << 23; - x0 -= x1; - x1 = As<Float4>(Int4(0x3AF61905)); // 1.8775767e-3f - x1 *= x0; - x1 += As<Float4>(Int4(0x3C134806)); // 8.9893397e-3f - x1 *= x0; - x1 += As<Float4>(Int4(0x3D64AA23)); // 5.5826318e-2f - x1 *= x0; - x1 += As<Float4>(Int4(0x3E75EAD4)); // 2.4015361e-1f - x1 *= x0; - x1 += As<Float4>(Int4(0x3F31727B)); // 6.9315308e-1f - x1 *= x0; - x1 += Float4(1.0f); - x1 *= As<Float4>(x2); - - return x1; + + Int4 i = RoundInt(x0 - Float4(0.5f)); + Float4 ii = As<Float4>((i + Int4(127)) << 23); // Add single-precision bias, and shift into exponent. + + // For the fractional part use a polynomial + // which approximates 2^f in the 0 to 1 range. + Float4 f = x0 - Float4(i); + Float4 ff = As<Float4>(Int4(0x3AF61905)); // 1.8775767e-3f + ff = ff * f + As<Float4>(Int4(0x3C134806)); // 8.9893397e-3f + ff = ff * f + As<Float4>(Int4(0x3D64AA23)); // 5.5826318e-2f + ff = ff * f + As<Float4>(Int4(0x3E75EAD4)); // 2.4015361e-1f + ff = ff * f + As<Float4>(Int4(0x3F31727B)); // 6.9315308e-1f + ff = ff * f + Float4(1.0f); + + return ii * ff; } Float4 logarithm2(RValue<Float4> x, bool absolute, bool pp) |