xref: /aosp_15_r20/external/angle/src/tests/perf_tests/InstancingPerf.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 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 // InstancingPerf:
7*8975f5c5SAndroid Build Coastguard Worker //   Performance tests for ANGLE instanced draw calls.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include "ANGLEPerfTest.h"
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker #include <cmath>
13*8975f5c5SAndroid Build Coastguard Worker #include <sstream>
14*8975f5c5SAndroid Build Coastguard Worker 
15*8975f5c5SAndroid Build Coastguard Worker #include "util/Matrix.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "util/random_utils.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "util/shader_utils.h"
18*8975f5c5SAndroid Build Coastguard Worker 
19*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
20*8975f5c5SAndroid Build Coastguard Worker using namespace egl_platform;
21*8975f5c5SAndroid Build Coastguard Worker 
22*8975f5c5SAndroid Build Coastguard Worker namespace
23*8975f5c5SAndroid Build Coastguard Worker {
24*8975f5c5SAndroid Build Coastguard Worker 
AnimationSignal(float t)25*8975f5c5SAndroid Build Coastguard Worker float AnimationSignal(float t)
26*8975f5c5SAndroid Build Coastguard Worker {
27*8975f5c5SAndroid Build Coastguard Worker     float l = t / 2.0f;
28*8975f5c5SAndroid Build Coastguard Worker     float f = l - std::floor(l);
29*8975f5c5SAndroid Build Coastguard Worker     return (f > 0.5f ? 1.0f - f : f) * 4.0f - 1.0f;
30*8975f5c5SAndroid Build Coastguard Worker }
31*8975f5c5SAndroid Build Coastguard Worker 
32*8975f5c5SAndroid Build Coastguard Worker template <typename T>
VectorSizeBytes(const std::vector<T> & vec)33*8975f5c5SAndroid Build Coastguard Worker size_t VectorSizeBytes(const std::vector<T> &vec)
34*8975f5c5SAndroid Build Coastguard Worker {
35*8975f5c5SAndroid Build Coastguard Worker     return sizeof(T) * vec.size();
36*8975f5c5SAndroid Build Coastguard Worker }
37*8975f5c5SAndroid Build Coastguard Worker 
RandomVector3(RNG * rng)38*8975f5c5SAndroid Build Coastguard Worker Vector3 RandomVector3(RNG *rng)
39*8975f5c5SAndroid Build Coastguard Worker {
40*8975f5c5SAndroid Build Coastguard Worker     return Vector3(rng->randomNegativeOneToOne(), rng->randomNegativeOneToOne(),
41*8975f5c5SAndroid Build Coastguard Worker                    rng->randomNegativeOneToOne());
42*8975f5c5SAndroid Build Coastguard Worker }
43*8975f5c5SAndroid Build Coastguard Worker 
44*8975f5c5SAndroid Build Coastguard Worker struct InstancingPerfParams final : public RenderTestParams
45*8975f5c5SAndroid Build Coastguard Worker {
46*8975f5c5SAndroid Build Coastguard Worker     // Common default options
InstancingPerfParams__anondd57d3d00111::InstancingPerfParams47*8975f5c5SAndroid Build Coastguard Worker     InstancingPerfParams()
48*8975f5c5SAndroid Build Coastguard Worker     {
49*8975f5c5SAndroid Build Coastguard Worker         majorVersion      = 2;
50*8975f5c5SAndroid Build Coastguard Worker         minorVersion      = 0;
51*8975f5c5SAndroid Build Coastguard Worker         windowWidth       = 256;
52*8975f5c5SAndroid Build Coastguard Worker         windowHeight      = 256;
53*8975f5c5SAndroid Build Coastguard Worker         iterationsPerStep = 1;
54*8975f5c5SAndroid Build Coastguard Worker         runTimeSeconds    = 10.0;
55*8975f5c5SAndroid Build Coastguard Worker         animationEnabled  = false;
56*8975f5c5SAndroid Build Coastguard Worker         instancingEnabled = true;
57*8975f5c5SAndroid Build Coastguard Worker     }
58*8975f5c5SAndroid Build Coastguard Worker 
story__anondd57d3d00111::InstancingPerfParams59*8975f5c5SAndroid Build Coastguard Worker     std::string story() const override
60*8975f5c5SAndroid Build Coastguard Worker     {
61*8975f5c5SAndroid Build Coastguard Worker         std::stringstream strstr;
62*8975f5c5SAndroid Build Coastguard Worker 
63*8975f5c5SAndroid Build Coastguard Worker         strstr << RenderTestParams::story();
64*8975f5c5SAndroid Build Coastguard Worker 
65*8975f5c5SAndroid Build Coastguard Worker         if (!instancingEnabled)
66*8975f5c5SAndroid Build Coastguard Worker         {
67*8975f5c5SAndroid Build Coastguard Worker             strstr << "_billboards";
68*8975f5c5SAndroid Build Coastguard Worker         }
69*8975f5c5SAndroid Build Coastguard Worker 
70*8975f5c5SAndroid Build Coastguard Worker         return strstr.str();
71*8975f5c5SAndroid Build Coastguard Worker     }
72*8975f5c5SAndroid Build Coastguard Worker 
73*8975f5c5SAndroid Build Coastguard Worker     double runTimeSeconds;
74*8975f5c5SAndroid Build Coastguard Worker     bool animationEnabled;
75*8975f5c5SAndroid Build Coastguard Worker     bool instancingEnabled;
76*8975f5c5SAndroid Build Coastguard Worker };
77*8975f5c5SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const InstancingPerfParams & params)78*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const InstancingPerfParams &params)
79*8975f5c5SAndroid Build Coastguard Worker {
80*8975f5c5SAndroid Build Coastguard Worker     os << params.backendAndStory().substr(1);
81*8975f5c5SAndroid Build Coastguard Worker     return os;
82*8975f5c5SAndroid Build Coastguard Worker }
83*8975f5c5SAndroid Build Coastguard Worker 
84*8975f5c5SAndroid Build Coastguard Worker class InstancingPerfBenchmark : public ANGLERenderTest,
85*8975f5c5SAndroid Build Coastguard Worker                                 public ::testing::WithParamInterface<InstancingPerfParams>
86*8975f5c5SAndroid Build Coastguard Worker {
87*8975f5c5SAndroid Build Coastguard Worker   public:
88*8975f5c5SAndroid Build Coastguard Worker     InstancingPerfBenchmark();
89*8975f5c5SAndroid Build Coastguard Worker 
90*8975f5c5SAndroid Build Coastguard Worker     void initializeBenchmark() override;
91*8975f5c5SAndroid Build Coastguard Worker     void destroyBenchmark() override;
92*8975f5c5SAndroid Build Coastguard Worker     void drawBenchmark() override;
93*8975f5c5SAndroid Build Coastguard Worker 
94*8975f5c5SAndroid Build Coastguard Worker   private:
95*8975f5c5SAndroid Build Coastguard Worker     GLuint mProgram;
96*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLuint> mBuffers;
97*8975f5c5SAndroid Build Coastguard Worker     GLuint mNumPoints;
98*8975f5c5SAndroid Build Coastguard Worker     std::vector<Vector3> mTranslateData;
99*8975f5c5SAndroid Build Coastguard Worker     std::vector<float> mSizeData;
100*8975f5c5SAndroid Build Coastguard Worker     std::vector<Vector3> mColorData;
101*8975f5c5SAndroid Build Coastguard Worker     angle::RNG mRNG;
102*8975f5c5SAndroid Build Coastguard Worker };
103*8975f5c5SAndroid Build Coastguard Worker 
InstancingPerfBenchmark()104*8975f5c5SAndroid Build Coastguard Worker InstancingPerfBenchmark::InstancingPerfBenchmark()
105*8975f5c5SAndroid Build Coastguard Worker     : ANGLERenderTest("InstancingPerf", GetParam()), mProgram(0), mNumPoints(75000)
106*8975f5c5SAndroid Build Coastguard Worker {}
107*8975f5c5SAndroid Build Coastguard Worker 
initializeBenchmark()108*8975f5c5SAndroid Build Coastguard Worker void InstancingPerfBenchmark::initializeBenchmark()
109*8975f5c5SAndroid Build Coastguard Worker {
110*8975f5c5SAndroid Build Coastguard Worker     const auto &params = GetParam();
111*8975f5c5SAndroid Build Coastguard Worker 
112*8975f5c5SAndroid Build Coastguard Worker     const char kVS[] =
113*8975f5c5SAndroid Build Coastguard Worker         "attribute vec2 aPosition;\n"
114*8975f5c5SAndroid Build Coastguard Worker         "attribute vec3 aTranslate;\n"
115*8975f5c5SAndroid Build Coastguard Worker         "attribute float aScale;\n"
116*8975f5c5SAndroid Build Coastguard Worker         "attribute vec3 aColor;\n"
117*8975f5c5SAndroid Build Coastguard Worker         "uniform mat4 uWorldMatrix;\n"
118*8975f5c5SAndroid Build Coastguard Worker         "uniform mat4 uProjectionMatrix;\n"
119*8975f5c5SAndroid Build Coastguard Worker         "varying vec3 vColor;\n"
120*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
121*8975f5c5SAndroid Build Coastguard Worker         "{\n"
122*8975f5c5SAndroid Build Coastguard Worker         "    vec4 position = uWorldMatrix * vec4(aTranslate, 1.0);\n"
123*8975f5c5SAndroid Build Coastguard Worker         "    position.xy += aPosition * aScale;\n"
124*8975f5c5SAndroid Build Coastguard Worker         "    gl_Position = uProjectionMatrix * position;\n"
125*8975f5c5SAndroid Build Coastguard Worker         "    vColor = aColor;\n"
126*8975f5c5SAndroid Build Coastguard Worker         "}\n";
127*8975f5c5SAndroid Build Coastguard Worker 
128*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] =
129*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
130*8975f5c5SAndroid Build Coastguard Worker         "varying vec3 vColor;\n"
131*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
132*8975f5c5SAndroid Build Coastguard Worker         "{\n"
133*8975f5c5SAndroid Build Coastguard Worker         "    gl_FragColor = vec4(vColor, 1.0);\n"
134*8975f5c5SAndroid Build Coastguard Worker         "}\n";
135*8975f5c5SAndroid Build Coastguard Worker 
136*8975f5c5SAndroid Build Coastguard Worker     mProgram = CompileProgram(kVS, kFS);
137*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(0u, mProgram);
138*8975f5c5SAndroid Build Coastguard Worker 
139*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
140*8975f5c5SAndroid Build Coastguard Worker 
141*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
142*8975f5c5SAndroid Build Coastguard Worker 
143*8975f5c5SAndroid Build Coastguard Worker     GLuint baseIndexData[6]     = {0, 1, 2, 1, 3, 2};
144*8975f5c5SAndroid Build Coastguard Worker     Vector2 basePositionData[4] = {Vector2(-1.0f, 1.0f), Vector2(1.0f, 1.0f), Vector2(-1.0f, -1.0f),
145*8975f5c5SAndroid Build Coastguard Worker                                    Vector2(1.0f, -1.0f)};
146*8975f5c5SAndroid Build Coastguard Worker 
147*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLuint> indexData;
148*8975f5c5SAndroid Build Coastguard Worker     std::vector<Vector2> positionData;
149*8975f5c5SAndroid Build Coastguard Worker 
150*8975f5c5SAndroid Build Coastguard Worker     if (!params.instancingEnabled)
151*8975f5c5SAndroid Build Coastguard Worker     {
152*8975f5c5SAndroid Build Coastguard Worker         GLuint pointVertexStride = 4;
153*8975f5c5SAndroid Build Coastguard Worker         for (GLuint pointIndex = 0; pointIndex < mNumPoints; ++pointIndex)
154*8975f5c5SAndroid Build Coastguard Worker         {
155*8975f5c5SAndroid Build Coastguard Worker             for (GLuint indexIndex = 0; indexIndex < 6; ++indexIndex)
156*8975f5c5SAndroid Build Coastguard Worker             {
157*8975f5c5SAndroid Build Coastguard Worker                 indexData.push_back(baseIndexData[indexIndex] + pointIndex * pointVertexStride);
158*8975f5c5SAndroid Build Coastguard Worker             }
159*8975f5c5SAndroid Build Coastguard Worker 
160*8975f5c5SAndroid Build Coastguard Worker             Vector3 randVec = RandomVector3(&mRNG);
161*8975f5c5SAndroid Build Coastguard Worker             for (GLuint vertexIndex = 0; vertexIndex < 4; ++vertexIndex)
162*8975f5c5SAndroid Build Coastguard Worker             {
163*8975f5c5SAndroid Build Coastguard Worker                 positionData.push_back(basePositionData[vertexIndex]);
164*8975f5c5SAndroid Build Coastguard Worker                 mTranslateData.push_back(randVec);
165*8975f5c5SAndroid Build Coastguard Worker             }
166*8975f5c5SAndroid Build Coastguard Worker         }
167*8975f5c5SAndroid Build Coastguard Worker 
168*8975f5c5SAndroid Build Coastguard Worker         mSizeData.resize(mNumPoints * 4, 0.012f);
169*8975f5c5SAndroid Build Coastguard Worker         mColorData.resize(mNumPoints * 4, Vector3(1.0f, 0.0f, 0.0f));
170*8975f5c5SAndroid Build Coastguard Worker     }
171*8975f5c5SAndroid Build Coastguard Worker     else
172*8975f5c5SAndroid Build Coastguard Worker     {
173*8975f5c5SAndroid Build Coastguard Worker         for (GLuint index : baseIndexData)
174*8975f5c5SAndroid Build Coastguard Worker         {
175*8975f5c5SAndroid Build Coastguard Worker             indexData.push_back(index);
176*8975f5c5SAndroid Build Coastguard Worker         }
177*8975f5c5SAndroid Build Coastguard Worker 
178*8975f5c5SAndroid Build Coastguard Worker         for (const Vector2 &position : basePositionData)
179*8975f5c5SAndroid Build Coastguard Worker         {
180*8975f5c5SAndroid Build Coastguard Worker             positionData.push_back(position);
181*8975f5c5SAndroid Build Coastguard Worker         }
182*8975f5c5SAndroid Build Coastguard Worker 
183*8975f5c5SAndroid Build Coastguard Worker         for (GLuint pointIndex = 0; pointIndex < mNumPoints; ++pointIndex)
184*8975f5c5SAndroid Build Coastguard Worker         {
185*8975f5c5SAndroid Build Coastguard Worker             Vector3 randVec = RandomVector3(&mRNG);
186*8975f5c5SAndroid Build Coastguard Worker             mTranslateData.push_back(randVec);
187*8975f5c5SAndroid Build Coastguard Worker         }
188*8975f5c5SAndroid Build Coastguard Worker 
189*8975f5c5SAndroid Build Coastguard Worker         mSizeData.resize(mNumPoints, 0.012f);
190*8975f5c5SAndroid Build Coastguard Worker         mColorData.resize(mNumPoints, Vector3(1.0f, 0.0f, 0.0f));
191*8975f5c5SAndroid Build Coastguard Worker     }
192*8975f5c5SAndroid Build Coastguard Worker 
193*8975f5c5SAndroid Build Coastguard Worker     mBuffers.resize(5, 0);
194*8975f5c5SAndroid Build Coastguard Worker     glGenBuffers(static_cast<GLsizei>(mBuffers.size()), &mBuffers[0]);
195*8975f5c5SAndroid Build Coastguard Worker 
196*8975f5c5SAndroid Build Coastguard Worker     // Index Data
197*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBuffers[0]);
198*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ELEMENT_ARRAY_BUFFER, VectorSizeBytes(indexData), &indexData[0],
199*8975f5c5SAndroid Build Coastguard Worker                  GL_STATIC_DRAW);
200*8975f5c5SAndroid Build Coastguard Worker 
201*8975f5c5SAndroid Build Coastguard Worker     // Position Data
202*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, mBuffers[1]);
203*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, VectorSizeBytes(positionData), &positionData[0], GL_STATIC_DRAW);
204*8975f5c5SAndroid Build Coastguard Worker     GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
205*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(-1, positionLocation);
206*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 8, nullptr);
207*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(positionLocation);
208*8975f5c5SAndroid Build Coastguard Worker 
209*8975f5c5SAndroid Build Coastguard Worker     // Translate Data
210*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, mBuffers[2]);
211*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, VectorSizeBytes(mTranslateData), &mTranslateData[0],
212*8975f5c5SAndroid Build Coastguard Worker                  GL_STATIC_DRAW);
213*8975f5c5SAndroid Build Coastguard Worker     GLint translateLocation = glGetAttribLocation(mProgram, "aTranslate");
214*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(-1, translateLocation);
215*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(translateLocation, 3, GL_FLOAT, GL_FALSE, 12, nullptr);
216*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(translateLocation);
217*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribDivisorANGLE(translateLocation, 1);
218*8975f5c5SAndroid Build Coastguard Worker 
219*8975f5c5SAndroid Build Coastguard Worker     // Scale Data
220*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, mBuffers[3]);
221*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, VectorSizeBytes(mSizeData), nullptr, GL_DYNAMIC_DRAW);
222*8975f5c5SAndroid Build Coastguard Worker     GLint scaleLocation = glGetAttribLocation(mProgram, "aScale");
223*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(-1, scaleLocation);
224*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(scaleLocation, 1, GL_FLOAT, GL_FALSE, 4, nullptr);
225*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(scaleLocation);
226*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribDivisorANGLE(scaleLocation, 1);
227*8975f5c5SAndroid Build Coastguard Worker 
228*8975f5c5SAndroid Build Coastguard Worker     // Color Data
229*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, mBuffers[4]);
230*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, VectorSizeBytes(mColorData), nullptr, GL_DYNAMIC_DRAW);
231*8975f5c5SAndroid Build Coastguard Worker     GLint colorLocation = glGetAttribLocation(mProgram, "aColor");
232*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(-1, colorLocation);
233*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(colorLocation, 3, GL_FLOAT, GL_FALSE, 12, nullptr);
234*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(colorLocation);
235*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribDivisorANGLE(colorLocation, 1);
236*8975f5c5SAndroid Build Coastguard Worker 
237*8975f5c5SAndroid Build Coastguard Worker     // Set the viewport
238*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
239*8975f5c5SAndroid Build Coastguard Worker 
240*8975f5c5SAndroid Build Coastguard Worker     // Init matrices
241*8975f5c5SAndroid Build Coastguard Worker     GLint worldMatrixLocation = glGetUniformLocation(mProgram, "uWorldMatrix");
242*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(-1, worldMatrixLocation);
243*8975f5c5SAndroid Build Coastguard Worker     Matrix4 worldMatrix = Matrix4::translate(Vector3(0, 0, -3.0f));
244*8975f5c5SAndroid Build Coastguard Worker     worldMatrix *= Matrix4::rotate(25.0f, Vector3(0.6f, 1.0f, 0.0f));
245*8975f5c5SAndroid Build Coastguard Worker     glUniformMatrix4fv(worldMatrixLocation, 1, GL_FALSE, &worldMatrix.data[0]);
246*8975f5c5SAndroid Build Coastguard Worker 
247*8975f5c5SAndroid Build Coastguard Worker     GLint projectionMatrixLocation = glGetUniformLocation(mProgram, "uProjectionMatrix");
248*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(-1, projectionMatrixLocation);
249*8975f5c5SAndroid Build Coastguard Worker     float fov =
250*8975f5c5SAndroid Build Coastguard Worker         static_cast<float>(getWindow()->getWidth()) / static_cast<float>(getWindow()->getHeight());
251*8975f5c5SAndroid Build Coastguard Worker     Matrix4 projectionMatrix = Matrix4::perspective(60.0f, fov, 1.0f, 300.0f);
252*8975f5c5SAndroid Build Coastguard Worker     glUniformMatrix4fv(projectionMatrixLocation, 1, GL_FALSE, &projectionMatrix.data[0]);
253*8975f5c5SAndroid Build Coastguard Worker 
254*8975f5c5SAndroid Build Coastguard Worker     getWindow()->setVisible(true);
255*8975f5c5SAndroid Build Coastguard Worker 
256*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
257*8975f5c5SAndroid Build Coastguard Worker }
258*8975f5c5SAndroid Build Coastguard Worker 
destroyBenchmark()259*8975f5c5SAndroid Build Coastguard Worker void InstancingPerfBenchmark::destroyBenchmark()
260*8975f5c5SAndroid Build Coastguard Worker {
261*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(mProgram);
262*8975f5c5SAndroid Build Coastguard Worker 
263*8975f5c5SAndroid Build Coastguard Worker     if (!mBuffers.empty())
264*8975f5c5SAndroid Build Coastguard Worker     {
265*8975f5c5SAndroid Build Coastguard Worker         glDeleteBuffers(static_cast<GLsizei>(mBuffers.size()), &mBuffers[0]);
266*8975f5c5SAndroid Build Coastguard Worker         mBuffers.clear();
267*8975f5c5SAndroid Build Coastguard Worker     }
268*8975f5c5SAndroid Build Coastguard Worker }
269*8975f5c5SAndroid Build Coastguard Worker 
drawBenchmark()270*8975f5c5SAndroid Build Coastguard Worker void InstancingPerfBenchmark::drawBenchmark()
271*8975f5c5SAndroid Build Coastguard Worker {
272*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
273*8975f5c5SAndroid Build Coastguard Worker 
274*8975f5c5SAndroid Build Coastguard Worker     const auto &params = GetParam();
275*8975f5c5SAndroid Build Coastguard Worker 
276*8975f5c5SAndroid Build Coastguard Worker     // Animation makes the test more interesting visually, but also eats up many CPU cycles.
277*8975f5c5SAndroid Build Coastguard Worker     if (params.animationEnabled)
278*8975f5c5SAndroid Build Coastguard Worker     {
279*8975f5c5SAndroid Build Coastguard Worker         float time = static_cast<float>(mTrialTimer.getElapsedWallClockTime());
280*8975f5c5SAndroid Build Coastguard Worker 
281*8975f5c5SAndroid Build Coastguard Worker         for (size_t pointIndex = 0; pointIndex < mTranslateData.size(); ++pointIndex)
282*8975f5c5SAndroid Build Coastguard Worker         {
283*8975f5c5SAndroid Build Coastguard Worker             const Vector3 &translate = mTranslateData[pointIndex];
284*8975f5c5SAndroid Build Coastguard Worker 
285*8975f5c5SAndroid Build Coastguard Worker             float tx = translate.x() + time;
286*8975f5c5SAndroid Build Coastguard Worker             float ty = translate.y() + time;
287*8975f5c5SAndroid Build Coastguard Worker             float tz = translate.z() + time;
288*8975f5c5SAndroid Build Coastguard Worker 
289*8975f5c5SAndroid Build Coastguard Worker             float scale           = AnimationSignal(tx) * 0.01f + 0.01f;
290*8975f5c5SAndroid Build Coastguard Worker             mSizeData[pointIndex] = scale;
291*8975f5c5SAndroid Build Coastguard Worker 
292*8975f5c5SAndroid Build Coastguard Worker             Vector3 color =
293*8975f5c5SAndroid Build Coastguard Worker                 Vector3(AnimationSignal(tx), AnimationSignal(ty), AnimationSignal(tz)) * 0.5f +
294*8975f5c5SAndroid Build Coastguard Worker                 Vector3(0.5f);
295*8975f5c5SAndroid Build Coastguard Worker 
296*8975f5c5SAndroid Build Coastguard Worker             mColorData[pointIndex] = color;
297*8975f5c5SAndroid Build Coastguard Worker         }
298*8975f5c5SAndroid Build Coastguard Worker     }
299*8975f5c5SAndroid Build Coastguard Worker 
300*8975f5c5SAndroid Build Coastguard Worker     // Update scales and colors.
301*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, mBuffers[3]);
302*8975f5c5SAndroid Build Coastguard Worker     glBufferSubData(GL_ARRAY_BUFFER, 0, VectorSizeBytes(mSizeData), &mSizeData[0]);
303*8975f5c5SAndroid Build Coastguard Worker 
304*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, mBuffers[4]);
305*8975f5c5SAndroid Build Coastguard Worker     glBufferSubData(GL_ARRAY_BUFFER, 0, VectorSizeBytes(mColorData), &mColorData[0]);
306*8975f5c5SAndroid Build Coastguard Worker 
307*8975f5c5SAndroid Build Coastguard Worker     // Render the instances/billboards.
308*8975f5c5SAndroid Build Coastguard Worker     if (params.instancingEnabled)
309*8975f5c5SAndroid Build Coastguard Worker     {
310*8975f5c5SAndroid Build Coastguard Worker         for (unsigned int it = 0; it < params.iterationsPerStep; it++)
311*8975f5c5SAndroid Build Coastguard Worker         {
312*8975f5c5SAndroid Build Coastguard Worker             glDrawElementsInstancedANGLE(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr, mNumPoints);
313*8975f5c5SAndroid Build Coastguard Worker         }
314*8975f5c5SAndroid Build Coastguard Worker     }
315*8975f5c5SAndroid Build Coastguard Worker     else
316*8975f5c5SAndroid Build Coastguard Worker     {
317*8975f5c5SAndroid Build Coastguard Worker         for (unsigned int it = 0; it < params.iterationsPerStep; it++)
318*8975f5c5SAndroid Build Coastguard Worker         {
319*8975f5c5SAndroid Build Coastguard Worker             glDrawElements(GL_TRIANGLES, 6 * mNumPoints, GL_UNSIGNED_INT, nullptr);
320*8975f5c5SAndroid Build Coastguard Worker         }
321*8975f5c5SAndroid Build Coastguard Worker     }
322*8975f5c5SAndroid Build Coastguard Worker 
323*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
324*8975f5c5SAndroid Build Coastguard Worker }
325*8975f5c5SAndroid Build Coastguard Worker 
InstancingPerfD3D11Params()326*8975f5c5SAndroid Build Coastguard Worker InstancingPerfParams InstancingPerfD3D11Params()
327*8975f5c5SAndroid Build Coastguard Worker {
328*8975f5c5SAndroid Build Coastguard Worker     InstancingPerfParams params;
329*8975f5c5SAndroid Build Coastguard Worker     params.eglParameters = D3D11();
330*8975f5c5SAndroid Build Coastguard Worker     return params;
331*8975f5c5SAndroid Build Coastguard Worker }
332*8975f5c5SAndroid Build Coastguard Worker 
InstancingPerfMetalParams()333*8975f5c5SAndroid Build Coastguard Worker InstancingPerfParams InstancingPerfMetalParams()
334*8975f5c5SAndroid Build Coastguard Worker {
335*8975f5c5SAndroid Build Coastguard Worker     InstancingPerfParams params;
336*8975f5c5SAndroid Build Coastguard Worker     params.eglParameters = METAL();
337*8975f5c5SAndroid Build Coastguard Worker     return params;
338*8975f5c5SAndroid Build Coastguard Worker }
339*8975f5c5SAndroid Build Coastguard Worker 
InstancingPerfOpenGLOrGLESParams()340*8975f5c5SAndroid Build Coastguard Worker InstancingPerfParams InstancingPerfOpenGLOrGLESParams()
341*8975f5c5SAndroid Build Coastguard Worker {
342*8975f5c5SAndroid Build Coastguard Worker     InstancingPerfParams params;
343*8975f5c5SAndroid Build Coastguard Worker     params.eglParameters = OPENGL_OR_GLES();
344*8975f5c5SAndroid Build Coastguard Worker     return params;
345*8975f5c5SAndroid Build Coastguard Worker }
346*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(InstancingPerfBenchmark,Run)347*8975f5c5SAndroid Build Coastguard Worker TEST_P(InstancingPerfBenchmark, Run)
348*8975f5c5SAndroid Build Coastguard Worker {
349*8975f5c5SAndroid Build Coastguard Worker     run();
350*8975f5c5SAndroid Build Coastguard Worker }
351*8975f5c5SAndroid Build Coastguard Worker 
352*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(InstancingPerfBenchmark,
353*8975f5c5SAndroid Build Coastguard Worker                        InstancingPerfD3D11Params(),
354*8975f5c5SAndroid Build Coastguard Worker                        InstancingPerfMetalParams(),
355*8975f5c5SAndroid Build Coastguard Worker                        InstancingPerfOpenGLOrGLESParams());
356*8975f5c5SAndroid Build Coastguard Worker 
357*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
358