Skip to content

Commit

Permalink
SpirvShader: Fixes for GLSLstd450Modf / GLSLstd450ModfStruct
Browse files Browse the repository at this point in the history
The returned whole and frac must have the same sign as the input parameter.

Tests: dEQP-VK.glsl.builtin.precision.modf.*
Tests: dEQP-VK.glsl.builtin.function.common.modf.*
Bug: b/126873455
Change-Id: I791891fdf46f9285e12d770e2b15b91ebfa3f0b1
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31590
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
Presubmit-Ready: Ben Clayton <bclayton@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
  • Loading branch information
ben-clayton committed May 20, 2019
1 parent 1d2ebed commit 9e2844f
Showing 1 changed file with 21 additions and 7 deletions.
28 changes: 21 additions & 7 deletions src/Pipeline/SpirvShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,23 @@ namespace
return rr::SignMask(~ints) != 0;
}

rr::RValue<sw::SIMD::Float> Sign(rr::RValue<sw::SIMD::Float> const &val)
{
return rr::As<sw::SIMD::Float>((rr::As<sw::SIMD::UInt>(val) & sw::SIMD::UInt(0x80000000)) | sw::SIMD::UInt(0x3f800000));
}

// Returns the <whole, frac> of val.
// Both whole and frac will have the same sign as val.
std::pair<rr::RValue<sw::SIMD::Float>, rr::RValue<sw::SIMD::Float>>
Modf(rr::RValue<sw::SIMD::Float> const &val)
{
auto abs = Abs(val);
auto sign = Sign(val);
auto whole = Floor(abs) * sign;
auto frac = Frac(abs) * sign;
return std::make_pair(whole, frac);
}

// Returns 1 << bits.
// If the resulting bit overflows a 32 bit integer, 0 is returned.
rr::RValue<sw::SIMD::UInt> NthBit32(rr::RValue<sw::SIMD::UInt> const &bits)
Expand Down Expand Up @@ -3805,11 +3822,9 @@ namespace sw

for (auto i = 0u; i < type.sizeInComponents; i++)
{
auto whole = Floor(val.Float(i));
auto frac = Frac(val.Float(i));

SIMD::Float whole, frac;
std::tie(whole, frac) = Modf(val.Float(i));
dst.move(i, frac);

auto p = ptr + (i * sizeof(float));
if (interleavedByLane) { p = interleaveByLane(p); }
SIMD::Store(p, whole, state->activeLaneMask());
Expand All @@ -3823,9 +3838,8 @@ namespace sw

for (auto i = 0u; i < valTy.sizeInComponents; i++)
{
auto whole = Floor(val.Float(i));
auto frac = Frac(val.Float(i));

SIMD::Float whole, frac;
std::tie(whole, frac) = Modf(val.Float(i));
dst.move(i, frac);
dst.move(i + valTy.sizeInComponents, whole);
}
Expand Down

0 comments on commit 9e2844f

Please sign in to comment.