affine.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * Copyright (c), Recep Aslantas.
  3. *
  4. * MIT License (MIT), http://opensource.org/licenses/MIT
  5. * Full license can be found in the LICENSE file
  6. */
  7. #ifndef cglm_affine_neon_h
  8. #define cglm_affine_neon_h
  9. #if defined(CGLM_NEON_FP)
  10. #include "../../common.h"
  11. #include "../intrin.h"
  12. CGLM_INLINE
  13. void
  14. glm_mul_neon(mat4 m1, mat4 m2, mat4 dest) {
  15. /* D = R * L (Column-Major) */
  16. glmm_128 l, r0, r1, r2, r3, v0, v1, v2, v3;
  17. l = glmm_load(m1[0]);
  18. r0 = glmm_load(m2[0]);
  19. r1 = glmm_load(m2[1]);
  20. r2 = glmm_load(m2[2]);
  21. r3 = glmm_load(m2[3]);
  22. v0 = vmulq_f32(glmm_splat_x(r0), l);
  23. v1 = vmulq_f32(glmm_splat_x(r1), l);
  24. v2 = vmulq_f32(glmm_splat_x(r2), l);
  25. v3 = vmulq_f32(glmm_splat_x(r3), l);
  26. l = glmm_load(m1[1]);
  27. v0 = glmm_fmadd(glmm_splat_y(r0), l, v0);
  28. v1 = glmm_fmadd(glmm_splat_y(r1), l, v1);
  29. v2 = glmm_fmadd(glmm_splat_y(r2), l, v2);
  30. v3 = glmm_fmadd(glmm_splat_y(r3), l, v3);
  31. l = glmm_load(m1[2]);
  32. v0 = glmm_fmadd(glmm_splat_z(r0), l, v0);
  33. v1 = glmm_fmadd(glmm_splat_z(r1), l, v1);
  34. v2 = glmm_fmadd(glmm_splat_z(r2), l, v2);
  35. v3 = glmm_fmadd(glmm_splat_z(r3), l, v3);
  36. v3 = glmm_fmadd(glmm_splat_w(r3), glmm_load(m1[3]), v3);
  37. glmm_store(dest[0], v0);
  38. glmm_store(dest[1], v1);
  39. glmm_store(dest[2], v2);
  40. glmm_store(dest[3], v3);
  41. }
  42. CGLM_INLINE
  43. void
  44. glm_mul_rot_neon(mat4 m1, mat4 m2, mat4 dest) {
  45. /* D = R * L (Column-Major) */
  46. glmm_128 l, r0, r1, r2, v0, v1, v2;
  47. l = glmm_load(m1[0]);
  48. r0 = glmm_load(m2[0]);
  49. r1 = glmm_load(m2[1]);
  50. r2 = glmm_load(m2[2]);
  51. v0 = vmulq_f32(glmm_splat_x(r0), l);
  52. v1 = vmulq_f32(glmm_splat_x(r1), l);
  53. v2 = vmulq_f32(glmm_splat_x(r2), l);
  54. l = glmm_load(m1[1]);
  55. v0 = glmm_fmadd(glmm_splat_y(r0), l, v0);
  56. v1 = glmm_fmadd(glmm_splat_y(r1), l, v1);
  57. v2 = glmm_fmadd(glmm_splat_y(r2), l, v2);
  58. l = glmm_load(m1[2]);
  59. v0 = glmm_fmadd(glmm_splat_z(r0), l, v0);
  60. v1 = glmm_fmadd(glmm_splat_z(r1), l, v1);
  61. v2 = glmm_fmadd(glmm_splat_z(r2), l, v2);
  62. glmm_store(dest[0], v0);
  63. glmm_store(dest[1], v1);
  64. glmm_store(dest[2], v2);
  65. glmm_store(dest[3], glmm_load(m1[3]));
  66. }
  67. CGLM_INLINE
  68. void
  69. glm_inv_tr_neon(mat4 mat) {
  70. float32x4x4_t vmat;
  71. glmm_128 r0, r1, r2, x0;
  72. vmat = vld4q_f32(mat[0]);
  73. r0 = vmat.val[0];
  74. r1 = vmat.val[1];
  75. r2 = vmat.val[2];
  76. x0 = glmm_fmadd(r0, glmm_splat_w(r0),
  77. glmm_fmadd(r1, glmm_splat_w(r1),
  78. vmulq_f32(r2, glmm_splat_w(r2))));
  79. x0 = vnegq_f32(x0);
  80. glmm_store(mat[0], r0);
  81. glmm_store(mat[1], r1);
  82. glmm_store(mat[2], r2);
  83. glmm_store(mat[3], x0);
  84. mat[0][3] = 0.0f;
  85. mat[1][3] = 0.0f;
  86. mat[2][3] = 0.0f;
  87. mat[3][3] = 1.0f;
  88. /* TODO: ?
  89. zo = vget_high_f32(r3);
  90. vst1_lane_f32(&mat[0][3], zo, 0);
  91. vst1_lane_f32(&mat[1][3], zo, 0);
  92. vst1_lane_f32(&mat[2][3], zo, 0);
  93. vst1_lane_f32(&mat[3][3], zo, 1);
  94. */
  95. }
  96. #endif
  97. #endif /* cglm_affine_neon_h */