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 // DrawBaseInstanceTest: Tests of GL_EXT_base_instance
9
10 #include "gpu_info_util/SystemInfo.h"
11 #include "test_utils/ANGLETest.h"
12 #include "test_utils/gl_raii.h"
13
14 #include <numeric>
15
16 using namespace angle;
17
18 namespace
19 {
20
21 // Create a kWidth * kHeight canvas equally split into kCountX * kCountY tiles
22 // each containing a quad partially covering each tile
23 constexpr uint32_t kWidth = 256;
24 constexpr uint32_t kHeight = 256;
25 constexpr uint32_t kCountX = 8;
26 constexpr uint32_t kCountY = 8;
27 constexpr std::array<GLfloat, 2> kTileSize = {
28 1.f / static_cast<GLfloat>(kCountX),
29 1.f / static_cast<GLfloat>(kCountY),
30 };
31 constexpr std::array<uint32_t, 2> kTilePixelSize = {kWidth / kCountX, kHeight / kCountY};
32 constexpr std::array<GLfloat, 2> kQuadRadius = {0.25f * kTileSize[0], 0.25f * kTileSize[1]};
33 constexpr std::array<uint32_t, 2> kPixelCheckSize = {
34 static_cast<uint32_t>(kQuadRadius[0] * kWidth),
35 static_cast<uint32_t>(kQuadRadius[1] * kHeight)};
36
getTileCenter(uint32_t x,uint32_t y)37 constexpr std::array<GLfloat, 2> getTileCenter(uint32_t x, uint32_t y)
38 {
39 return {
40 kTileSize[0] * (0.5f + static_cast<GLfloat>(x)),
41 kTileSize[1] * (0.5f + static_cast<GLfloat>(y)),
42 };
43 }
getQuadVertices(uint32_t x,uint32_t y)44 constexpr std::array<std::array<GLfloat, 3>, 4> getQuadVertices(uint32_t x, uint32_t y)
45 {
46 const auto center = getTileCenter(x, y);
47 return {
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 std::array<GLfloat, 3>{center[0] - kQuadRadius[0], center[1] + kQuadRadius[1], 0.0f},
52 };
53 }
54
55 enum class BaseVertexOption
56 {
57 NoBaseVertex,
58 UseBaseVertex
59 };
60
61 enum class BaseInstanceOption
62 {
63 NoBaseInstance,
64 UseBaseInstance
65 };
66
67 enum class BufferDataUsageOption
68 {
69 StaticDraw,
70 DynamicDraw
71 };
72
73 using DrawBaseVertexBaseInstanceTestParams = std::
74 tuple<angle::PlatformParameters, BaseVertexOption, BaseInstanceOption, BufferDataUsageOption>;
75
76 struct PrintToStringParamName
77 {
operator ()__anon3913e2b20111::PrintToStringParamName78 std::string operator()(
79 const ::testing::TestParamInfo<DrawBaseVertexBaseInstanceTestParams> &info) const
80 {
81 ::std::stringstream ss;
82 ss << std::get<0>(info.param) << "_"
83 << (std::get<3>(info.param) == BufferDataUsageOption::StaticDraw ? "_StaticDraw"
84 : "_DynamicDraw")
85 << (std::get<2>(info.param) == BaseInstanceOption::UseBaseInstance ? "_UseBaseInstance"
86 : "")
87 << (std::get<1>(info.param) == BaseVertexOption::UseBaseVertex ? "_UseBaseVertex" : "");
88 return ss.str();
89 }
90 };
91
92 // These tests check correctness of the ANGLE_base_vertex_base_instance extension.
93 // An array of quads is drawn across the screen.
94 // gl_VertexID, gl_InstanceID, gl_BaseVertex, and gl_BaseInstance
95 // are checked by using them to select the color of the draw.
96 class DrawBaseVertexBaseInstanceTest
97 : public ANGLETestBase,
98 public ::testing::TestWithParam<DrawBaseVertexBaseInstanceTestParams>
99 {
100 protected:
DrawBaseVertexBaseInstanceTest()101 DrawBaseVertexBaseInstanceTest() : ANGLETestBase(std::get<0>(GetParam()))
102 {
103 setWindowWidth(kWidth);
104 setWindowHeight(kHeight);
105 setConfigRedBits(8);
106 setConfigGreenBits(8);
107 setConfigBlueBits(8);
108 setConfigAlphaBits(8);
109
110 // Rects in the same column are within a vertex array, testing gl_VertexID, gl_BaseVertex
111 // Rects in the same row are drawn by instancing, testing gl_InstanceID, gl_BaseInstance
112
113 mIndices = {0, 1, 2, 0, 2, 3};
114
115 for (uint32_t y = 0; y < kCountY; ++y)
116 {
117 // v3 ---- v2
118 // | |
119 // | |
120 // v0 ---- v1
121
122 const auto vs = getQuadVertices(0, y);
123
124 for (const auto &v : vs)
125 {
126 mVertices.insert(mVertices.end(), v.begin(), v.end());
127 }
128
129 for (GLushort i : mIndices)
130 {
131 mNonIndexedVertices.insert(mNonIndexedVertices.end(), vs[i].begin(), vs[i].end());
132 }
133 }
134
135 mRegularIndices.resize(kCountY * mIndices.size());
136 for (uint32_t i = 0; i < kCountY; i++)
137 {
138 uint32_t oi = 6 * i;
139 uint32_t ov = 4 * i;
140 for (uint32_t j = 0; j < 6; j++)
141 {
142 mRegularIndices[oi + j] = mIndices[j] + ov;
143 }
144 }
145
146 std::iota(mInstancedArrayId.begin(), mInstancedArrayId.end(), 0.0f);
147 std::reverse_copy(mInstancedArrayId.begin(), mInstancedArrayId.end(),
148 mInstancedArrayColorId.begin());
149 }
150
SetUp()151 void SetUp() override { ANGLETestBase::ANGLETestSetUp(); }
152
useBaseVertexBuiltin() const153 bool useBaseVertexBuiltin() const
154 {
155 return std::get<1>(GetParam()) == BaseVertexOption::UseBaseVertex;
156 }
157
useBaseInstanceBuiltin() const158 bool useBaseInstanceBuiltin() const
159 {
160 return std::get<2>(GetParam()) == BaseInstanceOption::UseBaseInstance;
161 }
162
getBufferDataUsage() const163 GLenum getBufferDataUsage() const
164 {
165 return std::get<3>(GetParam()) == BufferDataUsageOption::StaticDraw ? GL_STATIC_DRAW
166 : GL_DYNAMIC_DRAW;
167 }
168
vertexShaderSource300(bool isDrawArrays,bool isMultiDraw,bool divisorTest)169 std::string vertexShaderSource300(bool isDrawArrays, bool isMultiDraw, bool divisorTest)
170 {
171 // Each color channel is to test the value of
172 // R: gl_InstanceID and gl_BaseInstance
173 // G: gl_VertexID and gl_BaseVertex
174 // B: gl_BaseVertex
175
176 std::stringstream shader;
177 shader << ("#version 300 es\n")
178 << (isMultiDraw ? "#extension GL_ANGLE_multi_draw : require\n" : "")
179 << ("#extension GL_ANGLE_base_vertex_base_instance_shader_builtin : require\n")
180 << "#define kCountX " << kCountX << "\n"
181 << "#define kCountY " << kCountY << "\n"
182 << R"(
183 in vec2 vPosition;
184 )" << (useBaseInstanceBuiltin() ? "" : "in float vInstanceID;\n")
185 << (!divisorTest ? "" : "in float vInstanceColorID;\n") << R"(
186 out vec4 color;
187 void main()
188 {
189 const float xStep = 1.0 / float(kCountX);
190 const float yStep = 1.0 / float(kCountY);
191 float x_id = )"
192 << (useBaseInstanceBuiltin() ? " float(gl_InstanceID + gl_BaseInstance);"
193 : "vInstanceID;")
194 << "float x_color = "
195 << (divisorTest ? "xStep * (vInstanceColorID + 1.0f);" : " 1.0 - xStep * x_id;")
196 << R"(
197 float y_id = float(gl_VertexID / )"
198 << (isDrawArrays ? "6" : "4") << R"();
199
200 color = vec4(
201 x_color,
202 1.0 - yStep * y_id,
203 )" << (useBaseVertexBuiltin() ? "1.0 - yStep * float(gl_BaseVertex) / 4.0" : "1.0")
204 << R"(,
205 1);
206
207 mat3 transform = mat3(1.0);
208 transform[2][0] = x_id * xStep;
209
210 gl_Position = vec4(transform * vec3(vPosition, 1.0) * 2.0 - 1.0, 1);
211 })";
212
213 return shader.str();
214 }
215
fragmentShaderSource300()216 std::string fragmentShaderSource300()
217 {
218 return
219 R"(#version 300 es
220 precision mediump float;
221 in vec4 color;
222 out vec4 o_color;
223 void main()
224 {
225 o_color = color;
226 })";
227 }
228
setupProgram(GLProgram & program,bool isDrawArrays=true,bool isMultiDraw=false,bool isDivisorTest=false)229 void setupProgram(GLProgram &program,
230 bool isDrawArrays = true,
231 bool isMultiDraw = false,
232 bool isDivisorTest = false)
233 {
234 program.makeRaster(vertexShaderSource300(isDrawArrays, isMultiDraw, isDivisorTest).c_str(),
235 fragmentShaderSource300().c_str());
236 EXPECT_GL_NO_ERROR();
237 ASSERT_TRUE(program.valid());
238 glUseProgram(program);
239 mPositionLoc = glGetAttribLocation(program, "vPosition");
240 if (!useBaseInstanceBuiltin())
241 {
242 mInstanceIDLoc = glGetAttribLocation(program, "vInstanceID");
243 mInstanceColorIDLoc = glGetAttribLocation(program, "vInstanceColorID");
244 }
245 }
246
setupNonIndexedBuffers(GLBuffer & vertexBuffer)247 void setupNonIndexedBuffers(GLBuffer &vertexBuffer)
248 {
249 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
250 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mNonIndexedVertices.size(),
251 mNonIndexedVertices.data(), getBufferDataUsage());
252
253 ASSERT_GL_NO_ERROR();
254 }
255
setupIndexedBuffers(GLBuffer & vertexBuffer,GLBuffer & indexBuffer)256 void setupIndexedBuffers(GLBuffer &vertexBuffer, GLBuffer &indexBuffer)
257 {
258 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
259 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mVertices.size(), mVertices.data(),
260 getBufferDataUsage());
261
262 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
263 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * mIndices.size(), mIndices.data(),
264 getBufferDataUsage());
265
266 ASSERT_GL_NO_ERROR();
267 }
268
setupInstanceIDBuffer(GLBuffer & instanceIDBuffer)269 void setupInstanceIDBuffer(GLBuffer &instanceIDBuffer)
270 {
271 glBindBuffer(GL_ARRAY_BUFFER, instanceIDBuffer);
272 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mInstancedArrayId.size(),
273 mInstancedArrayId.data(), getBufferDataUsage());
274
275 ASSERT_GL_NO_ERROR();
276 }
277
setupInstanceColorIDBuffer(GLBuffer & instanceIDBuffer)278 void setupInstanceColorIDBuffer(GLBuffer &instanceIDBuffer)
279 {
280 glBindBuffer(GL_ARRAY_BUFFER, instanceIDBuffer);
281 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mInstancedArrayColorId.size(),
282 mInstancedArrayColorId.data(), getBufferDataUsage());
283
284 ASSERT_GL_NO_ERROR();
285 }
286
setupRegularIndexedBuffer(GLBuffer & indexBuffer)287 void setupRegularIndexedBuffer(GLBuffer &indexBuffer)
288 {
289 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
290 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * mRegularIndices.size(),
291 mRegularIndices.data(), getBufferDataUsage());
292
293 ASSERT_GL_NO_ERROR();
294 }
295
setupPositionVertexAttribPointer()296 void setupPositionVertexAttribPointer()
297 {
298 glEnableVertexAttribArray(mPositionLoc);
299 glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
300 }
301
setupInstanceIDVertexAttribPointer(GLuint instanceIDLoc)302 void setupInstanceIDVertexAttribPointer(GLuint instanceIDLoc)
303 {
304 glEnableVertexAttribArray(instanceIDLoc);
305 glVertexAttribPointer(instanceIDLoc, 1, GL_FLOAT, GL_FALSE, 0, 0);
306 glVertexAttribDivisor(instanceIDLoc, 1);
307 }
308
doDrawArraysInstancedBaseInstance()309 void doDrawArraysInstancedBaseInstance()
310 {
311 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
312
313 const uint32_t countPerDraw = kCountY * 6;
314
315 for (uint32_t i = 0; i < kCountX; i += 2)
316 {
317 glDrawArraysInstancedBaseInstanceANGLE(GL_TRIANGLES, 0, countPerDraw, 2, i);
318 }
319 }
320
doMultiDrawArraysInstancedBaseInstance()321 void doMultiDrawArraysInstancedBaseInstance()
322 {
323 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
324
325 const uint32_t countPerDraw = kCountY * 6;
326
327 const GLsizei drawCount = kCountX / 2;
328 const std::vector<GLsizei> counts(drawCount, countPerDraw);
329 const std::vector<GLsizei> firsts(drawCount, 0);
330 const std::vector<GLsizei> instanceCounts(drawCount, 2);
331 std::vector<GLuint> baseInstances(drawCount);
332 for (size_t i = 0; i < drawCount; i++)
333 {
334 baseInstances[i] = i * 2;
335 }
336 glMultiDrawArraysInstancedBaseInstanceANGLE(GL_TRIANGLES, firsts.data(), counts.data(),
337 instanceCounts.data(), baseInstances.data(),
338 drawCount);
339 }
340
doDrawElementsInstancedBaseVertexBaseInstance()341 void doDrawElementsInstancedBaseVertexBaseInstance()
342 {
343 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
344
345 const uint32_t countPerDraw = 6;
346
347 for (uint32_t v = 0; v < kCountY; v++)
348 {
349 for (uint32_t i = 0; i < kCountX; i += 2)
350 {
351 glDrawElementsInstancedBaseVertexBaseInstanceANGLE(
352 GL_TRIANGLES, countPerDraw, GL_UNSIGNED_SHORT,
353 reinterpret_cast<GLvoid *>(static_cast<uintptr_t>(0)), 2, v * 4, i);
354 }
355 }
356 }
357
358 // Call this after the *BaseVertexBaseInstance draw call to check if value of BaseVertex and
359 // BaseInstance are reset to zero
doDrawArraysBaseInstanceReset()360 void doDrawArraysBaseInstanceReset()
361 {
362 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
363 glDrawArraysInstanced(GL_TRIANGLES, 0, 6 * kCountY, 1);
364 }
365
doDrawElementsBaseVertexBaseInstanceReset()366 void doDrawElementsBaseVertexBaseInstanceReset()
367 {
368 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
369 glDrawElementsInstanced(GL_TRIANGLES, 6 * kCountY, GL_UNSIGNED_SHORT,
370 reinterpret_cast<GLvoid *>(static_cast<uintptr_t>(0)), 1);
371 }
372
doMultiDrawElementsInstancedBaseVertexBaseInstance()373 void doMultiDrawElementsInstancedBaseVertexBaseInstance()
374 {
375 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
376
377 const GLsizei drawCount = kCountX * kCountY / 2;
378 const std::vector<GLsizei> counts(drawCount, 6);
379 const std::vector<GLsizei> instanceCounts(drawCount, 2);
380 const std::vector<GLvoid *> indices(drawCount, 0);
381 std::vector<GLint> baseVertices(drawCount);
382 std::vector<GLuint> baseInstances(drawCount);
383
384 GLsizei b = 0;
385 for (uint32_t v = 0; v < kCountY; v++)
386 {
387 for (uint32_t i = 0; i < kCountX; i += 2)
388 {
389 baseVertices[b] = v * 4;
390 baseInstances[b] = i;
391 b++;
392 }
393 }
394
395 glMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(
396 GL_TRIANGLES, counts.data(), GL_UNSIGNED_SHORT, indices.data(), instanceCounts.data(),
397 baseVertices.data(), baseInstances.data(), drawCount);
398 }
399
checkDrawResult(bool hasBaseVertex,bool oneColumn=false)400 void checkDrawResult(bool hasBaseVertex, bool oneColumn = false)
401 {
402 uint32_t numColums = oneColumn ? 1 : kCountX;
403 for (uint32_t y = 0; y < kCountY; ++y)
404 {
405 for (uint32_t x = 0; x < numColums; ++x)
406 {
407 uint32_t center_x = x * kTilePixelSize[0] + kTilePixelSize[0] / 2;
408 uint32_t center_y = y * kTilePixelSize[1] + kTilePixelSize[1] / 2;
409
410 EXPECT_PIXEL_NEAR(center_x - kPixelCheckSize[0] / 2,
411 center_y - kPixelCheckSize[1] / 2,
412 256.0 * (1.0 - (float)x / (float)kCountX),
413 256.0 * (1.0 - (float)y / (float)kCountY),
414 useBaseVertexBuiltin() && hasBaseVertex && !oneColumn
415 ? 256.0 * (1.0 - (float)y / (float)kCountY)
416 : 255,
417 255, 3);
418 }
419 }
420 }
421
TearDown()422 void TearDown() override { ANGLETestBase::ANGLETestTearDown(); }
423
requestDrawBaseVertexBaseInstanceExtension()424 bool requestDrawBaseVertexBaseInstanceExtension()
425 {
426 if (IsGLExtensionRequestable("GL_ANGLE_base_vertex_base_instance"))
427 {
428 glRequestExtensionANGLE("GL_ANGLE_base_vertex_base_instance");
429 }
430
431 if (!IsGLExtensionEnabled("GL_ANGLE_base_vertex_base_instance"))
432 {
433 return false;
434 }
435
436 if (IsGLExtensionRequestable("GL_ANGLE_base_vertex_base_instance_shader_builtin"))
437 {
438 glRequestExtensionANGLE("GL_ANGLE_base_vertex_base_instance_shader_builtin");
439 }
440
441 return true;
442 }
443
requestInstancedExtension()444 bool requestInstancedExtension()
445 {
446 if (IsGLExtensionRequestable("GL_ANGLE_instanced_arrays"))
447 {
448 glRequestExtensionANGLE("GL_ANGLE_instanced_arrays");
449 }
450
451 if (!IsGLExtensionEnabled("GL_ANGLE_instanced_arrays"))
452 {
453 return false;
454 }
455
456 return true;
457 }
458
requestExtensions()459 bool requestExtensions()
460 {
461 if (getClientMajorVersion() <= 2)
462 {
463 if (!requestInstancedExtension())
464 {
465 return false;
466 }
467 }
468 return requestDrawBaseVertexBaseInstanceExtension();
469 }
470
471 // Used for base vertex base instance draw calls
472 std::vector<GLushort> mIndices;
473 std::vector<GLfloat> mVertices;
474 std::vector<GLfloat> mNonIndexedVertices;
475 // Used when gl_BaseInstance is not used
476 std::array<GLfloat, kCountX> mInstancedArrayId = {};
477 std::array<GLfloat, kCountX> mInstancedArrayColorId = {};
478 // Used for regular draw calls without base vertex base instance
479 std::vector<GLushort> mRegularIndices;
480 GLint mPositionLoc = 0;
481 GLuint mInstanceIDLoc = 0;
482 GLuint mInstanceColorIDLoc = 0;
483 };
484
485 using DrawBaseInstanceTestParams = std::
486 tuple<angle::PlatformParameters, BaseVertexOption, BaseInstanceOption, BufferDataUsageOption>;
487
488 // The tests in DrawBaseInstanceTest check the correctness
489 // of the EXT_base_instance extension.
490 // gl_VertexID, gl_InstanceID, gl_BaseVertex, and gl_BaseInstance
491 // are checked by using them to select the color of the draw.
492 class DrawBaseInstanceTest : public ANGLETestBase,
493 public ::testing::TestWithParam<DrawBaseInstanceTestParams>
494 {
495 protected:
DrawBaseInstanceTest()496 DrawBaseInstanceTest() : ANGLETestBase(std::get<0>(GetParam()))
497 {
498 setWindowWidth(kWidth);
499 setWindowHeight(kHeight);
500 setConfigRedBits(8);
501 setConfigGreenBits(8);
502 setConfigBlueBits(8);
503 setConfigAlphaBits(8);
504
505 // Rects in the same column are within a vertex array, testing gl_VertexID, gl_BaseVertex
506 // Rects in the same row are drawn by instancing, testing gl_InstanceID, gl_BaseInstance
507
508 mIndices = {0, 1, 2, 0, 2, 3};
509
510 for (uint32_t y = 0; y < kCountY; ++y)
511 {
512 // v3 ---- v2
513 // | |
514 // | |
515 // v0 ---- v1
516
517 const auto vs = getQuadVertices(0, y);
518
519 for (const auto &v : vs)
520 {
521 mVertices.insert(mVertices.end(), v.begin(), v.end());
522 }
523
524 for (GLushort i : mIndices)
525 {
526 mNonIndexedVertices.insert(mNonIndexedVertices.end(), vs[i].begin(), vs[i].end());
527 }
528 }
529
530 mRegularIndices.resize(kCountY * mIndices.size());
531 for (uint32_t i = 0; i < kCountY; i++)
532 {
533 uint32_t oi = 6 * i;
534 uint32_t ov = 4 * i;
535 for (uint32_t j = 0; j < 6; j++)
536 {
537 mRegularIndices[oi + j] = mIndices[j] + ov;
538 }
539 }
540
541 std::iota(mInstancedArrayId.begin(), mInstancedArrayId.end(), 0.0f);
542 std::reverse_copy(mInstancedArrayId.begin(), mInstancedArrayId.end(),
543 mInstancedArrayColorId.begin());
544 }
545
SetUp()546 void SetUp() override { ANGLETestBase::ANGLETestSetUp(); }
547
useBaseVertexBuiltin() const548 bool useBaseVertexBuiltin() const
549 {
550 return std::get<1>(GetParam()) == BaseVertexOption::UseBaseVertex;
551 }
552
useBaseInstanceBuiltin() const553 bool useBaseInstanceBuiltin() const
554 {
555 return std::get<2>(GetParam()) == BaseInstanceOption::UseBaseInstance;
556 }
557
getBufferDataUsage() const558 GLenum getBufferDataUsage() const
559 {
560 return std::get<3>(GetParam()) == BufferDataUsageOption::StaticDraw ? GL_STATIC_DRAW
561 : GL_DYNAMIC_DRAW;
562 }
563
vertexShaderSource300(bool isDrawArrays,bool divisorTest)564 std::string vertexShaderSource300(bool isDrawArrays, bool divisorTest)
565 {
566 // Each color channel is to test the value of
567 // R: gl_InstanceID and gl_BaseInstance
568 // G: gl_VertexID and gl_BaseVertex
569 // B: gl_BaseVertex
570
571 std::stringstream shader;
572 shader << ("#version 300 es\n")
573 << ("#extension GL_ANGLE_base_vertex_base_instance_shader_builtin : require\n")
574 << "#define kCountX " << kCountX << "\n"
575 << "#define kCountY " << kCountY << "\n"
576 << R"(
577 in vec2 vPosition;
578 )" << (useBaseInstanceBuiltin() ? "" : "in float vInstanceID;\n")
579 << (!divisorTest ? "" : "in float vInstanceColorID;\n") << R"(
580 out vec4 color;
581 void main()
582 {
583 const float xStep = 1.0 / float(kCountX);
584 const float yStep = 1.0 / float(kCountY);
585 float x_id = )"
586 << (useBaseInstanceBuiltin() ? " float(gl_InstanceID + gl_BaseInstance);"
587 : "vInstanceID;")
588 << "float x_color = "
589 << (divisorTest ? "xStep * (vInstanceColorID + 1.0f);" : " 1.0 - xStep * x_id;")
590 << R"(
591 float y_id = float(gl_VertexID / )"
592 << (isDrawArrays ? "6" : "4") << R"();
593
594 color = vec4(
595 x_color,
596 1.0 - yStep * y_id,
597 )" << (useBaseVertexBuiltin() ? "1.0 - yStep * float(gl_BaseVertex) / 4.0" : "1.0")
598 << R"(,
599 1);
600
601 mat3 transform = mat3(1.0);
602 transform[2][0] = x_id * xStep;
603
604 gl_Position = vec4(transform * vec3(vPosition, 1.0) * 2.0 - 1.0, 1);
605 })";
606
607 return shader.str();
608 }
609
fragmentShaderSource300()610 std::string fragmentShaderSource300()
611 {
612 return
613 R"(#version 300 es
614 precision mediump float;
615 in vec4 color;
616 out vec4 o_color;
617 void main()
618 {
619 o_color = color;
620 })";
621 }
622
setupProgram(GLProgram & program,bool isDrawArrays=true,bool isDivisorTest=false)623 void setupProgram(GLProgram &program, bool isDrawArrays = true, bool isDivisorTest = false)
624 {
625 program.makeRaster(vertexShaderSource300(isDrawArrays, isDivisorTest).c_str(),
626 fragmentShaderSource300().c_str());
627 EXPECT_GL_NO_ERROR();
628 ASSERT_TRUE(program.valid());
629 glUseProgram(program);
630 mPositionLoc = glGetAttribLocation(program, "vPosition");
631 if (!useBaseInstanceBuiltin())
632 {
633 mInstanceIDLoc = glGetAttribLocation(program, "vInstanceID");
634 mInstanceColorIDLoc = glGetAttribLocation(program, "vInstanceColorID");
635 }
636 }
637
setupNonIndexedBuffers(GLBuffer & vertexBuffer)638 void setupNonIndexedBuffers(GLBuffer &vertexBuffer)
639 {
640 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
641 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mNonIndexedVertices.size(),
642 mNonIndexedVertices.data(), getBufferDataUsage());
643
644 ASSERT_GL_NO_ERROR();
645 }
646
setupIndexedBuffers(GLBuffer & vertexBuffer,GLBuffer & indexBuffer)647 void setupIndexedBuffers(GLBuffer &vertexBuffer, GLBuffer &indexBuffer)
648 {
649 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
650 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mVertices.size(), mVertices.data(),
651 getBufferDataUsage());
652
653 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
654 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * mIndices.size(), mIndices.data(),
655 getBufferDataUsage());
656
657 ASSERT_GL_NO_ERROR();
658 }
659
setupInstanceIDBuffer(GLBuffer & instanceIDBuffer)660 void setupInstanceIDBuffer(GLBuffer &instanceIDBuffer)
661 {
662 glBindBuffer(GL_ARRAY_BUFFER, instanceIDBuffer);
663 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mInstancedArrayId.size(),
664 mInstancedArrayId.data(), getBufferDataUsage());
665
666 ASSERT_GL_NO_ERROR();
667 }
668
setupInstanceColorIDBuffer(GLBuffer & instanceIDBuffer)669 void setupInstanceColorIDBuffer(GLBuffer &instanceIDBuffer)
670 {
671 glBindBuffer(GL_ARRAY_BUFFER, instanceIDBuffer);
672 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mInstancedArrayColorId.size(),
673 mInstancedArrayColorId.data(), getBufferDataUsage());
674
675 ASSERT_GL_NO_ERROR();
676 }
677
setupRegularIndexedBuffer(GLBuffer & indexBuffer)678 void setupRegularIndexedBuffer(GLBuffer &indexBuffer)
679 {
680 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
681 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * mRegularIndices.size(),
682 mRegularIndices.data(), getBufferDataUsage());
683
684 ASSERT_GL_NO_ERROR();
685 }
686
setupPositionVertexAttribPointer()687 void setupPositionVertexAttribPointer()
688 {
689 glEnableVertexAttribArray(mPositionLoc);
690 glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
691 }
692
setupInstanceIDVertexAttribPointer(GLuint instanceIDLoc)693 void setupInstanceIDVertexAttribPointer(GLuint instanceIDLoc)
694 {
695 glEnableVertexAttribArray(instanceIDLoc);
696 glVertexAttribPointer(instanceIDLoc, 1, GL_FLOAT, GL_FALSE, 0, 0);
697 glVertexAttribDivisor(instanceIDLoc, 1);
698 }
699
doDrawArraysInstancedBaseInstance()700 void doDrawArraysInstancedBaseInstance()
701 {
702 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
703
704 const uint32_t countPerDraw = kCountY * 6;
705
706 for (uint32_t i = 0; i < kCountX; i += 2)
707 {
708 glDrawArraysInstancedBaseInstanceEXT(GL_TRIANGLES, 0, countPerDraw, 2, i);
709 }
710 }
711
doDrawElementsInstancedBaseInstance()712 void doDrawElementsInstancedBaseInstance()
713 {
714 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
715
716 const uint32_t countPerDraw = 6;
717
718 for (uint32_t v = 0; v < kCountY; v++)
719 {
720 for (uint32_t i = 0; i < kCountX; i += 2)
721 {
722 glDrawElementsInstancedBaseInstanceEXT(GL_TRIANGLES, countPerDraw,
723 GL_UNSIGNED_SHORT,
724 (void *)(v * 6 * sizeof(GLushort)), 2, i);
725 }
726 }
727 }
728
doDrawElementsInstancedBaseVertexBaseInstance()729 void doDrawElementsInstancedBaseVertexBaseInstance()
730 {
731 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
732
733 const uint32_t countPerDraw = 6;
734
735 for (uint32_t v = 0; v < kCountY; v++)
736 {
737 for (uint32_t i = 0; i < kCountX; i += 2)
738 {
739 glDrawElementsInstancedBaseVertexBaseInstanceEXT(
740 GL_TRIANGLES, countPerDraw, GL_UNSIGNED_SHORT,
741 reinterpret_cast<GLvoid *>(static_cast<uintptr_t>(0)), 2, v * 4, i);
742 }
743 }
744 }
745
746 // Call this after the *BaseInstance draw call to check
747 // if value of BaseInstance is reset to zero
doDrawArraysBaseInstanceReset()748 void doDrawArraysBaseInstanceReset()
749 {
750 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
751 glDrawArraysInstanced(GL_TRIANGLES, 0, 6 * kCountY, 1);
752 }
753
doDrawElementsInstancedBaseInstanceReset()754 void doDrawElementsInstancedBaseInstanceReset()
755 {
756 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
757 glDrawElementsInstanced(GL_TRIANGLES, 6 * kCountY, GL_UNSIGNED_SHORT,
758 reinterpret_cast<GLvoid *>(static_cast<uintptr_t>(0)), 1);
759 }
760
doDrawElementsBaseVertexBaseInstanceReset()761 void doDrawElementsBaseVertexBaseInstanceReset()
762 {
763 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
764 glDrawElementsInstanced(GL_TRIANGLES, 6 * kCountY, GL_UNSIGNED_SHORT,
765 reinterpret_cast<GLvoid *>(static_cast<uintptr_t>(0)), 1);
766 }
767
checkDrawResult(bool hasBaseVertex,bool oneColumn=false)768 void checkDrawResult(bool hasBaseVertex, bool oneColumn = false)
769 {
770 uint32_t numColums = oneColumn ? 1 : kCountX;
771 for (uint32_t y = 0; y < kCountY; ++y)
772 {
773 for (uint32_t x = 0; x < numColums; ++x)
774 {
775 uint32_t center_x = x * kTilePixelSize[0] + kTilePixelSize[0] / 2;
776 uint32_t center_y = y * kTilePixelSize[1] + kTilePixelSize[1] / 2;
777
778 EXPECT_PIXEL_NEAR(center_x - kPixelCheckSize[0] / 2,
779 center_y - kPixelCheckSize[1] / 2,
780 256.0 * (1.0 - (float)x / (float)kCountX),
781 256.0 * (1.0 - (float)y / (float)kCountY),
782 useBaseVertexBuiltin() && hasBaseVertex && !oneColumn
783 ? 256.0 * (1.0 - (float)y / (float)kCountY)
784 : 255,
785 255, 3);
786 }
787 }
788 }
789
TearDown()790 void TearDown() override { ANGLETestBase::ANGLETestTearDown(); }
791
requestExtensions()792 bool requestExtensions()
793 {
794 if (IsGLExtensionRequestable("GL_ANGLE_base_vertex_base_instance_shader_builtin"))
795 {
796 glRequestExtensionANGLE("GL_ANGLE_base_vertex_base_instance_shader_builtin");
797 }
798
799 if (!IsGLExtensionEnabled("GL_ANGLE_base_vertex_base_instance_shader_builtin"))
800 {
801 return false;
802 }
803
804 return EnsureGLExtensionEnabled("GL_EXT_base_instance");
805 }
806
807 // Used for base vertex base instance draw calls
808 std::vector<GLushort> mIndices;
809 std::vector<GLfloat> mVertices;
810 std::vector<GLfloat> mNonIndexedVertices;
811 // Used when gl_BaseInstance is not used
812 std::array<GLfloat, kCountX> mInstancedArrayId = {};
813 std::array<GLfloat, kCountX> mInstancedArrayColorId = {};
814 // Used for regular draw calls without base vertex base instance
815 std::vector<GLushort> mRegularIndices;
816 GLint mPositionLoc = 0;
817 GLuint mInstanceIDLoc = 0;
818 GLuint mInstanceColorIDLoc = 0;
819 };
820
821 // Tests that compile a program with the extension succeeds
TEST_P(DrawBaseVertexBaseInstanceTest,CanCompile)822 TEST_P(DrawBaseVertexBaseInstanceTest, CanCompile)
823 {
824 ANGLE_SKIP_TEST_IF(!requestExtensions());
825 GLProgram p0;
826 setupProgram(p0, true, false);
827 GLProgram p1;
828 setupProgram(p1, true, true);
829 GLProgram p2;
830 setupProgram(p2, false, false);
831 GLProgram p3;
832 setupProgram(p3, false, true);
833 }
834
835 // Tests if baseInstance works properly with instanced array with non-zero divisor
TEST_P(DrawBaseVertexBaseInstanceTest,BaseInstanceDivisor)836 TEST_P(DrawBaseVertexBaseInstanceTest, BaseInstanceDivisor)
837 {
838 ANGLE_SKIP_TEST_IF(!requestExtensions());
839 ANGLE_SKIP_TEST_IF(useBaseInstanceBuiltin());
840
841 GLProgram program;
842 setupProgram(program, true, false, true);
843
844 GLBuffer nonIndexedVertexBuffer;
845 setupNonIndexedBuffers(nonIndexedVertexBuffer);
846 setupPositionVertexAttribPointer();
847
848 GLBuffer instanceIDBuffer;
849 GLBuffer instanceColorIDBuffer;
850
851 setupInstanceIDBuffer(instanceIDBuffer);
852 setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
853 setupInstanceColorIDBuffer(instanceColorIDBuffer);
854 setupInstanceIDVertexAttribPointer(mInstanceColorIDLoc);
855
856 doDrawArraysInstancedBaseInstance();
857 EXPECT_GL_NO_ERROR();
858 checkDrawResult(false);
859
860 doDrawArraysBaseInstanceReset();
861 EXPECT_GL_NO_ERROR();
862 checkDrawResult(false, true);
863
864 GLProgram programIndexed;
865 setupProgram(programIndexed, false, false, true);
866
867 GLBuffer indexBuffer;
868 GLBuffer vertexBuffer;
869 setupIndexedBuffers(vertexBuffer, indexBuffer);
870 setupPositionVertexAttribPointer();
871
872 glBindBuffer(GL_ARRAY_BUFFER, instanceIDBuffer);
873 setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
874 glBindBuffer(GL_ARRAY_BUFFER, instanceColorIDBuffer);
875 setupInstanceIDVertexAttribPointer(mInstanceColorIDLoc);
876
877 doDrawElementsInstancedBaseVertexBaseInstance();
878 EXPECT_GL_NO_ERROR();
879 checkDrawResult(true);
880
881 setupRegularIndexedBuffer(indexBuffer);
882 doDrawElementsBaseVertexBaseInstanceReset();
883 EXPECT_GL_NO_ERROR();
884 checkDrawResult(false, true);
885 }
886
887 // Tests basic functionality of glDrawArraysInstancedBaseInstanceANGLE
TEST_P(DrawBaseVertexBaseInstanceTest,DrawArraysInstancedBaseInstance)888 TEST_P(DrawBaseVertexBaseInstanceTest, DrawArraysInstancedBaseInstance)
889 {
890 // TODO(shrekshao): Temporarily skip this test
891 // before we could try updating win AMD bot driver version
892 // after Lab team fixed issues with ssh into bot machines
893 // Currently this test fail on certain Win7/Win2008Server AMD GPU
894 // with driver version 23.20.185.235 when using OpenGL backend.
895 // This failure couldn't be produced on local Win10 AMD machine with latest driver installed
896 // Same for the MultiDrawArraysInstancedBaseInstance test
897 if (IsAMD() && IsWindows() && IsDesktopOpenGL())
898 {
899 SystemInfo *systemInfo = GetTestSystemInfo();
900 if (!systemInfo->gpus.empty())
901 {
902 ANGLE_SKIP_TEST_IF(0x6613 == systemInfo->gpus[systemInfo->activeGPUIndex].deviceId);
903 }
904 }
905
906 ANGLE_SKIP_TEST_IF(!requestExtensions());
907
908 GLProgram program;
909 setupProgram(program, true);
910
911 GLBuffer vertexBuffer;
912 setupNonIndexedBuffers(vertexBuffer);
913 setupPositionVertexAttribPointer();
914
915 GLBuffer instanceIDBuffer;
916 if (!useBaseInstanceBuiltin())
917 {
918 setupInstanceIDBuffer(instanceIDBuffer);
919 setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
920 }
921
922 doDrawArraysInstancedBaseInstance();
923 EXPECT_GL_NO_ERROR();
924 checkDrawResult(false);
925
926 doDrawArraysBaseInstanceReset();
927 EXPECT_GL_NO_ERROR();
928 checkDrawResult(false, true);
929 }
930
931 // Tests basic functionality of glMultiDrawArraysInstancedBaseInstance
TEST_P(DrawBaseVertexBaseInstanceTest,MultiDrawArraysInstancedBaseInstance)932 TEST_P(DrawBaseVertexBaseInstanceTest, MultiDrawArraysInstancedBaseInstance)
933 {
934 if (IsAMD() && IsWindows() && IsDesktopOpenGL())
935 {
936 SystemInfo *systemInfo = GetTestSystemInfo();
937 if (!(systemInfo->activeGPUIndex < 0 || systemInfo->gpus.empty()))
938 {
939 ANGLE_SKIP_TEST_IF(0x6613 == systemInfo->gpus[systemInfo->activeGPUIndex].deviceId);
940 }
941 }
942
943 ANGLE_SKIP_TEST_IF(!requestExtensions());
944
945 GLProgram program;
946 setupProgram(program, true, true);
947
948 GLBuffer vertexBuffer;
949 setupNonIndexedBuffers(vertexBuffer);
950 setupPositionVertexAttribPointer();
951
952 GLBuffer instanceIDBuffer;
953 if (!useBaseInstanceBuiltin())
954 {
955 setupInstanceIDBuffer(instanceIDBuffer);
956 setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
957 }
958
959 doMultiDrawArraysInstancedBaseInstance();
960 EXPECT_GL_NO_ERROR();
961 checkDrawResult(false);
962
963 doDrawArraysBaseInstanceReset();
964 EXPECT_GL_NO_ERROR();
965 checkDrawResult(false, true);
966 }
967
968 // Tests basic functionality of glDrawElementsInstancedBaseVertexBaseInstanceANGLE
TEST_P(DrawBaseVertexBaseInstanceTest,DrawElementsInstancedBaseVertexBaseInstance)969 TEST_P(DrawBaseVertexBaseInstanceTest, DrawElementsInstancedBaseVertexBaseInstance)
970 {
971 ANGLE_SKIP_TEST_IF(!requestExtensions());
972
973 GLProgram program;
974 setupProgram(program, false);
975
976 GLBuffer indexBuffer;
977 GLBuffer vertexBuffer;
978 setupIndexedBuffers(vertexBuffer, indexBuffer);
979 setupPositionVertexAttribPointer();
980
981 GLBuffer instanceIDBuffer;
982 if (!useBaseInstanceBuiltin())
983 {
984 setupInstanceIDBuffer(instanceIDBuffer);
985 setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
986 }
987
988 doDrawElementsInstancedBaseVertexBaseInstance();
989 EXPECT_GL_NO_ERROR();
990 checkDrawResult(true);
991
992 setupRegularIndexedBuffer(indexBuffer);
993 doDrawElementsBaseVertexBaseInstanceReset();
994 EXPECT_GL_NO_ERROR();
995 checkDrawResult(true, true);
996 }
997
998 // Tests basic functionality of glMultiDrawElementsInstancedBaseVertexBaseInstance
TEST_P(DrawBaseVertexBaseInstanceTest,MultiDrawElementsInstancedBaseVertexBaseInstance)999 TEST_P(DrawBaseVertexBaseInstanceTest, MultiDrawElementsInstancedBaseVertexBaseInstance)
1000 {
1001 ANGLE_SKIP_TEST_IF(!requestExtensions());
1002
1003 GLProgram program;
1004 setupProgram(program, false, true);
1005
1006 GLBuffer indexBuffer;
1007 GLBuffer vertexBuffer;
1008 setupIndexedBuffers(vertexBuffer, indexBuffer);
1009 setupPositionVertexAttribPointer();
1010
1011 GLBuffer instanceIDBuffer;
1012 if (!useBaseInstanceBuiltin())
1013 {
1014 setupInstanceIDBuffer(instanceIDBuffer);
1015 setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
1016 }
1017
1018 doMultiDrawElementsInstancedBaseVertexBaseInstance();
1019 EXPECT_GL_NO_ERROR();
1020 checkDrawResult(true);
1021
1022 setupRegularIndexedBuffer(indexBuffer);
1023 doDrawElementsBaseVertexBaseInstanceReset();
1024 EXPECT_GL_NO_ERROR();
1025 checkDrawResult(true, true);
1026 }
1027
1028 // Tests if baseInstance works properly with instanced array with non-zero divisor
TEST_P(DrawBaseInstanceTest,BaseInstanceDivisor)1029 TEST_P(DrawBaseInstanceTest, BaseInstanceDivisor)
1030 {
1031 ANGLE_SKIP_TEST_IF(!requestExtensions());
1032 ANGLE_SKIP_TEST_IF(useBaseInstanceBuiltin());
1033
1034 GLProgram program;
1035 setupProgram(program, true, true);
1036
1037 GLBuffer nonIndexedVertexBuffer;
1038 setupNonIndexedBuffers(nonIndexedVertexBuffer);
1039 setupPositionVertexAttribPointer();
1040
1041 GLBuffer instanceIDBuffer;
1042 GLBuffer instanceColorIDBuffer;
1043
1044 setupInstanceIDBuffer(instanceIDBuffer);
1045 setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
1046 setupInstanceColorIDBuffer(instanceColorIDBuffer);
1047 setupInstanceIDVertexAttribPointer(mInstanceColorIDLoc);
1048
1049 doDrawArraysInstancedBaseInstance();
1050 EXPECT_GL_NO_ERROR();
1051 checkDrawResult(false);
1052
1053 doDrawArraysBaseInstanceReset();
1054 EXPECT_GL_NO_ERROR();
1055 checkDrawResult(false, true);
1056
1057 GLProgram programIndexed;
1058 setupProgram(programIndexed, false, true);
1059
1060 GLBuffer indexBuffer;
1061 GLBuffer vertexBuffer;
1062 setupIndexedBuffers(vertexBuffer, indexBuffer);
1063 setupPositionVertexAttribPointer();
1064
1065 glBindBuffer(GL_ARRAY_BUFFER, instanceIDBuffer);
1066 setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
1067 glBindBuffer(GL_ARRAY_BUFFER, instanceColorIDBuffer);
1068 setupInstanceIDVertexAttribPointer(mInstanceColorIDLoc);
1069
1070 doDrawElementsInstancedBaseVertexBaseInstance();
1071 EXPECT_GL_NO_ERROR();
1072 checkDrawResult(true);
1073
1074 setupRegularIndexedBuffer(indexBuffer);
1075 doDrawElementsBaseVertexBaseInstanceReset();
1076 EXPECT_GL_NO_ERROR();
1077 checkDrawResult(false, true);
1078 }
1079
1080 // Tests basic functionality of glDrawArraysInstancedBaseInstanceEXT
TEST_P(DrawBaseInstanceTest,DrawArraysInstancedBaseInstance)1081 TEST_P(DrawBaseInstanceTest, DrawArraysInstancedBaseInstance)
1082 {
1083 // This test fails on certain Win7/Win2008Server AMD GPU
1084 // with driver version 23.20.185.235 when using OpenGL backend.
1085 // See comments under the ANGLE test of DrawArraysInstancedBaseInstance above.
1086 if (IsAMD() && IsWindows() && IsDesktopOpenGL())
1087 {
1088 SystemInfo *systemInfo = GetTestSystemInfo();
1089 if (!systemInfo->gpus.empty())
1090 {
1091 ANGLE_SKIP_TEST_IF(0x6613 == systemInfo->gpus[systemInfo->activeGPUIndex].deviceId);
1092 }
1093 }
1094
1095 ANGLE_SKIP_TEST_IF(!requestExtensions());
1096
1097 GLProgram program;
1098 setupProgram(program);
1099
1100 GLBuffer vertexBuffer;
1101 setupNonIndexedBuffers(vertexBuffer);
1102 setupPositionVertexAttribPointer();
1103
1104 GLBuffer instanceIDBuffer;
1105 if (!useBaseInstanceBuiltin())
1106 {
1107 setupInstanceIDBuffer(instanceIDBuffer);
1108 setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
1109 }
1110
1111 doDrawArraysInstancedBaseInstance();
1112 EXPECT_GL_NO_ERROR();
1113 checkDrawResult(false);
1114
1115 doDrawArraysBaseInstanceReset();
1116 EXPECT_GL_NO_ERROR();
1117 checkDrawResult(false, true);
1118 }
1119
1120 // Tests basic functionality of glDrawElementsInstancedBaseInstanceEXT
TEST_P(DrawBaseInstanceTest,DrawElementsInstancedBaseInstance)1121 TEST_P(DrawBaseInstanceTest, DrawElementsInstancedBaseInstance)
1122 {
1123 ANGLE_SKIP_TEST_IF(!requestExtensions());
1124
1125 GLProgram program;
1126 setupProgram(program, false);
1127
1128 GLBuffer vertexBuffer;
1129 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
1130 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mVertices.size(), mVertices.data(),
1131 getBufferDataUsage());
1132 EXPECT_GL_NO_ERROR();
1133 setupPositionVertexAttribPointer();
1134
1135 GLBuffer indexBuffer;
1136 setupRegularIndexedBuffer(indexBuffer);
1137
1138 GLBuffer instanceIDBuffer;
1139 if (!useBaseInstanceBuiltin())
1140 {
1141 setupInstanceIDBuffer(instanceIDBuffer);
1142 setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
1143 }
1144
1145 doDrawElementsInstancedBaseInstance();
1146 EXPECT_GL_NO_ERROR();
1147 checkDrawResult(false);
1148
1149 doDrawElementsInstancedBaseInstanceReset();
1150 EXPECT_GL_NO_ERROR();
1151 checkDrawResult(false, true);
1152 }
1153
1154 // Tests basic functionality of glDrawElementsInstancedBaseVertexBaseInstanceEXT
TEST_P(DrawBaseInstanceTest,DrawElementsInstancedBaseVertexBaseInstance)1155 TEST_P(DrawBaseInstanceTest, DrawElementsInstancedBaseVertexBaseInstance)
1156 {
1157 ANGLE_SKIP_TEST_IF(!requestExtensions());
1158
1159 GLProgram program;
1160 setupProgram(program, false);
1161
1162 GLBuffer indexBuffer;
1163 GLBuffer vertexBuffer;
1164 setupIndexedBuffers(vertexBuffer, indexBuffer);
1165 setupPositionVertexAttribPointer();
1166
1167 GLBuffer instanceIDBuffer;
1168 if (!useBaseInstanceBuiltin())
1169 {
1170 setupInstanceIDBuffer(instanceIDBuffer);
1171 setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
1172 }
1173
1174 doDrawElementsInstancedBaseVertexBaseInstance();
1175 EXPECT_GL_NO_ERROR();
1176 checkDrawResult(true);
1177
1178 setupRegularIndexedBuffer(indexBuffer);
1179 doDrawElementsBaseVertexBaseInstanceReset();
1180 EXPECT_GL_NO_ERROR();
1181 checkDrawResult(true, true);
1182 }
1183
1184 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrawBaseVertexBaseInstanceTest);
1185
1186 #define ANGLE_ALL_BASEVERTEXBASEINTANCE_TEST_PLATFORMS_ES3 \
1187 ES3_D3D11().enable(Feature::AlwaysEnableEmulatedMultidrawExtensions), \
1188 ES3_OPENGL().enable(Feature::AlwaysEnableEmulatedMultidrawExtensions), \
1189 ES3_OPENGLES().enable(Feature::AlwaysEnableEmulatedMultidrawExtensions), \
1190 ES3_VULKAN().enable(Feature::AlwaysEnableEmulatedMultidrawExtensions), \
1191 ES3_VULKAN_SWIFTSHADER().enable(Feature::AlwaysEnableEmulatedMultidrawExtensions), \
1192 ES3_METAL().enable(Feature::AlwaysEnableEmulatedMultidrawExtensions)
1193
1194 ANGLE_INSTANTIATE_TEST_COMBINE_3(
1195 DrawBaseVertexBaseInstanceTest,
1196 PrintToStringParamName(),
1197 testing::Values(BaseVertexOption::NoBaseVertex, BaseVertexOption::UseBaseVertex),
1198 testing::Values(BaseInstanceOption::NoBaseInstance, BaseInstanceOption::UseBaseInstance),
1199 testing::Values(BufferDataUsageOption::StaticDraw, BufferDataUsageOption::DynamicDraw),
1200 ANGLE_ALL_BASEVERTEXBASEINTANCE_TEST_PLATFORMS_ES3);
1201
1202 ANGLE_INSTANTIATE_TEST_COMBINE_3(
1203 DrawBaseInstanceTest,
1204 PrintToStringParamName(),
1205 testing::Values(BaseVertexOption::NoBaseVertex, BaseVertexOption::UseBaseVertex),
1206 testing::Values(BaseInstanceOption::NoBaseInstance, BaseInstanceOption::UseBaseInstance),
1207 testing::Values(BufferDataUsageOption::StaticDraw, BufferDataUsageOption::DynamicDraw),
1208 ANGLE_ALL_BASEVERTEXBASEINTANCE_TEST_PLATFORMS_ES3);
1209
1210 } // namespace
1211