1 // GENERATED FILE - DO NOT EDIT.
2 // Generated by gen_emulated_builtin_function_tables.py using data from
3 // emulated_builtin_function_data_hlsl.json.
4 //
5 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
6 // Use of this source code is governed by a BSD-style license that can be
7 // found in the LICENSE file.
8 //
9 // emulated_builtin_functions_hlsl:
10 //   HLSL code for emulating GLSL builtin functions not present in HLSL.
11 
12 #include "compiler/translator/BuiltInFunctionEmulator.h"
13 #include "compiler/translator/tree_util/BuiltIn.h"
14 
15 namespace sh
16 {
17 
18 namespace
19 {
20 
21 struct FunctionPair
22 {
FunctionPairsh::__anon852060d30111::FunctionPair23     constexpr FunctionPair(const TSymbolUniqueId &idIn, const char *bodyIn)
24         : id(idIn.get()), body(bodyIn)
25     {}
26 
27     int id;
28     const char *body;
29 };
30 
31 constexpr FunctionPair g_hlslFunctions[] = {
32     {BuiltInId::mod_Float1_Float1,
33      "float mod_emu(float x, float y)\n"
34      "{\n"
35      "    return x - y * floor(x / y);\n"
36      "}\n"},
37     {BuiltInId::mod_Float2_Float2,
38      "float2 mod_emu(float2 x, float2 y)\n"
39      "{\n"
40      "    return x - y * floor(x / y);\n"
41      "}\n"},
42     {BuiltInId::mod_Float2_Float1,
43      "float2 mod_emu(float2 x, float y)\n"
44      "{\n"
45      "    return x - y * floor(x / y);\n"
46      "}\n"},
47     {BuiltInId::mod_Float3_Float3,
48      "float3 mod_emu(float3 x, float3 y)\n"
49      "{\n"
50      "    return x - y * floor(x / y);\n"
51      "}\n"},
52     {BuiltInId::mod_Float3_Float1,
53      "float3 mod_emu(float3 x, float y)\n"
54      "{\n"
55      "    return x - y * floor(x / y);\n"
56      "}\n"},
57     {BuiltInId::mod_Float4_Float4,
58      "float4 mod_emu(float4 x, float4 y)\n"
59      "{\n"
60      "    return x - y * floor(x / y);\n"
61      "}\n"},
62     {BuiltInId::mod_Float4_Float1,
63      "float4 mod_emu(float4 x, float y)\n"
64      "{\n"
65      "    return x - y * floor(x / y);\n"
66      "}\n"},
67     {BuiltInId::frexp_Float1_Int1,
68      "float frexp_emu(float x, out int exp)\n"
69      "{\n"
70      "    float fexp;\n"
71      "    float mantissa = frexp(abs(x), fexp) * sign(x);\n"
72      "    exp = int(fexp);\n"
73      "    return mantissa;\n"
74      "}\n"},
75     {BuiltInId::frexp_Float2_Int2,
76      "float2 frexp_emu(float2 x, out int2 exp)\n"
77      "{\n"
78      "    float2 fexp;\n"
79      "    float2 mantissa = frexp(abs(x), fexp) * sign(x);\n"
80      "    exp = int2(fexp);\n"
81      "    return mantissa;\n"
82      "}\n"},
83     {BuiltInId::frexp_Float3_Int3,
84      "float3 frexp_emu(float3 x, out int3 exp)\n"
85      "{\n"
86      "    float3 fexp;\n"
87      "    float3 mantissa = frexp(abs(x), fexp) * sign(x);\n"
88      "    exp = int3(fexp);\n"
89      "    return mantissa;\n"
90      "}\n"},
91     {BuiltInId::frexp_Float4_Int4,
92      "float4 frexp_emu(float4 x, out int4 exp)\n"
93      "{\n"
94      "    float4 fexp;\n"
95      "    float4 mantissa = frexp(abs(x), fexp) * sign(x);\n"
96      "    exp = int4(fexp);\n"
97      "    return mantissa;\n"
98      "}\n"},
99     {BuiltInId::ldexp_Float1_Int1,
100      "float ldexp_emu(float x, int exp)\n"
101      "{\n"
102      "    return ldexp(x, float(exp));\n"
103      "}\n"},
104     {BuiltInId::ldexp_Float2_Int2,
105      "float2 ldexp_emu(float2 x, int2 exp)\n"
106      "{\n"
107      "    return ldexp(x, float2(exp));\n"
108      "}\n"},
109     {BuiltInId::ldexp_Float3_Int3,
110      "float3 ldexp_emu(float3 x, int3 exp)\n"
111      "{\n"
112      "    return ldexp(x, float3(exp));\n"
113      "}\n"},
114     {BuiltInId::ldexp_Float4_Int4,
115      "float4 ldexp_emu(float4 x, int4 exp)\n"
116      "{\n"
117      "    return ldexp(x, float4(exp));\n"
118      "}\n"},
119     {BuiltInId::faceforward_Float1_Float1_Float1,
120      "float faceforward_emu(float N, float I, float Nref)\n"
121      "{\n"
122      "    if(dot(Nref, I) >= 0)\n"
123      "    {\n"
124      "        return -N;\n"
125      "    }\n"
126      "    else\n"
127      "    {\n"
128      "        return N;\n"
129      "    }\n"
130      "}\n"},
131     {BuiltInId::faceforward_Float2_Float2_Float2,
132      "float2 faceforward_emu(float2 N, float2 I, float2 Nref)\n"
133      "{\n"
134      "    if(dot(Nref, I) >= 0)\n"
135      "    {\n"
136      "        return -N;\n"
137      "    }\n"
138      "    else\n"
139      "    {\n"
140      "        return N;\n"
141      "    }\n"
142      "}\n"},
143     {BuiltInId::faceforward_Float3_Float3_Float3,
144      "float3 faceforward_emu(float3 N, float3 I, float3 Nref)\n"
145      "{\n"
146      "    if(dot(Nref, I) >= 0)\n"
147      "    {\n"
148      "        return -N;\n"
149      "    }\n"
150      "    else\n"
151      "    {\n"
152      "        return N;\n"
153      "    }\n"
154      "}\n"},
155     {BuiltInId::faceforward_Float4_Float4_Float4,
156      "float4 faceforward_emu(float4 N, float4 I, float4 Nref)\n"
157      "{\n"
158      "    if(dot(Nref, I) >= 0)\n"
159      "    {\n"
160      "        return -N;\n"
161      "    }\n"
162      "    else\n"
163      "    {\n"
164      "        return N;\n"
165      "    }\n"
166      "}\n"},
167     {BuiltInId::atan_Float1_Float1,
168      "float atan_emu(float y, float x)\n"
169      "{\n"
170      "    if(x == 0 && y == 0) x = 1;\n"
171      "    return atan2(y, x);\n"
172      "}\n"},
173     {BuiltInId::atan_Float2_Float2,
174      "float2 atan_emu(float2 y, float2 x)\n"
175      "{\n"
176      "    if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
177      "    if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
178      "    return float2(atan2(y[0], x[0]), atan2(y[1], x[1]));\n"
179      "}\n"},
180     {BuiltInId::atan_Float3_Float3,
181      "float3 atan_emu(float3 y, float3 x)\n"
182      "{\n"
183      "    if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
184      "    if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
185      "    if(x[2] == 0 && y[2] == 0) x[2] = 1;\n"
186      "    return float3(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]));\n"
187      "}\n"},
188     {BuiltInId::atan_Float4_Float4,
189      "float4 atan_emu(float4 y, float4 x)\n"
190      "{\n"
191      "    if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
192      "    if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
193      "    if(x[2] == 0 && y[2] == 0) x[2] = 1;\n"
194      "    if(x[3] == 0 && y[3] == 0) x[3] = 1;\n"
195      "    return float4(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], \n"
196      "    x[2]), atan2(y[3], x[3]));\n"
197      "}\n"},
198     {BuiltInId::asinh_Float1,
199      "float asinh_emu(in float x)\n"
200      "{\n"
201      "    return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
202      "}\n"},
203     {BuiltInId::asinh_Float2,
204      "float2 asinh_emu(in float2 x)\n"
205      "{\n"
206      "    return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
207      "}\n"},
208     {BuiltInId::asinh_Float3,
209      "float3 asinh_emu(in float3 x)\n"
210      "{\n"
211      "    return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
212      "}\n"},
213     {BuiltInId::asinh_Float4,
214      "float4 asinh_emu(in float4 x)\n"
215      "{\n"
216      "    return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
217      "}\n"},
218     {BuiltInId::acosh_Float1,
219      "float acosh_emu(in float x)\n"
220      "{\n"
221      "    return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
222      "}\n"},
223     {BuiltInId::acosh_Float2,
224      "float2 acosh_emu(in float2 x)\n"
225      "{\n"
226      "    return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
227      "}\n"},
228     {BuiltInId::acosh_Float3,
229      "float3 acosh_emu(in float3 x)\n"
230      "{\n"
231      "    return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
232      "}\n"},
233     {BuiltInId::acosh_Float4,
234      "float4 acosh_emu(in float4 x)\n"
235      "{\n"
236      "    return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
237      "}\n"},
238     {BuiltInId::atanh_Float1,
239      "float atanh_emu(in float x)\n"
240      "{\n"
241      "    return 0.5 * log((1.0 + x) / (1.0 - x));\n"
242      "}\n"},
243     {BuiltInId::atanh_Float2,
244      "float2 atanh_emu(in float2 x)\n"
245      "{\n"
246      "    return 0.5 * log((1.0 + x) / (1.0 - x));\n"
247      "}\n"},
248     {BuiltInId::atanh_Float3,
249      "float3 atanh_emu(in float3 x)\n"
250      "{\n"
251      "    return 0.5 * log((1.0 + x) / (1.0 - x));\n"
252      "}\n"},
253     {BuiltInId::atanh_Float4,
254      "float4 atanh_emu(in float4 x)\n"
255      "{\n"
256      "    return 0.5 * log((1.0 + x) / (1.0 - x));\n"
257      "}\n"},
258     {BuiltInId::roundEven_Float1,
259      "float roundEven_emu(in float x)\n"
260      "{\n"
261      "    return (frac(x) == 0.5 && trunc(x) % 2.0 == 0.0) ? trunc(x) : round(x);\n"
262      "}\n"},
263     {BuiltInId::roundEven_Float2,
264      "float2 roundEven_emu(in float2 x)\n"
265      "{\n"
266      "    float2 v;\n"
267      "    v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
268      "    v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
269      "    return v;\n"
270      "}\n"},
271     {BuiltInId::roundEven_Float3,
272      "float3 roundEven_emu(in float3 x)\n"
273      "{\n"
274      "    float3 v;\n"
275      "    v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
276      "    v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
277      "    v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);\n"
278      "    return v;\n"
279      "}\n"},
280     {BuiltInId::roundEven_Float4,
281      "float4 roundEven_emu(in float4 x)\n"
282      "{\n"
283      "    float4 v;\n"
284      "    v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
285      "    v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
286      "    v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);\n"
287      "    v[3] = (frac(x[3]) == 0.5 && trunc(x[3]) % 2.0 == 0.0) ? trunc(x[3]) : round(x[3]);\n"
288      "    return v;\n"
289      "}\n"},
290     {BuiltInId::packSnorm2x16_Float2,
291      "int webgl_toSnorm16(in float x) {\n"
292      "    return int(round(clamp(x, -1.0, 1.0) * 32767.0));\n"
293      "}\n"
294      "uint packSnorm2x16_emu(in float2 v)\n"
295      "{\n"
296      "    int x = webgl_toSnorm16(v.x);\n"
297      "    int y = webgl_toSnorm16(v.y);\n"
298      "    return (asuint(y) << 16) | (asuint(x) & 0xffffu);\n"
299      "}\n"},
300     {BuiltInId::packUnorm2x16_Float2,
301      "uint webgl_toUnorm16(in float x) {\n"
302      "    return uint(round(clamp(x, 0.0, 1.0) * 65535.0));\n"
303      "}\n"
304      "uint packUnorm2x16_emu(in float2 v)\n"
305      "{\n"
306      "    uint x = webgl_toUnorm16(v.x);\n"
307      "    uint y = webgl_toUnorm16(v.y);\n"
308      "    return (y << 16) | x;\n"
309      "}\n"},
310     {BuiltInId::packHalf2x16_Float2,
311      "uint packHalf2x16_emu(in float2 v)\n"
312      "{\n"
313      "    uint x = f32tof16(v.x);\n"
314      "    uint y = f32tof16(v.y);\n"
315      "    return (y << 16) | x;\n"
316      "}\n"},
317     {BuiltInId::unpackSnorm2x16_UInt1,
318      "float webgl_fromSnorm16(in uint x) {\n"
319      "    int xi = asint(x & 0x7fffu) - asint(x & 0x8000u);\n"
320      "    return clamp(float(xi) / 32767.0, -1.0, 1.0);\n"
321      "}\n"
322      "float2 unpackSnorm2x16_emu(in uint u)\n"
323      "{\n"
324      "    uint y = (u >> 16);\n"
325      "    uint x = u;\n"
326      "    return float2(webgl_fromSnorm16(x), webgl_fromSnorm16(y));\n"
327      "}\n"},
328     {BuiltInId::unpackUnorm2x16_UInt1,
329      "float webgl_fromUnorm16(in uint x) {\n"
330      "    return float(x) / 65535.0;\n"
331      "}\n"
332      "float2 unpackUnorm2x16_emu(in uint u)\n"
333      "{\n"
334      "    uint y = (u >> 16);\n"
335      "    uint x = u & 0xffffu;\n"
336      "    return float2(webgl_fromUnorm16(x), webgl_fromUnorm16(y));\n"
337      "}\n"},
338     {BuiltInId::unpackHalf2x16_UInt1,
339      "float2 unpackHalf2x16_emu(in uint u)\n"
340      "{\n"
341      "    uint y = (u >> 16);\n"
342      "    uint x = u & 0xffffu;\n"
343      "    return float2(f16tof32(x), f16tof32(y));\n"
344      "}\n"},
345     {BuiltInId::packSnorm4x8_Float4,
346      "int webgl_toSnorm8(in float x) {\n"
347      "    return int(round(clamp(x, -1.0, 1.0) * 127.0));\n"
348      "}\n"
349      "uint packSnorm4x8_emu(in float4 v)\n"
350      "{\n"
351      "    int x = webgl_toSnorm8(v.x);\n"
352      "    int y = webgl_toSnorm8(v.y);\n"
353      "    int z = webgl_toSnorm8(v.z);\n"
354      "    int w = webgl_toSnorm8(v.w);\n"
355      "    return ((asuint(w) & 0xffu) << 24) | ((asuint(z) & 0xffu) << 16) \n"
356      "    | ((asuint(y) & 0xffu) << 8) | (asuint(x) & 0xffu);\n"
357      "}\n"},
358     {BuiltInId::packUnorm4x8_Float4,
359      "uint webgl_toUnorm8(in float x) {\n"
360      "    return uint(round(clamp(x, 0.0, 1.0) * 255.0));\n"
361      "}\n"
362      "uint packUnorm4x8_emu(in float4 v)\n"
363      "{\n"
364      "    uint x = webgl_toUnorm8(v.x);\n"
365      "    uint y = webgl_toUnorm8(v.y);\n"
366      "    uint z = webgl_toUnorm8(v.z);\n"
367      "    uint w = webgl_toUnorm8(v.w);\n"
368      "    return (w << 24) | (z << 16) | (y << 8) | x;\n"
369      "}\n"},
370     {BuiltInId::unpackSnorm4x8_UInt1,
371      "float webgl_fromSnorm8(in uint x) {\n"
372      "    int xi = asint(x & 0x7fu) - asint(x & 0x80u);\n"
373      "    return clamp(float(xi) / 127.0, -1.0, 1.0);\n"
374      "}\n"
375      "float4 unpackSnorm4x8_emu(in uint u)\n"
376      "{\n"
377      "    uint w = (u >> 24);\n"
378      "    uint z = (u >> 16);\n"
379      "    uint y = (u >> 8);\n"
380      "    uint x = u;\n"
381      "    return float4(webgl_fromSnorm8(x), webgl_fromSnorm8(y), \n"
382      "    webgl_fromSnorm8(z), webgl_fromSnorm8(w));\n"
383      "}\n"},
384     {BuiltInId::unpackUnorm4x8_UInt1,
385      "float webgl_fromUnorm8(in uint x) {\n"
386      "    return float(x) / 255.0;\n"
387      "}\n"
388      "float4 unpackUnorm4x8_emu(in uint u)\n"
389      "{\n"
390      "    uint w = (u >> 24) & 0xffu;\n"
391      "    uint z = (u >> 16) & 0xffu;\n"
392      "    uint y = (u >> 8) & 0xffu;\n"
393      "    uint x = u & 0xffu;\n"
394      "    return float4(webgl_fromUnorm8(x), webgl_fromUnorm8(y), \n"
395      "    webgl_fromUnorm8(z), webgl_fromUnorm8(w));\n"
396      "}\n"},
397     // The matrix resulting from outer product needs to be transposed
398     // (matrices are stored as transposed to simplify element access in HLSL).
399     // So the function should return transpose(c * r) where c is a column vector
400     // and r is a row vector. This can be simplified by using the following
401     // formula:
402     // transpose(c * r) = transpose(r) * transpose(c)
403     // transpose(r) and transpose(c) are in a sense free, since to get the
404     // transpose of r, we simply can build a column matrix out of the original
405     // vector instead of a row matrix.
406     {BuiltInId::outerProduct_Float2_Float2,
407      "float2x2 outerProduct_emu(in float2 c, in float2 r)\n"
408      "{\n"
409      "    return mul(float2x1(r), float1x2(c));\n"
410      "}\n"},
411     {BuiltInId::outerProduct_Float3_Float3,
412      "float3x3 outerProduct_emu(in float3 c, in float3 r)\n"
413      "{\n"
414      "    return mul(float3x1(r), float1x3(c));\n"
415      "}\n"},
416     {BuiltInId::outerProduct_Float4_Float4,
417      "float4x4 outerProduct_emu(in float4 c, in float4 r)\n"
418      "{\n"
419      "    return mul(float4x1(r), float1x4(c));\n"
420      "}\n"},
421     {BuiltInId::outerProduct_Float3_Float2,
422      "float2x3 outerProduct_emu(in float3 c, in float2 r)\n"
423      "{\n"
424      "    return mul(float2x1(r), float1x3(c));\n"
425      "}\n"},
426     {BuiltInId::outerProduct_Float2_Float3,
427      "float3x2 outerProduct_emu(in float2 c, in float3 r)\n"
428      "{\n"
429      "    return mul(float3x1(r), float1x2(c));\n"
430      "}\n"},
431     {BuiltInId::outerProduct_Float4_Float2,
432      "float2x4 outerProduct_emu(in float4 c, in float2 r)\n"
433      "{\n"
434      "    return mul(float2x1(r), float1x4(c));\n"
435      "}\n"},
436     {BuiltInId::outerProduct_Float2_Float4,
437      "float4x2 outerProduct_emu(in float2 c, in float4 r)\n"
438      "{\n"
439      "    return mul(float4x1(r), float1x2(c));\n"
440      "}\n"},
441     {BuiltInId::outerProduct_Float4_Float3,
442      "float3x4 outerProduct_emu(in float4 c, in float3 r)\n"
443      "{\n"
444      "    return mul(float3x1(r), float1x4(c));\n"
445      "}\n"},
446     {BuiltInId::outerProduct_Float3_Float4,
447      "float4x3 outerProduct_emu(in float3 c, in float4 r)\n"
448      "{\n"
449      "    return mul(float4x1(r), float1x3(c));\n"
450      "}\n"},
451     // Remember here that the parameter matrix is actually the transpose
452     // of the matrix that we're trying to invert, and the resulting matrix
453     // should also be the transpose of the inverse.
454     // When accessing the parameter matrix with m[a][b] it can be thought of so
455     // that a is the column and b is the row of the matrix that we're inverting.
456     // We calculate the inverse as the adjugate matrix divided by the
457     // determinant of the matrix being inverted. However, as the result needs
458     // to be transposed, we actually use of the transpose of the adjugate matrix
459     // which happens to be the cofactor matrix. That's stored in 'cof'.
460     // We don't need to care about divide-by-zero since results are undefined
461     // for singular or poorly-conditioned matrices.
462     {BuiltInId::inverse_Float2x2,
463      "float2x2 inverse_emu(in float2x2 m)\n"
464      "{\n"
465      "    float2x2 cof = { m[1][1], -m[0][1], -m[1][0], m[0][0] };\n"
466      "    return cof / determinant(transpose(m));\n"
467      "}\n"},
468     // cofAB is the cofactor for column A and row B.
469     {BuiltInId::inverse_Float3x3,
470      "float3x3 inverse_emu(in float3x3 m)\n"
471      "{\n"
472      "    float cof00 = m[1][1] * m[2][2] - m[2][1] * m[1][2];\n"
473      "    float cof01 = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]);\n"
474      "    float cof02 = m[1][0] * m[2][1] - m[2][0] * m[1][1];\n"
475      "    float cof10 = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]);\n"
476      "    float cof11 = m[0][0] * m[2][2] - m[2][0] * m[0][2];\n"
477      "    float cof12 = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]);\n"
478      "    float cof20 = m[0][1] * m[1][2] - m[1][1] * m[0][2];\n"
479      "    float cof21 = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]);\n"
480      "    float cof22 = m[0][0] * m[1][1] - m[1][0] * m[0][1];\n"
481      "    float3x3 cof = { cof00, cof10, cof20, cof01, cof11, cof21, cof02, cof12, cof22 };\n"
482      "    return cof / determinant(transpose(m));\n"
483      "}\n"},
484     {BuiltInId::inverse_Float4x4,
485      "float4x4 inverse_emu(in float4x4 m)\n"
486      "{\n"
487      "    float cof00 = m[1][1] * m[2][2] * m[3][3] + m[2][1] * m[3][2] * m[1][3] + m[3][1] * \n"
488      "    m[1][2] * m[2][3]\n"
489      "     - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] - m[3][1] * m[2][2] * \n"
490      "    m[1][3];\n"
491      "    float cof01 = -(m[1][0] * m[2][2] * m[3][3] + m[2][0] * m[3][2] * m[1][3] + m[3][0] * \n"
492      "    m[1][2] * m[2][3]\n"
493      "     - m[1][0] * m[3][2] * m[2][3] - m[2][0] * m[1][2] * m[3][3] - m[3][0] * m[2][2] * \n"
494      "    m[1][3]);\n"
495      "    float cof02 = m[1][0] * m[2][1] * m[3][3] + m[2][0] * m[3][1] * m[1][3] + m[3][0] * \n"
496      "    m[1][1] * m[2][3]\n"
497      "     - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] - m[3][0] * m[2][1] * \n"
498      "    m[1][3];\n"
499      "    float cof03 = -(m[1][0] * m[2][1] * m[3][2] + m[2][0] * m[3][1] * m[1][2] + m[3][0] * \n"
500      "    m[1][1] * m[2][2]\n"
501      "     - m[1][0] * m[3][1] * m[2][2] - m[2][0] * m[1][1] * m[3][2] - m[3][0] * m[2][1] * \n"
502      "    m[1][2]);\n"
503      "    float cof10 = -(m[0][1] * m[2][2] * m[3][3] + m[2][1] * m[3][2] * m[0][3] + m[3][1] * \n"
504      "    m[0][2] * m[2][3]\n"
505      "     - m[0][1] * m[3][2] * m[2][3] - m[2][1] * m[0][2] * m[3][3] - m[3][1] * m[2][2] * \n"
506      "    m[0][3]);\n"
507      "    float cof11 = m[0][0] * m[2][2] * m[3][3] + m[2][0] * m[3][2] * m[0][3] + m[3][0] * \n"
508      "    m[0][2] * m[2][3]\n"
509      "     - m[0][0] * m[3][2] * m[2][3] - m[2][0] * m[0][2] * m[3][3] - m[3][0] * m[2][2] * \n"
510      "    m[0][3];\n"
511      "    float cof12 = -(m[0][0] * m[2][1] * m[3][3] + m[2][0] * m[3][1] * m[0][3] + m[3][0] * \n"
512      "    m[0][1] * m[2][3]\n"
513      "     - m[0][0] * m[3][1] * m[2][3] - m[2][0] * m[0][1] * m[3][3] - m[3][0] * m[2][1] * \n"
514      "    m[0][3]);\n"
515      "    float cof13 = m[0][0] * m[2][1] * m[3][2] + m[2][0] * m[3][1] * m[0][2] + m[3][0] * \n"
516      "    m[0][1] * m[2][2]\n"
517      "     - m[0][0] * m[3][1] * m[2][2] - m[2][0] * m[0][1] * m[3][2] - m[3][0] * m[2][1] * \n"
518      "    m[0][2];\n"
519      "    float cof20 = m[0][1] * m[1][2] * m[3][3] + m[1][1] * m[3][2] * m[0][3] + m[3][1] * \n"
520      "    m[0][2] * m[1][3]\n"
521      "     - m[0][1] * m[3][2] * m[1][3] - m[1][1] * m[0][2] * m[3][3] - m[3][1] * m[1][2] * \n"
522      "    m[0][3];\n"
523      "    float cof21 = -(m[0][0] * m[1][2] * m[3][3] + m[1][0] * m[3][2] * m[0][3] + m[3][0] * \n"
524      "    m[0][2] * m[1][3]\n"
525      "     - m[0][0] * m[3][2] * m[1][3] - m[1][0] * m[0][2] * m[3][3] - m[3][0] * m[1][2] * \n"
526      "    m[0][3]);\n"
527      "    float cof22 = m[0][0] * m[1][1] * m[3][3] + m[1][0] * m[3][1] * m[0][3] + m[3][0] * \n"
528      "    m[0][1] * m[1][3]\n"
529      "     - m[0][0] * m[3][1] * m[1][3] - m[1][0] * m[0][1] * m[3][3] - m[3][0] * m[1][1] * \n"
530      "    m[0][3];\n"
531      "    float cof23 = -(m[0][0] * m[1][1] * m[3][2] + m[1][0] * m[3][1] * m[0][2] + m[3][0] * \n"
532      "    m[0][1] * m[1][2]\n"
533      "     - m[0][0] * m[3][1] * m[1][2] - m[1][0] * m[0][1] * m[3][2] - m[3][0] * m[1][1] * \n"
534      "    m[0][2]);\n"
535      "    float cof30 = -(m[0][1] * m[1][2] * m[2][3] + m[1][1] * m[2][2] * m[0][3] + m[2][1] * \n"
536      "    m[0][2] * m[1][3]\n"
537      "     - m[0][1] * m[2][2] * m[1][3] - m[1][1] * m[0][2] * m[2][3] - m[2][1] * m[1][2] * \n"
538      "    m[0][3]);\n"
539      "    float cof31 = m[0][0] * m[1][2] * m[2][3] + m[1][0] * m[2][2] * m[0][3] + m[2][0] * \n"
540      "    m[0][2] * m[1][3]\n"
541      "     - m[0][0] * m[2][2] * m[1][3] - m[1][0] * m[0][2] * m[2][3] - m[2][0] * m[1][2] * \n"
542      "    m[0][3];\n"
543      "    float cof32 = -(m[0][0] * m[1][1] * m[2][3] + m[1][0] * m[2][1] * m[0][3] + m[2][0] * \n"
544      "    m[0][1] * m[1][3]\n"
545      "     - m[0][0] * m[2][1] * m[1][3] - m[1][0] * m[0][1] * m[2][3] - m[2][0] * m[1][1] * \n"
546      "    m[0][3]);\n"
547      "    float cof33 = m[0][0] * m[1][1] * m[2][2] + m[1][0] * m[2][1] * m[0][2] + m[2][0] * \n"
548      "    m[0][1] * m[1][2]\n"
549      "     - m[0][0] * m[2][1] * m[1][2] - m[1][0] * m[0][1] * m[2][2] - m[2][0] * m[1][1] * \n"
550      "    m[0][2];\n"
551      "    float4x4 cof = { cof00, cof10, cof20, cof30, cof01, cof11, cof21, cof31,\n"
552      "     cof02, cof12, cof22, cof32, cof03, cof13, cof23, cof33 };\n"
553      "    return cof / determinant(transpose(m));\n"
554      "}\n"},
555     // Emulate ESSL3 variant of mix that takes last argument as boolean vector.
556     // genType mix(genType x, genType y, genBType a): Selects which vector each returned component
557     // comes from. For a component of 'a' that is false, the corresponding component of 'x' is
558     // returned. For a component of 'a' that is true, the corresponding component of 'y' is
559     // returned.
560     {BuiltInId::mix_Float1_Float1_Bool1,
561      "float mix_emu(float x, float y, bool a)\n"
562      "{\n"
563      "    return a ? y : x;\n"
564      "}\n"},
565     {BuiltInId::mix_Float2_Float2_Bool2,
566      "float2 mix_emu(float2 x, float2 y, bool2 a)\n"
567      "{\n"
568      "    return a ? y : x;\n"
569      "}\n"},
570     {BuiltInId::mix_Float3_Float3_Bool3,
571      "float3 mix_emu(float3 x, float3 y, bool3 a)\n"
572      "{\n"
573      "    return a ? y : x;\n"
574      "}\n"},
575     {BuiltInId::mix_Float4_Float4_Bool4,
576      "float4 mix_emu(float4 x, float4 y, bool4 a)\n"
577      "{\n"
578      "    return a ? y : x;\n"
579      "}\n"},
580     {BuiltInId::bitfieldExtract_UInt1_Int1_Int1,
581      "uint bitfieldExtract_emu(uint value, int offset, int bits)\n"
582      "{\n"
583      "    if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
584      "    {\n"
585      "        return 0u;\n"
586      "    }\n"
587      "    uint maskMsb = (1u << (bits - 1));\n"
588      "    uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
589      "    return (value & mask) >> offset;\n"
590      "}\n"},
591     {BuiltInId::bitfieldExtract_UInt2_Int1_Int1,
592      "uint2 bitfieldExtract_emu(uint2 value, int offset, int bits)\n"
593      "{\n"
594      "    if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
595      "    {\n"
596      "        return uint2(0u, 0u);\n"
597      "    }\n"
598      "    uint maskMsb = (1u << (bits - 1));\n"
599      "    uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
600      "    return (value & mask) >> offset;\n"
601      "}\n"},
602     {BuiltInId::bitfieldExtract_UInt3_Int1_Int1,
603      "uint3 bitfieldExtract_emu(uint3 value, int offset, int bits)\n"
604      "{\n"
605      "    if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
606      "    {\n"
607      "        return uint3(0u, 0u, 0u);\n"
608      "    }\n"
609      "    uint maskMsb = (1u << (bits - 1));\n"
610      "    uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
611      "    return (value & mask) >> offset;\n"
612      "}\n"},
613     {BuiltInId::bitfieldExtract_UInt4_Int1_Int1,
614      "uint4 bitfieldExtract_emu(uint4 value, int offset, int bits)\n"
615      "{\n"
616      "    if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
617      "    {\n"
618      "        return uint4(0u, 0u, 0u, 0u);\n"
619      "    }\n"
620      "    uint maskMsb = (1u << (bits - 1));\n"
621      "    uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
622      "    return (value & mask) >> offset;\n"
623      "}\n"},
624     {BuiltInId::bitfieldExtract_Int1_Int1_Int1,
625      "int bitfieldExtract_emu(int value, int offset, int bits)\n"
626      "{\n"
627      "    if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
628      "    {\n"
629      "        return 0;\n"
630      "    }\n"
631      "    uint maskMsb = (1u << (bits - 1));\n"
632      "    uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
633      "    uint resultUnsigned = (asuint(value) & mask) >> offset;\n"
634      "    if (bits != 32 && (resultUnsigned & maskMsb) != 0)\n"
635      "    {\n"
636      "        uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;\n"
637      "        resultUnsigned |= higherBitsMask;\n"
638      "    }\n"
639      "    return asint(resultUnsigned);\n"
640      "}\n"},
641     {BuiltInId::bitfieldExtract_Int2_Int1_Int1,
642      "int2 bitfieldExtract_emu(int2 value, int offset, int bits)\n"
643      "{\n"
644      "    if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
645      "    {\n"
646      "        return int2(0, 0);\n"
647      "    }\n"
648      "    uint maskMsb = (1u << (bits - 1));\n"
649      "    uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
650      "    uint2 resultUnsigned = (asuint(value) & mask) >> offset;\n"
651      "    if (bits != 32)\n"
652      "    {\n"
653      "        uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;\n"
654      "        resultUnsigned |= ((resultUnsigned & maskMsb) >> (bits - 1)) * higherBitsMask;\n"
655      "    }\n"
656      "    return asint(resultUnsigned);\n"
657      "}\n"},
658     {BuiltInId::bitfieldExtract_Int3_Int1_Int1,
659      "int3 bitfieldExtract_emu(int3 value, int offset, int bits)\n"
660      "{\n"
661      "    if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
662      "    {\n"
663      "        return int3(0, 0, 0);\n"
664      "    }\n"
665      "    uint maskMsb = (1u << (bits - 1));\n"
666      "    uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
667      "    uint3 resultUnsigned = (asuint(value) & mask) >> offset;\n"
668      "    if (bits != 32)\n"
669      "    {\n"
670      "        uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;\n"
671      "        resultUnsigned |= ((resultUnsigned & maskMsb) >> (bits - 1)) * higherBitsMask;\n"
672      "    }\n"
673      "    return asint(resultUnsigned);\n"
674      "}\n"},
675     {BuiltInId::bitfieldExtract_Int4_Int1_Int1,
676      "int4 bitfieldExtract_emu(int4 value, int offset, int bits)\n"
677      "{\n"
678      "    if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
679      "    {\n"
680      "        return int4(0, 0, 0, 0);\n"
681      "    }\n"
682      "    uint maskMsb = (1u << (bits - 1));\n"
683      "    uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
684      "    uint4 resultUnsigned = (asuint(value) & mask) >> offset;\n"
685      "    if (bits != 32)\n"
686      "    {\n"
687      "        uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;\n"
688      "        resultUnsigned |= ((resultUnsigned & maskMsb) >> (bits - 1)) * higherBitsMask;\n"
689      "    }\n"
690      "    return asint(resultUnsigned);\n"
691      "}\n"},
692     {BuiltInId::bitfieldInsert_UInt1_UInt1_Int1_Int1,
693      "uint bitfieldInsert_emu(uint base, uint insert, int offset, int bits)\n"
694      "{\n"
695      "    if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
696      "    {\n"
697      "        return base;\n"
698      "    }\n"
699      "    uint maskMsb = (1u << (bits - 1));\n"
700      "    uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
701      "    uint baseMask = ~insertMask;\n"
702      "    return (base & baseMask) | ((insert << offset) & insertMask);\n"
703      "}\n"},
704     {BuiltInId::bitfieldInsert_UInt2_UInt2_Int1_Int1,
705      "uint2 bitfieldInsert_emu(uint2 base, uint2 insert, int offset, int bits)\n"
706      "{\n"
707      "    if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
708      "    {\n"
709      "        return base;\n"
710      "    }\n"
711      "    uint maskMsb = (1u << (bits - 1));\n"
712      "    uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
713      "    uint baseMask = ~insertMask;\n"
714      "    return (base & baseMask) | ((insert << offset) & insertMask);\n"
715      "}\n"},
716     {BuiltInId::bitfieldInsert_UInt3_UInt3_Int1_Int1,
717      "uint3 bitfieldInsert_emu(uint3 base, uint3 insert, int offset, int bits)\n"
718      "{\n"
719      "    if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
720      "    {\n"
721      "        return base;\n"
722      "    }\n"
723      "    uint maskMsb = (1u << (bits - 1));\n"
724      "    uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
725      "    uint baseMask = ~insertMask;\n"
726      "    return (base & baseMask) | ((insert << offset) & insertMask);\n"
727      "}\n"},
728     {BuiltInId::bitfieldInsert_UInt4_UInt4_Int1_Int1,
729      "uint4 bitfieldInsert_emu(uint4 base, uint4 insert, int offset, int bits)\n"
730      "{\n"
731      "    if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
732      "    {\n"
733      "        return base;\n"
734      "    }\n"
735      "    uint maskMsb = (1u << (bits - 1));\n"
736      "    uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
737      "    uint baseMask = ~insertMask;\n"
738      "    return (base & baseMask) | ((insert << offset) & insertMask);\n"
739      "}\n"},
740     {BuiltInId::bitfieldInsert_Int1_Int1_Int1_Int1,
741      "int bitfieldInsert_emu(int base, int insert, int offset, int bits)\n"
742      "{\n"
743      "    if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
744      "    {\n"
745      "        return base;\n"
746      "    }\n"
747      "    uint maskMsb = (1u << (bits - 1));\n"
748      "    uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
749      "    uint baseMask = ~insertMask;\n"
750      "    uint resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & \n"
751      "                           insertMask);\n"
752      "    return asint(resultUnsigned);\n"
753      "}\n"},
754     {BuiltInId::bitfieldInsert_Int2_Int2_Int1_Int1,
755      "int2 bitfieldInsert_emu(int2 base, int2 insert, int offset, int bits)\n"
756      "{\n"
757      "    if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
758      "    {\n"
759      "        return base;\n"
760      "    }\n"
761      "    uint maskMsb = (1u << (bits - 1));\n"
762      "    uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
763      "    uint baseMask = ~insertMask;\n"
764      "    uint2 resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & \n"
765      "                            insertMask);\n"
766      "    return asint(resultUnsigned);\n"
767      "}\n"},
768     {BuiltInId::bitfieldInsert_Int3_Int3_Int1_Int1,
769      "int3 bitfieldInsert_emu(int3 base, int3 insert, int offset, int bits)\n"
770      "{\n"
771      "    if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
772      "    {\n"
773      "        return base;\n"
774      "    }\n"
775      "    uint maskMsb = (1u << (bits - 1));\n"
776      "    uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
777      "    uint baseMask = ~insertMask;\n"
778      "    uint3 resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & \n"
779      "                            insertMask);\n"
780      "    return asint(resultUnsigned);\n"
781      "}\n"},
782     {BuiltInId::bitfieldInsert_Int4_Int4_Int1_Int1,
783      "int4 bitfieldInsert_emu(int4 base, int4 insert, int offset, int bits)\n"
784      "{\n"
785      "    if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
786      "    {\n"
787      "        return base;\n"
788      "    }\n"
789      "    uint maskMsb = (1u << (bits - 1));\n"
790      "    uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
791      "    uint baseMask = ~insertMask;\n"
792      "    uint4 resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & \n"
793      "    insertMask);\n"
794      "    return asint(resultUnsigned);\n"
795      "}\n"},
796     {BuiltInId::uaddCarry_UInt1_UInt1_UInt1,
797      "uint uaddCarry_emu(uint x, uint y, out uint carry)\n"
798      "{\n"
799      "    carry = uint(x > (0xffffffffu - y));\n"
800      "    return x + y;\n"
801      "}\n"},
802     {BuiltInId::uaddCarry_UInt2_UInt2_UInt2,
803      "uint2 uaddCarry_emu(uint2 x, uint2 y, out uint2 carry)\n"
804      "{\n"
805      "    carry = uint2(x > (0xffffffffu - y));\n"
806      "    return x + y;\n"
807      "}\n"},
808     {BuiltInId::uaddCarry_UInt3_UInt3_UInt3,
809      "uint3 uaddCarry_emu(uint3 x, uint3 y, out uint3 carry)\n"
810      "{\n"
811      "    carry = uint3(x > (0xffffffffu - y));\n"
812      "    return x + y;\n"
813      "}\n"},
814     {BuiltInId::uaddCarry_UInt4_UInt4_UInt4,
815      "uint4 uaddCarry_emu(uint4 x, uint4 y, out uint4 carry)\n"
816      "{\n"
817      "    carry = uint4(x > (0xffffffffu - y));\n"
818      "    return x + y;\n"
819      "}\n"},
820     {BuiltInId::usubBorrow_UInt1_UInt1_UInt1,
821      "uint usubBorrow_emu(uint x, uint y, out uint borrow)\n"
822      "{\n"
823      "    borrow = uint(x < y);\n"
824      "    return x - y;\n"
825      "}\n"},
826     {BuiltInId::usubBorrow_UInt2_UInt2_UInt2,
827      "uint2 usubBorrow_emu(uint2 x, uint2 y, out uint2 borrow)\n"
828      "{\n"
829      "    borrow = uint2(x < y);\n"
830      "    return x - y;\n"
831      "}\n"},
832     {BuiltInId::usubBorrow_UInt3_UInt3_UInt3,
833      "uint3 usubBorrow_emu(uint3 x, uint3 y, out uint3 borrow)\n"
834      "{\n"
835      "    borrow = uint3(x < y);\n"
836      "    return x - y;\n"
837      "}\n"},
838     {BuiltInId::usubBorrow_UInt4_UInt4_UInt4,
839      "uint4 usubBorrow_emu(uint4 x, uint4 y, out uint4 borrow)\n"
840      "{\n"
841      "    borrow = uint4(x < y);\n"
842      "    return x - y;\n"
843      "}\n"},
844     // We emulate tanh just to avoid overflow on large arguments.
845     {BuiltInId::tanh_Float1,
846      "float tanh_emu(float x)\n"
847      "{\n"
848      "    return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
849      "}\n"},
850     {BuiltInId::tanh_Float2,
851      "float2 tanh_emu(float2 x)\n"
852      "{\n"
853      "    return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
854      "}\n"},
855     {BuiltInId::tanh_Float3,
856      "float3 tanh_emu(float3 x)\n"
857      "{\n"
858      "    return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
859      "}\n"},
860     {BuiltInId::tanh_Float4,
861      "float4 tanh_emu(float4 x)\n"
862      "{\n"
863      "    return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
864      "}\n"},
865 };
866 }  // anonymous namespace
867 
FindHLSLFunction(int uniqueId)868 const char *FindHLSLFunction(int uniqueId)
869 {
870     for (size_t index = 0; index < ArraySize(g_hlslFunctions); ++index)
871     {
872         const auto &function = g_hlslFunctions[index];
873         if (function.id == uniqueId)
874         {
875             return function.body;
876         }
877     }
878 
879     return nullptr;
880 }
881 }  // namespace sh
882