Optimize Half2 conversion in Render2D
This commit is contained in:
@@ -71,7 +71,7 @@ public:
|
|||||||
/// <param name="g">The green channel value.</param>
|
/// <param name="g">The green channel value.</param>
|
||||||
/// <param name="b">The blue channel value.</param>
|
/// <param name="b">The blue channel value.</param>
|
||||||
/// <param name="a">The alpha channel value.</param>
|
/// <param name="a">The alpha channel value.</param>
|
||||||
Color(float r, float g, float b, float a = 1)
|
FORCE_INLINE Color(float r, float g, float b, float a = 1)
|
||||||
: R(r)
|
: R(r)
|
||||||
, G(g)
|
, G(g)
|
||||||
, B(b)
|
, B(b)
|
||||||
@@ -203,7 +203,7 @@ public:
|
|||||||
return Color(R - b.R, G - b.G, B - b.B, A - b.A);
|
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);
|
return Color(R * b.R, G * b.G, B * b.B, A * b.A);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
#include "Half.h"
|
#include "Half.h"
|
||||||
#include "Rectangle.h"
|
|
||||||
#include "Vector2.h"
|
|
||||||
#include "Vector3.h"
|
|
||||||
#include "Vector4.h"
|
#include "Vector4.h"
|
||||||
|
#include "Rectangle.h"
|
||||||
#include "Color.h"
|
#include "Color.h"
|
||||||
|
|
||||||
static_assert(sizeof(Half) == 2, "Invalid Half type size.");
|
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);
|
Half3 Half3::Zero(0.0f, 0.0f, 0.0f);
|
||||||
Half4 Half4::Zero(0.0f, 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);
|
Bits v, s;
|
||||||
Y = Float16Compressor::Compress(v.Y);
|
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
|
Float2 Half2::ToFloat2() const
|
||||||
{
|
{
|
||||||
return Float2(
|
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
|
Float3 Half3::ToFloat3() const
|
||||||
{
|
{
|
||||||
return Float3(
|
return Float3(
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Math.h"
|
#include "Math.h"
|
||||||
|
#include "Vector2.h"
|
||||||
|
#include "Vector3.h"
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Half-precision 16 bit floating point number consisting of a sign bit, a 5 bit biased exponent, and a 10 bit mantissa
|
/// 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;
|
static const int32 minD = minC - subC - 1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Half Compress(const float value)
|
|
||||||
{
|
|
||||||
#if USE_SSE_HALF_CONVERSION
|
#if USE_SSE_HALF_CONVERSION
|
||||||
|
FORCE_INLINE static Half Compress(float value)
|
||||||
|
{
|
||||||
__m128 value1 = _mm_set_ss(value);
|
__m128 value1 = _mm_set_ss(value);
|
||||||
__m128i value2 = _mm_cvtps_ph(value1, 0);
|
__m128i value2 = _mm_cvtps_ph(value1, 0);
|
||||||
return static_cast<Half>(_mm_cvtsi128_si32(value2));
|
return static_cast<Half>(_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<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;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
FORCE_INLINE static float Decompress(Half value)
|
||||||
static float Decompress(const Half value)
|
|
||||||
{
|
{
|
||||||
#if USE_SSE_HALF_CONVERSION
|
|
||||||
__m128i value1 = _mm_cvtsi32_si128(static_cast<int>(value));
|
__m128i value1 = _mm_cvtsi32_si128(static_cast<int>(value));
|
||||||
__m128 value2 = _mm_cvtph_ps(value1);
|
__m128 value2 = _mm_cvtph_ps(value1);
|
||||||
return _mm_cvtss_f32(value2);
|
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
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -128,7 +99,7 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="x">X component</param>
|
/// <param name="x">X component</param>
|
||||||
/// <param name="y">Y component</param>
|
/// <param name="y">Y component</param>
|
||||||
Half2(Half x, Half y)
|
FORCE_INLINE Half2(Half x, Half y)
|
||||||
: X(x)
|
: X(x)
|
||||||
, Y(y)
|
, Y(y)
|
||||||
{
|
{
|
||||||
@@ -139,7 +110,7 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="x">X component</param>
|
/// <param name="x">X component</param>
|
||||||
/// <param name="y">Y component</param>
|
/// <param name="y">Y component</param>
|
||||||
Half2(float x, float y)
|
FORCE_INLINE Half2(float x, float y)
|
||||||
{
|
{
|
||||||
X = Float16Compressor::Compress(x);
|
X = Float16Compressor::Compress(x);
|
||||||
Y = Float16Compressor::Compress(y);
|
Y = Float16Compressor::Compress(y);
|
||||||
@@ -149,7 +120,11 @@ public:
|
|||||||
/// Init
|
/// Init
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="v">X and Y components</param>
|
/// <param name="v">X and Y components</param>
|
||||||
Half2(const Float2& v);
|
FORCE_INLINE Half2(const Float2& v)
|
||||||
|
{
|
||||||
|
X = Float16Compressor::Compress(v.X);
|
||||||
|
Y = Float16Compressor::Compress(v.Y);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Float2 ToFloat2() const;
|
Float2 ToFloat2() const;
|
||||||
@@ -185,21 +160,26 @@ public:
|
|||||||
public:
|
public:
|
||||||
Half3() = default;
|
Half3() = default;
|
||||||
|
|
||||||
Half3(Half x, Half y, Half z)
|
FORCE_INLINE Half3(Half x, Half y, Half z)
|
||||||
: X(x)
|
: X(x)
|
||||||
, Y(y)
|
, Y(y)
|
||||||
, Z(z)
|
, 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);
|
X = Float16Compressor::Compress(x);
|
||||||
Y = Float16Compressor::Compress(y);
|
Y = Float16Compressor::Compress(y);
|
||||||
Z = Float16Compressor::Compress(z);
|
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:
|
public:
|
||||||
Float3 ToFloat3() const;
|
Float3 ToFloat3() const;
|
||||||
|
|||||||
Reference in New Issue
Block a user