Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/perf_tests/glmark2Benchmark.cpp
1693 views
1
//
2
// Copyright 2019 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
// glmark2Benchmark:
7
// Runs the glmark2 benchmark.
8
//
9
10
#include <gtest/gtest.h>
11
12
#include <stdio.h>
13
#include <sstream>
14
15
#include "../perf_tests/third_party/perf/perf_result_reporter.h"
16
#include "ANGLEPerfTestArgs.h"
17
#include "common/platform.h"
18
#include "common/string_utils.h"
19
#include "common/system_utils.h"
20
#include "test_utils/angle_test_configs.h"
21
#include "test_utils/angle_test_instantiate.h"
22
#include "util/test_utils.h"
23
24
using namespace angle;
25
26
namespace
27
{
28
29
struct BenchmarkInfo
30
{
31
const char *glmark2Config;
32
const char *name;
33
};
34
35
// Each glmark2 scene is individually benchmarked. If glmark2 is run without a specific benchmark,
36
// it can produce an aggregate score, which is not interesting at the moment. Adding an empty
37
// string ("") to this list will enable a test where glmark2 is run with the default scenes and the
38
// score for each test as well as the overall score is output.
39
constexpr BenchmarkInfo kBenchmarks[] = {
40
{"build:use-vbo=false", "build"},
41
{"build:use-vbo=true", "build_vbo"},
42
{"texture:texture-filter=nearest", "texture_nearest"},
43
{"texture:texture-filter=linear", "texture_linear"},
44
{"texture:texture-filter=mipmap", "texture_mipmap"},
45
{"shading:shading=gouraud", "shading_gouraud"},
46
{"shading:shading=blinn-phong-inf", "shading_blinn_phong"},
47
{"shading:shading=phong", "shading_phong"},
48
{"shading:shading=cel", "shading_cel"},
49
{"bump:bump-render=high-poly", "bump_high_poly"},
50
{"bump:bump-render=normals", "bump_normals"},
51
{"bump:bump-render=height", "bump_height"},
52
{"effect2d:kernel=0,1,0;1,-4,1;0,1,0;", "effect2d_edge"},
53
{"effect2d:kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;", "effect2d_blur"},
54
{"pulsar:light=false:quads=5:texture=false", "pulsar"},
55
{"desktop:blur-radius=5:effect=blur:passes=1:separable=true:windows=4", "desktop_blur"},
56
{"desktop:effect=shadow:windows=4", "desktop_shadow"},
57
{"buffer:columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method="
58
"map",
59
"buffer_map"},
60
{"buffer:columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method="
61
"subdata",
62
"buffer_subdata"},
63
{"buffer:columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method="
64
"map",
65
"buffer_map_interleave"},
66
{"ideas:speed=duration", "ideas"},
67
{"jellyfish", "jellyfish"},
68
{"terrain", "terrain"},
69
{"shadow", "shadow"},
70
{"refract", "refract"},
71
{"conditionals:fragment-steps=0:vertex-steps=0", "conditionals"},
72
{"conditionals:fragment-steps=5:vertex-steps=0", "conditionals_fragment"},
73
{"conditionals:fragment-steps=0:vertex-steps=5", "conditionals_vertex"},
74
{"function:fragment-complexity=low:fragment-steps=5", "function"},
75
{"function:fragment-complexity=medium:fragment-steps=5", "function_complex"},
76
{"loop:fragment-loop=false:fragment-steps=5:vertex-steps=5", "loop_no_fsloop"},
77
{"loop:fragment-steps=5:fragment-uniform=false:vertex-steps=5", "loop_no_uniform"},
78
{"loop:fragment-steps=5:fragment-uniform=true:vertex-steps=5", "loop"},
79
};
80
81
struct GLMark2TestParams : public PlatformParameters
82
{
83
BenchmarkInfo info;
84
};
85
86
std::ostream &operator<<(std::ostream &os, const GLMark2TestParams &params)
87
{
88
os << static_cast<const PlatformParameters &>(params) << "_" << params.info.name;
89
return os;
90
}
91
92
class GLMark2Benchmark : public testing::TestWithParam<GLMark2TestParams>
93
{
94
public:
95
GLMark2Benchmark()
96
{
97
switch (GetParam().getRenderer())
98
{
99
case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
100
mBackend = "d3d11";
101
break;
102
case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
103
mBackend = "gl";
104
break;
105
case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
106
mBackend = "vulkan";
107
break;
108
default:
109
break;
110
}
111
std::string story = GetParam().info.name;
112
mReporter = std::make_unique<perf_test::PerfResultReporter>("glmark2_" + mBackend, story);
113
mReporter->RegisterImportantMetric(".fps", "fps");
114
mReporter->RegisterImportantMetric(".score", "score");
115
}
116
117
void run()
118
{
119
// Only supported on Linux and Windows at the moment.
120
if (!IsLinux() && !IsWindows())
121
{
122
return;
123
}
124
125
const BenchmarkInfo benchmarkInfo = GetParam().info;
126
const char *benchmark = benchmarkInfo.glmark2Config;
127
const char *benchmarkName = benchmarkInfo.name;
128
bool completeRun = benchmark == nullptr || benchmark[0] == '\0';
129
130
Optional<std::string> cwd = GetCWD();
131
132
// Set the current working directory to the executable's, as the data path of glmark2 is
133
// set relative to that path.
134
std::string executableDir = GetExecutableDirectory();
135
SetCWD(executableDir.c_str());
136
SetEnvironmentVar("ANGLE_DEFAULT_PLATFORM", mBackend.c_str());
137
138
std::vector<const char *> args = {
139
"glmark2_angle",
140
};
141
if (OneFrame())
142
{
143
args.push_back("--validate");
144
}
145
if (!completeRun)
146
{
147
args.push_back("--benchmark");
148
args.push_back(benchmark);
149
fprintf(stderr, "Running benchmark: %s\n", benchmark);
150
}
151
args.push_back(nullptr);
152
153
ProcessHandle process(args, ProcessOutputCapture::StdoutOnly);
154
ASSERT_TRUE(process && process->started());
155
ASSERT_TRUE(process->finish());
156
157
// Restore the current working directory for the next tests.
158
if (cwd.valid())
159
{
160
SetCWD(cwd.value().c_str());
161
}
162
163
ASSERT_EQ(EXIT_SUCCESS, process->getExitCode());
164
165
if (!OneFrame())
166
{
167
std::string output = process->getStdout();
168
parseOutput(output, benchmarkName, completeRun);
169
}
170
}
171
172
private:
173
void parseOutput(const std::string &output, const char *benchmarkName, bool completeRun)
174
{
175
// Output is in the following format:
176
//
177
// =======================================================
178
// glmark2 2017.07
179
// =======================================================
180
// OpenGL Information
181
// GL_VENDOR: ...
182
// GL_RENDERER: ...
183
// GL_VERSION: ...
184
// =======================================================
185
// [test] config: FPS: uint FrameTime: float ms
186
// [test] config: Not Supported
187
// ...
188
// =======================================================
189
// glmark2 Score: uint
190
// =======================================================
191
//
192
// This function skips the header, prints one line for each test/config line where there's
193
// an FPS value, and finally prints the overall score.
194
std::istringstream glmark2Output(output);
195
std::string line;
196
197
// Forward any INFO: lines that may have been generated.
198
while (std::getline(glmark2Output, line) && BeginsWith(line, "INFO:"))
199
{
200
fprintf(stderr, "%s\n", line.c_str());
201
}
202
203
// Expect ==== at the top of the header
204
ASSERT_EQ('=', line[0]);
205
206
// Skip one line
207
std::getline(glmark2Output, line);
208
209
// Expect ==== in the middle of the header
210
std::getline(glmark2Output, line);
211
ASSERT_EQ('=', line[0]);
212
213
// Skip four lines
214
std::getline(glmark2Output, line);
215
std::getline(glmark2Output, line);
216
std::getline(glmark2Output, line);
217
std::getline(glmark2Output, line);
218
219
// The fourth line is the GL_VERSION. Expect it to include ANGLE, otherwise we are not
220
// running against ANGLE.
221
ASSERT_NE(line.find("ANGLE"), std::string::npos);
222
223
// Expect ==== at the bottom of the header
224
std::getline(glmark2Output, line);
225
ASSERT_EQ('=', line[0]);
226
227
// Read configs until the top of the footer is reached
228
while (std::getline(glmark2Output, line) && line[0] != '=')
229
{
230
// Parse the line
231
std::istringstream lin(line);
232
233
std::string testName, testConfig;
234
lin >> testName >> testConfig;
235
EXPECT_TRUE(lin);
236
237
std::string fpsTag, frametimeTag;
238
size_t fps;
239
float frametime;
240
241
lin >> fpsTag >> fps >> frametimeTag >> frametime;
242
243
// If the line is not in `FPS: uint FrameTime: Float ms` format, the test is not
244
// supported. It will be skipped.
245
if (!lin)
246
{
247
continue;
248
}
249
250
EXPECT_EQ("FPS:", fpsTag);
251
EXPECT_EQ("FrameTime:", frametimeTag);
252
253
if (!completeRun)
254
{
255
mReporter->AddResult(".fps", fps);
256
}
257
}
258
259
// Get the score line: `glmark2 Score: uint`
260
std::string glmark2Tag, scoreTag;
261
size_t score;
262
glmark2Output >> glmark2Tag >> scoreTag >> score;
263
EXPECT_TRUE(glmark2Output);
264
EXPECT_EQ("glmark2", glmark2Tag);
265
EXPECT_EQ("Score:", scoreTag);
266
267
if (completeRun)
268
{
269
mReporter->AddResult(".score", score);
270
}
271
}
272
273
std::string mBackend = "invalid";
274
std::unique_ptr<perf_test::PerfResultReporter> mReporter;
275
};
276
277
TEST_P(GLMark2Benchmark, Run)
278
{
279
run();
280
}
281
282
GLMark2TestParams CombineEGLPlatform(const GLMark2TestParams &in, EGLPlatformParameters eglParams)
283
{
284
GLMark2TestParams out = in;
285
out.eglParameters = eglParams;
286
return out;
287
}
288
289
GLMark2TestParams CombineInfo(const GLMark2TestParams &in, BenchmarkInfo info)
290
{
291
GLMark2TestParams out = in;
292
out.info = info;
293
return out;
294
}
295
296
using namespace egl_platform;
297
298
std::vector<GLMark2TestParams> gTestsWithInfo =
299
CombineWithValues({GLMark2TestParams()}, kBenchmarks, CombineInfo);
300
std::vector<EGLPlatformParameters> gEGLPlatforms = {D3D11(), OPENGLES(), VULKAN()};
301
std::vector<GLMark2TestParams> gTestsWithPlatform =
302
CombineWithValues(gTestsWithInfo, gEGLPlatforms, CombineEGLPlatform);
303
304
ANGLE_INSTANTIATE_TEST_ARRAY(GLMark2Benchmark, gTestsWithPlatform);
305
306
} // namespace
307
308