Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/gl_tests/DrawBaseVertexBaseInstanceTest.cpp
1693 views
1
//
2
// Copyright 2019 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
7
// DrawBaseVertexBaseInstanceTest: Tests of GL_ANGLE_base_vertex_base_instance
8
9
#include "gpu_info_util/SystemInfo.h"
10
#include "test_utils/ANGLETest.h"
11
#include "test_utils/gl_raii.h"
12
13
#include <numeric>
14
15
using namespace angle;
16
17
namespace
18
{
19
20
// Create a kWidth * kHeight canvas equally split into kCountX * kCountY tiles
21
// each containing a quad partially covering each tile
22
constexpr uint32_t kWidth = 256;
23
constexpr uint32_t kHeight = 256;
24
constexpr uint32_t kCountX = 8;
25
constexpr uint32_t kCountY = 8;
26
constexpr std::array<GLfloat, 2> kTileSize = {
27
1.f / static_cast<GLfloat>(kCountX),
28
1.f / static_cast<GLfloat>(kCountY),
29
};
30
constexpr std::array<uint32_t, 2> kTilePixelSize = {kWidth / kCountX, kHeight / kCountY};
31
constexpr std::array<GLfloat, 2> kQuadRadius = {0.25f * kTileSize[0], 0.25f * kTileSize[1]};
32
constexpr std::array<uint32_t, 2> kPixelCheckSize = {
33
static_cast<uint32_t>(kQuadRadius[0] * kWidth),
34
static_cast<uint32_t>(kQuadRadius[1] * kHeight)};
35
36
constexpr std::array<GLfloat, 2> getTileCenter(uint32_t x, uint32_t y)
37
{
38
return {
39
kTileSize[0] * (0.5f + static_cast<GLfloat>(x)),
40
kTileSize[1] * (0.5f + static_cast<GLfloat>(y)),
41
};
42
}
43
constexpr std::array<std::array<GLfloat, 3>, 4> getQuadVertices(uint32_t x, uint32_t y)
44
{
45
const auto center = getTileCenter(x, y);
46
return {
47
std::array<GLfloat, 3>{center[0] - kQuadRadius[0], center[1] - kQuadRadius[1], 0.0f},
48
std::array<GLfloat, 3>{center[0] + kQuadRadius[0], center[1] - kQuadRadius[1], 0.0f},
49
std::array<GLfloat, 3>{center[0] + kQuadRadius[0], center[1] + kQuadRadius[1], 0.0f},
50
std::array<GLfloat, 3>{center[0] - kQuadRadius[0], center[1] + kQuadRadius[1], 0.0f},
51
};
52
}
53
54
enum class BaseVertexOption
55
{
56
NoBaseVertex,
57
UseBaseVertex
58
};
59
60
enum class BaseInstanceOption
61
{
62
NoBaseInstance,
63
UseBaseInstance
64
};
65
66
enum class BufferDataUsageOption
67
{
68
StaticDraw,
69
DynamicDraw
70
};
71
72
using DrawBaseVertexBaseInstanceTestParams = std::
73
tuple<angle::PlatformParameters, BaseVertexOption, BaseInstanceOption, BufferDataUsageOption>;
74
75
struct PrintToStringParamName
76
{
77
std::string operator()(
78
const ::testing::TestParamInfo<DrawBaseVertexBaseInstanceTestParams> &info) const
79
{
80
::std::stringstream ss;
81
ss << std::get<0>(info.param) << "_"
82
<< (std::get<3>(info.param) == BufferDataUsageOption::StaticDraw ? "_StaticDraw"
83
: "_DynamicDraw")
84
<< (std::get<2>(info.param) == BaseInstanceOption::UseBaseInstance ? "_UseBaseInstance"
85
: "")
86
<< (std::get<1>(info.param) == BaseVertexOption::UseBaseVertex ? "_UseBaseVertex" : "");
87
return ss.str();
88
}
89
};
90
91
// These tests check correctness of the ANGLE_base_vertex_base_instance extension.
92
// An array of quads is drawn across the screen.
93
// gl_VertexID, gl_InstanceID, gl_BaseVertex, and gl_BaseInstance
94
// are checked by using them to select the color of the draw.
95
class DrawBaseVertexBaseInstanceTest
96
: public ANGLETestBase,
97
public ::testing::TestWithParam<DrawBaseVertexBaseInstanceTestParams>
98
{
99
protected:
100
DrawBaseVertexBaseInstanceTest() : ANGLETestBase(std::get<0>(GetParam()))
101
{
102
setWindowWidth(kWidth);
103
setWindowHeight(kHeight);
104
setConfigRedBits(8);
105
setConfigGreenBits(8);
106
setConfigBlueBits(8);
107
setConfigAlphaBits(8);
108
109
// Rects in the same column are within a vertex array, testing gl_VertexID, gl_BaseVertex
110
// Rects in the same row are drawn by instancing, testing gl_InstanceID, gl_BaseInstance
111
112
mIndices = {0, 1, 2, 0, 2, 3};
113
114
for (uint32_t y = 0; y < kCountY; ++y)
115
{
116
// v3 ---- v2
117
// | |
118
// | |
119
// v0 ---- v1
120
121
const auto vs = getQuadVertices(0, y);
122
123
for (const auto &v : vs)
124
{
125
mVertices.insert(mVertices.end(), v.begin(), v.end());
126
}
127
128
for (GLushort i : mIndices)
129
{
130
mNonIndexedVertices.insert(mNonIndexedVertices.end(), vs[i].begin(), vs[i].end());
131
}
132
}
133
134
mRegularIndices.resize(kCountY * mIndices.size());
135
for (uint32_t i = 0; i < kCountY; i++)
136
{
137
uint32_t oi = 6 * i;
138
uint32_t ov = 4 * i;
139
for (uint32_t j = 0; j < 6; j++)
140
{
141
mRegularIndices[oi + j] = mIndices[j] + ov;
142
}
143
}
144
145
std::iota(mInstancedArrayId.begin(), mInstancedArrayId.end(), 0.0f);
146
std::reverse_copy(mInstancedArrayId.begin(), mInstancedArrayId.end(),
147
mInstancedArrayColorId.begin());
148
}
149
150
void SetUp() override { ANGLETestBase::ANGLETestSetUp(); }
151
152
bool useBaseVertexBuiltin() const
153
{
154
return std::get<1>(GetParam()) == BaseVertexOption::UseBaseVertex;
155
}
156
157
bool useBaseInstanceBuiltin() const
158
{
159
return std::get<2>(GetParam()) == BaseInstanceOption::UseBaseInstance;
160
}
161
162
GLenum getBufferDataUsage() const
163
{
164
return std::get<3>(GetParam()) == BufferDataUsageOption::StaticDraw ? GL_STATIC_DRAW
165
: GL_DYNAMIC_DRAW;
166
}
167
168
std::string vertexShaderSource300(bool isDrawArrays, bool isMultiDraw, bool divisorTest)
169
{
170
// Each color channel is to test the value of
171
// R: gl_InstanceID and gl_BaseInstance
172
// G: gl_VertexID and gl_BaseVertex
173
// B: gl_BaseVertex
174
175
std::stringstream shader;
176
shader << ("#version 300 es\n")
177
<< (isMultiDraw ? "#extension GL_ANGLE_multi_draw : require\n" : "")
178
<< ("#extension GL_ANGLE_base_vertex_base_instance : require\n")
179
<< "#define kCountX " << kCountX << "\n"
180
<< "#define kCountY " << kCountY << "\n"
181
<< R"(
182
in vec2 vPosition;
183
)" << (useBaseInstanceBuiltin() ? "" : "in float vInstanceID;\n")
184
<< (!divisorTest ? "" : "in float vInstanceColorID;\n") << R"(
185
out vec4 color;
186
void main()
187
{
188
const float xStep = 1.0 / float(kCountX);
189
const float yStep = 1.0 / float(kCountY);
190
float x_id = )"
191
<< (useBaseInstanceBuiltin() ? " float(gl_InstanceID + gl_BaseInstance);"
192
: "vInstanceID;")
193
<< "float x_color = "
194
<< (divisorTest ? "xStep * (vInstanceColorID + 1.0f);" : " 1.0 - xStep * x_id;")
195
<< R"(
196
float y_id = float(gl_VertexID / )"
197
<< (isDrawArrays ? "6" : "4") << R"();
198
199
color = vec4(
200
x_color,
201
1.0 - yStep * y_id,
202
)" << (useBaseVertexBuiltin() ? "1.0 - yStep * float(gl_BaseVertex) / 4.0" : "1.0")
203
<< R"(,
204
1);
205
206
mat3 transform = mat3(1.0);
207
transform[2][0] = x_id * xStep;
208
209
gl_Position = vec4(transform * vec3(vPosition, 1.0) * 2.0 - 1.0, 1);
210
})";
211
212
return shader.str();
213
}
214
215
std::string fragmentShaderSource300()
216
{
217
return
218
R"(#version 300 es
219
precision mediump float;
220
in vec4 color;
221
out vec4 o_color;
222
void main()
223
{
224
o_color = color;
225
})";
226
}
227
228
void setupProgram(GLProgram &program,
229
bool isDrawArrays = true,
230
bool isMultiDraw = false,
231
bool isDivisorTest = false)
232
{
233
program.makeRaster(vertexShaderSource300(isDrawArrays, isMultiDraw, isDivisorTest).c_str(),
234
fragmentShaderSource300().c_str());
235
EXPECT_GL_NO_ERROR();
236
ASSERT_TRUE(program.valid());
237
glUseProgram(program.get());
238
mPositionLoc = glGetAttribLocation(program.get(), "vPosition");
239
if (!useBaseInstanceBuiltin())
240
{
241
mInstanceIDLoc = glGetAttribLocation(program.get(), "vInstanceID");
242
mInstanceColorIDLoc = glGetAttribLocation(program.get(), "vInstanceColorID");
243
}
244
}
245
246
void setupNonIndexedBuffers(GLBuffer &vertexBuffer)
247
{
248
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.get());
249
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mNonIndexedVertices.size(),
250
mNonIndexedVertices.data(), getBufferDataUsage());
251
252
ASSERT_GL_NO_ERROR();
253
}
254
255
void setupIndexedBuffers(GLBuffer &vertexBuffer, GLBuffer &indexBuffer)
256
{
257
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
258
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mVertices.size(), mVertices.data(),
259
getBufferDataUsage());
260
261
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
262
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * mIndices.size(), mIndices.data(),
263
getBufferDataUsage());
264
265
ASSERT_GL_NO_ERROR();
266
}
267
268
void setupInstanceIDBuffer(GLBuffer &instanceIDBuffer)
269
{
270
glBindBuffer(GL_ARRAY_BUFFER, instanceIDBuffer);
271
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mInstancedArrayId.size(),
272
mInstancedArrayId.data(), getBufferDataUsage());
273
274
ASSERT_GL_NO_ERROR();
275
}
276
277
void setupInstanceColorIDBuffer(GLBuffer &instanceIDBuffer)
278
{
279
glBindBuffer(GL_ARRAY_BUFFER, instanceIDBuffer);
280
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mInstancedArrayColorId.size(),
281
mInstancedArrayColorId.data(), getBufferDataUsage());
282
283
ASSERT_GL_NO_ERROR();
284
}
285
286
void setupRegularIndexedBuffer(GLBuffer &indexBuffer)
287
{
288
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
289
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * mRegularIndices.size(),
290
mRegularIndices.data(), getBufferDataUsage());
291
292
ASSERT_GL_NO_ERROR();
293
}
294
295
void setupPositionVertexAttribPointer()
296
{
297
glEnableVertexAttribArray(mPositionLoc);
298
glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
299
}
300
301
void setupInstanceIDVertexAttribPointer(GLuint instanceIDLoc)
302
{
303
glEnableVertexAttribArray(instanceIDLoc);
304
glVertexAttribPointer(instanceIDLoc, 1, GL_FLOAT, GL_FALSE, 0, 0);
305
glVertexAttribDivisor(instanceIDLoc, 1);
306
}
307
308
void doDrawArraysInstancedBaseInstance()
309
{
310
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
311
312
const uint32_t countPerDraw = kCountY * 6;
313
314
for (uint32_t i = 0; i < kCountX; i += 2)
315
{
316
glDrawArraysInstancedBaseInstanceANGLE(GL_TRIANGLES, 0, countPerDraw, 2, i);
317
}
318
}
319
320
void doMultiDrawArraysInstancedBaseInstance()
321
{
322
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
323
324
const uint32_t countPerDraw = kCountY * 6;
325
326
const GLsizei drawCount = kCountX / 2;
327
const std::vector<GLsizei> counts(drawCount, countPerDraw);
328
const std::vector<GLsizei> firsts(drawCount, 0);
329
const std::vector<GLsizei> instanceCounts(drawCount, 2);
330
std::vector<GLuint> baseInstances(drawCount);
331
for (size_t i = 0; i < drawCount; i++)
332
{
333
baseInstances[i] = i * 2;
334
}
335
glMultiDrawArraysInstancedBaseInstanceANGLE(GL_TRIANGLES, firsts.data(), counts.data(),
336
instanceCounts.data(), baseInstances.data(),
337
drawCount);
338
}
339
340
void doDrawElementsInstancedBaseVertexBaseInstance()
341
{
342
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
343
344
const uint32_t countPerDraw = 6;
345
346
for (uint32_t v = 0; v < kCountY; v++)
347
{
348
for (uint32_t i = 0; i < kCountX; i += 2)
349
{
350
glDrawElementsInstancedBaseVertexBaseInstanceANGLE(
351
GL_TRIANGLES, countPerDraw, GL_UNSIGNED_SHORT,
352
reinterpret_cast<GLvoid *>(static_cast<uintptr_t>(0)), 2, v * 4, i);
353
}
354
}
355
}
356
357
// Call this after the *BaseVertexBaseInstance draw call to check if value of BaseVertex and
358
// BaseInstance are reset to zero
359
void doDrawArraysBaseInstanceReset()
360
{
361
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
362
glDrawArraysInstanced(GL_TRIANGLES, 0, 6 * kCountY, 1);
363
}
364
365
void doDrawElementsBaseVertexBaseInstanceReset()
366
{
367
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
368
glDrawElementsInstanced(GL_TRIANGLES, 6 * kCountY, GL_UNSIGNED_SHORT,
369
reinterpret_cast<GLvoid *>(static_cast<uintptr_t>(0)), 1);
370
}
371
372
void doMultiDrawElementsInstancedBaseVertexBaseInstance()
373
{
374
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
375
376
const GLsizei drawCount = kCountX * kCountY / 2;
377
const std::vector<GLsizei> counts(drawCount, 6);
378
const std::vector<GLsizei> instanceCounts(drawCount, 2);
379
const std::vector<GLvoid *> indices(drawCount, 0);
380
std::vector<GLint> baseVertices(drawCount);
381
std::vector<GLuint> baseInstances(drawCount);
382
383
GLsizei b = 0;
384
for (uint32_t v = 0; v < kCountY; v++)
385
{
386
for (uint32_t i = 0; i < kCountX; i += 2)
387
{
388
baseVertices[b] = v * 4;
389
baseInstances[b] = i;
390
b++;
391
}
392
}
393
394
glMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(
395
GL_TRIANGLES, counts.data(), GL_UNSIGNED_SHORT, indices.data(), instanceCounts.data(),
396
baseVertices.data(), baseInstances.data(), drawCount);
397
}
398
399
void checkDrawResult(bool hasBaseVertex, bool oneColumn = false)
400
{
401
uint32_t numColums = oneColumn ? 1 : kCountX;
402
for (uint32_t y = 0; y < kCountY; ++y)
403
{
404
for (uint32_t x = 0; x < numColums; ++x)
405
{
406
uint32_t center_x = x * kTilePixelSize[0] + kTilePixelSize[0] / 2;
407
uint32_t center_y = y * kTilePixelSize[1] + kTilePixelSize[1] / 2;
408
409
EXPECT_PIXEL_NEAR(center_x - kPixelCheckSize[0] / 2,
410
center_y - kPixelCheckSize[1] / 2,
411
256.0 * (1.0 - (float)x / (float)kCountX),
412
256.0 * (1.0 - (float)y / (float)kCountY),
413
useBaseVertexBuiltin() && hasBaseVertex && !oneColumn
414
? 256.0 * (1.0 - (float)y / (float)kCountY)
415
: 255,
416
255, 3);
417
}
418
}
419
}
420
421
void TearDown() override { ANGLETestBase::ANGLETestTearDown(); }
422
423
bool requestDrawBaseVertexBaseInstanceExtension()
424
{
425
if (IsGLExtensionRequestable("GL_ANGLE_base_vertex_base_instance"))
426
{
427
glRequestExtensionANGLE("GL_ANGLE_base_vertex_base_instance");
428
}
429
430
if (!IsGLExtensionEnabled("GL_ANGLE_base_vertex_base_instance"))
431
{
432
return false;
433
}
434
435
return true;
436
}
437
438
bool requestInstancedExtension()
439
{
440
if (IsGLExtensionRequestable("GL_ANGLE_instanced_arrays"))
441
{
442
glRequestExtensionANGLE("GL_ANGLE_instanced_arrays");
443
}
444
445
if (!IsGLExtensionEnabled("GL_ANGLE_instanced_arrays"))
446
{
447
return false;
448
}
449
450
return true;
451
}
452
453
bool requestExtensions()
454
{
455
if (getClientMajorVersion() <= 2)
456
{
457
if (!requestInstancedExtension())
458
{
459
return false;
460
}
461
}
462
return requestDrawBaseVertexBaseInstanceExtension();
463
}
464
465
// Used for base vertex base instance draw calls
466
std::vector<GLushort> mIndices;
467
std::vector<GLfloat> mVertices;
468
std::vector<GLfloat> mNonIndexedVertices;
469
// Used when gl_BaseInstance is not used
470
std::array<GLfloat, kCountX> mInstancedArrayId;
471
std::array<GLfloat, kCountX> mInstancedArrayColorId;
472
// Used for regular draw calls without base vertex base instance
473
std::vector<GLushort> mRegularIndices;
474
GLint mPositionLoc;
475
GLuint mInstanceIDLoc;
476
GLuint mInstanceColorIDLoc;
477
};
478
479
// Tests that compile a program with the extension succeeds
480
TEST_P(DrawBaseVertexBaseInstanceTest, CanCompile)
481
{
482
ANGLE_SKIP_TEST_IF(!requestExtensions());
483
GLProgram p0;
484
setupProgram(p0, true, false);
485
GLProgram p1;
486
setupProgram(p1, true, true);
487
GLProgram p2;
488
setupProgram(p2, false, false);
489
GLProgram p3;
490
setupProgram(p3, false, true);
491
}
492
493
// Tests if baseInstance works properly with instanced array with non-zero divisor
494
TEST_P(DrawBaseVertexBaseInstanceTest, BaseInstanceDivisor)
495
{
496
ANGLE_SKIP_TEST_IF(!requestExtensions());
497
ANGLE_SKIP_TEST_IF(useBaseInstanceBuiltin());
498
499
GLProgram program;
500
setupProgram(program, true, false, true);
501
502
GLBuffer nonIndexedVertexBuffer;
503
setupNonIndexedBuffers(nonIndexedVertexBuffer);
504
setupPositionVertexAttribPointer();
505
506
GLBuffer instanceIDBuffer;
507
GLBuffer instanceColorIDBuffer;
508
509
setupInstanceIDBuffer(instanceIDBuffer);
510
setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
511
setupInstanceColorIDBuffer(instanceColorIDBuffer);
512
setupInstanceIDVertexAttribPointer(mInstanceColorIDLoc);
513
514
doDrawArraysInstancedBaseInstance();
515
EXPECT_GL_NO_ERROR();
516
checkDrawResult(false);
517
518
doDrawArraysBaseInstanceReset();
519
EXPECT_GL_NO_ERROR();
520
checkDrawResult(false, true);
521
522
GLProgram programIndexed;
523
setupProgram(programIndexed, false, false, true);
524
525
GLBuffer indexBuffer;
526
GLBuffer vertexBuffer;
527
setupIndexedBuffers(vertexBuffer, indexBuffer);
528
setupPositionVertexAttribPointer();
529
530
glBindBuffer(GL_ARRAY_BUFFER, instanceIDBuffer);
531
setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
532
glBindBuffer(GL_ARRAY_BUFFER, instanceColorIDBuffer);
533
setupInstanceIDVertexAttribPointer(mInstanceColorIDLoc);
534
535
doDrawElementsInstancedBaseVertexBaseInstance();
536
EXPECT_GL_NO_ERROR();
537
checkDrawResult(true);
538
539
setupRegularIndexedBuffer(indexBuffer);
540
doDrawElementsBaseVertexBaseInstanceReset();
541
EXPECT_GL_NO_ERROR();
542
checkDrawResult(false, true);
543
}
544
545
// Tests basic functionality of glDrawArraysInstancedBaseInstance
546
TEST_P(DrawBaseVertexBaseInstanceTest, DrawArraysInstancedBaseInstance)
547
{
548
// TODO(shrekshao): Temporarily skip this test
549
// before we could try updating win AMD bot driver version
550
// after Lab team fixed issues with ssh into bot machines
551
// Currently this test fail on certain Win7/Win2008Server AMD GPU
552
// with driver version 23.20.185.235 when using OpenGL backend.
553
// This failure couldn't be produced on local Win10 AMD machine with latest driver installed
554
// Same for the MultiDrawArraysInstancedBaseInstance test
555
if (IsAMD() && IsWindows() && IsDesktopOpenGL())
556
{
557
SystemInfo *systemInfo = GetTestSystemInfo();
558
if (!systemInfo->gpus.empty())
559
{
560
ANGLE_SKIP_TEST_IF(0x6613 == systemInfo->gpus[systemInfo->activeGPUIndex].deviceId);
561
}
562
}
563
564
ANGLE_SKIP_TEST_IF(!requestExtensions());
565
566
GLProgram program;
567
setupProgram(program, true);
568
569
GLBuffer vertexBuffer;
570
setupNonIndexedBuffers(vertexBuffer);
571
setupPositionVertexAttribPointer();
572
573
GLBuffer instanceIDBuffer;
574
if (!useBaseInstanceBuiltin())
575
{
576
setupInstanceIDBuffer(instanceIDBuffer);
577
setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
578
}
579
580
doDrawArraysInstancedBaseInstance();
581
EXPECT_GL_NO_ERROR();
582
checkDrawResult(false);
583
584
doDrawArraysBaseInstanceReset();
585
EXPECT_GL_NO_ERROR();
586
checkDrawResult(false, true);
587
}
588
589
// Tests basic functionality of glMultiDrawArraysInstancedBaseInstance
590
TEST_P(DrawBaseVertexBaseInstanceTest, MultiDrawArraysInstancedBaseInstance)
591
{
592
if (IsAMD() && IsWindows() && IsDesktopOpenGL())
593
{
594
SystemInfo *systemInfo = GetTestSystemInfo();
595
if (!(systemInfo->activeGPUIndex < 0 || systemInfo->gpus.empty()))
596
{
597
ANGLE_SKIP_TEST_IF(0x6613 == systemInfo->gpus[systemInfo->activeGPUIndex].deviceId);
598
}
599
}
600
601
ANGLE_SKIP_TEST_IF(!requestExtensions());
602
603
GLProgram program;
604
setupProgram(program, true, true);
605
606
GLBuffer vertexBuffer;
607
setupNonIndexedBuffers(vertexBuffer);
608
setupPositionVertexAttribPointer();
609
610
GLBuffer instanceIDBuffer;
611
if (!useBaseInstanceBuiltin())
612
{
613
setupInstanceIDBuffer(instanceIDBuffer);
614
setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
615
}
616
617
doMultiDrawArraysInstancedBaseInstance();
618
EXPECT_GL_NO_ERROR();
619
checkDrawResult(false);
620
621
doDrawArraysBaseInstanceReset();
622
EXPECT_GL_NO_ERROR();
623
checkDrawResult(false, true);
624
}
625
626
// Tests basic functionality of glDrawElementsInstancedBaseVertexBaseInstance
627
TEST_P(DrawBaseVertexBaseInstanceTest, DrawElementsInstancedBaseVertexBaseInstance)
628
{
629
ANGLE_SKIP_TEST_IF(!requestExtensions());
630
631
GLProgram program;
632
setupProgram(program, false);
633
634
GLBuffer indexBuffer;
635
GLBuffer vertexBuffer;
636
setupIndexedBuffers(vertexBuffer, indexBuffer);
637
setupPositionVertexAttribPointer();
638
639
GLBuffer instanceIDBuffer;
640
if (!useBaseInstanceBuiltin())
641
{
642
setupInstanceIDBuffer(instanceIDBuffer);
643
setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
644
}
645
646
doDrawElementsInstancedBaseVertexBaseInstance();
647
EXPECT_GL_NO_ERROR();
648
checkDrawResult(true);
649
650
setupRegularIndexedBuffer(indexBuffer);
651
doDrawElementsBaseVertexBaseInstanceReset();
652
EXPECT_GL_NO_ERROR();
653
checkDrawResult(true, true);
654
}
655
656
// Tests basic functionality of glMultiDrawElementsInstancedBaseVertexBaseInstance
657
TEST_P(DrawBaseVertexBaseInstanceTest, MultiDrawElementsInstancedBaseVertexBaseInstance)
658
{
659
ANGLE_SKIP_TEST_IF(!requestExtensions());
660
661
GLProgram program;
662
setupProgram(program, false, true);
663
664
GLBuffer indexBuffer;
665
GLBuffer vertexBuffer;
666
setupIndexedBuffers(vertexBuffer, indexBuffer);
667
setupPositionVertexAttribPointer();
668
669
GLBuffer instanceIDBuffer;
670
if (!useBaseInstanceBuiltin())
671
{
672
setupInstanceIDBuffer(instanceIDBuffer);
673
setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
674
}
675
676
doMultiDrawElementsInstancedBaseVertexBaseInstance();
677
EXPECT_GL_NO_ERROR();
678
checkDrawResult(true);
679
680
setupRegularIndexedBuffer(indexBuffer);
681
doDrawElementsBaseVertexBaseInstanceReset();
682
EXPECT_GL_NO_ERROR();
683
checkDrawResult(true, true);
684
}
685
686
const angle::PlatformParameters platforms[] = {
687
ES3_D3D11(),
688
ES3_OPENGL(),
689
ES3_OPENGLES(),
690
ES3_VULKAN(),
691
};
692
693
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrawBaseVertexBaseInstanceTest);
694
INSTANTIATE_TEST_SUITE_P(
695
,
696
DrawBaseVertexBaseInstanceTest,
697
testing::Combine(
698
testing::ValuesIn(::angle::FilterTestParams(platforms, ArraySize(platforms))),
699
testing::Values(BaseVertexOption::NoBaseVertex, BaseVertexOption::UseBaseVertex),
700
testing::Values(BaseInstanceOption::NoBaseInstance, BaseInstanceOption::UseBaseInstance),
701
testing::Values(BufferDataUsageOption::StaticDraw, BufferDataUsageOption::DynamicDraw)),
702
PrintToStringParamName());
703
704
} // namespace
705
706