Files
2024-02-26 19:00:48 +01:00

125 lines
3.0 KiB
C++

// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
#include "Half.h"
#include "Vector4.h"
#include "Rectangle.h"
#include "Color.h"
static_assert(sizeof(Half) == 2, "Invalid Half type size.");
static_assert(sizeof(Half2) == 4, "Invalid Half2 type size.");
static_assert(sizeof(Half3) == 6, "Invalid Half3 type size.");
static_assert(sizeof(Half4) == 8, "Invalid Half4 type size.");
Half2 Half2::Zero(0.0f, 0.0f);
Half3 Half3::Zero(0.0f, 0.0f, 0.0f);
Half4 Half4::Zero(0.0f, 0.0f, 0.0f, 0.0f);
#if !USE_SSE_HALF_CONVERSION
Half Float16Compressor::Compress(float value)
{
Bits v, s;
v.f = value;
uint32 sign = v.si & signN;
v.si ^= sign;
sign >>= shiftSign; // logical shift
s.si = mulN;
s.si = static_cast<int32>(s.f * v.f); // correct subnormals
v.si ^= (s.si ^ v.si) & -(minN > v.si);
v.si ^= (infN ^ v.si) & -((infN > v.si) & (v.si > maxN));
v.si ^= (nanN ^ v.si) & -((nanN > v.si) & (v.si > infN));
v.ui >>= shift; // logical shift
v.si ^= ((v.si - maxD) ^ v.si) & -(v.si > maxC);
v.si ^= ((v.si - minD) ^ v.si) & -(v.si > subC);
return v.ui | sign;
}
float Float16Compressor::Decompress(Half value)
{
Bits v;
v.ui = value;
int32 sign = v.si & signC;
v.si ^= sign;
sign <<= shiftSign;
v.si ^= ((v.si + minD) ^ v.si) & -(v.si > subC);
v.si ^= ((v.si + maxD) ^ v.si) & -(v.si > maxC);
Bits s;
s.si = mulC;
s.f *= v.si;
const int32 mask = -(norC > v.si);
v.si <<= shift;
v.si ^= (s.si ^ v.si) & mask;
v.si |= sign;
return v.f;
}
#endif
Float2 Half2::ToFloat2() const
{
return Float2(
Float16Compressor::Decompress(X),
Float16Compressor::Decompress(Y)
);
}
Float3 Half3::ToFloat3() const
{
return Float3(
Float16Compressor::Decompress(X),
Float16Compressor::Decompress(Y),
Float16Compressor::Decompress(Z)
);
}
Half4::Half4(const Float4& v)
{
X = Float16Compressor::Compress(v.X);
Y = Float16Compressor::Compress(v.Y);
Z = Float16Compressor::Compress(v.Z);
W = Float16Compressor::Compress(v.W);
}
Half4::Half4(const Color& c)
{
X = Float16Compressor::Compress(c.R);
Y = Float16Compressor::Compress(c.G);
Z = Float16Compressor::Compress(c.B);
W = Float16Compressor::Compress(c.A);
}
Half4::Half4(const Rectangle& rect)
{
X = Float16Compressor::Compress(rect.Location.X);
Y = Float16Compressor::Compress(rect.Location.Y);
Z = Float16Compressor::Compress(rect.Size.X);
W = Float16Compressor::Compress(rect.Size.Y);
}
Float2 Half4::ToFloat2() const
{
return Float2(
Float16Compressor::Decompress(X),
Float16Compressor::Decompress(Y)
);
}
Float3 Half4::ToFloat3() const
{
return Float3(
Float16Compressor::Decompress(X),
Float16Compressor::Decompress(Y),
Float16Compressor::Decompress(Z)
);
}
Float4 Half4::ToFloat4() const
{
return Float4(
Float16Compressor::Decompress(X),
Float16Compressor::Decompress(Y),
Float16Compressor::Decompress(Z),
Float16Compressor::Decompress(W)
);
}