1 #include "rs_types.rsh"
2
3 // Conversions
4 #define CVT_FUNC_2(typeout, typein) \
5 extern typeout##2 __attribute__((overloadable)) \
6 convert_##typeout##2(typein##2 v) { \
7 typeout##2 r = {(typeout)v.x, (typeout)v.y}; \
8 return r; \
9 } \
10 extern typeout##3 __attribute__((overloadable)) \
11 convert_##typeout##3(typein##3 v) { \
12 typeout##3 r = {(typeout)v.x, (typeout)v.y, (typeout)v.z}; \
13 return r; \
14 } \
15 extern typeout##4 __attribute__((overloadable)) \
16 convert_##typeout##4(typein##4 v) { \
17 typeout##4 r = {(typeout)v.x, (typeout)v.y, (typeout)v.z, \
18 (typeout)v.w}; \
19 return r; \
20 }
21
22 #define CVT_FUNC(type) CVT_FUNC_2(type, uchar) \
23 CVT_FUNC_2(type, char) \
24 CVT_FUNC_2(type, ushort) \
25 CVT_FUNC_2(type, short) \
26 CVT_FUNC_2(type, uint) \
27 CVT_FUNC_2(type, int) \
28 CVT_FUNC_2(type, float)
29
30 CVT_FUNC(char)
31 //CVT_FUNC(uchar)
32 CVT_FUNC(short)
33 CVT_FUNC(ushort)
34 CVT_FUNC(int)
35 CVT_FUNC(uint)
36 //CVT_FUNC(float)
37
38 // Float ops, 6.11.2
39
40 #define FN_FUNC_FN(fnc) \
41 extern float2 __attribute__((overloadable)) fnc(float2 v) { \
42 float2 r; \
43 r.x = fnc(v.x); \
44 r.y = fnc(v.y); \
45 return r; \
46 } \
47 extern float3 __attribute__((overloadable)) fnc(float3 v) { \
48 float3 r; \
49 r.x = fnc(v.x); \
50 r.y = fnc(v.y); \
51 r.z = fnc(v.z); \
52 return r; \
53 } \
54 extern float4 __attribute__((overloadable)) fnc(float4 v) { \
55 float4 r; \
56 r.x = fnc(v.x); \
57 r.y = fnc(v.y); \
58 r.z = fnc(v.z); \
59 r.w = fnc(v.w); \
60 return r; \
61 }
62
63 #define IN_FUNC_FN(fnc) \
64 extern int2 __attribute__((overloadable)) fnc(float2 v) { \
65 int2 r; \
66 r.x = fnc(v.x); \
67 r.y = fnc(v.y); \
68 return r; \
69 } \
70 extern int3 __attribute__((overloadable)) fnc(float3 v) { \
71 int3 r; \
72 r.x = fnc(v.x); \
73 r.y = fnc(v.y); \
74 r.z = fnc(v.z); \
75 return r; \
76 } \
77 extern int4 __attribute__((overloadable)) fnc(float4 v) { \
78 int4 r; \
79 r.x = fnc(v.x); \
80 r.y = fnc(v.y); \
81 r.z = fnc(v.z); \
82 r.w = fnc(v.w); \
83 return r; \
84 }
85
86 #define FN_FUNC_FN_FN(fnc) \
87 extern float2 __attribute__((overloadable)) fnc(float2 v1, float2 v2) { \
88 float2 r; \
89 r.x = fnc(v1.x, v2.x); \
90 r.y = fnc(v1.y, v2.y); \
91 return r; \
92 } \
93 extern float3 __attribute__((overloadable)) fnc(float3 v1, float3 v2) { \
94 float3 r; \
95 r.x = fnc(v1.x, v2.x); \
96 r.y = fnc(v1.y, v2.y); \
97 r.z = fnc(v1.z, v2.z); \
98 return r; \
99 } \
100 extern float4 __attribute__((overloadable)) fnc(float4 v1, float4 v2) { \
101 float4 r; \
102 r.x = fnc(v1.x, v2.x); \
103 r.y = fnc(v1.y, v2.y); \
104 r.z = fnc(v1.z, v2.z); \
105 r.w = fnc(v1.w, v2.w); \
106 return r; \
107 }
108
109 #define FN_FUNC_FN_F(fnc) \
110 extern float2 __attribute__((overloadable)) fnc(float2 v1, float v2) { \
111 float2 r; \
112 r.x = fnc(v1.x, v2); \
113 r.y = fnc(v1.y, v2); \
114 return r; \
115 } \
116 extern float3 __attribute__((overloadable)) fnc(float3 v1, float v2) { \
117 float3 r; \
118 r.x = fnc(v1.x, v2); \
119 r.y = fnc(v1.y, v2); \
120 r.z = fnc(v1.z, v2); \
121 return r; \
122 } \
123 extern float4 __attribute__((overloadable)) fnc(float4 v1, float v2) { \
124 float4 r; \
125 r.x = fnc(v1.x, v2); \
126 r.y = fnc(v1.y, v2); \
127 r.z = fnc(v1.z, v2); \
128 r.w = fnc(v1.w, v2); \
129 return r; \
130 }
131
132 #define FN_FUNC_FN_IN(fnc) \
133 extern float2 __attribute__((overloadable)) fnc(float2 v1, int2 v2) { \
134 float2 r; \
135 r.x = fnc(v1.x, v2.x); \
136 r.y = fnc(v1.y, v2.y); \
137 return r; \
138 } \
139 extern float3 __attribute__((overloadable)) fnc(float3 v1, int3 v2) { \
140 float3 r; \
141 r.x = fnc(v1.x, v2.x); \
142 r.y = fnc(v1.y, v2.y); \
143 r.z = fnc(v1.z, v2.z); \
144 return r; \
145 } \
146 extern float4 __attribute__((overloadable)) fnc(float4 v1, int4 v2) { \
147 float4 r; \
148 r.x = fnc(v1.x, v2.x); \
149 r.y = fnc(v1.y, v2.y); \
150 r.z = fnc(v1.z, v2.z); \
151 r.w = fnc(v1.w, v2.w); \
152 return r; \
153 }
154
155 #define FN_FUNC_FN_I(fnc) \
156 extern float2 __attribute__((overloadable)) fnc(float2 v1, int v2) { \
157 float2 r; \
158 r.x = fnc(v1.x, v2); \
159 r.y = fnc(v1.y, v2); \
160 return r; \
161 } \
162 extern float3 __attribute__((overloadable)) fnc(float3 v1, int v2) { \
163 float3 r; \
164 r.x = fnc(v1.x, v2); \
165 r.y = fnc(v1.y, v2); \
166 r.z = fnc(v1.z, v2); \
167 return r; \
168 } \
169 extern float4 __attribute__((overloadable)) fnc(float4 v1, int v2) { \
170 float4 r; \
171 r.x = fnc(v1.x, v2); \
172 r.y = fnc(v1.y, v2); \
173 r.z = fnc(v1.z, v2); \
174 r.w = fnc(v1.w, v2); \
175 return r; \
176 }
177
178 #define FN_FUNC_FN_PFN(fnc) \
179 extern float2 __attribute__((overloadable)) \
180 fnc(float2 v1, float2 *v2) { \
181 float2 r; \
182 float t[2]; \
183 r.x = fnc(v1.x, &t[0]); \
184 r.y = fnc(v1.y, &t[1]); \
185 v2->x = t[0]; \
186 v2->y = t[1]; \
187 return r; \
188 } \
189 extern float3 __attribute__((overloadable)) \
190 fnc(float3 v1, float3 *v2) { \
191 float3 r; \
192 float t[3]; \
193 r.x = fnc(v1.x, &t[0]); \
194 r.y = fnc(v1.y, &t[1]); \
195 r.z = fnc(v1.z, &t[2]); \
196 v2->x = t[0]; \
197 v2->y = t[1]; \
198 v2->z = t[2]; \
199 return r; \
200 } \
201 extern float4 __attribute__((overloadable)) \
202 fnc(float4 v1, float4 *v2) { \
203 float4 r; \
204 float t[4]; \
205 r.x = fnc(v1.x, &t[0]); \
206 r.y = fnc(v1.y, &t[1]); \
207 r.z = fnc(v1.z, &t[2]); \
208 r.w = fnc(v1.w, &t[3]); \
209 v2->x = t[0]; \
210 v2->y = t[1]; \
211 v2->z = t[2]; \
212 v2->w = t[3]; \
213 return r; \
214 }
215
216 #define FN_FUNC_FN_PIN(fnc) \
217 extern float2 __attribute__((overloadable)) fnc(float2 v1, int2 *v2) { \
218 float2 r; \
219 int t[2]; \
220 r.x = fnc(v1.x, &t[0]); \
221 r.y = fnc(v1.y, &t[1]); \
222 v2->x = t[0]; \
223 v2->y = t[1]; \
224 return r; \
225 } \
226 extern float3 __attribute__((overloadable)) fnc(float3 v1, int3 *v2) { \
227 float3 r; \
228 int t[3]; \
229 r.x = fnc(v1.x, &t[0]); \
230 r.y = fnc(v1.y, &t[1]); \
231 r.z = fnc(v1.z, &t[2]); \
232 v2->x = t[0]; \
233 v2->y = t[1]; \
234 v2->z = t[2]; \
235 return r; \
236 } \
237 extern float4 __attribute__((overloadable)) fnc(float4 v1, int4 *v2) { \
238 float4 r; \
239 int t[4]; \
240 r.x = fnc(v1.x, &t[0]); \
241 r.y = fnc(v1.y, &t[1]); \
242 r.z = fnc(v1.z, &t[2]); \
243 r.w = fnc(v1.w, &t[3]); \
244 v2->x = t[0]; \
245 v2->y = t[1]; \
246 v2->z = t[2]; \
247 v2->w = t[3]; \
248 return r; \
249 }
250
251 #define FN_FUNC_FN_FN_FN(fnc) \
252 extern float2 __attribute__((overloadable)) \
253 fnc(float2 v1, float2 v2, float2 v3) { \
254 float2 r; \
255 r.x = fnc(v1.x, v2.x, v3.x); \
256 r.y = fnc(v1.y, v2.y, v3.y); \
257 return r; \
258 } \
259 extern float3 __attribute__((overloadable)) \
260 fnc(float3 v1, float3 v2, float3 v3) { \
261 float3 r; \
262 r.x = fnc(v1.x, v2.x, v3.x); \
263 r.y = fnc(v1.y, v2.y, v3.y); \
264 r.z = fnc(v1.z, v2.z, v3.z); \
265 return r; \
266 } \
267 extern float4 __attribute__((overloadable)) \
268 fnc(float4 v1, float4 v2, float4 v3) { \
269 float4 r; \
270 r.x = fnc(v1.x, v2.x, v3.x); \
271 r.y = fnc(v1.y, v2.y, v3.y); \
272 r.z = fnc(v1.z, v2.z, v3.z); \
273 r.w = fnc(v1.w, v2.w, v3.w); \
274 return r; \
275 }
276
277 #define FN_FUNC_FN_FN_PIN(fnc) \
278 extern float2 __attribute__((overloadable)) \
279 fnc(float2 v1, float2 v2, int2 *v3) { \
280 float2 r; \
281 int t[2]; \
282 r.x = fnc(v1.x, v2.x, &t[0]); \
283 r.y = fnc(v1.y, v2.y, &t[1]); \
284 v3->x = t[0]; \
285 v3->y = t[1]; \
286 return r; \
287 } \
288 extern float3 __attribute__((overloadable)) \
289 fnc(float3 v1, float3 v2, int3 *v3) { \
290 float3 r; \
291 int t[3]; \
292 r.x = fnc(v1.x, v2.x, &t[0]); \
293 r.y = fnc(v1.y, v2.y, &t[1]); \
294 r.z = fnc(v1.z, v2.z, &t[2]); \
295 v3->x = t[0]; \
296 v3->y = t[1]; \
297 v3->z = t[2]; \
298 return r; \
299 } \
300 extern float4 __attribute__((overloadable)) \
301 fnc(float4 v1, float4 v2, int4 *v3) { \
302 float4 r; \
303 int t[4]; \
304 r.x = fnc(v1.x, v2.x, &t[0]); \
305 r.y = fnc(v1.y, v2.y, &t[1]); \
306 r.z = fnc(v1.z, v2.z, &t[2]); \
307 r.w = fnc(v1.w, v2.w, &t[3]); \
308 v3->x = t[0]; \
309 v3->y = t[1]; \
310 v3->z = t[2]; \
311 v3->w = t[3]; \
312 return r; \
313 }
314
315 static const int iposinf = 0x7f800000;
316 static const int ineginf = 0xff800000;
317
posinf()318 static const float posinf() {
319 float f = *((float*)&iposinf);
320 return f;
321 }
322
neginf()323 static const float neginf() {
324 float f = *((float*)&ineginf);
325 return f;
326 }
327
isinf(float f)328 static bool isinf(float f) {
329 int i = *((int*)(void*)&f);
330 return (i == iposinf) || (i == ineginf);
331 }
332
isnan(float f)333 static bool isnan(float f) {
334 int i = *((int*)(void*)&f);
335 return (((i & 0x7f800000) == 0x7f800000) && (i & 0x007fffff));
336 }
337
isposzero(float f)338 static bool isposzero(float f) {
339 int i = *((int*)(void*)&f);
340 return (i == 0x00000000);
341 }
342
isnegzero(float f)343 static bool isnegzero(float f) {
344 int i = *((int*)(void*)&f);
345 return (i == 0x80000000);
346 }
347
iszero(float f)348 static bool iszero(float f) {
349 return isposzero(f) || isnegzero(f);
350 }
351
352
353 extern float __attribute__((overloadable)) acos(float);
354 FN_FUNC_FN(acos)
355
356 extern float __attribute__((overloadable)) acosh(float);
FN_FUNC_FN(acosh)357 FN_FUNC_FN(acosh)
358
359
360 extern float __attribute__((overloadable)) acospi(float v) {
361 return acos(v) / M_PI;
362 }
363 FN_FUNC_FN(acospi)
364
365 extern float __attribute__((overloadable)) asin(float);
366 FN_FUNC_FN(asin)
367
368 extern float __attribute__((overloadable)) asinh(float);
FN_FUNC_FN(asinh)369 FN_FUNC_FN(asinh)
370
371 extern float __attribute__((overloadable)) asinpi(float v) {
372 return asin(v) / M_PI;
373 }
374 FN_FUNC_FN(asinpi)
375
376 extern float __attribute__((overloadable)) atan(float);
377 FN_FUNC_FN(atan)
378
379 extern float __attribute__((overloadable)) atan2(float, float);
380 FN_FUNC_FN_FN(atan2)
381
382 extern float __attribute__((overloadable)) atanh(float);
FN_FUNC_FN(atanh)383 FN_FUNC_FN(atanh)
384
385 extern float __attribute__((overloadable)) atanpi(float v) {
386 return atan(v) / M_PI;
387 }
FN_FUNC_FN(atanpi)388 FN_FUNC_FN(atanpi)
389
390
391 extern float __attribute__((overloadable)) atan2pi(float y, float x) {
392 return atan2(y, x) / M_PI;
393 }
394 FN_FUNC_FN_FN(atan2pi)
395
396 extern float __attribute__((overloadable)) cbrt(float);
397 FN_FUNC_FN(cbrt)
398
399 extern float __attribute__((overloadable)) ceil(float);
400 FN_FUNC_FN(ceil)
401
402 extern float __attribute__((overloadable)) copysign(float, float);
403 FN_FUNC_FN_FN(copysign)
404
405 extern float __attribute__((overloadable)) cos(float);
406 FN_FUNC_FN(cos)
407
408 extern float __attribute__((overloadable)) cosh(float);
FN_FUNC_FN(cosh)409 FN_FUNC_FN(cosh)
410
411 extern float __attribute__((overloadable)) cospi(float v) {
412 return cos(v * M_PI);
413 }
414 FN_FUNC_FN(cospi)
415
416 extern float __attribute__((overloadable)) erfc(float);
417 FN_FUNC_FN(erfc)
418
419 extern float __attribute__((overloadable)) erf(float);
420 FN_FUNC_FN(erf)
421
422 extern float __attribute__((overloadable)) exp(float);
423 FN_FUNC_FN(exp)
424
425 extern float __attribute__((overloadable)) exp2(float);
426 FN_FUNC_FN(exp2)
427
428 extern float __attribute__((overloadable)) pow(float, float);
429
exp10(float v)430 extern float __attribute__((overloadable)) exp10(float v) {
431 return pow(10.f, v);
432 }
433 FN_FUNC_FN(exp10)
434
435 extern float __attribute__((overloadable)) expm1(float);
436 FN_FUNC_FN(expm1)
437
438 extern float __attribute__((overloadable)) fabs(float);
439 FN_FUNC_FN(fabs)
440
441 extern float __attribute__((overloadable)) fdim(float, float);
442 FN_FUNC_FN_FN(fdim)
443
444 extern float __attribute__((overloadable)) floor(float);
445 FN_FUNC_FN(floor)
446
447 extern float __attribute__((overloadable)) fma(float, float, float);
448 FN_FUNC_FN_FN_FN(fma)
449
450 extern float __attribute__((overloadable)) fmax(float, float);
451 FN_FUNC_FN_FN(fmax);
452 FN_FUNC_FN_F(fmax);
453
454 extern float __attribute__((overloadable)) fmin(float, float);
455 FN_FUNC_FN_FN(fmin);
456 FN_FUNC_FN_F(fmin);
457
458 extern float __attribute__((overloadable)) fmod(float, float);
FN_FUNC_FN_FN(fmod)459 FN_FUNC_FN_FN(fmod)
460
461 extern float __attribute__((overloadable)) fract(float v, float *iptr) {
462 int i = (int)floor(v);
463 iptr[0] = i;
464 return fmin(v - i, 0x1.fffffep-1f);
465 }
466 FN_FUNC_FN_PFN(fract)
467
468 extern float __attribute__((overloadable)) frexp(float, int *);
469 FN_FUNC_FN_PIN(frexp)
470
471 extern float __attribute__((overloadable)) hypot(float, float);
472 FN_FUNC_FN_FN(hypot)
473
474 extern int __attribute__((overloadable)) ilogb(float);
475 IN_FUNC_FN(ilogb)
476
477 extern float __attribute__((overloadable)) ldexp(float, int);
478 FN_FUNC_FN_IN(ldexp)
479 FN_FUNC_FN_I(ldexp)
480
481 extern float __attribute__((overloadable)) lgamma(float);
482 FN_FUNC_FN(lgamma)
483 extern float __attribute__((overloadable)) lgamma(float, int*);
484 FN_FUNC_FN_PIN(lgamma)
485
486 extern float __attribute__((overloadable)) log(float);
487 FN_FUNC_FN(log)
488
489 extern float __attribute__((overloadable)) log10(float);
FN_FUNC_FN(log10)490 FN_FUNC_FN(log10)
491
492
493 extern float __attribute__((overloadable)) log2(float v) {
494 return log10(v) / log10(2.f);
495 }
496 FN_FUNC_FN(log2)
497
498 extern float __attribute__((overloadable)) log1p(float);
499 FN_FUNC_FN(log1p)
500
501 extern float __attribute__((overloadable)) logb(float);
FN_FUNC_FN(logb)502 FN_FUNC_FN(logb)
503
504 extern float __attribute__((overloadable)) mad(float a, float b, float c) {
505 return a * b + c;
506 }
mad(float2 a,float2 b,float2 c)507 extern float2 __attribute__((overloadable)) mad(float2 a, float2 b, float2 c) {
508 return a * b + c;
509 }
mad(float3 a,float3 b,float3 c)510 extern float3 __attribute__((overloadable)) mad(float3 a, float3 b, float3 c) {
511 return a * b + c;
512 }
mad(float4 a,float4 b,float4 c)513 extern float4 __attribute__((overloadable)) mad(float4 a, float4 b, float4 c) {
514 return a * b + c;
515 }
516
517 extern float __attribute__((overloadable)) modf(float, float *);
518 FN_FUNC_FN_PFN(modf);
519
nan(uint v)520 extern float __attribute__((overloadable)) nan(uint v) {
521 float f[1];
522 uint32_t *ip = (uint32_t *)f;
523 *ip = v | 0x7fc00000;
524 return f[0];
525 }
526
527 extern float __attribute__((overloadable)) nextafter(float, float);
528 FN_FUNC_FN_FN(nextafter)
529
FN_FUNC_FN_FN(pow)530 FN_FUNC_FN_FN(pow)
531
532 extern float __attribute__((overloadable)) pown(float v, int p) {
533 return pow(v, (float)p);
534 }
pown(float2 v,int2 p)535 extern float2 __attribute__((overloadable)) pown(float2 v, int2 p) {
536 return pow(v, (float2)p);
537 }
pown(float3 v,int3 p)538 extern float3 __attribute__((overloadable)) pown(float3 v, int3 p) {
539 return pow(v, (float3)p);
540 }
pown(float4 v,int4 p)541 extern float4 __attribute__((overloadable)) pown(float4 v, int4 p) {
542 return pow(v, (float4)p);
543 }
544
powr(float v,float p)545 extern float __attribute__((overloadable)) powr(float v, float p) {
546 return pow(v, p);
547 }
powr(float2 v,float2 p)548 extern float2 __attribute__((overloadable)) powr(float2 v, float2 p) {
549 return pow(v, p);
550 }
powr(float3 v,float3 p)551 extern float3 __attribute__((overloadable)) powr(float3 v, float3 p) {
552 return pow(v, p);
553 }
powr(float4 v,float4 p)554 extern float4 __attribute__((overloadable)) powr(float4 v, float4 p) {
555 return pow(v, p);
556 }
557
558 extern float __attribute__((overloadable)) remainder(float, float);
559 FN_FUNC_FN_FN(remainder)
560
561 extern float __attribute__((overloadable)) remquo(float, float, int *);
562 FN_FUNC_FN_FN_PIN(remquo)
563
564 extern float __attribute__((overloadable)) rint(float);
FN_FUNC_FN(rint)565 FN_FUNC_FN(rint)
566
567 extern float __attribute__((overloadable)) rootn(float v, int r) {
568 if (r == 0) {
569 return nan(0);
570 }
571
572 if (iszero(v)) {
573 if (r < 0) {
574 if (r & 1) {
575 return copysign(posinf(), v);
576 } else {
577 return posinf();
578 }
579 } else {
580 if (r & 1) {
581 return copysign(0.f, v);
582 } else {
583 return 0.f;
584 }
585 }
586 }
587
588 if (!isinf(v) && !isnan(v) && (v < 0.f)) {
589 if (r & 1) {
590 return (-1.f * pow(-1.f * v, 1.f / r));
591 } else {
592 return nan(0);
593 }
594 }
595
596 return pow(v, 1.f / r);
597 }
598 FN_FUNC_FN_IN(rootn);
599
600 extern float __attribute__((overloadable)) round(float);
601 FN_FUNC_FN(round)
602
603
604 extern float __attribute__((overloadable)) sqrt(float);
rsqrt(float v)605 extern float __attribute__((overloadable)) rsqrt(float v) {
606 return 1.f / sqrt(v);
607 }
608 FN_FUNC_FN(rsqrt)
609
610 extern float __attribute__((overloadable)) sin(float);
FN_FUNC_FN(sin)611 FN_FUNC_FN(sin)
612
613 extern float __attribute__((overloadable)) sincos(float v, float *cosptr) {
614 *cosptr = cos(v);
615 return sin(v);
616 }
sincos(float2 v,float2 * cosptr)617 extern float2 __attribute__((overloadable)) sincos(float2 v, float2 *cosptr) {
618 *cosptr = cos(v);
619 return sin(v);
620 }
sincos(float3 v,float3 * cosptr)621 extern float3 __attribute__((overloadable)) sincos(float3 v, float3 *cosptr) {
622 *cosptr = cos(v);
623 return sin(v);
624 }
sincos(float4 v,float4 * cosptr)625 extern float4 __attribute__((overloadable)) sincos(float4 v, float4 *cosptr) {
626 *cosptr = cos(v);
627 return sin(v);
628 }
629
630 extern float __attribute__((overloadable)) sinh(float);
FN_FUNC_FN(sinh)631 FN_FUNC_FN(sinh)
632
633 extern float __attribute__((overloadable)) sinpi(float v) {
634 return sin(v * M_PI);
635 }
636 FN_FUNC_FN(sinpi)
637
638 FN_FUNC_FN(sqrt)
639
640 extern float __attribute__((overloadable)) tan(float);
641 FN_FUNC_FN(tan)
642
643 extern float __attribute__((overloadable)) tanh(float);
FN_FUNC_FN(tanh)644 FN_FUNC_FN(tanh)
645
646 extern float __attribute__((overloadable)) tanpi(float v) {
647 return tan(v * M_PI);
648 }
649 FN_FUNC_FN(tanpi)
650
651
652 extern float __attribute__((overloadable)) tgamma(float);
653 FN_FUNC_FN(tgamma)
654
655 extern float __attribute__((overloadable)) trunc(float);
656 FN_FUNC_FN(trunc)
657
658 // Int ops (partial), 6.11.3
659
660 #define XN_FUNC_YN(typeout, fnc, typein) \
661 extern typeout __attribute__((overloadable)) fnc(typein); \
662 extern typeout##2 __attribute__((overloadable)) fnc(typein##2 v) { \
663 typeout##2 r; \
664 r.x = fnc(v.x); \
665 r.y = fnc(v.y); \
666 return r; \
667 } \
668 extern typeout##3 __attribute__((overloadable)) fnc(typein##3 v) { \
669 typeout##3 r; \
670 r.x = fnc(v.x); \
671 r.y = fnc(v.y); \
672 r.z = fnc(v.z); \
673 return r; \
674 } \
675 extern typeout##4 __attribute__((overloadable)) fnc(typein##4 v) { \
676 typeout##4 r; \
677 r.x = fnc(v.x); \
678 r.y = fnc(v.y); \
679 r.z = fnc(v.z); \
680 r.w = fnc(v.w); \
681 return r; \
682 }
683
684
685 #define UIN_FUNC_IN(fnc) \
686 XN_FUNC_YN(uchar, fnc, char) \
687 XN_FUNC_YN(ushort, fnc, short) \
688 XN_FUNC_YN(uint, fnc, int)
689
690 #define IN_FUNC_IN(fnc) \
691 XN_FUNC_YN(uchar, fnc, uchar) \
692 XN_FUNC_YN(char, fnc, char) \
693 XN_FUNC_YN(ushort, fnc, ushort) \
694 XN_FUNC_YN(short, fnc, short) \
695 XN_FUNC_YN(uint, fnc, uint) \
696 XN_FUNC_YN(int, fnc, int)
697
698
699 #define XN_FUNC_XN_XN_BODY(type, fnc, body) \
700 extern type __attribute__((overloadable)) \
701 fnc(type v1, type v2) { \
702 return body; \
703 } \
704 extern type##2 __attribute__((overloadable)) \
705 fnc(type##2 v1, type##2 v2) { \
706 type##2 r; \
707 r.x = fnc(v1.x, v2.x); \
708 r.y = fnc(v1.y, v2.y); \
709 return r; \
710 } \
711 extern type##3 __attribute__((overloadable)) \
712 fnc(type##3 v1, type##3 v2) { \
713 type##3 r; \
714 r.x = fnc(v1.x, v2.x); \
715 r.y = fnc(v1.y, v2.y); \
716 r.z = fnc(v1.z, v2.z); \
717 return r; \
718 } \
719 extern type##4 __attribute__((overloadable)) \
720 fnc(type##4 v1, type##4 v2) { \
721 type##4 r; \
722 r.x = fnc(v1.x, v2.x); \
723 r.y = fnc(v1.y, v2.y); \
724 r.z = fnc(v1.z, v2.z); \
725 r.w = fnc(v1.w, v2.w); \
726 return r; \
727 }
728
729 #define IN_FUNC_IN_IN_BODY(fnc, body) \
730 XN_FUNC_XN_XN_BODY(uchar, fnc, body) \
731 XN_FUNC_XN_XN_BODY(char, fnc, body) \
732 XN_FUNC_XN_XN_BODY(ushort, fnc, body) \
733 XN_FUNC_XN_XN_BODY(short, fnc, body) \
734 XN_FUNC_XN_XN_BODY(uint, fnc, body) \
735 XN_FUNC_XN_XN_BODY(int, fnc, body) \
736 XN_FUNC_XN_XN_BODY(float, fnc, body)
737
UIN_FUNC_IN(abs)738 UIN_FUNC_IN(abs)
739 IN_FUNC_IN(clz)
740
741 IN_FUNC_IN_IN_BODY(min, (v1 < v2 ? v1 : v2))
742 FN_FUNC_FN_F(min)
743
744 IN_FUNC_IN_IN_BODY(max, (v1 > v2 ? v1 : v2))
745 FN_FUNC_FN_F(max)
746
747
748 // 6.11.4
749
750
751 extern float __attribute__((overloadable)) degrees(float radians) {
752 return radians * (180.f / M_PI);
753 }
FN_FUNC_FN(degrees)754 FN_FUNC_FN(degrees)
755
756 extern float __attribute__((overloadable)) mix(float start, float stop, float amount) {
757 return start + (stop - start) * amount;
758 }
mix(float2 start,float2 stop,float2 amount)759 extern float2 __attribute__((overloadable)) mix(float2 start, float2 stop, float2 amount) {
760 return start + (stop - start) * amount;
761 }
mix(float3 start,float3 stop,float3 amount)762 extern float3 __attribute__((overloadable)) mix(float3 start, float3 stop, float3 amount) {
763 return start + (stop - start) * amount;
764 }
mix(float4 start,float4 stop,float4 amount)765 extern float4 __attribute__((overloadable)) mix(float4 start, float4 stop, float4 amount) {
766 return start + (stop - start) * amount;
767 }
mix(float2 start,float2 stop,float amount)768 extern float2 __attribute__((overloadable)) mix(float2 start, float2 stop, float amount) {
769 return start + (stop - start) * amount;
770 }
mix(float3 start,float3 stop,float amount)771 extern float3 __attribute__((overloadable)) mix(float3 start, float3 stop, float amount) {
772 return start + (stop - start) * amount;
773 }
mix(float4 start,float4 stop,float amount)774 extern float4 __attribute__((overloadable)) mix(float4 start, float4 stop, float amount) {
775 return start + (stop - start) * amount;
776 }
777
radians(float degrees)778 extern float __attribute__((overloadable)) radians(float degrees) {
779 return degrees * (M_PI / 180.f);
780 }
FN_FUNC_FN(radians)781 FN_FUNC_FN(radians)
782
783 extern float __attribute__((overloadable)) step(float edge, float v) {
784 return (v < edge) ? 0.f : 1.f;
785 }
step(float2 edge,float2 v)786 extern float2 __attribute__((overloadable)) step(float2 edge, float2 v) {
787 float2 r;
788 r.x = (v.x < edge.x) ? 0.f : 1.f;
789 r.y = (v.y < edge.y) ? 0.f : 1.f;
790 return r;
791 }
step(float3 edge,float3 v)792 extern float3 __attribute__((overloadable)) step(float3 edge, float3 v) {
793 float3 r;
794 r.x = (v.x < edge.x) ? 0.f : 1.f;
795 r.y = (v.y < edge.y) ? 0.f : 1.f;
796 r.z = (v.z < edge.z) ? 0.f : 1.f;
797 return r;
798 }
step(float4 edge,float4 v)799 extern float4 __attribute__((overloadable)) step(float4 edge, float4 v) {
800 float4 r;
801 r.x = (v.x < edge.x) ? 0.f : 1.f;
802 r.y = (v.y < edge.y) ? 0.f : 1.f;
803 r.z = (v.z < edge.z) ? 0.f : 1.f;
804 r.w = (v.w < edge.w) ? 0.f : 1.f;
805 return r;
806 }
step(float2 edge,float v)807 extern float2 __attribute__((overloadable)) step(float2 edge, float v) {
808 float2 r;
809 r.x = (v < edge.x) ? 0.f : 1.f;
810 r.y = (v < edge.y) ? 0.f : 1.f;
811 return r;
812 }
step(float3 edge,float v)813 extern float3 __attribute__((overloadable)) step(float3 edge, float v) {
814 float3 r;
815 r.x = (v < edge.x) ? 0.f : 1.f;
816 r.y = (v < edge.y) ? 0.f : 1.f;
817 r.z = (v < edge.z) ? 0.f : 1.f;
818 return r;
819 }
step(float4 edge,float v)820 extern float4 __attribute__((overloadable)) step(float4 edge, float v) {
821 float4 r;
822 r.x = (v < edge.x) ? 0.f : 1.f;
823 r.y = (v < edge.y) ? 0.f : 1.f;
824 r.z = (v < edge.z) ? 0.f : 1.f;
825 r.w = (v < edge.w) ? 0.f : 1.f;
826 return r;
827 }
828
829 extern float __attribute__((overloadable)) smoothstep(float, float, float);
830 extern float2 __attribute__((overloadable)) smoothstep(float2, float2, float2);
831 extern float3 __attribute__((overloadable)) smoothstep(float3, float3, float3);
832 extern float4 __attribute__((overloadable)) smoothstep(float4, float4, float4);
833 extern float2 __attribute__((overloadable)) smoothstep(float, float, float2);
834 extern float3 __attribute__((overloadable)) smoothstep(float, float, float3);
835 extern float4 __attribute__((overloadable)) smoothstep(float, float, float4);
836
sign(float v)837 extern float __attribute__((overloadable)) sign(float v) {
838 if (v > 0) return 1.f;
839 if (v < 0) return -1.f;
840 return v;
841 }
FN_FUNC_FN(sign)842 FN_FUNC_FN(sign)
843
844
845 // 6.11.5
846 extern float3 __attribute__((overloadable)) cross(float3 lhs, float3 rhs) {
847 float3 r;
848 r.x = lhs.y * rhs.z - lhs.z * rhs.y;
849 r.y = lhs.z * rhs.x - lhs.x * rhs.z;
850 r.z = lhs.x * rhs.y - lhs.y * rhs.x;
851 return r;
852 }
853
cross(float4 lhs,float4 rhs)854 extern float4 __attribute__((overloadable)) cross(float4 lhs, float4 rhs) {
855 float4 r;
856 r.x = lhs.y * rhs.z - lhs.z * rhs.y;
857 r.y = lhs.z * rhs.x - lhs.x * rhs.z;
858 r.z = lhs.x * rhs.y - lhs.y * rhs.x;
859 r.w = 0.f;
860 return r;
861 }
862
dot(float lhs,float rhs)863 extern float __attribute__((overloadable)) dot(float lhs, float rhs) {
864 return lhs * rhs;
865 }
dot(float2 lhs,float2 rhs)866 extern float __attribute__((overloadable)) dot(float2 lhs, float2 rhs) {
867 return lhs.x*rhs.x + lhs.y*rhs.y;
868 }
dot(float3 lhs,float3 rhs)869 extern float __attribute__((overloadable)) dot(float3 lhs, float3 rhs) {
870 return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z;
871 }
dot(float4 lhs,float4 rhs)872 extern float __attribute__((overloadable)) dot(float4 lhs, float4 rhs) {
873 return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z + lhs.w*rhs.w;
874 }
875
length(float v)876 extern float __attribute__((overloadable)) length(float v) {
877 return v;
878 }
length(float2 v)879 extern float __attribute__((overloadable)) length(float2 v) {
880 return sqrt(v.x*v.x + v.y*v.y);
881 }
length(float3 v)882 extern float __attribute__((overloadable)) length(float3 v) {
883 return sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
884 }
length(float4 v)885 extern float __attribute__((overloadable)) length(float4 v) {
886 return sqrt(v.x*v.x + v.y*v.y + v.z*v.z + v.w*v.w);
887 }
888
distance(float lhs,float rhs)889 extern float __attribute__((overloadable)) distance(float lhs, float rhs) {
890 return length(lhs - rhs);
891 }
distance(float2 lhs,float2 rhs)892 extern float __attribute__((overloadable)) distance(float2 lhs, float2 rhs) {
893 return length(lhs - rhs);
894 }
distance(float3 lhs,float3 rhs)895 extern float __attribute__((overloadable)) distance(float3 lhs, float3 rhs) {
896 return length(lhs - rhs);
897 }
distance(float4 lhs,float4 rhs)898 extern float __attribute__((overloadable)) distance(float4 lhs, float4 rhs) {
899 return length(lhs - rhs);
900 }
901
normalize(float v)902 extern float __attribute__((overloadable)) normalize(float v) {
903 return 1.f;
904 }
normalize(float2 v)905 extern float2 __attribute__((overloadable)) normalize(float2 v) {
906 return v / length(v);
907 }
normalize(float3 v)908 extern float3 __attribute__((overloadable)) normalize(float3 v) {
909 return v / length(v);
910 }
normalize(float4 v)911 extern float4 __attribute__((overloadable)) normalize(float4 v) {
912 return v / length(v);
913 }
914
915 #undef CVT_FUNC
916 #undef CVT_FUNC_2
917 #undef FN_FUNC_FN
918 #undef IN_FUNC_FN
919 #undef FN_FUNC_FN_FN
920 #undef FN_FUNC_FN_F
921 #undef FN_FUNC_FN_IN
922 #undef FN_FUNC_FN_I
923 #undef FN_FUNC_FN_PFN
924 #undef FN_FUNC_FN_PIN
925 #undef FN_FUNC_FN_FN_FN
926 #undef FN_FUNC_FN_FN_PIN
927 #undef XN_FUNC_YN
928 #undef UIN_FUNC_IN
929 #undef IN_FUNC_IN
930 #undef XN_FUNC_XN_XN_BODY
931 #undef IN_FUNC_IN_IN_BODY
932