From ef351e68a37fa740ea70d25b96ec45b88d893ad6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20de=20Vill=C3=A8le=20=5BUM=5D?= Date: Mon, 29 Aug 2022 13:19:56 +0200 Subject: [PATCH 1/2] Fix GLM_EXT_matrix_common compilation message It was previously printing 'GLM_EXT_matrix_transform is included', which does not match the extension name. --- glm/ext/matrix_common.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glm/ext/matrix_common.hpp b/glm/ext/matrix_common.hpp index 05c37991..f9a9dabe 100644 --- a/glm/ext/matrix_common.hpp +++ b/glm/ext/matrix_common.hpp @@ -16,7 +16,7 @@ #include "../detail/_fixes.hpp" #if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) -# pragma message("GLM: GLM_EXT_matrix_transform extension included") +# pragma message("GLM: GLM_EXT_matrix_common extension included") #endif namespace glm From 48e1ff3feecb34159880f915801ffcb3b96ebbd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20de=20Vill=C3=A8le=20=5BUM=5D?= Date: Mon, 29 Aug 2022 14:18:44 +0200 Subject: [PATCH 2/2] Add glm::abs() function for the glm::mat<> class This is added as part of the GLM_EXT_matrix_common extension, as this function is not provided by the core GLSL specification (version 4.20). The implementation of this glm::abs(mat<>) function mirrors the glm::abs(vec<>) implementation. It should be functionning the same in every way as the vec implementation. Bonus points : AFAICT this allows to vectorize operations on compilers that support optimization of these patterns, just like the functor1<> struct in _vectorize.hpp for vectors. --- glm/ext/_matrix_vectorize.hpp | 128 +++++++++++++++++++++++++++++++++ glm/ext/matrix_common.hpp | 3 + glm/ext/matrix_common.inl | 18 +++++ test/ext/ext_matrix_common.cpp | 30 ++++++++ 4 files changed, 179 insertions(+) create mode 100644 glm/ext/_matrix_vectorize.hpp diff --git a/glm/ext/_matrix_vectorize.hpp b/glm/ext/_matrix_vectorize.hpp new file mode 100644 index 00000000..acbedf2b --- /dev/null +++ b/glm/ext/_matrix_vectorize.hpp @@ -0,0 +1,128 @@ +#pragma once + +namespace glm { + + namespace detail { + + template class mat, length_t C, length_t R, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<2, 2, T, Q> call(Ret (*Func)(T x), mat<2, 2, T, Q> const &x) { + return mat<2, 2, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), + Func(x[1][0]), Func(x[1][1]) + ); + } + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<2, 3, T, Q> call(Ret (*Func)(T x), mat<2, 3, T, Q> const &x) { + return mat<2, 3, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), + Func(x[1][0]), Func(x[1][1]), + Func(x[2][0]), Func(x[2][1]) + ); + } + + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<2, 4, T, Q> call(Ret (*Func)(T x), mat<2, 4, T, Q> const &x) { + return mat<2, 4, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), + Func(x[1][0]), Func(x[1][1]), + Func(x[2][0]), Func(x[2][1]), + Func(x[3][0]), Func(x[3][1]) + ); + } + + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<3, 2, T, Q> call(Ret (*Func)(T x), mat<3, 2, T, Q> const &x) { + return mat<3, 2, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), Func(x[0][2]), + Func(x[1][0]), Func(x[1][1]), Func(x[1][2]) + ); + } + + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<3, 3, T, Q> call(Ret (*Func)(T x), mat<3, 3, T, Q> const &x) { + return mat<3, 3, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), Func(x[0][2]), + Func(x[1][0]), Func(x[1][1]), Func(x[1][2]), + Func(x[2][0]), Func(x[2][1]), Func(x[2][2]) + ); + } + + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<3, 4, T, Q> call(Ret (*Func)(T x), mat<3, 4, T, Q> const &x) { + return mat<3, 4, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), Func(x[0][2]), + Func(x[1][0]), Func(x[1][1]), Func(x[1][2]), + Func(x[2][0]), Func(x[2][1]), Func(x[2][2]), + Func(x[3][0]), Func(x[3][1]), Func(x[3][2]) + ); + } + + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<4, 2, T, Q> call(Ret (*Func)(T x), mat<4, 2, T, Q> const &x) { + return mat<4, 2, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), Func(x[0][2]), Func(x[0][3]), + Func(x[1][0]), Func(x[1][1]), Func(x[1][2]), Func(x[1][3]) + ); + } + + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<4, 3, T, Q> call(Ret (*Func)(T x), mat<4, 3, T, Q> const &x) { + return mat<4, 3, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), Func(x[0][2]), Func(x[0][3]), + Func(x[1][0]), Func(x[1][1]), Func(x[1][2]), Func(x[1][3]), + Func(x[2][0]), Func(x[2][1]), Func(x[2][2]), Func(x[2][3]) + ); + } + + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<4, 4, T, Q> call(Ret (*Func)(T x), mat<4, 4, T, Q> const &x) { + return mat<4, 4, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), Func(x[0][2]), Func(x[0][3]), + Func(x[1][0]), Func(x[1][1]), Func(x[1][2]), Func(x[1][3]), + Func(x[2][0]), Func(x[2][1]), Func(x[2][2]), Func(x[2][3]), + Func(x[3][0]), Func(x[3][1]), Func(x[3][2]), Func(x[3][3]) + ); + } + + }; + + } + +}// namespace glm diff --git a/glm/ext/matrix_common.hpp b/glm/ext/matrix_common.hpp index f9a9dabe..6bb3d06e 100644 --- a/glm/ext/matrix_common.hpp +++ b/glm/ext/matrix_common.hpp @@ -30,6 +30,9 @@ namespace glm template GLM_FUNC_DECL mat mix(mat const& x, mat const& y, U a); + template + GLM_FUNC_DECL GLM_CONSTEXPR mat abs(mat const& x); + /// @} }//namespace glm diff --git a/glm/ext/matrix_common.inl b/glm/ext/matrix_common.inl index 9d508485..1be42220 100644 --- a/glm/ext/matrix_common.inl +++ b/glm/ext/matrix_common.inl @@ -1,5 +1,7 @@ #include "../matrix.hpp" +#include "_matrix_vectorize.hpp" + namespace glm { template @@ -13,4 +15,20 @@ namespace glm { return matrixCompMult(mat(x), static_cast(1) - a) + matrixCompMult(mat(y), a); } + + template + struct compute_abs_matrix + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat call(mat const& x) + { + return detail::matrix_functor_1::call(abs, x); + } + }; + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat abs(mat const& x) + { + return compute_abs_matrix::value>::call(x); + } + }//namespace glm diff --git a/test/ext/ext_matrix_common.cpp b/test/ext/ext_matrix_common.cpp index df0c3fe4..fa940d9b 100644 --- a/test/ext/ext_matrix_common.cpp +++ b/test/ext/ext_matrix_common.cpp @@ -43,11 +43,41 @@ static int test_mix() return Error; } +static int test_abs() +{ + int Error = 0; + + { + glm::mat4 A( + 3.0f, 1.0f, 5.2f, 4.9f, + 1.4f, 0.5f, 9.3f, 3.7f, + 6.8f, 8.4f, 4.3f, 3.9f, + 5.6f, 7.2f, 1.1f, 4.4f + ); + glm::mat4 B( + 1.0,-1.0, 1.0, 1.0, + -1.0, 1.0, 1.0,-1.0, + 1.0,-1.0,-1.0,-1.0, + -1.0,-1.0, 1.0, 1.0 + ); + glm::mat4 C = glm::matrixCompMult(A, B); // Not * to avoid matrix product. + glm::mat4 D = glm::abs(C); + glm::bvec4 const row1 = glm::equal(D[0], A[0]); + glm::bvec4 const row2 = glm::equal(D[1], A[1]); + glm::bvec4 const row3 = glm::equal(D[2], A[2]); + glm::bvec4 const row4 = glm::equal(D[3], A[3]); + Error += glm::all(glm::bvec4{glm::all(row1), glm::all(row2), glm::all(row3), glm::all(row4)}) ? 0 : 1; + + return Error; + } +} + int main() { int Error = 0; Error += test_mix(); + Error += test_abs(); return Error; }