From c05f58a1699307c4ace5733dad8f6fa93f3801c2 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Fri, 13 Apr 2018 15:46:43 +0300 Subject: [PATCH] vec: add addadd, subadd and muladd helpers --- docs/source/vec3.rst | 33 +++++++++++++++++ docs/source/vec4.rst | 33 +++++++++++++++++ include/cglm/call/vec3.h | 12 +++++++ include/cglm/call/vec4.h | 12 +++++++ include/cglm/vec3.h | 54 ++++++++++++++++++++++++++++ include/cglm/vec4.h | 76 ++++++++++++++++++++++++++++++++++++++++ src/vec3.c | 18 ++++++++++ src/vec4.c | 20 ++++++++++- test/src/test_vec3.c | 16 ++++++++- test/src/test_vec4.c | 14 ++++++++ 10 files changed, 286 insertions(+), 2 deletions(-) diff --git a/docs/source/vec3.rst b/docs/source/vec3.rst index 86f17e4..1397700 100644 --- a/docs/source/vec3.rst +++ b/docs/source/vec3.rst @@ -46,6 +46,9 @@ Functions: #. :c:func:`glm_vec_scale_as` #. :c:func:`glm_vec_div` #. :c:func:`glm_vec_divs` +#. :c:func:`glm_vec_addadd` +#. :c:func:`glm_vec_subadd` +#. :c:func:`glm_vec_muladd` #. :c:func:`glm_vec_flipsign` #. :c:func:`glm_vec_flipsign_to` #. :c:func:`glm_vec_inv` @@ -220,6 +223,36 @@ Functions documentation | *[in]* **s** scalar | *[out]* **dest** result = (a[0] / s, a[1] / s, a[2] / s]) +.. c:function:: void glm_vec_addadd(vec3 a, vec3 b, vec3 dest) + + | add two vectors and add result to sum + | it applies += operator so dest must be initialized + + Parameters: + | *[in]* **a** vector 1 + | *[in]* **b** vector 2 + | *[out]* **dest** dest += (a + b) + +.. c:function:: void glm_vec_subadd(vec3 a, vec3 b, vec3 dest) + + | sub two vectors and add result to sum + | it applies += operator so dest must be initialized + + Parameters: + | *[in]* **a** vector 1 + | *[in]* **b** vector 2 + | *[out]* **dest** dest += (a - b) + +.. c:function:: void glm_vec_muladd(vec3 a, vec3 b, vec3 dest) + + | mul two vectors and add result to sum + | it applies += operator so dest must be initialized + + Parameters: + | *[in]* **a** vector 1 + | *[in]* **b** vector 2 + | *[out]* **dest** dest += (a * b) + .. c:function:: void glm_vec_flipsign(vec3 v) flip sign of all vec3 members diff --git a/docs/source/vec4.rst b/docs/source/vec4.rst index 89ac5c2..bd27978 100644 --- a/docs/source/vec4.rst +++ b/docs/source/vec4.rst @@ -38,6 +38,9 @@ Functions: #. :c:func:`glm_vec4_scale_as` #. :c:func:`glm_vec4_div` #. :c:func:`glm_vec4_divs` +#. :c:func:`glm_vec4_addadd` +#. :c:func:`glm_vec4_subadd` +#. :c:func:`glm_vec4_muladd` #. :c:func:`glm_vec4_flipsign` #. :c:func:`glm_vec_flipsign_to` #. :c:func:`glm_vec4_inv` @@ -205,6 +208,36 @@ Functions documentation | *[in]* **s** scalar | *[out]* **dest** result = (a[0] / s, a[1] / s, a[2] / s, a[3] / s) +.. c:function:: void glm_vec4_addadd(vec4 a, vec4 b, vec4 dest) + + | add two vectors and add result to sum + | it applies += operator so dest must be initialized + + Parameters: + | *[in]* **a** vector 1 + | *[in]* **b** vector 2 + | *[out]* **dest** dest += (a + b) + +.. c:function:: void glm_vec4_subadd(vec4 a, vec4 b, vec4 dest) + + | sub two vectors and add result to sum + | it applies += operator so dest must be initialized + + Parameters: + | *[in]* **a** vector 1 + | *[in]* **b** vector 2 + | *[out]* **dest** dest += (a - b) + +.. c:function:: void glm_vec4_muladd(vec4 a, vec4 b, vec4 dest) + + | mul two vectors and add result to sum + | it applies += operator so dest must be initialized + + Parameters: + | *[in]* **a** vector 1 + | *[in]* **b** vector 2 + | *[out]* **dest** dest += (a * b) + .. c:function:: void glm_vec4_flipsign(vec4 v) flip sign of all vec4 members diff --git a/include/cglm/call/vec3.h b/include/cglm/call/vec3.h index b2374e6..495ad0b 100644 --- a/include/cglm/call/vec3.h +++ b/include/cglm/call/vec3.h @@ -92,6 +92,18 @@ CGLM_EXPORT void glmc_vec_divs(vec3 a, float s, vec3 dest); +CGLM_EXPORT +void +glmc_vec_addadd(vec3 a, vec3 b, vec3 dest); + +CGLM_EXPORT +void +glmc_vec_subadd(vec3 a, vec3 b, vec3 dest); + +CGLM_EXPORT +void +glmc_vec_muladd(vec3 a, vec3 b, vec3 dest); + CGLM_EXPORT void glmc_vec_flipsign(vec3 v); diff --git a/include/cglm/call/vec4.h b/include/cglm/call/vec4.h index b460962..0fea5bf 100644 --- a/include/cglm/call/vec4.h +++ b/include/cglm/call/vec4.h @@ -93,6 +93,18 @@ CGLM_EXPORT void glmc_vec4_divs(vec4 v, float s, vec4 dest); +CGLM_EXPORT +void +glmc_vec4_addadd(vec4 a, vec4 b, vec4 dest); + +CGLM_EXPORT +void +glmc_vec4_subadd(vec4 a, vec4 b, vec4 dest); + +CGLM_EXPORT +void +glmc_vec4_muladd(vec4 a, vec4 b, vec4 dest); + CGLM_EXPORT void glmc_vec4_flipsign(vec4 v); diff --git a/include/cglm/vec3.h b/include/cglm/vec3.h index b3012b6..f803af6 100644 --- a/include/cglm/vec3.h +++ b/include/cglm/vec3.h @@ -37,6 +37,9 @@ CGLM_INLINE void glm_vec_scale_as(vec3 v, float s, vec3 dest); CGLM_INLINE void glm_vec_div(vec3 a, vec3 b, vec3 dest); CGLM_INLINE void glm_vec_divs(vec3 a, float s, vec3 dest); + CGLM_INLINE void glm_vec_addadd(vec3 a, vec3 b, vec3 dest); + CGLM_INLINE void glm_vec_subadd(vec3 a, vec3 b, vec3 dest); + CGLM_INLINE void glm_vec_muladd(vec3 a, vec3 b, vec3 dest); CGLM_INLINE void glm_vec_flipsign(vec3 v); CGLM_INLINE void glm_vec_inv(vec3 v); CGLM_INLINE void glm_vec_inv_to(vec3 v, vec3 dest); @@ -335,6 +338,57 @@ glm_vec_divs(vec3 v, float s, vec3 dest) { dest[2] = v[2] / s; } +/*! + * @brief add two vectors and add result to sum + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @param[out] dest dest += (a + b) + */ +CGLM_INLINE +void +glm_vec_addadd(vec3 a, vec3 b, vec3 dest) { + dest[0] += a[0] + b[0]; + dest[1] += a[1] + b[1]; + dest[2] += a[2] + b[2]; +} + +/*! + * @brief sub two vectors and add result to dest + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @param[out] dest dest += (a + b) + */ +CGLM_INLINE +void +glm_vec_subadd(vec3 a, vec3 b, vec3 dest) { + dest[0] += a[0] - b[0]; + dest[1] += a[1] - b[1]; + dest[2] += a[2] - b[2]; +} + +/*! + * @brief mul two vectors and add result to dest + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @param[out] dest dest += (a * b) + */ +CGLM_INLINE +void +glm_vec_muladd(vec3 a, vec3 b, vec3 dest) { + dest[0] += a[0] * b[0]; + dest[1] += a[1] * b[1]; + dest[2] += a[2] * b[2]; +} + /*! * @brief flip sign of all vec3 members * diff --git a/include/cglm/vec4.h b/include/cglm/vec4.h index e1319b9..c07a45e 100644 --- a/include/cglm/vec4.h +++ b/include/cglm/vec4.h @@ -37,6 +37,9 @@ CGLM_INLINE void glm_vec4_scale_as(vec4 v, float s, vec4 dest); CGLM_INLINE void glm_vec4_div(vec4 a, vec4 b, vec4 dest); CGLM_INLINE void glm_vec4_divs(vec4 v, float s, vec4 dest); + CGLM_INLINE void glm_vec4_addadd(vec4 a, vec4 b, vec4 dest); + CGLM_INLINE void glm_vec4_subadd(vec4 a, vec4 b, vec4 dest); + CGLM_INLINE void glm_vec4_muladd(vec4 a, vec4 b, vec4 dest); CGLM_INLINE void glm_vec4_flipsign(vec4 v); CGLM_INLINE void glm_vec4_inv(vec4 v); CGLM_INLINE void glm_vec4_inv_to(vec4 v, vec4 dest); @@ -396,6 +399,79 @@ glm_vec4_divs(vec4 v, float s, vec4 dest) { #endif } + +/*! + * @brief add two vectors and add result to sum + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @param[out] dest dest += (a + b) + */ +CGLM_INLINE +void +glm_vec4_addadd(vec4 a, vec4 b, vec4 dest) { +#if defined( __SSE__ ) || defined( __SSE2__ ) + _mm_store_ps(dest, _mm_add_ps(_mm_load_ps(dest), + _mm_add_ps(_mm_load_ps(a), + _mm_load_ps(b)))); +#else + dest[0] += a[0] + b[0]; + dest[1] += a[1] + b[1]; + dest[2] += a[2] + b[2]; + dest[3] += a[3] + b[3]; +#endif +} + +/*! + * @brief sub two vectors and add result to dest + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @param[out] dest dest += (a - b) + */ +CGLM_INLINE +void +glm_vec4_subadd(vec4 a, vec4 b, vec4 dest) { +#if defined( __SSE__ ) || defined( __SSE2__ ) + _mm_store_ps(dest, _mm_add_ps(_mm_load_ps(dest), + _mm_sub_ps(_mm_load_ps(a), + _mm_load_ps(b)))); +#else + dest[0] += a[0] - b[0]; + dest[1] += a[1] - b[1]; + dest[2] += a[2] - b[2]; + dest[3] += a[3] - b[3]; +#endif +} + +/*! + * @brief mul two vectors and add result to dest + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @param[out] dest dest += (a * b) + */ +CGLM_INLINE +void +glm_vec4_muladd(vec4 a, vec4 b, vec4 dest) { +#if defined( __SSE__ ) || defined( __SSE2__ ) + _mm_store_ps(dest, _mm_add_ps(_mm_load_ps(dest), + _mm_mul_ps(_mm_load_ps(a), + _mm_load_ps(b)))); +#else + dest[0] += a[0] * b[0]; + dest[1] += a[1] * b[1]; + dest[2] += a[2] * b[2]; + dest[3] += a[3] * b[3]; +#endif +} + /*! * @brief flip sign of all vec4 members * diff --git a/src/vec3.c b/src/vec3.c index b8553ec..d484446 100644 --- a/src/vec3.c +++ b/src/vec3.c @@ -122,6 +122,24 @@ glmc_vec_divs(vec3 a, float s, vec3 dest) { glm_vec_divs(a, s, dest); } +CGLM_EXPORT +void +glmc_vec_addadd(vec3 a, vec3 b, vec3 dest) { + glm_vec_addadd(a, b, dest); +} + +CGLM_EXPORT +void +glmc_vec_subadd(vec3 a, vec3 b, vec3 dest) { + glm_vec_subadd(a, b, dest); +} + +CGLM_EXPORT +void +glmc_vec_muladd(vec3 a, vec3 b, vec3 dest) { + glm_vec_muladd(a, b, dest); +} + CGLM_EXPORT void glmc_vec_flipsign(vec3 v) { diff --git a/src/vec4.c b/src/vec4.c index 282712c..c3df5d2 100644 --- a/src/vec4.c +++ b/src/vec4.c @@ -106,7 +106,7 @@ glmc_vec4_scale(vec4 v, float s, vec4 dest) { CGLM_EXPORT void -glmc_vec4_scale_as(vec3 v, float s, vec3 dest) { +glmc_vec4_scale_as(vec4 v, float s, vec4 dest) { glm_vec4_scale_as(v, s, dest); } @@ -122,6 +122,24 @@ glmc_vec4_divs(vec4 v, float s, vec4 dest) { glm_vec4_divs(v, s, dest); } +CGLM_EXPORT +void +glmc_vec4_addadd(vec4 a, vec4 b, vec4 dest) { + glm_vec4_addadd(a, b, dest); +} + +CGLM_EXPORT +void +glmc_vec4_subadd(vec4 a, vec4 b, vec4 dest) { + glm_vec4_subadd(a, b, dest); +} + +CGLM_EXPORT +void +glmc_vec4_muladd(vec4 a, vec4 b, vec4 dest) { + glm_vec4_muladd(a, b, dest); +} + CGLM_EXPORT void glmc_vec4_flipsign(vec4 v) { diff --git a/test/src/test_vec3.c b/test/src/test_vec3.c index c33e5ec..7c85d1f 100644 --- a/test/src/test_vec3.c +++ b/test/src/test_vec3.c @@ -9,7 +9,7 @@ void test_vec3(void **state) { - vec3 v, v1; + vec3 v, v1, v2; /* test zero */ glm_vec_zero(v); @@ -49,4 +49,18 @@ test_vec3(void **state) { glm_vec_scale(v1, 0.8, v1); glm_vec_scale_as(v, 0.8, v); test_assert_vec3_eq(v1, v); + + /* addadd, subadd, muladd */ + glm_vec_one(v); + + glm_vec_addadd(GLM_VEC3_ONE, GLM_VEC3_ONE, v); + assert_true(glmc_vec_eq_eps(v, 3)); + + glm_vec_subadd(GLM_VEC3_ONE, GLM_VEC3_ZERO, v); + assert_true(glmc_vec_eq_eps(v, 4)); + + glm_vec_broadcast(2, v1); + glm_vec_broadcast(3, v2); + glm_vec_muladd(v1, v2, v); + assert_true(glmc_vec_eq_eps(v, 10)); } diff --git a/test/src/test_vec4.c b/test/src/test_vec4.c index 60772a9..93ce9f7 100644 --- a/test/src/test_vec4.c +++ b/test/src/test_vec4.c @@ -109,4 +109,18 @@ test_vec4(void **state) { glm_vec4_scale(v1, 0.8, v1); glm_vec4_scale_as(v, 0.8, v); test_assert_vec4_eq(v1, v); + + /* addadd, subadd, muladd */ + glm_vec4_one(v); + + glm_vec4_addadd(GLM_VEC4_ONE, GLM_VEC4_ONE, v); + assert_true(glmc_vec4_eq_eps(v, 3)); + + glm_vec4_subadd(GLM_VEC4_ONE, GLM_VEC4_ZERO, v); + assert_true(glmc_vec4_eq_eps(v, 4)); + + glm_vec4_broadcast(2, v1); + glm_vec4_broadcast(3, v2); + glm_vec4_muladd(v1, v2, v); + assert_true(glmc_vec4_eq_eps(v, 10)); }