Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/perf_tests/GenerateMipmapPerf.cpp
1693 views
1
//
2
// Copyright 2020 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
// GenerateMipmapBenchmark:
7
// Performance test for generating texture mipmaps.
8
//
9
10
#include "ANGLEPerfTest.h"
11
12
#include <iostream>
13
#include <random>
14
#include <sstream>
15
16
#include "test_utils/gl_raii.h"
17
#include "util/shader_utils.h"
18
19
using namespace angle;
20
21
namespace
22
{
23
constexpr unsigned int kIterationsPerStep = 5;
24
25
struct GenerateMipmapParams final : public RenderTestParams
26
{
27
GenerateMipmapParams()
28
{
29
iterationsPerStep = kIterationsPerStep;
30
trackGpuTime = true;
31
32
textureWidth = 1920;
33
textureHeight = 1080;
34
35
internalFormat = GL_RGBA;
36
37
webgl = false;
38
}
39
40
std::string story() const override;
41
42
GLsizei textureWidth;
43
GLsizei textureHeight;
44
45
GLenum internalFormat;
46
47
bool webgl;
48
};
49
50
std::ostream &operator<<(std::ostream &os, const GenerateMipmapParams &params)
51
{
52
return os << params.backendAndStory().substr(1);
53
}
54
55
std::string GenerateMipmapParams::story() const
56
{
57
std::stringstream strstr;
58
59
strstr << RenderTestParams::story();
60
61
if (webgl)
62
{
63
strstr << "_webgl";
64
}
65
66
if (internalFormat == GL_RGB)
67
{
68
strstr << "_rgb";
69
}
70
71
return strstr.str();
72
}
73
74
template <typename T>
75
void FillWithRandomData(T *storage)
76
{
77
for (uint8_t &u : *storage)
78
{
79
u = rand() & 0xFF;
80
}
81
}
82
83
class GenerateMipmapBenchmarkBase : public ANGLERenderTest,
84
public ::testing::WithParamInterface<GenerateMipmapParams>
85
{
86
public:
87
GenerateMipmapBenchmarkBase(const char *benchmarkName);
88
89
void initializeBenchmark() override;
90
void destroyBenchmark() override;
91
92
protected:
93
void initShaders();
94
95
GLuint mProgram = 0;
96
GLuint mTexture = 0;
97
98
std::vector<uint8_t> mTextureData;
99
};
100
101
class GenerateMipmapBenchmark : public GenerateMipmapBenchmarkBase
102
{
103
public:
104
GenerateMipmapBenchmark() : GenerateMipmapBenchmarkBase("GenerateMipmap") {}
105
106
void initializeBenchmark() override;
107
108
void drawBenchmark() override;
109
};
110
111
class GenerateMipmapWithRedefineBenchmark : public GenerateMipmapBenchmarkBase
112
{
113
public:
114
GenerateMipmapWithRedefineBenchmark()
115
: GenerateMipmapBenchmarkBase("GenerateMipmapWithRedefine")
116
{}
117
118
void drawBenchmark() override;
119
};
120
121
GenerateMipmapBenchmarkBase::GenerateMipmapBenchmarkBase(const char *benchmarkName)
122
: ANGLERenderTest(benchmarkName, GetParam())
123
{
124
setWebGLCompatibilityEnabled(GetParam().webgl);
125
setRobustResourceInit(GetParam().webgl);
126
127
// Crashes on nvidia+d3d11. http://crbug.com/945415
128
if (GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
129
{
130
mSkipTest = true;
131
}
132
133
// Fails on Windows7 NVIDIA Vulkan, presumably due to old drivers. http://crbug.com/1096510
134
if (IsWindows7() && IsNVIDIA() &&
135
GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
136
{
137
mSkipTest = true;
138
}
139
}
140
141
void GenerateMipmapBenchmarkBase::initializeBenchmark()
142
{
143
const auto &params = GetParam();
144
145
initShaders();
146
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
147
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
148
149
if (mIsTimestampQueryAvailable && params.webgl)
150
{
151
glRequestExtensionANGLE("GL_EXT_disjoint_timer_query");
152
}
153
154
glGenTextures(1, &mTexture);
155
glBindTexture(GL_TEXTURE_2D, mTexture);
156
157
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
158
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
159
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
160
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
161
162
mTextureData.resize(params.textureWidth * params.textureHeight * 4);
163
FillWithRandomData(&mTextureData);
164
165
glTexImage2D(GL_TEXTURE_2D, 0, params.internalFormat, params.textureWidth, params.textureHeight,
166
0, params.internalFormat, GL_UNSIGNED_BYTE, mTextureData.data());
167
168
// Perform a draw so the image data is flushed.
169
glDrawArrays(GL_TRIANGLES, 0, 3);
170
171
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
172
173
ASSERT_GL_NO_ERROR();
174
}
175
176
void GenerateMipmapBenchmarkBase::initShaders()
177
{
178
constexpr char kVS[] = R"(void main()
179
{
180
gl_Position = vec4(0, 0, 0, 1);
181
})";
182
183
constexpr char kFS[] = R"(precision mediump float;
184
void main()
185
{
186
gl_FragColor = vec4(0);
187
})";
188
189
mProgram = CompileProgram(kVS, kFS);
190
ASSERT_NE(0u, mProgram);
191
192
glUseProgram(mProgram);
193
194
glDisable(GL_DEPTH_TEST);
195
196
ASSERT_GL_NO_ERROR();
197
}
198
199
void GenerateMipmapBenchmarkBase::destroyBenchmark()
200
{
201
glDeleteTextures(1, &mTexture);
202
glDeleteProgram(mProgram);
203
}
204
205
void GenerateMipmapBenchmark::initializeBenchmark()
206
{
207
GenerateMipmapBenchmarkBase::initializeBenchmark();
208
209
// Generate mipmaps once so the texture doesn't need to be redefined.
210
glGenerateMipmap(GL_TEXTURE_2D);
211
212
// Perform a draw so the image data is flushed.
213
glDrawArrays(GL_TRIANGLES, 0, 3);
214
}
215
216
void GenerateMipmapBenchmark::drawBenchmark()
217
{
218
const auto &params = GetParam();
219
220
startGpuTimer();
221
for (unsigned int iteration = 0; iteration < params.iterationsPerStep; ++iteration)
222
{
223
// Slightly modify the base texture so the mipmap is definitely regenerated.
224
std::array<uint8_t, 4> randomData;
225
FillWithRandomData(&randomData);
226
227
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, params.internalFormat, GL_UNSIGNED_BYTE,
228
randomData.data());
229
230
// Generate mipmaps
231
glGenerateMipmap(GL_TEXTURE_2D);
232
233
// Perform a draw just so the texture data is flushed. With the position attributes not
234
// set, a constant default value is used, resulting in a very cheap draw.
235
glDrawArrays(GL_TRIANGLES, 0, 3);
236
}
237
stopGpuTimer();
238
239
ASSERT_GL_NO_ERROR();
240
}
241
242
void GenerateMipmapWithRedefineBenchmark::drawBenchmark()
243
{
244
const auto &params = GetParam();
245
246
// Create a new texture every time, so image redefinition happens every time.
247
GLTexture texture;
248
glBindTexture(GL_TEXTURE_2D, texture);
249
250
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
251
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
252
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
253
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
254
255
glTexImage2D(GL_TEXTURE_2D, 0, params.internalFormat, params.textureWidth, params.textureHeight,
256
0, params.internalFormat, GL_UNSIGNED_BYTE, mTextureData.data());
257
258
// Perform a draw so the image data is flushed.
259
glDrawArrays(GL_TRIANGLES, 0, 3);
260
261
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
262
263
startGpuTimer();
264
265
// Do a single iteration, otherwise the cost of redefinition is amortized.
266
ASSERT_EQ(params.iterationsPerStep, 1u);
267
268
// Generate mipmaps
269
glGenerateMipmap(GL_TEXTURE_2D);
270
271
// Perform a draw just so the texture data is flushed. With the position attributes not
272
// set, a constant default value is used, resulting in a very cheap draw.
273
glDrawArrays(GL_TRIANGLES, 0, 3);
274
275
stopGpuTimer();
276
277
ASSERT_GL_NO_ERROR();
278
}
279
280
GenerateMipmapParams D3D11Params(bool webglCompat, bool singleIteration)
281
{
282
GenerateMipmapParams params;
283
params.eglParameters = egl_platform::D3D11();
284
params.majorVersion = 3;
285
params.minorVersion = 0;
286
params.webgl = webglCompat;
287
if (singleIteration)
288
{
289
params.iterationsPerStep = 1;
290
}
291
return params;
292
}
293
294
GenerateMipmapParams OpenGLOrGLESParams(bool webglCompat, bool singleIteration)
295
{
296
GenerateMipmapParams params;
297
params.eglParameters = egl_platform::OPENGL_OR_GLES();
298
params.majorVersion = 3;
299
params.minorVersion = 0;
300
params.webgl = webglCompat;
301
if (singleIteration)
302
{
303
params.iterationsPerStep = 1;
304
}
305
return params;
306
}
307
308
GenerateMipmapParams VulkanParams(bool webglCompat, bool singleIteration, bool emulatedFormat)
309
{
310
GenerateMipmapParams params;
311
params.eglParameters = egl_platform::VULKAN();
312
params.majorVersion = 3;
313
params.minorVersion = 0;
314
params.webgl = webglCompat;
315
if (emulatedFormat)
316
{
317
params.internalFormat = GL_RGB;
318
}
319
if (singleIteration)
320
{
321
params.iterationsPerStep = 1;
322
}
323
return params;
324
}
325
326
} // anonymous namespace
327
328
TEST_P(GenerateMipmapBenchmark, Run)
329
{
330
run();
331
}
332
333
TEST_P(GenerateMipmapWithRedefineBenchmark, Run)
334
{
335
run();
336
}
337
338
using namespace params;
339
340
ANGLE_INSTANTIATE_TEST(GenerateMipmapBenchmark,
341
D3D11Params(false, false),
342
D3D11Params(true, false),
343
OpenGLOrGLESParams(false, false),
344
OpenGLOrGLESParams(true, false),
345
VulkanParams(false, false, false),
346
VulkanParams(true, false, false),
347
VulkanParams(false, false, true),
348
VulkanParams(true, false, true));
349
350
ANGLE_INSTANTIATE_TEST(GenerateMipmapWithRedefineBenchmark,
351
D3D11Params(false, true),
352
D3D11Params(true, true),
353
OpenGLOrGLESParams(false, true),
354
OpenGLOrGLESParams(true, true),
355
VulkanParams(false, true, false),
356
VulkanParams(true, true, false),
357
VulkanParams(false, true, true),
358
VulkanParams(true, true, true));
359
360