Slang internal include file defining constructors and operators
[mesa.git] / src / mesa / shader / slang_core.gc
1
2 //
3 // This file defines nearly all constructors and operators for built-in data types, using
4 // extended language syntax. In general, compiler treats constructors and operators as
5 // ordinary functions with some exceptions. For example, the language does not allow
6 // functions to be called in constant expressions - here the exception is made to allow it.
7 //
8 // Each implementation provides its own version of this file. Each implementation can define
9 // the required set of operators and constructors in its own fashion.
10 //
11 // The extended language syntax is only present when compiling this file. It is implicitly
12 // included at the very beginning of the compiled shader, so no built-in functions can be
13 // used.
14 //
15 // To communicate with the implementation, a special extended "__asm" keyword is used, followed
16 // by an instruction name (any valid identifier), a destination variable identifier and a
17 // a list of zero or more source variable identifiers. A variable identifier is a variable name
18 // declared earlier in the code (as a function parameter, local or global variable).
19 // An instruction name designates an instruction that must be exported by the implementation.
20 // Each instruction receives data from destination and source variable identifiers and returns
21 // data in the destination variable identifier.
22 //
23 // It is up to the implementation how to define a particular operator or constructor. If it is
24 // expected to being used rarely, it can be defined in terms of other operators and constructors,
25 // for example:
26 //
27 // ivec2 operator + (const ivec2 x, const ivec2 y) {
28 // return ivec2 (x[0] + y[0], x[1] + y[1]);
29 // }
30 //
31 // If a particular operator or constructor is expected to be used very often or is an atomic
32 // operation (that is, an operation that cannot be expressed in terms of other operations or
33 // would create a dependency cycle) it must be defined using one or more __asm constructs.
34 //
35 // Each implementation must define constructors for all scalar types (bool, float, int).
36 // There are 9 scalar-to-scalar constructors (including identity constructors). However,
37 // since the language introduces special constructors (like matrix constructor with a single
38 // scalar value), implementations must also implement these cases.
39 // The compiler provides the following algorithm when resolving a constructor:
40 // - try to find a constructor with a prototype matching ours,
41 // - if no constructor is found and this is a scalar-to-scalar constructor, raise an error,
42 // - if a constructor is found, execute it and return,
43 // - count the size of the constructor parameter list - if it is less than the size of
44 // our constructor's type, raise an error,
45 // - for each parameter in the list do a recursive constructor matching for appropriate
46 // scalar fields in the constructed variable,
47 //
48 // Each implementation must also define a set of operators that deal with built-in data types.
49 // There are four kinds of operators:
50 // 1) Operators that are implemented only by the compiler: "()" (function call), "," (sequence)
51 // and "?:" (selection).
52 // 2) Operators that are implemented by the compiler by expressing it in terms of other operators:
53 // - "." (field selection) - translated to subscript access,
54 // - "&&" (logical and) - translated to "<left_expr> ? <right_expr> : false",
55 // - "||" (logical or) - translated to "<left_expr> ? true : <right_expr>",
56 // 3) Operators that can be defined by the implementation and if the required prototype is not
57 // found, standard behaviour is used:
58 // - "==", "!=", "=" (equality, assignment) - compare or assign matching fields one-by-one;
59 // note that at least operators for scalar data types must be defined by the implementation
60 // to get it work,
61 // 4) All other operators not mentioned above. If no required prototype is found, an error is
62 // raised. An implementation must follow the language specification to provide all valid
63 // operator prototypes.
64 //
65
66 //
67 // TODO:
68 // - do something with [] operator: leave it in compiler or move it here,
69 // - emulate bools and ints with floats (this should simplify target implementation),
70 // - are vec*mat and mat*vec definitions correct? is the list complete?
71 //
72
73 //
74 // From Shader Spec, ver. 1.051
75 //
76
77 //
78 // 5.4.1 Conversion and Scalar Constructors
79 //
80
81 //
82 // When constructors are used to convert a float to an int, the fractional part of the
83 // floating-point value is dropped.
84 //
85
86 int constructor (const float _f) {
87 int _i;
88 __asm float_to_int _i, _f;
89 return _i;
90 }
91
92 //
93 // When a constructor is used to convert an int or a float to bool, 0 and 0.0 are converted to
94 // false, and nonzero values are converted to true.
95 //
96
97 bool constructor (const int _i) {
98 return _i != 0;
99 }
100
101 bool constructor (const float _f) {
102 return _f != 0.0;
103 }
104
105 //
106 // When a constructor is used to convert a bool to an int or float, false is converted to 0 or
107 // 0.0, and true is converted to 1 or 1.0.
108 //
109
110 int constructor (const bool _b) {
111 return _b ? 1 : 0;
112 }
113
114 float constructor (const bool _b) {
115 return _b ? 1.0 : 0.0;
116 }
117
118 //
119 // Int to float constructor.
120 //
121
122 float constructor (const int _i) {
123 float _f;
124 __asm int_to_float _f, _i;
125 return _f;
126 }
127
128 //
129 // Identity constructors, like float(float) are also legal, but of little use.
130 //
131
132 bool constructor (const bool _b) {
133 return _b;
134 }
135
136 int constructor (const int _i) {
137 return _i;
138 }
139
140 float constructor (const float _f) {
141 return _f;
142 }
143
144 //
145 // Scalar constructors with non-scalar parameters can be used to take the first element from
146 // a non-scalar. For example, the constructor float(vec3) will select the first component of the
147 // vec3 parameter.
148 //
149
150 // [These scalar conversions will be handled internally by the compiler.]
151
152 //
153 // 5.4.2 Vector and Matrix Constructors
154 //
155 // Constructors can be used to create vectors or matrices from a set of scalars, vectors,
156 // or matrices. This includes the ability to shorten vectors or matrices.
157 //
158
159 //
160 // If there is a single scalar parameter to a vector constructor, it is used to initialize all
161 // components of the constructed vector to that scalar\92s value.
162 //
163 // If the basic type (bool, int, or float) of a parameter to a constructor does not match the basic
164 // type of the object being constructed, the scalar construction rules (above) are used to convert
165 // the parameters.
166 //
167
168 vec2 constructor (const float _f) {
169 return vec2 (_f, _f);
170 }
171
172 vec2 constructor (const int _i) {
173 return vec2 (_i, _i);
174 }
175
176 vec2 constructor (const bool _b) {
177 return vec2 (_b, _b);
178 }
179
180 vec3 constructor (const float _f) {
181 return vec3 (_f, _f, _f);
182 }
183
184 vec3 constructor (const int _i) {
185 return vec3 (_i, _i, _i);
186 }
187
188 vec3 constructor (const bool _b) {
189 return vec3 (_b, _b, _b);
190 }
191
192 vec4 constructor (const float _f) {
193 return vec4 (_f, _f, _f, _f);
194 }
195
196 vec4 constructor (const int _i) {
197 return vec4 (_i, _i, _i, _i);
198 }
199
200 vec4 constructor (const bool _b) {
201 return vec4 (_b, _b, _b, _b);
202 }
203
204 ivec2 constructor (const int _i) {
205 return ivec2 (_i, _i);
206 }
207
208 ivec2 constructor (const float _f) {
209 return ivec2 (_f, _f);
210 }
211
212 ivec2 constructor (const bool _b) {
213 return ivec2 (_b, _b);
214 }
215
216 ivec3 constructor (const int _i) {
217 return ivec3 (_i, _i, _i);
218 }
219
220 ivec3 constructor (const float _f) {
221 return ivec3 (_f, _f, _f);
222 }
223
224 ivec3 constructor (const bool _b) {
225 return ivec3 (_b, _b, _b);
226 }
227
228 ivec4 constructor (const int _i) {
229 return ivec4 (_i, _i, _i, _i);
230 }
231
232 ivec4 constructor (const float _f) {
233 return ivec4 (_f, _f, _f, _f);
234 }
235
236 ivec4 constructor (const bool _b) {
237 return ivec4 (_b, _b, _b, _b);
238 }
239
240 bvec2 constructor (const bool _b) {
241 return bvec2 (_b, _b);
242 }
243
244 bvec2 constructor (const float _f) {
245 return bvec2 (_f, _f);
246 }
247
248 bvec2 constructor (const int _i) {
249 return bvec2 (_i, _i);
250 }
251
252 bvec3 constructor (const bool _b) {
253 return bvec3 (_b, _b, _b);
254 }
255
256 bvec3 constructor (const float _f) {
257 return bvec3 (_f, _f, _f);
258 }
259
260 bvec3 constructor (const int _i) {
261 return bvec3 (_i, _i, _i);
262 }
263
264 bvec4 constructor (const bool _b) {
265 return bvec4 (_b, _b, _b, _b);
266 }
267
268 bvec4 constructor (const float _f) {
269 return bvec4 (_f, _f, _f, _f);
270 }
271
272 bvec4 constructor (const int _i) {
273 return bvec4 (_i, _i, _i, _i);
274 }
275
276 //
277 // If there is a single scalar parameter to a matrix constructor, it is used to initialize all the
278 // components on the matrix\92s diagonal, with the remaining components initialized to 0.0.
279 // (...) Matrices will be constructed in column major order.
280 //
281 // If the basic type (bool, int, or float) of a parameter to a constructor does not match the basic
282 // type of the object being constructed, the scalar construction rules (above) are used to convert
283 // the parameters.
284 //
285
286 mat2 constructor (const float _f) {
287 return mat2 (
288 _f, .0,
289 .0, _f
290 );
291 }
292
293 mat2 constructor (const int _i) {
294 return mat2 (
295 _i, .0,
296 .0, _i
297 );
298 }
299
300 mat2 constructor (const bool _b) {
301 return mat2 (
302 _b, .0,
303 .0, _b
304 );
305 }
306
307 mat3 constructor (const float _f) {
308 return mat3 (
309 _f, .0, .0,
310 .0, _f, .0,
311 .0, .0, _f
312 );
313 }
314
315 mat3 constructor (const int _i) {
316 return mat3 (
317 _i, .0, .0,
318 .0, _i, .0,
319 .0, .0, _i
320 );
321 }
322
323 mat3 constructor (const bool _b) {
324 return mat3 (
325 _b, .0, .0,
326 .0, _b, .0,
327 .0, .0, _b
328 );
329 }
330
331 mat4 constructor (const float _f) {
332 return mat4 (
333 _f, .0, .0, .0,
334 .0, _f, .0, .0,
335 .0, .0, _f, .0,
336 .0, .0, .0, _f
337 );
338 }
339
340 mat4 constructor (const int _i) {
341 return mat4 (
342 _i, .0, .0, .0,
343 .0, _i, .0, .0,
344 .0, .0, _i, .0,
345 .0, .0, .0, _i
346 );
347 }
348
349 mat4 constructor (const bool _b) {
350 return mat4 (
351 _b, .0, .0, .0,
352 .0, _b, .0, .0,
353 .0, .0, _b, .0,
354 .0, .0, .0, _b
355 );
356 }
357
358 //
359 // 5.8 Assignments
360 //
361 // Assignments of values to variable names are done with the assignment operator ( = ), like
362 //
363 // lvalue = expression
364 //
365 // The assignment operator stores the value of expression into lvalue. It will compile only if
366 // expression and lvalue have the same type. All desired type-conversions must be specified
367 // explicitly via a constructor. Lvalues must be writable. Variables that are built-in types,
368 // entire structures, structure fields, l-values with the field selector ( . ) applied to select
369 // components or swizzles without repeated fields, and l-values dereferenced with the array
370 // subscript operator ( [ ] ) are all possible l-values. Other binary or unary expressions,
371 // non-dereferenced arrays, function names, swizzles with repeated fields, and constants cannot
372 // be l-values.
373 //
374 // Expressions on the left of an assignment are evaluated before expressions on the right of the
375 // assignment.
376 //
377
378 void operator = (inout float a, const float b) {
379 __asm float_copy a, b;
380 }
381
382 void operator = (inout int a, const int b) {
383 __asm int_copy a, b;
384 }
385
386 void operator = (inout bool a, const bool b) {
387 __asm bool_copy a, b;
388 }
389
390 void operator = (inout vec2 v, const vec2 u) {
391 v.x = u.x, v.y = u.y;
392 }
393
394 void operator = (inout vec3 v, const vec3 u) {
395 v.x = u.x, v.y = u.y, v.z = u.z;
396 }
397
398 void operator = (inout vec4 v, const vec4 u) {
399 v.x = u.x, v.y = u.y, v.z = u.z, v.w = u.w;
400 }
401
402 void operator = (inout ivec2 v, const ivec2 u) {
403 v.x = u.x, v.y = u.y;
404 }
405
406 void operator = (inout ivec3 v, const ivec3 u) {
407 v.x = u.x, v.y = u.y, v.z = u.z;
408 }
409
410 void operator = (inout ivec4 v, const ivec4 u) {
411 v.x = u.x, v.y = u.y, v.z = u.z, v.w = u.w;
412 }
413
414 void operator = (inout bvec2 v, const bvec2 u) {
415 v.x = u.x, v.y = u.y;
416 }
417
418 void operator = (inout bvec3 v, const bvec3 u) {
419 v.x = u.x, v.y = u.y, v.z = u.z;
420 }
421
422 void operator = (inout bvec4 v, const bvec4 u) {
423 v.x = u.x, v.y = u.y, v.z = u.z, v.w = u.w;
424 }
425
426 void operator = (inout mat2 m, const mat2 n) {
427 m[0] = n[0], m[1] = n[1];
428 }
429
430 void operator = (inout mat3 m, const mat3 n) {
431 m[0] = n[0], m[1] = n[1], m[2] = n[2];
432 }
433
434 void operator = (inout mat4 m, const mat4 n) {
435 m[0] = n[0], m[1] = n[1], m[2] = n[2], m[3] = n[3];
436 }
437
438 //
439 // \95 The arithmetic assignments add into (+=), subtract from (-=), multiply into (*=), and divide
440 // into (/=). The variable and expression must be the same floating-point or integer type, ...
441 //
442
443 void operator += (inout float a, const float b) {
444 __asm float_add a, b;
445 }
446
447 void operator -= (inout float a, const float b) {
448 a += -b;
449 }
450
451 void operator *= (inout float a, const float b) {
452 __asm float_multiply a, b;
453 }
454
455 void operator /= (inout float a, const float b) {
456 __asm float_divide a, b;
457 }
458
459 void operator += (inout int x, const int y) {
460 __asm int_add x, y;
461 }
462
463 void operator -= (inout int x, const int y) {
464 x += -y;
465 }
466
467 void operator *= (inout int x, const int y) {
468 __asm int_multiply x, y;
469 }
470
471 void operator /= (inout int x, const int y) {
472 __asm int_divide x, y;
473 }
474
475 void operator += (inout vec2 v, const vec2 u) {
476 v.x += u.x, v.y += u.y;
477 }
478
479 void operator -= (inout vec2 v, const vec2 u) {
480 v.x -= u.x, v.y -= u.y;
481 }
482
483 void operator *= (inout vec2 v, const vec2 u) {
484 v.x *= u.x, v.y *= u.y;
485 }
486
487 void operator /= (inout vec2 v, const vec2 u) {
488 v.x /= u.x, v.y /= u.y;
489 }
490
491 void operator += (inout vec3 v, const vec3 u) {
492 v.x += u.x, v.y += u.y, v.z += u.z;
493 }
494
495 void operator -= (inout vec3 v, const vec3 u) {
496 v.x -= u.x, v.y -= u.y, v.z -= u.z;
497 }
498
499 void operator *= (inout vec3 v, const vec3 u) {
500 v.x *= u.x, v.y *= u.y, v.z *= u.z;
501 }
502
503 void operator /= (inout vec3 v, const vec3 u) {
504 v.x /= u.x, v.y /= u.y, v.z /= u.z;
505 }
506
507 void operator += (inout vec4 v, const vec4 u) {
508 v.x += u.x, v.y += u.y, v.z += u.z, v.w += u.w;
509 }
510
511 void operator -= (inout vec4 v, const vec4 u) {
512 v.x -= u.x, v.y -= u.y, v.z -= u.z, v.w -= u.w;
513 }
514
515 void operator *= (inout vec4 v, const vec4 u) {
516 v.x *= u.x, v.y *= u.y, v.z *= u.z, v.w *= u.w;
517 }
518
519 void operator /= (inout vec4 v, const vec4 u) {
520 v.x /= u.x, v.y /= u.y, v.z /= u.z, v.w /= u.w;
521 }
522
523 void operator += (inout ivec2 v, const ivec2 u) {
524 v.x += u.x, v.y += u.y;
525 }
526
527 void operator -= (inout ivec2 v, const ivec2 u) {
528 v.x -= u.x, v.y -= u.y;
529 }
530
531 void operator *= (inout ivec2 v, const ivec2 u) {
532 v.x *= u.x, v.y *= u.y;
533 }
534
535 void operator /= (inout ivec2 v, const ivec2 u) {
536 v.x /= u.x, v.y /= u.y;
537 }
538
539 void operator += (inout ivec3 v, const ivec3 u) {
540 v.x += u.x, v.y += u.y, v.z += u.z;
541 }
542
543 void operator -= (inout ivec3 v, const ivec3 u) {
544 v.x -= u.x, v.y -= u.y, v.z -= u.z;
545 }
546
547 void operator *= (inout ivec3 v, const ivec3 u) {
548 v.x *= u.x, v.y *= u.y, v.z *= u.z;
549 }
550
551 void operator /= (inout ivec3 v, const ivec3 u) {
552 v.x /= u.x, v.y /= u.y, v.z /= u.z;
553 }
554
555 void operator += (inout ivec4 v, const ivec4 u) {
556 v.x += u.x, v.y += u.y, v.z += u.z, v.w += u.w;
557 }
558
559 void operator -= (inout ivec4 v, const ivec4 u) {
560 v.x -= u.x, v.y -= u.y, v.z -= u.z, v.w -= u.w;
561 }
562
563 void operator *= (inout ivec4 v, const ivec4 u) {
564 v.x *= u.x, v.y *= u.y, v.z *= u.z, v.w *= u.w;
565 }
566
567 void operator /= (inout ivec4 v, const ivec4 u) {
568 v.x /= u.x, v.y /= u.y, v.z /= u.z, v.w /= u.w;
569 }
570
571 void operator += (inout mat2 m, const mat2 n) {
572 m[0] += n[0], m[1] += n[1];
573 }
574
575 void operator -= (inout mat2 v, const mat2 n) {
576 m[0] -= n[0], m[1] -= n[1];
577 }
578
579 void operator *= (inout mat2 m, const mat2 n) {
580 m = m * n;
581 }
582
583 void operator /= (inout mat2 m, const mat2 n) {
584 m[0] /= n[0], m[1] /= n[1];
585 }
586
587 void operator += (inout mat3 m, const mat3 n) {
588 m[0] += n[0], m[1] += n[1], m[2] += n[2];
589 }
590
591 void operator -= (inout mat3 m, const mat3 n) {
592 m[0] -= n[0], m[1] -= n[1], m[2] -= n[2];
593 }
594
595 void operator *= (inout mat3 m, const mat3 n) {
596 m = m * n;
597 }
598
599 void operator /= (inout mat3 m, const mat3 n) {
600 m[0] /= n[0], m[1] /= n[1], m[2] /= n[2];
601 }
602
603 void operator += (inout mat4 m, const mat4 n) {
604 m[0] += n[0], m[1] += n[1], m[2] += n[2], m[3] += n[3];
605 }
606
607 void operator -= (inout mat4 m, const mat4 n) {
608 m[0] -= n[0], m[1] -= n[1], m[2] -= n[2], m[3] -= n[3];
609 }
610
611 void operator *= (inout mat4 m, const mat4 n) {
612 m = m * n;
613 }
614
615 void operator /= (inout mat4 m, const mat4 n) {
616 m[0] /= n[0], m[1] /= n[1], m[2] /= n[2], m[3] /= n[3];
617 }
618
619 //
620 // ... or if the expression is a float, then the variable can be floating-point, a vector, or
621 // a matrix, ...
622 //
623
624 void operator += (inout vec2 v, const float a) {
625 v.x += a, v.y += a;
626 }
627
628 void operator -= (inout vec2 v, const float a) {
629 v.x -= a, v.y -= a;
630 }
631
632 void operator *= (inout vec2 v, const float a) {
633 v.x *= a, v.y *= a;
634 }
635
636 void operator /= (inout vec2 v, const float a) {
637 v.x /= a, v.y /= a;
638 }
639
640 void operator += (inout vec3 v, const float a) {
641 v.x += a, v.y += a, v.z += a;
642 }
643
644 void operator -= (inout vec3 v, const float a) {
645 v.x -= a, v.y -= a, v.z -= a;
646 }
647
648 void operator *= (inout vec3 v, const float a) {
649 v.x *= a, v.y *= a, v.z *= a;
650 }
651
652 void operator /= (inout vec3 v, const float a) {
653 v.x /= a, v.y /= a, v.z /= a;
654 }
655
656 void operator += (inout vec4 v, const float a) {
657 v.x += a, v.y += a, v.z += a, v.w += a;
658 }
659
660 void operator -= (inout vec4 v, const float a) {
661 v.x -= a, v.y -= a, v.z -= a, v.w -= a;
662 }
663
664 void operator *= (inout vec4 v, const float a) {
665 v.x *= a, v.y *= a, v.z *= a, v.w *= a;
666 }
667
668 void operator /= (inout vec4 v, const float a) {
669 v.x /= a, v.y /= a, v.z /= a, v.w /= a;
670 }
671
672 void operator += (inout mat2 m, const float a) {
673 m[0] += a, m[1] += a;
674 }
675
676 void operator -= (inout mat2 m, const float a) {
677 m[0] -= a, m[1] -= a;
678 }
679
680 void operator *= (inout mat2 m, const float a) {
681 m[0] *= a, m[1] *= a;
682 }
683
684 void operator /= (inout mat2 m, const float a) {
685 m[0] /= a, m[1] /= a;
686 }
687
688 void operator += (inout mat3 m, const float a) {
689 m[0] += a, m[1] += a, m[2] += a;
690 }
691
692 void operator -= (inout mat3 m, const float a) {
693 m[0] -= a, m[1] -= a, m[2] -= a;
694 }
695
696 void operator *= (inout mat3 m, const float a) {
697 m[0] *= a, m[1] *= a, m[2] *= a;
698 }
699
700 void operator /= (inout mat3 m, const float a) {
701 m[0] /= a, m[1] /= a, m[2] /= a;
702 }
703
704 void operator += (inout mat4 m, const float a) {
705 m[0] += a, m[1] += a, m[2] += a, m[3] += a;
706 }
707
708 void operator -= (inout mat4 m, const float a) {
709 m[0] -= a, m[1] -= a, m[2] -= a, m[3] -= a;
710 }
711
712 void operator *= (inout mat4 m, const float a) {
713 m[0] *= a, m[1] *= a, m[2] *= a, m[3] *= a;
714 }
715
716 void operator /= (inout mat4 m, const float a) {
717 m[0] /= a, m[1] /= a, m[2] /= a, m[3] /= a;
718 }
719
720 //
721 // ... or if the operation is multiply into (*=), then the variable can be a vector and the
722 // expression can be a matrix of matching size.
723 //
724
725 void operator *= (inout vec2 v, const mat2 m) {
726 v = v * m;
727 }
728
729 void operator *= (inout vec3 v, const mat3 m) {
730 v = v * m;
731 }
732
733 void operator *= (inout vec4 v, const mat4 m) {
734 v = v * m;
735 }
736
737 //
738 // 5.9 Expressions
739 //
740 // Expressions in the shading language include the following:
741 //
742
743 //
744 // \95 The arithmetic binary operators add (+), subtract (-), multiply (*), and divide (/), that
745 // operate on integer and floating-point typed expressions (including vectors and matrices).
746 // The two operands must be the same type, ...
747 //
748
749 float operator + (const float a, const float b) {
750 float c = a;
751 return c += b;
752 }
753
754 float operator - (const float a, const float b) {
755 return a + -b;
756 }
757
758 float operator * (const float a, const float b) {
759 float c = a;
760 return c *= b;
761 }
762
763 float operator / (const float a, const float b) {
764 float c = a;
765 return c /= b;
766 }
767
768 int operator + (const int a, const int b) {
769 int c = a;
770 return c += b;
771 }
772
773 int operator - (const int x, const int y) {
774 return x + -y;
775 }
776
777 int operator * (const int x, const int y) {
778 int z = x;
779 return z *= y;
780 }
781
782 int operator / (const int x, const int y) {
783 int z = x;
784 return z /= y;
785 }
786
787 vec2 operator + (const vec2 v, const vec2 u) {
788 return vec2 (v.x + u.x, v.y + u.y);
789 }
790
791 vec2 operator - (const vec2 v, const vec2 u) {
792 return vec2 (v.x - u.x, v.y - u.y);
793 }
794
795 vec3 operator + (const vec3 v, const vec3 u) {
796 return vec3 (v.x + u.x, v.y + u.y, v.z + u.z);
797 }
798
799 vec3 operator - (const vec3 v, const vec3 u) {
800 return vec3 (v.x - u.x, v.y - u.y, v.z - u.z);
801 }
802
803 vec4 operator + (const vec4 v, const vec4 u) {
804 return vec4 (v.x + u.x, v.y + u.y, v.z + u.z, v.w + u.w);
805 }
806
807 vec4 operator - (const vec4 v, const vec4 u) {
808 return vec4 (v.x - u.x, v.y - u.y, v.z - u.z, v.w - u.w);
809 }
810
811 ivec2 operator + (const ivec2 v, const ivec2 u) {
812 return ivec2 (v.x + u.x, v.y + u.y);
813 }
814
815 ivec2 operator - (const ivec2 v, const ivec2 u) {
816 return ivec2 (v.x - u.x, v.y - u.y);
817 }
818
819 ivec3 operator + (const ivec3 v, const ivec3 u) {
820 return ivec3 (v.x + u.x, v.y + u.y, v.z + u.z);
821 }
822
823 ivec3 operator - (const ivec3 v, const ivec3 u) {
824 return ivec3 (v.x - u.x, v.y - u.y, v.z - u.z);
825 }
826
827 ivec4 operator + (const ivec4 v, const ivec4 u) {
828 return ivec4 (v.x + u.x, v.y + u.y, v.z + u.z, v.w + u.w);
829 }
830
831 ivec4 operator - (const ivec4 v, const ivec4 u) {
832 return ivec4 (v.x - u.x, v.y - u.y, v.z - u.z, v.w - u.w);
833 }
834
835 mat2 operator + (const mat2 m, const mat2 n) {
836 return mat2 (m[0] + n[0], m[1] + n[1]);
837 }
838
839 mat2 operator - (const mat2 m, const mat2 n) {
840 return mat2 (m[0] - n[0], m[1] - n[1]);
841 }
842
843 mat3 operator + (const mat3 m, const mat3 n) {
844 return mat3 (m[0] + n[0], m[1] + n[1], m[2] + n[2]);
845 }
846
847 mat3 operator - (const mat3 m, const mat3 n) {
848 return mat3 (m[0] - n[0], m[1] - n[1], m[2] - n[2]);
849 }
850
851 mat4 operator + (const mat4 m, const mat4 n) {
852 return mat4 (m[0] + n[0], m[1] + n[1], m[2] + n[2], m[3] + n[3]);
853 }
854
855 mat4 operator - (const mat4 m, const mat4 n) {
856 return mat4 (m[0] - n[0], m[1] - n[1], m[2] - n[2], m[3] - n[3]);
857 }
858
859 //
860 // ... or one must be a scalar float and the other a vector or matrix, ...
861 //
862
863 vec2 operator + (const float a, const vec2 u) {
864 return vec2 (a + u.x, a + u.y);
865 }
866
867 vec2 operator + (const vec2 v, const float b) {
868 return vec2 (v.x + b, v.y + b);
869 }
870
871 vec2 operator - (const float a, const vec2 u) {
872 return vec2 (a - u.x, a - u.y);
873 }
874
875 vec2 operator - (const vec2 v, const float b) {
876 return vec2 (v.x - b, v.y - b);
877 }
878
879 vec2 operator * (const float a, const vec2 u) {
880 return vec2 (a * u.x, a * u.y);
881 }
882
883 vec2 operator * (const vec2 v, const float b) {
884 return vec2 (v.x * b, v.y * b);
885 }
886
887 vec2 operator / (const float a, const vec2 u) {
888 return vec2 (a / u.x, a / u.y);
889 }
890
891 vec2 operator / (const vec2 v, const float b) {
892 return vec2 (v.x / b, v.y / b);
893 }
894
895 vec3 operator + (const float a, const vec3 u) {
896 return vec3 (a + u.x, a + u.y, a + u.z);
897 }
898
899 vec3 operator + (const vec3 v, const float b) {
900 return vec3 (v.x + b, v.y + b, v.z + b);
901 }
902
903 vec3 operator - (const float a, const vec3 u) {
904 return vec3 (a - u.x, a - u.y, a - u.z);
905 }
906
907 vec3 operator - (const vec3 v, const float b) {
908 return vec3 (v.x - b, v.y - b, v.z - b);
909 }
910
911 vec3 operator * (const float a, const vec3 u) {
912 return vec3 (a * u.x, a * u.y, a * u.z);
913 }
914
915 vec3 operator * (const vec3 v, const float b) {
916 return vec3 (v.x * b, v.y * b, v.z * b);
917 }
918
919 vec3 operator / (const float a, const vec3 u) {
920 return vec3 (a / u.x, a / u.y, a / u.z);
921 }
922
923 vec3 operator / (const vec3 v, const float b) {
924 return vec3 (v.x / b, v.y / b, v.z / b);
925 }
926
927 vec4 operator + (const float a, const vec4 u) {
928 return vec4 (a + u.x, a + u.y, a + u.z, a + u.w);
929 }
930
931 vec4 operator + (const vec4 v, const float b) {
932 return vec4 (v.x + b, v.y + b, v.z + b, v.w + b);
933 }
934
935 vec4 operator - (const float a, const vec4 u) {
936 return vec4 (a - u.x, a - u.y, a - u.z, a - u.w);
937 }
938
939 vec4 operator - (const vec4 v, const float b) {
940 return vec4 (v.x - b, v.y - b, v.z - b, v.w - b);
941 }
942
943 vec4 operator * (const float a, const vec4 u) {
944 return vec4 (a * u.x, a * u.y, a * u.z, a * u.w);
945 }
946
947 vec4 operator * (const vec4 v, const float b) {
948 return vec4 (v.x * b, v.y * b, v.z * b, v.w * b);
949 }
950
951 vec4 operator / (const float a, const vec4 u) {
952 return vec4 (a / u.x, a / u.y, a / u.z, a / u.w);
953 }
954
955 vec4 operator / (const vec4 v, const float b) {
956 return vec4 (v.x / b, v.y / b, v.z / b, v.w / b);
957 }
958
959 mat2 operator + (const float a, const mat2 n) {
960 return mat2 (a + n[0], a + n[1]);
961 }
962
963 mat2 operator + (const mat2 m, const float b) {
964 return mat2 (m[0] + b, m[1] + b);
965 }
966
967 mat2 operator - (const float a, const mat2 n) {
968 return mat2 (a - n[0], a - n[1]);
969 }
970
971 mat2 operator - (const mat2 m, const float b) {
972 return mat2 (m[0] - b, m[1] - b);
973 }
974
975 mat2 operator * (const float a, const mat2 n) {
976 return mat2 (a * n[0], a * n[1]);
977 }
978
979 mat2 operator * (const mat2 m, const float b) {
980 return mat2 (m[0] * b, m[1] * b);
981 }
982
983 mat2 operator / (const float a, const mat2 n) {
984 return mat2 (a / n[0], a / n[1]);
985 }
986
987 mat2 operator / (const mat2 m, const float b) {
988 return mat2 (m[0] / b, m[1] / b);
989 }
990
991 mat3 operator + (const float a, const mat3 n) {
992 return mat3 (a + n[0], a + n[1], a + n[2]);
993 }
994
995 mat3 operator + (const mat3 m, const float b) {
996 return mat3 (m[0] + b, m[1] + b, m[2] + b);
997 }
998
999 mat3 operator - (const float a, const mat3 n) {
1000 return mat3 (a - n[0], a - n[1], a - n[2]);
1001 }
1002
1003 mat3 operator - (const mat3 m, const float b) {
1004 return mat3 (m[0] - b, m[1] - b, m[2] - b);
1005 }
1006
1007 mat3 operator * (const float a, const mat3 n) {
1008 return mat3 (a * n[0], a * n[1], a * n[2]);
1009 }
1010
1011 mat3 operator * (const mat3 m, const float b) {
1012 return mat3 (m[0] * b, m[1] * b, m[2] * b);
1013 }
1014
1015 mat3 operator / (const float a, const mat3 n) {
1016 return mat3 (a / n[0], a / n[1], a / n[2]);
1017 }
1018
1019 mat3 operator / (const mat3 m, const float b) {
1020 return mat3 (m[0] / b, m[1] / b, m[2] / b);
1021 }
1022
1023 mat4 operator + (const float a, const mat4 n) {
1024 return mat4 (a + n[0], a + n[1], a + n[2], a + n[3]);
1025 }
1026
1027 mat4 operator + (const mat4 m, const float b) {
1028 return mat4 (m[0] + b, m[1] + b, m[2] + b, m[3] + b);
1029 }
1030
1031 mat4 operator - (const float a, const mat4 n) {
1032 return mat4 (a - n[0], a - n[1], a - n[2], a - n[3]);
1033 }
1034
1035 mat4 operator - (const mat4 m, const float b) {
1036 return mat4 (m[0] - b, m[1] - b, m[2] - b, m[3] - b);
1037 }
1038
1039 mat4 operator * (const float a, const mat4 n) {
1040 return mat4 (a * n[0], a * n[1], a * n[2], a * n[3]);
1041 }
1042
1043 mat4 operator * (const mat4 m, const float b) {
1044 return mat4 (m[0] * b, m[1] * b, m[2] * b, m[3] * b);
1045 }
1046
1047 mat4 operator / (const float a, const mat4 n) {
1048 return mat4 (a / n[0], a / n[1], a / n[2], a / n[3]);
1049 }
1050
1051 mat4 operator / (const mat4 m, const float b) {
1052 return mat4 (m[0] / b, m[1] / b, m[2] / b, m[3] / b);
1053 }
1054
1055 //
1056 // ... or for multiply (*) one can be a vector and the other a matrix with the same dimensional
1057 // size of the vector.
1058 //
1059 // [When:]
1060 // \95 the left argument is a floating-point vector and the right is a matrix with a compatible
1061 // dimension in which case the * operator will do a row vector matrix multiplication.
1062 // \95 the left argument is a matrix and the right is a floating-point vector with a compatible
1063 // dimension in which case the * operator will do a column vector matrix multiplication.
1064 //
1065
1066 vec2 operator * (const mat2 m, const vec2 v) {
1067 return vec2 (
1068 v.x * m[0].x + v.y * m[1].x,
1069 v.x * m[0].y + v.y * m[1].y
1070 );
1071 }
1072
1073 vec2 operator * (const vec2 v, const mat2 m) {
1074 return vec2 (
1075 v.x * m[0].x + v.y * m[0].y,
1076 v.x * m[1].x + v.y * m[1].y
1077 );
1078 }
1079
1080 vec3 operator * (const mat3 m, const vec3 v) {
1081 return vec3 (
1082 v.x * m[0].x + v.y * m[1].x + v.z * m[2].x,
1083 v.x * m[0].y + v.y * m[1].y + v.z * m[2].y,
1084 v.x * m[0].z + v.y * m[1].z + v.z * m[2].z
1085 );
1086 }
1087
1088 vec3 operator * (const vec3 v, const mat3 m) {
1089 return vec3 (
1090 v.x * m[0].x + v.y * m[0].y + v.z * m[0].z,
1091 v.x * m[1].x + v.y * m[1].y + v.z * m[1].z,
1092 v.x * m[2].x + v.y * m[2].y + v.z * m[2].z
1093 );
1094 }
1095
1096 vec4 operator * (const mat4 m, const vec4 v) {
1097 return vec4 (
1098 v.x * m[0].x + v.y * m[1].x + v.z * m[2].x + v.w * m[3].x,
1099 v.x * m[0].y + v.y * m[1].y + v.z * m[2].y + v.w * m[3].y,
1100 v.x * m[0].z + v.y * m[1].z + v.z * m[2].z + v.w * m[3].z,
1101 v.x * m[0].w + v.y * m[1].w + v.z * m[2].w + v.w * m[3].w
1102 );
1103 }
1104
1105 vec4 operator * (const vec4 v, const mat4 m) {
1106 return vec4 (
1107 v.x * m[0].x + v.y * m[0].y + v.z * m[0].z + v.w * m[0].w,
1108 v.x * m[1].x + v.y * m[1].y + v.z * m[1].z + v.w * m[1].w,
1109 v.x * m[2].x + v.y * m[2].y + v.z * m[2].z + v.w * m[2].w,
1110 v.x * m[3].x + v.y * m[3].y + v.z * m[3].z + v.w * m[3].w
1111 );
1112 }
1113
1114 //
1115 // Multiply (*) applied to two vectors yields a component-wise multiply.
1116 //
1117
1118 vec2 operator * (const vec2 v, const vec2 u) {
1119 return vec2 (v.x * u.x, v.y * u.y);
1120 }
1121
1122 vec3 operator * (const vec3 v, const vec3 u) {
1123 return vec3 (v.x * u.x, v.y * u.y, v.z * u.z);
1124 }
1125
1126 vec4 operator * (const vec4 v, const vec4 u) {
1127 return vec4 (v.x * u.x, v.y * u.y, v.z * u.z, v.w * u.w);
1128 }
1129
1130 ivec2 operator * (const ivec2 v, const ivec2 u) {
1131 return ivec2 (v.x * u.x, v.y * u.y);
1132 }
1133
1134 ivec3 operator * (const ivec3 v, const ivec3 u) {
1135 return ivec3 (v.x * u.x, v.y * u.y, v.z * u.z);
1136 }
1137
1138 ivec4 operator * (const ivec4 v, const ivec4 u) {
1139 return ivec4 (v.x * u.x, v.y * u.y, v.z * u.z, v.w * u.w);
1140 }
1141
1142 //
1143 // Dividing by zero does not cause an exception but does result in an unspecified value.
1144 //
1145
1146 vec2 operator / (const vec2 v, const vec2 u) {
1147 return vec2 (v.x / u.x, v.y / u.y);
1148 }
1149
1150 vec3 operator / (const vec3 v, const vec3 u) {
1151 return vec3 (v.x / u.x, v.y / u.y, v.z / u.z);
1152 }
1153
1154 vec4 operator / (const vec4 v, const vec4 u) {
1155 return vec4 (v.x / u.x, v.y / u.y, v.z / u.z, v.w / u.w);
1156 }
1157
1158 ivec2 operator / (const ivec2 v, const ivec2 u) {
1159 return ivec2 (v.x / u.x, v.y / u.y);
1160 }
1161
1162 ivec3 operator / (const ivec3 v, const ivec3 u) {
1163 return ivec3 (v.x / u.x, v.y / u.y, v.z / u.z);
1164 }
1165
1166 ivec4 operator / (const ivec4 v, const ivec4 u) {
1167 return ivec4 (v.x / u.x, v.y / u.y, v.z / u.z, v.w / u.w);
1168 }
1169
1170 mat2 operator / (const mat2 m, const mat2 n) {
1171 return mat2 (m[0] / n[0], m[1] / n[1]);
1172 }
1173
1174 mat3 operator / (const mat3 m, const mat3 n) {
1175 return mat3 (m[0] / n[0], m[1] / n[1], m[2] / n[2]);
1176 }
1177
1178 mat4 operator / (const mat4 m, const mat4 n) {
1179 return mat4 (m[0] / n[0], m[1] / n[1], m[2] / n[2], m[3] / n[3]);
1180 }
1181
1182 //
1183 // Multiply (*) applied to two matrices yields a linear algebraic matrix multiply, not
1184 // a component-wise multiply.
1185 //
1186
1187 mat2 operator * (const mat2 m, const mat2 n) {
1188 return mat2 (m * n[0], m * n[1]);
1189 }
1190
1191 mat3 operator * (const mat3 m, const mat3 n) {
1192 return mat3 (m * n[0], m * n[1], m * n[2]);
1193 }
1194
1195 mat4 operator * (const mat4 m, const mat4 n) {
1196 return mat4 (m * n[0], m * n[1], m * n[2], m * n[3]);
1197 }
1198
1199 //
1200 // \95 The arithmetic unary operators negate (-), post- and pre-increment and decrement (-- and
1201 // ++) that operate on integer or floating-point values (including vectors and matrices). These
1202 // result with the same type they operated on. For post- and pre-increment and decrement, the
1203 // expression must be one that could be assigned to (an l-value). Pre-increment and predecrement
1204 // add or subtract 1 or 1.0 to the contents of the expression they operate on, and the
1205 // value of the pre-increment or pre-decrement expression is the resulting value of that
1206 // modification. Post-increment and post-decrement expressions add or subtract 1 or 1.0 to
1207 // the contents of the expression they operate on, but the resulting expression has the
1208 // expression\92s value before the post-increment or post-decrement was executed.
1209 //
1210 // [NOTE: postfix increment and decrement operators take additional dummy int parameter to
1211 // distinguish their prototypes from prefix ones.]
1212 //
1213
1214 float operator - (const float a) {
1215 float c = a;
1216 __asm float_negate c;
1217 return c;
1218 }
1219
1220 int operator - (const int a) {
1221 int c = a;
1222 __asm int_negate c;
1223 return c;
1224 }
1225
1226 vec2 operator - (const vec2 v) {
1227 return vec2 (-v.x, -v.y);
1228 }
1229
1230 vec3 operator - (const vec3 v) {
1231 return vec3 (-v.x, -v.y, -v.z);
1232 }
1233
1234 vec4 operator - (const vec4 v) {
1235 return vec4 (-v.x, -v.y, -v.z, -v.w);
1236 }
1237
1238 ivec2 operator - (const ivec2 v) {
1239 return ivec2 (-v.x, -v.y);
1240 }
1241
1242 ivec3 operator - (const ivec3 v) {
1243 return ivec3 (-v.x, -v.y, -v.z);
1244 }
1245
1246 ivec4 operator - (const ivec4 v) {
1247 return ivec4 (-v.x, -v.y, -v.z, -v.w);
1248 }
1249
1250 mat2 operator - (const mat2 m) {
1251 return mat2 (-m[0], -m[1]);
1252 }
1253
1254 mat3 operator - (const mat3 m) {
1255 return mat3 (-m[0], -m[1], -m[2]);
1256 }
1257
1258 mat4 operator - (const mat4 m) {
1259 return mat4 (-m[0], -m[1], -m[2], -m[3]);
1260 }
1261
1262 void operator -- (inout float a) {
1263 a -= 1.0;
1264 }
1265
1266 void operator -- (inout int a) {
1267 a -= 1;
1268 }
1269
1270 void operator -- (inout vec2 v) {
1271 --v.x, --v.y;
1272 }
1273
1274 void operator -- (inout vec3 v) {
1275 --v.x, --v.y, --v.z;
1276 }
1277
1278 void operator -- (inout vec4 v) {
1279 --v.x, --v.y, --v.z, --v.w;
1280 }
1281
1282 void operator -- (inout ivec2 v) {
1283 --v.x, --v.y;
1284 }
1285
1286 void operator -- (inout ivec3 v) {
1287 --v.x, --v.y, --v.z;
1288 }
1289
1290 void operator -- (inout ivec4 v) {
1291 --v.x, --v.y, --v.z, --v.w;
1292 }
1293
1294 void operator -- (inout mat2 m) {
1295 --m[0], --m[1];
1296 }
1297
1298 void operator -- (inout mat3 m) {
1299 --m[0], --m[1], --m[2];
1300 }
1301
1302 void operator -- (inout mat4 m) {
1303 --m[0], --m[1], --m[2], --m[3];
1304 }
1305
1306 void operator ++ (inout float a) {
1307 a += 1.0;
1308 }
1309
1310 void operator ++ (inout int a) {
1311 a += 1;
1312 }
1313
1314 void operator ++ (inout vec2 v) {
1315 ++v.x, ++v.y;
1316 }
1317
1318 void operator ++ (inout vec3 v) {
1319 ++v.x, ++v.y, ++v.z;
1320 }
1321
1322 void operator ++ (inout vec4 v) {
1323 ++v.x, ++v.y, ++v.z, ++v.w;
1324 }
1325
1326 void operator ++ (inout ivec2 v) {
1327 ++v.x, ++v.y;
1328 }
1329
1330 void operator ++ (inout ivec3 v) {
1331 ++v.x, ++v.y, ++v.z;
1332 }
1333
1334 void operator ++ (inout ivec4 v) {
1335 ++v.x, ++v.y, ++v.z, ++v.w;
1336 }
1337
1338 void operator ++ (inout mat2 m) {
1339 ++m[0], ++m[1];
1340 }
1341
1342 void operator ++ (inout mat3 m) {
1343 ++m[0], ++m[1], ++m[2];
1344 }
1345
1346 void operator ++ (inout mat4 m) {
1347 ++m[0], ++m[1], ++m[2], ++m[3];
1348 }
1349
1350 float operator -- (inout float a, const int) {
1351 const float c = a;
1352 --a;
1353 return c;
1354 }
1355
1356 int operator -- (inout int a, const int) {
1357 const int c = a;
1358 --a;
1359 return c;
1360 }
1361
1362 vec2 operator -- (inout vec2 v, const int) {
1363 return vec2 (v.x--, v.y--);
1364 }
1365
1366 vec3 operator -- (inout vec3 v, const int) {
1367 return vec3 (v.x--, v.y--, v.z--);
1368 }
1369
1370 vec4 operator -- (inout vec4 v, const int) {
1371 return vec4 (v.x--, v.y--, v.z--, v.w--);
1372 }
1373
1374 ivec2 operator -- (inout ivec2 v, const int) {
1375 return ivec2 (v.x--, v.y--);
1376 }
1377
1378 ivec3 operator -- (inout ivec3 v, const int) {
1379 return ivec3 (v.x--, v.y--, v.z--);
1380 }
1381
1382 ivec4 operator -- (inout ivec4 v, const int) {
1383 return ivec4 (v.x--, v.y--, v.z--, v.w--);
1384 }
1385
1386 mat2 operator -- (inout mat2 m, const int) {
1387 return mat2 (m[0]--, m[1]--);
1388 }
1389
1390 mat3 operator -- (inout mat3 m, const int) {
1391 return mat3 (m[0]--, m[1]--, m[2]--);
1392 }
1393
1394 mat4 operator -- (inout mat4 m, const int) {
1395 return mat4 (m[0]--, m[1]--, m[2]--, m[3]--);
1396 }
1397
1398 float operator ++ (inout float a, const int) {
1399 const float c = a;
1400 ++a;
1401 return c;
1402 }
1403
1404 int operator ++ (inout int a, const int) {
1405 const int c = a;
1406 ++a;
1407 return c;
1408 }
1409
1410 vec2 operator ++ (inout vec2 v, const int) {
1411 return vec2 (v.x++, v.y++);
1412 }
1413
1414 vec3 operator ++ (inout vec3 v, const int) {
1415 return vec3 (v.x++, v.y++, v.z++);
1416 }
1417
1418 vec4 operator ++ (inout vec4 v, const int) {
1419 return vec4 (v.x++, v.y++, v.z++, v.w++);
1420 }
1421
1422 ivec2 operator ++ (inout ivec2 v, const int) {
1423 return ivec2 (v.x++, v.y++);
1424 }
1425
1426 ivec3 operator ++ (inout ivec3 v, const int) {
1427 return ivec3 (v.x++, v.y++, v.z++);
1428 }
1429
1430 ivec4 operator ++ (inout ivec4 v, const int) {
1431 return ivec4 (v.x++, v.y++, v.z++, v.w++);
1432 }
1433
1434 mat2 operator ++ (inout mat2 m, const int) {
1435 return mat2 (m[0]++, m[1]++);
1436 }
1437
1438 mat3 operator ++ (inout mat3 m, const int) {
1439 return mat3 (m[0]++, m[1]++, m[2]++);
1440 }
1441
1442 mat4 operator ++ (inout mat4 m, const int) {
1443 return mat4 (m[0]++, m[1]++, m[2]++, m[3]++);
1444 }
1445
1446 //
1447 // \95 The relational operators greater than (>), less than (<), greater than or equal (>=), and less
1448 // than or equal (<=) operate only on scalar integer and scalar floating-point expressions. The
1449 // result is scalar Boolean. The operands\92 types must match. To do component-wise
1450 // comparisons on vectors, use the built-in functions lessThan, lessThanEqual,
1451 // greaterThan, and greaterThanEqual.
1452 //
1453
1454 bool operator < (const float a, const float b) {
1455 bool c;
1456 __asm float_less c, a, b;
1457 return c;
1458 }
1459
1460 bool operator < (const int a, const int b) {
1461 bool c;
1462 __asm int_less c, a, b;
1463 return c;
1464 }
1465
1466 bool operator > (const float a, const float b) {
1467 return b < a;
1468 }
1469
1470 bool operator > (const int a, const int b) {
1471 return b < a;
1472 }
1473
1474 bool operator >= (const float a, const float b) {
1475 return a > b || a == b;
1476 }
1477
1478 bool operator >= (const int a, const int b) {
1479 return a > b || a == b;
1480 }
1481
1482 bool operator <= (const float a, const float b) {
1483 return a < b || a == b;
1484 }
1485
1486 bool operator <= (const int a, const int b) {
1487 return a < b || a == b;
1488 }
1489
1490 //
1491 // \95 The equality operators equal (==), and not equal (!=) operate on all types except arrays.
1492 // They result in a scalar Boolean. For vectors, matrices, and structures, all components of the
1493 // operands must be equal for the operands to be considered equal. To get component-wise
1494 // equality results for vectors, use the built-in functions equal and notEqual.
1495 //
1496
1497 bool operator == (const float a, const float b) {
1498 bool c;
1499 __asm float_equal c, a, b;
1500 return c;
1501 }
1502
1503 bool operator == (const int a, const int b) {
1504 bool c;
1505 __asm int_equal c, a, b;
1506 return c;
1507 }
1508
1509 bool operator == (const bool a, const bool b) {
1510 bool c;
1511 __asm bool_equal c, a, b;
1512 return c;
1513 }
1514
1515 bool operator == (const vec2 v, const vec2 u) {
1516 return v.x == u.x && v.y == u.y;
1517 }
1518
1519 bool operator == (const vec3 v, const vec3 u) {
1520 return v.x == u.x && v.y == u.y && v.z == u.z;
1521 }
1522
1523 bool operator == (const vec4 v, const vec4 u) {
1524 return v.x == u.x && v.y == u.y && v.z == u.z && v.w == u.w;
1525 }
1526
1527 bool operator == (const ivec2 v, const ivec2 u) {
1528 return v.x == u.x && v.y == u.y;
1529 }
1530
1531 bool operator == (const ivec3 v, const ivec3 u) {
1532 return v.x == u.x && v.y == u.y && v.z == u.z;
1533 }
1534
1535 bool operator == (const ivec4 v, const ivec4 u) {
1536 return v.x == u.x && v.y == u.y && v.z == u.z && v.w == u.w;
1537 }
1538
1539 bool operator == (const bvec2 v, const bvec2 u) {
1540 return v.x == u.x && v.y == u.y;
1541 }
1542
1543 bool operator == (const bvec3 v, const bvec3 u) {
1544 return v.x == u.x && v.y == u.y && v.z == u.z;
1545 }
1546
1547 bool operator == (const bvec4 v, const bvec4 u) {
1548 return v.x == u.x && v.y == u.y && v.z == u.z && v.w == u.w;
1549 }
1550
1551 bool operator == (const mat2 m, const mat2 n) {
1552 return m[0] == n[0] && m[1] == n[1];
1553 }
1554
1555 bool operator == (const mat3 m, const mat3 n) {
1556 return m[0] == n[0] && m[1] == n[1] && m[2] == n[2];
1557 }
1558
1559 bool operator == (const mat4 m, const mat4 n) {
1560 return m[0] == n[0] && m[1] == n[1] && m[2] == n[2] && m[3] == n[3];
1561 }
1562
1563 bool operator != (const float a, const float b) {
1564 return !(a == b);
1565 }
1566
1567 bool operator != (const int a, const int b) {
1568 return !(a == b);
1569 }
1570
1571 bool operator != (const bool a, const bool b) {
1572 return !(a == b);
1573 }
1574
1575 bool operator != (const vec2 v, const vec2 u) {
1576 return v.x != u.x || v.y != u.y;
1577 }
1578
1579 bool operator != (const vec3 v, const vec3 u) {
1580 return v.x != u.x || v.y != u.y || v.z != u.z;
1581 }
1582
1583 bool operator != (const vec4 v, const vec4 u) {
1584 return v.x != u.x || v.y != u.y || v.z != u.z || v.w != u.w;
1585 }
1586
1587 bool operator != (const ivec2 v, const ivec2 u) {
1588 return v.x != u.x || v.y != u.y;
1589 }
1590
1591 bool operator != (const ivec3 v, const ivec3 u) {
1592 return v.x != u.x || v.y != u.y || v.z != u.z;
1593 }
1594
1595 bool operator != (const ivec4 v, const ivec4 u) {
1596 return v.x != u.x || v.y != u.y || v.z != u.z || v.w != u.w;
1597 }
1598
1599 bool operator != (const bvec2 v, const bvec2 u) {
1600 return v.x != u.x || v.y != u.y;
1601 }
1602
1603 bool operator != (const bvec3 v, const bvec3 u) {
1604 return v.x != u.x || v.y != u.y || v.z != u.z;
1605 }
1606
1607 bool operator != (const bvec4 v, const bvec4 u) {
1608 return v.x != u.x || v.y != u.y || v.z != u.z || v.w != u.w;
1609 }
1610
1611 bool operator != (const mat2 m, const mat2 n) {
1612 return m[0] != n[0] || m[1] != n[1];
1613 }
1614
1615 bool operator != (const mat3 m, const mat3 n) {
1616 return m[0] != n[0] || m[1] != n[1] || m[2] != n[2];
1617 }
1618
1619 bool operator != (const mat4 m, const mat4 n) {
1620 return m[0] != n[0] || m[1] != n[1] || m[2] != n[2] || m[3] != n[3];
1621 }
1622
1623 //
1624 // \95 The logical binary operators and (&&), or ( | | ), and exclusive or (^^). They operate only
1625 // on two Boolean expressions and result in a Boolean expression. And (&&) will only
1626 // evaluate the right hand operand if the left hand operand evaluated to true. Or ( | | ) will
1627 // only evaluate the right hand operand if the left hand operand evaluated to false. Exclusive or
1628 // (^^) will always evaluate both operands.
1629 //
1630
1631 bool operator ^^ (const bool a, const bool b) {
1632 return a != b;
1633 }
1634
1635 //
1636 // [These operators are handled internally by the compiler:]
1637 //
1638 // bool operator && (bool a, bool b) {
1639 // return a ? b : false;
1640 // }
1641 // bool operator || (bool a, bool b) {
1642 // return a ? true : b;
1643 // }
1644 //
1645
1646 //
1647 // \95 The logical unary operator not (!). It operates only on a Boolean expression and results in a
1648 // Boolean expression. To operate on a vector, use the built-in function not.
1649 //
1650
1651 bool operator ! (const bool a) {
1652 return a == false;
1653 }
1654