Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
1693 views
1
//
2
// Copyright 2002 The ANGLE Project Authors. All rights reserved.
3
// Use of this source code is governed by a BSD-style license that can be
4
// found in the LICENSE file.
5
//
6
7
#include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
8
9
#include "angle_gl.h"
10
#include "compiler/translator/BuiltInFunctionEmulator.h"
11
#include "compiler/translator/VersionGLSL.h"
12
#include "compiler/translator/tree_util/BuiltIn.h"
13
14
namespace sh
15
{
16
17
void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
18
sh::GLenum shaderType)
19
{
20
if (shaderType == GL_VERTEX_SHADER)
21
{
22
emu->addEmulatedFunction(BuiltInId::abs_Int1, "int abs_emu(int x) { return x * sign(x); }");
23
}
24
}
25
26
void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
27
int targetGLSLVersion)
28
{
29
// isnan() is supported since GLSL 1.3.
30
if (targetGLSLVersion < GLSL_VERSION_130)
31
return;
32
33
// !(x > 0.0 || x < 0.0 || x == 0.0) will be optimized and always equal to false.
34
emu->addEmulatedFunction(
35
BuiltInId::isnan_Float1,
36
"bool isnan_emu(float x) { return (x > 0.0 || x < 0.0) ? false : x != 0.0; }");
37
emu->addEmulatedFunction(
38
BuiltInId::isnan_Float2,
39
"bvec2 isnan_emu(vec2 x)\n"
40
"{\n"
41
" bvec2 isnan;\n"
42
" for (int i = 0; i < 2; i++)\n"
43
" {\n"
44
" isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
45
" }\n"
46
" return isnan;\n"
47
"}\n");
48
emu->addEmulatedFunction(
49
BuiltInId::isnan_Float3,
50
"bvec3 isnan_emu(vec3 x)\n"
51
"{\n"
52
" bvec3 isnan;\n"
53
" for (int i = 0; i < 3; i++)\n"
54
" {\n"
55
" isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
56
" }\n"
57
" return isnan;\n"
58
"}\n");
59
emu->addEmulatedFunction(
60
BuiltInId::isnan_Float4,
61
"bvec4 isnan_emu(vec4 x)\n"
62
"{\n"
63
" bvec4 isnan;\n"
64
" for (int i = 0; i < 4; i++)\n"
65
" {\n"
66
" isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
67
" }\n"
68
" return isnan;\n"
69
"}\n");
70
}
71
72
void InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu)
73
{
74
emu->addEmulatedFunction(BuiltInId::atan_Float1_Float1,
75
"emu_precision float atan_emu(emu_precision float y, emu_precision "
76
"float x)\n"
77
"{\n"
78
" if (x > 0.0) return atan(y / x);\n"
79
" else if (x < 0.0 && y >= 0.0) return atan(y / x) + 3.14159265;\n"
80
" else if (x < 0.0 && y < 0.0) return atan(y / x) - 3.14159265;\n"
81
" else return 1.57079632 * sign(y);\n"
82
"}\n");
83
static const std::array<TSymbolUniqueId, 4> ids = {
84
BuiltInId::atan_Float1_Float1,
85
BuiltInId::atan_Float2_Float2,
86
BuiltInId::atan_Float3_Float3,
87
BuiltInId::atan_Float4_Float4,
88
};
89
for (int dim = 2; dim <= 4; ++dim)
90
{
91
std::stringstream ss = sh::InitializeStream<std::stringstream>();
92
ss << "emu_precision vec" << dim << " atan_emu(emu_precision vec" << dim
93
<< " y, emu_precision vec" << dim << " x)\n"
94
<< "{\n"
95
" return vec"
96
<< dim << "(";
97
for (int i = 0; i < dim; ++i)
98
{
99
ss << "atan_emu(y[" << i << "], x[" << i << "])";
100
if (i < dim - 1)
101
{
102
ss << ", ";
103
}
104
}
105
ss << ");\n"
106
"}\n";
107
emu->addEmulatedFunctionWithDependency(BuiltInId::atan_Float1_Float1, ids[dim - 1],
108
ss.str().c_str());
109
}
110
}
111
112
// Emulate built-in functions missing from GLSL 1.30 and higher
113
void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu,
114
sh::GLenum shaderType,
115
int targetGLSLVersion)
116
{
117
// Emulate packUnorm2x16 and unpackUnorm2x16 (GLSL 4.10)
118
if (targetGLSLVersion < GLSL_VERSION_410)
119
{
120
// clang-format off
121
emu->addEmulatedFunction(BuiltInId::packUnorm2x16_Float2,
122
"uint packUnorm2x16_emu(vec2 v)\n"
123
"{\n"
124
" int x = int(round(clamp(v.x, 0.0, 1.0) * 65535.0));\n"
125
" int y = int(round(clamp(v.y, 0.0, 1.0) * 65535.0));\n"
126
" return uint((y << 16) | (x & 0xFFFF));\n"
127
"}\n");
128
129
emu->addEmulatedFunction(BuiltInId::unpackUnorm2x16_UInt1,
130
"vec2 unpackUnorm2x16_emu(uint u)\n"
131
"{\n"
132
" float x = float(u & 0xFFFFu) / 65535.0;\n"
133
" float y = float(u >> 16) / 65535.0;\n"
134
" return vec2(x, y);\n"
135
"}\n");
136
// clang-format on
137
}
138
139
// Emulate packSnorm2x16, packHalf2x16, unpackSnorm2x16, and unpackHalf2x16 (GLSL 4.20)
140
// by using floatBitsToInt, floatBitsToUint, intBitsToFloat, and uintBitsToFloat (GLSL 3.30).
141
if (targetGLSLVersion >= GLSL_VERSION_330 && targetGLSLVersion < GLSL_VERSION_420)
142
{
143
// clang-format off
144
emu->addEmulatedFunction(BuiltInId::packSnorm2x16_Float2,
145
"uint packSnorm2x16_emu(vec2 v)\n"
146
"{\n"
147
" #if defined(GL_ARB_shading_language_packing)\n"
148
" return packSnorm2x16(v);\n"
149
" #else\n"
150
" int x = int(round(clamp(v.x, -1.0, 1.0) * 32767.0));\n"
151
" int y = int(round(clamp(v.y, -1.0, 1.0) * 32767.0));\n"
152
" return uint((y << 16) | (x & 0xFFFF));\n"
153
" #endif\n"
154
"}\n");
155
emu->addEmulatedFunction(BuiltInId::unpackSnorm2x16_UInt1,
156
"#if !defined(GL_ARB_shading_language_packing)\n"
157
" float fromSnorm(uint x)\n"
158
" {\n"
159
" int xi = (int(x) & 0x7FFF) - (int(x) & 0x8000);\n"
160
" return clamp(float(xi) / 32767.0, -1.0, 1.0);\n"
161
" }\n"
162
"#endif\n"
163
"\n"
164
"vec2 unpackSnorm2x16_emu(uint u)\n"
165
"{\n"
166
" #if defined(GL_ARB_shading_language_packing)\n"
167
" return unpackSnorm2x16(u);\n"
168
" #else\n"
169
" uint y = (u >> 16);\n"
170
" uint x = u;\n"
171
" return vec2(fromSnorm(x), fromSnorm(y));\n"
172
" #endif\n"
173
"}\n");
174
// Functions uint f32tof16(float val) and float f16tof32(uint val) are
175
// based on the OpenGL redbook Appendix Session "Floating-Point Formats Used in OpenGL".
176
emu->addEmulatedFunction(BuiltInId::packHalf2x16_Float2,
177
"#if !defined(GL_ARB_shading_language_packing)\n"
178
" uint f32tof16(float val)\n"
179
" {\n"
180
" uint f32 = floatBitsToUint(val);\n"
181
" uint f16 = 0u;\n"
182
" uint sign = (f32 >> 16) & 0x8000u;\n"
183
" int exponent = int((f32 >> 23) & 0xFFu) - 127;\n"
184
" uint mantissa = f32 & 0x007FFFFFu;\n"
185
" if (exponent == 128)\n"
186
" {\n"
187
" // Infinity or NaN\n"
188
" // NaN bits that are masked out by 0x3FF get discarded.\n"
189
" // This can turn some NaNs to infinity, but this is allowed by the spec.\n"
190
" f16 = sign | (0x1Fu << 10);\n"
191
" f16 |= (mantissa & 0x3FFu);\n"
192
" }\n"
193
" else if (exponent > 15)\n"
194
" {\n"
195
" // Overflow - flush to Infinity\n"
196
" f16 = sign | (0x1Fu << 10);\n"
197
" }\n"
198
" else if (exponent > -15)\n"
199
" {\n"
200
" // Representable value\n"
201
" exponent += 15;\n"
202
" mantissa >>= 13;\n"
203
" f16 = sign | uint(exponent << 10) | mantissa;\n"
204
" }\n"
205
" else\n"
206
" {\n"
207
" f16 = sign;\n"
208
" }\n"
209
" return f16;\n"
210
" }\n"
211
"#endif\n"
212
"\n"
213
"uint packHalf2x16_emu(vec2 v)\n"
214
"{\n"
215
" #if defined(GL_ARB_shading_language_packing)\n"
216
" return packHalf2x16(v);\n"
217
" #else\n"
218
" uint x = f32tof16(v.x);\n"
219
" uint y = f32tof16(v.y);\n"
220
" return (y << 16) | x;\n"
221
" #endif\n"
222
"}\n");
223
emu->addEmulatedFunction(BuiltInId::unpackHalf2x16_UInt1,
224
"#if !defined(GL_ARB_shading_language_packing)\n"
225
" float f16tof32(uint val)\n"
226
" {\n"
227
" uint sign = (val & 0x8000u) << 16;\n"
228
" int exponent = int((val & 0x7C00u) >> 10);\n"
229
" uint mantissa = val & 0x03FFu;\n"
230
" float f32 = 0.0;\n"
231
" if(exponent == 0)\n"
232
" {\n"
233
" if (mantissa != 0u)\n"
234
" {\n"
235
" const float scale = 1.0 / (1 << 24);\n"
236
" f32 = scale * mantissa;\n"
237
" }\n"
238
" }\n"
239
" else if (exponent == 31)\n"
240
" {\n"
241
" return uintBitsToFloat(sign | 0x7F800000u | mantissa);\n"
242
" }\n"
243
" else\n"
244
" {\n"
245
" exponent -= 15;\n"
246
" float scale;\n"
247
" if(exponent < 0)\n"
248
" {\n"
249
" // The negative unary operator is buggy on OSX.\n"
250
" // Work around this by using abs instead.\n"
251
" scale = 1.0 / (1 << abs(exponent));\n"
252
" }\n"
253
" else\n"
254
" {\n"
255
" scale = 1 << exponent;\n"
256
" }\n"
257
" float decimal = 1.0 + float(mantissa) / float(1 << 10);\n"
258
" f32 = scale * decimal;\n"
259
" }\n"
260
"\n"
261
" if (sign != 0u)\n"
262
" {\n"
263
" f32 = -f32;\n"
264
" }\n"
265
"\n"
266
" return f32;\n"
267
" }\n"
268
"#endif\n"
269
"\n"
270
"vec2 unpackHalf2x16_emu(uint u)\n"
271
"{\n"
272
" #if defined(GL_ARB_shading_language_packing)\n"
273
" return unpackHalf2x16(u);\n"
274
" #else\n"
275
" uint y = (u >> 16);\n"
276
" uint x = u & 0xFFFFu;\n"
277
" return vec2(f16tof32(x), f16tof32(y));\n"
278
" #endif\n"
279
"}\n");
280
// clang-format on
281
}
282
}
283
284
} // namespace sh
285
286