From 58c369e025e5a7c4402a84e6c201db264b7179df Mon Sep 17 00:00:00 2001 From: Leonetienne Date: Thu, 20 Jan 2022 23:09:53 +0100 Subject: [PATCH] Improved g++ compatibility. Still not tested well enough. --- Eule/Eule.vcxproj | 1 + Eule/Eule.vcxproj.filters | 3 +++ Eule/Quaternion.cpp | 3 +++ Eule/Random.cpp | 2 +- Eule/Vector2.cpp | 26 +++++++++++++++++++++++--- Eule/Vector3.cpp | 26 ++++++++++++++++++++++++++ Eule/Vector4.cpp | 24 +++++++++++++++++++++++- Eule/gcccompat.h | 35 +++++++++++++++++++++++++++++++++++ 8 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 Eule/gcccompat.h diff --git a/Eule/Eule.vcxproj b/Eule/Eule.vcxproj index ae09deb..81d84de 100644 --- a/Eule/Eule.vcxproj +++ b/Eule/Eule.vcxproj @@ -32,6 +32,7 @@ + diff --git a/Eule/Eule.vcxproj.filters b/Eule/Eule.vcxproj.filters index 545d178..dbb8ce2 100644 --- a/Eule/Eule.vcxproj.filters +++ b/Eule/Eule.vcxproj.filters @@ -80,5 +80,8 @@ Headerdateien + + Headerdateien + \ No newline at end of file diff --git a/Eule/Quaternion.cpp b/Eule/Quaternion.cpp index 6d4d305..eff9938 100644 --- a/Eule/Quaternion.cpp +++ b/Eule/Quaternion.cpp @@ -1,9 +1,12 @@ #include "Quaternion.h" #include "Constants.h" +#include +#include //#define _EULE_NO_INTRINSICS_ #ifndef _EULE_NO_INTRINSICS_ #include +#include "gcccompat.h" #endif using namespace Eule; diff --git a/Eule/Random.cpp b/Eule/Random.cpp index 8a634cc..375a4bc 100644 --- a/Eule/Random.cpp +++ b/Eule/Random.cpp @@ -1,5 +1,5 @@ #include "Random.h" -#include +#include using namespace Eule; diff --git a/Eule/Vector2.cpp b/Eule/Vector2.cpp index dcfb857..1bbd831 100644 --- a/Eule/Vector2.cpp +++ b/Eule/Vector2.cpp @@ -19,6 +19,7 @@ using namespace Eule; */ // Good, optimized chad version for doubles +template<> double Vector2::DotProduct(const Vector2& other) const { #ifndef _EULE_NO_INTRINSICS_ @@ -44,6 +45,7 @@ double Vector2::DotProduct(const Vector2& other) const } // Slow, lame version for intcels +template<> double Vector2::DotProduct(const Vector2& other) const { int iDot = (x * other.x) + @@ -55,6 +57,7 @@ double Vector2::DotProduct(const Vector2& other) const // Good, optimized chad version for doubles +template<> double Vector2::CrossProduct(const Vector2& other) const { return (x * other.y) - @@ -62,6 +65,7 @@ double Vector2::CrossProduct(const Vector2& other) const } // Slow, lame version for intcels +template<> double Vector2::CrossProduct(const Vector2& other) const { int iCross = (x * other.y) - @@ -73,6 +77,7 @@ double Vector2::CrossProduct(const Vector2& other) const // Good, optimized chad version for doubles +template<> double Vector2::SqrMagnitude() const { // x.DotProduct(x) == x.SqrMagnitude() @@ -80,6 +85,7 @@ double Vector2::SqrMagnitude() const } // Slow, lame version for intcels +template<> double Vector2::SqrMagnitude() const { int iSqrMag = x*x + y*y; @@ -93,7 +99,7 @@ double Vector2::Magnitude() const } - +template<> Vector2 Vector2::VectorScale(const Vector2& scalar) const { #ifndef _EULE_NO_INTRINSICS_ @@ -124,6 +130,7 @@ Vector2 Vector2::VectorScale(const Vector2& scalar) cons #endif } +template<> Vector2 Vector2::VectorScale(const Vector2& scalar) const { return Vector2( @@ -143,6 +150,7 @@ Vector2 Vector2::Normalize() const } // Method to normalize a Vector2d +template<> void Vector2::NormalizeSelf() { double length = Magnitude(); @@ -184,6 +192,7 @@ void Vector2::NormalizeSelf() // You can't normalize an int vector, ffs! // But we need an implementation for T=int +template<> void Vector2::NormalizeSelf() { std::cerr << "Stop normalizing int-vectors!!" << std::endl; @@ -195,6 +204,7 @@ void Vector2::NormalizeSelf() // Good, optimized chad version for doubles +template<> void Vector2::LerpSelf(const Vector2& other, double t) { const double it = 1.0 - t; // Inverse t @@ -235,6 +245,7 @@ void Vector2::LerpSelf(const Vector2& other, double t) // Slow, lame version for intcels +template<> void Vector2::LerpSelf(const Vector2& other, double t) { const double it = 1.0 - t; // Inverse t @@ -245,6 +256,7 @@ void Vector2::LerpSelf(const Vector2& other, double t) return; } +template<> Vector2 Vector2::Lerp(const Vector2& other, double t) const { Vector2d copy(*this); @@ -253,6 +265,7 @@ Vector2 Vector2::Lerp(const Vector2& other, double t) co return copy; } +template<> Vector2 Vector2::Lerp(const Vector2& other, double t) const { Vector2d copy(this->ToDouble()); @@ -312,7 +325,7 @@ Vector2 Vector2::ToDouble() const return Vector2((double)x, (double)y); } - +template<> Vector2 Vector2::operator+(const Vector2& other) const { #ifndef _EULE_NO_INTRINSICS_ @@ -353,6 +366,7 @@ Vector2 Vector2::operator+(const Vector2& other) const +template<> void Vector2::operator+=(const Vector2& other) { #ifndef _EULE_NO_INTRINSICS_ @@ -391,6 +405,7 @@ void Vector2::operator+=(const Vector2& other) +template<> Vector2 Vector2::operator-(const Vector2& other) const { #ifndef _EULE_NO_INTRINSICS_ @@ -431,6 +446,7 @@ Vector2 Vector2::operator-(const Vector2& other) const +template<> void Vector2::operator-=(const Vector2& other) { #ifndef _EULE_NO_INTRINSICS_ @@ -469,6 +485,7 @@ void Vector2::operator-=(const Vector2& other) +template<> Vector2 Vector2::operator*(const double scale) const { #ifndef _EULE_NO_INTRINSICS_ @@ -510,6 +527,7 @@ Vector2 Vector2::operator*(const T scale) const +template<> void Vector2::operator*=(const double scale) { #ifndef _EULE_NO_INTRINSICS_ @@ -548,6 +566,7 @@ void Vector2::operator*=(const T scale) +template<> Vector2 Vector2::operator/(const double scale) const { #ifndef _EULE_NO_INTRINSICS_ @@ -589,6 +608,7 @@ Vector2 Vector2::operator/(const T scale) const +template<> void Vector2::operator/=(const double scale) { #ifndef _EULE_NO_INTRINSICS_ @@ -697,4 +717,4 @@ const Vector2 Vector2::left(-1, 0); template const Vector2 Vector2::one(1, 1); template -const Vector2 Vector2::zero(0, 0); \ No newline at end of file +const Vector2 Vector2::zero(0, 0); diff --git a/Eule/Vector3.cpp b/Eule/Vector3.cpp index b40afc1..c8d71ef 100644 --- a/Eule/Vector3.cpp +++ b/Eule/Vector3.cpp @@ -19,6 +19,7 @@ using namespace Eule; */ // Good, optimized chad version for doubles +template<> double Vector3::DotProduct(const Vector3& other) const { #ifndef _EULE_NO_INTRINSICS_ @@ -45,6 +46,7 @@ double Vector3::DotProduct(const Vector3& other) const } // Slow, lame version for intcels +template<> double Vector3::DotProduct(const Vector3& other) const { int iDot = (x * other.x) + (y * other.y) + (z * other.z); @@ -54,6 +56,7 @@ double Vector3::DotProduct(const Vector3& other) const // Good, optimized chad version for doubles +template<> Vector3 Vector3::CrossProduct(const Vector3& other) const { Vector3 cp; @@ -65,6 +68,7 @@ Vector3 Vector3::CrossProduct(const Vector3& other) cons } // Slow, lame version for intcels +template<> Vector3 Vector3::CrossProduct(const Vector3& other) const { Vector3 cp; @@ -78,6 +82,7 @@ Vector3 Vector3::CrossProduct(const Vector3& other) const // Good, optimized chad version for doubles +template<> double Vector3::SqrMagnitude() const { // x.DotProduct(x) == x.SqrMagnitude() @@ -85,6 +90,7 @@ double Vector3::SqrMagnitude() const } // Slow, lame version for intcels +template<> double Vector3::SqrMagnitude() const { int iSqrMag = x*x + y*y + z*z; @@ -99,6 +105,7 @@ double Vector3::Magnitude() const +template<> Vector3 Vector3::VectorScale(const Vector3& scalar) const { #ifndef _EULE_NO_INTRINSICS_ @@ -132,6 +139,7 @@ Vector3 Vector3::VectorScale(const Vector3& scalar) cons #endif } +template<> Vector3 Vector3::VectorScale(const Vector3& scalar) const { return Vector3( @@ -153,6 +161,7 @@ Vector3 Vector3::Normalize() const } // Method to normalize a Vector3d +template<> void Vector3::NormalizeSelf() { const double length = Magnitude(); @@ -197,6 +206,7 @@ void Vector3::NormalizeSelf() // You can't normalize an int vector, ffs! // But we need an implementation for T=int +template<> void Vector3::NormalizeSelf() { std::cerr << "Stop normalizing int-vectors!!" << std::endl; @@ -266,6 +276,7 @@ const T& Vector3::operator[](std::size_t idx) const // Good, optimized chad version for doubles +template<> void Vector3::LerpSelf(const Vector3& other, double t) { const double it = 1.0 - t; // Inverse t @@ -308,6 +319,7 @@ void Vector3::LerpSelf(const Vector3& other, double t) // Slow, lame version for intcels +template<> void Vector3::LerpSelf(const Vector3& other, double t) { const double it = 1.0 - t; // Inverse t @@ -319,6 +331,7 @@ void Vector3::LerpSelf(const Vector3& other, double t) return; } +template<> Vector3 Vector3::Lerp(const Vector3& other, double t) const { Vector3d copy(*this); @@ -327,6 +340,7 @@ Vector3 Vector3::Lerp(const Vector3& other, double t) co return copy; } +template<> Vector3 Vector3::Lerp(const Vector3& other, double t) const { Vector3d copy(this->ToDouble()); @@ -337,6 +351,7 @@ Vector3 Vector3::Lerp(const Vector3& other, double t) const +template<> Vector3 Vector3::operator+(const Vector3& other) const { #ifndef _EULE_NO_INTRINSICS_ @@ -380,6 +395,7 @@ Vector3 Vector3::operator+(const Vector3& other) const +template<> void Vector3::operator+=(const Vector3& other) { #ifndef _EULE_NO_INTRINSICS_ @@ -421,6 +437,7 @@ void Vector3::operator+=(const Vector3& other) +template<> Vector3 Vector3::operator-(const Vector3& other) const { #ifndef _EULE_NO_INTRINSICS_ @@ -464,6 +481,7 @@ Vector3 Vector3::operator-(const Vector3& other) const +template<> void Vector3::operator-=(const Vector3& other) { #ifndef _EULE_NO_INTRINSICS_ @@ -505,6 +523,7 @@ void Vector3::operator-=(const Vector3& other) +template<> Vector3 Vector3::operator*(const double scale) const { #ifndef _EULE_NO_INTRINSICS_ @@ -549,6 +568,7 @@ Vector3 Vector3::operator*(const T scale) const +template<> void Vector3::operator*=(const double scale) { #ifndef _EULE_NO_INTRINSICS_ @@ -590,6 +610,7 @@ void Vector3::operator*=(const T scale) +template<> Vector3 Vector3::operator/(const double scale) const { #ifndef _EULE_NO_INTRINSICS_ @@ -634,6 +655,7 @@ Vector3 Vector3::operator/(const T scale) const +template<> void Vector3::operator/=(const double scale) { #ifndef _EULE_NO_INTRINSICS_ @@ -674,6 +696,7 @@ void Vector3::operator/=(const T scale) // Good, optimized chad version for doubles +template<> Vector3 Vector3::operator*(const Matrix4x4& mat) const { Vector3 newVec; @@ -727,6 +750,7 @@ Vector3 Vector3::operator*(const Matrix4x4& mat) const } // Slow, lame version for intcels +template<> Vector3 Vector3::operator*(const Matrix4x4& mat) const { Vector3 newVec; @@ -751,6 +775,7 @@ Vector3 Vector3::operator*(const Matrix4x4& mat) const // Good, optimized chad version for doubles +template<> void Vector3::operator*=(const Matrix4x4& mat) { #ifndef _EULE_NO_INTRINSICS_ @@ -832,6 +857,7 @@ void Vector3::operator=(Vector3&& other) noexcept } // Slow, lame version for intcels +template<> void Vector3::operator*=(const Matrix4x4& mat) { Vector3 buffer(x, y, z); diff --git a/Eule/Vector4.cpp b/Eule/Vector4.cpp index 850c3bb..2c4a75c 100644 --- a/Eule/Vector4.cpp +++ b/Eule/Vector4.cpp @@ -19,6 +19,7 @@ using namespace Eule; */ // Good, optimized chad version for doubles +template<> double Vector4::SqrMagnitude() const { return (x * x) + @@ -28,6 +29,7 @@ double Vector4::SqrMagnitude() const } // Slow, lame version for intcels +template<> double Vector4::SqrMagnitude() const { int iSqrMag = x*x + y*y + z*z + w*w; @@ -41,6 +43,7 @@ double Vector4::Magnitude() const } +template<> Vector4 Vector4::VectorScale(const Vector4& scalar) const { #ifndef _EULE_NO_INTRINSICS_ @@ -76,6 +79,7 @@ Vector4 Vector4::VectorScale(const Vector4& scalar) cons } +template<> Vector4 Vector4::VectorScale(const Vector4& scalar) const { return Vector4( @@ -97,7 +101,8 @@ Vector4 Vector4::Normalize() const return norm; } -// Method to normalize a Vector43d +// Method to normalize a Vector4d +template<> void Vector4::NormalizeSelf() { double length = Magnitude(); @@ -145,6 +150,7 @@ void Vector4::NormalizeSelf() // You can't normalize an int vector, ffs! // But we need an implementation for T=int +template<> void Vector4::NormalizeSelf() { std::cerr << "Stop normalizing int-vectors!!" << std::endl; @@ -220,6 +226,7 @@ const T& Vector4::operator[](std::size_t idx) const // Good, optimized chad version for doubles +template<> void Vector4::LerpSelf(const Vector4& other, double t) { const double it = 1.0 - t; // Inverse t @@ -264,6 +271,7 @@ void Vector4::LerpSelf(const Vector4& other, double t) // Slow, lame version for intcels +template<> void Vector4::LerpSelf(const Vector4& other, double t) { const double it = 1.0 - t; @@ -276,6 +284,7 @@ void Vector4::LerpSelf(const Vector4& other, double t) return; } +template<> Vector4 Vector4::Lerp(const Vector4& other, double t) const { Vector4d copy(*this); @@ -284,6 +293,7 @@ Vector4 Vector4::Lerp(const Vector4& other, double t) co return copy; } +template<> Vector4 Vector4::Lerp(const Vector4& other, double t) const { Vector4d copy(this->ToDouble()); @@ -294,6 +304,7 @@ Vector4 Vector4::Lerp(const Vector4& other, double t) const +template<> Vector4 Vector4::operator+(const Vector4& other) const { #ifndef _EULE_NO_INTRINSICS_ @@ -340,6 +351,7 @@ Vector4 Vector4::operator+(const Vector4& other) const +template<> void Vector4::operator+=(const Vector4& other) { #ifndef _EULE_NO_INTRINSICS_ @@ -384,6 +396,7 @@ void Vector4::operator+=(const Vector4& other) +template<> Vector4 Vector4::operator-(const Vector4& other) const { #ifndef _EULE_NO_INTRINSICS_ @@ -430,6 +443,7 @@ Vector4 Vector4::operator-(const Vector4& other) const +template<> void Vector4::operator-=(const Vector4& other) { #ifndef _EULE_NO_INTRINSICS_ @@ -474,6 +488,7 @@ void Vector4::operator-=(const Vector4& other) +template<> Vector4 Vector4::operator*(const double scale) const { #ifndef _EULE_NO_INTRINSICS_ @@ -521,6 +536,7 @@ Vector4 Vector4::operator*(const T scale) const +template<> void Vector4::operator*=(const double scale) { #ifndef _EULE_NO_INTRINSICS_ @@ -565,6 +581,7 @@ void Vector4::operator*=(const T scale) +template<> Vector4 Vector4::operator/(const double scale) const { #ifndef _EULE_NO_INTRINSICS_ @@ -612,6 +629,7 @@ Vector4 Vector4::operator/(const T scale) const +template<> void Vector4::operator/=(const double scale) { #ifndef _EULE_NO_INTRINSICS_ @@ -668,6 +686,7 @@ bool Vector4::operator==(const Vector4& other) const // Good, optimized chad version for doubles +template<> Vector4 Vector4::operator*(const Matrix4x4& mat) const { Vector4 newVec; @@ -681,6 +700,7 @@ Vector4 Vector4::operator*(const Matrix4x4& mat) const } // Slow, lame version for intcels +template<> Vector4 Vector4::operator*(const Matrix4x4& mat) const { Vector4 newVec; @@ -701,6 +721,7 @@ Vector4 Vector4::operator*(const Matrix4x4& mat) const // Good, optimized chad version for doubles +template<> void Vector4::operator*=(const Matrix4x4& mat) { Vector4 buffer = *this; @@ -749,6 +770,7 @@ void Vector4::operator=(Vector4&& other) noexcept } // Slow, lame version for intcels +template<> void Vector4::operator*=(const Matrix4x4& mat) { Vector4 buffer(x, y, z, w); diff --git a/Eule/gcccompat.h b/Eule/gcccompat.h new file mode 100644 index 0000000..798b8b2 --- /dev/null +++ b/Eule/gcccompat.h @@ -0,0 +1,35 @@ +#pragma once + +/* +* Some intrinsic functions such as _mm_sincos_pd are not available on g++ by default (requires some specific library). +* So let's just "re"define them manually if we're on g++. +* This way the code still works, even with the other intrinsics enabled. +*/ + +#if (__GNUC__ && __cplusplus) +#include +#include + +inline __m256d _mm256_sincos_pd(__m256d* __cos, __m256d __vec) +{ + double vec[4]; + + _mm256_storeu_pd(vec, __vec); + + // Manually calculate cosines + *__cos = _mm256_set_pd( + cos(vec[3]), + cos(vec[2]), + cos(vec[1]), + cos(vec[0]) + ); + + // Manually calculate sines + return _mm256_set_pd( + sin(vec[3]), + sin(vec[2]), + sin(vec[1]), + sin(vec[0]) + ); +} +#endif