Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/perf_tests/TexturesPerf.cpp
1693 views
1
//
2
// Copyright 2016 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
// TexturesPerf:
7
// Performance test for setting texture state.
8
//
9
10
#include "ANGLEPerfTest.h"
11
12
#include <iostream>
13
#include <random>
14
#include <sstream>
15
16
#include "util/shader_utils.h"
17
18
namespace angle
19
{
20
constexpr unsigned int kIterationsPerStep = 256;
21
22
struct TexturesParams final : public RenderTestParams
23
{
24
TexturesParams()
25
{
26
iterationsPerStep = kIterationsPerStep;
27
28
// Common default params
29
majorVersion = 2;
30
minorVersion = 0;
31
windowWidth = 720;
32
windowHeight = 720;
33
34
numTextures = 8;
35
textureRebindFrequency = 5;
36
textureStateUpdateFrequency = 3;
37
textureMipCount = 8;
38
39
webgl = false;
40
}
41
42
std::string story() const override;
43
size_t numTextures;
44
size_t textureRebindFrequency;
45
size_t textureStateUpdateFrequency;
46
size_t textureMipCount;
47
48
bool webgl;
49
};
50
51
std::ostream &operator<<(std::ostream &os, const TexturesParams &params)
52
{
53
os << params.backendAndStory().substr(1);
54
return os;
55
}
56
57
std::string TexturesParams::story() const
58
{
59
std::stringstream strstr;
60
61
strstr << RenderTestParams::story();
62
strstr << "_" << numTextures << "_textures";
63
strstr << "_" << textureRebindFrequency << "_rebind";
64
strstr << "_" << textureStateUpdateFrequency << "_state";
65
strstr << "_" << textureMipCount << "_mips";
66
67
if (webgl)
68
{
69
strstr << "_webgl";
70
}
71
72
return strstr.str();
73
}
74
75
class TexturesBenchmark : public ANGLERenderTest,
76
public ::testing::WithParamInterface<TexturesParams>
77
{
78
public:
79
TexturesBenchmark();
80
81
void initializeBenchmark() override;
82
void destroyBenchmark() override;
83
void drawBenchmark() override;
84
85
private:
86
void initShaders();
87
void initTextures();
88
89
std::vector<GLuint> mTextures;
90
91
GLuint mProgram;
92
std::vector<GLuint> mUniformLocations;
93
};
94
95
TexturesBenchmark::TexturesBenchmark() : ANGLERenderTest("Textures", GetParam()), mProgram(0u)
96
{
97
setWebGLCompatibilityEnabled(GetParam().webgl);
98
setRobustResourceInit(GetParam().webgl);
99
}
100
101
void TexturesBenchmark::initializeBenchmark()
102
{
103
const auto &params = GetParam();
104
105
// Verify the uniform counts are within the limits
106
GLint maxTextureUnits;
107
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
108
if (params.numTextures > static_cast<size_t>(maxTextureUnits))
109
{
110
FAIL() << "Texture count (" << params.numTextures << ")"
111
<< " exceeds maximum texture unit count: " << maxTextureUnits << std::endl;
112
}
113
114
initShaders();
115
initTextures();
116
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
117
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
118
119
ASSERT_GL_NO_ERROR();
120
}
121
122
std::string GetUniformLocationName(size_t idx, bool vertexShader)
123
{
124
std::stringstream strstr;
125
strstr << (vertexShader ? "vs" : "fs") << "_u_" << idx;
126
return strstr.str();
127
}
128
129
void TexturesBenchmark::initShaders()
130
{
131
const auto &params = GetParam();
132
133
std::string vs =
134
"void main()\n"
135
"{\n"
136
" gl_Position = vec4(0, 0, 0, 0);\n"
137
"}\n";
138
139
std::stringstream fstrstr;
140
for (size_t i = 0; i < params.numTextures; i++)
141
{
142
fstrstr << "uniform sampler2D tex" << i << ";";
143
}
144
fstrstr << "void main()\n"
145
"{\n"
146
" gl_FragColor = vec4(0, 0, 0, 0)";
147
for (size_t i = 0; i < params.numTextures; i++)
148
{
149
fstrstr << "+ texture2D(tex" << i << ", vec2(0, 0))";
150
}
151
fstrstr << ";\n"
152
"}\n";
153
154
mProgram = CompileProgram(vs.c_str(), fstrstr.str().c_str());
155
ASSERT_NE(0u, mProgram);
156
157
for (size_t i = 0; i < params.numTextures; ++i)
158
{
159
std::stringstream uniformName;
160
uniformName << "tex" << i;
161
162
GLint location = glGetUniformLocation(mProgram, uniformName.str().c_str());
163
ASSERT_NE(-1, location);
164
mUniformLocations.push_back(location);
165
}
166
167
// Use the program object
168
glUseProgram(mProgram);
169
}
170
171
void TexturesBenchmark::initTextures()
172
{
173
const auto &params = GetParam();
174
175
size_t textureSize = static_cast<size_t>(1) << params.textureMipCount;
176
std::vector<GLubyte> textureData(textureSize * textureSize * 4);
177
for (auto &byte : textureData)
178
{
179
byte = rand() % 255u;
180
}
181
182
for (size_t texIndex = 0; texIndex < params.numTextures; texIndex++)
183
{
184
GLuint tex = 0;
185
glGenTextures(1, &tex);
186
187
glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + texIndex));
188
glBindTexture(GL_TEXTURE_2D, tex);
189
for (size_t mip = 0; mip < params.textureMipCount; mip++)
190
{
191
GLsizei levelSize = static_cast<GLsizei>(textureSize >> mip);
192
glTexImage2D(GL_TEXTURE_2D, static_cast<GLint>(mip), GL_RGBA, levelSize, levelSize, 0,
193
GL_RGBA, GL_UNSIGNED_BYTE, textureData.data());
194
}
195
mTextures.push_back(tex);
196
197
glUniform1i(mUniformLocations[texIndex], static_cast<GLint>(texIndex));
198
}
199
}
200
201
void TexturesBenchmark::destroyBenchmark()
202
{
203
glDeleteProgram(mProgram);
204
}
205
206
void TexturesBenchmark::drawBenchmark()
207
{
208
const auto &params = GetParam();
209
210
for (size_t it = 0; it < params.iterationsPerStep; ++it)
211
{
212
if (it % params.textureRebindFrequency == 0)
213
{
214
// Swap two textures
215
size_t swapTexture = (it / params.textureRebindFrequency) % (params.numTextures - 1);
216
217
glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + swapTexture));
218
glBindTexture(GL_TEXTURE_2D, mTextures[swapTexture]);
219
glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + swapTexture + 1));
220
glBindTexture(GL_TEXTURE_2D, mTextures[swapTexture + 1]);
221
std::swap(mTextures[swapTexture], mTextures[swapTexture + 1]);
222
}
223
224
if (it % params.textureStateUpdateFrequency == 0)
225
{
226
// Update a texture's state
227
size_t stateUpdateCount = it / params.textureStateUpdateFrequency;
228
229
const size_t numUpdateTextures = 4;
230
ASSERT_LE(numUpdateTextures, params.numTextures);
231
232
size_t firstTexture = stateUpdateCount % (params.numTextures - numUpdateTextures);
233
234
for (size_t updateTextureIdx = 0; updateTextureIdx < numUpdateTextures;
235
updateTextureIdx++)
236
{
237
size_t updateTexture = firstTexture + updateTextureIdx;
238
glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + updateTexture));
239
240
const GLenum minFilters[] = {
241
GL_NEAREST,
242
GL_LINEAR,
243
GL_NEAREST_MIPMAP_NEAREST,
244
GL_LINEAR_MIPMAP_NEAREST,
245
GL_NEAREST_MIPMAP_LINEAR,
246
GL_LINEAR_MIPMAP_LINEAR,
247
};
248
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
249
minFilters[stateUpdateCount % ArraySize(minFilters)]);
250
251
const GLenum magFilters[] = {
252
GL_NEAREST,
253
GL_LINEAR,
254
};
255
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
256
magFilters[stateUpdateCount % ArraySize(magFilters)]);
257
258
const GLenum wrapParameters[] = {
259
GL_CLAMP_TO_EDGE,
260
GL_REPEAT,
261
GL_MIRRORED_REPEAT,
262
};
263
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
264
wrapParameters[stateUpdateCount % ArraySize(wrapParameters)]);
265
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
266
wrapParameters[stateUpdateCount % ArraySize(wrapParameters)]);
267
}
268
}
269
270
glDrawArrays(GL_TRIANGLES, 0, 3);
271
}
272
273
ASSERT_GL_NO_ERROR();
274
}
275
276
TexturesParams D3D11Params(bool webglCompat, bool frequentUpdate)
277
{
278
TexturesParams params;
279
params.eglParameters = egl_platform::D3D11_NULL();
280
params.webgl = webglCompat;
281
if (frequentUpdate)
282
{
283
params.textureRebindFrequency = 1;
284
params.textureStateUpdateFrequency = 1;
285
}
286
return params;
287
}
288
289
TexturesParams OpenGLOrGLESParams(bool webglCompat, bool frequentUpdate)
290
{
291
TexturesParams params;
292
params.eglParameters = egl_platform::OPENGL_OR_GLES_NULL();
293
params.webgl = webglCompat;
294
if (frequentUpdate)
295
{
296
params.textureRebindFrequency = 1;
297
params.textureStateUpdateFrequency = 1;
298
}
299
return params;
300
}
301
302
TexturesParams VulkanParams(bool webglCompat, bool frequentUpdate)
303
{
304
TexturesParams params;
305
params.eglParameters = egl_platform::VULKAN_NULL();
306
params.webgl = webglCompat;
307
if (frequentUpdate)
308
{
309
params.textureRebindFrequency = 1;
310
params.textureStateUpdateFrequency = 1;
311
}
312
return params;
313
}
314
315
TEST_P(TexturesBenchmark, Run)
316
{
317
run();
318
}
319
320
ANGLE_INSTANTIATE_TEST(TexturesBenchmark,
321
D3D11Params(false, false),
322
D3D11Params(true, false),
323
D3D11Params(false, true),
324
D3D11Params(true, true),
325
OpenGLOrGLESParams(false, false),
326
OpenGLOrGLESParams(true, false),
327
OpenGLOrGLESParams(false, true),
328
OpenGLOrGLESParams(true, true),
329
VulkanParams(false, false),
330
VulkanParams(true, false),
331
VulkanParams(false, true),
332
VulkanParams(true, true));
333
} // namespace angle
334
335