master
ブランチ master
ShaderPlayground / deps / glm / glm / detail / type_vec4_simd.inl
11.6 KB、463行 生 Blame 履歴
1#if GLM_ARCH & GLM_ARCH_SSE2_BIT
2
3namespace glm{
4namespace detail
5{
6# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR
7 template<qualifier Q, int E0, int E1, int E2, int E3>
8 struct _swizzle_base1<4, float, Q, E0,E1,E2,E3, true> : public _swizzle_base0<float, 4>
9 {
10 GLM_FUNC_QUALIFIER vec<4, float, Q> operator ()() const
11 {
12 __m128 data = *reinterpret_cast<__m128 const*>(&this->_buffer);
13
14 vec<4, float, Q> Result;
15# if GLM_ARCH & GLM_ARCH_AVX_BIT
16 Result.data = _mm_permute_ps(data, _MM_SHUFFLE(E3, E2, E1, E0));
17# else
18 Result.data = _mm_shuffle_ps(data, data, _MM_SHUFFLE(E3, E2, E1, E0));
19# endif
20 return Result;
21 }
22 };
23
24 template<qualifier Q, int E0, int E1, int E2, int E3>
25 struct _swizzle_base1<4, int, Q, E0,E1,E2,E3, true> : public _swizzle_base0<int, 4>
26 {
27 GLM_FUNC_QUALIFIER vec<4, int, Q> operator ()() const
28 {
29 __m128i data = *reinterpret_cast<__m128i const*>(&this->_buffer);
30
31 vec<4, int, Q> Result;
32 Result.data = _mm_shuffle_epi32(data, _MM_SHUFFLE(E3, E2, E1, E0));
33 return Result;
34 }
35 };
36
37 template<qualifier Q, int E0, int E1, int E2, int E3>
38 struct _swizzle_base1<4, uint, Q, E0,E1,E2,E3, true> : public _swizzle_base0<uint, 4>
39 {
40 GLM_FUNC_QUALIFIER vec<4, uint, Q> operator ()() const
41 {
42 __m128i data = *reinterpret_cast<__m128i const*>(&this->_buffer);
43
44 vec<4, uint, Q> Result;
45 Result.data = _mm_shuffle_epi32(data, _MM_SHUFFLE(E3, E2, E1, E0));
46 return Result;
47 }
48 };
49# endif// GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR
50
51 template<qualifier Q>
52 struct compute_vec4_add<float, Q, true>
53 {
54 static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
55 {
56 vec<4, float, Q> Result;
57 Result.data = _mm_add_ps(a.data, b.data);
58 return Result;
59 }
60 };
61
62# if GLM_ARCH & GLM_ARCH_AVX_BIT
63 template<qualifier Q>
64 struct compute_vec4_add<double, Q, true>
65 {
66 static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b)
67 {
68 vec<4, double, Q> Result;
69 Result.data = _mm256_add_pd(a.data, b.data);
70 return Result;
71 }
72 };
73# endif
74
75 template<qualifier Q>
76 struct compute_vec4_sub<float, Q, true>
77 {
78 static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
79 {
80 vec<4, float, Q> Result;
81 Result.data = _mm_sub_ps(a.data, b.data);
82 return Result;
83 }
84 };
85
86# if GLM_ARCH & GLM_ARCH_AVX_BIT
87 template<qualifier Q>
88 struct compute_vec4_sub<double, Q, true>
89 {
90 static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b)
91 {
92 vec<4, double, Q> Result;
93 Result.data = _mm256_sub_pd(a.data, b.data);
94 return Result;
95 }
96 };
97# endif
98
99 template<qualifier Q>
100 struct compute_vec4_mul<float, Q, true>
101 {
102 static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
103 {
104 vec<4, float, Q> Result;
105 Result.data = _mm_mul_ps(a.data, b.data);
106 return Result;
107 }
108 };
109
110# if GLM_ARCH & GLM_ARCH_AVX_BIT
111 template<qualifier Q>
112 struct compute_vec4_mul<double, Q, true>
113 {
114 static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b)
115 {
116 vec<4, double, Q> Result;
117 Result.data = _mm256_mul_pd(a.data, b.data);
118 return Result;
119 }
120 };
121# endif
122
123 template<qualifier Q>
124 struct compute_vec4_div<float, Q, true>
125 {
126 static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
127 {
128 vec<4, float, Q> Result;
129 Result.data = _mm_div_ps(a.data, b.data);
130 return Result;
131 }
132 };
133
134 # if GLM_ARCH & GLM_ARCH_AVX_BIT
135 template<qualifier Q>
136 struct compute_vec4_div<double, Q, true>
137 {
138 static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b)
139 {
140 vec<4, double, Q> Result;
141 Result.data = _mm256_div_pd(a.data, b.data);
142 return Result;
143 }
144 };
145# endif
146
147 template<>
148 struct compute_vec4_div<float, aligned_lowp, true>
149 {
150 static vec<4, float, aligned_lowp> call(vec<4, float, aligned_lowp> const& a, vec<4, float, aligned_lowp> const& b)
151 {
152 vec<4, float, aligned_lowp> Result;
153 Result.data = _mm_mul_ps(a.data, _mm_rcp_ps(b.data));
154 return Result;
155 }
156 };
157
158 template<typename T, qualifier Q>
159 struct compute_vec4_and<T, Q, true, 32, true>
160 {
161 static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
162 {
163 vec<4, T, Q> Result;
164 Result.data = _mm_and_si128(a.data, b.data);
165 return Result;
166 }
167 };
168
169# if GLM_ARCH & GLM_ARCH_AVX2_BIT
170 template<typename T, qualifier Q>
171 struct compute_vec4_and<T, Q, true, 64, true>
172 {
173 static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
174 {
175 vec<4, T, Q> Result;
176 Result.data = _mm256_and_si256(a.data, b.data);
177 return Result;
178 }
179 };
180# endif
181
182 template<typename T, qualifier Q>
183 struct compute_vec4_or<T, Q, true, 32, true>
184 {
185 static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
186 {
187 vec<4, T, Q> Result;
188 Result.data = _mm_or_si128(a.data, b.data);
189 return Result;
190 }
191 };
192
193# if GLM_ARCH & GLM_ARCH_AVX2_BIT
194 template<typename T, qualifier Q>
195 struct compute_vec4_or<T, Q, true, 64, true>
196 {
197 static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
198 {
199 vec<4, T, Q> Result;
200 Result.data = _mm256_or_si256(a.data, b.data);
201 return Result;
202 }
203 };
204# endif
205
206 template<typename T, qualifier Q>
207 struct compute_vec4_xor<T, Q, true, 32, true>
208 {
209 static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
210 {
211 vec<4, T, Q> Result;
212 Result.data = _mm_xor_si128(a.data, b.data);
213 return Result;
214 }
215 };
216
217# if GLM_ARCH & GLM_ARCH_AVX2_BIT
218 template<typename T, qualifier Q>
219 struct compute_vec4_xor<T, Q, true, 64, true>
220 {
221 static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
222 {
223 vec<4, T, Q> Result;
224 Result.data = _mm256_xor_si256(a.data, b.data);
225 return Result;
226 }
227 };
228# endif
229
230 template<typename T, qualifier Q>
231 struct compute_vec4_shift_left<T, Q, true, 32, true>
232 {
233 static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
234 {
235 vec<4, T, Q> Result;
236 Result.data = _mm_sll_epi32(a.data, b.data);
237 return Result;
238 }
239 };
240
241# if GLM_ARCH & GLM_ARCH_AVX2_BIT
242 template<typename T, qualifier Q>
243 struct compute_vec4_shift_left<T, Q, true, 64, true>
244 {
245 static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
246 {
247 vec<4, T, Q> Result;
248 Result.data = _mm256_sll_epi64(a.data, b.data);
249 return Result;
250 }
251 };
252# endif
253
254 template<typename T, qualifier Q>
255 struct compute_vec4_shift_right<T, Q, true, 32, true>
256 {
257 static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
258 {
259 vec<4, T, Q> Result;
260 Result.data = _mm_srl_epi32(a.data, b.data);
261 return Result;
262 }
263 };
264
265# if GLM_ARCH & GLM_ARCH_AVX2_BIT
266 template<typename T, qualifier Q>
267 struct compute_vec4_shift_right<T, Q, true, 64, true>
268 {
269 static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
270 {
271 vec<4, T, Q> Result;
272 Result.data = _mm256_srl_epi64(a.data, b.data);
273 return Result;
274 }
275 };
276# endif
277
278 template<typename T, qualifier Q>
279 struct compute_vec4_bitwise_not<T, Q, true, 32, true>
280 {
281 static vec<4, T, Q> call(vec<4, T, Q> const& v)
282 {
283 vec<4, T, Q> Result;
284 Result.data = _mm_xor_si128(v.data, _mm_set1_epi32(-1));
285 return Result;
286 }
287 };
288
289# if GLM_ARCH & GLM_ARCH_AVX2_BIT
290 template<typename T, qualifier Q>
291 struct compute_vec4_bitwise_not<T, Q, true, 64, true>
292 {
293 static vec<4, T, Q> call(vec<4, T, Q> const& v)
294 {
295 vec<4, T, Q> Result;
296 Result.data = _mm256_xor_si256(v.data, _mm_set1_epi32(-1));
297 return Result;
298 }
299 };
300# endif
301
302 template<qualifier Q>
303 struct compute_vec4_equal<float, Q, false, 32, true>
304 {
305 static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2)
306 {
307 return _mm_movemask_ps(_mm_cmpeq_ps(v1.data, v2.data)) != 0;
308 }
309 };
310
311# if GLM_ARCH & GLM_ARCH_SSE41_BIT
312 template<qualifier Q>
313 struct compute_vec4_equal<int, Q, true, 32, true>
314 {
315 static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2)
316 {
317 //return _mm_movemask_epi8(_mm_cmpeq_epi32(v1.data, v2.data)) != 0;
318 __m128i neq = _mm_xor_si128(v1.data, v2.data);
319 return _mm_test_all_zeros(neq, neq) == 0;
320 }
321 };
322# endif
323
324 template<qualifier Q>
325 struct compute_vec4_nequal<float, Q, false, 32, true>
326 {
327 static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2)
328 {
329 return _mm_movemask_ps(_mm_cmpneq_ps(v1.data, v2.data)) != 0;
330 }
331 };
332
333# if GLM_ARCH & GLM_ARCH_SSE41_BIT
334 template<qualifier Q>
335 struct compute_vec4_nequal<int, Q, true, 32, true>
336 {
337 static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2)
338 {
339 //return _mm_movemask_epi8(_mm_cmpneq_epi32(v1.data, v2.data)) != 0;
340 __m128i neq = _mm_xor_si128(v1.data, v2.data);
341 return _mm_test_all_zeros(neq, neq) != 0;
342 }
343 };
344# endif
345}//namespace detail
346
347 template<>
348 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(float _s) :
349 data(_mm_set1_ps(_s))
350 {}
351
352 template<>
353 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(float _s) :
354 data(_mm_set1_ps(_s))
355 {}
356
357 template<>
358 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(float _s) :
359 data(_mm_set1_ps(_s))
360 {}
361
362# if GLM_ARCH & GLM_ARCH_AVX_BIT
363 template<>
364 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_lowp>::vec(double _s) :
365 data(_mm256_set1_pd(_s))
366 {}
367
368 template<>
369 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_mediump>::vec(double _s) :
370 data(_mm256_set1_pd(_s))
371 {}
372
373 template<>
374 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_highp>::vec(double _s) :
375 data(_mm256_set1_pd(_s))
376 {}
377# endif
378
379 template<>
380 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_lowp>::vec(int _s) :
381 data(_mm_set1_epi32(_s))
382 {}
383
384 template<>
385 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_mediump>::vec(int _s) :
386 data(_mm_set1_epi32(_s))
387 {}
388
389 template<>
390 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(int _s) :
391 data(_mm_set1_epi32(_s))
392 {}
393
394# if GLM_ARCH & GLM_ARCH_AVX2_BIT
395 template<>
396 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_lowp>::vec(detail::int64 _s) :
397 data(_mm256_set1_epi64x(_s))
398 {}
399
400 template<>
401 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_mediump>::vec(detail::int64 _s) :
402 data(_mm256_set1_epi64x(_s))
403 {}
404
405 template<>
406 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_highp>::vec(detail::int64 _s) :
407 data(_mm256_set1_epi64x(_s))
408 {}
409# endif
410
411 template<>
412 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(float _x, float _y, float _z, float _w) :
413 data(_mm_set_ps(_w, _z, _y, _x))
414 {}
415
416 template<>
417 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(float _x, float _y, float _z, float _w) :
418 data(_mm_set_ps(_w, _z, _y, _x))
419 {}
420
421 template<>
422 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(float _x, float _y, float _z, float _w) :
423 data(_mm_set_ps(_w, _z, _y, _x))
424 {}
425
426 template<>
427 template<>
428 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_lowp>::vec(int _x, int _y, int _z, int _w) :
429 data(_mm_set_epi32(_w, _z, _y, _x))
430 {}
431
432 template<>
433 template<>
434 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_mediump>::vec(int _x, int _y, int _z, int _w) :
435 data(_mm_set_epi32(_w, _z, _y, _x))
436 {}
437
438 template<>
439 template<>
440 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(int _x, int _y, int _z, int _w) :
441 data(_mm_set_epi32(_w, _z, _y, _x))
442 {}
443
444 template<>
445 template<>
446 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(int _x, int _y, int _z, int _w) :
447 data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x)))
448 {}
449
450 template<>
451 template<>
452 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(int _x, int _y, int _z, int _w) :
453 data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x)))
454 {}
455
456 template<>
457 template<>
458 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(int _x, int _y, int _z, int _w) :
459 data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x)))
460 {}
461}//namespace glm
462
463#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT