LCOV - code coverage report
Current view: top level - core/geom - SPSIMD.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 11 11 100.0 %
Date: 2024-05-12 00:16:13 Functions: 0 0 -

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2022 Roman Katuntsev <sbkarr@stappler.org>
       3             : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       4             : 
       5             : Permission is hereby granted, free of charge, to any person obtaining a copy
       6             : of this software and associated documentation files (the "Software"), to deal
       7             : in the Software without restriction, including without limitation the rights
       8             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9             : copies of the Software, and to permit persons to whom the Software is
      10             : furnished to do so, subject to the following conditions:
      11             : 
      12             : The above copyright notice and this permission notice shall be included in
      13             : all copies or substantial portions of the Software.
      14             : 
      15             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21             : THE SOFTWARE.
      22             : **/
      23             : 
      24             : #ifndef STAPPLER_GEOM_SPSIMD_H_
      25             : #define STAPPLER_GEOM_SPSIMD_H_
      26             : 
      27             : #include "SPCommon.h"
      28             : 
      29             : #define SP_SIMD_DEBUG 0
      30             : 
      31             : #if SP_SIMD_DEBUG
      32             : #define SP_ATTR_OPTIMIZE_FN
      33             : #define SP_ATTR_OPTIMIZE_INLINE_FN
      34             : #else
      35             : // mostly to debug SIMD in ASM, maybe disable for NDEBUG?
      36             : #if __clang__
      37             : #define SP_ATTR_OPTIMIZE_FN
      38             : #define SP_ATTR_OPTIMIZE_INLINE_FN __attribute__((always_inline))
      39             : #else
      40             : #define SP_ATTR_OPTIMIZE_FN __attribute__((optimize(3)))
      41             : #define SP_ATTR_OPTIMIZE_INLINE_FN __attribute__((optimize(3),always_inline))
      42             : #endif
      43             : #endif
      44             : 
      45             : #define SP_GEOM_DEFAULT_SIMD_SSE 1
      46             : #define SP_GEOM_DEFAULT_SIMD_NEON 2
      47             : #define SP_GEOM_DEFAULT_SIMD_NEON64 3
      48             : 
      49             : #if __SSE__
      50             : #define SP_GEOM_DEFAULT_SIMD SP_GEOM_DEFAULT_SIMD_SSE
      51             : #define SP_GEOM_DEFAULT_SIMD_NAMESPACE sse
      52             : #elif __arm__
      53             : #define SP_GEOM_DEFAULT_SIMD SP_GEOM_DEFAULT_SIMD_NEON
      54             : #define SP_GEOM_DEFAULT_SIMD_NAMESPACE neon
      55             : #elif __aarch64__
      56             : #define SP_GEOM_DEFAULT_SIMD SP_GEOM_DEFAULT_SIMD_NEON64
      57             : #define SP_GEOM_DEFAULT_SIMD_NAMESPACE neon64
      58             : #else
      59             : #define SP_GEOM_DEFAULT_SIMD SP_GEOM_DEFAULT_SIMD_SSE
      60             : #define SP_GEOM_DEFAULT_SIMD_NAMESPACE sse
      61             : #endif
      62             : 
      63             : #if SP_GEOM_DEFAULT_SIMD == SP_GEOM_DEFAULT_SIMD_NEON
      64             : #include "simde/arm/neon.h"
      65             : #include "simde/x86/sse.h"
      66             : #else
      67             : #include "simde/x86/sse.h"
      68             : #endif
      69             : 
      70             : // Defined by build system
      71             : // If SP_DEDICATED_SIMD is defined, replacements for SIMD on other platforms is not available
      72             : // If SP_DEDICATED_SIMD is not defined, you can use simd::neon on sse or simd::sse on NEON
      73             : #ifdef SP_DEDICATED_SIMD
      74             : #if SP_GEOM_DEFAULT_SIMD == SP_GEOM_DEFAULT_SIMD_NEON
      75             : #include "SPSIMD_Neon.h"
      76             : #elif SP_GEOM_DEFAULT_SIMD == SP_GEOM_DEFAULT_SIMD_NEON64
      77             : #include "SPSIMD_Neon64.h"
      78             : #else
      79             : #include "SPSIMD_Sse.h"
      80             : #endif
      81             : #else
      82             : #include "SPSIMD_Sse.h"
      83             : #include "SPSIMD_Neon.h"
      84             : #include "SPSIMD_Neon64.h"
      85             : #endif
      86             : 
      87             : 
      88             : namespace STAPPLER_VERSIONIZED stappler::simd {
      89             : 
      90             : using f32x4 = SP_GEOM_DEFAULT_SIMD_NAMESPACE::f32x4;
      91             : 
      92             : SP_ATTR_OPTIMIZE_INLINE_FN inline f32x4 load(float v1, float v2, float v3, float v4) {
      93             :         return SP_GEOM_DEFAULT_SIMD_NAMESPACE::load(v1, v2, v3, v4);
      94             : }
      95             : 
      96             : SP_ATTR_OPTIMIZE_INLINE_FN inline f32x4 load(const float v[4]) {
      97      141700 :         return SP_GEOM_DEFAULT_SIMD_NAMESPACE::load(v);
      98             : }
      99             : 
     100             : SP_ATTR_OPTIMIZE_INLINE_FN inline f32x4 load(float v) {
     101       98453 :         return SP_GEOM_DEFAULT_SIMD_NAMESPACE::load(v);
     102             : }
     103             : 
     104             : SP_ATTR_OPTIMIZE_INLINE_FN inline void store(float target[4], const f32x4 &v) {
     105             :         SP_GEOM_DEFAULT_SIMD_NAMESPACE::store(target, v);
     106      141337 : }
     107             : 
     108             : SP_ATTR_OPTIMIZE_INLINE_FN inline f32x4 mul(const f32x4 &v1, const f32x4 &v2) {
     109       98478 :         return SP_GEOM_DEFAULT_SIMD_NAMESPACE::mul(v1, v2);
     110             : }
     111             : 
     112             : SP_ATTR_OPTIMIZE_INLINE_FN inline f32x4 div(const f32x4 &v1, const f32x4 &v2) {
     113             :         return SP_GEOM_DEFAULT_SIMD_NAMESPACE::div(v1, v2);
     114             : }
     115             : 
     116             : SP_ATTR_OPTIMIZE_INLINE_FN inline f32x4 add(const f32x4 &v1, const f32x4 &v2) {
     117       43585 :         return SP_GEOM_DEFAULT_SIMD_NAMESPACE::add(v1, v2);
     118             : }
     119             : 
     120             : SP_ATTR_OPTIMIZE_INLINE_FN inline f32x4 sub(const f32x4 &v1, const f32x4 &v2) {
     121             :         return SP_GEOM_DEFAULT_SIMD_NAMESPACE::sub(v1, v2);
     122             : }
     123             : 
     124             : SP_ATTR_OPTIMIZE_INLINE_FN inline f32x4 rsqrt(const f32x4 &v) {
     125             :         return SP_GEOM_DEFAULT_SIMD_NAMESPACE::rsqrt(v);
     126             : }
     127             : 
     128             : SP_ATTR_OPTIMIZE_INLINE_FN inline f32x4 load1(float v) {
     129             :         return SP_GEOM_DEFAULT_SIMD_NAMESPACE::load1(v);
     130             : }
     131             : 
     132             : SP_ATTR_OPTIMIZE_INLINE_FN inline void store1(float *target, const f32x4 &v) {
     133             :         SP_GEOM_DEFAULT_SIMD_NAMESPACE::store1(target, v);
     134             : }
     135             : 
     136             : SP_ATTR_OPTIMIZE_INLINE_FN inline f32x4 mul1(const f32x4 &v1, const f32x4 &v2) {
     137             :         return SP_GEOM_DEFAULT_SIMD_NAMESPACE::mul1(v1, v2);
     138             : }
     139             : 
     140             : SP_ATTR_OPTIMIZE_INLINE_FN inline f32x4 add1(const f32x4 &v1, const f32x4 &v2) {
     141             :         return SP_GEOM_DEFAULT_SIMD_NAMESPACE::add1(v1, v2);
     142             : }
     143             : 
     144             : SP_ATTR_OPTIMIZE_INLINE_FN inline f32x4 sub1(const f32x4 &v1, const f32x4 &v2) {
     145             :         return SP_GEOM_DEFAULT_SIMD_NAMESPACE::sub1(v1, v2);
     146             : }
     147             : 
     148             : SP_ATTR_OPTIMIZE_INLINE_FN inline f32x4 rsqrt1(const f32x4 &v) {
     149             :         return SP_GEOM_DEFAULT_SIMD_NAMESPACE::rsqrt1(v);
     150             : }
     151             : 
     152             : SP_ATTR_OPTIMIZE_INLINE_FN inline void add(const float a[4], const float b[4], float dst[4]) {
     153             :         store(dst, add(load(a), load(b)));
     154          50 : }
     155             : 
     156             : SP_ATTR_OPTIMIZE_INLINE_FN inline void add(const float a[4], const float &b, float dst[4]) {
     157             :         store(dst, add(load(a), load(b)));
     158             : }
     159             : 
     160             : SP_ATTR_OPTIMIZE_INLINE_FN inline void sub(const float a[4], const float b[4], float dst[4]) {
     161             :         store(dst, sub(load(a), load(b)));
     162             : }
     163             : 
     164             : SP_ATTR_OPTIMIZE_INLINE_FN inline void sub(const float a[4], const float &b, float dst[4]) {
     165             :         store(dst, sub(load(a), load(b)));
     166             : }
     167             : 
     168             : SP_ATTR_OPTIMIZE_INLINE_FN inline void multiply(const float a[4], const float b[4], float dst[4]) {
     169             :         store(dst, mul(load(a), load(b)));
     170    30692772 : }
     171             : 
     172             : SP_ATTR_OPTIMIZE_INLINE_FN inline void multiply(const float a[4], const float &b, float dst[4]) {
     173             :         store(dst, mul(load(a), load(b)));
     174             : }
     175             : 
     176             : SP_ATTR_OPTIMIZE_INLINE_FN inline void divide(const float a[4], const float b[4], float dst[4]) {
     177             :         store(dst, div(load(a), load(b)));
     178             : }
     179             : 
     180             : SP_ATTR_OPTIMIZE_INLINE_FN inline void divide(const float a[4], const float &b, float dst[4]) {
     181             :         store(dst, div(load(a), load(b)));
     182             : }
     183             : 
     184             : SP_ATTR_OPTIMIZE_INLINE_FN inline void addMat4Scalar(const float m[16], float scalar, float dst[16]) {
     185             :         SP_GEOM_DEFAULT_SIMD_NAMESPACE::addMat4Scalar(m, scalar, dst);
     186             : }
     187             : 
     188             : SP_ATTR_OPTIMIZE_INLINE_FN inline void addMat4(const float m1[16], const float m2[16], float dst[16]) {
     189             :         SP_GEOM_DEFAULT_SIMD_NAMESPACE::addMat4(m1, m2, dst);
     190             : }
     191             : 
     192             : SP_ATTR_OPTIMIZE_INLINE_FN inline void subtractMat4(const float m1[16], const float m2[16], float dst[16]) {
     193             :         SP_GEOM_DEFAULT_SIMD_NAMESPACE::subtractMat4(m1, m2, dst);
     194             : }
     195             : 
     196             : SP_ATTR_OPTIMIZE_INLINE_FN inline void multiplyMat4Scalar(const float m[16], float scalar, float dst[16]) {
     197             :         SP_GEOM_DEFAULT_SIMD_NAMESPACE::multiplyMat4Scalar(m, scalar, dst);
     198       82100 : }
     199             : 
     200             : SP_ATTR_OPTIMIZE_INLINE_FN inline void multiplyMat4(const float m1[16], const float m2[16], float dst[16]) {
     201             :         SP_GEOM_DEFAULT_SIMD_NAMESPACE::multiplyMat4(m1, m2, dst);
     202     2697348 : }
     203             : 
     204             : SP_ATTR_OPTIMIZE_INLINE_FN inline void negateMat4(const float m[16], float dst[16]) {
     205             :         SP_GEOM_DEFAULT_SIMD_NAMESPACE::negateMat4(m, dst);
     206             : }
     207             : 
     208             : SP_ATTR_OPTIMIZE_INLINE_FN inline void transposeMat4(const float m[16], float dst[16]) {
     209             :         SP_GEOM_DEFAULT_SIMD_NAMESPACE::transposeMat4(m, dst);
     210             : }
     211             : 
     212             : SP_ATTR_OPTIMIZE_INLINE_FN inline void transformVec4Components(const float m[16], float x, float y, float z, float w, float dst[4]) {
     213             :         SP_GEOM_DEFAULT_SIMD_NAMESPACE::transformVec4Components(m, x, y, z, w, dst);
     214        7009 : }
     215             : 
     216             : SP_ATTR_OPTIMIZE_INLINE_FN inline void transformVec4(const float m[16], const float v[4], float dst[4]) {
     217             :         SP_GEOM_DEFAULT_SIMD_NAMESPACE::transformVec4(m, v, dst);
     218             : }
     219             : 
     220             : SP_ATTR_OPTIMIZE_INLINE_FN inline void crossVec3(const float v1[3], const float v2[3], float dst[3]) {
     221             :         SP_GEOM_DEFAULT_SIMD_NAMESPACE::crossVec3(v1, v2, dst);
     222         200 : }
     223             : 
     224             : // input for test A->B vs C->D (ax, ay, bx, by), (cx, cy, dx, dy)
     225             : SP_ATTR_OPTIMIZE_INLINE_FN inline bool isVec2BboxIntersects(const f32x4 & v1, const f32x4 & v2, f32x4 &isect) {
     226             :         return SP_GEOM_DEFAULT_SIMD_NAMESPACE::isVec2BboxIntersects(v1, v2, isect);
     227             : }
     228             : 
     229             : }
     230             : 
     231             : #endif /* STAPPLER_GEOM_SPSIMD_H_ */

Generated by: LCOV version 1.14