Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/gl_tests/DrawElementsTest.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
// DrawElementsTest:
7
// Tests for indexed draws.
8
//
9
10
#include "test_utils/ANGLETest.h"
11
#include "test_utils/gl_raii.h"
12
13
using namespace angle;
14
15
namespace
16
{
17
18
class DrawElementsTest : public ANGLETest
19
{
20
protected:
21
DrawElementsTest() : mProgram(0u)
22
{
23
setWindowWidth(64);
24
setWindowHeight(64);
25
setConfigRedBits(8);
26
setConfigGreenBits(8);
27
setConfigBlueBits(8);
28
setConfigAlphaBits(8);
29
}
30
31
~DrawElementsTest()
32
{
33
for (GLuint indexBuffer : mIndexBuffers)
34
{
35
if (indexBuffer != 0)
36
{
37
glDeleteBuffers(1, &indexBuffer);
38
}
39
}
40
41
for (GLuint vertexArray : mVertexArrays)
42
{
43
if (vertexArray != 0)
44
{
45
glDeleteVertexArrays(1, &vertexArray);
46
}
47
}
48
49
for (GLuint vertexBuffer : mVertexBuffers)
50
{
51
if (vertexBuffer != 0)
52
{
53
glDeleteBuffers(1, &vertexBuffer);
54
}
55
}
56
57
if (mProgram != 0u)
58
{
59
glDeleteProgram(mProgram);
60
}
61
}
62
63
std::vector<GLuint> mIndexBuffers;
64
std::vector<GLuint> mVertexArrays;
65
std::vector<GLuint> mVertexBuffers;
66
GLuint mProgram;
67
};
68
69
class WebGLDrawElementsTest : public DrawElementsTest
70
{
71
public:
72
WebGLDrawElementsTest() { setWebGLCompatibilityEnabled(true); }
73
};
74
75
// Test no error is generated when using client-side arrays, indices = nullptr and count = 0
76
TEST_P(DrawElementsTest, ClientSideNullptrArrayZeroCount)
77
{
78
constexpr char kVS[] =
79
"attribute vec3 a_pos;\n"
80
"void main()\n"
81
"{\n"
82
" gl_Position = vec4(a_pos, 1.0);\n"
83
"}\n";
84
85
ANGLE_GL_PROGRAM(program, kVS, essl1_shaders::fs::Blue());
86
87
GLint posLocation = glGetAttribLocation(program.get(), "a_pos");
88
ASSERT_NE(-1, posLocation);
89
glUseProgram(program.get());
90
91
const auto &vertices = GetQuadVertices();
92
93
GLBuffer vertexBuffer;
94
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.get());
95
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
96
GL_STATIC_DRAW);
97
98
glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
99
glEnableVertexAttribArray(posLocation);
100
ASSERT_GL_NO_ERROR();
101
102
// "If drawElements is called with a count greater than zero, and no WebGLBuffer is bound to the
103
// ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated."
104
glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, nullptr);
105
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
106
107
// count == 0 so it's fine to have no element array buffer bound.
108
glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_BYTE, nullptr);
109
ASSERT_GL_NO_ERROR();
110
}
111
112
// Test a state desync that can occur when using a streaming index buffer in GL in concert with
113
// deleting the applied index buffer.
114
TEST_P(DrawElementsTest, DeletingAfterStreamingIndexes)
115
{
116
// Init program
117
constexpr char kVS[] =
118
"attribute vec2 position;\n"
119
"attribute vec2 testFlag;\n"
120
"varying vec2 v_data;\n"
121
"void main() {\n"
122
" gl_Position = vec4(position, 0, 1);\n"
123
" v_data = testFlag;\n"
124
"}";
125
126
constexpr char kFS[] =
127
"varying highp vec2 v_data;\n"
128
"void main() {\n"
129
" gl_FragColor = vec4(v_data, 0, 1);\n"
130
"}";
131
132
mProgram = CompileProgram(kVS, kFS);
133
ASSERT_NE(0u, mProgram);
134
glUseProgram(mProgram);
135
136
GLint positionLocation = glGetAttribLocation(mProgram, "position");
137
ASSERT_NE(-1, positionLocation);
138
139
GLint testFlagLocation = glGetAttribLocation(mProgram, "testFlag");
140
ASSERT_NE(-1, testFlagLocation);
141
142
mIndexBuffers.resize(3u);
143
glGenBuffers(3, &mIndexBuffers[0]);
144
145
mVertexArrays.resize(2);
146
glGenVertexArrays(2, &mVertexArrays[0]);
147
148
mVertexBuffers.resize(2);
149
glGenBuffers(2, &mVertexBuffers[0]);
150
151
std::vector<GLuint> indexData[2];
152
indexData[0].push_back(0);
153
indexData[0].push_back(1);
154
indexData[0].push_back(2);
155
indexData[0].push_back(2);
156
indexData[0].push_back(3);
157
indexData[0].push_back(0);
158
159
indexData[1] = indexData[0];
160
for (GLuint &item : indexData[1])
161
{
162
item += 4u;
163
}
164
165
std::vector<GLfloat> positionData = {// quad verts
166
-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
167
// Repeat position data
168
-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f};
169
170
std::vector<GLfloat> testFlagData = {// red
171
1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
172
// green
173
0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f};
174
175
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[0]);
176
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indexData[0].size(), &indexData[0][0],
177
GL_STATIC_DRAW);
178
179
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[2]);
180
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indexData[0].size(), &indexData[0][0],
181
GL_STATIC_DRAW);
182
183
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[1]);
184
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indexData[1].size(), &indexData[1][0],
185
GL_STATIC_DRAW);
186
187
// Initialize first vertex array with second index buffer
188
glBindVertexArray(mVertexArrays[0]);
189
190
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[1]);
191
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[0]);
192
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],
193
GL_STATIC_DRAW);
194
glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
195
glEnableVertexAttribArray(positionLocation);
196
197
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[1]);
198
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * testFlagData.size(), &testFlagData[0],
199
GL_STATIC_DRAW);
200
glVertexAttribPointer(testFlagLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
201
glEnableVertexAttribArray(testFlagLocation);
202
203
// Initialize second vertex array with first index buffer
204
glBindVertexArray(mVertexArrays[1]);
205
206
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[0]);
207
208
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[0]);
209
glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
210
glEnableVertexAttribArray(positionLocation);
211
212
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[1]);
213
glVertexAttribPointer(testFlagLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
214
glEnableVertexAttribArray(testFlagLocation);
215
216
ASSERT_GL_NO_ERROR();
217
218
glBindVertexArray(mVertexArrays[0]);
219
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
220
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
221
222
glBindVertexArray(mVertexArrays[1]);
223
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
224
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
225
226
glBindVertexArray(mVertexArrays[0]);
227
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
228
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
229
230
// Trigger the bug here.
231
glDeleteBuffers(1, &mIndexBuffers[2]);
232
233
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
234
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
235
236
ASSERT_GL_NO_ERROR();
237
}
238
239
// Test drawing to part of the indices in an index buffer, and then all of them.
240
TEST_P(DrawElementsTest, PartOfIndexBufferThenAll)
241
{
242
// Init program
243
constexpr char kVS[] =
244
"attribute vec2 position;\n"
245
"attribute vec2 testFlag;\n"
246
"varying vec2 v_data;\n"
247
"void main() {\n"
248
" gl_Position = vec4(position, 0, 1);\n"
249
" v_data = testFlag;\n"
250
"}";
251
252
constexpr char kFS[] =
253
"varying highp vec2 v_data;\n"
254
"void main() {\n"
255
" gl_FragColor = vec4(v_data, 0, 1);\n"
256
"}";
257
258
mProgram = CompileProgram(kVS, kFS);
259
ASSERT_NE(0u, mProgram);
260
glUseProgram(mProgram);
261
262
GLint positionLocation = glGetAttribLocation(mProgram, "position");
263
ASSERT_NE(-1, positionLocation);
264
265
GLint testFlagLocation = glGetAttribLocation(mProgram, "testFlag");
266
ASSERT_NE(-1, testFlagLocation);
267
268
mIndexBuffers.resize(1);
269
glGenBuffers(1, &mIndexBuffers[0]);
270
271
mVertexArrays.resize(1);
272
glGenVertexArrays(1, &mVertexArrays[0]);
273
274
mVertexBuffers.resize(2);
275
glGenBuffers(2, &mVertexBuffers[0]);
276
277
std::vector<GLubyte> indexData[2];
278
indexData[0].push_back(0);
279
indexData[0].push_back(1);
280
indexData[0].push_back(2);
281
indexData[0].push_back(2);
282
indexData[0].push_back(3);
283
indexData[0].push_back(0);
284
indexData[0].push_back(4);
285
indexData[0].push_back(5);
286
indexData[0].push_back(6);
287
indexData[0].push_back(6);
288
indexData[0].push_back(7);
289
indexData[0].push_back(4);
290
291
// Make a copy:
292
indexData[1] = indexData[0];
293
294
std::vector<GLfloat> positionData = {// quad verts
295
-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
296
// Repeat position data
297
-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f};
298
299
std::vector<GLfloat> testFlagData = {// red
300
1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
301
// green
302
0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f};
303
304
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[0]);
305
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * indexData[0].size(), &indexData[0][0],
306
GL_STATIC_DRAW);
307
308
glBindVertexArray(mVertexArrays[0]);
309
310
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[0]);
311
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[0]);
312
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],
313
GL_STATIC_DRAW);
314
glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
315
glEnableVertexAttribArray(positionLocation);
316
317
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[1]);
318
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * testFlagData.size(), &testFlagData[0],
319
GL_STATIC_DRAW);
320
glVertexAttribPointer(testFlagLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
321
glEnableVertexAttribArray(testFlagLocation);
322
323
ASSERT_GL_NO_ERROR();
324
325
// Draw with just the second set of 6 items, then first 6, and then the entire index buffer
326
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, reinterpret_cast<const void *>(6));
327
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
328
329
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, nullptr);
330
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
331
332
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_BYTE, nullptr);
333
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
334
335
// Reload the buffer again with a copy of the same data
336
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * indexData[1].size(), &indexData[1][0],
337
GL_STATIC_DRAW);
338
339
// Draw with just the first 6 indices, and then with the entire index buffer
340
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, nullptr);
341
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
342
343
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_BYTE, nullptr);
344
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
345
346
// Reload the buffer again with a copy of the same data
347
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * indexData[0].size(), &indexData[0][0],
348
GL_STATIC_DRAW);
349
350
// This time, do not check color between draws (which causes a flush):
351
// Draw with just the second set of 6 items, then first 6, and then the entire index buffer
352
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, reinterpret_cast<const void *>(6));
353
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, nullptr);
354
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_BYTE, nullptr);
355
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
356
357
ASSERT_GL_NO_ERROR();
358
}
359
360
// Test that the offset in the index buffer is forced to be a multiple of the element size
361
TEST_P(WebGLDrawElementsTest, DrawElementsTypeAlignment)
362
{
363
constexpr char kVS[] =
364
"attribute vec3 a_pos;\n"
365
"void main()\n"
366
"{\n"
367
" gl_Position = vec4(a_pos, 1.0);\n"
368
"}\n";
369
370
ANGLE_GL_PROGRAM(program, kVS, essl1_shaders::fs::Blue());
371
372
GLint posLocation = glGetAttribLocation(program, "a_pos");
373
ASSERT_NE(-1, posLocation);
374
glUseProgram(program);
375
376
const auto &vertices = GetQuadVertices();
377
378
GLBuffer vertexBuffer;
379
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
380
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
381
GL_STATIC_DRAW);
382
383
glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
384
glEnableVertexAttribArray(posLocation);
385
386
GLBuffer indexBuffer;
387
const GLubyte indices1[] = {0, 0, 0, 0, 0, 0};
388
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
389
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices1), indices1, GL_STATIC_DRAW);
390
391
ASSERT_GL_NO_ERROR();
392
393
const char *zeroIndices = nullptr;
394
395
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, zeroIndices);
396
ASSERT_GL_NO_ERROR();
397
398
const GLushort indices2[] = {0, 0, 0, 0, 0, 0};
399
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
400
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices2), indices2, GL_STATIC_DRAW);
401
402
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, zeroIndices + 1);
403
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
404
}
405
406
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrawElementsTest);
407
ANGLE_INSTANTIATE_TEST_ES3(DrawElementsTest);
408
409
ANGLE_INSTANTIATE_TEST_ES2(WebGLDrawElementsTest);
410
} // namespace
411
412