|
|
@@ -1,6 +1,6 @@
|
|
|
// zlib open source license
|
|
|
//
|
|
|
-// Copyright (c) 2017 to 2022 David Forsgren Piuva
|
|
|
+// Copyright (c) 2017 to 2023 David Forsgren Piuva
|
|
|
//
|
|
|
// This software is provided 'as-is', without any express or implied
|
|
|
// warranty. In no event will the authors be held liable for any damages
|
|
|
@@ -31,157 +31,247 @@
|
|
|
#ifndef DFPSR_SIMD_3D
|
|
|
#define DFPSR_SIMD_3D
|
|
|
|
|
|
-// 3D vector in xxxxyyyyzzzz format
|
|
|
-struct F32x4x3 {
|
|
|
- F32x4 v1, v2, v3;
|
|
|
- // Direct constructor given 3 rows of length 4
|
|
|
- F32x4x3(const F32x4& v1, const F32x4& v2, const F32x4& v3)
|
|
|
- : v1(v1), v2(v2), v3(v3) {}
|
|
|
- // Transposed constructor given 4 columns of length 3
|
|
|
- F32x4x3(const dsr::FVector3D& vx, const dsr::FVector3D& vy, const dsr::FVector3D& vz, const dsr::FVector3D& vw)
|
|
|
- : v1(F32x4(vx.x, vy.x, vz.x, vw.x)),
|
|
|
- v2(F32x4(vx.y, vy.y, vz.y, vw.y)),
|
|
|
- v3(F32x4(vx.z, vy.z, vz.z, vw.z)) {}
|
|
|
- // Transposed constructor given a single repeated column
|
|
|
- F32x4x3(const dsr::FVector3D& v)
|
|
|
- : v1(F32x4(v.x, v.x, v.x, v.x)),
|
|
|
- v2(F32x4(v.y, v.y, v.y, v.y)),
|
|
|
- v3(F32x4(v.z, v.z, v.z, v.z)) {}
|
|
|
- // In-place math operations
|
|
|
- inline F32x4x3& operator+=(const F32x4x3& offset) { this->v1 = this->v1 + offset.v1; this->v2 = this->v2 + offset.v2; this->v3 = this->v3 + offset.v3; return *this; }
|
|
|
- inline F32x4x3& operator-=(const F32x4x3& offset) { this->v1 = this->v1 - offset.v1; this->v2 = this->v2 - offset.v2; this->v3 = this->v3 - offset.v3; return *this; }
|
|
|
- inline F32x4x3& operator*=(const F32x4x3& scale) { this->v1 = this->v1 * scale.v1; this->v2 = this->v2 * scale.v2; this->v3 = this->v3 * scale.v3; return *this; }
|
|
|
- inline F32x4x3& operator+=(const F32x4& offset) { this->v1 = this->v1 + offset; this->v2 = this->v2 + offset; this->v3 = this->v3 + offset; return *this; }
|
|
|
- inline F32x4x3& operator-=(const F32x4& offset) { this->v1 = this->v1 - offset; this->v2 = this->v2 - offset; this->v3 = this->v3 - offset; return *this; }
|
|
|
- inline F32x4x3& operator*=(const F32x4& scale) { this->v1 = this->v1 * scale; this->v2 = this->v2 * scale; this->v3 = this->v3 * scale; return *this; }
|
|
|
- inline F32x4x3& operator+=(const float& offset) { this->v1 = this->v1 + offset; this->v2 = this->v2 + offset; this->v3 = this->v3 + offset; return *this; }
|
|
|
- inline F32x4x3& operator-=(const float& offset) { this->v1 = this->v1 - offset; this->v2 = this->v2 - offset; this->v3 = this->v3 - offset; return *this; }
|
|
|
- inline F32x4x3& operator*=(const float& scale) { this->v1 = this->v1 * scale; this->v2 = this->v2 * scale; this->v3 = this->v3 * scale; return *this; }
|
|
|
-};
|
|
|
-
|
|
|
-inline F32x4x3 operator+(const F32x4x3 &left, const F32x4x3 &right) {
|
|
|
- return F32x4x3(left.v1 + right.v1, left.v2 + right.v2, left.v3 + right.v3);
|
|
|
-}
|
|
|
-inline F32x4x3 operator+(const F32x4x3 &left, const F32x4 &right) {
|
|
|
- return F32x4x3(left.v1 + right, left.v2 + right, left.v3 + right);
|
|
|
-}
|
|
|
-inline F32x4x3 operator+(const F32x4x3 &left, const float &right) {
|
|
|
- return F32x4x3(left.v1 + right, left.v2 + right, left.v3 + right);
|
|
|
+// These are the infix operations for 2D SIMD vectors F32x4x2, F32x8x2...
|
|
|
+#define SIMD_VECTOR_INFIX_OPERATORS_2D(VECTOR_TYPE, SIMD_TYPE, ELEMENT_TYPE) \
|
|
|
+inline VECTOR_TYPE operator+(const VECTOR_TYPE &left, const VECTOR_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 + right.v1, left.v2 + right.v2); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator+(const VECTOR_TYPE &left, const SIMD_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 + right, left.v2 + right); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator+(const VECTOR_TYPE &left, const ELEMENT_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 + right, left.v2 + right); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator-(const VECTOR_TYPE &left, const VECTOR_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 - right.v1, left.v2 - right.v2); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator-(const VECTOR_TYPE &left, const SIMD_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 - right, left.v2 - right); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator-(const VECTOR_TYPE &left, const ELEMENT_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 - right, left.v2 - right); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator-(const VECTOR_TYPE& value) { \
|
|
|
+ return VECTOR_TYPE(-value.v1, -value.v2); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator*(const VECTOR_TYPE &left, const VECTOR_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 * right.v1, left.v2 * right.v2); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator*(const VECTOR_TYPE &left, const SIMD_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 * right, left.v2 * right); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator*(const VECTOR_TYPE &left, const ELEMENT_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 * right, left.v2 * right); \
|
|
|
+} \
|
|
|
+inline SIMD_TYPE dotProduct(const VECTOR_TYPE &a, const VECTOR_TYPE &b) { \
|
|
|
+ return (a.v1 * b.v1) + (a.v2 * b.v2); \
|
|
|
+} \
|
|
|
+inline SIMD_TYPE squareLength(const VECTOR_TYPE &v) { \
|
|
|
+ return dotProduct(v, v); \
|
|
|
+} \
|
|
|
+inline SIMD_TYPE length(const VECTOR_TYPE &v) { \
|
|
|
+ return squareLength(v).squareRoot(); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE normalize(const VECTOR_TYPE &v) { \
|
|
|
+ return v * squareLength(v).reciprocalSquareRoot(); \
|
|
|
}
|
|
|
|
|
|
-inline F32x4x3 operator-(const F32x4x3 &left, const F32x4x3 &right) {
|
|
|
- return F32x4x3(left.v1 - right.v1, left.v2 - right.v2, left.v3 - right.v3);
|
|
|
-}
|
|
|
-inline F32x4x3 operator-(const F32x4x3 &left, const F32x4 &right) {
|
|
|
- return F32x4x3(left.v1 - right, left.v2 - right, left.v3 - right);
|
|
|
-}
|
|
|
-inline F32x4x3 operator-(const F32x4x3 &left, const float &right) {
|
|
|
- return F32x4x3(left.v1 - right, left.v2 - right, left.v3 - right);
|
|
|
-}
|
|
|
-inline F32x4x3 operator-(const F32x4x3& value) {
|
|
|
- return F32x4x3(-value.v1, -value.v2, -value.v3);
|
|
|
+// These are the infix operations for 3D SIMD vectors F32x4x3, F32x8x3...
|
|
|
+#define SIMD_VECTOR_INFIX_OPERATORS_3D(VECTOR_TYPE, SIMD_TYPE, ELEMENT_TYPE) \
|
|
|
+inline VECTOR_TYPE operator+(const VECTOR_TYPE &left, const VECTOR_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 + right.v1, left.v2 + right.v2, left.v3 + right.v3); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator+(const VECTOR_TYPE &left, const SIMD_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 + right, left.v2 + right, left.v3 + right); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator+(const VECTOR_TYPE &left, const ELEMENT_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 + right, left.v2 + right, left.v3 + right); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator-(const VECTOR_TYPE &left, const VECTOR_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 - right.v1, left.v2 - right.v2, left.v3 - right.v3); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator-(const VECTOR_TYPE &left, const SIMD_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 - right, left.v2 - right, left.v3 - right); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator-(const VECTOR_TYPE &left, const ELEMENT_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 - right, left.v2 - right, left.v3 - right); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator-(const VECTOR_TYPE& value) { \
|
|
|
+ return VECTOR_TYPE(-value.v1, -value.v2, -value.v3); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator*(const VECTOR_TYPE &left, const VECTOR_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 * right.v1, left.v2 * right.v2, left.v3 * right.v3); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator*(const VECTOR_TYPE &left, const SIMD_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 * right, left.v2 * right, left.v3 * right); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE operator*(const VECTOR_TYPE &left, const ELEMENT_TYPE &right) { \
|
|
|
+ return VECTOR_TYPE(left.v1 * right, left.v2 * right, left.v3 * right); \
|
|
|
+} \
|
|
|
+inline SIMD_TYPE dotProduct(const VECTOR_TYPE &a, const VECTOR_TYPE &b) { \
|
|
|
+ return (a.v1 * b.v1) + (a.v2 * b.v2) + (a.v3 * b.v3); \
|
|
|
+} \
|
|
|
+inline SIMD_TYPE squareLength(const VECTOR_TYPE &v) { \
|
|
|
+ return dotProduct(v, v); \
|
|
|
+} \
|
|
|
+inline SIMD_TYPE length(const VECTOR_TYPE &v) { \
|
|
|
+ return squareLength(v).squareRoot(); \
|
|
|
+} \
|
|
|
+inline VECTOR_TYPE normalize(const VECTOR_TYPE &v) { \
|
|
|
+ return v * squareLength(v).reciprocalSquareRoot(); \
|
|
|
}
|
|
|
|
|
|
-inline F32x4x3 operator*(const F32x4x3 &left, const F32x4x3 &right) {
|
|
|
- return F32x4x3(left.v1 * right.v1, left.v2 * right.v2, left.v3 * right.v3);
|
|
|
-}
|
|
|
-inline F32x4x3 operator*(const F32x4x3 &left, const F32x4 &right) {
|
|
|
- return F32x4x3(left.v1 * right, left.v2 * right, left.v3 * right);
|
|
|
-}
|
|
|
-inline F32x4x3 operator*(const F32x4x3 &left, const float &right) {
|
|
|
- return F32x4x3(left.v1 * right, left.v2 * right, left.v3 * right);
|
|
|
-}
|
|
|
-
|
|
|
-inline F32x4 dotProduct(const F32x4x3 &a, const F32x4x3 &b) {
|
|
|
- return (a.v1 * b.v1) + (a.v2 * b.v2) + (a.v3 * b.v3);
|
|
|
-}
|
|
|
-
|
|
|
-inline F32x4 squareLength(const F32x4x3 &v) {
|
|
|
- return dotProduct(v, v);
|
|
|
-}
|
|
|
-
|
|
|
-inline F32x4 length(const F32x4x3 &v) {
|
|
|
- return squareLength(v).squareRoot();
|
|
|
-}
|
|
|
+// These are the available in-plaxe operations for 2D SIMD vectors F32x4x2, F32x8x2...
|
|
|
+#define SIMD_VECTOR_MEMBER_OPERATORS_2D(VECTOR_TYPE, SIMD_TYPE, ELEMENT_TYPE) \
|
|
|
+ inline VECTOR_TYPE& operator+=(const VECTOR_TYPE& offset) { this->v1 = this->v1 + offset.v1; this->v2 = this->v2 + offset.v2; return *this; } \
|
|
|
+ inline VECTOR_TYPE& operator-=(const VECTOR_TYPE& offset) { this->v1 = this->v1 - offset.v1; this->v2 = this->v2 - offset.v2; return *this; } \
|
|
|
+ inline VECTOR_TYPE& operator*=(const VECTOR_TYPE& scale) { this->v1 = this->v1 * scale.v1; this->v2 = this->v2 * scale.v2; return *this; } \
|
|
|
+ inline VECTOR_TYPE& operator+=(const SIMD_TYPE& offset) { this->v1 = this->v1 + offset; this->v2 = this->v2 + offset; return *this; } \
|
|
|
+ inline VECTOR_TYPE& operator-=(const SIMD_TYPE& offset) { this->v1 = this->v1 - offset; this->v2 = this->v2 - offset; return *this; } \
|
|
|
+ inline VECTOR_TYPE& operator*=(const SIMD_TYPE& scale) { this->v1 = this->v1 * scale; this->v2 = this->v2 * scale; return *this; } \
|
|
|
+ inline VECTOR_TYPE& operator+=(const ELEMENT_TYPE& offset) { this->v1 = this->v1 + offset; this->v2 = this->v2 + offset; return *this; } \
|
|
|
+ inline VECTOR_TYPE& operator-=(const ELEMENT_TYPE& offset) { this->v1 = this->v1 - offset; this->v2 = this->v2 - offset; return *this; } \
|
|
|
+ inline VECTOR_TYPE& operator*=(const ELEMENT_TYPE& scale) { this->v1 = this->v1 * scale; this->v2 = this->v2 * scale; return *this; }
|
|
|
|
|
|
-inline F32x4x3 normalize(const F32x4x3 &v) {
|
|
|
- return v * squareLength(v).reciprocalSquareRoot();
|
|
|
-}
|
|
|
+// These are the available in-plaxe operations for 3D SIMD vectors F32x4x3, F32x8x3...
|
|
|
+#define SIMD_VECTOR_MEMBER_OPERATORS_3D(VECTOR_TYPE, SIMD_TYPE, ELEMENT_TYPE) \
|
|
|
+ inline VECTOR_TYPE& operator+=(const VECTOR_TYPE& offset) { this->v1 = this->v1 + offset.v1; this->v2 = this->v2 + offset.v2; this->v3 = this->v3 + offset.v3; return *this; } \
|
|
|
+ inline VECTOR_TYPE& operator-=(const VECTOR_TYPE& offset) { this->v1 = this->v1 - offset.v1; this->v2 = this->v2 - offset.v2; this->v3 = this->v3 - offset.v3; return *this; } \
|
|
|
+ inline VECTOR_TYPE& operator*=(const VECTOR_TYPE& scale) { this->v1 = this->v1 * scale.v1; this->v2 = this->v2 * scale.v2; this->v3 = this->v3 * scale.v3; return *this; } \
|
|
|
+ inline VECTOR_TYPE& operator+=(const SIMD_TYPE& offset) { this->v1 = this->v1 + offset; this->v2 = this->v2 + offset; this->v3 = this->v3 + offset; return *this; } \
|
|
|
+ inline VECTOR_TYPE& operator-=(const SIMD_TYPE& offset) { this->v1 = this->v1 - offset; this->v2 = this->v2 - offset; this->v3 = this->v3 - offset; return *this; } \
|
|
|
+ inline VECTOR_TYPE& operator*=(const SIMD_TYPE& scale) { this->v1 = this->v1 * scale; this->v2 = this->v2 * scale; this->v3 = this->v3 * scale; return *this; } \
|
|
|
+ inline VECTOR_TYPE& operator+=(const ELEMENT_TYPE& offset) { this->v1 = this->v1 + offset; this->v2 = this->v2 + offset; this->v3 = this->v3 + offset; return *this; } \
|
|
|
+ inline VECTOR_TYPE& operator-=(const ELEMENT_TYPE& offset) { this->v1 = this->v1 - offset; this->v2 = this->v2 - offset; this->v3 = this->v3 - offset; return *this; } \
|
|
|
+ inline VECTOR_TYPE& operator*=(const ELEMENT_TYPE& scale) { this->v1 = this->v1 * scale; this->v2 = this->v2 * scale; this->v3 = this->v3 * scale; return *this; }
|
|
|
|
|
|
-// 2D vector in xxxxyyyy format
|
|
|
+// 128x2-bit SIMD vectorized 2D math vector stored in xxxxyyyy format (one planar SIMD vector per dimension).
|
|
|
struct F32x4x2 {
|
|
|
F32x4 v1, v2;
|
|
|
// Direct constructor given 3 rows of length 4
|
|
|
F32x4x2(const F32x4& v1, const F32x4& v2)
|
|
|
: v1(v1), v2(v2) {}
|
|
|
- // Transposed constructor given 4 columns of length 3
|
|
|
- F32x4x2(const dsr::FVector2D& vx, const dsr::FVector2D& vy, const dsr::FVector2D& vz, const dsr::FVector2D& vw)
|
|
|
- : v1(F32x4(vx.x, vy.x, vz.x, vw.x)),
|
|
|
- v2(F32x4(vx.y, vy.y, vz.y, vw.y)) {}
|
|
|
+ // Gradient constructor from an initial vector and the increment for each element.
|
|
|
+ static F32x4x2 createGradient(const dsr::FVector3D& start, const dsr::FVector3D& increment) {
|
|
|
+ return F32x4x2(
|
|
|
+ F32x4::createGradient(start.x, increment.x),
|
|
|
+ F32x4::createGradient(start.y, increment.y)
|
|
|
+ );
|
|
|
+ }
|
|
|
+ // Transposed constructor given 4 columns of length 2 (Only allowed for fixed size SIMD, not X or F vector lengths)
|
|
|
+ F32x4x2(const dsr::FVector2D& a, const dsr::FVector2D& b, const dsr::FVector2D& c, const dsr::FVector2D& d)
|
|
|
+ : v1(a.x, b.x, c.x, d.x),
|
|
|
+ v2(a.y, b.y, c.y, d.y) {}
|
|
|
// Transposed constructor given a single repeated column
|
|
|
F32x4x2(const dsr::FVector2D& v)
|
|
|
- : v1(F32x4(v.x, v.x, v.x, v.x)),
|
|
|
- v2(F32x4(v.y, v.y, v.y, v.y)) {}
|
|
|
+ : v1(F32x4(v.x)),
|
|
|
+ v2(F32x4(v.y)) {}
|
|
|
// In-place math operations
|
|
|
- inline F32x4x2& operator+=(const F32x4x2& offset) { this->v1 = this->v1 + offset.v1; this->v2 = this->v2 + offset.v2; return *this; }
|
|
|
- inline F32x4x2& operator-=(const F32x4x2& offset) { this->v1 = this->v1 - offset.v1; this->v2 = this->v2 - offset.v2; return *this; }
|
|
|
- inline F32x4x2& operator*=(const F32x4x2& scale) { this->v1 = this->v1 * scale.v1; this->v2 = this->v2 * scale.v2; return *this; }
|
|
|
- inline F32x4x2& operator+=(const F32x4& offset) { this->v1 = this->v1 + offset; this->v2 = this->v2 + offset; return *this; }
|
|
|
- inline F32x4x2& operator-=(const F32x4& offset) { this->v1 = this->v1 - offset; this->v2 = this->v2 - offset; return *this; }
|
|
|
- inline F32x4x2& operator*=(const F32x4& scale) { this->v1 = this->v1 * scale; this->v2 = this->v2 * scale; return *this; }
|
|
|
- inline F32x4x2& operator+=(const float& offset) { this->v1 = this->v1 + offset; this->v2 = this->v2 + offset; return *this; }
|
|
|
- inline F32x4x2& operator-=(const float& offset) { this->v1 = this->v1 - offset; this->v2 = this->v2 - offset; return *this; }
|
|
|
- inline F32x4x2& operator*=(const float& scale) { this->v1 = this->v1 * scale; this->v2 = this->v2 * scale; return *this; }
|
|
|
+ SIMD_VECTOR_MEMBER_OPERATORS_2D(F32x4x2, F32x4, float)
|
|
|
};
|
|
|
+SIMD_VECTOR_INFIX_OPERATORS_2D(F32x4x2, F32x4, float)
|
|
|
|
|
|
-inline F32x4x2 operator+(const F32x4x2 &left, const F32x4x2 &right) {
|
|
|
- return F32x4x2(left.v1 + right.v1, left.v2 + right.v2);
|
|
|
-}
|
|
|
-inline F32x4x2 operator+(const F32x4x2 &left, const F32x4 &right) {
|
|
|
- return F32x4x2(left.v1 + right, left.v2 + right);
|
|
|
-}
|
|
|
-inline F32x4x2 operator+(const F32x4x2 &left, const float &right) {
|
|
|
- return F32x4x2(left.v1 + right, left.v2 + right);
|
|
|
-}
|
|
|
-
|
|
|
-inline F32x4x2 operator-(const F32x4x2 &left, const F32x4x2 &right) {
|
|
|
- return F32x4x2(left.v1 - right.v1, left.v2 - right.v2);
|
|
|
-}
|
|
|
-inline F32x4x2 operator-(const F32x4x2 &left, const F32x4 &right) {
|
|
|
- return F32x4x2(left.v1 - right, left.v2 - right);
|
|
|
-}
|
|
|
-inline F32x4x2 operator-(const F32x4x2 &left, const float &right) {
|
|
|
- return F32x4x2(left.v1 - right, left.v2 - right);
|
|
|
-}
|
|
|
-inline F32x4x2 operator-(const F32x4x2& value) {
|
|
|
- return F32x4x2(-value.v1, -value.v2);
|
|
|
-}
|
|
|
-
|
|
|
-inline F32x4x2 operator*(const F32x4x2 &left, const F32x4x2 &right) {
|
|
|
- return F32x4x2(left.v1 * right.v1, left.v2 * right.v2);
|
|
|
-}
|
|
|
-inline F32x4x2 operator*(const F32x4x2 &left, const F32x4 &right) {
|
|
|
- return F32x4x2(left.v1 * right, left.v2 * right);
|
|
|
-}
|
|
|
-inline F32x4x2 operator*(const F32x4x2 &left, const float &right) {
|
|
|
- return F32x4x2(left.v1 * right, left.v2 * right);
|
|
|
-}
|
|
|
+// 256x2-bit SIMD vectorized 2D math vector stored in xxxxxxxxyyyyyyyy format (one planar SIMD vector per dimension).
|
|
|
+struct F32x8x2 {
|
|
|
+ F32x8 v1, v2;
|
|
|
+ // Direct constructor given 3 rows of length 4
|
|
|
+ F32x8x2(const F32x8& v1, const F32x8& v2)
|
|
|
+ : v1(v1), v2(v2) {}
|
|
|
+ // Gradient constructor from an initial vector and the increment for each element.
|
|
|
+ static F32x8x2 createGradient(const dsr::FVector3D& start, const dsr::FVector3D& increment) {
|
|
|
+ return F32x8x2(
|
|
|
+ F32x8::createGradient(start.x, increment.x),
|
|
|
+ F32x8::createGradient(start.y, increment.y)
|
|
|
+ );
|
|
|
+ }
|
|
|
+ // Transposed constructor given 4 columns of length 2 (Only allowed for fixed size SIMD, not X or F vector lengths)
|
|
|
+ F32x8x2(const dsr::FVector2D& a, const dsr::FVector2D& b, const dsr::FVector2D& c, const dsr::FVector2D& d, const dsr::FVector2D& e, const dsr::FVector2D& f, const dsr::FVector2D& g, const dsr::FVector2D& h)
|
|
|
+ : v1(a.x, b.x, c.x, d.x, e.x, f.x, g.x, h.x),
|
|
|
+ v2(a.y, b.y, c.y, d.y, e.y, f.y, g.y, h.y) {}
|
|
|
+ // Transposed constructor given a single repeated column
|
|
|
+ F32x8x2(const dsr::FVector2D& v)
|
|
|
+ : v1(F32x8(v.x)),
|
|
|
+ v2(F32x8(v.y)) {}
|
|
|
+ // In-place math operations
|
|
|
+ SIMD_VECTOR_MEMBER_OPERATORS_2D(F32x8x2, F32x8, float)
|
|
|
+};
|
|
|
+SIMD_VECTOR_INFIX_OPERATORS_2D(F32x8x2, F32x8, float)
|
|
|
|
|
|
-inline F32x4 dotProduct(const F32x4x2 &a, const F32x4x2 &b) {
|
|
|
- return (a.v1 * b.v1) + (a.v2 * b.v2);
|
|
|
-}
|
|
|
+// 128x3-bit SIMD vectorized 3D math vector stored in xxxxyyyyzzzz format (one planar SIMD vector per dimension).
|
|
|
+struct F32x4x3 {
|
|
|
+ F32x4 v1, v2, v3;
|
|
|
+ // Direct constructor given 3 rows of length 4
|
|
|
+ F32x4x3(const F32x4& v1, const F32x4& v2, const F32x4& v3)
|
|
|
+ : v1(v1), v2(v2), v3(v3) {}
|
|
|
+ // Gradient constructor from an initial vector and the increment for each element.
|
|
|
+ static F32x4x3 createGradient(const dsr::FVector3D& start, const dsr::FVector3D& increment) {
|
|
|
+ return F32x4x3(
|
|
|
+ F32x4::createGradient(start.x, increment.x),
|
|
|
+ F32x4::createGradient(start.y, increment.y),
|
|
|
+ F32x4::createGradient(start.z, increment.z)
|
|
|
+ );
|
|
|
+ }
|
|
|
+ // Transposed constructor given 4 columns of length 3
|
|
|
+ F32x4x3(const dsr::FVector3D& a, const dsr::FVector3D& b, const dsr::FVector3D& c, const dsr::FVector3D& d)
|
|
|
+ : v1(a.x, b.x, c.x, d.x),
|
|
|
+ v2(a.y, b.y, c.y, d.y),
|
|
|
+ v3(a.z, b.z, c.z, d.z) {}
|
|
|
+ // Transposed constructor given a single repeated column
|
|
|
+ F32x4x3(const dsr::FVector3D& v)
|
|
|
+ : v1(F32x4(v.x)),
|
|
|
+ v2(F32x4(v.y)),
|
|
|
+ v3(F32x4(v.z)) {}
|
|
|
+ // In-place math operations
|
|
|
+ SIMD_VECTOR_MEMBER_OPERATORS_3D(F32x4x3, F32x4, float)
|
|
|
+};
|
|
|
+SIMD_VECTOR_INFIX_OPERATORS_3D(F32x4x3, F32x4, float)
|
|
|
|
|
|
-inline F32x4 squareLength(const F32x4x2 &v) {
|
|
|
- return dotProduct(v, v);
|
|
|
-}
|
|
|
+// 256x3-bit SIMD vectorized 3D math vector stored in xxxxxxxxyyyyyyyyzzzzzzzz format (one planar SIMD vector per dimension).
|
|
|
+struct F32x8x3 {
|
|
|
+ F32x8 v1, v2, v3;
|
|
|
+ // Direct constructor given 3 rows of length 4
|
|
|
+ F32x8x3(const F32x8& v1, const F32x8& v2, const F32x8& v3)
|
|
|
+ : v1(v1), v2(v2), v3(v3) {}
|
|
|
+ // Gradient constructor from an initial vector and the increment for each element.
|
|
|
+ static F32x8x3 createGradient(const dsr::FVector3D& start, const dsr::FVector3D& increment) {
|
|
|
+ return F32x8x3(
|
|
|
+ F32x8::createGradient(start.x, increment.x),
|
|
|
+ F32x8::createGradient(start.y, increment.y),
|
|
|
+ F32x8::createGradient(start.z, increment.z)
|
|
|
+ );
|
|
|
+ }
|
|
|
+ // Transposed constructor given 4 columns of length 3
|
|
|
+ F32x8x3(const dsr::FVector3D& a, const dsr::FVector3D& b, const dsr::FVector3D& c, const dsr::FVector3D& d, const dsr::FVector3D& e, const dsr::FVector3D& f, const dsr::FVector3D& g, const dsr::FVector3D& h)
|
|
|
+ : v1(a.x, b.x, c.x, d.x, e.x, f.x, g.x, h.x),
|
|
|
+ v2(a.y, b.y, c.y, d.y, e.y, f.y, g.y, h.y),
|
|
|
+ v3(a.z, b.z, c.z, d.z, e.z, f.z, g.z, h.z) {}
|
|
|
+ // Transposed constructor given a single repeated column
|
|
|
+ F32x8x3(const dsr::FVector3D& v)
|
|
|
+ : v1(F32x8(v.x)),
|
|
|
+ v2(F32x8(v.y)),
|
|
|
+ v3(F32x8(v.z)) {}
|
|
|
+ // In-place math operations
|
|
|
+ SIMD_VECTOR_MEMBER_OPERATORS_3D(F32x8x3, F32x8, float)
|
|
|
+};
|
|
|
+SIMD_VECTOR_INFIX_OPERATORS_3D(F32x8x3, F32x8, float)
|
|
|
|
|
|
-inline F32x4 length(const F32x4x2 &v) {
|
|
|
- return squareLength(v).squareRoot();
|
|
|
-}
|
|
|
+// X vector aliases
|
|
|
+#if DSR_DEFAULT_VECTOR_SIZE == 16
|
|
|
+ using F32xXx3 = F32x4x3;
|
|
|
+ using F32xXx2 = F32x4x2;
|
|
|
+#elif DSR_DEFAULT_VECTOR_SIZE == 32
|
|
|
+ using F32xXx3 = F32x8x3;
|
|
|
+ using F32xXx2 = F32x8x2;
|
|
|
+#endif
|
|
|
|
|
|
-inline F32x4x2 normalize(const F32x4x2 &v) {
|
|
|
- return v * squareLength(v).reciprocalSquareRoot();
|
|
|
-}
|
|
|
+// F vector aliases
|
|
|
+#if DSR_FLOAT_VECTOR_SIZE == 16
|
|
|
+ using F32xFx3 = F32x4x3;
|
|
|
+ using F32xFx2 = F32x4x2;
|
|
|
+#elif DSR_FLOAT_VECTOR_SIZE == 32
|
|
|
+ using F32xFx3 = F32x8x3;
|
|
|
+ using F32xFx2 = F32x8x2;
|
|
|
+#endif
|
|
|
|
|
|
#endif
|
|
|
|