Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/perf_tests/InstancingPerf.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
// InstancingPerf:
7
// Performance tests for ANGLE instanced draw calls.
8
//
9
10
#include "ANGLEPerfTest.h"
11
12
#include <cmath>
13
#include <sstream>
14
15
#include "util/Matrix.h"
16
#include "util/random_utils.h"
17
#include "util/shader_utils.h"
18
19
using namespace angle;
20
using namespace egl_platform;
21
22
namespace
23
{
24
25
float AnimationSignal(float t)
26
{
27
float l = t / 2.0f;
28
float f = l - std::floor(l);
29
return (f > 0.5f ? 1.0f - f : f) * 4.0f - 1.0f;
30
}
31
32
template <typename T>
33
size_t VectorSizeBytes(const std::vector<T> &vec)
34
{
35
return sizeof(T) * vec.size();
36
}
37
38
Vector3 RandomVector3(RNG *rng)
39
{
40
return Vector3(rng->randomNegativeOneToOne(), rng->randomNegativeOneToOne(),
41
rng->randomNegativeOneToOne());
42
}
43
44
struct InstancingPerfParams final : public RenderTestParams
45
{
46
// Common default options
47
InstancingPerfParams()
48
{
49
majorVersion = 2;
50
minorVersion = 0;
51
windowWidth = 256;
52
windowHeight = 256;
53
iterationsPerStep = 1;
54
runTimeSeconds = 10.0;
55
animationEnabled = false;
56
instancingEnabled = true;
57
}
58
59
std::string story() const override
60
{
61
std::stringstream strstr;
62
63
strstr << RenderTestParams::story();
64
65
if (!instancingEnabled)
66
{
67
strstr << "_billboards";
68
}
69
70
return strstr.str();
71
}
72
73
double runTimeSeconds;
74
bool animationEnabled;
75
bool instancingEnabled;
76
};
77
78
std::ostream &operator<<(std::ostream &os, const InstancingPerfParams &params)
79
{
80
os << params.backendAndStory().substr(1);
81
return os;
82
}
83
84
class InstancingPerfBenchmark : public ANGLERenderTest,
85
public ::testing::WithParamInterface<InstancingPerfParams>
86
{
87
public:
88
InstancingPerfBenchmark();
89
90
void initializeBenchmark() override;
91
void destroyBenchmark() override;
92
void drawBenchmark() override;
93
94
private:
95
GLuint mProgram;
96
std::vector<GLuint> mBuffers;
97
GLuint mNumPoints;
98
std::vector<Vector3> mTranslateData;
99
std::vector<float> mSizeData;
100
std::vector<Vector3> mColorData;
101
angle::RNG mRNG;
102
};
103
104
InstancingPerfBenchmark::InstancingPerfBenchmark()
105
: ANGLERenderTest("InstancingPerf", GetParam()), mProgram(0), mNumPoints(75000)
106
{}
107
108
void InstancingPerfBenchmark::initializeBenchmark()
109
{
110
const auto &params = GetParam();
111
112
const char kVS[] =
113
"attribute vec2 aPosition;\n"
114
"attribute vec3 aTranslate;\n"
115
"attribute float aScale;\n"
116
"attribute vec3 aColor;\n"
117
"uniform mat4 uWorldMatrix;\n"
118
"uniform mat4 uProjectionMatrix;\n"
119
"varying vec3 vColor;\n"
120
"void main()\n"
121
"{\n"
122
" vec4 position = uWorldMatrix * vec4(aTranslate, 1.0);\n"
123
" position.xy += aPosition * aScale;\n"
124
" gl_Position = uProjectionMatrix * position;\n"
125
" vColor = aColor;\n"
126
"}\n";
127
128
constexpr char kFS[] =
129
"precision mediump float;\n"
130
"varying vec3 vColor;\n"
131
"void main()\n"
132
"{\n"
133
" gl_FragColor = vec4(vColor, 1.0);\n"
134
"}\n";
135
136
mProgram = CompileProgram(kVS, kFS);
137
ASSERT_NE(0u, mProgram);
138
139
glUseProgram(mProgram);
140
141
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
142
143
GLuint baseIndexData[6] = {0, 1, 2, 1, 3, 2};
144
Vector2 basePositionData[4] = {Vector2(-1.0f, 1.0f), Vector2(1.0f, 1.0f), Vector2(-1.0f, -1.0f),
145
Vector2(1.0f, -1.0f)};
146
147
std::vector<GLuint> indexData;
148
std::vector<Vector2> positionData;
149
150
if (!params.instancingEnabled)
151
{
152
GLuint pointVertexStride = 4;
153
for (GLuint pointIndex = 0; pointIndex < mNumPoints; ++pointIndex)
154
{
155
for (GLuint indexIndex = 0; indexIndex < 6; ++indexIndex)
156
{
157
indexData.push_back(baseIndexData[indexIndex] + pointIndex * pointVertexStride);
158
}
159
160
Vector3 randVec = RandomVector3(&mRNG);
161
for (GLuint vertexIndex = 0; vertexIndex < 4; ++vertexIndex)
162
{
163
positionData.push_back(basePositionData[vertexIndex]);
164
mTranslateData.push_back(randVec);
165
}
166
}
167
168
mSizeData.resize(mNumPoints * 4, 0.012f);
169
mColorData.resize(mNumPoints * 4, Vector3(1.0f, 0.0f, 0.0f));
170
}
171
else
172
{
173
for (GLuint index : baseIndexData)
174
{
175
indexData.push_back(index);
176
}
177
178
for (const Vector2 &position : basePositionData)
179
{
180
positionData.push_back(position);
181
}
182
183
for (GLuint pointIndex = 0; pointIndex < mNumPoints; ++pointIndex)
184
{
185
Vector3 randVec = RandomVector3(&mRNG);
186
mTranslateData.push_back(randVec);
187
}
188
189
mSizeData.resize(mNumPoints, 0.012f);
190
mColorData.resize(mNumPoints, Vector3(1.0f, 0.0f, 0.0f));
191
}
192
193
mBuffers.resize(5, 0);
194
glGenBuffers(static_cast<GLsizei>(mBuffers.size()), &mBuffers[0]);
195
196
// Index Data
197
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBuffers[0]);
198
glBufferData(GL_ELEMENT_ARRAY_BUFFER, VectorSizeBytes(indexData), &indexData[0],
199
GL_STATIC_DRAW);
200
201
// Position Data
202
glBindBuffer(GL_ARRAY_BUFFER, mBuffers[1]);
203
glBufferData(GL_ARRAY_BUFFER, VectorSizeBytes(positionData), &positionData[0], GL_STATIC_DRAW);
204
GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
205
ASSERT_NE(-1, positionLocation);
206
glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 8, nullptr);
207
glEnableVertexAttribArray(positionLocation);
208
209
// Translate Data
210
glBindBuffer(GL_ARRAY_BUFFER, mBuffers[2]);
211
glBufferData(GL_ARRAY_BUFFER, VectorSizeBytes(mTranslateData), &mTranslateData[0],
212
GL_STATIC_DRAW);
213
GLint translateLocation = glGetAttribLocation(mProgram, "aTranslate");
214
ASSERT_NE(-1, translateLocation);
215
glVertexAttribPointer(translateLocation, 3, GL_FLOAT, GL_FALSE, 12, nullptr);
216
glEnableVertexAttribArray(translateLocation);
217
glVertexAttribDivisorANGLE(translateLocation, 1);
218
219
// Scale Data
220
glBindBuffer(GL_ARRAY_BUFFER, mBuffers[3]);
221
glBufferData(GL_ARRAY_BUFFER, VectorSizeBytes(mSizeData), nullptr, GL_DYNAMIC_DRAW);
222
GLint scaleLocation = glGetAttribLocation(mProgram, "aScale");
223
ASSERT_NE(-1, scaleLocation);
224
glVertexAttribPointer(scaleLocation, 1, GL_FLOAT, GL_FALSE, 4, nullptr);
225
glEnableVertexAttribArray(scaleLocation);
226
glVertexAttribDivisorANGLE(scaleLocation, 1);
227
228
// Color Data
229
glBindBuffer(GL_ARRAY_BUFFER, mBuffers[4]);
230
glBufferData(GL_ARRAY_BUFFER, VectorSizeBytes(mColorData), nullptr, GL_DYNAMIC_DRAW);
231
GLint colorLocation = glGetAttribLocation(mProgram, "aColor");
232
ASSERT_NE(-1, colorLocation);
233
glVertexAttribPointer(colorLocation, 3, GL_FLOAT, GL_FALSE, 12, nullptr);
234
glEnableVertexAttribArray(colorLocation);
235
glVertexAttribDivisorANGLE(colorLocation, 1);
236
237
// Set the viewport
238
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
239
240
// Init matrices
241
GLint worldMatrixLocation = glGetUniformLocation(mProgram, "uWorldMatrix");
242
ASSERT_NE(-1, worldMatrixLocation);
243
Matrix4 worldMatrix = Matrix4::translate(Vector3(0, 0, -3.0f));
244
worldMatrix *= Matrix4::rotate(25.0f, Vector3(0.6f, 1.0f, 0.0f));
245
glUniformMatrix4fv(worldMatrixLocation, 1, GL_FALSE, &worldMatrix.data[0]);
246
247
GLint projectionMatrixLocation = glGetUniformLocation(mProgram, "uProjectionMatrix");
248
ASSERT_NE(-1, projectionMatrixLocation);
249
float fov =
250
static_cast<float>(getWindow()->getWidth()) / static_cast<float>(getWindow()->getHeight());
251
Matrix4 projectionMatrix = Matrix4::perspective(60.0f, fov, 1.0f, 300.0f);
252
glUniformMatrix4fv(projectionMatrixLocation, 1, GL_FALSE, &projectionMatrix.data[0]);
253
254
getWindow()->setVisible(true);
255
256
ASSERT_GL_NO_ERROR();
257
}
258
259
void InstancingPerfBenchmark::destroyBenchmark()
260
{
261
glDeleteProgram(mProgram);
262
263
if (!mBuffers.empty())
264
{
265
glDeleteBuffers(static_cast<GLsizei>(mBuffers.size()), &mBuffers[0]);
266
mBuffers.clear();
267
}
268
}
269
270
void InstancingPerfBenchmark::drawBenchmark()
271
{
272
glClear(GL_COLOR_BUFFER_BIT);
273
274
const auto &params = GetParam();
275
276
// Animatino makes the test more interesting visually, but also eats up many CPU cycles.
277
if (params.animationEnabled)
278
{
279
float time = static_cast<float>(mTimer.getElapsedTime());
280
281
for (size_t pointIndex = 0; pointIndex < mTranslateData.size(); ++pointIndex)
282
{
283
const Vector3 &translate = mTranslateData[pointIndex];
284
285
float tx = translate.x() + time;
286
float ty = translate.y() + time;
287
float tz = translate.z() + time;
288
289
float scale = AnimationSignal(tx) * 0.01f + 0.01f;
290
mSizeData[pointIndex] = scale;
291
292
Vector3 color =
293
Vector3(AnimationSignal(tx), AnimationSignal(ty), AnimationSignal(tz)) * 0.5f +
294
Vector3(0.5f);
295
296
mColorData[pointIndex] = color;
297
}
298
}
299
300
// Update scales and colors.
301
glBindBuffer(GL_ARRAY_BUFFER, mBuffers[3]);
302
glBufferSubData(GL_ARRAY_BUFFER, 0, VectorSizeBytes(mSizeData), &mSizeData[0]);
303
304
glBindBuffer(GL_ARRAY_BUFFER, mBuffers[4]);
305
glBufferSubData(GL_ARRAY_BUFFER, 0, VectorSizeBytes(mColorData), &mColorData[0]);
306
307
// Render the instances/billboards.
308
if (params.instancingEnabled)
309
{
310
for (unsigned int it = 0; it < params.iterationsPerStep; it++)
311
{
312
glDrawElementsInstancedANGLE(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr, mNumPoints);
313
}
314
}
315
else
316
{
317
for (unsigned int it = 0; it < params.iterationsPerStep; it++)
318
{
319
glDrawElements(GL_TRIANGLES, 6 * mNumPoints, GL_UNSIGNED_INT, nullptr);
320
}
321
}
322
323
ASSERT_GL_NO_ERROR();
324
}
325
326
InstancingPerfParams InstancingPerfD3D11Params()
327
{
328
InstancingPerfParams params;
329
params.eglParameters = D3D11();
330
return params;
331
}
332
333
InstancingPerfParams InstancingPerfOpenGLOrGLESParams()
334
{
335
InstancingPerfParams params;
336
params.eglParameters = OPENGL_OR_GLES();
337
return params;
338
}
339
340
TEST_P(InstancingPerfBenchmark, Run)
341
{
342
run();
343
}
344
345
ANGLE_INSTANTIATE_TEST(InstancingPerfBenchmark,
346
InstancingPerfD3D11Params(),
347
InstancingPerfOpenGLOrGLESParams());
348
349
} // anonymous namespace
350
351