summaryrefslogtreecommitdiff
path: root/source/core/slang-math.h
diff options
context:
space:
mode:
authorEllie Hermaszewska <ellieh@nvidia.com>2024-10-29 14:49:26 +0800
committerGitHub <noreply@github.com>2024-10-29 14:49:26 +0800
commitf65d756bff8d4c5cbc15bd0322a2ae8e6b896a21 (patch)
treeea1d61342cd29368e19135000ec2948813096205 /source/core/slang-math.h
parenta729c15e9dce9f5116a38afc66329ab2ca4cea54 (diff)
format
* format * Minor test fixes * enable checking cpp format in ci
Diffstat (limited to 'source/core/slang-math.h')
-rw-r--r--source/core/slang-math.h460
1 files changed, 234 insertions, 226 deletions
diff --git a/source/core/slang-math.h b/source/core/slang-math.h
index 51ada76a9..e977dc37d 100644
--- a/source/core/slang-math.h
+++ b/source/core/slang-math.h
@@ -2,264 +2,272 @@
#define SLANG_CORE_MATH_H
#include "slang.h"
+
#include <cmath>
namespace Slang
{
- // Some handy constants
+// Some handy constants
- // The largest positive (or negative) number
-# define SLANG_HALF_MAX 65504.0f
- // Smallest (denormalized) value. 1 / 2^24
-# define SLANG_HALF_SUB_NORMAL_MIN (1.0f / 16777216.0f)
+// The largest positive (or negative) number
+#define SLANG_HALF_MAX 65504.0f
+// Smallest (denormalized) value. 1 / 2^24
+#define SLANG_HALF_SUB_NORMAL_MIN (1.0f / 16777216.0f)
- class Math
- {
- public:
- // Use to fix type punning issues with strict aliasing
- union FloatIntUnion
- {
- float fvalue;
- int ivalue;
+class Math
+{
+public:
+ // Use to fix type punning issues with strict aliasing
+ union FloatIntUnion
+ {
+ float fvalue;
+ int ivalue;
- SLANG_FORCE_INLINE static FloatIntUnion makeFromInt(int i) { FloatIntUnion cast; cast.ivalue = i; return cast; }
- SLANG_FORCE_INLINE static FloatIntUnion makeFromFloat(float f) { FloatIntUnion cast; cast.fvalue = f; return cast; }
- };
- union DoubleInt64Union
+ SLANG_FORCE_INLINE static FloatIntUnion makeFromInt(int i)
{
- double dvalue;
- int64_t ivalue;
- SLANG_FORCE_INLINE static DoubleInt64Union makeFromInt64(int64_t i) { DoubleInt64Union cast; cast.ivalue = i; return cast; }
- SLANG_FORCE_INLINE static DoubleInt64Union makeFromDouble(double d) { DoubleInt64Union cast; cast.dvalue = d; return cast; }
- };
-
- static const float Pi;
-
- template <typename T>
- static T Abs(T a)
+ FloatIntUnion cast;
+ cast.ivalue = i;
+ return cast;
+ }
+ SLANG_FORCE_INLINE static FloatIntUnion makeFromFloat(float f)
+ {
+ FloatIntUnion cast;
+ cast.fvalue = f;
+ return cast;
+ }
+ };
+ union DoubleInt64Union
+ {
+ double dvalue;
+ int64_t ivalue;
+ SLANG_FORCE_INLINE static DoubleInt64Union makeFromInt64(int64_t i)
{
- return (a < 0) ? -a : a;
+ DoubleInt64Union cast;
+ cast.ivalue = i;
+ return cast;
}
+ SLANG_FORCE_INLINE static DoubleInt64Union makeFromDouble(double d)
+ {
+ DoubleInt64Union cast;
+ cast.dvalue = d;
+ return cast;
+ }
+ };
- template<typename T>
- static T Min(const T& v1, const T&v2)
- {
- return v1<v2?v1:v2;
- }
- template<typename T>
- static T Max(const T& v1, const T&v2)
- {
- return v1>v2?v1:v2;
- }
- template<typename T>
- static T Min(const T& v1, const T&v2, const T&v3)
- {
- return Min(v1, Min(v2, v3));
- }
- template<typename T>
- static T Max(const T& v1, const T&v2, const T&v3)
- {
- return Max(v1, Max(v2, v3));
- }
- template<typename T>
- static T Clamp(const T& val, const T& vmin, const T&vmax)
- {
- if (val < vmin) return vmin;
- else if (val > vmax) return vmax;
- else return val;
- }
+ static const float Pi;
- static inline int FastFloor(float x)
- {
- int i = (int)x;
- return i - (i > x);
- }
+ template<typename T>
+ static T Abs(T a)
+ {
+ return (a < 0) ? -a : a;
+ }
- static inline int FastFloor(double x)
- {
- int i = (int)x;
- return i - (i > x);
- }
+ template<typename T>
+ static T Min(const T& v1, const T& v2)
+ {
+ return v1 < v2 ? v1 : v2;
+ }
+ template<typename T>
+ static T Max(const T& v1, const T& v2)
+ {
+ return v1 > v2 ? v1 : v2;
+ }
+ template<typename T>
+ static T Min(const T& v1, const T& v2, const T& v3)
+ {
+ return Min(v1, Min(v2, v3));
+ }
+ template<typename T>
+ static T Max(const T& v1, const T& v2, const T& v3)
+ {
+ return Max(v1, Max(v2, v3));
+ }
+ template<typename T>
+ static T Clamp(const T& val, const T& vmin, const T& vmax)
+ {
+ if (val < vmin)
+ return vmin;
+ else if (val > vmax)
+ return vmax;
+ else
+ return val;
+ }
- static inline int IsNaN(float x)
- {
- return std::isnan(x);
- }
+ static inline int FastFloor(float x)
+ {
+ int i = (int)x;
+ return i - (i > x);
+ }
- static inline int IsInf(float x)
- {
- return std::isinf(x);
- }
+ static inline int FastFloor(double x)
+ {
+ int i = (int)x;
+ return i - (i > x);
+ }
- static inline unsigned int Ones32(unsigned int x)
- {
- /* 32-bit recursive reduction using SWAR...
- but first step is mapping 2-bit values
- into sum of 2 1-bit values in sneaky way
- */
- x -= ((x >> 1) & 0x55555555);
- x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
- x = (((x >> 4) + x) & 0x0f0f0f0f);
- x += (x >> 8);
- x += (x >> 16);
- return(x & 0x0000003f);
- }
+ static inline int IsNaN(float x) { return std::isnan(x); }
- static inline unsigned int Log2Floor(unsigned int x)
- {
- x |= (x >> 1);
- x |= (x >> 2);
- x |= (x >> 4);
- x |= (x >> 8);
- x |= (x >> 16);
- return(Ones32(x >> 1));
- }
+ static inline int IsInf(float x) { return std::isinf(x); }
- static inline unsigned int Log2Ceil(unsigned int x)
- {
- int y = (x & (x - 1));
- y |= -y;
- y >>= (32 - 1);
- x |= (x >> 1);
- x |= (x >> 2);
- x |= (x >> 4);
- x |= (x >> 8);
- x |= (x >> 16);
- return(Ones32(x >> 1) - y);
- }
- /*
- static inline int Log2(float x)
- {
- unsigned int ix = (unsigned int&)x;
- unsigned int exp = (ix >> 23) & 0xFF;
- int log2 = (unsigned int)(exp) - 127;
+ static inline unsigned int Ones32(unsigned int x)
+ {
+ /* 32-bit recursive reduction using SWAR...
+ but first step is mapping 2-bit values
+ into sum of 2 1-bit values in sneaky way
+ */
+ x -= ((x >> 1) & 0x55555555);
+ x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
+ x = (((x >> 4) + x) & 0x0f0f0f0f);
+ x += (x >> 8);
+ x += (x >> 16);
+ return (x & 0x0000003f);
+ }
- return log2;
- }
- */
+ static inline unsigned int Log2Floor(unsigned int x)
+ {
+ x |= (x >> 1);
+ x |= (x >> 2);
+ x |= (x >> 4);
+ x |= (x >> 8);
+ x |= (x >> 16);
+ return (Ones32(x >> 1));
+ }
- static bool AreNearlyEqual(double a, double b, double epsilon)
- {
- // If they are equal then we are done
- if (a == b)
- {
- return true;
- }
+ static inline unsigned int Log2Ceil(unsigned int x)
+ {
+ int y = (x & (x - 1));
+ y |= -y;
+ y >>= (32 - 1);
+ x |= (x >> 1);
+ x |= (x >> 2);
+ x |= (x >> 4);
+ x |= (x >> 8);
+ x |= (x >> 16);
+ return (Ones32(x >> 1) - y);
+ }
+ /*
+ static inline int Log2(float x)
+ {
+ unsigned int ix = (unsigned int&)x;
+ unsigned int exp = (ix >> 23) & 0xFF;
+ int log2 = (unsigned int)(exp) - 127;
- const double absA = Abs(a);
- const double absB = Abs(b);
- const double diff = Abs(a - b);
+ return log2;
+ }
+ */
- // https://en.wikipedia.org/wiki/Double_precision_floating-point_format
- const double minNormal = 2.2250738585072014e-308;
- // Either a or b are very close to being zero, so doing relative comparison isn't really appropriate
- if (a == 0.0 || b == 0.0 || (absA + absB < minNormal))
- {
- return diff < (epsilon * minNormal);
- }
- else
- {
- // Calculate a relative relative error
- return diff < epsilon * (absA + absB);
- }
+ static bool AreNearlyEqual(double a, double b, double epsilon)
+ {
+ // If they are equal then we are done
+ if (a == b)
+ {
+ return true;
}
- template <typename T>
- static T getLowestBit(T val)
+ const double absA = Abs(a);
+ const double absB = Abs(b);
+ const double diff = Abs(a - b);
+
+ // https://en.wikipedia.org/wiki/Double_precision_floating-point_format
+ const double minNormal = 2.2250738585072014e-308;
+ // Either a or b are very close to being zero, so doing relative comparison isn't really
+ // appropriate
+ if (a == 0.0 || b == 0.0 || (absA + absB < minNormal))
+ {
+ return diff < (epsilon * minNormal);
+ }
+ else
{
- return val & (-val);
+ // Calculate a relative relative error
+ return diff < epsilon * (absA + absB);
}
- };
- inline int FloatAsInt(float val)
- {
- return Math::FloatIntUnion::makeFromFloat(val).ivalue;
- }
- inline float IntAsFloat(int val)
- {
- return Math::FloatIntUnion::makeFromInt(val).fvalue;
- }
+ }
+
+ template<typename T>
+ static T getLowestBit(T val)
+ {
+ return val & (-val);
+ }
+};
+inline int FloatAsInt(float val)
+{
+ return Math::FloatIntUnion::makeFromFloat(val).ivalue;
+}
+inline float IntAsFloat(int val)
+{
+ return Math::FloatIntUnion::makeFromInt(val).fvalue;
+}
- SLANG_FORCE_INLINE int64_t DoubleAsInt64(double val)
+SLANG_FORCE_INLINE int64_t DoubleAsInt64(double val)
+{
+ return Math::DoubleInt64Union::makeFromDouble(val).ivalue;
+}
+SLANG_FORCE_INLINE double Int64AsDouble(int64_t value)
+{
+ return Math::DoubleInt64Union::makeFromInt64(value).dvalue;
+}
+
+inline unsigned short FloatToHalf(float val)
+{
+ const auto x = FloatAsInt(val);
+
+ unsigned short bits = (x >> 16) & 0x8000;
+ unsigned short m = (x >> 12) & 0x07ff;
+ unsigned int e = (x >> 23) & 0xff;
+ if (e < 103)
+ return bits;
+ if (e > 142)
{
- return Math::DoubleInt64Union::makeFromDouble(val).ivalue;
+ bits |= 0x7c00u;
+ bits |= e == 255 && (x & 0x007fffffu);
+ return bits;
}
- SLANG_FORCE_INLINE double Int64AsDouble(int64_t value)
+ if (e < 113)
{
- return Math::DoubleInt64Union::makeFromInt64(value).dvalue;
+ m |= 0x0800u;
+ bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1);
+ return bits;
}
+ bits |= ((e - 112) << 10) | (m >> 1);
+ bits += m & 1;
+ return bits;
+}
- inline unsigned short FloatToHalf(float val)
- {
- const auto x = FloatAsInt(val);
-
- unsigned short bits = (x >> 16) & 0x8000;
- unsigned short m = (x >> 12) & 0x07ff;
- unsigned int e = (x >> 23) & 0xff;
- if (e < 103)
- return bits;
- if (e > 142)
- {
- bits |= 0x7c00u;
- bits |= e == 255 && (x & 0x007fffffu);
- return bits;
- }
- if (e < 113)
- {
- m |= 0x0800u;
- bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1);
- return bits;
- }
- bits |= ((e - 112) << 10) | (m >> 1);
- bits += m & 1;
- return bits;
- }
+inline float HalfToFloat(unsigned short input)
+{
+ static const auto magic = Math::FloatIntUnion::makeFromInt((127 + (127 - 15)) << 23);
+ static const auto was_infnan = Math::FloatIntUnion::makeFromInt((127 + 16) << 23);
+ Math::FloatIntUnion o;
+ o.ivalue = (input & 0x7fff) << 13; // exponent/mantissa bits
+ o.fvalue *= magic.fvalue; // exponent adjust
+ if (o.fvalue >= was_infnan.fvalue) // make sure Inf/NaN survive
+ o.ivalue |= 255 << 23;
+ o.ivalue |= (input & 0x8000) << 16; // sign bit
+ return o.fvalue;
+}
- inline float HalfToFloat(unsigned short input)
- {
- static const auto magic = Math::FloatIntUnion::makeFromInt((127 + (127 - 15)) << 23);
- static const auto was_infnan = Math::FloatIntUnion::makeFromInt((127 + 16) << 23);
- Math::FloatIntUnion o;
- o.ivalue = (input & 0x7fff) << 13; // exponent/mantissa bits
- o.fvalue *= magic.fvalue; // exponent adjust
- if (o.fvalue >= was_infnan.fvalue) // make sure Inf/NaN survive
- o.ivalue |= 255 << 23;
- o.ivalue |= (input & 0x8000) << 16; // sign bit
- return o.fvalue;
- }
+class Random
+{
+private:
+ unsigned int seed;
- class Random
- {
- private:
- unsigned int seed;
- public:
- Random(int seed)
- {
- this->seed = seed;
- }
- int Next() // random between 0 and RandMax (currently 0x7fff)
- {
- return ((seed = ((seed << 12) + 150889L) % 714025) & 0x7fff);
- }
- int Next(int min, int max) // inclusive min, exclusive max
- {
- unsigned int a = ((seed = ((seed << 12) + 150889L) % 714025) & 0xFFFF);
- unsigned int b = ((seed = ((seed << 12) + 150889L) % 714025) & 0xFFFF);
- unsigned int r = (a << 16) + b;
- return min + r % (max - min);
- }
- float NextFloat()
- {
- return ((Next() << 15) + Next()) / ((float)(1 << 30));
- }
- float NextFloat(float valMin, float valMax)
- {
- return valMin + (valMax - valMin) * NextFloat();
- }
- static int RandMax()
- {
- return 0x7fff;
- }
- };
-}
+public:
+ Random(int seed) { this->seed = seed; }
+ int Next() // random between 0 and RandMax (currently 0x7fff)
+ {
+ return ((seed = ((seed << 12) + 150889L) % 714025) & 0x7fff);
+ }
+ int Next(int min, int max) // inclusive min, exclusive max
+ {
+ unsigned int a = ((seed = ((seed << 12) + 150889L) % 714025) & 0xFFFF);
+ unsigned int b = ((seed = ((seed << 12) + 150889L) % 714025) & 0xFFFF);
+ unsigned int r = (a << 16) + b;
+ return min + r % (max - min);
+ }
+ float NextFloat() { return ((Next() << 15) + Next()) / ((float)(1 << 30)); }
+ float NextFloat(float valMin, float valMax) { return valMin + (valMax - valMin) * NextFloat(); }
+ static int RandMax() { return 0x7fff; }
+};
+} // namespace Slang
-#endif
+#endif