From 90cb26688620bf3f51a3136697fd9266b540758a Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 2 Jan 2025 20:52:19 +1000 Subject: [PATCH] Common: Small tidy-up and constexpr-ify GSMatrix4x4 --- src/common/gsvector.cpp | 125 ++++------------------------------------ src/common/gsvector.h | 70 +++++++++++++++++++--- 2 files changed, 71 insertions(+), 124 deletions(-) diff --git a/src/common/gsvector.cpp b/src/common/gsvector.cpp index c62da4d8a..a617f3924 100644 --- a/src/common/gsvector.cpp +++ b/src/common/gsvector.cpp @@ -66,53 +66,11 @@ void GSMatrix2x2::store(void* m) std::memcpy(m, E, sizeof(E)); } -GSMatrix4x4::GSMatrix4x4(float e00, float e01, float e02, float e03, float e10, float e11, float e12, float e13, - float e20, float e21, float e22, float e23, float e30, float e31, float e32, float e33) -{ - E[0][0] = e00; - E[0][1] = e01; - E[0][2] = e02; - E[0][3] = e03; - E[1][0] = e10; - E[1][1] = e11; - E[1][2] = e12; - E[1][3] = e13; - E[2][0] = e20; - E[2][1] = e21; - E[2][2] = e22; - E[2][3] = e23; - E[3][0] = e30; - E[3][1] = e31; - E[3][2] = e32; - E[3][3] = e33; -} - -GSMatrix4x4::GSMatrix4x4(const GSMatrix2x2& m) -{ - E[0][0] = m.E[0][0]; - E[0][1] = m.E[0][1]; - E[0][2] = 0.0f; - E[0][3] = 0.0f; - E[1][0] = m.E[1][0]; - E[1][1] = m.E[1][1]; - E[1][2] = 0.0f; - E[1][3] = 0.0f; - E[2][0] = 0.0f; - E[2][1] = 0.0f; - E[2][2] = 1.0f; - E[2][3] = 0.0f; - E[3][0] = 0.0f; - E[3][1] = 0.0f; - E[3][2] = 0.0f; - E[3][3] = 1.0f; -} - -GSMatrix4x4 GSMatrix4x4::operator*(const GSMatrix4x4& m) const +ALWAYS_INLINE static void MatrixMult4x4(GSMatrix4x4& res, const GSMatrix4x4& lhs, const GSMatrix4x4& rhs) { // This isn't speedy by any means, but it's not hot code either. - GSMatrix4x4 res; - -#define MultRC(rw, cl) E[rw][0] * m.E[0][cl] + E[rw][1] * m.E[1][cl] + E[rw][2] * m.E[2][cl] + E[rw][3] * m.E[3][cl] +#define MultRC(rw, cl) \ + lhs.E[rw][0] * rhs.E[0][cl] + lhs.E[rw][1] * rhs.E[1][cl] + lhs.E[rw][2] * rhs.E[2][cl] + lhs.E[rw][3] * rhs.E[3][cl] res.E[0][0] = MultRC(0, 0); res.E[0][1] = MultRC(0, 1); @@ -132,75 +90,22 @@ GSMatrix4x4 GSMatrix4x4::operator*(const GSMatrix4x4& m) const res.E[3][3] = MultRC(3, 3); #undef MultRC +} +GSMatrix4x4 GSMatrix4x4::operator*(const GSMatrix4x4& m) const +{ + GSMatrix4x4 res; + MatrixMult4x4(res, *this, m); return res; } GSMatrix4x4& GSMatrix4x4::operator*=(const GSMatrix4x4& m) { const GSMatrix4x4 copy(*this); - -#define MultRC(rw, cl) \ - copy.E[rw][0] * m.E[0][cl] + copy.E[rw][1] * m.E[1][cl] + copy.E[rw][2] * m.E[2][cl] + copy.E[rw][3] * m.E[3][cl] - - E[0][0] = MultRC(0, 0); - E[0][1] = MultRC(0, 1); - E[0][2] = MultRC(0, 2); - E[0][3] = MultRC(0, 3); - E[1][0] = MultRC(1, 0); - E[1][1] = MultRC(1, 1); - E[1][2] = MultRC(1, 2); - E[1][3] = MultRC(1, 3); - E[2][0] = MultRC(2, 0); - E[2][1] = MultRC(2, 1); - E[2][2] = MultRC(2, 2); - E[2][3] = MultRC(2, 3); - E[3][0] = MultRC(3, 0); - E[3][1] = MultRC(3, 1); - E[3][2] = MultRC(3, 2); - E[3][3] = MultRC(3, 3); - -#undef MultRC - + MatrixMult4x4(*this, copy, m); return *this; } -GSVector4 GSMatrix4x4::operator*(const GSVector4& v) const -{ - const GSVector4 r0 = row(0); - const GSVector4 r1 = row(1); - const GSVector4 r2 = row(2); - const GSVector4 r3 = row(3); - - return GSVector4(r0.dot(v), r1.dot(v), r2.dot(v), r3.dot(v)); -} - -GSMatrix4x4 GSMatrix4x4::Identity() -{ - GSMatrix4x4 res; - -#define MultRC(rw, cl) E[rw][0] * m.E[0][cl] + E[rw][1] * m.E[1][cl] + E[rw][2] * m.E[2][cl] + E[rw][3] * m.E[3][cl] - - res.E[0][0] = 1.0f; - res.E[0][1] = 0.0f; - res.E[0][2] = 0.0f; - res.E[0][3] = 0.0f; - res.E[1][0] = 0.0f; - res.E[1][1] = 1.0f; - res.E[1][2] = 0.0f; - res.E[1][3] = 0.0f; - res.E[2][0] = 0.0f; - res.E[2][1] = 0.0f; - res.E[2][2] = 1.0f; - res.E[2][3] = 0.0f; - res.E[3][0] = 0.0f; - res.E[3][1] = 0.0f; - res.E[3][2] = 0.0f; - res.E[3][3] = 1.0f; - - return res; -} - GSMatrix4x4 GSMatrix4x4::RotationX(float angle_in_radians) { const float sin_angle = std::sin(angle_in_radians); @@ -246,17 +151,7 @@ GSMatrix4x4 GSMatrix4x4::OffCenterOrthographicProjection(float width, float heig return OffCenterOrthographicProjection(0.0f, 0.0f, width, height, zNear, zFar); } -GSVector4 GSMatrix4x4::row(size_t i) const -{ - return GSVector4::load(&E[i][0]); -} - -GSVector4 GSMatrix4x4::col(size_t i) const -{ - return GSVector4(E[0][i], E[1][i], E[2][i], E[3][i]); -} - -GSMatrix4x4 GSMatrix4x4::Invert() const +GSMatrix4x4 GSMatrix4x4::invert() const { GSMatrix4x4 ret; diff --git a/src/common/gsvector.h b/src/common/gsvector.h index 4a3b1306c..d0dc89faf 100644 --- a/src/common/gsvector.h +++ b/src/common/gsvector.h @@ -41,17 +41,60 @@ public: class alignas(VECTOR_ALIGNMENT) GSMatrix4x4 { public: - GSMatrix4x4() = default; - GSMatrix4x4(float e00, float e01, float e02, float e03, float e10, float e11, float e12, float e13, float e20, - float e21, float e22, float e23, float e30, float e31, float e32, float e33); - GSMatrix4x4(const GSMatrix2x2& m); + constexpr GSMatrix4x4() = default; + constexpr GSMatrix4x4(float e00, float e01, float e02, float e03, float e10, float e11, float e12, float e13, + float e20, float e21, float e22, float e23, float e30, float e31, float e32, float e33) + { + E[0][0] = e00; + E[0][1] = e01; + E[0][2] = e02; + E[0][3] = e03; + E[1][0] = e10; + E[1][1] = e11; + E[1][2] = e12; + E[1][3] = e13; + E[2][0] = e20; + E[2][1] = e21; + E[2][2] = e22; + E[2][3] = e23; + E[3][0] = e30; + E[3][1] = e31; + E[3][2] = e32; + E[3][3] = e33; + } + + constexpr GSMatrix4x4(const GSMatrix2x2& m) + { + E[0][0] = m.E[0][0]; + E[0][1] = m.E[0][1]; + E[0][2] = 0.0f; + E[0][3] = 0.0f; + E[1][0] = m.E[1][0]; + E[1][1] = m.E[1][1]; + E[1][2] = 0.0f; + E[1][3] = 0.0f; + E[2][0] = 0.0f; + E[2][1] = 0.0f; + E[2][2] = 1.0f; + E[2][3] = 0.0f; + E[3][0] = 0.0f; + E[3][1] = 0.0f; + E[3][2] = 0.0f; + E[3][3] = 1.0f; + } GSMatrix4x4 operator*(const GSMatrix4x4& m) const; GSMatrix4x4& operator*=(const GSMatrix4x4& m); - GSVector4 operator*(const GSVector4& v) const; + GSVector4 operator*(const GSVector4& v) const + { + return GSVector4(row(0).dot(v), row(1).dot(v), row(2).dot(v), row(3).dot(v)); + } - static GSMatrix4x4 Identity(); + static constexpr GSMatrix4x4 Identity() + { + return GSMatrix4x4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); + } static GSMatrix4x4 RotationX(float angle_in_radians); static GSMatrix4x4 RotationY(float angle_in_radians); @@ -62,10 +105,19 @@ public: float zFar); static GSMatrix4x4 OffCenterOrthographicProjection(float width, float height, float zNear, float zFar); - GSVector4 row(size_t i) const; - GSVector4 col(size_t i) const; + GSVector4 row(size_t i) const { return GSVector4::load(&E[i][0]); } + GSVector4 col(size_t i) const { return GSVector4(E[0][i], E[1][i], E[2][i], E[3][i]); } - GSMatrix4x4 Invert() const; + void set_row(size_t i, GSVector4 row) { GSVector4::store(&E[i][0], row); } + void set_col(size_t i, GSVector4 col) + { + E[0][i] = col.x; + E[1][i] = col.y; + E[2][i] = col.z; + E[3][i] = col.w; + } + + GSMatrix4x4 invert() const; void store(void* m);