Commit fc77af18 by Ben Clayton

SpirvShader: Implement GLSLstd450Frexp

Bug: b/126873455 Tests: dEQP-VK.glsl.builtin.function.common.frexp.* Change-Id: Ic725c53191c3a6ec6494859d6eb8e6a8eb77c90e Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28628Tested-by: 's avatarBen Clayton <bclayton@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 50e64936
...@@ -3179,6 +3179,48 @@ namespace sw ...@@ -3179,6 +3179,48 @@ namespace sw
dst.move(1, HalfToFloatBits((val.UInt(0) & SIMD::UInt(0xFFFF0000)) >> 16)); dst.move(1, HalfToFloatBits((val.UInt(0) & SIMD::UInt(0xFFFF0000)) >> 16));
break; break;
} }
case GLSLstd450Frexp:
{
auto val = GenericValue(this, routine, insn.word(5));
auto ptrId = Object::ID(insn.word(6));
auto ptrTy = getType(getObject(ptrId).type);
auto ptr = GetPointerToData(ptrId, 0, routine);
bool interleavedByLane = IsStorageInterleavedByLane(ptrTy.storageClass);
for (auto i = 0u; i < type.sizeInComponents; i++)
{
SIMD::Float significand;
SIMD::Int exponent;
std::tie(significand, exponent) = Frexp(val.Float(i));
dst.move(i, significand);
// TODO: Refactor and consolidate with EmitStore.
for (int j = 0; j < SIMD::Width; j++)
{
auto ptrBase = Pointer<Int>(ptr.base);
If(Extract(state->activeLaneMask(), j) != 0)
{
Int offset = Int(i) + Extract(ptr.offset, j);
if (interleavedByLane) { offset = offset * SIMD::Width + j; }
Store(Extract(exponent, j), &ptrBase[offset], sizeof(uint32_t), false, std::memory_order_relaxed);
}
}
}
break;
}
case GLSLstd450FrexpStruct:
{
auto val = GenericValue(this, routine, insn.word(5));
auto numComponents = getType(val.type).sizeInComponents;
for (auto i = 0u; i < numComponents; i++)
{
auto significandAndExponent = Frexp(val.Float(i));
dst.move(i, significandAndExponent.first);
dst.move(i + numComponents, significandAndExponent.second);
}
break;
}
default: default:
UNIMPLEMENTED("Unhandled ExtInst %d", extInstIndex); UNIMPLEMENTED("Unhandled ExtInst %d", extInstIndex);
} }
...@@ -3250,6 +3292,17 @@ namespace sw ...@@ -3250,6 +3292,17 @@ namespace sw
(CmpNLE(As<SIMD::UInt>(expmant), SIMD::UInt(was_infnan)) & SIMD::UInt(exp_infnan)); (CmpNLE(As<SIMD::UInt>(expmant), SIMD::UInt(was_infnan)) & SIMD::UInt(exp_infnan));
} }
std::pair<SIMD::Float, SIMD::Int> SpirvShader::Frexp(RValue<SIMD::Float> val) const
{
// Assumes IEEE 754
auto v = As<SIMD::UInt>(val);
auto isNotZero = CmpNEQ(v & SIMD::UInt(0x7FFFFFFF), SIMD::UInt(0));
auto zeroSign = v & SIMD::UInt(0x80000000) & ~isNotZero;
auto significand = As<SIMD::Float>((v & SIMD::UInt(0x807FFFFF) | SIMD::UInt(0x3F000000)) & isNotZero | zeroSign);
auto exponent = (SIMD::Int((v >> SIMD::UInt(23)) & SIMD::UInt(0xFF)) - SIMD::Int(126)) & SIMD::Int(isNotZero);
return std::make_pair(significand, exponent);
}
SpirvShader::EmitResult SpirvShader::EmitAny(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitAny(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine; auto routine = state->routine;
......
...@@ -691,8 +691,15 @@ namespace sw ...@@ -691,8 +691,15 @@ namespace sw
// Helper as we often need to take dot products as part of doing other things. // Helper as we often need to take dot products as part of doing other things.
SIMD::Float Dot(unsigned numComponents, GenericValue const & x, GenericValue const & y) const; SIMD::Float Dot(unsigned numComponents, GenericValue const & x, GenericValue const & y) const;
SIMD::UInt FloatToHalfBits(SIMD::UInt floatBits, bool storeInUpperBits) const; SIMD::UInt FloatToHalfBits(SIMD::UInt floatBits, bool storeInUpperBits) const;
SIMD::UInt HalfToFloatBits(SIMD::UInt halfBits) const; SIMD::UInt HalfToFloatBits(SIMD::UInt halfBits) const;
// Splits x into a floating-point significand in the range [0.5, 1.0)
// and an integral exponent of two, such that:
// x = significand * 2^exponent
// Returns the pair <significand, exponent>
std::pair<SIMD::Float, SIMD::Int> Frexp(RValue<SIMD::Float> val) const;
}; };
class SpirvRoutine class SpirvRoutine
......
...@@ -3572,6 +3572,16 @@ namespace rr ...@@ -3572,6 +3572,16 @@ namespace rr
return RValue<UInt4>(Nucleus::createNot(val.value)); return RValue<UInt4>(Nucleus::createNot(val.value));
} }
RValue<UInt> Extract(RValue<UInt4> x, int i)
{
return RValue<UInt>(Nucleus::createExtractElement(x.value, Int::getType(), i));
}
RValue<UInt4> Insert(RValue<UInt4> x, RValue<UInt> element, int i)
{
return RValue<UInt4>(Nucleus::createInsertElement(x.value, element.value, i));
}
Half::Half(RValue<Float> cast) Half::Half(RValue<Float> cast)
{ {
UInt fp32i = As<UInt>(cast); UInt fp32i = As<UInt>(cast);
......
...@@ -1972,6 +1972,8 @@ namespace rr ...@@ -1972,6 +1972,8 @@ namespace rr
RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y); RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y);
RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y); RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y);
RValue<UInt4> MulHigh(RValue<UInt4> x, RValue<UInt4> y); RValue<UInt4> MulHigh(RValue<UInt4> x, RValue<UInt4> y);
RValue<UInt> Extract(RValue<UInt4> val, int i);
RValue<UInt4> Insert(RValue<UInt4> val, RValue<UInt> element, int i);
// RValue<UInt4> RoundInt(RValue<Float4> cast); // RValue<UInt4> RoundInt(RValue<Float4> cast);
class Half : public LValue<Half> class Half : public LValue<Half>
......
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