1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2021 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 // VertexArrayPerfTest:
7*8975f5c5SAndroid Build Coastguard Worker // Performance test for glBindVertexArray.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker
10*8975f5c5SAndroid Build Coastguard Worker #include "ANGLEPerfTest.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "DrawCallPerfParams.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
13*8975f5c5SAndroid Build Coastguard Worker
14*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
15*8975f5c5SAndroid Build Coastguard Worker
16*8975f5c5SAndroid Build Coastguard Worker namespace
17*8975f5c5SAndroid Build Coastguard Worker {
18*8975f5c5SAndroid Build Coastguard Worker enum class TestMode
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker BufferData,
21*8975f5c5SAndroid Build Coastguard Worker BindBuffer,
22*8975f5c5SAndroid Build Coastguard Worker UpdateBufferData,
23*8975f5c5SAndroid Build Coastguard Worker };
24*8975f5c5SAndroid Build Coastguard Worker
25*8975f5c5SAndroid Build Coastguard Worker struct VertexArrayParams final : public RenderTestParams
26*8975f5c5SAndroid Build Coastguard Worker {
VertexArrayParams__anon5ac9623f0111::VertexArrayParams27*8975f5c5SAndroid Build Coastguard Worker VertexArrayParams()
28*8975f5c5SAndroid Build Coastguard Worker {
29*8975f5c5SAndroid Build Coastguard Worker iterationsPerStep = 1;
30*8975f5c5SAndroid Build Coastguard Worker
31*8975f5c5SAndroid Build Coastguard Worker // Common default params
32*8975f5c5SAndroid Build Coastguard Worker majorVersion = 3;
33*8975f5c5SAndroid Build Coastguard Worker minorVersion = 0;
34*8975f5c5SAndroid Build Coastguard Worker windowWidth = 720;
35*8975f5c5SAndroid Build Coastguard Worker windowHeight = 720;
36*8975f5c5SAndroid Build Coastguard Worker }
37*8975f5c5SAndroid Build Coastguard Worker
38*8975f5c5SAndroid Build Coastguard Worker std::string story() const override;
39*8975f5c5SAndroid Build Coastguard Worker
40*8975f5c5SAndroid Build Coastguard Worker int numVertexArrays = 2000;
41*8975f5c5SAndroid Build Coastguard Worker int numBuffers = 5;
42*8975f5c5SAndroid Build Coastguard Worker GLuint bufferSize[5] = {384, 1028, 192, 384, 192};
43*8975f5c5SAndroid Build Coastguard Worker TestMode testMode = TestMode::BufferData;
44*8975f5c5SAndroid Build Coastguard Worker };
45*8975f5c5SAndroid Build Coastguard Worker
operator <<(std::ostream & os,const VertexArrayParams & params)46*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const VertexArrayParams ¶ms)
47*8975f5c5SAndroid Build Coastguard Worker {
48*8975f5c5SAndroid Build Coastguard Worker os << params.backendAndStory().substr(1);
49*8975f5c5SAndroid Build Coastguard Worker return os;
50*8975f5c5SAndroid Build Coastguard Worker }
51*8975f5c5SAndroid Build Coastguard Worker
story() const52*8975f5c5SAndroid Build Coastguard Worker std::string VertexArrayParams::story() const
53*8975f5c5SAndroid Build Coastguard Worker {
54*8975f5c5SAndroid Build Coastguard Worker std::stringstream strstr;
55*8975f5c5SAndroid Build Coastguard Worker
56*8975f5c5SAndroid Build Coastguard Worker strstr << RenderTestParams::story();
57*8975f5c5SAndroid Build Coastguard Worker
58*8975f5c5SAndroid Build Coastguard Worker if (testMode == TestMode::BindBuffer)
59*8975f5c5SAndroid Build Coastguard Worker {
60*8975f5c5SAndroid Build Coastguard Worker strstr << "_bindbuffer";
61*8975f5c5SAndroid Build Coastguard Worker }
62*8975f5c5SAndroid Build Coastguard Worker else if (testMode == TestMode::UpdateBufferData)
63*8975f5c5SAndroid Build Coastguard Worker {
64*8975f5c5SAndroid Build Coastguard Worker strstr << "_updatebufferdata";
65*8975f5c5SAndroid Build Coastguard Worker }
66*8975f5c5SAndroid Build Coastguard Worker
67*8975f5c5SAndroid Build Coastguard Worker return strstr.str();
68*8975f5c5SAndroid Build Coastguard Worker }
69*8975f5c5SAndroid Build Coastguard Worker
70*8975f5c5SAndroid Build Coastguard Worker class VertexArrayBenchmark : public ANGLERenderTest,
71*8975f5c5SAndroid Build Coastguard Worker public ::testing::WithParamInterface<VertexArrayParams>
72*8975f5c5SAndroid Build Coastguard Worker {
73*8975f5c5SAndroid Build Coastguard Worker public:
74*8975f5c5SAndroid Build Coastguard Worker VertexArrayBenchmark();
75*8975f5c5SAndroid Build Coastguard Worker
76*8975f5c5SAndroid Build Coastguard Worker void initializeBenchmark() override;
77*8975f5c5SAndroid Build Coastguard Worker void destroyBenchmark() override;
78*8975f5c5SAndroid Build Coastguard Worker void drawBenchmark() override;
79*8975f5c5SAndroid Build Coastguard Worker
80*8975f5c5SAndroid Build Coastguard Worker void rebindVertexArray(GLuint vertexArrayID, GLuint bufferID);
81*8975f5c5SAndroid Build Coastguard Worker void updateBufferData(GLuint vertexArrayID, GLuint bufferID, GLuint bufferSize);
82*8975f5c5SAndroid Build Coastguard Worker
83*8975f5c5SAndroid Build Coastguard Worker private:
84*8975f5c5SAndroid Build Coastguard Worker std::vector<GLuint> mBuffers;
85*8975f5c5SAndroid Build Coastguard Worker GLuint mProgram = 0;
86*8975f5c5SAndroid Build Coastguard Worker GLint mAttribLocation = 0;
87*8975f5c5SAndroid Build Coastguard Worker std::vector<GLuint> mVertexArrays;
88*8975f5c5SAndroid Build Coastguard Worker };
89*8975f5c5SAndroid Build Coastguard Worker
VertexArrayBenchmark()90*8975f5c5SAndroid Build Coastguard Worker VertexArrayBenchmark::VertexArrayBenchmark() : ANGLERenderTest("VertexArrayPerf", GetParam()) {}
91*8975f5c5SAndroid Build Coastguard Worker
initializeBenchmark()92*8975f5c5SAndroid Build Coastguard Worker void VertexArrayBenchmark::initializeBenchmark()
93*8975f5c5SAndroid Build Coastguard Worker {
94*8975f5c5SAndroid Build Coastguard Worker constexpr char kVS[] = R"(attribute vec4 position;
95*8975f5c5SAndroid Build Coastguard Worker attribute float in_attrib;
96*8975f5c5SAndroid Build Coastguard Worker varying float v_attrib;
97*8975f5c5SAndroid Build Coastguard Worker void main()
98*8975f5c5SAndroid Build Coastguard Worker {
99*8975f5c5SAndroid Build Coastguard Worker v_attrib = in_attrib;
100*8975f5c5SAndroid Build Coastguard Worker gl_Position = position;
101*8975f5c5SAndroid Build Coastguard Worker })";
102*8975f5c5SAndroid Build Coastguard Worker
103*8975f5c5SAndroid Build Coastguard Worker constexpr char kFS[] = R"(precision mediump float;
104*8975f5c5SAndroid Build Coastguard Worker varying float v_attrib;
105*8975f5c5SAndroid Build Coastguard Worker void main()
106*8975f5c5SAndroid Build Coastguard Worker {
107*8975f5c5SAndroid Build Coastguard Worker gl_FragColor = vec4(v_attrib, 0, 0, 1);
108*8975f5c5SAndroid Build Coastguard Worker })";
109*8975f5c5SAndroid Build Coastguard Worker
110*8975f5c5SAndroid Build Coastguard Worker mProgram = CompileProgram(kVS, kFS);
111*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(0u, mProgram);
112*8975f5c5SAndroid Build Coastguard Worker
113*8975f5c5SAndroid Build Coastguard Worker mAttribLocation = glGetAttribLocation(mProgram, "in_attrib");
114*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(mAttribLocation, -1);
115*8975f5c5SAndroid Build Coastguard Worker
116*8975f5c5SAndroid Build Coastguard Worker // Generate 5 buffers.
117*8975f5c5SAndroid Build Coastguard Worker int numBuffers = GetParam().numBuffers;
118*8975f5c5SAndroid Build Coastguard Worker mBuffers.resize(numBuffers, 0);
119*8975f5c5SAndroid Build Coastguard Worker glGenBuffers(numBuffers, mBuffers.data());
120*8975f5c5SAndroid Build Coastguard Worker
121*8975f5c5SAndroid Build Coastguard Worker int numVertexArrays = GetParam().numVertexArrays;
122*8975f5c5SAndroid Build Coastguard Worker mVertexArrays.resize(numVertexArrays, 0);
123*8975f5c5SAndroid Build Coastguard Worker glGenVertexArrays(numVertexArrays, mVertexArrays.data());
124*8975f5c5SAndroid Build Coastguard Worker
125*8975f5c5SAndroid Build Coastguard Worker // Bind one VBO to all VAOs.
126*8975f5c5SAndroid Build Coastguard Worker for (GLuint vertexArray : mVertexArrays)
127*8975f5c5SAndroid Build Coastguard Worker {
128*8975f5c5SAndroid Build Coastguard Worker rebindVertexArray(vertexArray, mBuffers[0]);
129*8975f5c5SAndroid Build Coastguard Worker }
130*8975f5c5SAndroid Build Coastguard Worker
131*8975f5c5SAndroid Build Coastguard Worker glBindVertexArray(0);
132*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ARRAY_BUFFER, mBuffers[0]);
133*8975f5c5SAndroid Build Coastguard Worker }
134*8975f5c5SAndroid Build Coastguard Worker
rebindVertexArray(GLuint vertexArrayID,GLuint bufferID)135*8975f5c5SAndroid Build Coastguard Worker void VertexArrayBenchmark::rebindVertexArray(GLuint vertexArrayID, GLuint bufferID)
136*8975f5c5SAndroid Build Coastguard Worker {
137*8975f5c5SAndroid Build Coastguard Worker // Rebind a vertex array object and a generic vertex attribute inside of it.
138*8975f5c5SAndroid Build Coastguard Worker glBindVertexArray(vertexArrayID);
139*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ARRAY_BUFFER, bufferID);
140*8975f5c5SAndroid Build Coastguard Worker glEnableVertexAttribArray(mAttribLocation);
141*8975f5c5SAndroid Build Coastguard Worker glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, nullptr);
142*8975f5c5SAndroid Build Coastguard Worker glVertexAttribDivisor(mAttribLocation, 1);
143*8975f5c5SAndroid Build Coastguard Worker glBindVertexArray(0);
144*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ARRAY_BUFFER, 0);
145*8975f5c5SAndroid Build Coastguard Worker }
146*8975f5c5SAndroid Build Coastguard Worker
updateBufferData(GLuint vertexArrayID,GLuint bufferID,GLuint bufferSize)147*8975f5c5SAndroid Build Coastguard Worker void VertexArrayBenchmark::updateBufferData(GLuint vertexArrayID,
148*8975f5c5SAndroid Build Coastguard Worker GLuint bufferID,
149*8975f5c5SAndroid Build Coastguard Worker GLuint bufferSize)
150*8975f5c5SAndroid Build Coastguard Worker {
151*8975f5c5SAndroid Build Coastguard Worker glBindVertexArray(vertexArrayID);
152*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ARRAY_BUFFER, bufferID);
153*8975f5c5SAndroid Build Coastguard Worker glEnableVertexAttribArray(mAttribLocation);
154*8975f5c5SAndroid Build Coastguard Worker glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, nullptr);
155*8975f5c5SAndroid Build Coastguard Worker glBufferData(GL_ARRAY_BUFFER, bufferSize, nullptr, GL_STATIC_DRAW);
156*8975f5c5SAndroid Build Coastguard Worker glBindVertexArray(0);
157*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ARRAY_BUFFER, 0);
158*8975f5c5SAndroid Build Coastguard Worker }
159*8975f5c5SAndroid Build Coastguard Worker
destroyBenchmark()160*8975f5c5SAndroid Build Coastguard Worker void VertexArrayBenchmark::destroyBenchmark()
161*8975f5c5SAndroid Build Coastguard Worker {
162*8975f5c5SAndroid Build Coastguard Worker glDeleteProgram(mProgram);
163*8975f5c5SAndroid Build Coastguard Worker glDeleteVertexArrays(static_cast<GLsizei>(mVertexArrays.size()), mVertexArrays.data());
164*8975f5c5SAndroid Build Coastguard Worker mVertexArrays.clear();
165*8975f5c5SAndroid Build Coastguard Worker glDeleteBuffers(static_cast<GLsizei>(mBuffers.size()), mBuffers.data());
166*8975f5c5SAndroid Build Coastguard Worker mBuffers.clear();
167*8975f5c5SAndroid Build Coastguard Worker }
168*8975f5c5SAndroid Build Coastguard Worker
drawBenchmark()169*8975f5c5SAndroid Build Coastguard Worker void VertexArrayBenchmark::drawBenchmark()
170*8975f5c5SAndroid Build Coastguard Worker {
171*8975f5c5SAndroid Build Coastguard Worker const VertexArrayParams ¶ms = GetParam();
172*8975f5c5SAndroid Build Coastguard Worker if (params.testMode == TestMode::BufferData)
173*8975f5c5SAndroid Build Coastguard Worker {
174*8975f5c5SAndroid Build Coastguard Worker glBufferData(GL_ARRAY_BUFFER, 128, nullptr, GL_STATIC_DRAW);
175*8975f5c5SAndroid Build Coastguard Worker }
176*8975f5c5SAndroid Build Coastguard Worker else if (params.testMode == TestMode::UpdateBufferData)
177*8975f5c5SAndroid Build Coastguard Worker {
178*8975f5c5SAndroid Build Coastguard Worker int bufferSizeIndex = 0;
179*8975f5c5SAndroid Build Coastguard Worker for (GLuint vertexArray : mVertexArrays)
180*8975f5c5SAndroid Build Coastguard Worker {
181*8975f5c5SAndroid Build Coastguard Worker bufferSizeIndex = ((bufferSizeIndex + 1) == 5) ? 0 : (bufferSizeIndex + 1);
182*8975f5c5SAndroid Build Coastguard Worker updateBufferData(vertexArray, mBuffers[0], params.bufferSize[bufferSizeIndex]);
183*8975f5c5SAndroid Build Coastguard Worker }
184*8975f5c5SAndroid Build Coastguard Worker }
185*8975f5c5SAndroid Build Coastguard Worker else
186*8975f5c5SAndroid Build Coastguard Worker {
187*8975f5c5SAndroid Build Coastguard Worker int bufferIndex = 0;
188*8975f5c5SAndroid Build Coastguard Worker for (GLuint vertexArray : mVertexArrays)
189*8975f5c5SAndroid Build Coastguard Worker {
190*8975f5c5SAndroid Build Coastguard Worker bufferIndex = ((bufferIndex + 1) == params.numBuffers) ? 0 : (bufferIndex + 1);
191*8975f5c5SAndroid Build Coastguard Worker rebindVertexArray(vertexArray, mBuffers[bufferIndex]);
192*8975f5c5SAndroid Build Coastguard Worker }
193*8975f5c5SAndroid Build Coastguard Worker }
194*8975f5c5SAndroid Build Coastguard Worker }
195*8975f5c5SAndroid Build Coastguard Worker
TEST_P(VertexArrayBenchmark,Run)196*8975f5c5SAndroid Build Coastguard Worker TEST_P(VertexArrayBenchmark, Run)
197*8975f5c5SAndroid Build Coastguard Worker {
198*8975f5c5SAndroid Build Coastguard Worker run();
199*8975f5c5SAndroid Build Coastguard Worker }
200*8975f5c5SAndroid Build Coastguard Worker
MetalParams()201*8975f5c5SAndroid Build Coastguard Worker VertexArrayParams MetalParams()
202*8975f5c5SAndroid Build Coastguard Worker {
203*8975f5c5SAndroid Build Coastguard Worker VertexArrayParams params;
204*8975f5c5SAndroid Build Coastguard Worker params.eglParameters = egl_platform::METAL();
205*8975f5c5SAndroid Build Coastguard Worker return params;
206*8975f5c5SAndroid Build Coastguard Worker }
207*8975f5c5SAndroid Build Coastguard Worker
VulkanParams()208*8975f5c5SAndroid Build Coastguard Worker VertexArrayParams VulkanParams()
209*8975f5c5SAndroid Build Coastguard Worker {
210*8975f5c5SAndroid Build Coastguard Worker VertexArrayParams params;
211*8975f5c5SAndroid Build Coastguard Worker params.eglParameters = egl_platform::VULKAN();
212*8975f5c5SAndroid Build Coastguard Worker return params;
213*8975f5c5SAndroid Build Coastguard Worker }
214*8975f5c5SAndroid Build Coastguard Worker
VulkanNullParams(TestMode testMode)215*8975f5c5SAndroid Build Coastguard Worker VertexArrayParams VulkanNullParams(TestMode testMode)
216*8975f5c5SAndroid Build Coastguard Worker {
217*8975f5c5SAndroid Build Coastguard Worker VertexArrayParams params;
218*8975f5c5SAndroid Build Coastguard Worker params.eglParameters = egl_platform::VULKAN_NULL();
219*8975f5c5SAndroid Build Coastguard Worker params.testMode = testMode;
220*8975f5c5SAndroid Build Coastguard Worker return params;
221*8975f5c5SAndroid Build Coastguard Worker }
222*8975f5c5SAndroid Build Coastguard Worker
223*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VertexArrayBenchmark);
224*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(VertexArrayBenchmark,
225*8975f5c5SAndroid Build Coastguard Worker MetalParams(),
226*8975f5c5SAndroid Build Coastguard Worker VulkanParams(),
227*8975f5c5SAndroid Build Coastguard Worker VulkanNullParams(TestMode::BindBuffer),
228*8975f5c5SAndroid Build Coastguard Worker VulkanNullParams(TestMode::BufferData),
229*8975f5c5SAndroid Build Coastguard Worker VulkanNullParams(TestMode::UpdateBufferData),
230*8975f5c5SAndroid Build Coastguard Worker params::Native(VertexArrayParams()));
231*8975f5c5SAndroid Build Coastguard Worker } // namespace
232