Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/perf_tests/TextureSampling.cpp
1693 views
1
//
2
// Copyright 2015 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
// TextureSamplingBenchmark:
7
// Performance test for texture sampling. The test generates a texture containing random data
8
// and then blurs it in a fragment shader using nearest neighbor sampling. The test is
9
// specifically designed to test overhead of GLSL's builtin texture*() functions that may result
10
// from how ANGLE translates them on each backend.
11
//
12
13
#include "ANGLEPerfTest.h"
14
15
#include <iostream>
16
#include <random>
17
#include <sstream>
18
19
#include "util/shader_utils.h"
20
21
using namespace angle;
22
23
namespace
24
{
25
constexpr unsigned int kIterationsPerStep = 4;
26
27
struct TextureSamplingParams final : public RenderTestParams
28
{
29
TextureSamplingParams()
30
{
31
iterationsPerStep = kIterationsPerStep;
32
33
// Common default params
34
majorVersion = 3;
35
minorVersion = 0;
36
windowWidth = 720;
37
windowHeight = 720;
38
39
numSamplers = 2;
40
textureSize = 32;
41
kernelSize = 3;
42
}
43
44
std::string story() const override;
45
unsigned int numSamplers;
46
unsigned int textureSize;
47
unsigned int kernelSize;
48
};
49
50
std::ostream &operator<<(std::ostream &os, const TextureSamplingParams &params)
51
{
52
os << params.backendAndStory().substr(1);
53
return os;
54
}
55
56
std::string TextureSamplingParams::story() const
57
{
58
std::stringstream strstr;
59
60
strstr << RenderTestParams::story() << "_" << numSamplers << "samplers";
61
62
return strstr.str();
63
}
64
65
class TextureSamplingBenchmark : public ANGLERenderTest,
66
public ::testing::WithParamInterface<TextureSamplingParams>
67
{
68
public:
69
TextureSamplingBenchmark();
70
71
void initializeBenchmark() override;
72
void destroyBenchmark() override;
73
void drawBenchmark() override;
74
75
protected:
76
void initShaders();
77
void initVertexBuffer();
78
void initTextures();
79
80
GLuint mProgram;
81
GLuint mBuffer;
82
std::vector<GLuint> mTextures;
83
};
84
85
TextureSamplingBenchmark::TextureSamplingBenchmark()
86
: ANGLERenderTest("TextureSampling", GetParam()), mProgram(0u), mBuffer(0u)
87
{}
88
89
void TextureSamplingBenchmark::initializeBenchmark()
90
{
91
const auto &params = GetParam();
92
93
// Verify "numSamplers" is within MAX_TEXTURE_IMAGE_UNITS limit
94
GLint maxTextureImageUnits;
95
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
96
97
if (params.numSamplers > static_cast<unsigned int>(maxTextureImageUnits))
98
{
99
FAIL() << "Sampler count (" << params.numSamplers << ")"
100
<< " exceeds maximum texture count: " << maxTextureImageUnits << std::endl;
101
}
102
initShaders();
103
initVertexBuffer();
104
initTextures();
105
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
106
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
107
108
ASSERT_GL_NO_ERROR();
109
}
110
111
void TextureSamplingBenchmark::initShaders()
112
{
113
const auto &params = GetParam();
114
115
std::stringstream vstrstr;
116
vstrstr << "attribute vec2 aPosition;\n"
117
"varying vec2 vTextureCoordinates;\n"
118
"void main()\n"
119
"{\n"
120
" vTextureCoordinates = (aPosition + vec2(1.0)) * 0.5;\n"
121
" gl_Position = vec4(aPosition, 0, 1.0);\n"
122
"}";
123
124
std::stringstream fstrstr;
125
fstrstr << "precision mediump float;\n"
126
"varying vec2 vTextureCoordinates;\n";
127
for (unsigned int count = 0; count < params.numSamplers; count++)
128
{
129
fstrstr << "uniform sampler2D uSampler" << count << ";\n";
130
}
131
fstrstr << "void main()\n"
132
"{\n"
133
" const float inverseTextureSize = 1.0 / "
134
<< params.textureSize
135
<< ".0;\n"
136
" vec4 colorOut = vec4(0.0, 0.0, 0.0, 1.0);\n";
137
for (unsigned int count = 0; count < params.numSamplers; count++)
138
{
139
fstrstr << " for (int x = 0; x < " << params.kernelSize
140
<< "; ++x)\n"
141
" {\n"
142
" for (int y = 0; y < "
143
<< params.kernelSize
144
<< "; ++y)\n"
145
" {\n"
146
" colorOut += texture2D(uSampler"
147
<< count
148
<< ", vTextureCoordinates + vec2(x, y) * inverseTextureSize) * 0.1;\n"
149
" }\n"
150
" }\n";
151
}
152
fstrstr << " gl_FragColor = colorOut;\n"
153
"}\n";
154
155
mProgram = CompileProgram(vstrstr.str().c_str(), fstrstr.str().c_str());
156
ASSERT_NE(0u, mProgram);
157
158
// Use the program object
159
glUseProgram(mProgram);
160
}
161
162
void TextureSamplingBenchmark::initVertexBuffer()
163
{
164
std::vector<float> vertexPositions(12);
165
{
166
// Bottom left triangle
167
vertexPositions[0] = -1.0f;
168
vertexPositions[1] = -1.0f;
169
vertexPositions[2] = 1.0f;
170
vertexPositions[3] = -1.0f;
171
vertexPositions[4] = -1.0f;
172
vertexPositions[5] = 1.0f;
173
174
// Top right triangle
175
vertexPositions[6] = -1.0f;
176
vertexPositions[7] = 1.0f;
177
vertexPositions[8] = 1.0f;
178
vertexPositions[9] = -1.0f;
179
vertexPositions[10] = 1.0f;
180
vertexPositions[11] = 1.0f;
181
}
182
183
glGenBuffers(1, &mBuffer);
184
glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
185
glBufferData(GL_ARRAY_BUFFER, vertexPositions.size() * sizeof(float), &vertexPositions[0],
186
GL_STATIC_DRAW);
187
188
GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
189
ASSERT_NE(-1, positionLocation);
190
191
glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
192
glEnableVertexAttribArray(positionLocation);
193
}
194
195
void TextureSamplingBenchmark::initTextures()
196
{
197
const auto &params = GetParam();
198
199
unsigned int dataSize = params.textureSize * params.textureSize;
200
std::vector<unsigned int> randomTextureData;
201
randomTextureData.resize(dataSize);
202
203
unsigned int pseudoRandom = 1u;
204
for (unsigned int i = 0; i < dataSize; ++i)
205
{
206
pseudoRandom = pseudoRandom * 1664525u + 1013904223u;
207
randomTextureData[i] = pseudoRandom;
208
}
209
210
mTextures.resize(params.numSamplers);
211
glGenTextures(params.numSamplers, mTextures.data());
212
for (unsigned int i = 0; i < params.numSamplers; ++i)
213
{
214
glActiveTexture(GL_TEXTURE0 + i);
215
glBindTexture(GL_TEXTURE_2D, mTextures[i]);
216
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
217
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
218
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
219
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
220
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, params.textureSize, params.textureSize, 0, GL_RGBA,
221
GL_UNSIGNED_BYTE, randomTextureData.data());
222
}
223
224
for (unsigned int count = 0; count < params.numSamplers; count++)
225
{
226
std::stringstream samplerstrstr;
227
samplerstrstr << "uSampler" << count;
228
GLint samplerLocation = glGetUniformLocation(mProgram, samplerstrstr.str().c_str());
229
ASSERT_NE(-1, samplerLocation);
230
231
glUniform1i(samplerLocation, count);
232
}
233
}
234
235
void TextureSamplingBenchmark::destroyBenchmark()
236
{
237
const auto &params = GetParam();
238
239
glDeleteProgram(mProgram);
240
glDeleteBuffers(1, &mBuffer);
241
if (!mTextures.empty())
242
{
243
glDeleteTextures(params.numSamplers, mTextures.data());
244
}
245
}
246
247
void TextureSamplingBenchmark::drawBenchmark()
248
{
249
glClear(GL_COLOR_BUFFER_BIT);
250
251
const auto &params = GetParam();
252
253
for (unsigned int it = 0; it < params.iterationsPerStep; ++it)
254
{
255
glDrawArrays(GL_TRIANGLES, 0, 6);
256
}
257
258
ASSERT_GL_NO_ERROR();
259
}
260
261
// Identical to TextureSamplingBenchmark, but enables and then disables
262
// EXT_texture_format_sRGB_override during initialization. This should force the internal texture
263
// representation to use VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, which is expected to carry a
264
// performance penalty. This penalty can be quantified by comparing the results of this test with
265
// the results from TextureSamplingBenchmark
266
class TextureSamplingMutableFormatBenchmark : public TextureSamplingBenchmark
267
{
268
public:
269
void initializeBenchmark() override;
270
271
protected:
272
void initTextures();
273
};
274
275
void TextureSamplingMutableFormatBenchmark::initializeBenchmark()
276
{
277
if (IsGLExtensionEnabled("GL_EXT_texture_format_sRGB_override"))
278
{
279
TextureSamplingBenchmark::initializeBenchmark();
280
initTextures();
281
}
282
}
283
284
void TextureSamplingMutableFormatBenchmark::initTextures()
285
{
286
TextureSamplingBenchmark::initTextures();
287
288
for (unsigned int i = 0; i < mTextures.size(); ++i)
289
{
290
glActiveTexture(GL_TEXTURE0 + i);
291
glBindTexture(GL_TEXTURE_2D, mTextures[i]);
292
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT, GL_SRGB);
293
}
294
295
// Force a state update
296
drawBenchmark();
297
298
for (unsigned int i = 0; i < mTextures.size(); ++i)
299
{
300
glActiveTexture(GL_TEXTURE0 + i);
301
glBindTexture(GL_TEXTURE_2D, mTextures[i]);
302
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT, GL_NONE);
303
}
304
}
305
306
TextureSamplingParams D3D11Params()
307
{
308
TextureSamplingParams params;
309
params.eglParameters = egl_platform::D3D11();
310
return params;
311
}
312
313
TextureSamplingParams OpenGLOrGLESParams()
314
{
315
TextureSamplingParams params;
316
params.eglParameters = egl_platform::OPENGL_OR_GLES();
317
return params;
318
}
319
320
TextureSamplingParams VulkanParams()
321
{
322
TextureSamplingParams params;
323
params.eglParameters = egl_platform::VULKAN();
324
return params;
325
}
326
327
} // anonymous namespace
328
329
TEST_P(TextureSamplingBenchmark, Run)
330
{
331
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_format_sRGB_override"));
332
run();
333
}
334
335
TEST_P(TextureSamplingMutableFormatBenchmark, Run)
336
{
337
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_format_sRGB_override"));
338
run();
339
}
340
341
ANGLE_INSTANTIATE_TEST(TextureSamplingBenchmark,
342
D3D11Params(),
343
OpenGLOrGLESParams(),
344
VulkanParams());
345
346
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureSamplingMutableFormatBenchmark);
347
ANGLE_INSTANTIATE_TEST(TextureSamplingMutableFormatBenchmark, VulkanParams());
348
349