xref: /aosp_15_r20/external/angle/src/tests/perf_tests/BindingPerf.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2016 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 // BindingPerf:
7*8975f5c5SAndroid Build Coastguard Worker //   Performance test for binding objects
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 <iostream>
13*8975f5c5SAndroid Build Coastguard Worker #include <random>
14*8975f5c5SAndroid Build Coastguard Worker #include <sstream>
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/angle_test_instantiate.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "util/shader_utils.h"
18*8975f5c5SAndroid Build Coastguard Worker 
19*8975f5c5SAndroid Build Coastguard Worker namespace angle
20*8975f5c5SAndroid Build Coastguard Worker {
21*8975f5c5SAndroid Build Coastguard Worker namespace
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker constexpr unsigned int kIterationsPerStep = 128;
24*8975f5c5SAndroid Build Coastguard Worker 
25*8975f5c5SAndroid Build Coastguard Worker enum TestMode
26*8975f5c5SAndroid Build Coastguard Worker {
27*8975f5c5SAndroid Build Coastguard Worker     VertexArray,
28*8975f5c5SAndroid Build Coastguard Worker     MultipleBindings,
29*8975f5c5SAndroid Build Coastguard Worker };
30*8975f5c5SAndroid Build Coastguard Worker 
31*8975f5c5SAndroid Build Coastguard Worker enum AllocationStyle
32*8975f5c5SAndroid Build Coastguard Worker {
33*8975f5c5SAndroid Build Coastguard Worker     EVERY_ITERATION,
34*8975f5c5SAndroid Build Coastguard Worker     AT_INITIALIZATION
35*8975f5c5SAndroid Build Coastguard Worker };
36*8975f5c5SAndroid Build Coastguard Worker 
37*8975f5c5SAndroid Build Coastguard Worker struct BindingsParams final : public RenderTestParams
38*8975f5c5SAndroid Build Coastguard Worker {
BindingsParamsangle::__anon94a4391d0111::BindingsParams39*8975f5c5SAndroid Build Coastguard Worker     BindingsParams()
40*8975f5c5SAndroid Build Coastguard Worker     {
41*8975f5c5SAndroid Build Coastguard Worker         // Common default params
42*8975f5c5SAndroid Build Coastguard Worker         majorVersion = 2;
43*8975f5c5SAndroid Build Coastguard Worker         minorVersion = 0;
44*8975f5c5SAndroid Build Coastguard Worker         windowWidth  = 720;
45*8975f5c5SAndroid Build Coastguard Worker         windowHeight = 720;
46*8975f5c5SAndroid Build Coastguard Worker 
47*8975f5c5SAndroid Build Coastguard Worker         numObjects        = 100;
48*8975f5c5SAndroid Build Coastguard Worker         allocationStyle   = EVERY_ITERATION;
49*8975f5c5SAndroid Build Coastguard Worker         iterationsPerStep = kIterationsPerStep;
50*8975f5c5SAndroid Build Coastguard Worker     }
51*8975f5c5SAndroid Build Coastguard Worker 
52*8975f5c5SAndroid Build Coastguard Worker     std::string story() const override;
53*8975f5c5SAndroid Build Coastguard Worker     TestMode testMode = TestMode::MultipleBindings;
54*8975f5c5SAndroid Build Coastguard Worker     size_t numObjects;
55*8975f5c5SAndroid Build Coastguard Worker     AllocationStyle allocationStyle;
56*8975f5c5SAndroid Build Coastguard Worker };
57*8975f5c5SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const BindingsParams & params)58*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const BindingsParams &params)
59*8975f5c5SAndroid Build Coastguard Worker {
60*8975f5c5SAndroid Build Coastguard Worker     os << params.backendAndStory().substr(1);
61*8975f5c5SAndroid Build Coastguard Worker     return os;
62*8975f5c5SAndroid Build Coastguard Worker }
63*8975f5c5SAndroid Build Coastguard Worker 
story() const64*8975f5c5SAndroid Build Coastguard Worker std::string BindingsParams::story() const
65*8975f5c5SAndroid Build Coastguard Worker {
66*8975f5c5SAndroid Build Coastguard Worker     std::stringstream strstr;
67*8975f5c5SAndroid Build Coastguard Worker 
68*8975f5c5SAndroid Build Coastguard Worker     strstr << RenderTestParams::story();
69*8975f5c5SAndroid Build Coastguard Worker 
70*8975f5c5SAndroid Build Coastguard Worker     if (testMode == TestMode::VertexArray)
71*8975f5c5SAndroid Build Coastguard Worker     {
72*8975f5c5SAndroid Build Coastguard Worker         strstr << "_vertexarray";
73*8975f5c5SAndroid Build Coastguard Worker     }
74*8975f5c5SAndroid Build Coastguard Worker     else
75*8975f5c5SAndroid Build Coastguard Worker     {
76*8975f5c5SAndroid Build Coastguard Worker         strstr << "_" << numObjects << "_objects";
77*8975f5c5SAndroid Build Coastguard Worker 
78*8975f5c5SAndroid Build Coastguard Worker         switch (allocationStyle)
79*8975f5c5SAndroid Build Coastguard Worker         {
80*8975f5c5SAndroid Build Coastguard Worker             case EVERY_ITERATION:
81*8975f5c5SAndroid Build Coastguard Worker                 strstr << "_allocated_every_iteration";
82*8975f5c5SAndroid Build Coastguard Worker                 break;
83*8975f5c5SAndroid Build Coastguard Worker             case AT_INITIALIZATION:
84*8975f5c5SAndroid Build Coastguard Worker                 strstr << "_allocated_at_initialization";
85*8975f5c5SAndroid Build Coastguard Worker                 break;
86*8975f5c5SAndroid Build Coastguard Worker             default:
87*8975f5c5SAndroid Build Coastguard Worker                 strstr << "_err";
88*8975f5c5SAndroid Build Coastguard Worker                 break;
89*8975f5c5SAndroid Build Coastguard Worker         }
90*8975f5c5SAndroid Build Coastguard Worker     }
91*8975f5c5SAndroid Build Coastguard Worker 
92*8975f5c5SAndroid Build Coastguard Worker     return strstr.str();
93*8975f5c5SAndroid Build Coastguard Worker }
94*8975f5c5SAndroid Build Coastguard Worker 
95*8975f5c5SAndroid Build Coastguard Worker class BindingsBenchmark : public ANGLERenderTest,
96*8975f5c5SAndroid Build Coastguard Worker                           public ::testing::WithParamInterface<BindingsParams>
97*8975f5c5SAndroid Build Coastguard Worker {
98*8975f5c5SAndroid Build Coastguard Worker   public:
99*8975f5c5SAndroid Build Coastguard Worker     BindingsBenchmark();
100*8975f5c5SAndroid Build Coastguard Worker 
101*8975f5c5SAndroid Build Coastguard Worker     void initializeBenchmark() override;
102*8975f5c5SAndroid Build Coastguard Worker     void destroyBenchmark() override;
103*8975f5c5SAndroid Build Coastguard Worker     void drawBenchmark() override;
104*8975f5c5SAndroid Build Coastguard Worker 
105*8975f5c5SAndroid Build Coastguard Worker   private:
106*8975f5c5SAndroid Build Coastguard Worker     // TODO: Test binding perf of more than just buffers
107*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLuint> mBuffers;
108*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLenum> mBindingPoints;
109*8975f5c5SAndroid Build Coastguard Worker     GLuint mMaxVertexAttribs = 0;
110*8975f5c5SAndroid Build Coastguard Worker };
111*8975f5c5SAndroid Build Coastguard Worker 
BindingsBenchmark()112*8975f5c5SAndroid Build Coastguard Worker BindingsBenchmark::BindingsBenchmark() : ANGLERenderTest("Bindings", GetParam())
113*8975f5c5SAndroid Build Coastguard Worker {
114*8975f5c5SAndroid Build Coastguard Worker     if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
115*8975f5c5SAndroid Build Coastguard Worker     {
116*8975f5c5SAndroid Build Coastguard Worker         skipTest("http://anglebug.com/42264783 Flaky on OpenGL");
117*8975f5c5SAndroid Build Coastguard Worker     }
118*8975f5c5SAndroid Build Coastguard Worker }
119*8975f5c5SAndroid Build Coastguard Worker 
initializeBenchmark()120*8975f5c5SAndroid Build Coastguard Worker void BindingsBenchmark::initializeBenchmark()
121*8975f5c5SAndroid Build Coastguard Worker {
122*8975f5c5SAndroid Build Coastguard Worker     const BindingsParams &params = GetParam();
123*8975f5c5SAndroid Build Coastguard Worker 
124*8975f5c5SAndroid Build Coastguard Worker     mBuffers.resize(params.numObjects, 0);
125*8975f5c5SAndroid Build Coastguard Worker     if (params.allocationStyle == AT_INITIALIZATION)
126*8975f5c5SAndroid Build Coastguard Worker     {
127*8975f5c5SAndroid Build Coastguard Worker         glGenBuffers(static_cast<GLsizei>(mBuffers.size()), mBuffers.data());
128*8975f5c5SAndroid Build Coastguard Worker         for (size_t bufferIdx = 0; bufferIdx < mBuffers.size(); bufferIdx++)
129*8975f5c5SAndroid Build Coastguard Worker         {
130*8975f5c5SAndroid Build Coastguard Worker             glBindBuffer(GL_ARRAY_BUFFER, mBuffers[bufferIdx]);
131*8975f5c5SAndroid Build Coastguard Worker         }
132*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, 0);
133*8975f5c5SAndroid Build Coastguard Worker     }
134*8975f5c5SAndroid Build Coastguard Worker 
135*8975f5c5SAndroid Build Coastguard Worker     if (params.testMode == TestMode::MultipleBindings)
136*8975f5c5SAndroid Build Coastguard Worker     {
137*8975f5c5SAndroid Build Coastguard Worker         mBindingPoints.push_back(GL_ARRAY_BUFFER);
138*8975f5c5SAndroid Build Coastguard Worker         mBindingPoints.push_back(GL_ELEMENT_ARRAY_BUFFER);
139*8975f5c5SAndroid Build Coastguard Worker         if (params.majorVersion >= 3)
140*8975f5c5SAndroid Build Coastguard Worker         {
141*8975f5c5SAndroid Build Coastguard Worker             mBindingPoints.push_back(GL_PIXEL_PACK_BUFFER);
142*8975f5c5SAndroid Build Coastguard Worker             mBindingPoints.push_back(GL_PIXEL_UNPACK_BUFFER);
143*8975f5c5SAndroid Build Coastguard Worker             mBindingPoints.push_back(GL_COPY_READ_BUFFER);
144*8975f5c5SAndroid Build Coastguard Worker             mBindingPoints.push_back(GL_COPY_WRITE_BUFFER);
145*8975f5c5SAndroid Build Coastguard Worker             mBindingPoints.push_back(GL_TRANSFORM_FEEDBACK_BUFFER);
146*8975f5c5SAndroid Build Coastguard Worker             mBindingPoints.push_back(GL_UNIFORM_BUFFER);
147*8975f5c5SAndroid Build Coastguard Worker         }
148*8975f5c5SAndroid Build Coastguard Worker         if (params.majorVersion > 3 || (params.majorVersion == 3 && params.minorVersion >= 1))
149*8975f5c5SAndroid Build Coastguard Worker         {
150*8975f5c5SAndroid Build Coastguard Worker             mBindingPoints.push_back(GL_ATOMIC_COUNTER_BUFFER);
151*8975f5c5SAndroid Build Coastguard Worker             mBindingPoints.push_back(GL_SHADER_STORAGE_BUFFER);
152*8975f5c5SAndroid Build Coastguard Worker             mBindingPoints.push_back(GL_DRAW_INDIRECT_BUFFER);
153*8975f5c5SAndroid Build Coastguard Worker             mBindingPoints.push_back(GL_DISPATCH_INDIRECT_BUFFER);
154*8975f5c5SAndroid Build Coastguard Worker         }
155*8975f5c5SAndroid Build Coastguard Worker     }
156*8975f5c5SAndroid Build Coastguard Worker     else
157*8975f5c5SAndroid Build Coastguard Worker     {
158*8975f5c5SAndroid Build Coastguard Worker         mBindingPoints.resize(mBuffers.size(), GL_ARRAY_BUFFER);
159*8975f5c5SAndroid Build Coastguard Worker     }
160*8975f5c5SAndroid Build Coastguard Worker 
161*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, reinterpret_cast<GLint *>(&mMaxVertexAttribs));
162*8975f5c5SAndroid Build Coastguard Worker }
163*8975f5c5SAndroid Build Coastguard Worker 
destroyBenchmark()164*8975f5c5SAndroid Build Coastguard Worker void BindingsBenchmark::destroyBenchmark()
165*8975f5c5SAndroid Build Coastguard Worker {
166*8975f5c5SAndroid Build Coastguard Worker     const BindingsParams &params = GetParam();
167*8975f5c5SAndroid Build Coastguard Worker     if (params.allocationStyle == AT_INITIALIZATION)
168*8975f5c5SAndroid Build Coastguard Worker     {
169*8975f5c5SAndroid Build Coastguard Worker         glDeleteBuffers(static_cast<GLsizei>(mBuffers.size()), mBuffers.data());
170*8975f5c5SAndroid Build Coastguard Worker     }
171*8975f5c5SAndroid Build Coastguard Worker }
172*8975f5c5SAndroid Build Coastguard Worker 
drawBenchmark()173*8975f5c5SAndroid Build Coastguard Worker void BindingsBenchmark::drawBenchmark()
174*8975f5c5SAndroid Build Coastguard Worker {
175*8975f5c5SAndroid Build Coastguard Worker     const BindingsParams &params = GetParam();
176*8975f5c5SAndroid Build Coastguard Worker 
177*8975f5c5SAndroid Build Coastguard Worker     for (unsigned int it = 0; it < params.iterationsPerStep; ++it)
178*8975f5c5SAndroid Build Coastguard Worker     {
179*8975f5c5SAndroid Build Coastguard Worker         // Generate a buffer (if needed) and bind it to a "random" binding point
180*8975f5c5SAndroid Build Coastguard Worker         if (params.allocationStyle == EVERY_ITERATION)
181*8975f5c5SAndroid Build Coastguard Worker         {
182*8975f5c5SAndroid Build Coastguard Worker             glGenBuffers(static_cast<GLsizei>(mBuffers.size()), mBuffers.data());
183*8975f5c5SAndroid Build Coastguard Worker         }
184*8975f5c5SAndroid Build Coastguard Worker 
185*8975f5c5SAndroid Build Coastguard Worker         // Fetch a few variables from the underlying data structure to keep them in registers.
186*8975f5c5SAndroid Build Coastguard Worker         // Otherwise each loop iteration they'll be fetched again because the compiler cannot
187*8975f5c5SAndroid Build Coastguard Worker         // guarantee that those are unchanged when calling glBindBuffer.
188*8975f5c5SAndroid Build Coastguard Worker         const GLuint *buffers       = mBuffers.data();
189*8975f5c5SAndroid Build Coastguard Worker         const GLenum *bindingPoints = mBindingPoints.data();
190*8975f5c5SAndroid Build Coastguard Worker         size_t bindingPointsSize    = mBindingPoints.size();
191*8975f5c5SAndroid Build Coastguard Worker         size_t buffersSize          = mBuffers.size();
192*8975f5c5SAndroid Build Coastguard Worker         size_t bindingIndex         = it % bindingPointsSize;
193*8975f5c5SAndroid Build Coastguard Worker         for (GLuint bufferIdx = 0; bufferIdx < buffersSize; bufferIdx++)
194*8975f5c5SAndroid Build Coastguard Worker         {
195*8975f5c5SAndroid Build Coastguard Worker             GLenum binding = bindingPoints[bindingIndex];
196*8975f5c5SAndroid Build Coastguard Worker             glBindBuffer(binding, buffers[bufferIdx]);
197*8975f5c5SAndroid Build Coastguard Worker 
198*8975f5c5SAndroid Build Coastguard Worker             // Instead of doing a costly division to get an index in the range [0,bindingPointsSize)
199*8975f5c5SAndroid Build Coastguard Worker             // do a bounds-check and reset the index.
200*8975f5c5SAndroid Build Coastguard Worker             ++bindingIndex;
201*8975f5c5SAndroid Build Coastguard Worker             bindingIndex = (bindingIndex >= bindingPointsSize) ? 0 : bindingIndex;
202*8975f5c5SAndroid Build Coastguard Worker 
203*8975f5c5SAndroid Build Coastguard Worker             if (params.testMode == TestMode::VertexArray)
204*8975f5c5SAndroid Build Coastguard Worker             {
205*8975f5c5SAndroid Build Coastguard Worker                 GLuint vertexAttribIndex = bufferIdx % mMaxVertexAttribs;
206*8975f5c5SAndroid Build Coastguard Worker                 glVertexAttribPointer(vertexAttribIndex, 1, GL_FLOAT, GL_FALSE, 0, 0);
207*8975f5c5SAndroid Build Coastguard Worker             }
208*8975f5c5SAndroid Build Coastguard Worker         }
209*8975f5c5SAndroid Build Coastguard Worker 
210*8975f5c5SAndroid Build Coastguard Worker         // Delete all the buffers
211*8975f5c5SAndroid Build Coastguard Worker         if (params.allocationStyle == EVERY_ITERATION)
212*8975f5c5SAndroid Build Coastguard Worker         {
213*8975f5c5SAndroid Build Coastguard Worker             glDeleteBuffers(static_cast<GLsizei>(mBuffers.size()), mBuffers.data());
214*8975f5c5SAndroid Build Coastguard Worker         }
215*8975f5c5SAndroid Build Coastguard Worker     }
216*8975f5c5SAndroid Build Coastguard Worker 
217*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
218*8975f5c5SAndroid Build Coastguard Worker }
219*8975f5c5SAndroid Build Coastguard Worker 
D3D11Params(AllocationStyle allocationStyle)220*8975f5c5SAndroid Build Coastguard Worker BindingsParams D3D11Params(AllocationStyle allocationStyle)
221*8975f5c5SAndroid Build Coastguard Worker {
222*8975f5c5SAndroid Build Coastguard Worker     BindingsParams params;
223*8975f5c5SAndroid Build Coastguard Worker     params.eglParameters   = egl_platform::D3D11_NULL();
224*8975f5c5SAndroid Build Coastguard Worker     params.allocationStyle = allocationStyle;
225*8975f5c5SAndroid Build Coastguard Worker     return params;
226*8975f5c5SAndroid Build Coastguard Worker }
227*8975f5c5SAndroid Build Coastguard Worker 
OpenGLOrGLESParams(AllocationStyle allocationStyle)228*8975f5c5SAndroid Build Coastguard Worker BindingsParams OpenGLOrGLESParams(AllocationStyle allocationStyle)
229*8975f5c5SAndroid Build Coastguard Worker {
230*8975f5c5SAndroid Build Coastguard Worker     BindingsParams params;
231*8975f5c5SAndroid Build Coastguard Worker     params.eglParameters   = egl_platform::OPENGL_OR_GLES_NULL();
232*8975f5c5SAndroid Build Coastguard Worker     params.allocationStyle = allocationStyle;
233*8975f5c5SAndroid Build Coastguard Worker     return params;
234*8975f5c5SAndroid Build Coastguard Worker }
235*8975f5c5SAndroid Build Coastguard Worker 
VulkanParams(AllocationStyle allocationStyle,TestMode testMode)236*8975f5c5SAndroid Build Coastguard Worker BindingsParams VulkanParams(AllocationStyle allocationStyle, TestMode testMode)
237*8975f5c5SAndroid Build Coastguard Worker {
238*8975f5c5SAndroid Build Coastguard Worker     BindingsParams params;
239*8975f5c5SAndroid Build Coastguard Worker     params.eglParameters   = egl_platform::VULKAN_NULL();
240*8975f5c5SAndroid Build Coastguard Worker     params.allocationStyle = allocationStyle;
241*8975f5c5SAndroid Build Coastguard Worker     params.testMode        = testMode;
242*8975f5c5SAndroid Build Coastguard Worker     return params;
243*8975f5c5SAndroid Build Coastguard Worker }
244*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(BindingsBenchmark,Run)245*8975f5c5SAndroid Build Coastguard Worker TEST_P(BindingsBenchmark, Run)
246*8975f5c5SAndroid Build Coastguard Worker {
247*8975f5c5SAndroid Build Coastguard Worker     run();
248*8975f5c5SAndroid Build Coastguard Worker }
249*8975f5c5SAndroid Build Coastguard Worker }  // namespace
250*8975f5c5SAndroid Build Coastguard Worker 
251*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(BindingsBenchmark,
252*8975f5c5SAndroid Build Coastguard Worker                        D3D11Params(EVERY_ITERATION),
253*8975f5c5SAndroid Build Coastguard Worker                        D3D11Params(AT_INITIALIZATION),
254*8975f5c5SAndroid Build Coastguard Worker                        OpenGLOrGLESParams(EVERY_ITERATION),
255*8975f5c5SAndroid Build Coastguard Worker                        OpenGLOrGLESParams(AT_INITIALIZATION),
256*8975f5c5SAndroid Build Coastguard Worker                        VulkanParams(EVERY_ITERATION, TestMode::MultipleBindings),
257*8975f5c5SAndroid Build Coastguard Worker                        VulkanParams(AT_INITIALIZATION, TestMode::MultipleBindings),
258*8975f5c5SAndroid Build Coastguard Worker                        VulkanParams(AT_INITIALIZATION, TestMode::VertexArray));
259*8975f5c5SAndroid Build Coastguard Worker 
260*8975f5c5SAndroid Build Coastguard Worker }  // namespace angle
261