Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/perf_tests/BufferSubData.cpp
1693 views
1
//
2
// Copyright 2014 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
// BufferSubDataBenchmark:
7
// Performance test for ANGLE buffer updates.
8
//
9
10
#include <sstream>
11
12
#include "ANGLEPerfTest.h"
13
#include "test_utils/draw_call_perf_utils.h"
14
15
using namespace angle;
16
17
namespace
18
{
19
constexpr unsigned int kIterationsPerStep = 4;
20
21
struct BufferSubDataParams final : public RenderTestParams
22
{
23
BufferSubDataParams()
24
{
25
// Common default values
26
majorVersion = 2;
27
minorVersion = 0;
28
windowWidth = 512;
29
windowHeight = 512;
30
updateSize = 32000;
31
bufferSize = 40000;
32
iterationsPerStep = kIterationsPerStep;
33
updateRate = 1;
34
}
35
36
std::string story() const override;
37
38
GLboolean vertexNormalized;
39
GLenum vertexType;
40
GLint vertexComponentCount;
41
unsigned int updateRate;
42
43
// static parameters
44
GLsizeiptr updateSize;
45
GLsizeiptr bufferSize;
46
};
47
48
std::ostream &operator<<(std::ostream &os, const BufferSubDataParams &params)
49
{
50
os << params.backendAndStory().substr(1);
51
return os;
52
}
53
54
class BufferSubDataBenchmark : public ANGLERenderTest,
55
public ::testing::WithParamInterface<BufferSubDataParams>
56
{
57
public:
58
BufferSubDataBenchmark();
59
60
void initializeBenchmark() override;
61
void destroyBenchmark() override;
62
void drawBenchmark() override;
63
64
private:
65
GLuint mProgram;
66
GLuint mBuffer;
67
uint8_t *mUpdateData;
68
int mNumTris;
69
};
70
71
GLfloat *GetFloatData(GLint componentCount)
72
{
73
static GLfloat vertices2[] = {
74
1, 2, 0, 0, 2, 0,
75
};
76
77
static GLfloat vertices3[] = {
78
1, 2, 1, 0, 0, 1, 2, 0, 1,
79
};
80
81
static GLfloat vertices4[] = {
82
1, 2, 1, 3, 0, 0, 1, 3, 2, 0, 1, 3,
83
};
84
85
switch (componentCount)
86
{
87
case 2:
88
return vertices2;
89
case 3:
90
return vertices3;
91
case 4:
92
return vertices4;
93
default:
94
return nullptr;
95
}
96
}
97
98
template <class T>
99
GLsizeiptr GetNormalizedData(GLsizeiptr numElements, GLfloat *floatData, std::vector<uint8_t> *data)
100
{
101
GLsizeiptr triDataSize = sizeof(T) * numElements;
102
data->resize(triDataSize);
103
104
T *destPtr = reinterpret_cast<T *>(data->data());
105
106
for (GLsizeiptr dataIndex = 0; dataIndex < numElements; dataIndex++)
107
{
108
GLfloat scaled = floatData[dataIndex] * 0.25f;
109
destPtr[dataIndex] =
110
static_cast<T>(scaled * static_cast<GLfloat>(std::numeric_limits<T>::max()));
111
}
112
113
return triDataSize;
114
}
115
116
template <class T>
117
GLsizeiptr GetIntData(GLsizeiptr numElements, GLfloat *floatData, std::vector<uint8_t> *data)
118
{
119
GLsizeiptr triDataSize = sizeof(T) * numElements;
120
data->resize(triDataSize);
121
122
T *destPtr = reinterpret_cast<T *>(data->data());
123
124
for (GLsizeiptr dataIndex = 0; dataIndex < numElements; dataIndex++)
125
{
126
destPtr[dataIndex] = static_cast<T>(floatData[dataIndex]);
127
}
128
129
return triDataSize;
130
}
131
132
GLsizeiptr GetVertexData(GLenum type,
133
GLint componentCount,
134
GLboolean normalized,
135
std::vector<uint8_t> *data)
136
{
137
GLsizeiptr triDataSize = 0;
138
GLfloat *floatData = GetFloatData(componentCount);
139
140
if (type == GL_FLOAT)
141
{
142
triDataSize = sizeof(GLfloat) * componentCount * 3;
143
data->resize(triDataSize);
144
memcpy(data->data(), floatData, triDataSize);
145
}
146
else if (normalized == GL_TRUE)
147
{
148
GLsizeiptr numElements = componentCount * 3;
149
150
switch (type)
151
{
152
case GL_BYTE:
153
triDataSize = GetNormalizedData<GLbyte>(numElements, floatData, data);
154
break;
155
case GL_SHORT:
156
triDataSize = GetNormalizedData<GLshort>(numElements, floatData, data);
157
break;
158
case GL_INT:
159
triDataSize = GetNormalizedData<GLint>(numElements, floatData, data);
160
break;
161
case GL_UNSIGNED_BYTE:
162
triDataSize = GetNormalizedData<GLubyte>(numElements, floatData, data);
163
break;
164
case GL_UNSIGNED_SHORT:
165
triDataSize = GetNormalizedData<GLushort>(numElements, floatData, data);
166
break;
167
case GL_UNSIGNED_INT:
168
triDataSize = GetNormalizedData<GLuint>(numElements, floatData, data);
169
break;
170
default:
171
assert(0);
172
}
173
}
174
else
175
{
176
GLsizeiptr numElements = componentCount * 3;
177
178
switch (type)
179
{
180
case GL_BYTE:
181
triDataSize = GetIntData<GLbyte>(numElements, floatData, data);
182
break;
183
case GL_SHORT:
184
triDataSize = GetIntData<GLshort>(numElements, floatData, data);
185
break;
186
case GL_INT:
187
triDataSize = GetIntData<GLint>(numElements, floatData, data);
188
break;
189
case GL_UNSIGNED_BYTE:
190
triDataSize = GetIntData<GLubyte>(numElements, floatData, data);
191
break;
192
case GL_UNSIGNED_SHORT:
193
triDataSize = GetIntData<GLushort>(numElements, floatData, data);
194
break;
195
case GL_UNSIGNED_INT:
196
triDataSize = GetIntData<GLuint>(numElements, floatData, data);
197
break;
198
default:
199
assert(0);
200
}
201
}
202
203
return triDataSize;
204
}
205
206
std::string BufferSubDataParams::story() const
207
{
208
std::stringstream strstr;
209
210
strstr << RenderTestParams::story();
211
212
if (vertexNormalized)
213
{
214
strstr << "_norm";
215
}
216
217
switch (vertexType)
218
{
219
case GL_FLOAT:
220
strstr << "_float";
221
break;
222
case GL_INT:
223
strstr << "_int";
224
break;
225
case GL_BYTE:
226
strstr << "_byte";
227
break;
228
case GL_SHORT:
229
strstr << "_short";
230
break;
231
case GL_UNSIGNED_INT:
232
strstr << "_uint";
233
break;
234
case GL_UNSIGNED_BYTE:
235
strstr << "_ubyte";
236
break;
237
case GL_UNSIGNED_SHORT:
238
strstr << "_ushort";
239
break;
240
default:
241
strstr << "_vunk_" << vertexType << "_";
242
break;
243
}
244
245
strstr << vertexComponentCount;
246
strstr << "_every" << updateRate;
247
248
return strstr.str();
249
}
250
251
BufferSubDataBenchmark::BufferSubDataBenchmark()
252
: ANGLERenderTest("BufferSubData", GetParam()),
253
mProgram(0),
254
mBuffer(0),
255
mUpdateData(nullptr),
256
mNumTris(0)
257
{}
258
259
void BufferSubDataBenchmark::initializeBenchmark()
260
{
261
const auto &params = GetParam();
262
263
ASSERT_LT(1, params.vertexComponentCount);
264
265
mProgram = SetupSimpleScaleAndOffsetProgram();
266
ASSERT_NE(0u, mProgram);
267
268
if (params.vertexNormalized == GL_TRUE)
269
{
270
GLfloat scale = 2.0f;
271
GLfloat offset = -0.5f;
272
glUniform1f(glGetUniformLocation(mProgram, "uScale"), scale);
273
glUniform1f(glGetUniformLocation(mProgram, "uOffset"), offset);
274
}
275
276
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
277
278
std::vector<uint8_t> zeroData(params.bufferSize);
279
memset(&zeroData[0], 0, zeroData.size());
280
281
glGenBuffers(1, &mBuffer);
282
glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
283
glBufferData(GL_ARRAY_BUFFER, params.bufferSize, &zeroData[0], GL_DYNAMIC_DRAW);
284
285
glVertexAttribPointer(0, params.vertexComponentCount, params.vertexType,
286
params.vertexNormalized, 0, 0);
287
glEnableVertexAttribArray(0);
288
289
if (params.updateSize > 0)
290
{
291
mUpdateData = new uint8_t[params.updateSize];
292
}
293
294
std::vector<uint8_t> data;
295
GLsizei triDataSize = static_cast<GLsizei>(GetVertexData(
296
params.vertexType, params.vertexComponentCount, params.vertexNormalized, &data));
297
298
mNumTris = static_cast<int>(params.updateSize / triDataSize);
299
for (int i = 0, offset = 0; i < mNumTris; ++i)
300
{
301
memcpy(mUpdateData + offset, &data[0], triDataSize);
302
offset += triDataSize;
303
}
304
305
if (params.updateSize == 0)
306
{
307
mNumTris = 1;
308
glBufferSubData(GL_ARRAY_BUFFER, 0, data.size(), &data[0]);
309
}
310
311
// Set the viewport
312
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
313
314
ASSERT_GL_NO_ERROR();
315
}
316
317
void BufferSubDataBenchmark::destroyBenchmark()
318
{
319
glDeleteProgram(mProgram);
320
glDeleteBuffers(1, &mBuffer);
321
SafeDeleteArray(mUpdateData);
322
}
323
324
void BufferSubDataBenchmark::drawBenchmark()
325
{
326
glClear(GL_COLOR_BUFFER_BIT);
327
328
const auto &params = GetParam();
329
330
for (unsigned int it = 0; it < params.iterationsPerStep; it++)
331
{
332
if (params.updateSize > 0 && ((getNumStepsPerformed() % params.updateRate) == 0))
333
{
334
glBufferSubData(GL_ARRAY_BUFFER, 0, params.updateSize, mUpdateData);
335
}
336
337
glDrawArrays(GL_TRIANGLES, 0, 3 * mNumTris);
338
}
339
340
ASSERT_GL_NO_ERROR();
341
}
342
343
BufferSubDataParams BufferUpdateD3D11Params()
344
{
345
BufferSubDataParams params;
346
params.eglParameters = egl_platform::D3D11();
347
params.vertexType = GL_FLOAT;
348
params.vertexComponentCount = 4;
349
params.vertexNormalized = GL_FALSE;
350
return params;
351
}
352
353
BufferSubDataParams BufferUpdateOpenGLOrGLESParams()
354
{
355
BufferSubDataParams params;
356
params.eglParameters = egl_platform::OPENGL_OR_GLES();
357
params.vertexType = GL_FLOAT;
358
params.vertexComponentCount = 4;
359
params.vertexNormalized = GL_FALSE;
360
return params;
361
}
362
363
BufferSubDataParams BufferUpdateVulkanParams()
364
{
365
BufferSubDataParams params;
366
params.eglParameters = egl_platform::VULKAN();
367
params.vertexType = GL_FLOAT;
368
params.vertexComponentCount = 4;
369
params.vertexNormalized = GL_FALSE;
370
return params;
371
}
372
373
TEST_P(BufferSubDataBenchmark, Run)
374
{
375
run();
376
}
377
378
ANGLE_INSTANTIATE_TEST(BufferSubDataBenchmark,
379
BufferUpdateD3D11Params(),
380
BufferUpdateOpenGLOrGLESParams(),
381
BufferUpdateVulkanParams());
382
383
} // namespace
384
385