xref: /aosp_15_r20/external/angle/src/tests/gl_tests/DrawBaseVertexVariantsTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2020 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker // DrawBaseVertexVariantsTest: Tests variants of drawElements*BaseVertex* call from different
8*8975f5c5SAndroid Build Coastguard Worker // extensions
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include "gpu_info_util/SystemInfo.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
13*8975f5c5SAndroid Build Coastguard Worker 
14*8975f5c5SAndroid Build Coastguard Worker #include <numeric>
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
17*8975f5c5SAndroid Build Coastguard Worker 
18*8975f5c5SAndroid Build Coastguard Worker namespace
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker 
21*8975f5c5SAndroid Build Coastguard Worker // Create a kWidth * kHeight canvas equally split into kCountX * kCountY tiles
22*8975f5c5SAndroid Build Coastguard Worker // each containing a quad partially covering each tile
23*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kWidth                   = 256;
24*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kHeight                  = 256;
25*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kCountX                  = 8;
26*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kCountY                  = 8;
27*8975f5c5SAndroid Build Coastguard Worker constexpr int kBoxCount                     = kCountX * kCountY;
28*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kIndexPatternRepeatCount = 3;
29*8975f5c5SAndroid Build Coastguard Worker constexpr std::array<GLfloat, 2> kTileSize  = {
30*8975f5c5SAndroid Build Coastguard Worker     1.f / static_cast<GLfloat>(kCountX),
31*8975f5c5SAndroid Build Coastguard Worker     1.f / static_cast<GLfloat>(kCountY),
32*8975f5c5SAndroid Build Coastguard Worker };
33*8975f5c5SAndroid Build Coastguard Worker constexpr std::array<uint32_t, 2> kTilePixelSize  = {kWidth / kCountX, kHeight / kCountY};
34*8975f5c5SAndroid Build Coastguard Worker constexpr std::array<GLfloat, 2> kQuadRadius      = {0.25f * kTileSize[0], 0.25f * kTileSize[1]};
35*8975f5c5SAndroid Build Coastguard Worker constexpr std::array<uint32_t, 2> kPixelCheckSize = {
36*8975f5c5SAndroid Build Coastguard Worker     static_cast<uint32_t>(kQuadRadius[0] * kWidth),
37*8975f5c5SAndroid Build Coastguard Worker     static_cast<uint32_t>(kQuadRadius[1] * kHeight)};
38*8975f5c5SAndroid Build Coastguard Worker constexpr GLenum kBufferDataUsage[] = {GL_STATIC_DRAW, GL_DYNAMIC_DRAW, GL_STREAM_DRAW};
39*8975f5c5SAndroid Build Coastguard Worker 
GetTileCenter(uint32_t x,uint32_t y)40*8975f5c5SAndroid Build Coastguard Worker constexpr std::array<GLfloat, 2> GetTileCenter(uint32_t x, uint32_t y)
41*8975f5c5SAndroid Build Coastguard Worker {
42*8975f5c5SAndroid Build Coastguard Worker     return {
43*8975f5c5SAndroid Build Coastguard Worker         kTileSize[0] * (0.5f + static_cast<GLfloat>(x)),
44*8975f5c5SAndroid Build Coastguard Worker         kTileSize[1] * (0.5f + static_cast<GLfloat>(y)),
45*8975f5c5SAndroid Build Coastguard Worker     };
46*8975f5c5SAndroid Build Coastguard Worker }
GetQuadVertices(uint32_t x,uint32_t y)47*8975f5c5SAndroid Build Coastguard Worker constexpr std::array<std::array<GLfloat, 2>, 4> GetQuadVertices(uint32_t x, uint32_t y)
48*8975f5c5SAndroid Build Coastguard Worker {
49*8975f5c5SAndroid Build Coastguard Worker     const auto center = GetTileCenter(x, y);
50*8975f5c5SAndroid Build Coastguard Worker     return {
51*8975f5c5SAndroid Build Coastguard Worker         std::array<GLfloat, 2>{center[0] - kQuadRadius[0], center[1] - kQuadRadius[1]},
52*8975f5c5SAndroid Build Coastguard Worker         std::array<GLfloat, 2>{center[0] + kQuadRadius[0], center[1] - kQuadRadius[1]},
53*8975f5c5SAndroid Build Coastguard Worker         std::array<GLfloat, 2>{center[0] + kQuadRadius[0], center[1] + kQuadRadius[1]},
54*8975f5c5SAndroid Build Coastguard Worker         std::array<GLfloat, 2>{center[0] - kQuadRadius[0], center[1] + kQuadRadius[1]},
55*8975f5c5SAndroid Build Coastguard Worker     };
56*8975f5c5SAndroid Build Coastguard Worker }
57*8975f5c5SAndroid Build Coastguard Worker 
58*8975f5c5SAndroid Build Coastguard Worker enum class DrawCallVariants
59*8975f5c5SAndroid Build Coastguard Worker {
60*8975f5c5SAndroid Build Coastguard Worker     DrawElementsBaseVertex,
61*8975f5c5SAndroid Build Coastguard Worker     DrawElementsInstancedBaseVertex,
62*8975f5c5SAndroid Build Coastguard Worker     DrawRangeElementsBaseVertex,
63*8975f5c5SAndroid Build Coastguard Worker     DrawElementsInstancedBaseVertexBaseInstance
64*8975f5c5SAndroid Build Coastguard Worker };
65*8975f5c5SAndroid Build Coastguard Worker 
66*8975f5c5SAndroid Build Coastguard Worker using DrawBaseVertexVariantsTestParams = std::tuple<angle::PlatformParameters, GLenum>;
67*8975f5c5SAndroid Build Coastguard Worker 
DrawBaseVertexVariantsTestPrint(const::testing::TestParamInfo<DrawBaseVertexVariantsTestParams> & paramsInfo)68*8975f5c5SAndroid Build Coastguard Worker std::string DrawBaseVertexVariantsTestPrint(
69*8975f5c5SAndroid Build Coastguard Worker     const ::testing::TestParamInfo<DrawBaseVertexVariantsTestParams> &paramsInfo)
70*8975f5c5SAndroid Build Coastguard Worker {
71*8975f5c5SAndroid Build Coastguard Worker     const DrawBaseVertexVariantsTestParams &params = paramsInfo.param;
72*8975f5c5SAndroid Build Coastguard Worker     std::ostringstream out;
73*8975f5c5SAndroid Build Coastguard Worker 
74*8975f5c5SAndroid Build Coastguard Worker     out << std::get<0>(params) << "__";
75*8975f5c5SAndroid Build Coastguard Worker 
76*8975f5c5SAndroid Build Coastguard Worker     switch (std::get<1>(params))
77*8975f5c5SAndroid Build Coastguard Worker     {
78*8975f5c5SAndroid Build Coastguard Worker         case GL_STATIC_DRAW:
79*8975f5c5SAndroid Build Coastguard Worker             out << "STATIC_DRAW";
80*8975f5c5SAndroid Build Coastguard Worker             break;
81*8975f5c5SAndroid Build Coastguard Worker         case GL_DYNAMIC_DRAW:
82*8975f5c5SAndroid Build Coastguard Worker             out << "DYNAMIC_DRAW";
83*8975f5c5SAndroid Build Coastguard Worker             break;
84*8975f5c5SAndroid Build Coastguard Worker         case GL_STREAM_DRAW:
85*8975f5c5SAndroid Build Coastguard Worker             out << "STREAM_DRAW";
86*8975f5c5SAndroid Build Coastguard Worker             break;
87*8975f5c5SAndroid Build Coastguard Worker         default:
88*8975f5c5SAndroid Build Coastguard Worker             out << "UPDATE_THIS_SWITCH";
89*8975f5c5SAndroid Build Coastguard Worker             break;
90*8975f5c5SAndroid Build Coastguard Worker     }
91*8975f5c5SAndroid Build Coastguard Worker 
92*8975f5c5SAndroid Build Coastguard Worker     return out.str();
93*8975f5c5SAndroid Build Coastguard Worker }
94*8975f5c5SAndroid Build Coastguard Worker 
95*8975f5c5SAndroid Build Coastguard Worker // These tests check correctness of variants of baseVertex draw calls from different extensions
96*8975f5c5SAndroid Build Coastguard Worker 
97*8975f5c5SAndroid Build Coastguard Worker class DrawBaseVertexVariantsTest : public ANGLETest<DrawBaseVertexVariantsTestParams>
98*8975f5c5SAndroid Build Coastguard Worker {
99*8975f5c5SAndroid Build Coastguard Worker   protected:
DrawBaseVertexVariantsTest()100*8975f5c5SAndroid Build Coastguard Worker     DrawBaseVertexVariantsTest()
101*8975f5c5SAndroid Build Coastguard Worker     {
102*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(kWidth);
103*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(kHeight);
104*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
105*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
106*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
107*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
108*8975f5c5SAndroid Build Coastguard Worker 
109*8975f5c5SAndroid Build Coastguard Worker         std::array<GLushort, 6> indices = {0, 1, 2, 0, 2, 3};
110*8975f5c5SAndroid Build Coastguard Worker         mIndices.resize(indices.size() * kIndexPatternRepeatCount);
111*8975f5c5SAndroid Build Coastguard Worker         for (uint32_t i = 0; i < kIndexPatternRepeatCount; i++)
112*8975f5c5SAndroid Build Coastguard Worker         {
113*8975f5c5SAndroid Build Coastguard Worker             size_t o  = i * indices.size();
114*8975f5c5SAndroid Build Coastguard Worker             size_t vo = i * 4;  // each quad has 4 vertices, index offset by 4
115*8975f5c5SAndroid Build Coastguard Worker             for (size_t j = 0; j < indices.size(); j++)
116*8975f5c5SAndroid Build Coastguard Worker             {
117*8975f5c5SAndroid Build Coastguard Worker                 mIndices[o + j] = vo + indices[j];
118*8975f5c5SAndroid Build Coastguard Worker             }
119*8975f5c5SAndroid Build Coastguard Worker         }
120*8975f5c5SAndroid Build Coastguard Worker 
121*8975f5c5SAndroid Build Coastguard Worker         mColorPalette = {GLColor(0x7f, 0x7f, 0x7f, 0xff),
122*8975f5c5SAndroid Build Coastguard Worker                          GLColor::red,
123*8975f5c5SAndroid Build Coastguard Worker                          GLColor::green,
124*8975f5c5SAndroid Build Coastguard Worker                          GLColor::yellow,
125*8975f5c5SAndroid Build Coastguard Worker                          GLColor::blue,
126*8975f5c5SAndroid Build Coastguard Worker                          GLColor::magenta,
127*8975f5c5SAndroid Build Coastguard Worker                          GLColor::cyan,
128*8975f5c5SAndroid Build Coastguard Worker                          GLColor::white};
129*8975f5c5SAndroid Build Coastguard Worker 
130*8975f5c5SAndroid Build Coastguard Worker         for (uint32_t y = 0; y < kCountY; ++y)
131*8975f5c5SAndroid Build Coastguard Worker         {
132*8975f5c5SAndroid Build Coastguard Worker             for (uint32_t x = 0; x < kCountX; ++x)
133*8975f5c5SAndroid Build Coastguard Worker             {
134*8975f5c5SAndroid Build Coastguard Worker                 // v3 ---- v2
135*8975f5c5SAndroid Build Coastguard Worker                 // |       |
136*8975f5c5SAndroid Build Coastguard Worker                 // |       |
137*8975f5c5SAndroid Build Coastguard Worker                 // v0 ---- v1
138*8975f5c5SAndroid Build Coastguard Worker 
139*8975f5c5SAndroid Build Coastguard Worker                 const auto vs = ::GetQuadVertices(x, y);
140*8975f5c5SAndroid Build Coastguard Worker 
141*8975f5c5SAndroid Build Coastguard Worker                 for (const auto &v : vs)
142*8975f5c5SAndroid Build Coastguard Worker                 {
143*8975f5c5SAndroid Build Coastguard Worker                     mVertices.insert(mVertices.end(), v.begin(), v.end());
144*8975f5c5SAndroid Build Coastguard Worker                 }
145*8975f5c5SAndroid Build Coastguard Worker 
146*8975f5c5SAndroid Build Coastguard Worker                 const auto &colorPicked = mColorPalette[(x + y) % mColorPalette.size()];
147*8975f5c5SAndroid Build Coastguard Worker                 for (int i = 0; i < 4; ++i)
148*8975f5c5SAndroid Build Coastguard Worker                 {
149*8975f5c5SAndroid Build Coastguard Worker                     mVertexColors.push_back(colorPicked.R);
150*8975f5c5SAndroid Build Coastguard Worker                     mVertexColors.push_back(colorPicked.G);
151*8975f5c5SAndroid Build Coastguard Worker                     mVertexColors.push_back(colorPicked.B);
152*8975f5c5SAndroid Build Coastguard Worker                     mVertexColors.push_back(colorPicked.A);
153*8975f5c5SAndroid Build Coastguard Worker                 }
154*8975f5c5SAndroid Build Coastguard Worker             }
155*8975f5c5SAndroid Build Coastguard Worker         }
156*8975f5c5SAndroid Build Coastguard Worker 
157*8975f5c5SAndroid Build Coastguard Worker         mRegularIndices.resize(kCountY * kCountX * mIndices.size());
158*8975f5c5SAndroid Build Coastguard Worker         for (uint32_t y = 0; y < kCountY; y++)
159*8975f5c5SAndroid Build Coastguard Worker         {
160*8975f5c5SAndroid Build Coastguard Worker             for (uint32_t x = 0; x < kCountX; x++)
161*8975f5c5SAndroid Build Coastguard Worker             {
162*8975f5c5SAndroid Build Coastguard Worker                 uint32_t i  = x + y * kCountX;
163*8975f5c5SAndroid Build Coastguard Worker                 uint32_t oi = 6 * i;
164*8975f5c5SAndroid Build Coastguard Worker                 uint32_t ov = 4 * i;
165*8975f5c5SAndroid Build Coastguard Worker                 for (uint32_t j = 0; j < 6; j++)
166*8975f5c5SAndroid Build Coastguard Worker                 {
167*8975f5c5SAndroid Build Coastguard Worker                     mRegularIndices[oi + j] = mIndices[j] + ov;
168*8975f5c5SAndroid Build Coastguard Worker                 }
169*8975f5c5SAndroid Build Coastguard Worker             }
170*8975f5c5SAndroid Build Coastguard Worker         }
171*8975f5c5SAndroid Build Coastguard Worker     }
172*8975f5c5SAndroid Build Coastguard Worker 
setupProgram(GLProgram & program)173*8975f5c5SAndroid Build Coastguard Worker     void setupProgram(GLProgram &program)
174*8975f5c5SAndroid Build Coastguard Worker     {
175*8975f5c5SAndroid Build Coastguard Worker         constexpr char vs[] = R"(
176*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
177*8975f5c5SAndroid Build Coastguard Worker attribute vec2 vPosition;
178*8975f5c5SAndroid Build Coastguard Worker attribute vec4 vColor;
179*8975f5c5SAndroid Build Coastguard Worker varying vec4 color;
180*8975f5c5SAndroid Build Coastguard Worker void main()
181*8975f5c5SAndroid Build Coastguard Worker {
182*8975f5c5SAndroid Build Coastguard Worker     gl_Position = vec4(vec3(vPosition, 1.0) * 2.0 - 1.0, 1.0);
183*8975f5c5SAndroid Build Coastguard Worker     color = vColor;
184*8975f5c5SAndroid Build Coastguard Worker })";
185*8975f5c5SAndroid Build Coastguard Worker         constexpr char fs[] = R"(
186*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
187*8975f5c5SAndroid Build Coastguard Worker varying vec4 color;
188*8975f5c5SAndroid Build Coastguard Worker void main()
189*8975f5c5SAndroid Build Coastguard Worker {
190*8975f5c5SAndroid Build Coastguard Worker     gl_FragColor = color;
191*8975f5c5SAndroid Build Coastguard Worker })";
192*8975f5c5SAndroid Build Coastguard Worker         program.makeRaster(vs, fs);
193*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
194*8975f5c5SAndroid Build Coastguard Worker         ASSERT_TRUE(program.valid());
195*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(program);
196*8975f5c5SAndroid Build Coastguard Worker         mPositionLoc = glGetAttribLocation(program, "vPosition");
197*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(-1, mPositionLoc);
198*8975f5c5SAndroid Build Coastguard Worker         mColorLoc = glGetAttribLocation(program, "vColor");
199*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(-1, mColorLoc);
200*8975f5c5SAndroid Build Coastguard Worker     }
201*8975f5c5SAndroid Build Coastguard Worker 
setupIndexedBuffers(GLBuffer & vertexPositionBuffer,GLBuffer & vertexColorBuffer,GLBuffer & indexBuffer)202*8975f5c5SAndroid Build Coastguard Worker     void setupIndexedBuffers(GLBuffer &vertexPositionBuffer,
203*8975f5c5SAndroid Build Coastguard Worker                              GLBuffer &vertexColorBuffer,
204*8975f5c5SAndroid Build Coastguard Worker                              GLBuffer &indexBuffer)
205*8975f5c5SAndroid Build Coastguard Worker     {
206*8975f5c5SAndroid Build Coastguard Worker         GLenum usage = std::get<1>(GetParam());
207*8975f5c5SAndroid Build Coastguard Worker 
208*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, vertexColorBuffer);
209*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, sizeof(GLubyte) * mVertexColors.size(), mVertexColors.data(),
210*8975f5c5SAndroid Build Coastguard Worker                      usage);
211*8975f5c5SAndroid Build Coastguard Worker 
212*8975f5c5SAndroid Build Coastguard Worker         glEnableVertexAttribArray(mColorLoc);
213*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(mColorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
214*8975f5c5SAndroid Build Coastguard Worker 
215*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer);
216*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mVertices.size(), mVertices.data(), usage);
217*8975f5c5SAndroid Build Coastguard Worker 
218*8975f5c5SAndroid Build Coastguard Worker         glEnableVertexAttribArray(mPositionLoc);
219*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(mPositionLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
220*8975f5c5SAndroid Build Coastguard Worker 
221*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
222*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * mIndices.size(), mIndices.data(),
223*8975f5c5SAndroid Build Coastguard Worker                      usage);
224*8975f5c5SAndroid Build Coastguard Worker 
225*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
226*8975f5c5SAndroid Build Coastguard Worker     }
227*8975f5c5SAndroid Build Coastguard Worker 
doDrawElementsBaseVertexVariants(DrawCallVariants drawCallType)228*8975f5c5SAndroid Build Coastguard Worker     void doDrawElementsBaseVertexVariants(DrawCallVariants drawCallType)
229*8975f5c5SAndroid Build Coastguard Worker     {
230*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
231*8975f5c5SAndroid Build Coastguard Worker 
232*8975f5c5SAndroid Build Coastguard Worker         int baseRepetition = 0;
233*8975f5c5SAndroid Build Coastguard Worker         int i              = 0;
234*8975f5c5SAndroid Build Coastguard Worker 
235*8975f5c5SAndroid Build Coastguard Worker         // Start at various repetitions within the patterned index buffer to exercise base
236*8975f5c5SAndroid Build Coastguard Worker         // index.
237*8975f5c5SAndroid Build Coastguard Worker 
238*8975f5c5SAndroid Build Coastguard Worker         static_assert(kIndexPatternRepeatCount >= 3, "Repeat pattern count should be at least 3");
239*8975f5c5SAndroid Build Coastguard Worker 
240*8975f5c5SAndroid Build Coastguard Worker         while (i < kBoxCount)
241*8975f5c5SAndroid Build Coastguard Worker         {
242*8975f5c5SAndroid Build Coastguard Worker             int repetitionCount = std::min(3 - baseRepetition, kBoxCount - i);
243*8975f5c5SAndroid Build Coastguard Worker 
244*8975f5c5SAndroid Build Coastguard Worker             updateVertexColorData(i, repetitionCount);
245*8975f5c5SAndroid Build Coastguard Worker 
246*8975f5c5SAndroid Build Coastguard Worker             switch (drawCallType)
247*8975f5c5SAndroid Build Coastguard Worker             {
248*8975f5c5SAndroid Build Coastguard Worker                 case DrawCallVariants::DrawElementsInstancedBaseVertexBaseInstance:
249*8975f5c5SAndroid Build Coastguard Worker                     glDrawElementsInstancedBaseVertexBaseInstanceANGLE(
250*8975f5c5SAndroid Build Coastguard Worker                         GL_TRIANGLES, repetitionCount * 6, GL_UNSIGNED_SHORT,
251*8975f5c5SAndroid Build Coastguard Worker                         reinterpret_cast<GLvoid *>(
252*8975f5c5SAndroid Build Coastguard Worker                             static_cast<uintptr_t>(baseRepetition * 6 * sizeof(GLushort))),
253*8975f5c5SAndroid Build Coastguard Worker                         1, (i - baseRepetition) * 4, 0);
254*8975f5c5SAndroid Build Coastguard Worker                     break;
255*8975f5c5SAndroid Build Coastguard Worker                 case DrawCallVariants::DrawElementsBaseVertex:
256*8975f5c5SAndroid Build Coastguard Worker                     glDrawElementsBaseVertexEXT(
257*8975f5c5SAndroid Build Coastguard Worker                         GL_TRIANGLES, repetitionCount * 6, GL_UNSIGNED_SHORT,
258*8975f5c5SAndroid Build Coastguard Worker                         reinterpret_cast<GLvoid *>(
259*8975f5c5SAndroid Build Coastguard Worker                             static_cast<uintptr_t>(baseRepetition * 6 * sizeof(GLushort))),
260*8975f5c5SAndroid Build Coastguard Worker                         (i - baseRepetition) * 4);
261*8975f5c5SAndroid Build Coastguard Worker                     break;
262*8975f5c5SAndroid Build Coastguard Worker                 case DrawCallVariants::DrawElementsInstancedBaseVertex:
263*8975f5c5SAndroid Build Coastguard Worker                     glDrawElementsInstancedBaseVertexEXT(
264*8975f5c5SAndroid Build Coastguard Worker                         GL_TRIANGLES, repetitionCount * 6, GL_UNSIGNED_SHORT,
265*8975f5c5SAndroid Build Coastguard Worker                         reinterpret_cast<GLvoid *>(
266*8975f5c5SAndroid Build Coastguard Worker                             static_cast<uintptr_t>(baseRepetition * 6 * sizeof(GLushort))),
267*8975f5c5SAndroid Build Coastguard Worker                         1, (i - baseRepetition) * 4);
268*8975f5c5SAndroid Build Coastguard Worker                     break;
269*8975f5c5SAndroid Build Coastguard Worker                 case DrawCallVariants::DrawRangeElementsBaseVertex:
270*8975f5c5SAndroid Build Coastguard Worker                     glDrawRangeElementsBaseVertexEXT(
271*8975f5c5SAndroid Build Coastguard Worker                         GL_TRIANGLES, baseRepetition * 4,
272*8975f5c5SAndroid Build Coastguard Worker                         (baseRepetition + repetitionCount) * 4 - 1, repetitionCount * 6,
273*8975f5c5SAndroid Build Coastguard Worker                         GL_UNSIGNED_SHORT,
274*8975f5c5SAndroid Build Coastguard Worker                         reinterpret_cast<GLvoid *>(
275*8975f5c5SAndroid Build Coastguard Worker                             static_cast<uintptr_t>(baseRepetition * 6 * sizeof(GLushort))),
276*8975f5c5SAndroid Build Coastguard Worker                         (i - baseRepetition) * 4);
277*8975f5c5SAndroid Build Coastguard Worker                     break;
278*8975f5c5SAndroid Build Coastguard Worker                 default:
279*8975f5c5SAndroid Build Coastguard Worker                     EXPECT_TRUE(false);
280*8975f5c5SAndroid Build Coastguard Worker                     break;
281*8975f5c5SAndroid Build Coastguard Worker             }
282*8975f5c5SAndroid Build Coastguard Worker 
283*8975f5c5SAndroid Build Coastguard Worker             baseRepetition = (baseRepetition + 1) % 3;
284*8975f5c5SAndroid Build Coastguard Worker             i += repetitionCount;
285*8975f5c5SAndroid Build Coastguard Worker         }
286*8975f5c5SAndroid Build Coastguard Worker 
287*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
288*8975f5c5SAndroid Build Coastguard Worker         checkDrawResult();
289*8975f5c5SAndroid Build Coastguard Worker     }
290*8975f5c5SAndroid Build Coastguard Worker 
updateVertexColorData(GLint drawnQuadCount,GLint toDrawQuadCount)291*8975f5c5SAndroid Build Coastguard Worker     void updateVertexColorData(GLint drawnQuadCount, GLint toDrawQuadCount)
292*8975f5c5SAndroid Build Coastguard Worker     {
293*8975f5c5SAndroid Build Coastguard Worker         // update the vertex color of the next [count] of quads to draw
294*8975f5c5SAndroid Build Coastguard Worker         if (std::get<1>(GetParam()) == GL_STATIC_DRAW)
295*8975f5c5SAndroid Build Coastguard Worker         {
296*8975f5c5SAndroid Build Coastguard Worker             return;
297*8975f5c5SAndroid Build Coastguard Worker         }
298*8975f5c5SAndroid Build Coastguard Worker 
299*8975f5c5SAndroid Build Coastguard Worker         GLint offset = sizeof(GLubyte) * drawnQuadCount * 4 * sizeof(GLColor);
300*8975f5c5SAndroid Build Coastguard Worker 
301*8975f5c5SAndroid Build Coastguard Worker         for (GLint i = 0; i < toDrawQuadCount; i++)
302*8975f5c5SAndroid Build Coastguard Worker         {
303*8975f5c5SAndroid Build Coastguard Worker             const GLColor &color = mColorPalette[(drawnQuadCount + i) % mColorPalette.size()];
304*8975f5c5SAndroid Build Coastguard Worker             for (GLint j = 0; j < 4; j++)
305*8975f5c5SAndroid Build Coastguard Worker             {
306*8975f5c5SAndroid Build Coastguard Worker                 glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(GLColor), color.data());
307*8975f5c5SAndroid Build Coastguard Worker                 offset += sizeof(GLColor);
308*8975f5c5SAndroid Build Coastguard Worker             }
309*8975f5c5SAndroid Build Coastguard Worker         }
310*8975f5c5SAndroid Build Coastguard Worker     }
311*8975f5c5SAndroid Build Coastguard Worker 
checkDrawResult()312*8975f5c5SAndroid Build Coastguard Worker     void checkDrawResult()
313*8975f5c5SAndroid Build Coastguard Worker     {
314*8975f5c5SAndroid Build Coastguard Worker         bool dynamicLayout = std::get<1>(GetParam()) == GL_STATIC_DRAW ? false : true;
315*8975f5c5SAndroid Build Coastguard Worker 
316*8975f5c5SAndroid Build Coastguard Worker         for (uint32_t y = 0; y < kCountY; ++y)
317*8975f5c5SAndroid Build Coastguard Worker         {
318*8975f5c5SAndroid Build Coastguard Worker             for (uint32_t x = 0; x < kCountX; ++x)
319*8975f5c5SAndroid Build Coastguard Worker             {
320*8975f5c5SAndroid Build Coastguard Worker                 uint32_t center_x = x * kTilePixelSize[0] + kTilePixelSize[0] / 2;
321*8975f5c5SAndroid Build Coastguard Worker                 uint32_t center_y = y * kTilePixelSize[1] + kTilePixelSize[1] / 2;
322*8975f5c5SAndroid Build Coastguard Worker 
323*8975f5c5SAndroid Build Coastguard Worker                 const auto &color =
324*8975f5c5SAndroid Build Coastguard Worker                     mColorPalette[(dynamicLayout ? x : x + y) % mColorPalette.size()];
325*8975f5c5SAndroid Build Coastguard Worker 
326*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_PIXEL_NEAR(center_x - kPixelCheckSize[0] / 2,
327*8975f5c5SAndroid Build Coastguard Worker                                   center_y - kPixelCheckSize[1] / 2, color[0], color[1], color[2],
328*8975f5c5SAndroid Build Coastguard Worker                                   color[3], 1);
329*8975f5c5SAndroid Build Coastguard Worker             }
330*8975f5c5SAndroid Build Coastguard Worker         }
331*8975f5c5SAndroid Build Coastguard Worker     }
332*8975f5c5SAndroid Build Coastguard Worker 
requestAngleBaseVertexBaseInstanceExtensions()333*8975f5c5SAndroid Build Coastguard Worker     bool requestAngleBaseVertexBaseInstanceExtensions()
334*8975f5c5SAndroid Build Coastguard Worker     {
335*8975f5c5SAndroid Build Coastguard Worker         if (getClientMajorVersion() <= 2)
336*8975f5c5SAndroid Build Coastguard Worker         {
337*8975f5c5SAndroid Build Coastguard Worker             if (!EnsureGLExtensionEnabled("GL_ANGLE_instanced_arrays"))
338*8975f5c5SAndroid Build Coastguard Worker             {
339*8975f5c5SAndroid Build Coastguard Worker                 return false;
340*8975f5c5SAndroid Build Coastguard Worker             }
341*8975f5c5SAndroid Build Coastguard Worker         }
342*8975f5c5SAndroid Build Coastguard Worker         if (!EnsureGLExtensionEnabled("GL_ANGLE_base_vertex_base_instance"))
343*8975f5c5SAndroid Build Coastguard Worker         {
344*8975f5c5SAndroid Build Coastguard Worker             return false;
345*8975f5c5SAndroid Build Coastguard Worker         }
346*8975f5c5SAndroid Build Coastguard Worker 
347*8975f5c5SAndroid Build Coastguard Worker         return EnsureGLExtensionEnabled("GL_ANGLE_base_vertex_base_instance_shader_builtin");
348*8975f5c5SAndroid Build Coastguard Worker     }
349*8975f5c5SAndroid Build Coastguard Worker 
requestNativeBaseVertexExtensions()350*8975f5c5SAndroid Build Coastguard Worker     bool requestNativeBaseVertexExtensions()
351*8975f5c5SAndroid Build Coastguard Worker     {
352*8975f5c5SAndroid Build Coastguard Worker         return (EnsureGLExtensionEnabled("GL_OES_draw_elements_base_vertex") ||
353*8975f5c5SAndroid Build Coastguard Worker                 EnsureGLExtensionEnabled("GL_EXT_draw_elements_base_vertex"));
354*8975f5c5SAndroid Build Coastguard Worker     }
355*8975f5c5SAndroid Build Coastguard Worker 
356*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLushort> mIndices;
357*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLfloat> mVertices;
358*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLubyte> mVertexColors;
359*8975f5c5SAndroid Build Coastguard Worker 
360*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLColor> mColorPalette;
361*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLushort> mRegularIndices;
362*8975f5c5SAndroid Build Coastguard Worker     GLint mPositionLoc;
363*8975f5c5SAndroid Build Coastguard Worker     GLint mColorLoc;
364*8975f5c5SAndroid Build Coastguard Worker };
365*8975f5c5SAndroid Build Coastguard Worker 
366*8975f5c5SAndroid Build Coastguard Worker // Test drawElementsBaseVertex from OES/EXT_draw_elements_base_vertex
TEST_P(DrawBaseVertexVariantsTest,DrawElementsBaseVertex)367*8975f5c5SAndroid Build Coastguard Worker TEST_P(DrawBaseVertexVariantsTest, DrawElementsBaseVertex)
368*8975f5c5SAndroid Build Coastguard Worker {
369*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestNativeBaseVertexExtensions());
370*8975f5c5SAndroid Build Coastguard Worker 
371*8975f5c5SAndroid Build Coastguard Worker     GLProgram program;
372*8975f5c5SAndroid Build Coastguard Worker     setupProgram(program);
373*8975f5c5SAndroid Build Coastguard Worker 
374*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer;
375*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexPositionBuffer;
376*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexColorBuffer;
377*8975f5c5SAndroid Build Coastguard Worker     setupIndexedBuffers(vertexPositionBuffer, vertexColorBuffer, indexBuffer);
378*8975f5c5SAndroid Build Coastguard Worker 
379*8975f5c5SAndroid Build Coastguard Worker     // for potential update vertex color later
380*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, vertexColorBuffer);
381*8975f5c5SAndroid Build Coastguard Worker 
382*8975f5c5SAndroid Build Coastguard Worker     doDrawElementsBaseVertexVariants(DrawCallVariants::DrawElementsBaseVertex);
383*8975f5c5SAndroid Build Coastguard Worker }
384*8975f5c5SAndroid Build Coastguard Worker 
385*8975f5c5SAndroid Build Coastguard Worker // Test drawElementsInstancedBaseVertex from OES/EXT_draw_elements_base_vertex
TEST_P(DrawBaseVertexVariantsTest,DrawElementsInstancedBaseVertex)386*8975f5c5SAndroid Build Coastguard Worker TEST_P(DrawBaseVertexVariantsTest, DrawElementsInstancedBaseVertex)
387*8975f5c5SAndroid Build Coastguard Worker {
388*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestNativeBaseVertexExtensions());
389*8975f5c5SAndroid Build Coastguard Worker 
390*8975f5c5SAndroid Build Coastguard Worker     GLProgram program;
391*8975f5c5SAndroid Build Coastguard Worker     setupProgram(program);
392*8975f5c5SAndroid Build Coastguard Worker 
393*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer;
394*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexPositionBuffer;
395*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexColorBuffer;
396*8975f5c5SAndroid Build Coastguard Worker     setupIndexedBuffers(vertexPositionBuffer, vertexColorBuffer, indexBuffer);
397*8975f5c5SAndroid Build Coastguard Worker 
398*8975f5c5SAndroid Build Coastguard Worker     // for potential update vertex color later
399*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, vertexColorBuffer);
400*8975f5c5SAndroid Build Coastguard Worker 
401*8975f5c5SAndroid Build Coastguard Worker     doDrawElementsBaseVertexVariants(DrawCallVariants::DrawElementsInstancedBaseVertex);
402*8975f5c5SAndroid Build Coastguard Worker }
403*8975f5c5SAndroid Build Coastguard Worker 
404*8975f5c5SAndroid Build Coastguard Worker // Test drawRangeElementsBaseVertex from OES/EXT_draw_elements_base_vertex
TEST_P(DrawBaseVertexVariantsTest,DrawRangeElementsBaseVertex)405*8975f5c5SAndroid Build Coastguard Worker TEST_P(DrawBaseVertexVariantsTest, DrawRangeElementsBaseVertex)
406*8975f5c5SAndroid Build Coastguard Worker {
407*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestNativeBaseVertexExtensions());
408*8975f5c5SAndroid Build Coastguard Worker 
409*8975f5c5SAndroid Build Coastguard Worker     GLProgram program;
410*8975f5c5SAndroid Build Coastguard Worker     setupProgram(program);
411*8975f5c5SAndroid Build Coastguard Worker 
412*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer;
413*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexPositionBuffer;
414*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexColorBuffer;
415*8975f5c5SAndroid Build Coastguard Worker     setupIndexedBuffers(vertexPositionBuffer, vertexColorBuffer, indexBuffer);
416*8975f5c5SAndroid Build Coastguard Worker 
417*8975f5c5SAndroid Build Coastguard Worker     // for potential update vertex color later
418*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, vertexColorBuffer);
419*8975f5c5SAndroid Build Coastguard Worker 
420*8975f5c5SAndroid Build Coastguard Worker     doDrawElementsBaseVertexVariants(DrawCallVariants::DrawRangeElementsBaseVertex);
421*8975f5c5SAndroid Build Coastguard Worker }
422*8975f5c5SAndroid Build Coastguard Worker 
423*8975f5c5SAndroid Build Coastguard Worker // Test drawElementsInstancedBaseVertexBaseInstance from ANGLE_base_vertex_base_instance
TEST_P(DrawBaseVertexVariantsTest,DrawElementsInstancedBaseVertexBaseInstance)424*8975f5c5SAndroid Build Coastguard Worker TEST_P(DrawBaseVertexVariantsTest, DrawElementsInstancedBaseVertexBaseInstance)
425*8975f5c5SAndroid Build Coastguard Worker {
426*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestAngleBaseVertexBaseInstanceExtensions());
427*8975f5c5SAndroid Build Coastguard Worker 
428*8975f5c5SAndroid Build Coastguard Worker     GLProgram program;
429*8975f5c5SAndroid Build Coastguard Worker     setupProgram(program);
430*8975f5c5SAndroid Build Coastguard Worker 
431*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer;
432*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexPositionBuffer;
433*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexColorBuffer;
434*8975f5c5SAndroid Build Coastguard Worker     setupIndexedBuffers(vertexPositionBuffer, vertexColorBuffer, indexBuffer);
435*8975f5c5SAndroid Build Coastguard Worker 
436*8975f5c5SAndroid Build Coastguard Worker     // for potential update vertex color later
437*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, vertexColorBuffer);
438*8975f5c5SAndroid Build Coastguard Worker 
439*8975f5c5SAndroid Build Coastguard Worker     doDrawElementsBaseVertexVariants(DrawCallVariants::DrawElementsInstancedBaseVertexBaseInstance);
440*8975f5c5SAndroid Build Coastguard Worker }
441*8975f5c5SAndroid Build Coastguard Worker 
442*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrawBaseVertexVariantsTest);
443*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_COMBINE_1(DrawBaseVertexVariantsTest,
444*8975f5c5SAndroid Build Coastguard Worker                                  DrawBaseVertexVariantsTestPrint,
445*8975f5c5SAndroid Build Coastguard Worker                                  testing::ValuesIn(kBufferDataUsage),
446*8975f5c5SAndroid Build Coastguard Worker                                  ES3_D3D11(),
447*8975f5c5SAndroid Build Coastguard Worker                                  ES3_METAL(),
448*8975f5c5SAndroid Build Coastguard Worker                                  ES3_OPENGL(),
449*8975f5c5SAndroid Build Coastguard Worker                                  ES3_OPENGLES(),
450*8975f5c5SAndroid Build Coastguard Worker                                  ES3_VULKAN());
451*8975f5c5SAndroid Build Coastguard Worker 
452*8975f5c5SAndroid Build Coastguard Worker }  // namespace
453