1 | /* graphene-simd4f.c |
2 | * |
3 | * SPDX-License-Identifier: MIT |
4 | * |
5 | * Copyright 2014 Emmanuele Bassi |
6 | * |
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
8 | * of this software and associated documentation files (the "Software"), to deal |
9 | * in the Software without restriction, including without limitation the rights |
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
11 | * copies of the Software, and to permit persons to whom the Software is |
12 | * furnished to do so, subject to the following conditions: |
13 | * |
14 | * The above copyright notice and this permission notice shall be included in |
15 | * all copies or substantial portions of the Software. |
16 | * |
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
23 | * THE SOFTWARE. |
24 | */ |
25 | |
26 | /** |
27 | * SECTION:graphene-simd4f |
28 | * @Title: SIMD vector |
29 | * @short_description: Low level floating point 4-sized vector |
30 | * |
31 | * The #graphene_simd4f_t type wraps a platform specific implementation of |
32 | * a vector of four floating point values. |
33 | * |
34 | * Graphene can be compiled to use different implementations of the SIMD |
35 | * types, and will generally prefer the faster hardware-backed implementation |
36 | * if one is available. |
37 | * |
38 | * The #graphene_simd4f_t should be treated as an opaque, integral type; |
39 | * you cannot access its components directly, and you can only operate on |
40 | * all components at the same time. |
41 | */ |
42 | |
43 | #include "graphene-private.h" |
44 | #include "graphene-simd4f.h" |
45 | |
46 | #include <string.h> |
47 | #include <math.h> |
48 | |
49 | /** |
50 | * graphene_simd4f_t: |
51 | * |
52 | * A vector type containing four floating point values. |
53 | * |
54 | * The contents of the #graphene_simd4f_t type are private and |
55 | * cannot be directly accessed; use the provided API instead. |
56 | * |
57 | * Since: 1.0 |
58 | */ |
59 | |
60 | /* fast paths are all defined in the graphene-simd4f.h header */ |
61 | #if defined(GRAPHENE_USE_SSE) || defined(GRAPHENE_USE_GCC) || defined(GRAPHENE_USE_ARM_NEON) |
62 | |
63 | /** |
64 | * graphene_simd4f_init: |
65 | * @x: the first component of the vector |
66 | * @y: the second component of the vector |
67 | * @z: the third component of the vector |
68 | * @w: the fourth component of the vector |
69 | * |
70 | * Initializes a #graphene_simd4f_t with the given values. |
71 | * |
72 | * Returns: the initialized #graphene_simd4f_t |
73 | * |
74 | * Since: 1.0 |
75 | */ |
76 | graphene_simd4f_t |
77 | (graphene_simd4f_init) (float x, |
78 | float y, |
79 | float z, |
80 | float w) |
81 | { |
82 | return graphene_simd4f_init (x, y, z, w); |
83 | } |
84 | |
85 | /** |
86 | * graphene_simd4f_init_zero: |
87 | * |
88 | * Initializes a #graphene_simd4f_t with 0 in all components. |
89 | * |
90 | * Returns: the initialized #graphene_simd4f_t |
91 | * |
92 | * Since: 1.0 |
93 | */ |
94 | graphene_simd4f_t |
95 | (graphene_simd4f_init_zero) (void) |
96 | { |
97 | return graphene_simd4f_init_zero (); |
98 | } |
99 | |
100 | /** |
101 | * graphene_simd4f_init_4f: |
102 | * @v: (array fixed-size=4): an array of at least 4 floating |
103 | * point values |
104 | * |
105 | * Initializes a #graphene_simd4f_t using an array of 4 floating |
106 | * point values. |
107 | * |
108 | * Returns: the initialized #graphene_simd4f_t |
109 | * |
110 | * Since: 1.0 |
111 | */ |
112 | graphene_simd4f_t |
113 | (graphene_simd4f_init_4f) (const float *v) |
114 | { |
115 | return graphene_simd4f_init_4f (v); |
116 | } |
117 | |
118 | /** |
119 | * graphene_simd4f_init_3f: |
120 | * @v: (array fixed-size=3): an array of at least 3 floating |
121 | * point values |
122 | * |
123 | * Initializes a #graphene_simd4f_t using an array of 3 floating |
124 | * point values. |
125 | * |
126 | * Returns: the initialized #graphene_simd4f_t |
127 | * |
128 | * Since: 1.0 |
129 | */ |
130 | graphene_simd4f_t |
131 | (graphene_simd4f_init_3f) (const float *v) |
132 | { |
133 | return graphene_simd4f_init_3f (v); |
134 | } |
135 | |
136 | /** |
137 | * graphene_simd4f_init_2f: |
138 | * @v: (array fixed-size=2): an array of at least 2 floating |
139 | * point values |
140 | * |
141 | * Initializes a #graphene_simd4f_t using an array of 2 floating |
142 | * point values. |
143 | * |
144 | * Returns: the initialized #graphene_simd4f_t |
145 | * |
146 | * Since: 1.0 |
147 | */ |
148 | graphene_simd4f_t |
149 | (graphene_simd4f_init_2f) (const float *v) |
150 | { |
151 | return graphene_simd4f_init_2f (v); |
152 | } |
153 | |
154 | /** |
155 | * graphene_simd4f_dup_4f: |
156 | * @s: a #graphene_simd4f_t |
157 | * @v: (out) (array fixed-size=4): return location for an |
158 | * array of at least 4 floating point values |
159 | * |
160 | * Copies the contents of a #graphene_simd4f_t into an |
161 | * array of floating points. |
162 | * |
163 | * Since: 1.0 |
164 | */ |
165 | void |
166 | (graphene_simd4f_dup_4f) (const graphene_simd4f_t s, |
167 | float *v) |
168 | { |
169 | graphene_simd4f_dup_4f (s, v); |
170 | } |
171 | |
172 | /** |
173 | * graphene_simd4f_dup_3f: |
174 | * @s: a #graphene_simd4f_t |
175 | * @v: (out) (array fixed-size=3): return location for an |
176 | * array of at least 3 floating point values |
177 | * |
178 | * Copies the contents of a #graphene_simd4f_t into an |
179 | * array of floating points. |
180 | * |
181 | * Since: 1.0 |
182 | */ |
183 | void |
184 | (graphene_simd4f_dup_3f) (const graphene_simd4f_t s, |
185 | float *v) |
186 | { |
187 | graphene_simd4f_dup_3f (s, v); |
188 | } |
189 | |
190 | /** |
191 | * graphene_simd4f_dup_2f: |
192 | * @s: a #graphene_simd4f_t |
193 | * @v: (out) (array fixed-size=2): return location for an |
194 | * array of at least 2 floating point values |
195 | * |
196 | * Copies the contents of a #graphene_simd4f_t into an |
197 | * array of floating points. |
198 | * |
199 | * Since: 1.0 |
200 | */ |
201 | void |
202 | (graphene_simd4f_dup_2f) (const graphene_simd4f_t s, |
203 | float *v) |
204 | { |
205 | graphene_simd4f_dup_2f (s, v); |
206 | } |
207 | |
208 | /** |
209 | * graphene_simd4f_get: |
210 | * @s: a #graphene_simd4f_t |
211 | * @i: the index of the component to retrieve |
212 | * |
213 | * Retrieves the given component of a #graphene_simd4f_t. |
214 | * |
215 | * Since: 1.2 |
216 | */ |
217 | float |
218 | (graphene_simd4f_get) (const graphene_simd4f_t s, |
219 | unsigned int i) |
220 | { |
221 | switch (i) |
222 | { |
223 | case 0: |
224 | return graphene_simd4f_get (s, 0); |
225 | |
226 | case 1: |
227 | return graphene_simd4f_get (s, 1); |
228 | |
229 | case 2: |
230 | return graphene_simd4f_get (s, 2); |
231 | |
232 | case 3: |
233 | return graphene_simd4f_get (s, 3); |
234 | |
235 | default: |
236 | return 0.f; |
237 | } |
238 | } |
239 | |
240 | /** |
241 | * graphene_simd4f_get_x: |
242 | * @s: a #graphene_simd4f_t |
243 | * |
244 | * Retrieves the first component of @s. |
245 | * |
246 | * Returns: the first component of a #graphene_simd4f_t |
247 | * |
248 | * Since: 1.0 |
249 | */ |
250 | float |
251 | (graphene_simd4f_get_x) (const graphene_simd4f_t s) |
252 | { |
253 | return graphene_simd4f_get_x (s); |
254 | } |
255 | |
256 | /** |
257 | * graphene_simd4f_get_y: |
258 | * @s: a #graphene_simd4f_t |
259 | * |
260 | * Retrieves the second component of @s. |
261 | * |
262 | * Returns: the second component of a #graphene_simd4f_t |
263 | * |
264 | * Since: 1.0 |
265 | */ |
266 | float |
267 | (graphene_simd4f_get_y) (const graphene_simd4f_t s) |
268 | { |
269 | return graphene_simd4f_get_y (s); |
270 | } |
271 | |
272 | /** |
273 | * graphene_simd4f_get_z: |
274 | * @s: a #graphene_simd4f_t |
275 | * |
276 | * Retrieves the third component of @s. |
277 | * |
278 | * Returns: the third component of a #graphene_simd4f_t |
279 | * |
280 | * Since: 1.0 |
281 | */ |
282 | float |
283 | (graphene_simd4f_get_z) (const graphene_simd4f_t s) |
284 | { |
285 | return graphene_simd4f_get_z (s); |
286 | } |
287 | |
288 | /** |
289 | * graphene_simd4f_get_w: |
290 | * @s: a #graphene_simd4f_t |
291 | * |
292 | * Retrieves the fourth component of @s. |
293 | * |
294 | * Returns: the fourth component of a #graphene_simd4f_t |
295 | * |
296 | * Since: 1.0 |
297 | */ |
298 | float |
299 | (graphene_simd4f_get_w) (const graphene_simd4f_t s) |
300 | { |
301 | return graphene_simd4f_get_w (s); |
302 | } |
303 | |
304 | /** |
305 | * graphene_simd4f_splat: |
306 | * @v: a floating point value |
307 | * |
308 | * Sets all the components of a new #graphene_simd4f_t to the |
309 | * same value @v: |
310 | * |
311 | * |[<!-- language="plain" --> |
312 | * { |
313 | * .x = v, |
314 | * .y = v, |
315 | * .z = v, |
316 | * .w = v |
317 | * }; |
318 | * ]| |
319 | * |
320 | * Returns: the initialized #graphene_simd4f_t |
321 | * |
322 | * Since: 1.0 |
323 | */ |
324 | graphene_simd4f_t |
325 | (graphene_simd4f_splat) (float v) |
326 | { |
327 | return graphene_simd4f_splat (v); |
328 | } |
329 | |
330 | /** |
331 | * graphene_simd4f_splat_x: |
332 | * @s: a #graphene_simd4f_t |
333 | * |
334 | * Sets all the components of a new #graphene_simd4f_t to the |
335 | * same value of the first component of the passed vector: |
336 | * |
337 | * |[<!-- language="plain" --> |
338 | * { |
339 | * .x = s.x, |
340 | * .y = s.x, |
341 | * .z = s.x, |
342 | * .w = s.x |
343 | * } |
344 | * ]| |
345 | * |
346 | * Returns: the initialized #graphene_simd4f_t |
347 | * |
348 | * Since: 1.0 |
349 | */ |
350 | graphene_simd4f_t |
351 | (graphene_simd4f_splat_x) (const graphene_simd4f_t s) |
352 | { |
353 | return graphene_simd4f_splat_x (s); |
354 | } |
355 | |
356 | /** |
357 | * graphene_simd4f_splat_y: |
358 | * @s: a #graphene_simd4f_t |
359 | * |
360 | * Sets all the components of a new #graphene_simd4f_t to the |
361 | * same value of the second component of the passed vector: |
362 | * |
363 | * |[<!-- language="plain" --> |
364 | * { |
365 | * .x = s.y, |
366 | * .y = s.y, |
367 | * .z = s.y, |
368 | * .w = s.y |
369 | * } |
370 | * ]| |
371 | * |
372 | * Returns: the initialized #graphene_simd4f_t |
373 | * |
374 | * Since: 1.0 |
375 | */ |
376 | graphene_simd4f_t |
377 | (graphene_simd4f_splat_y) (const graphene_simd4f_t s) |
378 | { |
379 | return graphene_simd4f_splat_y (s); |
380 | } |
381 | |
382 | /** |
383 | * graphene_simd4f_splat_z: |
384 | * @s: a #graphene_simd4f_t |
385 | * |
386 | * Sets all the components of a #graphene_simd4f_t to the |
387 | * same value of the third component of the passed vector: |
388 | * |
389 | * |[<!-- language="plain" --> |
390 | * { |
391 | * .x = s.z, |
392 | * .y = s.z, |
393 | * .z = s.z, |
394 | * .w = s.z |
395 | * } |
396 | * ]| |
397 | * |
398 | * Returns: the initialized #graphene_simd4f_t |
399 | * |
400 | * Since: 1.0 |
401 | */ |
402 | graphene_simd4f_t |
403 | (graphene_simd4f_splat_z) (const graphene_simd4f_t s) |
404 | { |
405 | return graphene_simd4f_splat_z (s); |
406 | } |
407 | |
408 | /** |
409 | * graphene_simd4f_splat_w: |
410 | * @s: a #graphene_simd4f_t |
411 | * |
412 | * Sets all the components of a #graphene_simd4f_t to the |
413 | * same value of the fourth component of the passed vector: |
414 | * |
415 | * |[<!-- language="plain" --> |
416 | * { |
417 | * .x = s.w, |
418 | * .y = s.w, |
419 | * .z = s.w, |
420 | * .w = s.w |
421 | * } |
422 | * ]| |
423 | * |
424 | * Returns: the initialized #graphene_simd4f_t |
425 | * |
426 | * Since: 1.0 |
427 | */ |
428 | graphene_simd4f_t |
429 | (graphene_simd4f_splat_w) (const graphene_simd4f_t s) |
430 | { |
431 | return graphene_simd4f_splat_w (s); |
432 | } |
433 | |
434 | /** |
435 | * graphene_simd4f_reciprocal: |
436 | * @s: a #graphene_simd4f_t |
437 | * |
438 | * Computes the reciprocal of every component of @s. |
439 | * |
440 | * |[<!-- language="plain" --> |
441 | * { |
442 | * .x = 1.0 / s.x, |
443 | * .y = 1.0 / s.y, |
444 | * .z = 1.0 / s.z, |
445 | * .w = 1.0 / s.w |
446 | * } |
447 | * ]| |
448 | * |
449 | * Returns: a vector containing the reciprocal of the |
450 | * passed vector |
451 | * |
452 | * Since: 1.0 |
453 | */ |
454 | graphene_simd4f_t |
455 | (graphene_simd4f_reciprocal) (const graphene_simd4f_t s) |
456 | { |
457 | return graphene_simd4f_reciprocal (s); |
458 | } |
459 | |
460 | /** |
461 | * graphene_simd4f_sqrt: |
462 | * @s: a #graphene_simd4f_t |
463 | * |
464 | * Computes the square root of every component of @s. |
465 | * |
466 | * |[<!-- language="plain" --> |
467 | * { |
468 | * .x = sqrt (s.x), |
469 | * .y = sqrt (s.y), |
470 | * .z = sqrt (s.z), |
471 | * .w = sqrt (s.w) |
472 | * } |
473 | * ]| |
474 | * |
475 | * Returns: a vector containing the square root of the |
476 | * passed vector |
477 | * |
478 | * Since: 1.0 |
479 | */ |
480 | graphene_simd4f_t |
481 | (graphene_simd4f_sqrt) (const graphene_simd4f_t s) |
482 | { |
483 | return graphene_simd4f_sqrt (s); |
484 | } |
485 | |
486 | /** |
487 | * graphene_simd4f_rsqrt: |
488 | * @s: a #graphene_simd4f_t |
489 | * |
490 | * Computes the reciprocal square root of every component |
491 | * of @s. |
492 | * |
493 | * |[<!-- language="plain" --> |
494 | * { |
495 | * .x = 1.0 / sqrt (s.x), |
496 | * .y = 1.0 / sqrt (s.y), |
497 | * .z = 1.0 / sqrt (s.z), |
498 | * .w = 1.0 / sqrt (s.w) |
499 | * } |
500 | * ]| |
501 | * |
502 | * Returns: a vector containing the reciprocal square root |
503 | * of the passed vector |
504 | * |
505 | * Since: 1.0 |
506 | */ |
507 | graphene_simd4f_t |
508 | (graphene_simd4f_rsqrt) (const graphene_simd4f_t s) |
509 | { |
510 | return graphene_simd4f_rsqrt (s); |
511 | } |
512 | |
513 | /** |
514 | * graphene_simd4f_add: |
515 | * @a: a #graphene_simd4f_t |
516 | * @b: a #graphene_simd4f_t |
517 | * |
518 | * Creates a new #graphene_simd4f_t vector where each |
519 | * component is the sum of the respective components |
520 | * in @a and @b. |
521 | * |
522 | * |[<!-- lanugage="plain" --> |
523 | * { |
524 | * .x = a.x + b.x, |
525 | * .y = a.y + b.y, |
526 | * .z = a.z + b.z, |
527 | * .w = a.w + b.w |
528 | * } |
529 | * ]| |
530 | * |
531 | * Returns: the sum vector |
532 | * |
533 | * Since: 1.0 |
534 | */ |
535 | graphene_simd4f_t |
536 | (graphene_simd4f_add) (const graphene_simd4f_t a, |
537 | const graphene_simd4f_t b) |
538 | { |
539 | return graphene_simd4f_add (a, b); |
540 | } |
541 | |
542 | /** |
543 | * graphene_simd4f_sub: |
544 | * @a: a #graphene_simd4f_t |
545 | * @b: a #graphene_simd4f_t |
546 | * |
547 | * Creates a new #graphene_simd4f_t vector where each |
548 | * component is the subtraction of the respective components |
549 | * in @a and @b. |
550 | * |
551 | * |[<!-- lanugage="plain" --> |
552 | * { |
553 | * .x = a.x - b.x, |
554 | * .y = a.y - b.y, |
555 | * .z = a.z - b.z, |
556 | * .w = a.w - b.w |
557 | * } |
558 | * ]| |
559 | * |
560 | * Returns: the subtraction vector |
561 | * |
562 | * Since: 1.0 |
563 | */ |
564 | graphene_simd4f_t |
565 | (graphene_simd4f_sub) (const graphene_simd4f_t a, |
566 | const graphene_simd4f_t b) |
567 | { |
568 | return graphene_simd4f_sub (a, b); |
569 | } |
570 | |
571 | /** |
572 | * graphene_simd4f_mul: |
573 | * @a: a #graphene_simd4f_t |
574 | * @b: a #graphene_simd4f_t |
575 | * |
576 | * Creates a new #graphene_simd4f_t vector where each |
577 | * component is the multiplication of the respective components |
578 | * in @a and @b. |
579 | * |
580 | * |[<!-- lanugage="plain" --> |
581 | * { |
582 | * .x = a.x * b.x, |
583 | * .y = a.y * b.y, |
584 | * .z = a.z * b.z, |
585 | * .w = a.w * b.w |
586 | * } |
587 | * ]| |
588 | * |
589 | * Returns: the multiplication vector |
590 | * |
591 | * Since: 1.0 |
592 | */ |
593 | graphene_simd4f_t |
594 | (graphene_simd4f_mul) (const graphene_simd4f_t a, |
595 | const graphene_simd4f_t b) |
596 | { |
597 | return graphene_simd4f_mul (a, b); |
598 | } |
599 | |
600 | /** |
601 | * graphene_simd4f_div: |
602 | * @a: a #graphene_simd4f_t |
603 | * @b: a #graphene_simd4f_t |
604 | * |
605 | * Creates a new #graphene_simd4f_t vector where each |
606 | * component is the division of the respective components |
607 | * in @a and @b. |
608 | * |
609 | * |[<!-- lanugage="plain" --> |
610 | * { |
611 | * .x = a.x / b.x, |
612 | * .y = a.y / b.y, |
613 | * .z = a.z / b.z, |
614 | * .w = a.w / b.w |
615 | * } |
616 | * ]| |
617 | * |
618 | * Returns: the division vector |
619 | * |
620 | * Since: 1.0 |
621 | */ |
622 | graphene_simd4f_t |
623 | (graphene_simd4f_div) (const graphene_simd4f_t a, |
624 | const graphene_simd4f_t b) |
625 | { |
626 | return graphene_simd4f_div (a, b); |
627 | } |
628 | |
629 | /** |
630 | * graphene_simd4f_cross3: |
631 | * @a: a #graphene_simd4f_t |
632 | * @b: a #graphene_simd4f_t |
633 | * |
634 | * Creates a new #graphene_simd4f_t vector where each |
635 | * component contains the 3-way cross product of the |
636 | * given @a and @b vectors. |
637 | * |
638 | * Returns: the cross3 vector |
639 | * |
640 | * Since: 1.0 |
641 | */ |
642 | graphene_simd4f_t |
643 | (graphene_simd4f_cross3) (const graphene_simd4f_t a, |
644 | const graphene_simd4f_t b) |
645 | { |
646 | return graphene_simd4f_cross3 (a, b); |
647 | } |
648 | |
649 | /** |
650 | * graphene_simd4f_dot3: |
651 | * @a: a #graphene_simd4f_t |
652 | * @b: a #graphene_simd4f_t |
653 | * |
654 | * Computes the dot product of the first three components of the |
655 | * two given #graphene_simd4f_t. |
656 | * |
657 | * Returns: a vector whose components are all set to the |
658 | * dot product of the components of the two operands |
659 | * |
660 | * Since: 1.0 |
661 | */ |
662 | graphene_simd4f_t |
663 | (graphene_simd4f_dot3) (const graphene_simd4f_t a, |
664 | const graphene_simd4f_t b) |
665 | { |
666 | return graphene_simd4f_dot3 (a, b); |
667 | } |
668 | |
669 | /** |
670 | * graphene_simd4f_dot3_scalar: |
671 | * @a: a #graphene_simd4f_t |
672 | * @b: a #graphene_simd4f_t |
673 | * |
674 | * Computes the dot product of the first three components of the |
675 | * two given #graphene_simd4f_t. |
676 | * |
677 | * Returns: the dot product of the two vectors, as a scalar value. |
678 | * |
679 | * Since: 1.4 |
680 | */ |
681 | float |
682 | (graphene_simd4f_dot3_scalar) (const graphene_simd4f_t a, |
683 | const graphene_simd4f_t b) |
684 | { |
685 | return graphene_simd4f_dot3_scalar (a, b); |
686 | } |
687 | |
688 | /** |
689 | * graphene_simd4f_min: |
690 | * @a: a #graphene_simd4f_t |
691 | * @b: a #graphene_simd4f_t |
692 | * |
693 | * Creates a new #graphene_simd4f_t that contains the |
694 | * minimum value of each component of @a and @b. |
695 | * |
696 | * Returns: the new minimum vector |
697 | * |
698 | * Since: 1.0 |
699 | */ |
700 | graphene_simd4f_t |
701 | (graphene_simd4f_min) (const graphene_simd4f_t a, |
702 | const graphene_simd4f_t b) |
703 | { |
704 | return graphene_simd4f_min (a, b); |
705 | } |
706 | |
707 | /** |
708 | * graphene_simd4f_max: |
709 | * @a: a #graphene_simd4f_t |
710 | * @b: a #graphene_simd4f_t |
711 | * |
712 | * Creates a new #graphene_simd4f_t that contains the |
713 | * maximum value of each component of @a and @b. |
714 | * |
715 | * Returns: the new maximum vector |
716 | * |
717 | * Since: 1.0 |
718 | */ |
719 | graphene_simd4f_t |
720 | (graphene_simd4f_max) (const graphene_simd4f_t a, |
721 | const graphene_simd4f_t b) |
722 | { |
723 | return graphene_simd4f_max (a, b); |
724 | } |
725 | |
726 | /** |
727 | * graphene_simd4f_shuffle_wxyz: |
728 | * @s: a #graphene_simd4f_t |
729 | * |
730 | * Creates a new #graphene_simd4f_t that contains the |
731 | * re-ordered values of the W, X, Y, and Z components |
732 | * of @s. |
733 | * |
734 | * Returns: the new vector |
735 | * |
736 | * Since: 1.0 |
737 | */ |
738 | graphene_simd4f_t |
739 | (graphene_simd4f_shuffle_wxyz) (const graphene_simd4f_t s) |
740 | { |
741 | return graphene_simd4f_shuffle_wxyz (s); |
742 | } |
743 | |
744 | /** |
745 | * graphene_simd4f_shuffle_zwxy: |
746 | * @s: a #graphene_simd4f_t |
747 | * |
748 | * Creates a new #graphene_simd4f_t that contains the |
749 | * re-ordered values of the Z, W, X, and Y components |
750 | * of @s. |
751 | * |
752 | * Returns: the new vector |
753 | * |
754 | * Since: 1.0 |
755 | */ |
756 | graphene_simd4f_t |
757 | (graphene_simd4f_shuffle_zwxy) (const graphene_simd4f_t s) |
758 | { |
759 | return graphene_simd4f_shuffle_zwxy (s); |
760 | } |
761 | |
762 | /** |
763 | * graphene_simd4f_shuffle_yzwx: |
764 | * @s: a #graphene_simd4f_t |
765 | * |
766 | * Creates a new #graphene_simd4f_t that contains the |
767 | * re-ordered values of the Y, Z, W, and X components |
768 | * of @s. |
769 | * |
770 | * Returns: the new vector |
771 | * |
772 | * Since: 1.0 |
773 | */ |
774 | graphene_simd4f_t |
775 | (graphene_simd4f_shuffle_yzwx) (const graphene_simd4f_t s) |
776 | { |
777 | return graphene_simd4f_shuffle_yzwx (s); |
778 | } |
779 | |
780 | /** |
781 | * graphene_simd4f_zero_w: |
782 | * @s: a #graphene_simd4f_t |
783 | * |
784 | * Creates a new #graphene_simd4f_t that contains the |
785 | * same values of the given @s vector, except for the |
786 | * W component, which is set to 0. |
787 | * |
788 | * Returns: the new vector |
789 | * |
790 | * Since: 1.0 |
791 | */ |
792 | graphene_simd4f_t |
793 | (graphene_simd4f_zero_w) (const graphene_simd4f_t s) |
794 | { |
795 | return graphene_simd4f_zero_w (s); |
796 | } |
797 | |
798 | /** |
799 | * graphene_simd4f_zero_zw: |
800 | * @s: a #graphene_simd4f_t |
801 | * |
802 | * Creates a new #graphene_simd4f_t that contains the |
803 | * same values of the given @s vector, except for the |
804 | * Z and W components, which are set to 0. |
805 | * |
806 | * Returns: the new vector |
807 | * |
808 | * Since: 1.0 |
809 | */ |
810 | graphene_simd4f_t |
811 | (graphene_simd4f_zero_zw) (const graphene_simd4f_t s) |
812 | { |
813 | return graphene_simd4f_zero_zw (s); |
814 | } |
815 | |
816 | /** |
817 | * graphene_simd4f_merge_w: |
818 | * @s: a #graphene_simd4f_t |
819 | * @v: the new value of the W component |
820 | * |
821 | * Creates a new #graphene_simd4f_t that contains the |
822 | * same values of the given @s vector, except for the |
823 | * W component, which is set to @v. |
824 | * |
825 | * Returns: the new vector |
826 | * |
827 | * Since: 1.0 |
828 | */ |
829 | graphene_simd4f_t |
830 | (graphene_simd4f_merge_w) (const graphene_simd4f_t s, |
831 | float v) |
832 | { |
833 | return graphene_simd4f_merge_w (s, v); |
834 | } |
835 | |
836 | /** |
837 | * graphene_simd4f_merge_high: |
838 | * @a: a #graphene_simd4f_t |
839 | * @b: a #graphene_simd4f_t |
840 | * |
841 | * Creates a new #graphene_simd4f_t that contains the |
842 | * last two components of the vector @a and the last |
843 | * two components of the vector @b. |
844 | * |
845 | * Returns: the new vector |
846 | * |
847 | * Since: 1.0 |
848 | */ |
849 | graphene_simd4f_t |
850 | (graphene_simd4f_merge_high) (const graphene_simd4f_t a, |
851 | const graphene_simd4f_t b) |
852 | { |
853 | return graphene_simd4f_merge_high (a, b); |
854 | } |
855 | |
856 | /** |
857 | * graphene_simd4f_merge_low: |
858 | * @a: a #graphene_simd4f_t |
859 | * @b: a #graphene_simd4f_t |
860 | * |
861 | * Creates a new #graphene_simd4f_t that contains the |
862 | * first two components of the vector @a and the first |
863 | * two components of the vector @b. |
864 | * |
865 | * Returns: the new vector |
866 | * |
867 | * Since: 1.0 |
868 | */ |
869 | graphene_simd4f_t |
870 | (graphene_simd4f_merge_low) (const graphene_simd4f_t a, |
871 | const graphene_simd4f_t b) |
872 | { |
873 | return graphene_simd4f_merge_low (a, b); |
874 | } |
875 | |
876 | /** |
877 | * graphene_simd4f_flip_sign_0101: |
878 | * @s: a #graphene_simd4f_t |
879 | * |
880 | * Flips the signs of the second and fourth components of |
881 | * the given vector @s. |
882 | * |
883 | * Returns: the new vector, with the changed signs |
884 | * |
885 | * Since: 1.0 |
886 | */ |
887 | graphene_simd4f_t |
888 | (graphene_simd4f_flip_sign_0101) (const graphene_simd4f_t s) |
889 | { |
890 | return graphene_simd4f_flip_sign_0101 (s); |
891 | } |
892 | |
893 | /** |
894 | * graphene_simd4f_flip_sign_1010: |
895 | * @s: a #graphene_simd4f_t |
896 | * |
897 | * Flips the signs of the first and third components of |
898 | * the given vector @s. |
899 | * |
900 | * Returns: the new vector, with the changed signs |
901 | * |
902 | * Since: 1.0 |
903 | */ |
904 | graphene_simd4f_t |
905 | (graphene_simd4f_flip_sign_1010) (const graphene_simd4f_t s) |
906 | { |
907 | return graphene_simd4f_flip_sign_1010 (s); |
908 | } |
909 | |
910 | /** |
911 | * graphene_simd4f_cmp_eq: |
912 | * @a: a #graphene_simd4f_t |
913 | * @b: a #graphene_simd4f_t |
914 | * |
915 | * Checks if the two given #graphene_simd4f_t are equal. |
916 | * |
917 | * Returns: `true` if the values of the vectors are equal |
918 | * |
919 | * Since: 1.0 |
920 | */ |
921 | bool |
922 | (graphene_simd4f_cmp_eq) (const graphene_simd4f_t a, |
923 | const graphene_simd4f_t b) |
924 | { |
925 | return graphene_simd4f_cmp_eq (a, b); |
926 | } |
927 | |
928 | /** |
929 | * graphene_simd4f_cmp_neq: |
930 | * @a: a #graphene_simd4f_t |
931 | * @b: a #graphene_simd4f_t |
932 | * |
933 | * Checks if the two given #graphene_simd4f_t are not equal. |
934 | * |
935 | * Returns: `true` if the values of the vectors are not equal |
936 | * |
937 | * Since: 1.0 |
938 | */ |
939 | bool |
940 | (graphene_simd4f_cmp_neq) (const graphene_simd4f_t a, |
941 | const graphene_simd4f_t b) |
942 | { |
943 | return graphene_simd4f_cmp_neq (a, b); |
944 | } |
945 | |
946 | /** |
947 | * graphene_simd4f_cmp_lt: |
948 | * @a: a #graphene_simd4f_t |
949 | * @b: a #graphene_simd4f_t |
950 | * |
951 | * Compares two #graphene_simd4f_t and checks if all components |
952 | * of the vector @a are less than the respective components of |
953 | * the vector @b. |
954 | * |
955 | * Returns: `true` if vector @a is less than @b |
956 | * |
957 | * Since: 1.2 |
958 | */ |
959 | bool |
960 | (graphene_simd4f_cmp_lt) (const graphene_simd4f_t a, |
961 | const graphene_simd4f_t b) |
962 | { |
963 | return graphene_simd4f_cmp_lt (a, b); |
964 | } |
965 | |
966 | /** |
967 | * graphene_simd4f_cmp_le: |
968 | * @a: a #graphene_simd4f_t |
969 | * @b: a #graphene_simd4f_t |
970 | * |
971 | * Compares two #graphene_simd4f_t and checks if all components |
972 | * of the vector @a are less than or equal to the respective components |
973 | * of the vector @b. |
974 | * |
975 | * Returns: `true` if vector @a is less than or equal to @b |
976 | * |
977 | * Since: 1.2 |
978 | */ |
979 | bool |
980 | (graphene_simd4f_cmp_le) (const graphene_simd4f_t a, |
981 | const graphene_simd4f_t b) |
982 | { |
983 | return graphene_simd4f_cmp_le (a, b); |
984 | } |
985 | |
986 | /** |
987 | * graphene_simd4f_cmp_ge: |
988 | * @a: a #graphene_simd4f_t |
989 | * @b: a #graphene_simd4f_t |
990 | * |
991 | * Compares two #graphene_simd4f_t and checks if all components |
992 | * of the vector @a are greater than or equal to the respective |
993 | * components of the vector @b. |
994 | * |
995 | * Returns: `true` if vector @a is greater than or equal to @b |
996 | * |
997 | * Since: 1.0 |
998 | */ |
999 | bool |
1000 | (graphene_simd4f_cmp_ge) (const graphene_simd4f_t a, |
1001 | const graphene_simd4f_t b) |
1002 | { |
1003 | return graphene_simd4f_cmp_ge (a, b); |
1004 | } |
1005 | |
1006 | /** |
1007 | * graphene_simd4f_cmp_gt: |
1008 | * @a: a #graphene_simd4f_t |
1009 | * @b: a #graphene_simd4f_t |
1010 | * |
1011 | * Compares two #graphene_simd4f_t and checks if all components |
1012 | * of the vector @a are greater than the respective components of |
1013 | * the vector @b. |
1014 | * |
1015 | * Returns: `true` if vector @a is greater than @b |
1016 | * |
1017 | * Since: 1.0 |
1018 | */ |
1019 | bool |
1020 | (graphene_simd4f_cmp_gt) (const graphene_simd4f_t a, |
1021 | const graphene_simd4f_t b) |
1022 | { |
1023 | return graphene_simd4f_cmp_gt (a, b); |
1024 | } |
1025 | |
1026 | /** |
1027 | * graphene_simd4f_neg: |
1028 | * @s: a #graphene_simd4f_t |
1029 | * |
1030 | * Negates the values of @s. |
1031 | * |
1032 | * Returns: the negated vector |
1033 | * |
1034 | * Since: 1.0 |
1035 | */ |
1036 | graphene_simd4f_t |
1037 | (graphene_simd4f_neg) (const graphene_simd4f_t s) |
1038 | { |
1039 | return graphene_simd4f_neg (s); |
1040 | } |
1041 | |
1042 | #else /* GRAPHENE_USE_SCALAR */ |
1043 | |
1044 | graphene_simd4f_t |
1045 | (graphene_simd4f_init) (float x, |
1046 | float y, |
1047 | float z, |
1048 | float w) |
1049 | { |
1050 | graphene_simd4f_t s = { x, y, z, w }; |
1051 | return s; |
1052 | } |
1053 | |
1054 | graphene_simd4f_t |
1055 | (graphene_simd4f_init_zero) (void) |
1056 | { |
1057 | return graphene_simd4f_init (0.f, 0.f, 0.f, 0.f); |
1058 | } |
1059 | |
1060 | graphene_simd4f_t |
1061 | (graphene_simd4f_init_4f) (const float *v) |
1062 | { |
1063 | return graphene_simd4f_init (v[0], v[1], v[2], v[3]); |
1064 | } |
1065 | |
1066 | graphene_simd4f_t |
1067 | (graphene_simd4f_init_3f) (const float *v) |
1068 | { |
1069 | return graphene_simd4f_init (v[0], v[1], v[2], 0.f); |
1070 | } |
1071 | |
1072 | graphene_simd4f_t |
1073 | (graphene_simd4f_init_2f) (const float *v) |
1074 | { |
1075 | return graphene_simd4f_init (v[0], v[1], 0.f, 0.f); |
1076 | } |
1077 | |
1078 | void |
1079 | (graphene_simd4f_dup_4f) (const graphene_simd4f_t s, |
1080 | float *v) |
1081 | { |
1082 | memcpy (v, &s, sizeof (float) * 4); |
1083 | } |
1084 | |
1085 | void |
1086 | (graphene_simd4f_dup_3f) (const graphene_simd4f_t s, |
1087 | float *v) |
1088 | { |
1089 | memcpy (v, &s, sizeof (float) * 3); |
1090 | } |
1091 | |
1092 | void |
1093 | (graphene_simd4f_dup_2f) (const graphene_simd4f_t s, |
1094 | float *v) |
1095 | { |
1096 | memcpy (v, &s, sizeof (float) * 2); |
1097 | } |
1098 | |
1099 | float |
1100 | (graphene_simd4f_get) (const graphene_simd4f_t s, |
1101 | unsigned int i) |
1102 | { |
1103 | switch (i) |
1104 | { |
1105 | case 0: |
1106 | return s.x; |
1107 | case 1: |
1108 | return s.y; |
1109 | case 2: |
1110 | return s.z; |
1111 | case 3: |
1112 | return s.w; |
1113 | } |
1114 | |
1115 | return 0; |
1116 | } |
1117 | |
1118 | float |
1119 | (graphene_simd4f_get_x) (const graphene_simd4f_t s) |
1120 | { |
1121 | return s.x; |
1122 | } |
1123 | |
1124 | float |
1125 | (graphene_simd4f_get_y) (const graphene_simd4f_t s) |
1126 | { |
1127 | return s.y; |
1128 | } |
1129 | |
1130 | float |
1131 | (graphene_simd4f_get_z) (const graphene_simd4f_t s) |
1132 | { |
1133 | return s.z; |
1134 | } |
1135 | |
1136 | float |
1137 | (graphene_simd4f_get_w) (const graphene_simd4f_t s) |
1138 | { |
1139 | return s.w; |
1140 | } |
1141 | |
1142 | graphene_simd4f_t |
1143 | (graphene_simd4f_splat) (float v) |
1144 | { |
1145 | graphene_simd4f_t s = { v, v, v, v }; |
1146 | return s; |
1147 | } |
1148 | |
1149 | graphene_simd4f_t |
1150 | (graphene_simd4f_splat_x) (graphene_simd4f_t v) |
1151 | { |
1152 | graphene_simd4f_t s = { v.x, v.x, v.x, v.x }; |
1153 | return s; |
1154 | } |
1155 | |
1156 | graphene_simd4f_t |
1157 | (graphene_simd4f_splat_y) (graphene_simd4f_t v) |
1158 | { |
1159 | graphene_simd4f_t s = { v.y, v.y, v.y, v.y }; |
1160 | return s; |
1161 | } |
1162 | |
1163 | graphene_simd4f_t |
1164 | (graphene_simd4f_splat_z) (graphene_simd4f_t v) |
1165 | { |
1166 | graphene_simd4f_t s = { v.z, v.z, v.z, v.z }; |
1167 | return s; |
1168 | } |
1169 | |
1170 | graphene_simd4f_t |
1171 | (graphene_simd4f_splat_w) (graphene_simd4f_t v) |
1172 | { |
1173 | graphene_simd4f_t s = { v.w, v.w, v.w, v.w }; |
1174 | return s; |
1175 | } |
1176 | |
1177 | graphene_simd4f_t |
1178 | (graphene_simd4f_reciprocal) (graphene_simd4f_t v) |
1179 | { |
1180 | graphene_simd4f_t s = { |
1181 | fabsf (v.x) > FLT_EPSILON ? 1.0f / v.x : 0.f, |
1182 | fabsf (v.y) > FLT_EPSILON ? 1.0f / v.y : 0.f, |
1183 | fabsf (v.z) > FLT_EPSILON ? 1.0f / v.z : 0.f, |
1184 | fabsf (v.w) > FLT_EPSILON ? 1.0f / v.w : 0.f |
1185 | }; |
1186 | return s; |
1187 | } |
1188 | |
1189 | graphene_simd4f_t |
1190 | (graphene_simd4f_sqrt) (graphene_simd4f_t v) |
1191 | { |
1192 | graphene_simd4f_t s = { |
1193 | sqrtf (v.x), |
1194 | sqrtf (v.y), |
1195 | sqrtf (v.z), |
1196 | sqrtf (v.w) |
1197 | }; |
1198 | return s; |
1199 | } |
1200 | |
1201 | graphene_simd4f_t |
1202 | (graphene_simd4f_rsqrt) (graphene_simd4f_t v) |
1203 | { |
1204 | graphene_simd4f_t s = { |
1205 | fabsf (v.x) > FLT_EPSILON ? 1.0f / sqrtf (v.x) : 0.f, |
1206 | fabsf (v.y) > FLT_EPSILON ? 1.0f / sqrtf (v.y) : 0.f, |
1207 | fabsf (v.z) > FLT_EPSILON ? 1.0f / sqrtf (v.z) : 0.f, |
1208 | fabsf (v.w) > FLT_EPSILON ? 1.0f / sqrtf (v.w) : 0.f |
1209 | }; |
1210 | return s; |
1211 | } |
1212 | |
1213 | graphene_simd4f_t |
1214 | (graphene_simd4f_add) (const graphene_simd4f_t a, |
1215 | const graphene_simd4f_t b) |
1216 | { |
1217 | graphene_simd4f_t s = { |
1218 | a.x + b.x, |
1219 | a.y + b.y, |
1220 | a.z + b.z, |
1221 | a.w + b.w |
1222 | }; |
1223 | return s; |
1224 | } |
1225 | |
1226 | graphene_simd4f_t |
1227 | (graphene_simd4f_sub) (const graphene_simd4f_t a, |
1228 | const graphene_simd4f_t b) |
1229 | { |
1230 | graphene_simd4f_t s = { |
1231 | a.x - b.x, |
1232 | a.y - b.y, |
1233 | a.z - b.z, |
1234 | a.w - b.w |
1235 | }; |
1236 | return s; |
1237 | } |
1238 | |
1239 | graphene_simd4f_t |
1240 | (graphene_simd4f_mul) (const graphene_simd4f_t a, |
1241 | const graphene_simd4f_t b) |
1242 | { |
1243 | graphene_simd4f_t s = { |
1244 | a.x * b.x, |
1245 | a.y * b.y, |
1246 | a.z * b.z, |
1247 | a.w * b.w |
1248 | }; |
1249 | return s; |
1250 | } |
1251 | |
1252 | graphene_simd4f_t |
1253 | (graphene_simd4f_div) (const graphene_simd4f_t a, |
1254 | const graphene_simd4f_t b) |
1255 | { |
1256 | graphene_simd4f_t s = { |
1257 | fabsf (b.x) > FLT_EPSILON ? a.x / b.x : 0.f, |
1258 | fabsf (b.y) > FLT_EPSILON ? a.y / b.y : 0.f, |
1259 | fabsf (b.z) > FLT_EPSILON ? a.z / b.z : 0.f, |
1260 | fabsf (b.w) > FLT_EPSILON ? a.w / b.w : 0.f |
1261 | }; |
1262 | return s; |
1263 | } |
1264 | |
1265 | graphene_simd4f_t |
1266 | (graphene_simd4f_cross3) (const graphene_simd4f_t a, |
1267 | const graphene_simd4f_t b) |
1268 | { |
1269 | return graphene_simd4f_init (a.y * b.z - a.z * b.y, |
1270 | a.z * b.x - a.x * b.z, |
1271 | a.x * b.y - a.y * b.x, |
1272 | 0.f); |
1273 | } |
1274 | |
1275 | graphene_simd4f_t |
1276 | (graphene_simd4f_dot3) (const graphene_simd4f_t a, |
1277 | const graphene_simd4f_t b) |
1278 | { |
1279 | return graphene_simd4f_splat (graphene_simd4f_dot3_scalar (a, b)); |
1280 | } |
1281 | |
1282 | float |
1283 | (graphene_simd4f_dot3_scalar) (const graphene_simd4f_t a, |
1284 | const graphene_simd4f_t b) |
1285 | { |
1286 | return a.x * b.x + a.y * b.y + a.z * b.z; |
1287 | } |
1288 | |
1289 | graphene_simd4f_t |
1290 | (graphene_simd4f_min) (const graphene_simd4f_t a, |
1291 | const graphene_simd4f_t b) |
1292 | { |
1293 | return graphene_simd4f_init (a.x < b.x ? a.x : b.x, |
1294 | a.y < b.y ? a.y : b.y, |
1295 | a.z < b.z ? a.z : b.z, |
1296 | a.w < b.w ? a.w : b.w); |
1297 | } |
1298 | |
1299 | graphene_simd4f_t |
1300 | (graphene_simd4f_max) (const graphene_simd4f_t a, |
1301 | const graphene_simd4f_t b) |
1302 | { |
1303 | return graphene_simd4f_init (a.x > b.x ? a.x : b.x, |
1304 | a.y > b.y ? a.y : b.y, |
1305 | a.z > b.z ? a.z : b.z, |
1306 | a.w > b.w ? a.w : b.w); |
1307 | } |
1308 | |
1309 | graphene_simd4f_t |
1310 | (graphene_simd4f_shuffle_wxyz) (const graphene_simd4f_t s) |
1311 | { |
1312 | return graphene_simd4f_init (s.w, s.x, s.y, s.z); |
1313 | } |
1314 | |
1315 | graphene_simd4f_t |
1316 | (graphene_simd4f_shuffle_zwxy) (const graphene_simd4f_t s) |
1317 | { |
1318 | return graphene_simd4f_init (s.z, s.w, s.x, s.y); |
1319 | } |
1320 | |
1321 | graphene_simd4f_t |
1322 | (graphene_simd4f_shuffle_yzwx) (const graphene_simd4f_t s) |
1323 | { |
1324 | return graphene_simd4f_init (s.y, s.z, s.w, s.x); |
1325 | } |
1326 | |
1327 | graphene_simd4f_t |
1328 | (graphene_simd4f_zero_w) (const graphene_simd4f_t s) |
1329 | { |
1330 | return graphene_simd4f_init (s.x, s.y, s.z, 0.0f); |
1331 | } |
1332 | |
1333 | graphene_simd4f_t |
1334 | (graphene_simd4f_zero_zw) (const graphene_simd4f_t s) |
1335 | { |
1336 | return graphene_simd4f_init (s.x, s.y, 0.0f, 0.0f); |
1337 | } |
1338 | |
1339 | graphene_simd4f_t |
1340 | (graphene_simd4f_merge_w) (const graphene_simd4f_t s, |
1341 | float v) |
1342 | { |
1343 | return graphene_simd4f_init (s.x, s.y, s.z, v); |
1344 | } |
1345 | |
1346 | graphene_simd4f_t |
1347 | (graphene_simd4f_merge_high) (const graphene_simd4f_t a, |
1348 | const graphene_simd4f_t b) |
1349 | { |
1350 | return graphene_simd4f_init (a.z, a.w, b.z, b.w); |
1351 | } |
1352 | |
1353 | graphene_simd4f_t |
1354 | (graphene_simd4f_merge_low) (const graphene_simd4f_t a, |
1355 | const graphene_simd4f_t b) |
1356 | { |
1357 | return graphene_simd4f_init (a.x, a.y, b.x, b.y); |
1358 | } |
1359 | |
1360 | graphene_simd4f_t |
1361 | (graphene_simd4f_flip_sign_0101) (const graphene_simd4f_t s) |
1362 | { |
1363 | return graphene_simd4f_init (s.x, -s.y, s.z, -s.w); |
1364 | } |
1365 | |
1366 | graphene_simd4f_t |
1367 | (graphene_simd4f_flip_sign_1010) (const graphene_simd4f_t s) |
1368 | { |
1369 | return graphene_simd4f_init (-s.x, s.y, -s.z, s.w); |
1370 | } |
1371 | |
1372 | static inline bool |
1373 | approx_equal (float a, |
1374 | float b, |
1375 | float epsilon) |
1376 | { |
1377 | #ifdef HAVE_ISINFF |
1378 | if (isinff (a) && isinff (b)) |
1379 | return true; |
1380 | #else |
1381 | if (fpclassify (a) == FP_INFINITE && fpclassify (b) == FP_INFINITE) |
1382 | return true; |
1383 | #endif |
1384 | |
1385 | float diff = fabsf (a - b); |
1386 | if (isnan (diff)) |
1387 | return true; |
1388 | |
1389 | if (diff <= epsilon) |
1390 | return true; |
1391 | |
1392 | float abs_a = fabsf (a); |
1393 | float abs_b = fabsf (b); |
1394 | |
1395 | float largest = abs_b > abs_a ? abs_b : abs_a; |
1396 | |
1397 | return diff <= largest * epsilon; |
1398 | } |
1399 | |
1400 | bool |
1401 | (graphene_simd4f_cmp_eq) (const graphene_simd4f_t a, |
1402 | const graphene_simd4f_t b) |
1403 | { |
1404 | return approx_equal (a.x, b.x, FLT_EPSILON) && |
1405 | approx_equal (a.y, b.y, FLT_EPSILON) && |
1406 | approx_equal (a.z, b.z, FLT_EPSILON) && |
1407 | approx_equal (a.w, b.w, FLT_EPSILON); |
1408 | } |
1409 | |
1410 | bool |
1411 | (graphene_simd4f_cmp_neq) (const graphene_simd4f_t a, |
1412 | const graphene_simd4f_t b) |
1413 | { |
1414 | return !approx_equal (a.x, b.x, FLT_EPSILON) || |
1415 | !approx_equal (a.y, b.y, FLT_EPSILON) || |
1416 | !approx_equal (a.z, b.z, FLT_EPSILON) || |
1417 | !approx_equal (a.w, b.w, FLT_EPSILON); |
1418 | } |
1419 | |
1420 | bool |
1421 | (graphene_simd4f_cmp_lt) (const graphene_simd4f_t a, |
1422 | const graphene_simd4f_t b) |
1423 | { |
1424 | return a.x < b.x && |
1425 | a.y < b.y && |
1426 | a.z < b.z && |
1427 | a.w < b.w; |
1428 | } |
1429 | |
1430 | bool |
1431 | (graphene_simd4f_cmp_le) (const graphene_simd4f_t a, |
1432 | const graphene_simd4f_t b) |
1433 | { |
1434 | return a.x <= b.x && |
1435 | a.y <= b.y && |
1436 | a.z <= b.z && |
1437 | a.w <= b.w; |
1438 | } |
1439 | |
1440 | bool |
1441 | (graphene_simd4f_cmp_ge) (const graphene_simd4f_t a, |
1442 | const graphene_simd4f_t b) |
1443 | { |
1444 | return a.x >= b.x && |
1445 | a.y >= b.y && |
1446 | a.z >= b.z && |
1447 | a.w >= b.w; |
1448 | } |
1449 | |
1450 | bool |
1451 | (graphene_simd4f_cmp_gt) (const graphene_simd4f_t a, |
1452 | const graphene_simd4f_t b) |
1453 | { |
1454 | return a.x > b.x && |
1455 | a.y > b.y && |
1456 | a.z > b.z && |
1457 | a.w > b.w; |
1458 | } |
1459 | |
1460 | graphene_simd4f_t |
1461 | (graphene_simd4f_neg) (const graphene_simd4f_t s) |
1462 | { |
1463 | return graphene_simd4f_init (-s.x, -s.y, -s.z, -s.w); |
1464 | } |
1465 | |
1466 | #endif /* GRAPHENE_USE_SCALAR */ |
1467 | |