aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Capens <capn@google.com>2018-01-11 21:19:34 -0500
committerNicolas Capens <nicolascapens@google.com>2018-03-01 20:31:56 +0000
commit41bcdc786d73293eea620cf4a97903d3d400542e (patch)
tree2fa08a0332344eb2c4185f44d6ca7d03fed97eaa
parent749ac9c82b3b7c17df616beca7beb602a1c660c4 (diff)
downloadswiftshader-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.cpp47
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)