5.4 KB、212行 生 Blame 履歴
1/// @ref core
2/// @file glm/detail/func_geometric_simd.inl
3
4#include "../simd/geometric.h"
5
6#if GLM_ARCH & GLM_ARCH_SSE2_BIT
7
8namespace glm{
9namespace detail
10{
11 template<qualifier Q>
12 struct compute_length<4, float, Q, true>
13 {
14 GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& v)
15 {
16 return _mm_cvtss_f32(glm_vec4_length(v.data));
17 }
18 };
19
20 template<qualifier Q>
21 struct compute_distance<4, float, Q, true>
22 {
23 GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& p0, vec<4, float, Q> const& p1)
24 {
25 return _mm_cvtss_f32(glm_vec4_distance(p0.data, p1.data));
26 }
27 };
28
29 template<qualifier Q>
30 struct compute_dot<vec<4, float, Q>, float, true>
31 {
32 GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& x, vec<4, float, Q> const& y)
33 {
34 return _mm_cvtss_f32(glm_vec1_dot(x.data, y.data));
35 }
36 };
37
38 template<qualifier Q>
39 struct compute_dot<vec<3, float, Q>, float, true>
40 {
41 GLM_FUNC_QUALIFIER static float call(vec<3, float, Q> const& a, vec<3, float, Q> const& b)
42 {
43 return _mm_cvtss_f32(glm_vec3_dot(a.data, b.data)); // aligned as vec4
44 }
45 };
46
47 template<qualifier Q>
48 struct compute_cross<float, Q, true>
49 {
50 GLM_FUNC_QUALIFIER static vec<3, float, Q> call(vec<3, float, Q> const& a, vec<3, float, Q> const& b)
51 {
52 vec<4, float, Q> aa = xyzz(a);
53 vec<4, float, Q> bb = xyzz(b);
54 __m128 const xpd0 = glm_vec4_cross(aa.data, bb.data);
55
56 vec<3, float, Q> Result;
57 Result.data = xpd0;
58 return Result;
59 }
60
61 GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
62 {
63 vec<4, float, Q> Result;
64 Result.data = glm_vec4_cross(a.data, b.data);
65 return Result;
66 }
67 };
68
69 template<>
70 struct compute_normalize<4, float, aligned_lowp, true>
71 {
72 GLM_FUNC_QUALIFIER static vec<4, float, aligned_lowp> call(vec<4, float, aligned_lowp> const& v)
73 {
74 vec<4, float, aligned_lowp> Result;
75 Result.data = glm_vec4_normalize(v.data);
76 return Result;
77 }
78 };
79
80 template<>
81 struct compute_normalize<3, float, aligned_lowp, true>
82 {
83 GLM_FUNC_QUALIFIER static vec<3, float, aligned_lowp> call(vec<3, float, aligned_lowp> const& v)
84 {
85 vec<3, float, aligned_lowp> Result;
86 Result.data = glm_vec3_normalize_lowp(v.data);
87 return Result;
88 }
89 };
90
91 template<qualifier Q>
92 struct compute_normalize<4, float, Q, true>
93 {
94 GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v)
95 {
96 vec<4, float, Q> Result;
97 Result.data = glm_vec4_normalize(v.data);
98 return Result;
99 }
100 };
101
102 template<qualifier Q>
103 struct compute_normalize<3, float, Q, true>
104 {
105 GLM_FUNC_QUALIFIER static vec<3, float, Q> call(vec<3, float, Q> const& v)
106 {
107 vec<3, float, Q> Result;
108 Result.data = glm_vec3_normalize(v.data);
109 return Result;
110 }
111 };
112
113 template<qualifier Q>
114 struct compute_faceforward<4, float, Q, true>
115 {
116 GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& N, vec<4, float, Q> const& I, vec<4, float, Q> const& Nref)
117 {
118 vec<4, float, Q> Result;
119 Result.data = glm_vec4_faceforward(N.data, I.data, Nref.data);
120 return Result;
121 }
122 };
123
124 template<qualifier Q>
125 struct compute_reflect<4, float, Q, true>
126 {
127 GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& I, vec<4, float, Q> const& N)
128 {
129 vec<4, float, Q> Result;
130 Result.data = glm_vec4_reflect(I.data, N.data);
131 return Result;
132 }
133 };
134
135 template<qualifier Q>
136 struct compute_refract<4, float, Q, true>
137 {
138 GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& I, vec<4, float, Q> const& N, float eta)
139 {
140 vec<4, float, Q> Result;
141 Result.data = glm_vec4_refract(I.data, N.data, _mm_set1_ps(eta));
142 return Result;
143 }
144 };
145}//namespace detail
146}//namespace glm
147
148#elif GLM_ARCH & GLM_ARCH_NEON_BIT
149namespace glm{
150namespace detail
151{
152 template<qualifier Q>
153 struct compute_length<4, float, Q, true>
154 {
155 GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& v)
156 {
157 return sqrt(compute_dot<vec<4, float, Q>, float, true>::call(v, v));
158 }
159 };
160
161 template<qualifier Q>
162 struct compute_distance<4, float, Q, true>
163 {
164 GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& p0, vec<4, float, Q> const& p1)
165 {
166 return compute_length<4, float, Q, true>::call(p1 - p0);
167 }
168 };
169
170
171 template<qualifier Q>
172 struct compute_dot<vec<4, float, Q>, float, true>
173 {
174 GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& x, vec<4, float, Q> const& y)
175 {
176#if GLM_ARCH & GLM_ARCH_ARMV8_BIT
177 float32x4_t v = vmulq_f32(x.data, y.data);
178 return vaddvq_f32(v);
179#else // Armv7a with Neon
180 float32x4_t p = vmulq_f32(x.data, y.data);
181 float32x2_t v = vpadd_f32(vget_low_f32(p), vget_high_f32(p));
182 v = vpadd_f32(v, v);
183 return vget_lane_f32(v, 0);
184#endif
185 }
186 };
187
188 template<qualifier Q>
189 struct compute_normalize<4, float, Q, true>
190 {
191 GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v)
192 {
193 float32x4_t p = vmulq_f32(v.data, v.data);
194#if GLM_ARCH & GLM_ARCH_ARMV8_BIT
195 p = vpaddq_f32(p, p);
196 p = vpaddq_f32(p, p);
197#else
198 float32x2_t t = vpadd_f32(vget_low_f32(p), vget_high_f32(p));
199 t = vpadd_f32(t, t);
200 p = vcombine_f32(t, t);
201#endif
202
203 float32x4_t vd = vrsqrteq_f32(p);
204 vec<4, float, Q> Result;
205 Result.data = vmulq_f32(v.data, vd);
206 return Result;
207 }
208 };
209}//namespace detail
210}//namespace glm
211
212#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT