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 extern float __attribute__((overloadable)) acos(float);
316 FN_FUNC_FN(acos)
317
318 extern float __attribute__((overloadable)) acosh(float);
FN_FUNC_FN(acosh)319 FN_FUNC_FN(acosh)
320
321
322 extern float __attribute__((overloadable)) acospi(float v) {
323 return acos(v) / M_PI;
324 }
325 FN_FUNC_FN(acospi)
326
327 extern float __attribute__((overloadable)) asin(float);
328 FN_FUNC_FN(asin)
329
330 extern float __attribute__((overloadable)) asinh(float);
FN_FUNC_FN(asinh)331 FN_FUNC_FN(asinh)
332
333 extern float __attribute__((overloadable)) asinpi(float v) {
334 return asin(v) / M_PI;
335 }
336 FN_FUNC_FN(asinpi)
337
338 extern float __attribute__((overloadable)) atan(float);
339 FN_FUNC_FN(atan)
340
341 extern float __attribute__((overloadable)) atan2(float, float);
342 FN_FUNC_FN_FN(atan2)
343
344 extern float __attribute__((overloadable)) atanh(float);
FN_FUNC_FN(atanh)345 FN_FUNC_FN(atanh)
346
347 extern float __attribute__((overloadable)) atanpi(float v) {
348 return atan(v) / M_PI;
349 }
FN_FUNC_FN(atanpi)350 FN_FUNC_FN(atanpi)
351
352
353 extern float __attribute__((overloadable)) atan2pi(float y, float x) {
354 return atan2(y, x) / M_PI;
355 }
356 FN_FUNC_FN_FN(atan2pi)
357
358 extern float __attribute__((overloadable)) cbrt(float);
359 FN_FUNC_FN(cbrt)
360
361 extern float __attribute__((overloadable)) ceil(float);
362 FN_FUNC_FN(ceil)
363
364 extern float __attribute__((overloadable)) copysign(float, float);
365 FN_FUNC_FN_FN(copysign)
366
367 extern float __attribute__((overloadable)) cos(float);
368 FN_FUNC_FN(cos)
369
370 extern float __attribute__((overloadable)) cosh(float);
FN_FUNC_FN(cosh)371 FN_FUNC_FN(cosh)
372
373 extern float __attribute__((overloadable)) cospi(float v) {
374 return cos(v * M_PI);
375 }
376 FN_FUNC_FN(cospi)
377
378 extern float __attribute__((overloadable)) erfc(float);
379 FN_FUNC_FN(erfc)
380
381 extern float __attribute__((overloadable)) erf(float);
382 FN_FUNC_FN(erf)
383
384 extern float __attribute__((overloadable)) exp(float);
385 FN_FUNC_FN(exp)
386
387 extern float __attribute__((overloadable)) exp2(float);
388 FN_FUNC_FN(exp2)
389
390 extern float __attribute__((overloadable)) pow(float, float);
391
exp10(float v)392 extern float __attribute__((overloadable)) exp10(float v) {
393 return pow(10.f, v);
394 }
395 FN_FUNC_FN(exp10)
396
397 extern float __attribute__((overloadable)) expm1(float);
398 FN_FUNC_FN(expm1)
399
400 extern float __attribute__((overloadable)) fabs(float);
401 FN_FUNC_FN(fabs)
402
403 extern float __attribute__((overloadable)) fdim(float, float);
404 FN_FUNC_FN_FN(fdim)
405
406 extern float __attribute__((overloadable)) floor(float);
407 FN_FUNC_FN(floor)
408
409 extern float __attribute__((overloadable)) fma(float, float, float);
410 FN_FUNC_FN_FN_FN(fma)
411
412 extern float __attribute__((overloadable)) fmax(float, float);
413 FN_FUNC_FN_FN(fmax);
414 FN_FUNC_FN_F(fmax);
415
416 extern float __attribute__((overloadable)) fmin(float, float);
417 FN_FUNC_FN_FN(fmin);
418 FN_FUNC_FN_F(fmin);
419
420 extern float __attribute__((overloadable)) fmod(float, float);
FN_FUNC_FN_FN(fmod)421 FN_FUNC_FN_FN(fmod)
422
423 extern float __attribute__((overloadable)) fract(float v, float *iptr) {
424 int i = (int)floor(v);
425 iptr[0] = i;
426 return fmin(v - i, 0x1.fffffep-1f);
427 }
428 FN_FUNC_FN_PFN(fract)
429
430 extern float __attribute__((overloadable)) frexp(float, int *);
431 FN_FUNC_FN_PIN(frexp)
432
433 extern float __attribute__((overloadable)) hypot(float, float);
434 FN_FUNC_FN_FN(hypot)
435
436 extern int __attribute__((overloadable)) ilogb(float);
437 IN_FUNC_FN(ilogb)
438
439 extern float __attribute__((overloadable)) ldexp(float, int);
440 FN_FUNC_FN_IN(ldexp)
441 FN_FUNC_FN_I(ldexp)
442
443 extern float __attribute__((overloadable)) lgamma(float);
444 FN_FUNC_FN(lgamma)
445 extern float __attribute__((overloadable)) lgamma(float, int*);
446 FN_FUNC_FN_PIN(lgamma)
447
448 extern float __attribute__((overloadable)) log(float);
449 FN_FUNC_FN(log)
450
451 extern float __attribute__((overloadable)) log10(float);
FN_FUNC_FN(log10)452 FN_FUNC_FN(log10)
453
454
455 extern float __attribute__((overloadable)) log2(float v) {
456 return log10(v) / log10(2.f);
457 }
458 FN_FUNC_FN(log2)
459
460 extern float __attribute__((overloadable)) log1p(float);
461 FN_FUNC_FN(log1p)
462
463 extern float __attribute__((overloadable)) logb(float);
464 FN_FUNC_FN(logb)
465
466 extern float __attribute__((overloadable)) mad(float, float, float);
467 FN_FUNC_FN_FN_FN(mad)
468
469 extern float __attribute__((overloadable)) modf(float, float *);
470 FN_FUNC_FN_PFN(modf);
471
472 //extern float __attribute__((overloadable)) nan(uint);
473
474 extern float __attribute__((overloadable)) nextafter(float, float);
475 FN_FUNC_FN_FN(nextafter)
476
FN_FUNC_FN_FN(pow)477 FN_FUNC_FN_FN(pow)
478
479 extern float __attribute__((overloadable)) pown(float v, int p) {
480 return pow(v, (float)p);
481 }
pown(float2 v,int2 p)482 extern float2 __attribute__((overloadable)) pown(float2 v, int2 p) {
483 return pow(v, (float2)p);
484 }
pown(float3 v,int3 p)485 extern float3 __attribute__((overloadable)) pown(float3 v, int3 p) {
486 return pow(v, (float3)p);
487 }
pown(float4 v,int4 p)488 extern float4 __attribute__((overloadable)) pown(float4 v, int4 p) {
489 return pow(v, (float4)p);
490 }
491
powr(float v,float p)492 extern float __attribute__((overloadable)) powr(float v, float p) {
493 return pow(v, p);
494 }
powr(float2 v,float2 p)495 extern float2 __attribute__((overloadable)) powr(float2 v, float2 p) {
496 return pow(v, p);
497 }
powr(float3 v,float3 p)498 extern float3 __attribute__((overloadable)) powr(float3 v, float3 p) {
499 return pow(v, p);
500 }
powr(float4 v,float4 p)501 extern float4 __attribute__((overloadable)) powr(float4 v, float4 p) {
502 return pow(v, p);
503 }
504
505 extern float __attribute__((overloadable)) remainder(float, float);
506 FN_FUNC_FN_FN(remainder)
507
508 extern float __attribute__((overloadable)) remquo(float, float, int *);
509 FN_FUNC_FN_FN_PIN(remquo)
510
511 extern float __attribute__((overloadable)) rint(float);
FN_FUNC_FN(rint)512 FN_FUNC_FN(rint)
513
514 extern float __attribute__((overloadable)) rootn(float v, int r) {
515 return pow(v, 1.f / r);
516 }
rootn(float2 v,int2 r)517 extern float2 __attribute__((overloadable)) rootn(float2 v, int2 r) {
518 float2 t = {1.f / r.x, 1.f / r.y};
519 return pow(v, t);
520 }
rootn(float3 v,int3 r)521 extern float3 __attribute__((overloadable)) rootn(float3 v, int3 r) {
522 float3 t = {1.f / r.x, 1.f / r.y, 1.f / r.z};
523 return pow(v, t);
524 }
rootn(float4 v,int4 r)525 extern float4 __attribute__((overloadable)) rootn(float4 v, int4 r) {
526 float4 t = {1.f / r.x, 1.f / r.y, 1.f / r.z, 1.f / r.w};
527 return pow(v, t);
528 }
529
530 extern float __attribute__((overloadable)) round(float);
531 FN_FUNC_FN(round)
532
533
534 extern float __attribute__((overloadable)) sqrt(float);
rsqrt(float v)535 extern float __attribute__((overloadable)) rsqrt(float v) {
536 return 1.f / sqrt(v);
537 }
538 FN_FUNC_FN(rsqrt)
539
540 extern float __attribute__((overloadable)) sin(float);
FN_FUNC_FN(sin)541 FN_FUNC_FN(sin)
542
543 extern float __attribute__((overloadable)) sincos(float v, float *cosptr) {
544 *cosptr = cos(v);
545 return sin(v);
546 }
sincos(float2 v,float2 * cosptr)547 extern float2 __attribute__((overloadable)) sincos(float2 v, float2 *cosptr) {
548 *cosptr = cos(v);
549 return sin(v);
550 }
sincos(float3 v,float3 * cosptr)551 extern float3 __attribute__((overloadable)) sincos(float3 v, float3 *cosptr) {
552 *cosptr = cos(v);
553 return sin(v);
554 }
sincos(float4 v,float4 * cosptr)555 extern float4 __attribute__((overloadable)) sincos(float4 v, float4 *cosptr) {
556 *cosptr = cos(v);
557 return sin(v);
558 }
559
560 extern float __attribute__((overloadable)) sinh(float);
FN_FUNC_FN(sinh)561 FN_FUNC_FN(sinh)
562
563 extern float __attribute__((overloadable)) sinpi(float v) {
564 return sin(v * M_PI);
565 }
566 FN_FUNC_FN(sinpi)
567
568 FN_FUNC_FN(sqrt)
569
570 extern float __attribute__((overloadable)) tan(float);
571 FN_FUNC_FN(tan)
572
573 extern float __attribute__((overloadable)) tanh(float);
FN_FUNC_FN(tanh)574 FN_FUNC_FN(tanh)
575
576 extern float __attribute__((overloadable)) tanpi(float v) {
577 return tan(v * M_PI);
578 }
579 FN_FUNC_FN(tanpi)
580
581
582 extern float __attribute__((overloadable)) tgamma(float);
583 FN_FUNC_FN(tgamma)
584
585 extern float __attribute__((overloadable)) trunc(float);
586 FN_FUNC_FN(trunc)
587
588 // Int ops (partial), 6.11.3
589
590 #define XN_FUNC_YN(typeout, fnc, typein) \
591 extern typeout __attribute__((overloadable)) fnc(typein); \
592 extern typeout##2 __attribute__((overloadable)) fnc(typein##2 v) { \
593 typeout##2 r; \
594 r.x = fnc(v.x); \
595 r.y = fnc(v.y); \
596 return r; \
597 } \
598 extern typeout##3 __attribute__((overloadable)) fnc(typein##3 v) { \
599 typeout##3 r; \
600 r.x = fnc(v.x); \
601 r.y = fnc(v.y); \
602 r.z = fnc(v.z); \
603 return r; \
604 } \
605 extern typeout##4 __attribute__((overloadable)) fnc(typein##4 v) { \
606 typeout##4 r; \
607 r.x = fnc(v.x); \
608 r.y = fnc(v.y); \
609 r.z = fnc(v.z); \
610 r.w = fnc(v.w); \
611 return r; \
612 }
613
614
615 #define UIN_FUNC_IN(fnc) \
616 XN_FUNC_YN(uchar, fnc, char) \
617 XN_FUNC_YN(ushort, fnc, short) \
618 XN_FUNC_YN(uint, fnc, int)
619
620 #define IN_FUNC_IN(fnc) \
621 XN_FUNC_YN(uchar, fnc, uchar) \
622 XN_FUNC_YN(char, fnc, char) \
623 XN_FUNC_YN(ushort, fnc, ushort) \
624 XN_FUNC_YN(short, fnc, short) \
625 XN_FUNC_YN(uint, fnc, uint) \
626 XN_FUNC_YN(int, fnc, int)
627
628
629 #define XN_FUNC_XN_XN_BODY(type, fnc, body) \
630 extern type __attribute__((overloadable)) \
631 fnc(type v1, type v2) { \
632 return body; \
633 } \
634 extern type##2 __attribute__((overloadable)) \
635 fnc(type##2 v1, type##2 v2) { \
636 type##2 r; \
637 r.x = fnc(v1.x, v2.x); \
638 r.y = fnc(v1.y, v2.y); \
639 return r; \
640 } \
641 extern type##3 __attribute__((overloadable)) \
642 fnc(type##3 v1, type##3 v2) { \
643 type##3 r; \
644 r.x = fnc(v1.x, v2.x); \
645 r.y = fnc(v1.y, v2.y); \
646 r.z = fnc(v1.z, v2.z); \
647 return r; \
648 } \
649 extern type##4 __attribute__((overloadable)) \
650 fnc(type##4 v1, type##4 v2) { \
651 type##4 r; \
652 r.x = fnc(v1.x, v2.x); \
653 r.y = fnc(v1.y, v2.y); \
654 r.z = fnc(v1.z, v2.z); \
655 r.w = fnc(v1.w, v2.w); \
656 return r; \
657 }
658
659 #define IN_FUNC_IN_IN_BODY(fnc, body) \
660 XN_FUNC_XN_XN_BODY(uchar, fnc, body) \
661 XN_FUNC_XN_XN_BODY(char, fnc, body) \
662 XN_FUNC_XN_XN_BODY(ushort, fnc, body) \
663 XN_FUNC_XN_XN_BODY(short, fnc, body) \
664 XN_FUNC_XN_XN_BODY(uint, fnc, body) \
665 XN_FUNC_XN_XN_BODY(int, fnc, body) \
666 XN_FUNC_XN_XN_BODY(float, fnc, body)
667
UIN_FUNC_IN(abs)668 UIN_FUNC_IN(abs)
669 IN_FUNC_IN(clz)
670
671 IN_FUNC_IN_IN_BODY(min, (v1 < v2 ? v1 : v2))
672 FN_FUNC_FN_F(min)
673
674 IN_FUNC_IN_IN_BODY(max, (v1 > v2 ? v1 : v2))
675 FN_FUNC_FN_F(max)
676
677
678 // 6.11.4
679
680 extern float __attribute__((overloadable)) clamp(float amount, float low, float high) {
681 return amount < low ? low : (amount > high ? high : amount);
682 }
clamp(float2 amount,float2 low,float2 high)683 extern float2 __attribute__((overloadable)) clamp(float2 amount, float2 low, float2 high) {
684 float2 r;
685 r.x = amount.x < low.x ? low.x : (amount.x > high.x ? high.x : amount.x);
686 r.y = amount.y < low.y ? low.y : (amount.y > high.y ? high.y : amount.y);
687 return r;
688 }
clamp(float3 amount,float3 low,float3 high)689 extern float3 __attribute__((overloadable)) clamp(float3 amount, float3 low, float3 high) {
690 float3 r;
691 r.x = amount.x < low.x ? low.x : (amount.x > high.x ? high.x : amount.x);
692 r.y = amount.y < low.y ? low.y : (amount.y > high.y ? high.y : amount.y);
693 r.z = amount.z < low.z ? low.z : (amount.z > high.z ? high.z : amount.z);
694 return r;
695 }
clamp(float4 amount,float4 low,float4 high)696 extern float4 __attribute__((overloadable)) clamp(float4 amount, float4 low, float4 high) {
697 float4 r;
698 r.x = amount.x < low.x ? low.x : (amount.x > high.x ? high.x : amount.x);
699 r.y = amount.y < low.y ? low.y : (amount.y > high.y ? high.y : amount.y);
700 r.z = amount.z < low.z ? low.z : (amount.z > high.z ? high.z : amount.z);
701 r.w = amount.w < low.w ? low.w : (amount.w > high.w ? high.w : amount.w);
702 return r;
703 }
clamp(float2 amount,float low,float high)704 extern float2 __attribute__((overloadable)) clamp(float2 amount, float low, float high) {
705 float2 r;
706 r.x = amount.x < low ? low : (amount.x > high ? high : amount.x);
707 r.y = amount.y < low ? low : (amount.y > high ? high : amount.y);
708 return r;
709 }
clamp(float3 amount,float low,float high)710 extern float3 __attribute__((overloadable)) clamp(float3 amount, float low, float high) {
711 float3 r;
712 r.x = amount.x < low ? low : (amount.x > high ? high : amount.x);
713 r.y = amount.y < low ? low : (amount.y > high ? high : amount.y);
714 r.z = amount.z < low ? low : (amount.z > high ? high : amount.z);
715 return r;
716 }
clamp(float4 amount,float low,float high)717 extern float4 __attribute__((overloadable)) clamp(float4 amount, float low, float high) {
718 float4 r;
719 r.x = amount.x < low ? low : (amount.x > high ? high : amount.x);
720 r.y = amount.y < low ? low : (amount.y > high ? high : amount.y);
721 r.z = amount.z < low ? low : (amount.z > high ? high : amount.z);
722 r.w = amount.w < low ? low : (amount.w > high ? high : amount.w);
723 return r;
724 }
725
degrees(float radians)726 extern float __attribute__((overloadable)) degrees(float radians) {
727 return radians * (180.f / M_PI);
728 }
FN_FUNC_FN(degrees)729 FN_FUNC_FN(degrees)
730
731 extern float __attribute__((overloadable)) mix(float start, float stop, float amount) {
732 return start + (stop - start) * amount;
733 }
mix(float2 start,float2 stop,float2 amount)734 extern float2 __attribute__((overloadable)) mix(float2 start, float2 stop, float2 amount) {
735 return start + (stop - start) * amount;
736 }
mix(float3 start,float3 stop,float3 amount)737 extern float3 __attribute__((overloadable)) mix(float3 start, float3 stop, float3 amount) {
738 return start + (stop - start) * amount;
739 }
mix(float4 start,float4 stop,float4 amount)740 extern float4 __attribute__((overloadable)) mix(float4 start, float4 stop, float4 amount) {
741 return start + (stop - start) * amount;
742 }
mix(float2 start,float2 stop,float amount)743 extern float2 __attribute__((overloadable)) mix(float2 start, float2 stop, float amount) {
744 return start + (stop - start) * amount;
745 }
mix(float3 start,float3 stop,float amount)746 extern float3 __attribute__((overloadable)) mix(float3 start, float3 stop, float amount) {
747 return start + (stop - start) * amount;
748 }
mix(float4 start,float4 stop,float amount)749 extern float4 __attribute__((overloadable)) mix(float4 start, float4 stop, float amount) {
750 return start + (stop - start) * amount;
751 }
752
radians(float degrees)753 extern float __attribute__((overloadable)) radians(float degrees) {
754 return degrees * (M_PI / 180.f);
755 }
FN_FUNC_FN(radians)756 FN_FUNC_FN(radians)
757
758 extern float __attribute__((overloadable)) step(float edge, float v) {
759 return (v < edge) ? 0.f : 1.f;
760 }
step(float2 edge,float2 v)761 extern float2 __attribute__((overloadable)) step(float2 edge, float2 v) {
762 float2 r;
763 r.x = (v.x < edge.x) ? 0.f : 1.f;
764 r.y = (v.y < edge.y) ? 0.f : 1.f;
765 return r;
766 }
step(float3 edge,float3 v)767 extern float3 __attribute__((overloadable)) step(float3 edge, float3 v) {
768 float3 r;
769 r.x = (v.x < edge.x) ? 0.f : 1.f;
770 r.y = (v.y < edge.y) ? 0.f : 1.f;
771 r.z = (v.z < edge.z) ? 0.f : 1.f;
772 return r;
773 }
step(float4 edge,float4 v)774 extern float4 __attribute__((overloadable)) step(float4 edge, float4 v) {
775 float4 r;
776 r.x = (v.x < edge.x) ? 0.f : 1.f;
777 r.y = (v.y < edge.y) ? 0.f : 1.f;
778 r.z = (v.z < edge.z) ? 0.f : 1.f;
779 r.w = (v.w < edge.w) ? 0.f : 1.f;
780 return r;
781 }
step(float2 edge,float v)782 extern float2 __attribute__((overloadable)) step(float2 edge, float v) {
783 float2 r;
784 r.x = (v < edge.x) ? 0.f : 1.f;
785 r.y = (v < edge.y) ? 0.f : 1.f;
786 return r;
787 }
step(float3 edge,float v)788 extern float3 __attribute__((overloadable)) step(float3 edge, float v) {
789 float3 r;
790 r.x = (v < edge.x) ? 0.f : 1.f;
791 r.y = (v < edge.y) ? 0.f : 1.f;
792 r.z = (v < edge.z) ? 0.f : 1.f;
793 return r;
794 }
step(float4 edge,float v)795 extern float4 __attribute__((overloadable)) step(float4 edge, float v) {
796 float4 r;
797 r.x = (v < edge.x) ? 0.f : 1.f;
798 r.y = (v < edge.y) ? 0.f : 1.f;
799 r.z = (v < edge.z) ? 0.f : 1.f;
800 r.w = (v < edge.w) ? 0.f : 1.f;
801 return r;
802 }
803
804 extern float __attribute__((overloadable)) smoothstep(float, float, float);
805 extern float2 __attribute__((overloadable)) smoothstep(float2, float2, float2);
806 extern float3 __attribute__((overloadable)) smoothstep(float3, float3, float3);
807 extern float4 __attribute__((overloadable)) smoothstep(float4, float4, float4);
808 extern float2 __attribute__((overloadable)) smoothstep(float, float, float2);
809 extern float3 __attribute__((overloadable)) smoothstep(float, float, float3);
810 extern float4 __attribute__((overloadable)) smoothstep(float, float, float4);
811
sign(float v)812 extern float __attribute__((overloadable)) sign(float v) {
813 if (v > 0) return 1.f;
814 if (v < 0) return -1.f;
815 return v;
816 }
FN_FUNC_FN(sign)817 FN_FUNC_FN(sign)
818
819
820 // 6.11.5
821 extern float3 __attribute__((overloadable)) cross(float3 lhs, float3 rhs) {
822 float3 r;
823 r.x = lhs.y * rhs.z - lhs.z * rhs.y;
824 r.y = lhs.z * rhs.x - lhs.x * rhs.z;
825 r.z = lhs.x * rhs.y - lhs.y * rhs.x;
826 return r;
827 }
828
cross(float4 lhs,float4 rhs)829 extern float4 __attribute__((overloadable)) cross(float4 lhs, float4 rhs) {
830 float4 r;
831 r.x = lhs.y * rhs.z - lhs.z * rhs.y;
832 r.y = lhs.z * rhs.x - lhs.x * rhs.z;
833 r.z = lhs.x * rhs.y - lhs.y * rhs.x;
834 r.w = 0.f;
835 return r;
836 }
837
dot(float lhs,float rhs)838 extern float __attribute__((overloadable)) dot(float lhs, float rhs) {
839 return lhs * rhs;
840 }
dot(float2 lhs,float2 rhs)841 extern float __attribute__((overloadable)) dot(float2 lhs, float2 rhs) {
842 return lhs.x*rhs.x + lhs.y*rhs.y;
843 }
dot(float3 lhs,float3 rhs)844 extern float __attribute__((overloadable)) dot(float3 lhs, float3 rhs) {
845 return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z;
846 }
dot(float4 lhs,float4 rhs)847 extern float __attribute__((overloadable)) dot(float4 lhs, float4 rhs) {
848 return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z + lhs.w*rhs.w;
849 }
850
length(float v)851 extern float __attribute__((overloadable)) length(float v) {
852 return v;
853 }
length(float2 v)854 extern float __attribute__((overloadable)) length(float2 v) {
855 return sqrt(v.x*v.x + v.y*v.y);
856 }
length(float3 v)857 extern float __attribute__((overloadable)) length(float3 v) {
858 return sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
859 }
length(float4 v)860 extern float __attribute__((overloadable)) length(float4 v) {
861 return sqrt(v.x*v.x + v.y*v.y + v.z*v.z + v.w*v.w);
862 }
863
distance(float lhs,float rhs)864 extern float __attribute__((overloadable)) distance(float lhs, float rhs) {
865 return length(lhs - rhs);
866 }
distance(float2 lhs,float2 rhs)867 extern float __attribute__((overloadable)) distance(float2 lhs, float2 rhs) {
868 return length(lhs - rhs);
869 }
distance(float3 lhs,float3 rhs)870 extern float __attribute__((overloadable)) distance(float3 lhs, float3 rhs) {
871 return length(lhs - rhs);
872 }
distance(float4 lhs,float4 rhs)873 extern float __attribute__((overloadable)) distance(float4 lhs, float4 rhs) {
874 return length(lhs - rhs);
875 }
876
normalize(float v)877 extern float __attribute__((overloadable)) normalize(float v) {
878 return 1.f;
879 }
normalize(float2 v)880 extern float2 __attribute__((overloadable)) normalize(float2 v) {
881 return v / length(v);
882 }
normalize(float3 v)883 extern float3 __attribute__((overloadable)) normalize(float3 v) {
884 return v / length(v);
885 }
normalize(float4 v)886 extern float4 __attribute__((overloadable)) normalize(float4 v) {
887 return v / length(v);
888 }
889
890 #undef CVT_FUNC
891 #undef CVT_FUNC_2
892 #undef FN_FUNC_FN
893 #undef IN_FUNC_FN
894 #undef FN_FUNC_FN_FN
895 #undef FN_FUNC_FN_F
896 #undef FN_FUNC_FN_IN
897 #undef FN_FUNC_FN_I
898 #undef FN_FUNC_FN_PFN
899 #undef FN_FUNC_FN_PIN
900 #undef FN_FUNC_FN_FN_FN
901 #undef FN_FUNC_FN_FN_PIN
902 #undef XN_FUNC_YN
903 #undef UIN_FUNC_IN
904 #undef IN_FUNC_IN
905 #undef XN_FUNC_XN_XN_BODY
906 #undef IN_FUNC_IN_IN_BODY
907