[WHLSL] Allow uniform buffers to be used in the interpreter
[WebKit-https.git] / Tools / WebGPUShadingLanguageRI / StandardLibrary.js
1 /*
2  * Copyright (C) 2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25 "use strict";
26
27 let standardLibrary = (function() {
28     let result = "";
29     function print(s)
30     {
31         if (s)
32             result += s;
33         result += "\n";
34     }
35     (function() {
36         print(`// This was autogenerated from Generate_Standard_Library.swift! Do not edit!!`);
37         print();
38
39         for (let type of [`void`, `bool`, `uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`, `atomic_int`, `atomic_uint`]) {
40             print(`native typedef ${type};`);
41         }
42         for (let type of [`bool`, `uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
43             for (let size of [2, 3, 4]) {
44                 print(`native typedef vector<${type}, ${size}>;`);
45                 print(`typedef ${type}${size} = vector<${type}, ${size}>;`);
46             }
47         }
48         print();
49
50         for (let type of [`half`, `float`]) {
51             for (let i of [2, 3, 4]) {
52                 for (let j of [2, 3, 4]) {
53                     print(`native typedef matrix<${type}, ${i}, ${j}>;`);
54                     print(`typedef ${type}${i}x${j} = matrix<${type}, ${i}, ${j}>;`);
55                 }
56             }
57         }
58         print(`native typedef sampler;`);
59         for (let type of [`Texture1D`, `RWTexture1D`, `Texture1DArray`, `RWTexture1DArray`, `Texture2D`, `RWTexture2D`, `Texture2DArray`, `RWTexture2DArray`, `Texture3D`, `RWTexture3D`, `TextureCube`]) {
60             for (let typeArgumentBase of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
61                 for (let size of [``, `2`, `3`, `4`]) {
62                     print(`native typedef ${type}<${typeArgumentBase}${size}>;`);
63                 }
64             }
65         }
66         for (let type of [`TextureDepth2D`, `RWTextureDepth2D`, `TextureDepth2DArray`, `RWTextureDepth2DArray`, `TextureDepthCube`]) {
67             for (let typeArgument of [`float`, `half`]) {
68                 print(`native typedef ${type}<${typeArgument}>;`);
69             }
70         }
71         print();
72
73         for (let type1 of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
74             for (let type2 of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
75                 if (type1 != type2) {
76                     print(`native operator ${type1}(${type2});`);
77                 }
78             }
79         }
80         print();
81
82         for (let type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
83             print(`operator bool(${type} x) {`);
84             print(`    return x != 0;`);
85             print(`}`);
86         }
87         print();
88
89         print(`native operator int(atomic_int);`);
90         print(`native operator uint(atomic_uint);`);
91         print();
92
93         print(`native bool operator==(bool, bool);`);
94
95         print(`bool operator&(bool a, bool b) {`);
96         print(`    return a && b;`);
97         print(`}`);
98
99         print(`bool operator|(bool a, bool b) {`);
100         print(`    return a || b;`);
101         print(`}`);
102
103         print(`bool operator^(bool a, bool b) {`);
104         print(`    if (a)`);
105         print(`        return !b;`);
106         print(`    return b;`);
107         print(`}`);
108
109         print(`bool operator~(bool value) {`);
110         print(`    return !value;`);
111         print(`}`);
112
113         for (let type of [`int`, `uint`, `float`]) {
114             print(`native ${type} operator+(${type}, ${type});`);
115             print(`native ${type} operator-(${type}, ${type});`);
116             print(`native ${type} operator*(${type}, ${type});`);
117             print(`native ${type} operator/(${type}, ${type});`);
118             print(`native bool operator==(${type}, ${type});`);
119             print(`native bool operator<(${type}, ${type});`);
120             print(`native bool operator<=(${type}, ${type});`);
121             print(`native bool operator>(${type}, ${type});`);
122             print(`native bool operator>=(${type}, ${type});`);
123         }
124
125         for (let type of [`int`, `uint`]) {
126             print(`native ${type} operator&(${type}, ${type});`);
127             print(`native ${type} operator|(${type}, ${type});`);
128             print(`native ${type} operator^(${type}, ${type});`);
129             print(`native ${type} operator~(${type});`);
130             print(`native ${type} operator<<(${type}, uint);`);
131             print(`native ${type} operator>>(${type}, uint);`);
132         }
133
134         for (let type of [`uchar`, `ushort`]) {
135             print(`${type} operator+(${type} a, ${type} b) {`);
136             print(`    return ${type}(uint(a) + uint(b));`);
137             print(`}`);
138             print(`${type} operator-(${type} a, ${type} b) {`);
139             print(`    return ${type}(uint(a) - uint(b));`);
140             print(`}`);
141             print(`${type} operator*(${type} a, ${type} b) {`);
142             print(`    return ${type}(uint(a) * uint(b));`);
143             print(`}`);
144             print(`${type} operator/(${type} a, ${type} b) {`);
145             print(`    return ${type}(uint(a) / uint(b));`);
146             print(`}`);
147             print(`${type} operator&(${type} a, ${type} b) {`);
148             print(`    return ${type}(uint(a) & uint(b));`);
149             print(`}`);
150             print(`${type} operator|(${type} a, ${type} b) {`);
151             print(`    return ${type}(uint(a) | uint(b));`);
152             print(`}`);
153             print(`${type} operator^(${type} a, ${type} b) {`);
154             print(`    return ${type}(uint(a) ^ uint(b));`);
155             print(`}`);
156             print(`${type} operator~(${type} a) {`);
157             print(`    return ${type}(~uint(a));`);
158             print(`}`);
159             print(`bool operator==(${type} a, ${type} b) {`);
160             print(`    return uint(a) == uint(b);`);
161             print(`}`);
162             print(`bool operator<(${type} a, ${type} b) {`);
163             print(`    return uint(a) < uint(b);`);
164             print(`}`);
165             print(`bool operator<=(${type} a, ${type} b) {`);
166             print(`    return uint(a) <= uint(b);`);
167             print(`}`);
168             print(`bool operator>(${type} a, ${type} b) {`);
169             print(`    return uint(a) > uint(b);`);
170             print(`}`);
171             print(`bool operator>=(${type} a, ${type} b) {`);
172             print(`    return uint(a) >= uint(b);`);
173             print(`}`);
174         }
175         print(`uchar operator<<(uchar a, uint b) {`);
176         print(`    return uchar(uint(a) << (b & 255));`);
177         print(`}`);
178         print(`ushort operator<<(ushort a, uint b) {`);
179         print(`    return ushort(uint(a) << (b & 65535));`);
180         print(`}`);
181         print(`uchar operator>>(uchar a, uint b) {`);
182         print(`    return uchar(uint(a) >> (b & 255));`);
183         print(`}`);
184         print(`ushort operator>>(ushort a, uint b) {`);
185         print(`    return ushort(uint(a) >> (b & 65535));`);
186         print(`}`);
187
188         for (let type of [`char`, `short`]) {
189             print(`${type} operator+(${type} a, ${type} b) {`);
190             print(`    return ${type}(int(a) + int(b));`);
191             print(`}`);
192             print(`${type} operator-(${type} a, ${type} b) {`);
193             print(`    return ${type}(int(a) - int(b));`);
194             print(`}`);
195             print(`${type} operator*(${type} a, ${type} b) {`);
196             print(`    return ${type}(int(a) * int(b));`);
197             print(`}`);
198             print(`${type} operator/(${type} a, ${type} b) {`);
199             print(`    return ${type}(int(a) / int(b));`);
200             print(`}`);
201             print(`${type} operator&(${type} a, ${type} b) {`);
202             print(`    return ${type}(int(a) & int(b));`);
203             print(`}`);
204             print(`${type} operator|(${type} a, ${type} b) {`);
205             print(`    return ${type}(int(a) | int(b));`);
206             print(`}`);
207             print(`${type} operator^(${type} a, ${type} b) {`);
208             print(`    return ${type}(int(a) ^ int(b));`);
209             print(`}`);
210             print(`${type} operator~(${type} a) {`);
211             print(`    return ${type}(~int(a));`);
212             print(`}`);
213             print(`bool operator==(${type} a, ${type} b) {`);
214             print(`    return int(a) == int(b);`);
215             print(`}`);
216             print(`bool operator>(${type} a, ${type} b) {`);
217             print(`    return int(a) > int(b);`);
218             print(`}`);
219             print(`bool operator>=(${type} a, ${type} b) {`);
220             print(`    return int(a) >= int(b);`);
221             print(`}`);
222             print(`bool operator<(${type} a, ${type} b) {`);
223             print(`    return int(a) < int(b);`);
224             print(`}`);
225             print(`bool operator<=(${type} a, ${type} b) {`);
226             print(`    return int(a) <= int(b);`);
227             print(`}`);
228         }
229         print(`char operator<<(char a, uint b) {`);
230         print(`    return char(int(a) << (b & 255));`);
231         print(`}`);
232         print(`short operator<<(short a, uint b) {`);
233         print(`    return short(int(a) << (b & 65535));`);
234         print(`}`);
235         print(`char operator>>(char a, uint b) {`);
236         print(`    return char(int(a) >> (b & 255));`);
237         print(`}`);
238         print(`short operator>>(short a, uint b) {`);
239         print(`    return short(int(a) >> (b & 65535));`);
240         print(`}`);
241
242         for (let type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
243             print(`${type} operator++(${type} value) {`);
244             print(`    return value + 1;`);
245             print(`}`);
246             print(`${type} operator--(${type} value) {`);
247             print(`    return value - 1;`);
248             print(`}`);
249         }
250
251         print(`half operator+(half a, half b) {`);
252         print(`    return half(float(a) + float(b));`);
253         print(`}`);
254         print(`half operator-(half a, half b) {`);
255         print(`    return half(float(a) - float(b));`);
256         print(`}`);
257         print(`half operator*(half a, half b) {`);
258         print(`    return half(float(a) * float(b));`);
259         print(`}`);
260         print(`half operator/(half a, half b) {`);
261         print(`    return half(float(a) / float(b));`);
262         print(`}`);
263         print(`bool operator==(half a, half b) {`);
264         print(`    return float(a) == float(b);`);
265         print(`}`);
266         print(`bool operator<(half a, half b) {`);
267         print(`    return float(a) < float(b);`);
268         print(`}`);
269         print(`bool operator<=(half a, half b) {`);
270         print(`    return float(a) <= float(b);`);
271         print(`}`);
272         print(`bool operator>(half a, half b) {`);
273         print(`    return float(a) < float(b);`);
274         print(`}`);
275         print(`bool operator>=(half a, half b) {`);
276         print(`    return float(a) <= float(b);`);
277         print(`}`);
278         print(`char operator-(char x) {`);
279         print(`    return char(-int(x));`);
280         print(`}`);
281         print(`short operator-(short x) {`);
282         print(`    return short(-int(x));`);
283         print(`}`);
284         print(`half operator-(half x) {`);
285         print(`    return half(-float(x));`);
286         print(`}`);
287         print(`native int operator-(int);`);
288         print(`native float operator-(float);`);
289         print();
290
291         for (let type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
292             for (let size of [2, 3, 4]) {
293                 print(`${type}${size} operator+(${type}${size} a, ${type}${size} b) {`);
294                 print(`    ${type}${size} result;`);
295                 for (let m = 0; m < size; ++m) {
296                     print(`    result[${m}] = a[${m}] + b[${m}];`);
297                 }
298                 print(`    return result;`);
299                 print(`}`);
300                 print(`${type}${size} operator-(${type}${size} a, ${type}${size} b) {`);
301                 print(`    ${type}${size} result;`);
302                 for (let m = 0; m < size; ++m) {
303                     print(`    result[${m}] = a[${m}] - b[${m}];`);
304                 }
305                 print(`    return result;`);
306                 print(`}`);
307                 print(`${type}${size} operator*(${type}${size} a, ${type}${size} b) {`);
308                 print(`    ${type}${size} result;`);
309                 for (let m = 0; m < size; ++m) {
310                     print(`    result[${m}] = a[${m}] * b[${m}];`);
311                 }
312                 print(`    return result;`);
313                 print(`}`);
314                 print(`${type}${size} operator*(${type}${size} a, ${type} b) {`);
315                 print(`    ${type}${size} result;`);
316                 for (let m = 0; m < size; ++m) {
317                     print(`    result[${m}] = a[${m}] * b;`);
318                 }
319                 print(`    return result;`);
320                 print(`}`);
321                 print(`${type}${size} operator*(${type} a, ${type}${size} b) {`);
322                 print(`    ${type}${size} result;`);
323                 for (let m = 0; m < size; ++m) {
324                     print(`    result[${m}] = a * b[${m}];`);
325                 }
326                 print(`    return result;`);
327                 print(`}`);
328                 print(`${type}${size} operator/(${type}${size} a, ${type}${size} b) {`);
329                 print(`    ${type}${size} result;`);
330                 for (let m = 0; m < size; ++m) {
331                     print(`    result[${m}] = a[${m}] / b[${m}];`);
332                 }
333                 print(`    return result;`);
334                 print(`}`);
335                 print(`${type}${size} operator/(${type}${size} a, ${type} b) {`);
336                 print(`    ${type}${size} result;`);
337                 for (let m = 0; m < size; ++m) {
338                     print(`    result[${m}] = a[${m}] / b;`);
339                 }
340                 print(`    return result;`);
341                 print(`}`);
342                 print(`${type}${size} operator/(${type} a, ${type}${size} b) {`);
343                 print(`    ${type}${size} result;`);
344                 for (let m = 0; m < size; ++m) {
345                     print(`    result[${m}] = a / b[${m}];`);
346                 }
347                 print(`    return result;`);
348                 print(`}`);
349             }
350         }
351         for (let type of [`char`, `short`, `int`, `half`, `float`]) {
352             for (let size of [2, 3, 4]) {
353                 print(`${type}${size} operator-(${type}${size} a) {`);
354                 print(`    ${type}${size} result;`);
355                 for (let m = 0; m < size; ++m) {
356                     print(`    result[${m}] = -a[${m}];`);
357                 }
358                 print(`    return result;`);
359                 print(`}`);
360             }
361         }
362         for (let type of [`half`, `float`]) {
363             for (let i of [2, 3, 4]) {
364                 for (let j of [2, 3, 4]) {
365                     print(`${type}${i}x${j} operator+(${type}${i}x${j} a, ${type}${i}x${j} b) {`);
366                     print(`    ${type}${i}x${j} result;`);
367                     for (let m = 0; m < i; ++m) {
368                         for (let n = 0; n < j; ++n) {
369                             print(`    result[${m}][${n}] = a[${m}][${n}] + b[${m}][${n}];`);
370                         }
371                     }
372                     print(`    return result;`);
373                     print(`}`);
374                     print(`${type}${i}x${j} operator-(${type}${i}x${j} a, ${type}${i}x${j} b) {`);
375                     print(`    ${type}${i}x${j} result;`);
376                     for (let m = 0; m < i; ++m) {
377                         for (let n = 0; n < j; ++n) {
378                             print(`    result[${m}][${n}] = a[${m}][${n}] - b[${m}][${n}];`);
379                         }
380                     }
381                     print(`    return result;`);
382                     print(`}`);
383                     print(`${type}${i}x${j} operator-(${type}${i}x${j} a) {`);
384                     print(`    ${type}${i}x${j} result;`);
385                     for (let m = 0; m < i; ++m) {
386                         for (let n = 0; n < j; ++n) {
387                             print(`    result[${m}][${n}] = -a[${m}][${n}];`);
388                         }
389                     }
390                     print(`    return result;`);
391                     print(`}`);
392                     print(`${type}${i}x${j} operator*(${type}${i}x${j} a, ${type}${i}x${j} b) {`);
393                     print(`    ${type}${i}x${j} result;`);
394                     for (let m = 0; m < i; ++m) {
395                         for (let n = 0; n < j; ++n) {
396                             print(`    result[${m}][${n}] = a[${m}][${n}] * b[${m}][${n}];`);
397                         }
398                     }
399                     print(`    return result;`);
400                     print(`}`);
401                     print(`${type}${i}x${j} operator*(${type}${i}x${j} a, ${type} b) {`);
402                     print(`    ${type}${i}x${j} result;`);
403                     for (let m = 0; m < i; ++m) {
404                         for (let n = 0; n < j; ++n) {
405                             print(`    result[${m}][${n}] = a[${m}][${n}] * b;`);
406                         }
407                     }
408                     print(`    return result;`);
409                     print(`}`);
410                     print(`${type}${i}x${j} operator*(${type} a, ${type}${i}x${j} b) {`);
411                     print(`    ${type}${i}x${j} result;`);
412                     for (let m = 0; m < i; ++m) {
413                         for (let n = 0; n < j; ++n) {
414                             print(`    result[${m}][${n}] = a * b[${m}][${n}];`);
415                         }
416                     }
417                     print(`    return result;`);
418                     print(`}`);
419                     print(`${type}${i}x${j} operator/(${type}${i}x${j} a, ${type}${i}x${j} b) {`);
420                     print(`    ${type}${i}x${j} result;`);
421                     for (let m = 0; m < i; ++m) {
422                         for (let n = 0; n < j; ++n) {
423                             print(`    result[${m}][${n}] = a[${m}][${n}] / b[${m}][${n}];`);
424                         }
425                     }
426                     print(`    return result;`);
427                     print(`}`);
428                     print(`${type}${i}x${j} operator/(${type}${i}x${j} a, ${type} b) {`);
429                     print(`    ${type}${i}x${j} result;`);
430                     for (let m = 0; m < i; ++m) {
431                         for (let n = 0; n < j; ++n) {
432                             print(`    result[${m}][${n}] = a[${m}][${n}] / b;`);
433                         }
434                     }
435                     print(`    return result;`);
436                     print(`}`);
437                     print(`${type}${i}x${j} operator/(${type} a, ${type}${i}x${j} b) {`);
438                     print(`    ${type}${i}x${j} result;`);
439                     for (let m = 0; m < i; ++m) {
440                         for (let n = 0; n < j; ++n) {
441                             print(`    result[${m}][${n}] = a / b[${m}][${n}];`);
442                         }
443                     }
444                     print(`    return result;`);
445                     print(`}`);
446                 }
447             }
448         }
449
450         for (let type of [`bool`, `uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
451             print(`operator ${type}2(${type} x, ${type} y) {`);
452             print(`    ${type}2 result;`);
453             print(`    result.x = x;`);
454             print(`    result.y = y;`);
455             print(`    return result;`);
456             print(`}`);
457             print(`operator ${type}3(${type} x, ${type} y, ${type} z) {`);
458             print(`    ${type}3 result;`);
459             print(`    result.x = x;`);
460             print(`    result.y = y;`);
461             print(`    result.z = z;`);
462             print(`    return result;`);
463             print(`}`);
464             print(`operator ${type}3(${type}2 x, ${type} y) {`);
465             print(`    ${type}3 result;`);
466             print(`    result.x = x.x;`);
467             print(`    result.y = x.y;`);
468             print(`    result.z = y;`);
469             print(`    return result;`);
470             print(`}`);
471             print(`operator ${type}3(${type} x, ${type}2 y) {`);
472             print(`    ${type}3 result;`);
473             print(`    result.x = x;`);
474             print(`    result.y = y.x;`);
475             print(`    result.z = y.y;`);
476             print(`    return result;`);
477             print(`}`);
478             print(`operator ${type}4(${type} x, ${type} y, ${type} z, ${type} w) {`);
479             print(`    ${type}4 result;`);
480             print(`    result.x = x;`);
481             print(`    result.y = y;`);
482             print(`    result.z = z;`);
483             print(`    result.w = w;`);
484             print(`    return result;`);
485             print(`}`);
486             print(`operator ${type}4(${type}2 x, ${type} y, ${type} z) {`);
487             print(`    ${type}4 result;`);
488             print(`    result.x = x.x;`);
489             print(`    result.y = x.y;`);
490             print(`    result.z = y;`);
491             print(`    result.w = z;`);
492             print(`    return result;`);
493             print(`}`);
494             print(`operator ${type}4(${type} x, ${type}2 y, ${type} z) {`);
495             print(`    ${type}4 result;`);
496             print(`    result.x = x;`);
497             print(`    result.y = y.x;`);
498             print(`    result.z = y.y;`);
499             print(`    result.w = z;`);
500             print(`    return result;`);
501             print(`}`);
502             print(`operator ${type}4(${type} x, ${type} y, ${type}2 z) {`);
503             print(`    ${type}4 result;`);
504             print(`    result.x = x;`);
505             print(`    result.y = y;`);
506             print(`    result.z = z.x;`);
507             print(`    result.w = z.y;`);
508             print(`    return result;`);
509             print(`}`);
510             print(`operator ${type}4(${type}2 x, ${type}2 y) {`);
511             print(`    ${type}4 result;`);
512             print(`    result.x = x.x;`);
513             print(`    result.y = x.y;`);
514             print(`    result.z = y.x;`);
515             print(`    result.w = y.y;`);
516             print(`    return result;`);
517             print(`}`);
518             print(`operator ${type}4(${type}3 x, ${type} y) {`);
519             print(`    ${type}4 result;`);
520             print(`    result.x = x.x;`);
521             print(`    result.y = x.y;`);
522             print(`    result.z = x.z;`);
523             print(`    result.w = y;`);
524             print(`    return result;`);
525             print(`}`);
526             print(`operator ${type}4(${type} x, ${type}3 y) {`);
527             print(`    ${type}4 result;`);
528             print(`    result.x = x;`);
529             print(`    result.y = y.x;`);
530             print(`    result.z = y.y;`);
531             print(`    result.w = y.z;`);
532             print(`    return result;`);
533             print(`}`);
534             print(`uint operator.length(${type}2) {`);
535             print(`    return 2;`);
536             print(`}`);
537             print(`uint operator.length(${type}3) {`);
538             print(`    return 3;`);
539             print(`}`);
540             print(`uint operator.length(${type}4) {`);
541             print(`    return 4;`);
542             print(`}`);
543         }
544         print();
545
546         for (let type of [`half`, `float`]) {
547             let variables = [`a`, `b`, `c`, `d`];
548             for (let m of [2, 3, 4]) {
549                 for (let n of [2, 3, 4]) {
550                     let signature = `operator ${type}${m}x${n}(`;
551                     for (let i = 0; i < m; ++i) {
552                         if (i != 0) {
553                             signature += `, `;
554                         }
555                         signature += `${type}${n} ${variables[i]}`;
556                     }
557                     signature += `) {`;
558                     print(signature);
559                     print(`    ${type}${m}x${n} result;`);
560                     for (let i = 0; i < m; ++i) {
561                         print(`    result[${i}] = ${variables[i]};`);
562                     }
563                     print(`    return result;`);
564                     print(`}`);
565                 }
566             }
567         }
568         print();
569
570         for (let type of [`bool`, `uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
571             print(`bool operator==(${type}2 a, ${type}2 b) {`);
572             print(`    return a.x == b.x && a.y == b.y;`);
573             print(`}`);
574             print(`bool operator==(${type}3 a, ${type}3 b) {`);
575             print(`    return a.x == b.x && a.y == b.y && a.z == b.z;`);
576             print(`}`);
577             print(`bool operator==(${type}4 a, ${type}4 b) {`);
578             print(`    return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w;`);
579             print(`}`);
580             print(`native ${type} operator.x(${type}2);`);
581             print(`native ${type} operator.y(${type}2);`);
582             print(`native ${type} operator.x(${type}3);`);
583             print(`native ${type} operator.y(${type}3);`);
584             print(`native ${type} operator.z(${type}3);`);
585             print(`native ${type} operator.x(${type}4);`);
586             print(`native ${type} operator.y(${type}4);`);
587             print(`native ${type} operator.z(${type}4);`);
588             print(`native ${type} operator.w(${type}4);`);
589             print(`native ${type}2 operator.x=(${type}2, ${type});`);
590             print(`native ${type}2 operator.y=(${type}2, ${type});`);
591             print(`native ${type}3 operator.x=(${type}3, ${type});`);
592             print(`native ${type}3 operator.y=(${type}3, ${type});`);
593             print(`native ${type}3 operator.z=(${type}3, ${type});`);
594             print(`native ${type}4 operator.x=(${type}4, ${type});`);
595             print(`native ${type}4 operator.y=(${type}4, ${type});`);
596             print(`native ${type}4 operator.z=(${type}4, ${type});`);
597             print(`native ${type}4 operator.w=(${type}4, ${type});`);
598             print(`${type} operator[](${type}2 v, uint index) {`);
599             print(`    switch (index) {`);
600             print(`        case 0:`);
601             print(`            return v.x;`);
602             print(`        case 1:`);
603             print(`            return v.y;`);
604             print(`        default:`);
605             print(`            trap;`);
606             print(`    }`);
607             print(`}`);
608             print(`${type} operator[](${type}3 v, uint index) {`);
609             print(`    switch (index) {`);
610             print(`        case 0:`);
611             print(`            return v.x;`);
612             print(`        case 1:`);
613             print(`            return v.y;`);
614             print(`        case 2:`);
615             print(`            return v.z;`);
616             print(`        default:`);
617             print(`            trap;`);
618             print(`    }`);
619             print(`}`);
620             print(`${type} operator[](${type}4 v, uint index) {`);
621             print(`    switch (index) {`);
622             print(`        case 0:`);
623             print(`            return v.x;`);
624             print(`        case 1:`);
625             print(`            return v.y;`);
626             print(`        case 2:`);
627             print(`            return v.z;`);
628             print(`        case 3:`);
629             print(`            return v.w;`);
630             print(`        default:`);
631             print(`            trap;`);
632             print(`    }`);
633             print(`}`);
634             print(`${type}2 operator[]=(${type}2 v, uint index, ${type} a) {`);
635             print(`    switch (index) {`);
636             print(`        case 0:`);
637             print(`            v.x = a;`);
638             print(`            break;`);
639             print(`        case 1:`);
640             print(`            v.y = a;`);
641             print(`            break;`);
642             print(`        default:`);
643             print(`            trap;`);
644             print(`    }`);
645             print(`    return v;`);
646             print(`}`);
647             print(`${type}3 operator[]=(${type}3 v, uint index, ${type} a) {`);
648             print(`    switch (index) {`);
649             print(`        case 0:`);
650             print(`            v.x = a;`);
651             print(`            break;`);
652             print(`        case 1:`);
653             print(`            v.y = a;`);
654             print(`            break;`);
655             print(`        case 2:`);
656             print(`            v.z = a;`);
657             print(`            break;`);
658             print(`        default:`);
659             print(`            trap;`);
660             print(`    }`);
661             print(`    return v;`);
662             print(`}`);
663             print(`${type}4 operator[]=(${type}4 v, uint index, ${type} a) {`);
664             print(`    switch (index) {`);
665             print(`        case 0:`);
666             print(`            v.x = a;`);
667             print(`            break;`);
668             print(`        case 1:`);
669             print(`            v.y = a;`);
670             print(`            break;`);
671             print(`        case 2:`);
672             print(`            v.z = a;`);
673             print(`            break;`);
674             print(`        case 3:`);
675             print(`            v.w = a;`);
676             print(`            break;`);
677             print(`        default:`);
678             print(`            trap;`);
679             print(`    }`);
680             print(`    return v;`);
681             print(`}`);
682         }
683         print();
684
685         for (let type of [`half`, `float`]) {
686             for (let m of [2, 3, 4]) {
687                 for (let n of [2, 3, 4]) {
688                     print(`native ${type}${n} operator[](${type}${m}x${n}, uint);`);
689                     print(`native ${type}${m}x${n} operator[]=(${type}${m}x${n}, uint, ${type}${n});`);
690                 }
691             }
692         }
693         print();
694
695         for (let type of [`half`, `float`]) {
696             for (let i of [2, 3, 4]) {
697                 for (let j of [2, 3, 4]) {
698                     print(`bool operator==(${type}${i}x${j} a, ${type}${i}x${j} b) {`);
699                     print(`    return`);
700                     for (let m = 0; m < i; ++m) {
701                         for (let n = 0; n < j; ++n) {
702                             print(`        a[${m}][${n}] == b[${m}][${n}] &&`);
703                         }
704                     }
705                     print(`    true;`);
706                     print(`}`);
707                 }
708             }
709         }
710
711         function computeSwizzle(components, maxValue, maxLength) {
712             if (components.length == maxLength) {
713                 return [components];
714             } else {
715                 let result = [];
716                 for (let i = 0; i < maxValue; ++i) {
717                     result = result.concat(computeSwizzle(components.concat([i]), maxValue, maxLength));
718                 }
719                 return result;
720             }
721         }
722
723         function component(value) {
724             switch (value) {
725                 case 0:
726                     return `x`;
727                 case 1:
728                     return `y`;
729                 case 2:
730                     return `z`;
731                 case 3:
732                     return `w`;
733                 default:
734                     fatalError();
735             }
736         }
737
738         function uniqueLength(swizzle) {
739             let has0 = false;
740             let has1 = false;
741             let has2 = false;
742             let has3 = false;
743             for (let v of swizzle) {
744                 switch (v) {
745                     case 0:
746                         has0 = true;
747                         break;
748                     case 1:
749                         has1 = true;
750                         break;
751                     case 2:
752                         has2 = true;
753                         break;
754                     case 3:
755                         has3 = true;
756                         break;
757                     default:
758                         fatalError();
759                 }
760             }
761             let result = 0;
762             if (has0) {
763                 result += 1;
764             }
765             if (has1) {
766                 result += 1;
767             }
768             if (has2) {
769                 result += 1;
770             }
771             if (has3) {
772                 result += 1;
773             }
774             return result;
775         }
776
777         for (let type of [`bool`, `uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
778             for (let size of [2, 3, 4]) {
779                 for (let maxValue of [2, 3, 4]) {
780                     for (let swizzle of computeSwizzle([], maxValue, size)) {
781                         let swizzleName = swizzle.map(component).join("");
782                         print(`${type}${size} operator.${swizzleName}(${type}${maxValue} v) {`);
783                         print(`    ${type}${size} result;`);
784                         for (let i = 0; i < size; ++i) {
785                             print(`    result.${component(i)} = v.${component(swizzle[i])};`);
786                         }
787                         print(`    return result;`);
788                         print(`}`);
789                         if (uniqueLength(swizzle) == size) {
790                             print(`${type}${maxValue} operator.${swizzleName}=(${type}${maxValue} v, ${type}${size} c) {`);
791                             print(`    ${type}${maxValue} result = v;`);
792                             for (let i = 0; i < size; ++i) {
793                                 print(`    result.${component(swizzle[i])} = c.${component(i)};`);
794                             }
795                             print(`    return result;`);
796                             print(`}`);
797                         }
798                     }
799                 }
800             }
801         }
802
803         // These functions are unary floating-point scalar functions,
804         // which can also be applied to vectors and matrices component-wise.
805         (function() {
806             let nativeFunctions = [`cos`, `sin`, `tan`, `acos`, `asin`, `atan`, `cosh`, `sinh`, `tanh`, `ceil`, `exp`, `floor`, `log`, `round`, `trunc`];
807             let nativeFragmentFunctions = [`ddx`, `ddy`];
808             let nonNativeFunctions = [`sqrt`, `log2`, `log10`, `frac`, `exp2`, `degrees`, `radians`, `rcp`, `rsqrt`, `saturate`, `ddx_coarse`, `ddx_fine`, `ddy_coarse`, `ddy_fine`, `fwidth`];
809
810             for (let nativeFunction of nativeFunctions) {
811                 print(`native float ${nativeFunction}(float);`);
812                 print(`half ${nativeFunction}(half x) {`);
813                 print(`    return half(${nativeFunction}(float(x)));`);
814                 print(`}`);
815             }
816
817             for (let nativeFunction of nativeFragmentFunctions) {
818                 print(`native fragment float ${nativeFunction}(float);`);
819                 print(`half ${nativeFunction}(half x) {`);
820                 print(`    return half(${nativeFunction}(float(x)));`);
821                 print(`}`);
822             }
823
824             for (let type of [`half`, `float`]) {
825                 print(`${type} sqrt(${type} x) {`);
826                 print(`    return pow(x, 0.5);`);
827                 print(`}`);
828                 print(`${type} log2(${type} x) {`);
829                 print(`    return log(x) / log(${type}(2));`);
830                 print(`}`);
831                 print(`${type} log10(${type} x) {`);
832                 print(`    return log(x) / log(${type}(10));`);
833                 print(`}`);
834                 print(`${type} frac(${type} x) {`);
835                 print(`    return x - floor(x);`);
836                 print(`}`);
837                 print(`${type} exp2(${type} x) {`);
838                 print(`    return exp(x * log(${type}(2)));`);
839                 print(`}`);
840                 print(`${type} degrees(${type} x) {`);
841                 print(`    return x * 180 / 3.14159;`);
842                 print(`}`);
843                 print(`${type} radians(${type} x) {`);
844                 print(`    return x * 3.14159 / 180;`);
845                 print(`}`);
846                 print(`${type} rcp(${type} x) {`);
847                 print(`    return 1 / x;`);
848                 print(`}`);
849                 print(`${type} rsqrt(${type} x) {`);
850                 print(`    return 1 / sqrt(x);`);
851                 print(`}`);
852                 print(`${type} saturate(${type} x) {`);
853                 print(`    return clamp(x, 0, 1);`);
854                 print(`}`);
855                 print(`${type} ddx_coarse(${type} x) {`);
856                 print(`    return ddx(x);`);
857                 print(`}`);
858                 print(`${type} ddx_fine(${type} x) {`);
859                 print(`    return ddx(x);`);
860                 print(`}`);
861                 print(`${type} ddy_coarse(${type} x) {`);
862                 print(`    return ddy(x);`);
863                 print(`}`);
864                 print(`${type} ddy_fine(${type} x) {`);
865                 print(`    return ddy(x);`);
866                 print(`}`);
867                 print(`${type} fwidth(${type} x) {`);
868                 print(`    return abs(ddx(x)) + abs(ddy(x));`);
869                 print(`}`);
870
871                 for (let outputFunction of nativeFunctions.concat(nativeFragmentFunctions.concat(nonNativeFunctions))) {
872                     for (let size of [2, 3, 4]) {
873                         print(`${type}${size} ${outputFunction}(${type}${size} x) {`);
874                         print(`    ${type}${size} result;`);
875                         for (let i = 0; i < size; ++i) {
876                             print(`    result[${i}] = ${outputFunction}(x[${i}]);`);
877                         }
878                         print(`    return result;`);
879                         print(`}`);
880                     }
881                     for (let i of [2, 3, 4]) {
882                         for (let j of [2, 3, 4]) {
883                             print(`${type}${i}x${j} ${outputFunction}(${type}${i}x${j} x) {`);
884                             print(`    ${type}${i}x${j} result;`);
885                             for (let m = 0; m < i; ++m) {
886                                 for (let n = 0; n < j; ++n) {
887                                     print(`    result[${m}][${n}] = ${outputFunction}(x[${m}][${n}]);`);
888                                 }
889                             }
890                             print(`    return result;`);
891                             print(`}`);
892                         }
893                     }
894                 }
895                 print();
896             }
897         })();
898
899         // These functions are binary floating-point scalar functions,
900         // which can also be applied to vectors and matrices component-wise.
901         (function() {
902             let nativeFunctions = [`pow`];
903
904             for (let nativeFunction of nativeFunctions) {
905                 print(`native float ${nativeFunction}(float, float);`);
906                 print(`half ${nativeFunction}(half x, half y) {`);
907                 print(`    return half(${nativeFunction}(float(x), float(y)));`);
908                 print(`}`);
909             }
910
911             for (let type of [`half`, `float`]) {
912                 let nonNativeFunctions = [`step`, `ldexp`, `fmod`];
913
914                 print(`${type} step(${type} y, ${type} x) {`);
915                 print(`    return x >= y ? 1 : 0;`);
916                 print(`}`);
917                 print(`${type} ldexp(${type} x, ${type} e) {`);
918                 print(`    return x * pow(2, e);`);
919                 print(`}`);
920                 print(`${type} fmod(${type} x, ${type} y) {`);
921                 print(`    uint whole = uint(x / y);`);
922                 print(`    ${type} multiple = ${type}(whole) * y;`);
923                 print(`    return x - multiple;`);
924                 print(`}`);
925
926                 for (let outputFunction of nativeFunctions.concat(nonNativeFunctions)) {
927                     for (let size of [2, 3, 4]) {
928                         print(`${type}${size} ${outputFunction}(${type}${size} x, ${type}${size} y) {`);
929                         print(`    ${type}${size} result;`);
930                         for (let i = 0; i < size; ++i) {
931                             print(`    result[${i}] = ${outputFunction}(x[${i}], y[${i}]);`);
932                         }
933                         print(`    return result;`);
934                         print(`}`);
935                     }
936                     for (let i of [2, 3, 4]) {
937                         for (let j of [2, 3, 4]) {
938                             print(`${type}${i}x${j} ${outputFunction}(${type}${i}x${j} x, ${type}${i}x${j} y) {`);
939                             print(`    ${type}${i}x${j} result;`);
940                             for (let m = 0; m < i; ++m) {
941                                 for (let n = 0; n < j; ++n) {
942                                     print(`    result[${m}][${n}] = ${outputFunction}(x[${m}][${n}], y[${m}][${n}]);`);
943                                 }
944                             }
945                             print(`    return result;`);
946                             print(`}`);
947                         }
948                     }
949                 }
950                 print();
951             }
952         })();
953
954         // These functions are ternary floating-point scalar functions,
955         // which can also be applied to vectors and matrices component-wise.
956         for (let type of [`half`, `float`]) {
957             let nonNativeFunctions = [`smoothstep`, `lerp`, `fma`, `mad`];
958
959             print(`${type} smoothstep(${type} edge0, ${type} edge1, ${type} x) {`);
960             print(`    ${type} t = clamp((x - edge0) / (edge1 - edge0), 0, 1);`);
961             print(`    return t * t * (3 - 2 * t);`);
962             print(`}`);
963             print(`${type} lerp(${type} x, ${type} y, ${type} s) {`);
964             print(`    return x * (1 - s) + y * s;`);
965             print(`}`);
966             print(`${type} fma(${type} x, ${type} y, ${type} z) {`);
967             print(`    return x * y + z;`);
968             print(`}`);
969             print(`${type} mad(${type} x, ${type} y, ${type} z) {`);
970             print(`    return x * y + z;`);
971             print(`}`);
972
973             for (let nonNativeFunction of nonNativeFunctions) {
974                 for (let size of [2, 3, 4]) {
975                     print(`${type}${size} ${nonNativeFunction}(${type}${size} x, ${type}${size} y, ${type}${size} z) {`);
976                     print(`    ${type}${size} result;`);
977                     for (let i = 0; i < size; ++i) {
978                         print(`    result[${i}] = ${nonNativeFunction}(x[${i}], y[${i}], z[${i}]);`);
979                     }
980                     print(`    return result;`);
981                     print(`}`);
982                 }
983                 for (let i of [2, 3, 4]) {
984                     for (let j of [2, 3, 4]) {
985                         print(`${type}${i}x${j} ${nonNativeFunction}(${type}${i}x${j} x, ${type}${i}x${j} y, ${type}${i}x${j} z) {`);
986                         print(`    ${type}${i}x${j} result;`);
987                         for (let m = 0; m < i; ++m) {
988                             for (let n = 0; n < j; ++n) {
989                                 print(`    result[${m}][${n}] = ${nonNativeFunction}(x[${m}][${n}], y[${m}][${n}], z[${m}][${n}]);`);
990                             }
991                         }
992                         print(`    return result;`);
993                         print(`}`);
994                     }
995                 }
996             }
997             print();
998         }
999
1000         print(`native bool isnormal(half);`);
1001         print(`native bool isnormal(float);`);
1002         for (let type of [`half`, `float`]) {
1003             for (let size of [2, 3, 4]) {
1004                 print(`bool${size} isnormal(${type}${size} x) {`);
1005                 print(`    bool${size} result;`);
1006                 for (let i = 0; i < size; ++i) {
1007                     print(`    result[${i}] = isnormal(x[${i}]);`);
1008                 }
1009                 print(`    return result;`);
1010                 print(`}`);
1011             }
1012             print();
1013         }
1014
1015         (function() {
1016             let nativeFunctions = [`isfinite`, `isinf`, `isnan`];
1017
1018             for (let nativeFunction of nativeFunctions) {
1019                 print(`native bool ${nativeFunction}(float);`);
1020                 print(`bool ${nativeFunction}(half x) {`);
1021                 print(`    return ${nativeFunction}(float(x));`);
1022                 print(`}`);
1023             }
1024
1025             for (let type of [`half`, `float`]) {
1026                 for (let nativeFunction of nativeFunctions) {
1027                     for (let size of [2, 3, 4]) {
1028                         print(`bool${size} ${nativeFunction}(${type}${size} x) {`);
1029                         print(`    bool${size} result;`);
1030                         for (let i = 0; i < size; ++i) {
1031                             print(`    result[${i}] = ${nativeFunction}(x[${i}]);`);
1032                         }
1033                         print(`    return result;`);
1034                         print(`}`);
1035                     }
1036                 }
1037                 print();
1038             }
1039         })()
1040
1041         for (let type of [`half`, `float`]) {
1042             let nonNativeFunctions = [`isordered`, `isunordered`];
1043
1044             print(`bool isordered(${type} x, ${type} y) {`);
1045             print(`    return (x == x) && (y == y);`);
1046             print(`}`);
1047             print(`bool isunordered(${type} x, ${type} y) {`);
1048             print(`    return isnan(x) || isnan(y);`);
1049             print(`}`);
1050
1051             for (let nonNativeFunction of nonNativeFunctions) {
1052                 for (let size of [2, 3, 4]) {
1053                     print(`bool${size} ${nonNativeFunction}(${type}${size} x, ${type}${size} y) {`);
1054                     print(`    bool${size} result;`);
1055                     for (let i = 0; i < size; ++i) {
1056                         print(`    result[${i}] = ${nonNativeFunction}(x[${i}], y[${i}]);`);
1057                     }
1058                     print(`    return result;`);
1059                     print(`}`);
1060                 }
1061             }
1062             print();
1063         }
1064
1065         print(`native float atan2(float, float);`);
1066         print(`half atan2(half x, half y) {`);
1067         print(`    return half(atan2(float(x), float(y)));`);
1068         print(`}`);
1069         for (let type of [`half`, `float`]) {
1070             for (let size of [2, 3, 4]) {
1071                 print(`${type}${size} atan2(${type}${size} x, ${type}${size} y) {`);
1072                 print(`    ${type}${size} result;`);
1073                 for (let i = 0; i < size; ++i) {
1074                     print(`    result[${i}] = atan2(x[${i}], y[${i}]);`);
1075                 }
1076                 print(`    return result;`);
1077                 print(`}`);
1078             }
1079             for (let i of [2, 3, 4]) {
1080                 for (let j of [2, 3, 4]) {
1081                     print(`${type}${i}x${j} atan2(${type}${i}x${j} x, ${type}${i}x${j} y) {`);
1082                     print(`    ${type}${i}x${j} result;`);
1083                     for (let m = 0; m < i; ++m) {
1084                         for (let n = 0; n < j; ++n) {
1085                             print(`    result[${m}][${n}] = atan2(x[${m}][${n}], y[${m}][${n}]);`);
1086                         }
1087                     }
1088                     print(`    return result;`);
1089                     print(`}`);
1090                 }
1091             }
1092         }
1093         print();
1094
1095         for (let addressSpace1 of [`thread`, `device`, `threadgroup`]) {
1096             for (let addressSpace2 of [`thread`, `device`, `threadgroup`]) {
1097                 for (let type of [`half`, `float`]) {
1098                     print(`void sincos(${type} x, ${addressSpace1} ${type}* y, ${addressSpace2} ${type}* z) {`);
1099                     print(`    if (y != null)`);
1100                     print(`        *y = sin(x);`);
1101                     print(`    if (z != null)`);
1102                     print(`        *z = cos(x);`);
1103                     print(`}`);
1104                     for (let size of [2, 3, 4]) {
1105                         print(`void sincos(${type}${size} x, ${addressSpace1} ${type}${size}* y, ${addressSpace2} ${type}${size}* z) {`);
1106                         // Can't take a pointer to a member of a vector.
1107                         print(`    ${type} sinResult;`);
1108                         print(`    ${type} cosResult;`);
1109                         for (let i = 0; i < size; ++i) {
1110                             print(`    sincos(x[${i}], &sinResult, &cosResult);`);
1111                             print(`    if (y != null)`);
1112                             print(`        (*y)[${i}] = sinResult;`);
1113                             print(`    if (z != null)`);
1114                             print(`        (*z)[${i}] = cosResult;`);
1115                         }
1116                         print(`}`);
1117                     }
1118                     for (let i of [2, 3, 4]) {
1119                         for (let j of [2, 3, 4]) {
1120                             print(`void sincos(${type}${i}x${j} x, ${addressSpace1} ${type}${i}x${j}* y, ${addressSpace2} ${type}${i}x${j}* z) {`);
1121                             // Can't take a pointer to a member of a matrix.
1122                             print(`    ${type} sinResult;`);
1123                             print(`    ${type} cosResult;`);
1124                             for (let m = 0; m < i; ++m) {
1125                                 for (let n = 0; n < j; ++n) {
1126                                     print(`    sincos(x[${m}][${n}], &sinResult, &cosResult);`);
1127                                     print(`    if (y != null)`);
1128                                     print(`        (*y)[${m}][${n}] = sinResult;`);
1129                                     print(`    if (z != null)`);
1130                                     print(`        (*z)[${m}][${n}] = cosResult;`);
1131                                 }
1132                             }
1133                             print(`}`);
1134                         }
1135                     }
1136                 }
1137             }
1138         }
1139         print();
1140
1141         for (let binaryFunction of [[`all`, `true`, `&&`], [`any`, `false`, `||`]]) {
1142             print(`bool ${binaryFunction[0]}(bool x) {`);
1143             print(`    return x;`);
1144             print(`}`);
1145             for (let size of [2, 3, 4]) {
1146                 print(`bool ${binaryFunction[0]}(bool${size} x) {`);
1147                 print(`    bool result = ${binaryFunction[1]};`);
1148                 for (let i = 0; i < size; ++i) {
1149                     print(`    result = result ${binaryFunction[2]} (x[${i}]);`);
1150                 }
1151                 print(`    return result;`);
1152                 print(`}`);
1153             }
1154             for (let type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
1155                 print(`bool ${binaryFunction[0]}(${type} x) {`);
1156                 print(`    return x != 0;`);
1157                 print(`}`);
1158                 for (let size of [2, 3, 4]) {
1159                     print(`bool ${binaryFunction[0]}(${type}${size} x) {`);
1160                     print(`    bool result = ${binaryFunction[1]};`);
1161                     for (let i = 0; i < size; ++i) {
1162                         print(`    result = result ${binaryFunction[2]} (x[${i}] != 0);`);
1163                     }
1164                     print(`    return result;`);
1165                     print(`}`);
1166                 }
1167                 if (type == `half` || type == `float`) {
1168                     for (let i of [2, 3, 4]) {
1169                         for (let j of [2, 3, 4]) {
1170                             print(`bool ${binaryFunction[0]}(${type}${i}x${j} x) {`);
1171                             print(`    bool result = ${binaryFunction[1]};`);
1172                             for (let m = 0; m < i; ++m) {
1173                                 for (let n = 0; n < j; ++n) {
1174                                     print(`    result = result ${binaryFunction[2]} (x[${m}][${n}] != 0);`);
1175                                 }
1176                             }
1177                             print(`    return result;`);
1178                             print(`}`);
1179                         }
1180                     }
1181                 }
1182             }
1183             print();
1184         }
1185
1186         for (let type of [`uchar`, `ushort`, `uint`]) {
1187             print(`${type} abs(${type} x) {`);
1188             print(`    return x;`);
1189             print(`}`);
1190         }
1191         for (let type of [`char`, `short`, `int`, `half`, `float`]) {
1192             print(`${type} abs(${type} x) {`);
1193             print(`    if (x < 0)`);
1194             print(`        return -x;`);
1195             print(`    return x;`);
1196             print(`}`);
1197         }
1198         for (let type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
1199             for (let size of [2, 3, 4]) {
1200                 print(`${type}${size} abs(${type}${size} x) {`);
1201                 print(`    ${type}${size} result;`);
1202                 for (let i = 0; i < size; ++i) {
1203                     print(`    result[${i}] = abs(x[${i}]);`);
1204                 }
1205                 print(`    return result;`);
1206                 print(`}`);
1207             }
1208             if (type == `half` || type == `float`) {
1209                 for (let i of [2, 3, 4]) {
1210                     for (let j of [2, 3, 4]) {
1211                         print(`${type}${i}x${j} abs(${type}${i}x${j} x) {`);
1212                         print(`    ${type}${i}x${j} result;`);
1213                         for (let m = 0; m < i; ++m) {
1214                             for (let n = 0; n < j; ++n) {
1215                                 print(`    result[${m}][${n}] = abs(x[${m}][${n}]);`);
1216                             }
1217                         }
1218                         print(`    return result;`);
1219                         print(`}`);
1220                     }
1221                 }
1222             }
1223         }
1224         print();
1225
1226         for (let type of [`uchar`, `ushort`, `uint`]) {
1227             print(`${type} sign(${type} x) {`);
1228             print(`    return x == 0 ? 0 : 1;`);
1229             print(`}`);
1230         }
1231         for (let type of [`char`, `short`, `int`, `half`, `float`]) {
1232             print(`${type} sign(${type} x) {`);
1233             print(`    if (x < 0)`);
1234             print(`        return -1;`);
1235             print(`    if (x == 0)`);
1236             print(`        return 0;`);
1237             print(`    return 1;`);
1238             print(`}`);
1239         }
1240         for (let type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
1241             for (let size of [2, 3, 4]) {
1242                 print(`${type}${size} sign(${type}${size} x) {`);
1243                 print(`    ${type}${size} result;`);
1244                 for (let i = 0; i < size; ++i) {
1245                     print(`    result[${i}] = sign(x[${i}]);`);
1246                 }
1247                 print(`    return result;`);
1248                 print(`}`);
1249             }
1250             if (type == `half` || type == `float`) {
1251                 for (let i of [2, 3, 4]) {
1252                     for (let j of [2, 3, 4]) {
1253                         print(`${type}${i}x${j} sign(${type}${i}x${j} x) {`);
1254                         print(`    ${type}${i}x${j} result;`);
1255                         for (let m = 0; m < i; ++m) {
1256                             for (let n = 0; n < j; ++n) {
1257                                 print(`    result[${m}][${n}] = sign(x[${m}][${n}]);`);
1258                             }
1259                         }
1260                         print(`    return result;`);
1261                         print(`}`);
1262                     }
1263                 }
1264             }
1265         }
1266         print();
1267
1268         for (let type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
1269             let nonNativeFunctions = [`min`, `max`];
1270
1271             print(`${type} min(${type} x, ${type} y) {`);
1272             print(`    return x > y ? y : x;`);
1273             print(`}`);
1274             print(`${type} max(${type} x, ${type} y) {`);
1275             print(`    return x > y ? x : y;`);
1276             print(`}`);
1277
1278             for (let nonNativeFunction of nonNativeFunctions) {
1279                 for (let size of [2, 3, 4]) {
1280                     print(`${type}${size} ${nonNativeFunction}(${type}${size} x, ${type}${size} y) {`);
1281                     print(`    ${type}${size} result;`);
1282                     for (let i = 0; i < size; ++i) {
1283                         print(`    result[${i}] = ${nonNativeFunction}(x[${i}], y[${i}]);`);
1284                     }
1285                     print(`    return result;`);
1286                     print(`}`);
1287                 }
1288                 if (type == `half` || type == `float`) {
1289                     for (let i of [2, 3, 4]) {
1290                         for (let j of [2, 3, 4]) {
1291                             print(`${type}${i}x${j} ${nonNativeFunction}(${type}${i}x${j} x, ${type}${i}x${j} y) {`);
1292                             print(`    ${type}${i}x${j} result;`);
1293                             for (let m = 0; m < i; ++m) {
1294                                 for (let n = 0; n < j; ++n) {
1295                                     print(`    result[${m}][${n}] = ${nonNativeFunction}(x[${m}][${n}], y[${m}][${n}]);`);
1296                                 }
1297                             }
1298                             print(`    return result;`);
1299                             print(`}`);
1300                         }
1301                     }
1302                 }
1303             }
1304             print();
1305         }
1306
1307         for (let type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
1308             let nonNativeFunctions = [`clamp`];
1309
1310             print(`${type} clamp(${type} x, ${type} lower, ${type} upper) {`);
1311             print(`    return max(min(upper, x), lower);`);
1312             print(`}`);
1313
1314             for (let nonNativeFunction of nonNativeFunctions) {
1315                 for (let size of [2, 3, 4]) {
1316                     print(`${type}${size} ${nonNativeFunction}(${type}${size} x, ${type}${size} y, ${type}${size} z) {`);
1317                     print(`    ${type}${size} result;`);
1318                     for (let i = 0; i < size; ++i) {
1319                         print(`    result[${i}] = ${nonNativeFunction}(x[${i}], y[${i}], z[${i}]);`);
1320                     }
1321                     print(`    return result;`);
1322                     print(`}`);
1323                 }
1324                 if (type == `half` || type == `float`) {
1325                     for (let i of [2, 3, 4]) {
1326                         for (let j of [2, 3, 4]) {
1327                             print(`${type}${i}x${j} ${nonNativeFunction}(${type}${i}x${j} x, ${type}${i}x${j} y, ${type}${i}x${j} z) {`);
1328                             print(`    ${type}${i}x${j} result;`);
1329                             for (let m = 0; m < i; ++m) {
1330                                 for (let n = 0; n < j; ++n) {
1331                                     print(`    result[${m}][${n}] = ${nonNativeFunction}(x[${m}][${n}], y[${m}][${n}], z[${m}][${n}]);`);
1332                                 }
1333                             }
1334                             print(`    return result;`);
1335                             print(`}`);
1336                         }
1337                     }
1338                 }
1339             }
1340             print();
1341         }
1342
1343         for (let addressSpace of [`thread`, `device`, `threadgroup`]) {
1344             for (let type of [`half`, `float`]) {
1345                 print(`${type} modf(${type} x, ${addressSpace} ${type}* ip) {`);
1346                 print(`    uint result = uint(x);`);
1347                 print(`    if (ip != null)`);
1348                 print(`        *ip = x - ${type}(result);`);
1349                 print(`    return ${type}(result);`);
1350                 print(`}`);
1351
1352                 for (let size of [2, 3, 4]) {
1353                     print(`${type}${size} modf(${type}${size} x, ${addressSpace} ${type}${size}* y) {`);
1354                     print(`    ${type}${size} result;`);
1355                     // Can't take a pointer to a member of a vector.
1356                     print(`    ${type} buffer;`);
1357                     for (let i = 0; i < size; ++i) {
1358                         print(`    result[${i}] = modf(x[${i}], &buffer);`);
1359                         print(`    if (y != null)`);
1360                         print(`        (*y)[${i}] = buffer;`);
1361                     }
1362                     print(`    return result;`);
1363                     print(`}`);
1364                 }
1365                 for (let i of [2, 3, 4]) {
1366                     for (let j of [2, 3, 4]) {
1367                         print(`${type}${i}x${j} modf(${type}${i}x${j} x, ${addressSpace} ${type}${i}x${j}* y) {`);
1368                         print(`    ${type}${i}x${j} result;`);
1369                         // Can't take a pointer to a member of a matrix.
1370                         print(`    ${type} buffer;`);
1371                         for (let m = 0; m < i; ++m) {
1372                             for (let n = 0; n < j; ++n) {
1373                                 print(`    result[${m}][${n}] = modf(x[${m}][${n}], &buffer);`);
1374                                 print(`    if (y != null)`);
1375                                 print(`        (*y)[${m}][${n}] = buffer;`);
1376                             }
1377                         }
1378                         print(`    return result;`);
1379                         print(`}`);
1380                     }
1381                 }
1382                 print();
1383             }
1384         }
1385
1386         print(`uchar count_bits(uchar x) {`);
1387         print(`    return uchar(((x | uchar(1 << 0)) == 0 ? 0 : 1) +`);
1388         for (let i = 1; i < 7; ++i) {
1389             print(`           ((x | uchar(1 << ${i})) == 0 ? 0 : 1) +`);
1390         }
1391         print(`           ((x | uchar(1 << 7)) == 0 ? 0 : 1));`);
1392         print(`}`);
1393         print(`uchar count_bits(ushort x) {`);
1394         print(`    return uchar(((x | ushort(1 << 0)) == 0 ? 0 : 1) +`);
1395         for (let i = 1; i < 15; ++i) {
1396             print(`           ((x | ushort(1 << ${i})) == 0 ? 0 : 1) +`);
1397         }
1398         print(`           ((x | ushort(1 << 15)) == 0 ? 0 : 1));`);
1399         print(`}`);
1400         print(`uchar count_bits(uint x) {`);
1401         print(`    return uchar(((x | uint(1 << 0)) == 0 ? 0 : 1) +`);
1402         for (let i = 1; i < 31; ++i) {
1403             print(`           ((x | uint(1 << ${i})) == 0 ? 0 : 1) +`);
1404         }
1405         print(`           ((x | uint(1 << 31)) == 0 ? 0 : 1));`);
1406         print(`}`);
1407         print(`uchar reversebits(uchar x) {`);
1408         print(`    return uchar(((x & uchar(1 << 0)) << 7) |`);
1409         for (let i = 1; i < 7; ++i) {
1410             let offset = 7 - 2 * i
1411             print(`           ((x & uchar(1 << ${i})) ${offset > 0 ? `<<` : `>>`} ${Math.abs(offset)}) |`);
1412         }
1413         print(`           ((x & uchar(1 << 7)) >> 7));`);
1414         print(`}`);
1415         print(`ushort reversebits(ushort x) {`);
1416         print(`    return ushort(((x & ushort(1 << 0)) << 15) |`);
1417         for (let i = 1; i < 15; ++i) {
1418             let offset = 15 - 2 * i
1419             print(`           ((x & ushort(1 << ${i})) ${offset > 0 ? `<<` : `>>`} ${Math.abs(offset)}) |`);
1420         }
1421         print(`           ((x & ushort(1 << 15)) >> 15));`);
1422         print(`}`);
1423         print(`uint reversebits(uint x) {`);
1424         print(`    return uint(((x & uint(1 << 0)) << 31) |`);
1425         for (let i = 1; i < 31; ++i) {
1426             let offset = 31 - 2 * i
1427             print(`           ((x & uint(1 << ${i})) ${offset > 0 ? `<<` : `>>`} ${Math.abs(offset)}) |`);
1428         }
1429         print(`           ((x & uint(1 << 31)) >> 31));`);
1430         print(`}`);
1431         for (let type of [`uchar`, `ushort`, `uint`]) {
1432             for (let size of [2, 3, 4]) {
1433                 print(`uchar${size} count_bits(${type}${size} x) {`);
1434                 print(`    uchar${size} result;`);
1435                 for (let i = 0; i < size; ++i) {
1436                     print(`    result[${i}] = count_bits(x[${i}]);`);
1437                 }
1438                 print(`    return result;`);
1439                 print(`}`);
1440             }
1441         }
1442         for (let type of [`uchar`, `ushort`, `uint`]) {
1443             for (let size of [2, 3, 4]) {
1444                 print(`${type}${size} reversebits(${type}${size} x) {`);
1445                 print(`    ${type}${size} result;`);
1446                 for (let i = 0; i < size; ++i) {
1447                     print(`    result[${i}] = reversebits(x[${i}]);`);
1448                 }
1449                 print(`    return result;`);
1450                 print(`}`);
1451             }
1452         }
1453         print();
1454
1455         print(`uint firstbithigh(uchar x) {`);
1456         for (let i = 0; i <= 7; ++i) {
1457             print(`    if ((x & uchar(1 << ${7 - i})) != 0)`);
1458             print(`        return ${i};`);
1459         }
1460         print(`    return 8;`);
1461         print(`}`);
1462         print(`uint firstbithigh(ushort x) {`);
1463         for (let i = 0; i <= 15; ++i) {
1464             print(`    if ((x & ushort(1 << ${15 - i})) != 0)`);
1465             print(`        return ${i};`);
1466         }
1467             print(`    return 16;`);
1468         print(`}`);
1469         print(`uint firstbithigh(uint x) {`);
1470         for (let i = 0; i <= 31; ++i) {
1471             print(`    if ((x & uint(1 << ${31 - i})) != 0)`);
1472             print(`        return ${i};`);
1473         }
1474         print(`    return 32;`);
1475         print(`}`);
1476         print(`uint firstbithigh(char x) {`);
1477         print(`    return firstbithigh(uchar(x));`);
1478         print(`}`);
1479         print(`uint firstbithigh(short x) {`);
1480         print(`    return firstbithigh(ushort(x));`);
1481         print(`}`);
1482         print(`uint firstbithigh(int x) {`);
1483         print(`    return firstbithigh(uint(x));`);
1484         print(`}`);
1485         print(`uint firstbitlow(uchar x) {`);
1486         for (let i = 0; i <= 7; ++i) {
1487             print(`    if ((x & uchar(1 << ${i})) != 0)`);
1488             print(`        return ${7 - i};`);
1489         }
1490         print(`    return 8;`);
1491         print(`}`);
1492         print(`uint firstbitlow(ushort x) {`);
1493         for (let i = 0; i <= 15; ++i) {
1494             print(`    if ((x & ushort(1 << ${i})) != 0)`);
1495             print(`        return ${15 - i};`);
1496         }
1497         print(`    return 16;`);
1498         print(`}`);
1499         print(`uint firstbitlow(uint x) {`);
1500         for (let i = 0; i <= 31; ++i) {
1501             print(`    if ((x & uint(1 << ${i})) != 0)`);
1502             print(`        return ${31 - i};`);
1503         }
1504         print(`    return 32;`);
1505         print(`}`);
1506         print(`uint firstbitlow(char x) {`);
1507         print(`    return firstbitlow(uchar(x));`);
1508         print(`}`);
1509         print(`uint firstbitlow(short x) {`);
1510         print(`    return firstbitlow(ushort(x));`);
1511         print(`}`);
1512         print(`uint firstbitlow(int x) {`);
1513         print(`    return firstbitlow(uint(x));`);
1514         print(`}`);
1515         for (let functionName of [`firstbithigh`, `firstbitlow`]) {
1516             for (let type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`]) {
1517                 for (let size of [2, 3, 4]) {
1518                     print(`uint${size} ${functionName}(${type}${size} x) {`);
1519                     print(`    uint${size} result;`);
1520                     for (let i = 0; i < size; ++i) {
1521                         print(`    result[${i}] = ${functionName}(x[${i}]);`);
1522                     }
1523                     print(`    return result;`);
1524                     print(`}`);
1525                 }
1526             }
1527         }
1528         print();
1529
1530         // Row-major, so the first index selects which row, and the second index selects which column
1531         for (let type of [`half`, `float`]) {
1532             print(`${type} determinant(${type} x) {`);
1533             print(`    return x;`);
1534             print(`}`);
1535             print(`${type} determinant(${type}2x2 x) {`);
1536             print(`    return x[0][0] * x[1][1] - x[0][1] * x[1][0];`);
1537             print(`}`);
1538             print(`${type} determinant(${type}3x3 x) {`);
1539             print(`    return x[0][0] * x[1][1] * x[2][2] +`);
1540             print(`           x[0][1] * x[1][2] * x[2][0] +`);
1541             print(`           x[0][2] * x[1][0] * x[2][1] -`);
1542             print(`           x[2][0] * x[1][1] * x[0][2] -`);
1543             print(`           x[2][1] * x[1][2] * x[0][0] -`);
1544             print(`           x[2][2] * x[1][0] * x[0][1];`);
1545             print(`}`);
1546             print(`${type} determinant(${type}4x4 x) {`);
1547             print(`    ${type} result;`);
1548             print(`    ${type}3x3 minor;`);
1549             print(`    minor[0][0] = x[1][1];`);
1550             print(`    minor[0][1] = x[1][2];`);
1551             print(`    minor[0][2] = x[1][3];`);
1552             print(`    minor[1][0] = x[2][1];`);
1553             print(`    minor[1][1] = x[2][2];`);
1554             print(`    minor[1][2] = x[2][3];`);
1555             print(`    minor[2][0] = x[3][1];`);
1556             print(`    minor[2][1] = x[3][2];`);
1557             print(`    minor[2][2] = x[3][3];`);
1558             print(`    result = result + x[0][0] * determinant(minor);`);
1559             print(`    minor[0][0] = x[1][0];`);
1560             print(`    minor[0][1] = x[1][2];`);
1561             print(`    minor[0][2] = x[1][3];`);
1562             print(`    minor[1][0] = x[2][0];`);
1563             print(`    minor[1][1] = x[2][2];`);
1564             print(`    minor[1][2] = x[2][3];`);
1565             print(`    minor[2][0] = x[3][0];`);
1566             print(`    minor[2][1] = x[3][2];`);
1567             print(`    minor[2][2] = x[3][3];`);
1568             print(`    result = result - x[0][1] * determinant(minor);`);
1569             print(`    minor[0][0] = x[1][0];`);
1570             print(`    minor[0][1] = x[1][1];`);
1571             print(`    minor[0][2] = x[1][3];`);
1572             print(`    minor[1][0] = x[2][0];`);
1573             print(`    minor[1][1] = x[2][1];`);
1574             print(`    minor[1][2] = x[2][3];`);
1575             print(`    minor[2][0] = x[3][0];`);
1576             print(`    minor[2][1] = x[3][1];`);
1577             print(`    minor[2][2] = x[3][3];`);
1578             print(`    result = result + x[0][2] * determinant(minor);`);
1579             print(`    minor[0][0] = x[1][0];`);
1580             print(`    minor[0][1] = x[1][1];`);
1581             print(`    minor[0][2] = x[1][2];`);
1582             print(`    minor[1][0] = x[2][0];`);
1583             print(`    minor[1][1] = x[2][1];`);
1584             print(`    minor[1][2] = x[2][2];`);
1585             print(`    minor[2][0] = x[3][0];`);
1586             print(`    minor[2][1] = x[3][1];`);
1587             print(`    minor[2][2] = x[3][2];`);
1588             print(`    result = result - x[0][3] * determinant(minor);`);
1589             print(`    return result;`);
1590             print(`}`);
1591         }
1592         print();
1593
1594         for (let type of [`uchar4`, `ushort4`, `uint4`, `char4`, `short4`, `int4`, `half4`, `float4`]) {
1595             print(`${type} dst(${type} src0, ${type} src1) {`);
1596             print(`    ${type} result;`);
1597             print(`    result.x = 1;`);
1598             print(`    result.y = src0.y * src1.y;`);
1599             print(`    result.z = src0.z;`);
1600             print(`    result.w = src1.w;`);
1601             print(`    return result;`);
1602             print(`}`);
1603         }
1604         print();
1605
1606         for (let type of [`half`, `float`]) {
1607             print(`${type} distance(${type} x, ${type} y) {`);
1608             print(`    return length(x - y);`);
1609             print(`}`);
1610             for (let size of [2, 3, 4]) {
1611                 print(`${type} distance(${type}${size} x, ${type}${size} y) {`);
1612                 print(`    return length(x - y);`);
1613                 print(`}`);
1614             }
1615         }
1616         print();
1617
1618         for (let type of [`half3`, `float3`]) {
1619             print(`${type} cross(${type} u, ${type} v) {`);
1620             print(`    ${type} result;`);
1621             print(`    result.x = u.y * v.z - u.z * v.y;`);
1622             print(`    result.y = u.z * v.x - u.x * v.z;`);
1623             print(`    result.z = u.x * v.y - u.y * v.x;`);
1624             print(`    return result;`);
1625             print(`}`);
1626         }
1627         print();
1628
1629         for (let type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
1630             print(`${type} dot(${type} a, ${type} b) {`);
1631             print(`    return a * b;`);
1632             print(`}`);
1633             for (let size of [2, 3, 4]) {
1634                 print(`${type} dot(${type}${size} a, ${type}${size} b) {`);
1635                 print(`    ${type} result = 0;`);
1636                 for (let i = 0; i < size; ++i) {
1637                     print(`    result = result + a[${i}] * b[${i}];`);
1638                 }
1639                 print(`    return result;`);
1640                 print(`}`);
1641             }
1642         }
1643         print();
1644
1645         for (let type of [`half`, `float`]) {
1646             for (let size of [``, `2`, `3`, `4`]) {
1647                 print(`${type}${size} faceforward(${type}${size} n, ${type}${size} i, ${type}${size} ng) {`);
1648                 print(`    return -n * sign(dot(i, ng));`);
1649                 print(`}`);
1650             }
1651         }
1652         print();
1653
1654         for (let type of [`half`, `float`]) {
1655             for (let size of [``, `2`, `3`, `4`]) {
1656                 print(`${type} length(${type}${size} x) {`);
1657                 print(`    return sqrt(dot(x, x));`);
1658                 print(`}`);
1659             }
1660         }
1661         print();
1662
1663         for (let type of [`half`, `float`]) {
1664             print(`${type}4 lit(${type} n_dot_l, ${type} n_dot_h, ${type} m) {`);
1665             print(`    ${type} ambient = 1;`);
1666             print(`    ${type} diffuse = max(0, n_dot_l);`);
1667             print(`    ${type} specular = n_dot_l < 0 || n_dot_h < 0 ? 0 : n_dot_h * m;`);
1668             print(`    ${type}4 result;`);
1669             print(`    result.x = ambient;`);
1670             print(`    result.y = diffuse;`);
1671             print(`    result.z = specular;`);
1672             print(`    result.w = 1;`);
1673             print(`    return result;`);
1674             print(`}`);
1675         }
1676         print();
1677
1678         for (let type of [`half`, `float`]) {
1679             for (let size of [``, `2`, `3`, `4`]) {
1680                 print(`${type}${size} normalize(${type}${size} x) {`);
1681                 print(`    return x / length(x);`);
1682                 print(`}`);
1683             }
1684         }
1685         print();
1686
1687         for (let type of [`half`, `float`]) {
1688             for (let size of [``, `2`, `3`, `4`]) {
1689                 print(`${type}${size} reflect(${type}${size} i, ${type}${size} n) {`);
1690                 print(`    return i - 2 * n * dot(i, n);`);
1691                 print(`}`);
1692             }
1693         }
1694         print();
1695
1696         // OpenGL ES v3.30 section 8.4
1697         for (let type of [`half`, `float`]) {
1698             for (let size of [``, `2`, `3`, `4`]) {
1699                 print(`${type}${size} refract(${type}${size} i, ${type}${size} n, ${type} eta) {`);
1700                 print(`    ${type}${size} result;`);
1701                 print(`    ${type} k = 1 - eta * eta * (1 - dot(n, i) * dot(n, i));`);
1702                 print(`    if (k < 0)`);
1703                 print(`        return result;`);
1704                 print(`    return eta * i - (eta * dot(n, i) + sqrt(k)) * n;`);
1705                 print(`}`);
1706             }
1707         }
1708         print();
1709
1710         for (let type of [`half`, `float`]) {
1711             print(`${type} transpose(${type} x) {`);
1712             print(`    return x;`);
1713             print(`}`);
1714             for (let i of [2, 3, 4]) {
1715                 for (let j of [2, 3, 4]) {
1716                     print(`${type}${i}x${j} transpose(${type}${j}x${i} x) {`);
1717                     print(`    ${type}${i}x${j} result;`);
1718                     for (let m = 0; m < i; ++m) {
1719                         for (let n = 0; n < j; ++n) {
1720                             print(`    result[${m}][${n}] = x[${n}][${m}];`);
1721                         }
1722                     }
1723                     print(`    return result;`);
1724                     print(`}`);
1725                 }
1726             }
1727         }
1728         print();
1729
1730         for (let resultType of [`int`, `uint`, `float`]) {
1731             for (let type of [`int`, `uint`, `float`]) {
1732                 if (type == resultType) {
1733                     print(`${resultType} as${resultType}(${type} x) {`);
1734                     print(`    return x;`);
1735                     print(`}`);
1736                 } else  if (resultType == `int` && type == `uint` || resultType == `uint` && type == `int`) {
1737                     print(`${resultType} as${resultType}(${type} x) {`);
1738                     print(`    return ${resultType}(x);`);
1739                     print(`}`);
1740                 } else {
1741                     print(`native ${resultType} as${resultType}(${type});`);
1742                 }
1743                 for (let size of [2, 3, 4]) {
1744                     if (type == resultType) {
1745                         print(`${resultType}${size} as${resultType}(${type}${size} x) {`);
1746                         print(`    return x;`);
1747                         print(`}`);
1748                     } else {
1749                         print(`${resultType}${size} as${resultType}(${type}${size} x) {`);
1750                         print(`    ${resultType}${size} result;`);
1751                         for (let i = 0; i < size; ++i) {
1752                             print(`    result[${i}] = as${resultType}(x[${i}]);`);
1753                         }
1754                         print(`    return result;`);
1755                         print(`}`);
1756                     }
1757                 }
1758                 if (resultType == `float` && type == `float`) {
1759                     for (let i of [2, 3, 4]) {
1760                         for (let j of [2, 3, 4]) {
1761                             if (type == resultType) {
1762                                 print(`${resultType}${i}x${j} as${resultType}(${type}${i}x${j} x) {`);
1763                                 print(`    return x;`);
1764                                 print(`}`);
1765                             } else {
1766                                 print(`${resultType}${i}x${j} as${resultType}(${type}${i}x${j} x) {`);
1767                                 print(`    ${resultType}${i}x${j} result;`);
1768                                 for (let m = 0; m < i; ++m) {
1769                                     for (let n = 0; n < j; ++n) {
1770                                         print(`    result[${m}][${n}] = as${resultType}(x[${m}][${n}]);`);
1771                                     }
1772                                 }
1773                                 print(`    return result;`);
1774                                 print(`}`);
1775                             }
1776                         }
1777                     }
1778                 }
1779             }
1780         }
1781         print();
1782
1783         print(`native float f16tof32(uint);`);
1784         print(`native uint f32tof16(float);`);
1785         for (let size of [2, 3, 4]) {
1786             print(`float${size} f16tof32(uint${size} x) {`);
1787             print(`    float${size} result;`);
1788             for (let i = 0; i < size; ++i) {
1789                 print(`    result[${i}] = f16tof32(x[${i}]);`);
1790             }
1791             print(`    return result;`);
1792             print(`}`);
1793             print(`uint${size} f32tof16(float${size} x) {`);
1794             print(`    uint${size} result;`);
1795             for (let i = 0; i < size; ++i) {
1796                 print(`    result[${i}] = f32tof16(x[${i}]);`);
1797             }
1798             print(`    return result;`);
1799             print(`}`);
1800         }
1801         print();
1802
1803         print(`native compute void AllMemoryBarrierWithGroupSync();`);
1804         print(`native compute void DeviceMemoryBarrierWithGroupSync();`);
1805         print(`native compute void GroupMemoryBarrierWithGroupSync();`);
1806         print();
1807
1808         for (let type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
1809             print(`${type} mul(${type} x, ${type} y) {`);
1810             print(`    return x * y;`);
1811             print(`}`);
1812         }
1813
1814         for (let type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
1815             for (let size of [2, 3, 4]) {
1816                 print(`${type}${size} mul(${type} x, ${type}${size} y) {`);
1817                 print(`    ${type}${size} result;`);
1818                 for (let i = 0; i < size; ++i) {
1819                     print(`    result[${i}] = x * y[${i}];`);
1820                 }
1821                 print(`    return result;`);
1822                 print(`}`);
1823                 print(`${type}${size} mul(${type}${size} x, ${type} y) {`);
1824                 print(`    ${type}${size} result;`);
1825                 for (let i = 0; i < size; ++i) {
1826                     print(`    result[${i}] = x[${i}] * y;`);
1827                 }
1828                 print(`    return result;`);
1829                 print(`}`);
1830             }
1831         }
1832
1833         for (let type of [`half`, `float`]) {
1834             for (let i of [2, 3, 4]) {
1835                 for (let j of [2, 3, 4]) {
1836                     print(`${type}${i}x${j} mul(${type} x, ${type}${i}x${j} y) {`);
1837                     print(`    ${type}${i}x${j} result;`);
1838                     for (let m = 0; m < i; ++m) {
1839                         for (let n = 0; n < j; ++n) {
1840                             print(`    result[${m}][${n}] = x * y[${m}][${n}];`);
1841                         }
1842                     }
1843                     print(`    return result;`);
1844                     print(`}`);
1845                     print(`${type}${i}x${j} mul(${type}${i}x${j} x, ${type} y) {`);
1846                     print(`    ${type}${i}x${j} result;`);
1847                     for (let m = 0; m < i; ++m) {
1848                         for (let n = 0; n < j; ++n) {
1849                             print(`    result[${m}][${n}] = x[${m}][${n}] * y;`);
1850                         }
1851                     }
1852                     print(`    return result;`);
1853                     print(`}`);
1854                 }
1855             }
1856         }
1857
1858         for (let type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
1859             for (let size of [2, 3, 4]) {
1860                 print(`${type} mul(${type}${size} x, ${type}${size} y) {`);
1861                 print(`    return dot(x, y);`);
1862                 print(`}`);
1863             }
1864         }
1865
1866         for (let type of [`half`, `float`]) {
1867             for (let i of [2, 3, 4]) {
1868                 for (let j of [2, 3, 4]) {
1869                     print(`${type}${j} mul(${type}${i} x, ${type}${i}x${j} y) {`);
1870                     print(`    ${type}${j} result;`);
1871                     for (let m = 0; m < j; ++m) {
1872                         print(`    result[${m}] = 0;`);
1873                         for (let n = 0; n < i; ++n) {
1874                             print(`    result[${m}] += x[${n}] * y[${n}][${m}];`);
1875                         }
1876                     }
1877                     print(`    return result;`);
1878                     print(`}`);
1879                     print(`${type}${i} mul(${type}${i}x${j} x, ${type}${j} y) {`);
1880                     print(`    ${type}${i} result;`);
1881                     for (let m = 0; m < i; ++m) {
1882                         print(`    result[${m}] = 0;`);
1883                         for (let n = 0; n < j; ++n) {
1884                             print(`    result[${m}] += x[${m}][${n}] * y[${n}];`);
1885                         }
1886                     }
1887                     print(`    return result;`);
1888                     print(`}`);
1889                 }
1890             }
1891         }
1892
1893         for (let type of [`half`, `float`]) {
1894             for (let i of [2, 3, 4]) {
1895                 for (let j of [2, 3, 4]) {
1896                     for (let k of [2, 3, 4]) {
1897                         print(`${type}${i}x${k} mul(${type}${i}x${j} x, ${type}${j}x${k} y) {`);
1898                         print(`    ${type}${i}x${k} result;`);
1899                         for (let p = 0; p < i; ++p) {
1900                             for (let r = 0; r < k; ++r) {
1901                                 print(`    result[${p}][${r}] = 0;`);
1902                                 for (let q = 0; q < j; ++q) {
1903                                     print(`    result[${p}][${r}] += x[${p}][${q}] * y[${q}][${r}];`);
1904                                 }
1905                             }
1906                         }
1907                         print(`    return result;`);
1908                         print(`}`);
1909                     }
1910                 }
1911             }
1912         }
1913         print();
1914
1915         for (let addressSpace1 of [`thread`, `device`, `threadgroup`]) {
1916             for (let addressSpace2 of [`thread`, `device`, `threadgroup`]) {
1917                 for (let type of [`uint`, `int`]) {
1918                     for (let functionName of [`Add`, `And`, `Exchange`, `Max`, `Min`, `Or`, `Xor`])
1919                         print(`native void Interlocked${functionName}(${addressSpace1} atomic_${type}*, ${type}, ${addressSpace2} ${type}*);`);
1920                     print(`native void InterlockedCompareExchange(${addressSpace1} atomic_${type}*, ${type}, ${type}, ${addressSpace2} ${type}*);`);
1921                 }
1922             }
1923         }
1924         print();
1925
1926         // You might think that the sampling functions that rely on implicit derivatives can't be called in vertex shaders.
1927         // However, they do work; they just a level of 0.
1928         for (let type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
1929             for (let length of [``, `2`, `3`, `4`]) {
1930                 print(`native ${type}${length} Sample(Texture1D<${type}${length}>, sampler, float location);`);
1931                 print(`native ${type}${length} Sample(Texture1D<${type}${length}>, sampler, float location, int offset);`);
1932                 print(`native ${type}${length} Load(Texture1D<${type}${length}>, int2 location);`);
1933                 print(`native ${type}${length} Load(Texture1D<${type}${length}>, int2 location, int offset);`);
1934                 for (let addressSpace1 of [`thread`, `device`, `threadgroup`]) {
1935                     for (let addressSpace2 of [`thread`, `device`, `threadgroup`])
1936                         print(`native void GetDimensions(Texture1D<${type}${length}>, uint MipLevel, ${addressSpace1} uint* Width, ${addressSpace2} uint* NumberOfLevels);`);
1937                 }
1938                 print();
1939                 print(`native ${type}${length} Sample(Texture1DArray<${type}${length}>, sampler, float2 location);`);
1940                 print(`native ${type}${length} Sample(Texture1DArray<${type}${length}>, sampler, float2 location, int offset);`);
1941                 print(`native ${type}${length} Load(Texture1DArray<${type}${length}>, int3 location);`);
1942                 print(`native ${type}${length} Load(Texture1DArray<${type}${length}>, int3 location, int offset);`);
1943                 for (let addressSpace1 of [`thread`, `device`, `threadgroup`]) {
1944                     for (let addressSpace2 of [`thread`, `device`, `threadgroup`]) {
1945                         for (let addressSpace3 of [`thread`, `device`, `threadgroup`])
1946                             print(`native void GetDimensions(Texture1DArray<${type}${length}>, uint MipLevel, ${addressSpace1} uint* Width, ${addressSpace2} uint* Elements, ${addressSpace3} uint* NumberOfLevels);`);
1947                     }
1948                 }
1949                 print();
1950                 print(`native ${type}${length} Sample(Texture2D<${type}${length}>, sampler, float2 location);`);
1951                 print(`native ${type}${length} Sample(Texture2D<${type}${length}>, sampler, float2 location, int2 offset);`);
1952                 print(`native ${type}${length} SampleBias(Texture2D<${type}${length}>, sampler, float2 location, float Bias);`);
1953                 print(`native ${type}${length} SampleBias(Texture2D<${type}${length}>, sampler, float2 location, float Bias, int2 offset);`);
1954                 print(`native ${type}${length} SampleGrad(Texture2D<${type}${length}>, sampler, float2 location, float2 DDX, float2 DDY);`);
1955                 print(`native ${type}${length} SampleGrad(Texture2D<${type}${length}>, sampler, float2 location, float2 DDX, float2 DDY, int2 offset);`);
1956                 print(`native ${type}${length} SampleLevel(Texture2D<${type}${length}>, sampler, float2 location, float LOD);`);
1957                 print(`native ${type}${length} SampleLevel(Texture2D<${type}${length}>, sampler, float2 location, float LOD, int2 offset);`);
1958                 print(`native ${type}4 Gather(Texture2D<${type}${length}>, sampler, float2 location);`);
1959                 print(`native ${type}4 Gather(Texture2D<${type}${length}>, sampler, float2 location, int2 offset);`);
1960                 print(`native ${type}4 GatherRed(Texture2D<${type}${length}>, sampler, float2 location);`);
1961                 print(`native ${type}4 GatherRed(Texture2D<${type}${length}>, sampler, float2 location, int2 offset);`);
1962                 if (length == "2" || length == "3" || length == "4") {
1963                     print(`native ${type}4 GatherGreen(Texture2D<${type}${length}>, sampler, float2 location);`);
1964                     print(`native ${type}4 GatherGreen(Texture2D<${type}${length}>, sampler, float2 location, int2 offset);`);
1965                     if (length == "3" || length == "4") {
1966                         print(`native ${type}4 GatherBlue(Texture2D<${type}${length}>, sampler, float2 location);`);
1967                         print(`native ${type}4 GatherBlue(Texture2D<${type}${length}>, sampler, float2 location, int2 offset);`);
1968                         if (length == "4") {
1969                             print(`native ${type}4 GatherAlpha(Texture2D<${type}${length}>, sampler, float2 location);`);
1970                             print(`native ${type}4 GatherAlpha(Texture2D<${type}${length}>, sampler, float2 location, int2 offset);`);
1971                         }
1972                     }
1973                 }
1974                 print(`native ${type}${length} Load(Texture2D<${type}${length}>, int3 location);`);
1975                 print(`native ${type}${length} Load(Texture2D<${type}${length}>, int3 location, int2 offset);`);
1976                 for (let addressSpace1 of [`thread`, `device`, `threadgroup`]) {
1977                     for (let addressSpace2 of [`thread`, `device`, `threadgroup`])
1978                         for (let addressSpace3 of [`thread`, `device`, `threadgroup`]) {
1979                             print(`native void GetDimensions(Texture2D<${type}${length}>, uint MipLevel, ${addressSpace1} uint* Width, ${addressSpace2} uint* Height, ${addressSpace3} uint* NumberOfLevels);`);
1980                     }
1981                 }
1982                 print();
1983                 print(`native ${type}${length} Sample(Texture2DArray<${type}${length}>, sampler, float3 location);`);
1984                 print(`native ${type}${length} Sample(Texture2DArray<${type}${length}>, sampler, float3 location, int2 offset);`);
1985                 print(`native ${type}${length} SampleBias(Texture2DArray<${type}${length}>, sampler, float3 location, float Bias);`);
1986                 print(`native ${type}${length} SampleBias(Texture2DArray<${type}${length}>, sampler, float3 location, float Bias, int2 offset);`);
1987                 print(`native ${type}${length} SampleGrad(Texture2DArray<${type}${length}>, sampler, float3 location, float2 DDX, float2 DDY);`);
1988                 print(`native ${type}${length} SampleGrad(Texture2DArray<${type}${length}>, sampler, float3 location, float2 DDX, float2 DDY, int2 offset);`);
1989                 print(`native ${type}${length} SampleLevel(Texture2DArray<${type}${length}>, sampler, float3 location, float LOD);`);
1990                 print(`native ${type}${length} SampleLevel(Texture2DArray<${type}${length}>, sampler, float3 location, float LOD, int2 offset);`);
1991                 print(`native ${type}4 Gather(Texture2DArray<${type}${length}>, sampler, float3 location);`);
1992                 print(`native ${type}4 Gather(Texture2DArray<${type}${length}>, sampler, float3 location, int2 offset);`);
1993                 print(`native ${type}4 GatherRed(Texture2DArray<${type}${length}>, sampler, float3 location);`);
1994                 print(`native ${type}4 GatherRed(Texture2DArray<${type}${length}>, sampler, float3 location, int2 offset);`);
1995                 if (length == "2" || length == "3" || length == "4") {
1996                     print(`native ${type}4 GatherGreen(Texture2DArray<${type}${length}>, sampler, float3 location);`);
1997                     print(`native ${type}4 GatherGreen(Texture2DArray<${type}${length}>, sampler, float3 location, int2 offset);`);
1998                     if (length == "3" || length == "4") {
1999                         print(`native ${type}4 GatherBlue(Texture2DArray<${type}${length}>, sampler, float3 location);`);
2000                         print(`native ${type}4 GatherBlue(Texture2DArray<${type}${length}>, sampler, float3 location, int2 offset);`);
2001                         if (length == "4") {
2002                             print(`native ${type}4 GatherAlpha(Texture2DArray<${type}${length}>, sampler, float3 location);`);
2003                             print(`native ${type}4 GatherAlpha(Texture2DArray<${type}${length}>, sampler, float3 location, int2 offset);`);
2004                         }
2005                     }
2006                 }
2007                 print(`native ${type}${length} Load(Texture2DArray<${type}${length}>, int4 location);`);
2008                 print(`native ${type}${length} Load(Texture2DArray<${type}${length}>, int4 location, int2 offset);`);
2009                 for (let addressSpace1 of [`thread`, `device`, `threadgroup`]) {
2010                     for (let addressSpace2 of [`thread`, `device`, `threadgroup`]) {
2011                         for (let addressSpace3 of [`thread`, `device`, `threadgroup`]) {
2012                             for (let addressSpace4 of [`thread`, `device`, `threadgroup`])
2013                                 print(`native void GetDimensions(Texture2DArray<${type}${length}>, uint MipLevel, ${addressSpace1} uint* Width, ${addressSpace2} uint* Height, ${addressSpace3} uint* Elements, ${addressSpace4} uint* NumberOfLevels);`);
2014                         }
2015                     }
2016                 }
2017                 print();
2018                 print(`native ${type}${length} Sample(Texture3D<${type}${length}>, sampler, float3 location);`);
2019                 print(`native ${type}${length} Sample(Texture3D<${type}${length}>, sampler, float3 location, int3 offset);`);
2020                 print(`native ${type}${length} Load(Texture3D<${type}${length}>, int4 location);`);
2021                 print(`native ${type}${length} Load(Texture3D<${type}${length}>, int4 location, int3 offset);`);
2022                 for (let addressSpace1 of [`thread`, `device`, `threadgroup`]) {
2023                     for (let addressSpace2 of [`thread`, `device`, `threadgroup`]) {
2024                         for (let addressSpace3 of [`thread`, `device`, `threadgroup`]) {
2025                             for (let addressSpace4 of [`thread`, `device`, `threadgroup`])
2026                                 print(`native void GetDimensions(Texture3D<${type}${length}>, uint MipLevel, ${addressSpace1} uint* Width, ${addressSpace2} uint* Height, ${addressSpace3} uint* Depth, ${addressSpace4} uint* NumberOfLevels);`);
2027                         }
2028                     }
2029                 }
2030                 print();
2031                 print(`native ${type}${length} Sample(TextureCube<${type}${length}>, sampler, float3 location);`);
2032                 print(`native ${type}${length} SampleBias(TextureCube<${type}${length}>, sampler, float3 location, float Bias);`);
2033                 print(`native ${type}${length} SampleGrad(TextureCube<${type}${length}>, sampler, float3 location, float3 DDX, float3 DDY);`);
2034                 print(`native ${type}${length} SampleLevel(TextureCube<${type}${length}>, sampler, float3 location, float LOD);`);
2035                 print(`native ${type}4 Gather(TextureCube<${type}${length}>, sampler, float3 location);`);
2036                 print(`native ${type}4 GatherRed(TextureCube<${type}${length}>, sampler, float3 location);`);
2037                 if (length == "2" || length == "3" || length == "4") {
2038                     print(`native ${type}4 GatherGreen(TextureCube<${type}${length}>, sampler, float3 location);`);
2039                     if (length == "3" || length == "4") {
2040                         print(`native ${type}4 GatherBlue(TextureCube<${type}${length}>, sampler, float3 location);`);
2041                         if (length == "4")
2042                             print(`native ${type}4 GatherAlpha(TextureCube<${type}${length}>, sampler, float3 location);`);
2043                     }
2044                 }
2045                 for (let addressSpace1 of [`thread`, `device`, `threadgroup`]) {
2046                     for (let addressSpace2 of [`thread`, `device`, `threadgroup`]) {
2047                         for (let addressSpace3 of [`thread`, `device`, `threadgroup`])
2048                             print(`native void GetDimensions(TextureCube<${type}${length}>, uint MipLevel, ${addressSpace1} uint* Width, ${addressSpace2} uint* Height, ${addressSpace3} uint* NumberOfLevels);`);
2049                     }
2050                 }
2051                 print();
2052                 for (let addressSpace of [`thread`, `device`, `threadgroup`]) {
2053                     print(`native void GetDimensions(RWTexture1D<${type}${length}>, ${addressSpace} uint* Width);`);
2054                     print(`native void GetDimensions(RWTexture1D<${type}${length}>, ${addressSpace} float* Width);`);
2055                 }
2056                 print(`native ${type}${length} Load(RWTexture1D<${type}${length}>, int location);`);
2057                 print(`native void Store(RWTexture1D<${type}${length}>, ${type}${length}, uint location);`);
2058                 print();
2059                 for (let addressSpace1 of [`thread`, `device`, `threadgroup`]) {
2060                     for (let addressSpace2 of [`thread`, `device`, `threadgroup`]) {
2061                         print(`native void GetDimensions(RWTexture1DArray<${type}${length}>, ${addressSpace1} uint* Width, ${addressSpace2} uint* Elements);`);
2062                         print(`native void GetDimensions(RWTexture1DArray<${type}${length}>, ${addressSpace1} float* Width, ${addressSpace2} uint* Elements);`);
2063                     }
2064                 }
2065                 print(`native ${type}${length} Load(RWTexture1DArray<${type}${length}>, int2 location);`);
2066                 print(`native void Store(RWTexture1DArray<${type}${length}>, ${type}${length}, uint2 location);`);
2067                 print();
2068                 for (let addressSpace1 of [`thread`, `device`, `threadgroup`]) {
2069                     for (let addressSpace2 of [`thread`, `device`, `threadgroup`]) {
2070                         print(`native void GetDimensions(RWTexture2D<${type}${length}>, ${addressSpace1} uint* Width, ${addressSpace2} uint* Height);`);
2071                         print(`native void GetDimensions(RWTexture2D<${type}${length}>, ${addressSpace1} float* Width, ${addressSpace2} float* Height);`);
2072                     }
2073                 }
2074                 print(`native ${type}${length} Load(RWTexture2D<${type}${length}>, int2 location);`);
2075                 print(`native void Store(RWTexture2D<${type}${length}>, ${type}${length}, uint2 location);`);
2076                 print();
2077                 for (let addressSpace1 of [`thread`, `device`, `threadgroup`]) {
2078                     for (let addressSpace2 of [`thread`, `device`, `threadgroup`]) {
2079                         for (let addressSpace3 of [`thread`, `device`, `threadgroup`]) {
2080                             print(`native void GetDimensions(RWTexture2DArray<${type}${length}>, ${addressSpace1} uint* Width, ${addressSpace2} uint* Height, ${addressSpace3} uint* Elements);`);
2081                             print(`native void GetDimensions(RWTexture2DArray<${type}${length}>, ${addressSpace1} float* Width, ${addressSpace2} float* Height, ${addressSpace3} float* Elements);`);
2082                         }
2083                     }
2084                 }
2085                 print(`native ${type}${length} Load(RWTexture2DArray<${type}${length}>, int3 location);`);
2086                 print(`native void Store(RWTexture2DArray<${type}${length}>, ${type}${length}, uint3 location);`);
2087                 print();
2088                 for (let addressSpace1 of [`thread`, `device`, `threadgroup`]) {
2089                     for (let addressSpace2 of [`thread`, `device`, `threadgroup`]) {
2090                         for (let addressSpace3 of [`thread`, `device`, `threadgroup`]) {
2091                             print(`native void GetDimensions(RWTexture3D<${type}${length}>, ${addressSpace1} uint* Width, ${addressSpace2} uint* Height, ${addressSpace3} uint* Depth);`);
2092                             print(`native void GetDimensions(RWTexture3D<${type}${length}>, ${addressSpace1} float* Width, ${addressSpace2} float* Height, ${addressSpace3} float* Depth);`);
2093                         }
2094                     }
2095                 }
2096                 print(`native ${type}${length} Load(RWTexture3D<${type}${length}>, int3 location);`);
2097                 print(`native void Store(RWTexture3D<${type}${length}>, ${type}${length}, uint3 location);`);
2098                 print();
2099             }
2100         }
2101
2102         for (let type of [`half`, `float`]) {
2103             print(`native ${type} Sample(TextureDepth2D<${type}>, sampler, float2 location);`);
2104             print(`native ${type} Sample(TextureDepth2D<${type}>, sampler, float2 location, int2 offset);`);
2105             print(`native ${type} SampleCmp(TextureDepth2D<${type}>, sampler, float2 location, ${type} CompareValue);`);
2106             print(`native ${type} SampleCmp(TextureDepth2D<${type}>, sampler, float2 location, ${type} CompareValue, int2 offset);`);
2107             print(`native ${type} SampleCmpLevelZero(TextureDepth2D<${type}>, sampler, float2 location, ${type} CompareValue);`);
2108             print(`native ${type} SampleCmpLevelZero(TextureDepth2D<${type}>, sampler, float2 location, ${type} CompareValue, int2 offset);`);
2109             print(`native ${type} SampleBias(TextureDepth2D<${type}>, sampler, float2 location, float Bias);`);
2110             print(`native ${type} SampleBias(TextureDepth2D<${type}>, sampler, float2 location, float Bias, int2 offset);`);
2111             print(`native ${type} SampleGrad(TextureDepth2D<${type}>, sampler, float2 location, float2 DDX, float2 DDY);`);
2112             print(`native ${type} SampleGrad(TextureDepth2D<${type}>, sampler, float2 location, float2 DDX, float2 DDY, int2 offset);`);
2113             print(`native ${type} SampleLevel(TextureDepth2D<${type}>, sampler, float2 location, float LOD);`);
2114             print(`native ${type} SampleLevel(TextureDepth2D<${type}>, sampler, float2 location, float LOD, int2 offset);`);
2115             print(`native ${type}4 Gather(TextureDepth2D<${type}>, sampler, float2 location);`);
2116             print(`native ${type}4 Gather(TextureDepth2D<${type}>, sampler, float2 location, int2 offset);`);
2117             print(`native ${type}4 GatherRed(TextureDepth2D<${type}>, sampler, float2 location);`);
2118             print(`native ${type}4 GatherRed(TextureDepth2D<${type}>, sampler, float2 location, int2 offset);`);
2119             print(`native ${type}4 GatherCmp(TextureDepth2D<${type}>, sampler, float2 location, float compare_value);`);
2120             print(`native ${type}4 GatherCmp(TextureDepth2D<${type}>, sampler, float2 location, float compare_value, int2 offset);`);
2121             print(`native ${type}4 GatherCmpRed(TextureDepth2D<${type}>, sampler, float2 location, float compare_value);`);
2122             print(`native ${type}4 GatherCmpRed(TextureDepth2D<${type}>, sampler, float2 location, float compare_value, int2 offset);`);
2123             print(`native ${type} Load(TextureDepth2D<${type}>, int3 location);`);
2124             print(`native ${type} Load(TextureDepth2D<${type}>, int3 location, int2 offset);`);
2125             for (let addressSpace1 of [`thread`, `device`, `threadgroup`]) {
2126                 for (let addressSpace2 of [`thread`, `device`, `threadgroup`]) {
2127                     for (let addressSpace3 of [`thread`, `device`, `threadgroup`])
2128                         print(`native void GetDimensions(TextureDepth2D<${type}>, uint MipLevel, ${addressSpace1} uint* Width, ${addressSpace2} uint* Height, ${addressSpace3} uint* NumberOfLevels);`);
2129                 }
2130             }
2131             print();
2132             print(`native ${type} Sample(TextureDepth2DArray<${type}>, sampler, float3 location);`);
2133             print(`native ${type} Sample(TextureDepth2DArray<${type}>, sampler, float3 location, int2 offset);`);
2134             print(`native ${type} SampleCmp(TextureDepth2DArray<${type}>, sampler, float3 location, ${type} CompareValue);`);
2135             print(`native ${type} SampleCmp(TextureDepth2DArray<${type}>, sampler, float3 location, ${type} CompareValue, int2 offset);`);
2136             print(`native ${type} SampleCmpLevelZero(TextureDepth2DArray<${type}>, sampler, float3 location, ${type} CompareValue);`);
2137             print(`native ${type} SampleCmpLevelZero(TextureDepth2DArray<${type}>, sampler, float3 location, ${type} CompareValue, int2 offset);`);
2138             print(`native ${type} SampleBias(TextureDepth2DArray<${type}>, sampler, float3 location, float Bias);`);
2139             print(`native ${type} SampleBias(TextureDepth2DArray<${type}>, sampler, float3 location, float Bias, int2 offset);`);
2140             print(`native ${type} SampleGrad(TextureDepth2DArray<${type}>, sampler, float3 location, float2 DDX, float2 DDY);`);
2141             print(`native ${type} SampleGrad(TextureDepth2DArray<${type}>, sampler, float3 location, float2 DDX, float2 DDY, int2 offset);`);
2142             print(`native ${type} SampleLevel(TextureDepth2DArray<${type}>, sampler, float3 location, float LOD);`);
2143             print(`native ${type} SampleLevel(TextureDepth2DArray<${type}>, sampler, float3 location, float LOD, int2 offset);`);
2144             print(`native ${type}4 Gather(TextureDepth2DArray<${type}>, sampler, float3 location);`);
2145             print(`native ${type}4 Gather(TextureDepth2DArray<${type}>, sampler, float3 location, int2 offset);`);
2146             print(`native ${type}4 GatherRed(TextureDepth2DArray<${type}>, sampler, float3 location);`);
2147             print(`native ${type}4 GatherRed(TextureDepth2DArray<${type}>, sampler, float3 location, int2 offset);`);
2148             print(`native ${type}4 GatherCmp(TextureDepth2DArray<${type}>, sampler, float3 location, float compare_value);`);
2149             print(`native ${type}4 GatherCmp(TextureDepth2DArray<${type}>, sampler, float3 location, float compare_value, int2 offset);`);
2150             print(`native ${type}4 GatherCmpRed(TextureDepth2DArray<${type}>, sampler, float3 location, float compare_value);`);
2151             print(`native ${type}4 GatherCmpRed(TextureDepth2DArray<${type}>, sampler, float3 location, float compare_value, int2 offset);`);
2152             print(`native ${type} Load(TextureDepth2DArray<${type}>, int4 location);`);
2153             print(`native ${type} Load(TextureDepth2DArray<${type}>, int4 location, int2 offset);`);
2154             for (let addressSpace1 of [`thread`, `device`, `threadgroup`]) {
2155                 for (let addressSpace2 of [`thread`, `device`, `threadgroup`]) {
2156                     for (let addressSpace3 of [`thread`, `device`, `threadgroup`]) {
2157                         for (let addressSpace4 of [`thread`, `device`, `threadgroup`])
2158                             print(`native void GetDimensions(TextureDepth2DArray<${type}>, uint MipLevel, ${addressSpace1} uint* Width, ${addressSpace2} uint* Height, ${addressSpace3} uint* Elements, ${addressSpace4} uint* NumberOfLevels);`);
2159                     }
2160                 }
2161             }
2162             print();
2163             print(`native ${type} Sample(TextureDepthCube<${type}>, sampler, float3 location);`);
2164             print(`native ${type} SampleCmp(TextureDepthCube<${type}>, sampler, float3 location, ${type} CompareValue);`);
2165             print(`native ${type} SampleCmpLevelZero(TextureDepthCube<${type}>, sampler, float3 location, ${type} CompareValue);`);
2166             print(`native ${type} SampleBias(TextureDepthCube<${type}>, sampler, float3 location, float Bias);`);
2167             print(`native ${type} SampleGrad(TextureDepthCube<${type}>, sampler, float3 location, float3 DDX, float3 DDY);`);
2168             print(`native ${type} SampleLevel(TextureDepthCube<${type}>, sampler, float3 location, float LOD);`);
2169             print(`native ${type}4 Gather(TextureDepthCube<${type}>, sampler, float3 location);`);
2170             print(`native ${type}4 GatherRed(TextureDepthCube<${type}>, sampler, float3 location);`);
2171             print(`native ${type}4 GatherCmp(TextureDepthCube<${type}>, sampler, float3 location, float compare_value);`);
2172             print(`native ${type}4 GatherCmpRed(TextureDepthCube<${type}>, sampler, float3 location, float compare_value);`);
2173             for (let addressSpace1 of [`thread`, `device`, `threadgroup`]) {
2174                 for (let addressSpace2 of [`thread`, `device`, `threadgroup`]) {
2175                     for (let addressSpace3 of [`thread`, `device`, `threadgroup`])
2176                         print(`native void GetDimensions(TextureDepthCube<${type}>, uint MipLevel, ${addressSpace1} uint* Width, ${addressSpace2} uint* Height, ${addressSpace3} uint* NumberOfLevels);`);
2177                 }
2178             }
2179             print();
2180             for (let addressSpace1 of [`thread`, `device`, `threadgroup`]) {
2181                 for (let addressSpace2 of [`thread`, `device`, `threadgroup`]) {
2182                     print(`native void GetDimensions(RWTextureDepth2D<${type}>, ${addressSpace1} uint* Width, ${addressSpace2} uint* Height);`);
2183                     print(`native void GetDimensions(RWTextureDepth2D<${type}>, ${addressSpace1} float* Width, ${addressSpace2} float* Height);`);
2184                 }
2185             }
2186             print(`native ${type} Load(RWTextureDepth2D<${type}>, int2 location);`);
2187             print(`native void Store(RWTextureDepth2D<${type}>, ${type}, uint2 location);`);
2188             print();
2189             for (let addressSpace1 of [`thread`, `device`, `threadgroup`]) {
2190                 for (let addressSpace2 of [`thread`, `device`, `threadgroup`]) {
2191                     for (let addressSpace3 of [`thread`, `device`, `threadgroup`]) {
2192                         print(`native void GetDimensions(RWTextureDepth2DArray<${type}>, ${addressSpace1} uint* Width, ${addressSpace2} uint* Height, ${addressSpace3} uint* Elements);`);
2193                         print(`native void GetDimensions(RWTextureDepth2DArray<${type}>, ${addressSpace1} float* Width, ${addressSpace2} float* Height, ${addressSpace3} float* Elements);`);
2194                     }
2195                 }
2196             }
2197             print(`native ${type} Load(RWTextureDepth2DArray<${type}>, int3 location);`);
2198             print(`native void Store(RWTextureDepth2DArray<${type}>, ${type}, uint3 location);`);
2199             print();
2200         }
2201     })();
2202     return result;
2203 })();
2204
2205 // FIXME: Once the standard library has been replaced with a new version, this comments should be removed.
2206 // This list is used to restrict the availability of vector types available in the langauge.
2207 // Permissible vector element types must appear in this list and in the standard library
2208 const VectorElementTypes = [ "bool", "uchar", "char", "ushort", "short", "uint", "int", "half", "float" ];
2209 const VectorElementSizes = [ 2, 3, 4 ];
2210
2211 function allVectorTypeNames()
2212 {
2213     const names = [];
2214     for (let elementType of VectorElementTypes) {
2215         for (let size of VectorElementSizes)
2216             names.push(`${elementType}${size}`);
2217     }
2218     return names;
2219 }