affine.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  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_mat_avx_h
  8. #define cglm_affine_mat_avx_h
  9. #ifdef __AVX__
  10. #include "../../common.h"
  11. #include "../intrin.h"
  12. #include <immintrin.h>
  13. CGLM_INLINE
  14. void
  15. glm_mul_avx(mat4 m1, mat4 m2, mat4 dest) {
  16. /* D = R * L (Column-Major) */
  17. __m256 y0, y1, y2, y3, y4, y5, y6, y7, y8, y9;
  18. y0 = glmm_load256(m2[0]); /* h g f e d c b a */
  19. y1 = glmm_load256(m2[2]); /* p o n m l k j i */
  20. y2 = glmm_load256(m1[0]); /* h g f e d c b a */
  21. y3 = glmm_load256(m1[2]); /* p o n m l k j i */
  22. /* 0x03: 0b00000011 */
  23. y4 = _mm256_permute2f128_ps(y2, y2, 0x03); /* d c b a h g f e */
  24. y5 = _mm256_permute2f128_ps(y3, y3, 0x03); /* l k j i p o n m */
  25. /* f f f f a a a a */
  26. /* h h h h c c c c */
  27. /* e e e e b b b b */
  28. /* g g g g d d d d */
  29. y6 = _mm256_permutevar_ps(y0, _mm256_set_epi32(1, 1, 1, 1, 0, 0, 0, 0));
  30. y7 = _mm256_permutevar_ps(y0, _mm256_set_epi32(3, 3, 3, 3, 2, 2, 2, 2));
  31. y8 = _mm256_permutevar_ps(y0, _mm256_set_epi32(0, 0, 0, 0, 1, 1, 1, 1));
  32. y9 = _mm256_permutevar_ps(y0, _mm256_set_epi32(2, 2, 2, 2, 3, 3, 3, 3));
  33. glmm_store256(dest[0],
  34. _mm256_add_ps(_mm256_add_ps(_mm256_mul_ps(y2, y6),
  35. _mm256_mul_ps(y3, y7)),
  36. _mm256_add_ps(_mm256_mul_ps(y4, y8),
  37. _mm256_mul_ps(y5, y9))));
  38. /* n n n n i i i i */
  39. /* p p p p k k k k */
  40. /* m m m m j j j j */
  41. /* o o o o l l l l */
  42. y6 = _mm256_permutevar_ps(y1, _mm256_set_epi32(1, 1, 1, 1, 0, 0, 0, 0));
  43. y7 = _mm256_permutevar_ps(y1, _mm256_set_epi32(3, 3, 3, 3, 2, 2, 2, 2));
  44. y8 = _mm256_permutevar_ps(y1, _mm256_set_epi32(0, 0, 0, 0, 1, 1, 1, 1));
  45. y9 = _mm256_permutevar_ps(y1, _mm256_set_epi32(2, 2, 2, 2, 3, 3, 3, 3));
  46. glmm_store256(dest[2],
  47. _mm256_add_ps(_mm256_add_ps(_mm256_mul_ps(y2, y6),
  48. _mm256_mul_ps(y3, y7)),
  49. _mm256_add_ps(_mm256_mul_ps(y4, y8),
  50. _mm256_mul_ps(y5, y9))));
  51. }
  52. #endif
  53. #endif /* cglm_affine_mat_avx_h */