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.
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.
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
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.
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,
27 // ivec2 operator + (const ivec2 x, const ivec2 y) {
28 // return ivec2 (x[0] + y[0], x[1] + y[1]);
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.
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,
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
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.
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?
74 // From Shader Spec, ver. 1.051
78 // 5.4.1 Conversion and Scalar Constructors
82 // When constructors are used to convert a float to an int, the fractional part of the
83 // floating-point value is dropped.
86 int constructor (const float _f) {
88 __asm float_to_int _i, _f;
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.
97 bool constructor (const int _i) {
101 bool constructor (const float _f) {
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.
110 int constructor (const bool _b) {
114 float constructor (const bool _b) {
115 return _b ? 1.0 : 0.0;
119 // Int to float constructor.
122 float constructor (const int _i) {
124 __asm int_to_float _f, _i;
129 // Identity constructors, like float(float) are also legal, but of little use.
132 bool constructor (const bool _b) {
136 int constructor (const int _i) {
140 float constructor (const float _f) {
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
150 // [These scalar conversions will be handled internally by the compiler.]
153 // 5.4.2 Vector and Matrix Constructors
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.
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.
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
168 vec2 constructor (const float _f) {
169 return vec2 (_f, _f);
172 vec2 constructor (const int _i) {
173 return vec2 (_i, _i);
176 vec2 constructor (const bool _b) {
177 return vec2 (_b, _b);
180 vec3 constructor (const float _f) {
181 return vec3 (_f, _f, _f);
184 vec3 constructor (const int _i) {
185 return vec3 (_i, _i, _i);
188 vec3 constructor (const bool _b) {
189 return vec3 (_b, _b, _b);
192 vec4 constructor (const float _f) {
193 return vec4 (_f, _f, _f, _f);
196 vec4 constructor (const int _i) {
197 return vec4 (_i, _i, _i, _i);
200 vec4 constructor (const bool _b) {
201 return vec4 (_b, _b, _b, _b);
204 ivec2 constructor (const int _i) {
205 return ivec2 (_i, _i);
208 ivec2 constructor (const float _f) {
209 return ivec2 (_f, _f);
212 ivec2 constructor (const bool _b) {
213 return ivec2 (_b, _b);
216 ivec3 constructor (const int _i) {
217 return ivec3 (_i, _i, _i);
220 ivec3 constructor (const float _f) {
221 return ivec3 (_f, _f, _f);
224 ivec3 constructor (const bool _b) {
225 return ivec3 (_b, _b, _b);
228 ivec4 constructor (const int _i) {
229 return ivec4 (_i, _i, _i, _i);
232 ivec4 constructor (const float _f) {
233 return ivec4 (_f, _f, _f, _f);
236 ivec4 constructor (const bool _b) {
237 return ivec4 (_b, _b, _b, _b);
240 bvec2 constructor (const bool _b) {
241 return bvec2 (_b, _b);
244 bvec2 constructor (const float _f) {
245 return bvec2 (_f, _f);
248 bvec2 constructor (const int _i) {
249 return bvec2 (_i, _i);
252 bvec3 constructor (const bool _b) {
253 return bvec3 (_b, _b, _b);
256 bvec3 constructor (const float _f) {
257 return bvec3 (_f, _f, _f);
260 bvec3 constructor (const int _i) {
261 return bvec3 (_i, _i, _i);
264 bvec4 constructor (const bool _b) {
265 return bvec4 (_b, _b, _b, _b);
268 bvec4 constructor (const float _f) {
269 return bvec4 (_f, _f, _f, _f);
272 bvec4 constructor (const int _i) {
273 return bvec4 (_i, _i, _i, _i);
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.
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
286 mat2 constructor (const float _f) {
293 mat2 constructor (const int _i) {
300 mat2 constructor (const bool _b) {
307 mat3 constructor (const float _f) {
315 mat3 constructor (const int _i) {
323 mat3 constructor (const bool _b) {
331 mat4 constructor (const float _f) {
340 mat4 constructor (const int _i) {
349 mat4 constructor (const bool _b) {
361 // Assignments of values to variable names are done with the assignment operator ( = ), like
363 // lvalue = expression
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
374 // Expressions on the left of an assignment are evaluated before expressions on the right of the
378 void operator = (inout float a, const float b) {
379 __asm float_copy a, b;
382 void operator = (inout int a, const int b) {
386 void operator = (inout bool a, const bool b) {
387 __asm bool_copy a, b;
390 void operator = (inout vec2 v, const vec2 u) {
391 v.x = u.x, v.y = u.y;
394 void operator = (inout vec3 v, const vec3 u) {
395 v.x = u.x, v.y = u.y, v.z = u.z;
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;
402 void operator = (inout ivec2 v, const ivec2 u) {
403 v.x = u.x, v.y = u.y;
406 void operator = (inout ivec3 v, const ivec3 u) {
407 v.x = u.x, v.y = u.y, v.z = u.z;
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;
414 void operator = (inout bvec2 v, const bvec2 u) {
415 v.x = u.x, v.y = u.y;
418 void operator = (inout bvec3 v, const bvec3 u) {
419 v.x = u.x, v.y = u.y, v.z = u.z;
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;
426 void operator = (inout mat2 m, const mat2 n) {
427 m[0] = n[0], m[1] = n[1];
430 void operator = (inout mat3 m, const mat3 n) {
431 m[0] = n[0], m[1] = n[1], m[2] = n[2];
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];
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, ...
443 void operator += (inout float a, const float b) {
444 __asm float_add a, b;
447 void operator -= (inout float a, const float b) {
451 void operator *= (inout float a, const float b) {
452 __asm float_multiply a, b;
455 void operator /= (inout float a, const float b) {
456 __asm float_divide a, b;
459 void operator += (inout int x, const int y) {
463 void operator -= (inout int x, const int y) {
467 void operator *= (inout int x, const int y) {
468 __asm int_multiply x, y;
471 void operator /= (inout int x, const int y) {
472 __asm int_divide x, y;
475 void operator += (inout vec2 v, const vec2 u) {
476 v.x += u.x, v.y += u.y;
479 void operator -= (inout vec2 v, const vec2 u) {
480 v.x -= u.x, v.y -= u.y;
483 void operator *= (inout vec2 v, const vec2 u) {
484 v.x *= u.x, v.y *= u.y;
487 void operator /= (inout vec2 v, const vec2 u) {
488 v.x /= u.x, v.y /= u.y;
491 void operator += (inout vec3 v, const vec3 u) {
492 v.x += u.x, v.y += u.y, v.z += u.z;
495 void operator -= (inout vec3 v, const vec3 u) {
496 v.x -= u.x, v.y -= u.y, v.z -= u.z;
499 void operator *= (inout vec3 v, const vec3 u) {
500 v.x *= u.x, v.y *= u.y, v.z *= u.z;
503 void operator /= (inout vec3 v, const vec3 u) {
504 v.x /= u.x, v.y /= u.y, v.z /= u.z;
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;
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;
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;
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;
523 void operator += (inout ivec2 v, const ivec2 u) {
524 v.x += u.x, v.y += u.y;
527 void operator -= (inout ivec2 v, const ivec2 u) {
528 v.x -= u.x, v.y -= u.y;
531 void operator *= (inout ivec2 v, const ivec2 u) {
532 v.x *= u.x, v.y *= u.y;
535 void operator /= (inout ivec2 v, const ivec2 u) {
536 v.x /= u.x, v.y /= u.y;
539 void operator += (inout ivec3 v, const ivec3 u) {
540 v.x += u.x, v.y += u.y, v.z += u.z;
543 void operator -= (inout ivec3 v, const ivec3 u) {
544 v.x -= u.x, v.y -= u.y, v.z -= u.z;
547 void operator *= (inout ivec3 v, const ivec3 u) {
548 v.x *= u.x, v.y *= u.y, v.z *= u.z;
551 void operator /= (inout ivec3 v, const ivec3 u) {
552 v.x /= u.x, v.y /= u.y, v.z /= u.z;
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;
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;
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;
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;
571 void operator += (inout mat2 m, const mat2 n) {
572 m[0] += n[0], m[1] += n[1];
575 void operator -= (inout mat2 v, const mat2 n) {
576 m[0] -= n[0], m[1] -= n[1];
579 void operator *= (inout mat2 m, const mat2 n) {
583 void operator /= (inout mat2 m, const mat2 n) {
584 m[0] /= n[0], m[1] /= n[1];
587 void operator += (inout mat3 m, const mat3 n) {
588 m[0] += n[0], m[1] += n[1], m[2] += n[2];
591 void operator -= (inout mat3 m, const mat3 n) {
592 m[0] -= n[0], m[1] -= n[1], m[2] -= n[2];
595 void operator *= (inout mat3 m, const mat3 n) {
599 void operator /= (inout mat3 m, const mat3 n) {
600 m[0] /= n[0], m[1] /= n[1], m[2] /= n[2];
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];
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];
611 void operator *= (inout mat4 m, const mat4 n) {
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];
620 // ... or if the expression is a float, then the variable can be floating-point, a vector, or
624 void operator += (inout vec2 v, const float a) {
628 void operator -= (inout vec2 v, const float a) {
632 void operator *= (inout vec2 v, const float a) {
636 void operator /= (inout vec2 v, const float a) {
640 void operator += (inout vec3 v, const float a) {
641 v.x += a, v.y += a, v.z += a;
644 void operator -= (inout vec3 v, const float a) {
645 v.x -= a, v.y -= a, v.z -= a;
648 void operator *= (inout vec3 v, const float a) {
649 v.x *= a, v.y *= a, v.z *= a;
652 void operator /= (inout vec3 v, const float a) {
653 v.x /= a, v.y /= a, v.z /= a;
656 void operator += (inout vec4 v, const float a) {
657 v.x += a, v.y += a, v.z += a, v.w += a;
660 void operator -= (inout vec4 v, const float a) {
661 v.x -= a, v.y -= a, v.z -= a, v.w -= a;
664 void operator *= (inout vec4 v, const float a) {
665 v.x *= a, v.y *= a, v.z *= a, v.w *= a;
668 void operator /= (inout vec4 v, const float a) {
669 v.x /= a, v.y /= a, v.z /= a, v.w /= a;
672 void operator += (inout mat2 m, const float a) {
673 m[0] += a, m[1] += a;
676 void operator -= (inout mat2 m, const float a) {
677 m[0] -= a, m[1] -= a;
680 void operator *= (inout mat2 m, const float a) {
681 m[0] *= a, m[1] *= a;
684 void operator /= (inout mat2 m, const float a) {
685 m[0] /= a, m[1] /= a;
688 void operator += (inout mat3 m, const float a) {
689 m[0] += a, m[1] += a, m[2] += a;
692 void operator -= (inout mat3 m, const float a) {
693 m[0] -= a, m[1] -= a, m[2] -= a;
696 void operator *= (inout mat3 m, const float a) {
697 m[0] *= a, m[1] *= a, m[2] *= a;
700 void operator /= (inout mat3 m, const float a) {
701 m[0] /= a, m[1] /= a, m[2] /= a;
704 void operator += (inout mat4 m, const float a) {
705 m[0] += a, m[1] += a, m[2] += a, m[3] += a;
708 void operator -= (inout mat4 m, const float a) {
709 m[0] -= a, m[1] -= a, m[2] -= a, m[3] -= a;
712 void operator *= (inout mat4 m, const float a) {
713 m[0] *= a, m[1] *= a, m[2] *= a, m[3] *= a;
716 void operator /= (inout mat4 m, const float a) {
717 m[0] /= a, m[1] /= a, m[2] /= a, m[3] /= a;
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.
725 void operator *= (inout vec2 v, const mat2 m) {
729 void operator *= (inout vec3 v, const mat3 m) {
733 void operator *= (inout vec4 v, const mat4 m) {
740 // Expressions in the shading language include the following:
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, ...
749 float operator + (const float a, const float b) {
754 float operator - (const float a, const float b) {
758 float operator * (const float a, const float b) {
763 float operator / (const float a, const float b) {
768 int operator + (const int a, const int b) {
773 int operator - (const int x, const int y) {
777 int operator * (const int x, const int y) {
782 int operator / (const int x, const int y) {
787 vec2 operator + (const vec2 v, const vec2 u) {
788 return vec2 (v.x + u.x, v.y + u.y);
791 vec2 operator - (const vec2 v, const vec2 u) {
792 return vec2 (v.x - u.x, v.y - u.y);
795 vec3 operator + (const vec3 v, const vec3 u) {
796 return vec3 (v.x + u.x, v.y + u.y, v.z + u.z);
799 vec3 operator - (const vec3 v, const vec3 u) {
800 return vec3 (v.x - u.x, v.y - u.y, v.z - u.z);
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);
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);
811 ivec2 operator + (const ivec2 v, const ivec2 u) {
812 return ivec2 (v.x + u.x, v.y + u.y);
815 ivec2 operator - (const ivec2 v, const ivec2 u) {
816 return ivec2 (v.x - u.x, v.y - u.y);
819 ivec3 operator + (const ivec3 v, const ivec3 u) {
820 return ivec3 (v.x + u.x, v.y + u.y, v.z + u.z);
823 ivec3 operator - (const ivec3 v, const ivec3 u) {
824 return ivec3 (v.x - u.x, v.y - u.y, v.z - u.z);
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);
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);
835 mat2 operator + (const mat2 m, const mat2 n) {
836 return mat2 (m[0] + n[0], m[1] + n[1]);
839 mat2 operator - (const mat2 m, const mat2 n) {
840 return mat2 (m[0] - n[0], m[1] - n[1]);
843 mat3 operator + (const mat3 m, const mat3 n) {
844 return mat3 (m[0] + n[0], m[1] + n[1], m[2] + n[2]);
847 mat3 operator - (const mat3 m, const mat3 n) {
848 return mat3 (m[0] - n[0], m[1] - n[1], m[2] - n[2]);
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]);
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]);
860 // ... or one must be a scalar float and the other a vector or matrix, ...
863 vec2 operator + (const float a, const vec2 u) {
864 return vec2 (a + u.x, a + u.y);
867 vec2 operator + (const vec2 v, const float b) {
868 return vec2 (v.x + b, v.y + b);
871 vec2 operator - (const float a, const vec2 u) {
872 return vec2 (a - u.x, a - u.y);
875 vec2 operator - (const vec2 v, const float b) {
876 return vec2 (v.x - b, v.y - b);
879 vec2 operator * (const float a, const vec2 u) {
880 return vec2 (a * u.x, a * u.y);
883 vec2 operator * (const vec2 v, const float b) {
884 return vec2 (v.x * b, v.y * b);
887 vec2 operator / (const float a, const vec2 u) {
888 return vec2 (a / u.x, a / u.y);
891 vec2 operator / (const vec2 v, const float b) {
892 return vec2 (v.x / b, v.y / b);
895 vec3 operator + (const float a, const vec3 u) {
896 return vec3 (a + u.x, a + u.y, a + u.z);
899 vec3 operator + (const vec3 v, const float b) {
900 return vec3 (v.x + b, v.y + b, v.z + b);
903 vec3 operator - (const float a, const vec3 u) {
904 return vec3 (a - u.x, a - u.y, a - u.z);
907 vec3 operator - (const vec3 v, const float b) {
908 return vec3 (v.x - b, v.y - b, v.z - b);
911 vec3 operator * (const float a, const vec3 u) {
912 return vec3 (a * u.x, a * u.y, a * u.z);
915 vec3 operator * (const vec3 v, const float b) {
916 return vec3 (v.x * b, v.y * b, v.z * b);
919 vec3 operator / (const float a, const vec3 u) {
920 return vec3 (a / u.x, a / u.y, a / u.z);
923 vec3 operator / (const vec3 v, const float b) {
924 return vec3 (v.x / b, v.y / b, v.z / b);
927 vec4 operator + (const float a, const vec4 u) {
928 return vec4 (a + u.x, a + u.y, a + u.z, a + u.w);
931 vec4 operator + (const vec4 v, const float b) {
932 return vec4 (v.x + b, v.y + b, v.z + b, v.w + b);
935 vec4 operator - (const float a, const vec4 u) {
936 return vec4 (a - u.x, a - u.y, a - u.z, a - u.w);
939 vec4 operator - (const vec4 v, const float b) {
940 return vec4 (v.x - b, v.y - b, v.z - b, v.w - b);
943 vec4 operator * (const float a, const vec4 u) {
944 return vec4 (a * u.x, a * u.y, a * u.z, a * u.w);
947 vec4 operator * (const vec4 v, const float b) {
948 return vec4 (v.x * b, v.y * b, v.z * b, v.w * b);
951 vec4 operator / (const float a, const vec4 u) {
952 return vec4 (a / u.x, a / u.y, a / u.z, a / u.w);
955 vec4 operator / (const vec4 v, const float b) {
956 return vec4 (v.x / b, v.y / b, v.z / b, v.w / b);
959 mat2 operator + (const float a, const mat2 n) {
960 return mat2 (a + n[0], a + n[1]);
963 mat2 operator + (const mat2 m, const float b) {
964 return mat2 (m[0] + b, m[1] + b);
967 mat2 operator - (const float a, const mat2 n) {
968 return mat2 (a - n[0], a - n[1]);
971 mat2 operator - (const mat2 m, const float b) {
972 return mat2 (m[0] - b, m[1] - b);
975 mat2 operator * (const float a, const mat2 n) {
976 return mat2 (a * n[0], a * n[1]);
979 mat2 operator * (const mat2 m, const float b) {
980 return mat2 (m[0] * b, m[1] * b);
983 mat2 operator / (const float a, const mat2 n) {
984 return mat2 (a / n[0], a / n[1]);
987 mat2 operator / (const mat2 m, const float b) {
988 return mat2 (m[0] / b, m[1] / b);
991 mat3 operator + (const float a, const mat3 n) {
992 return mat3 (a + n[0], a + n[1], a + n[2]);
995 mat3 operator + (const mat3 m, const float b) {
996 return mat3 (m[0] + b, m[1] + b, m[2] + b);
999 mat3 operator - (const float a, const mat3 n) {
1000 return mat3 (a - n[0], a - n[1], a - n[2]);
1003 mat3 operator - (const mat3 m, const float b) {
1004 return mat3 (m[0] - b, m[1] - b, m[2] - b);
1007 mat3 operator * (const float a, const mat3 n) {
1008 return mat3 (a * n[0], a * n[1], a * n[2]);
1011 mat3 operator * (const mat3 m, const float b) {
1012 return mat3 (m[0] * b, m[1] * b, m[2] * b);
1015 mat3 operator / (const float a, const mat3 n) {
1016 return mat3 (a / n[0], a / n[1], a / n[2]);
1019 mat3 operator / (const mat3 m, const float b) {
1020 return mat3 (m[0] / b, m[1] / b, m[2] / b);
1023 mat4 operator + (const float a, const mat4 n) {
1024 return mat4 (a + n[0], a + n[1], a + n[2], a + n[3]);
1027 mat4 operator + (const mat4 m, const float b) {
1028 return mat4 (m[0] + b, m[1] + b, m[2] + b, m[3] + b);
1031 mat4 operator - (const float a, const mat4 n) {
1032 return mat4 (a - n[0], a - n[1], a - n[2], a - n[3]);
1035 mat4 operator - (const mat4 m, const float b) {
1036 return mat4 (m[0] - b, m[1] - b, m[2] - b, m[3] - b);
1039 mat4 operator * (const float a, const mat4 n) {
1040 return mat4 (a * n[0], a * n[1], a * n[2], a * n[3]);
1043 mat4 operator * (const mat4 m, const float b) {
1044 return mat4 (m[0] * b, m[1] * b, m[2] * b, m[3] * b);
1047 mat4 operator / (const float a, const mat4 n) {
1048 return mat4 (a / n[0], a / n[1], a / n[2], a / n[3]);
1051 mat4 operator / (const mat4 m, const float b) {
1052 return mat4 (m[0] / b, m[1] / b, m[2] / b, m[3] / b);
1056 // ... or for multiply (*) one can be a vector and the other a matrix with the same dimensional
1057 // size of the vector.
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.
1066 vec2 operator * (const mat2 m, const vec2 v) {
1068 v.x * m[0].x + v.y * m[1].x,
1069 v.x * m[0].y + v.y * m[1].y
1073 vec2 operator * (const vec2 v, const mat2 m) {
1075 v.x * m[0].x + v.y * m[0].y,
1076 v.x * m[1].x + v.y * m[1].y
1080 vec3 operator * (const mat3 m, const vec3 v) {
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
1088 vec3 operator * (const vec3 v, const mat3 m) {
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
1096 vec4 operator * (const mat4 m, const vec4 v) {
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
1105 vec4 operator * (const vec4 v, const mat4 m) {
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
1115 // Multiply (*) applied to two vectors yields a component-wise multiply.
1118 vec2 operator * (const vec2 v, const vec2 u) {
1119 return vec2 (v.x * u.x, v.y * u.y);
1122 vec3 operator * (const vec3 v, const vec3 u) {
1123 return vec3 (v.x * u.x, v.y * u.y, v.z * u.z);
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);
1130 ivec2 operator * (const ivec2 v, const ivec2 u) {
1131 return ivec2 (v.x * u.x, v.y * u.y);
1134 ivec3 operator * (const ivec3 v, const ivec3 u) {
1135 return ivec3 (v.x * u.x, v.y * u.y, v.z * u.z);
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);
1143 // Dividing by zero does not cause an exception but does result in an unspecified value.
1146 vec2 operator / (const vec2 v, const vec2 u) {
1147 return vec2 (v.x / u.x, v.y / u.y);
1150 vec3 operator / (const vec3 v, const vec3 u) {
1151 return vec3 (v.x / u.x, v.y / u.y, v.z / u.z);
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);
1158 ivec2 operator / (const ivec2 v, const ivec2 u) {
1159 return ivec2 (v.x / u.x, v.y / u.y);
1162 ivec3 operator / (const ivec3 v, const ivec3 u) {
1163 return ivec3 (v.x / u.x, v.y / u.y, v.z / u.z);
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);
1170 mat2 operator / (const mat2 m, const mat2 n) {
1171 return mat2 (m[0] / n[0], m[1] / n[1]);
1174 mat3 operator / (const mat3 m, const mat3 n) {
1175 return mat3 (m[0] / n[0], m[1] / n[1], m[2] / n[2]);
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]);
1183 // Multiply (*) applied to two matrices yields a linear algebraic matrix multiply, not
1184 // a component-wise multiply.
1187 mat2 operator * (const mat2 m, const mat2 n) {
1188 return mat2 (m * n[0], m * n[1]);
1191 mat3 operator * (const mat3 m, const mat3 n) {
1192 return mat3 (m * n[0], m * n[1], m * n[2]);
1195 mat4 operator * (const mat4 m, const mat4 n) {
1196 return mat4 (m * n[0], m * n[1], m * n[2], m * n[3]);
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.
1210 // [NOTE: postfix increment and decrement operators take additional dummy int parameter to
1211 // distinguish their prototypes from prefix ones.]
1214 float operator - (const float a) {
1216 __asm float_negate c;
1220 int operator - (const int a) {
1226 vec2 operator - (const vec2 v) {
1227 return vec2 (-v.x, -v.y);
1230 vec3 operator - (const vec3 v) {
1231 return vec3 (-v.x, -v.y, -v.z);
1234 vec4 operator - (const vec4 v) {
1235 return vec4 (-v.x, -v.y, -v.z, -v.w);
1238 ivec2 operator - (const ivec2 v) {
1239 return ivec2 (-v.x, -v.y);
1242 ivec3 operator - (const ivec3 v) {
1243 return ivec3 (-v.x, -v.y, -v.z);
1246 ivec4 operator - (const ivec4 v) {
1247 return ivec4 (-v.x, -v.y, -v.z, -v.w);
1250 mat2 operator - (const mat2 m) {
1251 return mat2 (-m[0], -m[1]);
1254 mat3 operator - (const mat3 m) {
1255 return mat3 (-m[0], -m[1], -m[2]);
1258 mat4 operator - (const mat4 m) {
1259 return mat4 (-m[0], -m[1], -m[2], -m[3]);
1262 void operator -- (inout float a) {
1266 void operator -- (inout int a) {
1270 void operator -- (inout vec2 v) {
1274 void operator -- (inout vec3 v) {
1275 --v.x, --v.y, --v.z;
1278 void operator -- (inout vec4 v) {
1279 --v.x, --v.y, --v.z, --v.w;
1282 void operator -- (inout ivec2 v) {
1286 void operator -- (inout ivec3 v) {
1287 --v.x, --v.y, --v.z;
1290 void operator -- (inout ivec4 v) {
1291 --v.x, --v.y, --v.z, --v.w;
1294 void operator -- (inout mat2 m) {
1298 void operator -- (inout mat3 m) {
1299 --m[0], --m[1], --m[2];
1302 void operator -- (inout mat4 m) {
1303 --m[0], --m[1], --m[2], --m[3];
1306 void operator ++ (inout float a) {
1310 void operator ++ (inout int a) {
1314 void operator ++ (inout vec2 v) {
1318 void operator ++ (inout vec3 v) {
1319 ++v.x, ++v.y, ++v.z;
1322 void operator ++ (inout vec4 v) {
1323 ++v.x, ++v.y, ++v.z, ++v.w;
1326 void operator ++ (inout ivec2 v) {
1330 void operator ++ (inout ivec3 v) {
1331 ++v.x, ++v.y, ++v.z;
1334 void operator ++ (inout ivec4 v) {
1335 ++v.x, ++v.y, ++v.z, ++v.w;
1338 void operator ++ (inout mat2 m) {
1342 void operator ++ (inout mat3 m) {
1343 ++m[0], ++m[1], ++m[2];
1346 void operator ++ (inout mat4 m) {
1347 ++m[0], ++m[1], ++m[2], ++m[3];
1350 float operator -- (inout float a, const int) {
1356 int operator -- (inout int a, const int) {
1362 vec2 operator -- (inout vec2 v, const int) {
1363 return vec2 (v.x--, v.y--);
1366 vec3 operator -- (inout vec3 v, const int) {
1367 return vec3 (v.x--, v.y--, v.z--);
1370 vec4 operator -- (inout vec4 v, const int) {
1371 return vec4 (v.x--, v.y--, v.z--, v.w--);
1374 ivec2 operator -- (inout ivec2 v, const int) {
1375 return ivec2 (v.x--, v.y--);
1378 ivec3 operator -- (inout ivec3 v, const int) {
1379 return ivec3 (v.x--, v.y--, v.z--);
1382 ivec4 operator -- (inout ivec4 v, const int) {
1383 return ivec4 (v.x--, v.y--, v.z--, v.w--);
1386 mat2 operator -- (inout mat2 m, const int) {
1387 return mat2 (m[0]--, m[1]--);
1390 mat3 operator -- (inout mat3 m, const int) {
1391 return mat3 (m[0]--, m[1]--, m[2]--);
1394 mat4 operator -- (inout mat4 m, const int) {
1395 return mat4 (m[0]--, m[1]--, m[2]--, m[3]--);
1398 float operator ++ (inout float a, const int) {
1404 int operator ++ (inout int a, const int) {
1410 vec2 operator ++ (inout vec2 v, const int) {
1411 return vec2 (v.x++, v.y++);
1414 vec3 operator ++ (inout vec3 v, const int) {
1415 return vec3 (v.x++, v.y++, v.z++);
1418 vec4 operator ++ (inout vec4 v, const int) {
1419 return vec4 (v.x++, v.y++, v.z++, v.w++);
1422 ivec2 operator ++ (inout ivec2 v, const int) {
1423 return ivec2 (v.x++, v.y++);
1426 ivec3 operator ++ (inout ivec3 v, const int) {
1427 return ivec3 (v.x++, v.y++, v.z++);
1430 ivec4 operator ++ (inout ivec4 v, const int) {
1431 return ivec4 (v.x++, v.y++, v.z++, v.w++);
1434 mat2 operator ++ (inout mat2 m, const int) {
1435 return mat2 (m[0]++, m[1]++);
1438 mat3 operator ++ (inout mat3 m, const int) {
1439 return mat3 (m[0]++, m[1]++, m[2]++);
1442 mat4 operator ++ (inout mat4 m, const int) {
1443 return mat4 (m[0]++, m[1]++, m[2]++, m[3]++);
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.
1454 bool operator < (const float a, const float b) {
1456 __asm float_less c, a, b;
1460 bool operator < (const int a, const int b) {
1462 __asm int_less c, a, b;
1466 bool operator > (const float a, const float b) {
1470 bool operator > (const int a, const int b) {
1474 bool operator >= (const float a, const float b) {
1475 return a > b || a == b;
1478 bool operator >= (const int a, const int b) {
1479 return a > b || a == b;
1482 bool operator <= (const float a, const float b) {
1483 return a < b || a == b;
1486 bool operator <= (const int a, const int b) {
1487 return a < b || a == b;
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.
1497 bool operator == (const float a, const float b) {
1499 __asm float_equal c, a, b;
1503 bool operator == (const int a, const int b) {
1505 __asm int_equal c, a, b;
1509 bool operator == (const bool a, const bool b) {
1511 __asm bool_equal c, a, b;
1515 bool operator == (const vec2 v, const vec2 u) {
1516 return v.x == u.x && v.y == u.y;
1519 bool operator == (const vec3 v, const vec3 u) {
1520 return v.x == u.x && v.y == u.y && v.z == u.z;
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;
1527 bool operator == (const ivec2 v, const ivec2 u) {
1528 return v.x == u.x && v.y == u.y;
1531 bool operator == (const ivec3 v, const ivec3 u) {
1532 return v.x == u.x && v.y == u.y && v.z == u.z;
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;
1539 bool operator == (const bvec2 v, const bvec2 u) {
1540 return v.x == u.x && v.y == u.y;
1543 bool operator == (const bvec3 v, const bvec3 u) {
1544 return v.x == u.x && v.y == u.y && v.z == u.z;
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;
1551 bool operator == (const mat2 m, const mat2 n) {
1552 return m[0] == n[0] && m[1] == n[1];
1555 bool operator == (const mat3 m, const mat3 n) {
1556 return m[0] == n[0] && m[1] == n[1] && m[2] == n[2];
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];
1563 bool operator != (const float a, const float b) {
1567 bool operator != (const int a, const int b) {
1571 bool operator != (const bool a, const bool b) {
1575 bool operator != (const vec2 v, const vec2 u) {
1576 return v.x != u.x || v.y != u.y;
1579 bool operator != (const vec3 v, const vec3 u) {
1580 return v.x != u.x || v.y != u.y || v.z != u.z;
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;
1587 bool operator != (const ivec2 v, const ivec2 u) {
1588 return v.x != u.x || v.y != u.y;
1591 bool operator != (const ivec3 v, const ivec3 u) {
1592 return v.x != u.x || v.y != u.y || v.z != u.z;
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;
1599 bool operator != (const bvec2 v, const bvec2 u) {
1600 return v.x != u.x || v.y != u.y;
1603 bool operator != (const bvec3 v, const bvec3 u) {
1604 return v.x != u.x || v.y != u.y || v.z != u.z;
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;
1611 bool operator != (const mat2 m, const mat2 n) {
1612 return m[0] != n[0] || m[1] != n[1];
1615 bool operator != (const mat3 m, const mat3 n) {
1616 return m[0] != n[0] || m[1] != n[1] || m[2] != n[2];
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];
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.
1631 bool operator ^^ (const bool a, const bool b) {
1636 // [These operators are handled internally by the compiler:]
1638 // bool operator && (bool a, bool b) {
1639 // return a ? b : false;
1641 // bool operator || (bool a, bool b) {
1642 // return a ? true : b;
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.
1651 bool operator ! (const bool a) {