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