Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/perf_tests/TextureUploadPerf.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
// TextureUploadBenchmark:
7
// Performance test for uploading texture data.
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 = 2;
24
25
struct TextureUploadParams final : public RenderTestParams
26
{
27
TextureUploadParams()
28
{
29
iterationsPerStep = kIterationsPerStep;
30
trackGpuTime = true;
31
32
baseSize = 1024;
33
subImageSize = 64;
34
35
webgl = false;
36
}
37
38
std::string story() const override;
39
40
GLsizei baseSize;
41
GLsizei subImageSize;
42
43
bool webgl;
44
};
45
46
std::ostream &operator<<(std::ostream &os, const TextureUploadParams &params)
47
{
48
os << params.backendAndStory().substr(1);
49
return os;
50
}
51
52
std::string TextureUploadParams::story() const
53
{
54
std::stringstream strstr;
55
56
strstr << RenderTestParams::story();
57
58
if (webgl)
59
{
60
strstr << "_webgl";
61
}
62
63
return strstr.str();
64
}
65
66
class TextureUploadBenchmarkBase : public ANGLERenderTest,
67
public ::testing::WithParamInterface<TextureUploadParams>
68
{
69
public:
70
TextureUploadBenchmarkBase(const char *benchmarkName);
71
72
void initializeBenchmark() override;
73
void destroyBenchmark() override;
74
75
protected:
76
void initShaders();
77
78
GLuint mProgram = 0;
79
GLint mPositionLoc = -1;
80
GLint mSamplerLoc = -1;
81
GLuint mTexture = 0;
82
std::vector<float> mTextureData;
83
};
84
85
class TextureUploadSubImageBenchmark : public TextureUploadBenchmarkBase
86
{
87
public:
88
TextureUploadSubImageBenchmark() : TextureUploadBenchmarkBase("TexSubImage")
89
{
90
addExtensionPrerequisite("GL_EXT_texture_storage");
91
92
// http://anglebug.com/6319
93
if (IsLinux() && IsIntel() &&
94
GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
95
{
96
mSkipTest = true;
97
}
98
}
99
100
void initializeBenchmark() override
101
{
102
TextureUploadBenchmarkBase::initializeBenchmark();
103
104
const auto &params = GetParam();
105
glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, params.baseSize, params.baseSize);
106
}
107
108
void drawBenchmark() override;
109
};
110
111
class TextureUploadFullMipBenchmark : public TextureUploadBenchmarkBase
112
{
113
public:
114
TextureUploadFullMipBenchmark() : TextureUploadBenchmarkBase("TextureUpload") {}
115
116
void drawBenchmark() override;
117
};
118
119
class PBOSubImageBenchmark : public TextureUploadBenchmarkBase
120
{
121
public:
122
PBOSubImageBenchmark() : TextureUploadBenchmarkBase("PBO") {}
123
124
void initializeBenchmark() override
125
{
126
TextureUploadBenchmarkBase::initializeBenchmark();
127
128
const auto &params = GetParam();
129
130
glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, params.baseSize, params.baseSize);
131
132
glGenBuffers(1, &mPBO);
133
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
134
glBufferData(GL_PIXEL_UNPACK_BUFFER, params.baseSize * params.baseSize * 4,
135
mTextureData.data(), GL_STREAM_DRAW);
136
}
137
138
void destroyBenchmark()
139
{
140
TextureUploadBenchmarkBase::destroyBenchmark();
141
glDeleteBuffers(1, &mPBO);
142
}
143
144
void drawBenchmark() override;
145
146
private:
147
GLuint mPBO;
148
};
149
150
class PBOCompressedSubImageBenchmark : public TextureUploadBenchmarkBase
151
{
152
public:
153
PBOCompressedSubImageBenchmark() : TextureUploadBenchmarkBase("PBOCompressed") {}
154
155
void initializeBenchmark() override
156
{
157
TextureUploadBenchmarkBase::initializeBenchmark();
158
159
const auto &params = GetParam();
160
161
glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, params.baseSize,
162
params.baseSize);
163
164
glGenBuffers(1, &mPBO);
165
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
166
glBufferData(GL_PIXEL_UNPACK_BUFFER, params.subImageSize * params.subImageSize / 2,
167
mTextureData.data(), GL_STREAM_DRAW);
168
}
169
170
void destroyBenchmark()
171
{
172
TextureUploadBenchmarkBase::destroyBenchmark();
173
glDeleteBuffers(1, &mPBO);
174
}
175
176
void drawBenchmark() override;
177
178
private:
179
GLuint mPBO;
180
};
181
182
TextureUploadBenchmarkBase::TextureUploadBenchmarkBase(const char *benchmarkName)
183
: ANGLERenderTest(benchmarkName, GetParam())
184
{
185
setWebGLCompatibilityEnabled(GetParam().webgl);
186
setRobustResourceInit(GetParam().webgl);
187
188
// Crashes on nvidia+d3d11. http://crbug.com/945415
189
if (GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
190
{
191
mSkipTest = true;
192
}
193
}
194
195
void TextureUploadBenchmarkBase::initializeBenchmark()
196
{
197
const auto &params = GetParam();
198
199
initShaders();
200
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
201
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
202
203
if (mIsTimestampQueryAvailable && params.webgl)
204
{
205
glRequestExtensionANGLE("GL_EXT_disjoint_timer_query");
206
}
207
208
glActiveTexture(GL_TEXTURE0);
209
glGenTextures(1, &mTexture);
210
glBindTexture(GL_TEXTURE_2D, mTexture);
211
212
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
213
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
214
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
215
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
216
217
ASSERT_TRUE(params.baseSize >= params.subImageSize);
218
mTextureData.resize(params.baseSize * params.baseSize * 4, 0.5);
219
220
ASSERT_GL_NO_ERROR();
221
}
222
223
void TextureUploadBenchmarkBase::initShaders()
224
{
225
constexpr char kVS[] = R"(attribute vec4 a_position;
226
void main()
227
{
228
gl_Position = a_position;
229
})";
230
231
constexpr char kFS[] = R"(precision mediump float;
232
uniform sampler2D s_texture;
233
void main()
234
{
235
gl_FragColor = texture2D(s_texture, vec2(0, 0));
236
})";
237
238
mProgram = CompileProgram(kVS, kFS);
239
ASSERT_NE(0u, mProgram);
240
241
mPositionLoc = glGetAttribLocation(mProgram, "a_position");
242
mSamplerLoc = glGetUniformLocation(mProgram, "s_texture");
243
glUseProgram(mProgram);
244
glUniform1i(mSamplerLoc, 0);
245
246
glDisable(GL_DEPTH_TEST);
247
248
ASSERT_GL_NO_ERROR();
249
}
250
251
void TextureUploadBenchmarkBase::destroyBenchmark()
252
{
253
glDeleteTextures(1, &mTexture);
254
glDeleteProgram(mProgram);
255
}
256
257
void TextureUploadSubImageBenchmark::drawBenchmark()
258
{
259
const auto &params = GetParam();
260
261
startGpuTimer();
262
for (unsigned int iteration = 0; iteration < params.iterationsPerStep; ++iteration)
263
{
264
glTexSubImage2D(GL_TEXTURE_2D, 0, rand() % (params.baseSize - params.subImageSize),
265
rand() % (params.baseSize - params.subImageSize), params.subImageSize,
266
params.subImageSize, GL_RGBA, GL_UNSIGNED_BYTE, mTextureData.data());
267
268
// Perform a draw just so the texture data is flushed. With the position attributes not
269
// set, a constant default value is used, resulting in a very cheap draw.
270
glDrawArrays(GL_TRIANGLES, 0, 3);
271
}
272
stopGpuTimer();
273
274
ASSERT_GL_NO_ERROR();
275
}
276
277
void TextureUploadFullMipBenchmark::drawBenchmark()
278
{
279
const auto &params = GetParam();
280
281
startGpuTimer();
282
for (size_t it = 0; it < params.iterationsPerStep; ++it)
283
{
284
// Stage data for all mips
285
GLint mip = 0;
286
for (GLsizei levelSize = params.baseSize; levelSize > 0; levelSize >>= 1)
287
{
288
glTexImage2D(GL_TEXTURE_2D, mip++, GL_RGBA, levelSize, levelSize, 0, GL_RGBA,
289
GL_UNSIGNED_BYTE, mTextureData.data());
290
}
291
292
// Perform a draw just so the texture data is flushed. With the position attributes not
293
// set, a constant default value is used, resulting in a very cheap draw.
294
glDrawArrays(GL_TRIANGLES, 0, 3);
295
}
296
stopGpuTimer();
297
298
ASSERT_GL_NO_ERROR();
299
}
300
301
void PBOSubImageBenchmark::drawBenchmark()
302
{
303
const auto &params = GetParam();
304
305
startGpuTimer();
306
for (unsigned int iteration = 0; iteration < params.iterationsPerStep; ++iteration)
307
{
308
glTexSubImage2D(GL_TEXTURE_2D, 0, rand() % (params.baseSize - params.subImageSize),
309
rand() % (params.baseSize - params.subImageSize), params.subImageSize,
310
params.subImageSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
311
312
// Perform a draw just so the texture data is flushed. With the position attributes not
313
// set, a constant default value is used, resulting in a very cheap draw.
314
glDrawArrays(GL_TRIANGLES, 0, 3);
315
}
316
stopGpuTimer();
317
318
ASSERT_GL_NO_ERROR();
319
}
320
321
void PBOCompressedSubImageBenchmark::drawBenchmark()
322
{
323
const auto &params = GetParam();
324
325
startGpuTimer();
326
for (unsigned int iteration = 0; iteration < params.iterationsPerStep; ++iteration)
327
{
328
glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, params.subImageSize, params.subImageSize,
329
GL_COMPRESSED_RGB8_ETC2,
330
params.subImageSize * params.subImageSize / 2, 0);
331
332
// Perform a draw just so the texture data is flushed. With the position attributes not
333
// set, a constant default value is used, resulting in a very cheap draw.
334
glDrawArrays(GL_TRIANGLES, 0, 3);
335
}
336
stopGpuTimer();
337
338
ASSERT_GL_NO_ERROR();
339
}
340
341
TextureUploadParams D3D11Params(bool webglCompat)
342
{
343
TextureUploadParams params;
344
params.eglParameters = egl_platform::D3D11();
345
params.webgl = webglCompat;
346
return params;
347
}
348
349
TextureUploadParams OpenGLOrGLESParams(bool webglCompat)
350
{
351
TextureUploadParams params;
352
params.eglParameters = egl_platform::OPENGL_OR_GLES();
353
params.webgl = webglCompat;
354
return params;
355
}
356
357
TextureUploadParams VulkanParams(bool webglCompat)
358
{
359
TextureUploadParams params;
360
params.eglParameters = egl_platform::VULKAN();
361
params.webgl = webglCompat;
362
return params;
363
}
364
365
TextureUploadParams VulkanPBOParams(GLsizei baseSize, GLsizei subImageSize)
366
{
367
TextureUploadParams params;
368
params.eglParameters = egl_platform::VULKAN();
369
params.webgl = false;
370
params.trackGpuTime = false;
371
params.baseSize = baseSize;
372
params.subImageSize = subImageSize;
373
return params;
374
}
375
376
TextureUploadParams ES3OpenGLPBOParams(GLsizei baseSize, GLsizei subImageSize)
377
{
378
TextureUploadParams params;
379
params.eglParameters = egl_platform::OPENGL();
380
params.majorVersion = 3;
381
params.minorVersion = 0;
382
params.webgl = false;
383
params.trackGpuTime = false;
384
params.baseSize = baseSize;
385
params.subImageSize = subImageSize;
386
return params;
387
}
388
389
} // anonymous namespace
390
391
TEST_P(TextureUploadSubImageBenchmark, Run)
392
{
393
run();
394
}
395
396
TEST_P(TextureUploadFullMipBenchmark, Run)
397
{
398
run();
399
}
400
401
TEST_P(PBOSubImageBenchmark, Run)
402
{
403
run();
404
}
405
406
TEST_P(PBOCompressedSubImageBenchmark, Run)
407
{
408
run();
409
}
410
411
using namespace params;
412
413
ANGLE_INSTANTIATE_TEST(TextureUploadSubImageBenchmark,
414
D3D11Params(false),
415
D3D11Params(true),
416
OpenGLOrGLESParams(false),
417
OpenGLOrGLESParams(true),
418
VulkanParams(false),
419
NullDevice(VulkanParams(false)),
420
VulkanParams(true));
421
422
ANGLE_INSTANTIATE_TEST(TextureUploadFullMipBenchmark,
423
D3D11Params(false),
424
D3D11Params(true),
425
OpenGLOrGLESParams(false),
426
OpenGLOrGLESParams(true),
427
VulkanParams(false),
428
VulkanParams(true));
429
430
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PBOSubImageBenchmark);
431
ANGLE_INSTANTIATE_TEST(PBOSubImageBenchmark,
432
ES3OpenGLPBOParams(1024, 128),
433
VulkanPBOParams(1024, 128));
434
435
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PBOCompressedSubImageBenchmark);
436
ANGLE_INSTANTIATE_TEST(PBOCompressedSubImageBenchmark,
437
ES3OpenGLPBOParams(128, 128),
438
VulkanPBOParams(128, 128));
439
440