Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/perf_tests/CompilerPerf.cpp
1693 views
1
//
2
// Copyright 2018 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
// CompilerPerfTest:
7
// Performance test for the shader translator. The test initializes the compiler once and then
8
// compiles the same shader repeatedly. There are different variations of the tests using
9
// different shaders.
10
//
11
12
#include "ANGLEPerfTest.h"
13
14
#include "GLSLANG/ShaderLang.h"
15
#include "compiler/translator/Compiler.h"
16
#include "compiler/translator/InitializeGlobals.h"
17
#include "compiler/translator/PoolAlloc.h"
18
19
namespace
20
{
21
22
const char *kSimpleESSL100FragSource = R"(
23
precision mediump float;
24
void main()
25
{
26
gl_FragColor = vec4(0, 1, 0, 1);
27
}
28
)";
29
30
const char *kSimpleESSL100Id = "SimpleESSL100";
31
32
const char *kSimpleESSL300FragSource = R"(#version 300 es
33
precision highp float;
34
out vec4 outColor;
35
void main()
36
{
37
outColor = vec4(0, 1, 0, 1);
38
}
39
)";
40
41
const char *kSimpleESSL300Id = "SimpleESSL300";
42
43
const char *kRealWorldESSL100FragSource = R"(precision highp float;
44
precision highp sampler2D;
45
precision highp int;
46
varying vec2 vPixelCoords; // in pixels
47
uniform int uCircleCount;
48
uniform sampler2D uCircleParameters;
49
uniform sampler2D uBrushTex;
50
void main(void)
51
{
52
float destAlpha = 0.0;
53
for (int i = 0; i < 32; ++i)
54
{
55
vec4 parameterColor = texture2D(uCircleParameters,vec2(0.25, (float(i) + 0.5) / 32.0));
56
vec2 center = parameterColor.xy;
57
float circleRadius = parameterColor.z;
58
float circleFlowAlpha = parameterColor.w;
59
vec4 parameterColor2 = texture2D(uCircleParameters,vec2(0.75, (float(i) + 0.5) / 32.0));
60
float circleRotation = parameterColor2.x;
61
vec2 centerDiff = vPixelCoords - center;
62
float radius = max(circleRadius, 0.5);
63
float flowAlpha = (circleRadius < 0.5) ? circleFlowAlpha * circleRadius * circleRadius * 4.0: circleFlowAlpha;
64
float antialiasMult = clamp((radius + 1.0 - length(centerDiff)) * 0.5, 0.0, 1.0);
65
mat2 texRotation = mat2(cos(circleRotation), -sin(circleRotation), sin(circleRotation), cos(circleRotation));
66
vec2 texCoords = texRotation * centerDiff / radius * 0.5 + 0.5;
67
float texValue = texture2D(uBrushTex, texCoords).r;
68
float circleAlpha = flowAlpha * antialiasMult * texValue;
69
if (i < uCircleCount)
70
{
71
destAlpha = clamp(circleAlpha + (1.0 - circleAlpha) * destAlpha, 0.0, 1.0);
72
}
73
}
74
gl_FragColor = vec4(0.0, 0.0, 0.0, destAlpha);
75
})";
76
77
const char *kRealWorldESSL100Id = "RealWorldESSL100";
78
79
// This shader is intended to trigger many AST transformations, particularly on the HLSL backend.
80
const char *kTrickyESSL300FragSource = R"(#version 300 es
81
precision highp float;
82
precision highp sampler2D;
83
precision highp isampler2D;
84
precision highp int;
85
86
float globalF;
87
88
uniform ivec4 uivec;
89
uniform int ui;
90
91
struct SS
92
{
93
int iField;
94
float fField;
95
vec2 f2Field;
96
sampler2D sField;
97
isampler2D isField;
98
};
99
uniform SS us;
100
101
out vec4 my_FragColor;
102
103
float[3] sideEffectArray()
104
{
105
globalF += 1.0;
106
return float[3](globalF, globalF * 2.0, globalF * 3.0);
107
}
108
109
// This struct is unused and can be pruned.
110
struct SUnused
111
{
112
vec2 fField;
113
};
114
115
void main()
116
{
117
struct S2
118
{
119
float fField;
120
} s2;
121
vec4 foo = vec4(ui);
122
mat4 fooM = mat4(foo.x);
123
124
// Some unused variables that can be pruned.
125
float fUnused, fUnused2;
126
ivec4 iUnused, iUnused2;
127
128
globalF = us.fField;
129
s2.fField = us.fField;
130
131
float[3] fa = sideEffectArray();
132
133
globalF -= us.fField;
134
if (fa == sideEffectArray())
135
{
136
globalF += us.fField * sin(2.0);
137
}
138
139
// Switch with fall-through.
140
switch (ui)
141
{
142
case 0:
143
// Sequence operator and matrix and vector dynamic indexing.
144
(globalF += 1.0, fooM[ui][ui] += fooM[ui - 1][uivec[ui] + 1]);
145
case 1:
146
// Built-in emulation.
147
foo[3] = tanh(foo[1]);
148
default:
149
// Sequence operator and length of an array expression with side effects.
150
foo[2] += (globalF -= 1.0, float((sideEffectArray()).length() * 2));
151
}
152
int i = 0;
153
do
154
{
155
s2.fField = us.fField * us.f2Field.x;
156
// Sequence operator and short-circuiting operator with side effects on the right hand side.
157
} while ((++i, i < int(us.fField) && ++i <= ui || ++i < ui * 2 - 3));
158
// Samplers in structures and integer texture sampling.
159
foo += texture(us.sField, us.f2Field) + intBitsToFloat(texture(us.isField, us.f2Field + 4.0));
160
my_FragColor = foo * s2.fField * globalF + fooM[ui];
161
})";
162
163
const char *kTrickyESSL300Id = "TrickyESSL300";
164
165
constexpr int kNumIterationsPerStep = 4;
166
167
struct CompilerParameters
168
{
169
CompilerParameters() { output = SH_HLSL_4_1_OUTPUT; }
170
171
CompilerParameters(ShShaderOutput output) : output(output) {}
172
173
const char *str() const
174
{
175
switch (output)
176
{
177
case SH_HLSL_4_1_OUTPUT:
178
return "HLSL_4_1";
179
case SH_GLSL_450_CORE_OUTPUT:
180
return "GLSL_4_50";
181
case SH_ESSL_OUTPUT:
182
return "ESSL";
183
default:
184
UNREACHABLE();
185
return "unk";
186
}
187
}
188
189
ShShaderOutput output;
190
};
191
192
bool IsPlatformAvailable(const CompilerParameters &param)
193
{
194
switch (param.output)
195
{
196
case SH_HLSL_4_1_OUTPUT:
197
case SH_HLSL_4_0_FL9_3_OUTPUT:
198
case SH_HLSL_3_0_OUTPUT:
199
{
200
angle::PoolAllocator allocator;
201
InitializePoolIndex();
202
allocator.push();
203
SetGlobalPoolAllocator(&allocator);
204
ShHandle translator =
205
sh::ConstructCompiler(GL_FRAGMENT_SHADER, SH_WEBGL2_SPEC, param.output);
206
bool success = translator != nullptr;
207
SetGlobalPoolAllocator(nullptr);
208
allocator.pop();
209
FreePoolIndex();
210
if (!success)
211
{
212
return false;
213
}
214
break;
215
}
216
default:
217
break;
218
}
219
return true;
220
}
221
222
struct CompilerPerfParameters final : public CompilerParameters
223
{
224
CompilerPerfParameters(ShShaderOutput output,
225
const char *shaderSource,
226
const char *shaderSourceId)
227
: CompilerParameters(output), shaderSource(shaderSource)
228
{
229
testId = shaderSourceId;
230
testId += "_";
231
testId += CompilerParameters::str();
232
}
233
234
const char *shaderSource;
235
std::string testId;
236
};
237
238
std::ostream &operator<<(std::ostream &stream, const CompilerPerfParameters &p)
239
{
240
stream << p.testId;
241
return stream;
242
}
243
244
class CompilerPerfTest : public ANGLEPerfTest,
245
public ::testing::WithParamInterface<CompilerPerfParameters>
246
{
247
public:
248
CompilerPerfTest();
249
250
void step() override;
251
252
void SetUp() override;
253
void TearDown() override;
254
255
protected:
256
void setTestShader(const char *str) { mTestShader = str; }
257
258
private:
259
const char *mTestShader;
260
261
ShBuiltInResources mResources;
262
angle::PoolAllocator mAllocator;
263
sh::TCompiler *mTranslator;
264
};
265
266
CompilerPerfTest::CompilerPerfTest()
267
: ANGLEPerfTest("CompilerPerf", "", GetParam().testId, kNumIterationsPerStep)
268
{}
269
270
void CompilerPerfTest::SetUp()
271
{
272
ANGLEPerfTest::SetUp();
273
274
InitializePoolIndex();
275
mAllocator.push();
276
SetGlobalPoolAllocator(&mAllocator);
277
278
const auto &params = GetParam();
279
280
mTranslator = sh::ConstructCompiler(GL_FRAGMENT_SHADER, SH_WEBGL2_SPEC, params.output);
281
sh::InitBuiltInResources(&mResources);
282
mResources.FragmentPrecisionHigh = true;
283
if (!mTranslator->Init(mResources))
284
{
285
SafeDelete(mTranslator);
286
}
287
288
setTestShader(params.shaderSource);
289
}
290
291
void CompilerPerfTest::TearDown()
292
{
293
SafeDelete(mTranslator);
294
295
SetGlobalPoolAllocator(nullptr);
296
mAllocator.pop();
297
298
FreePoolIndex();
299
300
ANGLEPerfTest::TearDown();
301
}
302
303
void CompilerPerfTest::step()
304
{
305
const char *shaderStrings[] = {mTestShader};
306
307
ShCompileOptions compileOptions = SH_OBJECT_CODE | SH_VARIABLES |
308
SH_INITIALIZE_UNINITIALIZED_LOCALS | SH_INIT_OUTPUT_VARIABLES;
309
310
#if !defined(NDEBUG)
311
// Make sure that compilation succeeds and print the info log if it doesn't in debug mode.
312
if (!mTranslator->compile(shaderStrings, 1, compileOptions))
313
{
314
std::cout << "Compiling perf test shader failed with log:\n"
315
<< mTranslator->getInfoSink().info.c_str();
316
}
317
#endif
318
319
for (unsigned int iteration = 0; iteration < kNumIterationsPerStep; ++iteration)
320
{
321
mTranslator->compile(shaderStrings, 1, compileOptions);
322
}
323
}
324
325
TEST_P(CompilerPerfTest, Run)
326
{
327
run();
328
}
329
330
ANGLE_INSTANTIATE_TEST(
331
CompilerPerfTest,
332
CompilerPerfParameters(SH_HLSL_4_1_OUTPUT, kSimpleESSL100FragSource, kSimpleESSL100Id),
333
CompilerPerfParameters(SH_HLSL_4_1_OUTPUT, kSimpleESSL300FragSource, kSimpleESSL300Id),
334
CompilerPerfParameters(SH_HLSL_4_1_OUTPUT, kRealWorldESSL100FragSource, kRealWorldESSL100Id),
335
CompilerPerfParameters(SH_HLSL_4_1_OUTPUT, kTrickyESSL300FragSource, kTrickyESSL300Id),
336
CompilerPerfParameters(SH_GLSL_450_CORE_OUTPUT, kSimpleESSL100FragSource, kSimpleESSL100Id),
337
CompilerPerfParameters(SH_GLSL_450_CORE_OUTPUT, kSimpleESSL300FragSource, kSimpleESSL300Id),
338
CompilerPerfParameters(SH_GLSL_450_CORE_OUTPUT,
339
kRealWorldESSL100FragSource,
340
kRealWorldESSL100Id),
341
CompilerPerfParameters(SH_GLSL_450_CORE_OUTPUT, kTrickyESSL300FragSource, kTrickyESSL300Id),
342
CompilerPerfParameters(SH_ESSL_OUTPUT, kSimpleESSL100FragSource, kSimpleESSL100Id),
343
CompilerPerfParameters(SH_ESSL_OUTPUT, kSimpleESSL300FragSource, kSimpleESSL300Id),
344
CompilerPerfParameters(SH_ESSL_OUTPUT, kRealWorldESSL100FragSource, kRealWorldESSL100Id),
345
CompilerPerfParameters(SH_ESSL_OUTPUT, kTrickyESSL300FragSource, kTrickyESSL300Id));
346
347
} // anonymous namespace
348
349