mat4.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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_mat_simd_avx_h
  8. #define cglm_mat_simd_avx_h
  9. #ifdef __AVX__
  10. #include "../../common.h"
  11. #include "../intrin.h"
  12. CGLM_INLINE
  13. void
  14. glm_mat4_scale_avx(mat4 m, float s) {
  15. __m256 y0, y1, y2, y3, y4;
  16. y0 = glmm_load256(m[0]); /* h g f e d c b a */
  17. y1 = glmm_load256(m[2]); /* p o n m l k j i */
  18. y2 = _mm256_broadcast_ss(&s);
  19. y3 = _mm256_mul_ps(y0, y2);
  20. y4 = _mm256_mul_ps(y1, y2);
  21. glmm_store256(m[0], y3);
  22. glmm_store256(m[2], y4);
  23. }
  24. /* TODO: this must be tested and compared to SSE version, may be slower!!! */
  25. CGLM_INLINE
  26. void
  27. glm_mat4_transp_avx(mat4 m, mat4 dest) {
  28. __m256 y0, y1, y2, y3;
  29. y0 = glmm_load256(m[0]); /* h g f e d c b a */
  30. y1 = glmm_load256(m[2]); /* p o n m l k j i */
  31. y2 = _mm256_unpacklo_ps(y0, y1); /* n f m e j b i a */
  32. y3 = _mm256_unpackhi_ps(y0, y1); /* p h o g l d k c */
  33. y0 = _mm256_permute2f128_ps(y2, y3, 0x20); /* l d k c j b i a */
  34. y1 = _mm256_permute2f128_ps(y2, y3, 0x31); /* p h o g n f m e */
  35. y2 = _mm256_unpacklo_ps(y0, y1); /* o k g c m i e a */
  36. y3 = _mm256_unpackhi_ps(y0, y1); /* p l h d n j f b */
  37. y0 = _mm256_permute2f128_ps(y2, y3, 0x20); /* n j f b m i e a */
  38. y1 = _mm256_permute2f128_ps(y2, y3, 0x31); /* p l h d o k g c */
  39. glmm_store256(dest[0], y0);
  40. glmm_store256(dest[2], y1);
  41. }
  42. CGLM_INLINE
  43. void
  44. glm_mat4_mul_avx(mat4 m1, mat4 m2, mat4 dest) {
  45. /* D = R * L (Column-Major) */
  46. __m256 y0, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11, y12, y13;
  47. __m256i yi0, yi1, yi2, yi3;
  48. y0 = glmm_load256(m2[0]); /* h g f e d c b a */
  49. y1 = glmm_load256(m2[2]); /* p o n m l k j i */
  50. y2 = glmm_load256(m1[0]); /* h g f e d c b a */
  51. y3 = glmm_load256(m1[2]); /* p o n m l k j i */
  52. /* 0x03: 0b00000011 */
  53. y4 = _mm256_permute2f128_ps(y2, y2, 0x03); /* d c b a h g f e */
  54. y5 = _mm256_permute2f128_ps(y3, y3, 0x03); /* l k j i p o n m */
  55. yi0 = _mm256_set_epi32(1, 1, 1, 1, 0, 0, 0, 0);
  56. yi1 = _mm256_set_epi32(3, 3, 3, 3, 2, 2, 2, 2);
  57. yi2 = _mm256_set_epi32(0, 0, 0, 0, 1, 1, 1, 1);
  58. yi3 = _mm256_set_epi32(2, 2, 2, 2, 3, 3, 3, 3);
  59. /* f f f f a a a a */
  60. /* h h h h c c c c */
  61. /* e e e e b b b b */
  62. /* g g g g d d d d */
  63. y6 = _mm256_permutevar_ps(y0, yi0);
  64. y7 = _mm256_permutevar_ps(y0, yi1);
  65. y8 = _mm256_permutevar_ps(y0, yi2);
  66. y9 = _mm256_permutevar_ps(y0, yi3);
  67. /* n n n n i i i i */
  68. /* p p p p k k k k */
  69. /* m m m m j j j j */
  70. /* o o o o l l l l */
  71. y10 = _mm256_permutevar_ps(y1, yi0);
  72. y11 = _mm256_permutevar_ps(y1, yi1);
  73. y12 = _mm256_permutevar_ps(y1, yi2);
  74. y13 = _mm256_permutevar_ps(y1, yi3);
  75. y0 = _mm256_mul_ps(y2, y6);
  76. y1 = _mm256_mul_ps(y2, y10);
  77. y0 = glmm256_fmadd(y3, y7, y0);
  78. y1 = glmm256_fmadd(y3, y11, y1);
  79. y0 = glmm256_fmadd(y4, y8, y0);
  80. y1 = glmm256_fmadd(y4, y12, y1);
  81. y0 = glmm256_fmadd(y5, y9, y0);
  82. y1 = glmm256_fmadd(y5, y13, y1);
  83. glmm_store256(dest[0], y0);
  84. glmm_store256(dest[2], y1);
  85. }
  86. #endif
  87. #endif /* cglm_mat_simd_avx_h */