Commit cd280441 by Ben Clayton

SpirvShader: Precision fixes for GLSLstd450Ldexp

Bug: b/126873455 Tests: dEQP-VK.glsl.builtin.precision.ldexp.* Tests: dEQP-VK.glsl.builtin.function.common.ldexp.* Change-Id: If70125d749ba976abfa7295f067be51c5e8c2417 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31409 Presubmit-Ready: Ben Clayton <bclayton@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com>
parent a1c28d07
......@@ -3955,10 +3955,29 @@ namespace sw
for (auto i = 0u; i < type.sizeInComponents; i++)
{
// Assumes IEEE 754
auto significandExponent = Exponent(significand.Float(i));
auto in = significand.Float(i);
auto significandExponent = Exponent(in);
auto combinedExponent = exponent.Int(i) + significandExponent;
SIMD::UInt v = (significand.UInt(i) & SIMD::UInt(0x807FFFFF)) |
(SIMD::UInt(combinedExponent + SIMD::Int(126)) << SIMD::UInt(23));
auto isSignificandZero = SIMD::UInt(CmpEQ(significand.Int(0), SIMD::Int(0)));
auto isSignificandInf = SIMD::UInt(IsInf(in));
auto isSignificandNaN = SIMD::UInt(IsNan(in));
auto isExponentNotTooSmall = SIMD::UInt(CmpGE(combinedExponent, SIMD::Int(-126)));
auto isExponentNotTooLarge = SIMD::UInt(CmpLE(combinedExponent, SIMD::Int(128)));
auto isExponentInBounds = isExponentNotTooSmall & isExponentNotTooLarge;
SIMD::UInt v;
v = significand.UInt(i) & SIMD::UInt(0x7FFFFF); // Add significand.
v |= (SIMD::UInt(combinedExponent + SIMD::Int(126)) << SIMD::UInt(23)); // Add exponent.
v &= isExponentInBounds; // Clear v if the exponent is OOB.
v |= significand.UInt(i) & SIMD::UInt(0x80000000); // Add sign bit.
v |= ~isExponentNotTooLarge & SIMD::UInt(0x7F800000); // Mark as inf if the exponent is too great.
// If the input significand is zero, inf or nan, just return the
// input significand.
auto passthrough = isSignificandZero | isSignificandInf | isSignificandNaN;
v = (v & ~passthrough) | (significand.UInt(0) & passthrough);
dst.move(i, As<SIMD::Float>(v));
}
break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment