diff --git a/Source/Engine/Core/Math/Color.h b/Source/Engine/Core/Math/Color.h index af93fc0f2..836ead090 100644 --- a/Source/Engine/Core/Math/Color.h +++ b/Source/Engine/Core/Math/Color.h @@ -71,7 +71,7 @@ public: /// The green channel value. /// The blue channel value. /// The alpha channel value. - Color(float r, float g, float b, float a = 1) + FORCE_INLINE Color(float r, float g, float b, float a = 1) : R(r) , G(g) , B(b) @@ -203,7 +203,7 @@ public: return Color(R - b.R, G - b.G, B - b.B, A - b.A); } - Color operator*(const Color& b) const + FORCE_INLINE Color operator*(const Color& b) const { return Color(R * b.R, G * b.G, B * b.B, A * b.A); } diff --git a/Source/Engine/Core/Math/Half.cpp b/Source/Engine/Core/Math/Half.cpp index 4e4b6eb50..b3c1696a5 100644 --- a/Source/Engine/Core/Math/Half.cpp +++ b/Source/Engine/Core/Math/Half.cpp @@ -1,10 +1,8 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #include "Half.h" -#include "Rectangle.h" -#include "Vector2.h" -#include "Vector3.h" #include "Vector4.h" +#include "Rectangle.h" #include "Color.h" static_assert(sizeof(Half) == 2, "Invalid Half type size."); @@ -16,12 +14,47 @@ 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); -Half2::Half2(const Float2& v) +#if !USE_SSE_HALF_CONVERSION + +Half Float16Compressor::Compress(float value) { - X = Float16Compressor::Compress(v.X); - Y = Float16Compressor::Compress(v.Y); + 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(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( @@ -30,13 +63,6 @@ Float2 Half2::ToFloat2() const ); } -Half3::Half3(const Float3& v) -{ - X = Float16Compressor::Compress(v.X); - Y = Float16Compressor::Compress(v.Y); - Z = Float16Compressor::Compress(v.Z); -} - Float3 Half3::ToFloat3() const { return Float3( diff --git a/Source/Engine/Core/Math/Half.h b/Source/Engine/Core/Math/Half.h index 346b5d6b3..44b90df66 100644 --- a/Source/Engine/Core/Math/Half.h +++ b/Source/Engine/Core/Math/Half.h @@ -3,6 +3,8 @@ #pragma once #include "Math.h" +#include "Vector2.h" +#include "Vector3.h" /// /// Half-precision 16 bit floating point number consisting of a sign bit, a 5 bit biased exponent, and a 10 bit mantissa @@ -45,54 +47,23 @@ class FLAXENGINE_API Float16Compressor static const int32 minD = minC - subC - 1; public: - static Half Compress(const float value) - { #if USE_SSE_HALF_CONVERSION + FORCE_INLINE static Half Compress(float value) + { __m128 value1 = _mm_set_ss(value); __m128i value2 = _mm_cvtps_ph(value1, 0); return static_cast(_mm_cvtsi128_si32(value2)); -#else - 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(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; -#endif } - - static float Decompress(const Half value) + FORCE_INLINE static float Decompress(Half value) { -#if USE_SSE_HALF_CONVERSION __m128i value1 = _mm_cvtsi32_si128(static_cast(value)); __m128 value2 = _mm_cvtph_ps(value1); return _mm_cvtss_f32(value2); -#else - 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 } +#else + static Half Compress(float value); + static float Decompress(Half value); +#endif }; /// @@ -128,7 +99,7 @@ public: /// /// X component /// Y component - Half2(Half x, Half y) + FORCE_INLINE Half2(Half x, Half y) : X(x) , Y(y) { @@ -139,7 +110,7 @@ public: /// /// X component /// Y component - Half2(float x, float y) + FORCE_INLINE Half2(float x, float y) { X = Float16Compressor::Compress(x); Y = Float16Compressor::Compress(y); @@ -149,7 +120,11 @@ public: /// Init /// /// X and Y components - Half2(const Float2& v); + FORCE_INLINE Half2(const Float2& v) + { + X = Float16Compressor::Compress(v.X); + Y = Float16Compressor::Compress(v.Y); + } public: Float2 ToFloat2() const; @@ -185,21 +160,26 @@ public: public: Half3() = default; - Half3(Half x, Half y, Half z) + FORCE_INLINE Half3(Half x, Half y, Half z) : X(x) , Y(y) , Z(z) { } - Half3(const float x, const float y, const float z) + FORCE_INLINE Half3(float x, float y, float z) { X = Float16Compressor::Compress(x); Y = Float16Compressor::Compress(y); Z = Float16Compressor::Compress(z); } - Half3(const Float3& v); + FORCE_INLINE Half3(const Float3& v) + { + X = Float16Compressor::Compress(v.X); + Y = Float16Compressor::Compress(v.Y); + Z = Float16Compressor::Compress(v.Z); + } public: Float3 ToFloat3() const;