| 1 | |
| 2 | |
| 3 | |
| 4 | #pragma once |
| 5 | |
| 6 | #include "common.h" |
| 7 | |
| 8 | #if GLM_ARCH & GLM_ARCH_SSE2_BIT |
| 9 | |
| 10 | GLM_FUNC_DECL glm_vec4 glm_vec4_dot(glm_vec4 v1, glm_vec4 v2); |
| 11 | GLM_FUNC_DECL glm_vec4 glm_vec1_dot(glm_vec4 v1, glm_vec4 v2); |
| 12 | |
| 13 | GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_length(glm_vec4 x) |
| 14 | { |
| 15 | glm_vec4 const dot0 = glm_vec4_dot(x, x); |
| 16 | glm_vec4 const sqt0 = _mm_sqrt_ps(dot0); |
| 17 | return sqt0; |
| 18 | } |
| 19 | |
| 20 | GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_distance(glm_vec4 p0, glm_vec4 p1) |
| 21 | { |
| 22 | glm_vec4 const sub0 = _mm_sub_ps(p0, p1); |
| 23 | glm_vec4 const len0 = glm_vec4_length(sub0); |
| 24 | return len0; |
| 25 | } |
| 26 | |
| 27 | GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_dot(glm_vec4 v1, glm_vec4 v2) |
| 28 | { |
| 29 | # if GLM_ARCH & GLM_ARCH_AVX_BIT |
| 30 | return _mm_dp_ps(v1, v2, 0xff); |
| 31 | # elif GLM_ARCH & GLM_ARCH_SSE3_BIT |
| 32 | glm_vec4 const mul0 = _mm_mul_ps(v1, v2); |
| 33 | glm_vec4 const hadd0 = _mm_hadd_ps(mul0, mul0); |
| 34 | glm_vec4 const hadd1 = _mm_hadd_ps(hadd0, hadd0); |
| 35 | return hadd1; |
| 36 | # else |
| 37 | glm_vec4 const mul0 = _mm_mul_ps(v1, v2); |
| 38 | glm_vec4 const swp0 = _mm_shuffle_ps(mul0, mul0, _MM_SHUFFLE(2, 3, 0, 1)); |
| 39 | glm_vec4 const add0 = _mm_add_ps(mul0, swp0); |
| 40 | glm_vec4 const swp1 = _mm_shuffle_ps(add0, add0, _MM_SHUFFLE(0, 1, 2, 3)); |
| 41 | glm_vec4 const add1 = _mm_add_ps(add0, swp1); |
| 42 | return add1; |
| 43 | # endif |
| 44 | } |
| 45 | |
| 46 | GLM_FUNC_QUALIFIER glm_vec4 glm_vec1_dot(glm_vec4 v1, glm_vec4 v2) |
| 47 | { |
| 48 | # if GLM_ARCH & GLM_ARCH_AVX_BIT |
| 49 | return _mm_dp_ps(v1, v2, 0xff); |
| 50 | # elif GLM_ARCH & GLM_ARCH_SSE3_BIT |
| 51 | glm_vec4 const mul0 = _mm_mul_ps(v1, v2); |
| 52 | glm_vec4 const had0 = _mm_hadd_ps(mul0, mul0); |
| 53 | glm_vec4 const had1 = _mm_hadd_ps(had0, had0); |
| 54 | return had1; |
| 55 | # else |
| 56 | glm_vec4 const mul0 = _mm_mul_ps(v1, v2); |
| 57 | glm_vec4 const mov0 = _mm_movehl_ps(mul0, mul0); |
| 58 | glm_vec4 const add0 = _mm_add_ps(mov0, mul0); |
| 59 | glm_vec4 const swp1 = _mm_shuffle_ps(add0, add0, 1); |
| 60 | glm_vec4 const add1 = _mm_add_ss(add0, swp1); |
| 61 | return add1; |
| 62 | # endif |
| 63 | } |
| 64 | |
| 65 | GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_cross(glm_vec4 v1, glm_vec4 v2) |
| 66 | { |
| 67 | glm_vec4 const swp0 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 0, 2, 1)); |
| 68 | glm_vec4 const swp1 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 1, 0, 2)); |
| 69 | glm_vec4 const swp2 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 0, 2, 1)); |
| 70 | glm_vec4 const swp3 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 1, 0, 2)); |
| 71 | glm_vec4 const mul0 = _mm_mul_ps(swp0, swp3); |
| 72 | glm_vec4 const mul1 = _mm_mul_ps(swp1, swp2); |
| 73 | glm_vec4 const sub0 = _mm_sub_ps(mul0, mul1); |
| 74 | return sub0; |
| 75 | } |
| 76 | |
| 77 | GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_normalize(glm_vec4 v) |
| 78 | { |
| 79 | glm_vec4 const dot0 = glm_vec4_dot(v, v); |
| 80 | glm_vec4 const isr0 = _mm_rsqrt_ps(dot0); |
| 81 | glm_vec4 const mul0 = _mm_mul_ps(v, isr0); |
| 82 | return mul0; |
| 83 | } |
| 84 | |
| 85 | GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_faceforward(glm_vec4 N, glm_vec4 I, glm_vec4 Nref) |
| 86 | { |
| 87 | glm_vec4 const dot0 = glm_vec4_dot(Nref, I); |
| 88 | glm_vec4 const sgn0 = glm_vec4_sign(dot0); |
| 89 | glm_vec4 const mul0 = _mm_mul_ps(sgn0, _mm_set1_ps(-1.0f)); |
| 90 | glm_vec4 const mul1 = _mm_mul_ps(N, mul0); |
| 91 | return mul1; |
| 92 | } |
| 93 | |
| 94 | GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_reflect(glm_vec4 I, glm_vec4 N) |
| 95 | { |
| 96 | glm_vec4 const dot0 = glm_vec4_dot(N, I); |
| 97 | glm_vec4 const mul0 = _mm_mul_ps(N, dot0); |
| 98 | glm_vec4 const mul1 = _mm_mul_ps(mul0, _mm_set1_ps(2.0f)); |
| 99 | glm_vec4 const sub0 = _mm_sub_ps(I, mul1); |
| 100 | return sub0; |
| 101 | } |
| 102 | |
| 103 | GLM_FUNC_QUALIFIER __m128 glm_vec4_refract(glm_vec4 I, glm_vec4 N, glm_vec4 eta) |
| 104 | { |
| 105 | glm_vec4 const dot0 = glm_vec4_dot(N, I); |
| 106 | glm_vec4 const mul0 = _mm_mul_ps(eta, eta); |
| 107 | glm_vec4 const mul1 = _mm_mul_ps(dot0, dot0); |
| 108 | glm_vec4 const sub0 = _mm_sub_ps(_mm_set1_ps(1.0f), mul0); |
| 109 | glm_vec4 const sub1 = _mm_sub_ps(_mm_set1_ps(1.0f), mul1); |
| 110 | glm_vec4 const mul2 = _mm_mul_ps(sub0, sub1); |
| 111 | |
| 112 | if(_mm_movemask_ps(_mm_cmplt_ss(mul2, _mm_set1_ps(0.0f))) == 0) |
| 113 | return _mm_set1_ps(0.0f); |
| 114 | |
| 115 | glm_vec4 const sqt0 = _mm_sqrt_ps(mul2); |
| 116 | glm_vec4 const mad0 = glm_vec4_fma(eta, dot0, sqt0); |
| 117 | glm_vec4 const mul4 = _mm_mul_ps(mad0, N); |
| 118 | glm_vec4 const mul5 = _mm_mul_ps(eta, I); |
| 119 | glm_vec4 const sub2 = _mm_sub_ps(mul5, mul4); |
| 120 | |
| 121 | return sub2; |
| 122 | } |
| 123 | |
| 124 | #endif |