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::__anon8b714af90111::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