xref: /aosp_15_r20/external/angle/src/tests/perf_tests/InterleavedAttributeData.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2014 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 // InterleavedAttributeData:
7*8975f5c5SAndroid Build Coastguard Worker //   Performance test for draws using interleaved attribute data in vertex buffers.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include <sstream>
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker #include "ANGLEPerfTest.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "util/shader_utils.h"
14*8975f5c5SAndroid Build Coastguard Worker 
15*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
16*8975f5c5SAndroid Build Coastguard Worker 
17*8975f5c5SAndroid Build Coastguard Worker namespace
18*8975f5c5SAndroid Build Coastguard Worker {
19*8975f5c5SAndroid Build Coastguard Worker 
20*8975f5c5SAndroid Build Coastguard Worker struct InterleavedAttributeDataParams final : public RenderTestParams
21*8975f5c5SAndroid Build Coastguard Worker {
InterleavedAttributeDataParams__anon69ff6b160111::InterleavedAttributeDataParams22*8975f5c5SAndroid Build Coastguard Worker     InterleavedAttributeDataParams()
23*8975f5c5SAndroid Build Coastguard Worker     {
24*8975f5c5SAndroid Build Coastguard Worker         iterationsPerStep = 1;
25*8975f5c5SAndroid Build Coastguard Worker 
26*8975f5c5SAndroid Build Coastguard Worker         // Common default values
27*8975f5c5SAndroid Build Coastguard Worker         majorVersion = 2;
28*8975f5c5SAndroid Build Coastguard Worker         minorVersion = 0;
29*8975f5c5SAndroid Build Coastguard Worker         windowWidth  = 512;
30*8975f5c5SAndroid Build Coastguard Worker         windowHeight = 512;
31*8975f5c5SAndroid Build Coastguard Worker         numSprites   = 3000;
32*8975f5c5SAndroid Build Coastguard Worker     }
33*8975f5c5SAndroid Build Coastguard Worker 
34*8975f5c5SAndroid Build Coastguard Worker     // static parameters
35*8975f5c5SAndroid Build Coastguard Worker     unsigned int numSprites;
36*8975f5c5SAndroid Build Coastguard Worker };
37*8975f5c5SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const InterleavedAttributeDataParams & params)38*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const InterleavedAttributeDataParams &params)
39*8975f5c5SAndroid Build Coastguard Worker {
40*8975f5c5SAndroid Build Coastguard Worker     os << params.backendAndStory().substr(1);
41*8975f5c5SAndroid Build Coastguard Worker 
42*8975f5c5SAndroid Build Coastguard Worker     if (params.eglParameters.majorVersion != EGL_DONT_CARE)
43*8975f5c5SAndroid Build Coastguard Worker     {
44*8975f5c5SAndroid Build Coastguard Worker         os << "_" << params.eglParameters.majorVersion << "_" << params.eglParameters.minorVersion;
45*8975f5c5SAndroid Build Coastguard Worker     }
46*8975f5c5SAndroid Build Coastguard Worker 
47*8975f5c5SAndroid Build Coastguard Worker     return os;
48*8975f5c5SAndroid Build Coastguard Worker }
49*8975f5c5SAndroid Build Coastguard Worker 
50*8975f5c5SAndroid Build Coastguard Worker class InterleavedAttributeDataBenchmark
51*8975f5c5SAndroid Build Coastguard Worker     : public ANGLERenderTest,
52*8975f5c5SAndroid Build Coastguard Worker       public ::testing::WithParamInterface<InterleavedAttributeDataParams>
53*8975f5c5SAndroid Build Coastguard Worker {
54*8975f5c5SAndroid Build Coastguard Worker   public:
55*8975f5c5SAndroid Build Coastguard Worker     InterleavedAttributeDataBenchmark();
56*8975f5c5SAndroid Build Coastguard Worker 
57*8975f5c5SAndroid Build Coastguard Worker     void initializeBenchmark() override;
58*8975f5c5SAndroid Build Coastguard Worker     void destroyBenchmark() override;
59*8975f5c5SAndroid Build Coastguard Worker     void drawBenchmark() override;
60*8975f5c5SAndroid Build Coastguard Worker 
61*8975f5c5SAndroid Build Coastguard Worker   private:
62*8975f5c5SAndroid Build Coastguard Worker     GLuint mPointSpriteProgram;
63*8975f5c5SAndroid Build Coastguard Worker     GLuint mPositionColorBuffer[2];
64*8975f5c5SAndroid Build Coastguard Worker 
65*8975f5c5SAndroid Build Coastguard Worker     // The buffers contain two floats and 3 unsigned bytes per point sprite
66*8975f5c5SAndroid Build Coastguard Worker     // Has to be aligned for float access on arm
67*8975f5c5SAndroid Build Coastguard Worker     const size_t mBytesPerSpriteUnaligned = 2 * sizeof(float) + 3;
68*8975f5c5SAndroid Build Coastguard Worker     const size_t mBytesPerSprite =
69*8975f5c5SAndroid Build Coastguard Worker         ((mBytesPerSpriteUnaligned + sizeof(float) - 1) / sizeof(float)) * sizeof(float);
70*8975f5c5SAndroid Build Coastguard Worker };
71*8975f5c5SAndroid Build Coastguard Worker 
InterleavedAttributeDataBenchmark()72*8975f5c5SAndroid Build Coastguard Worker InterleavedAttributeDataBenchmark::InterleavedAttributeDataBenchmark()
73*8975f5c5SAndroid Build Coastguard Worker     : ANGLERenderTest("InterleavedAttributeData", GetParam()), mPointSpriteProgram(0)
74*8975f5c5SAndroid Build Coastguard Worker {
75*8975f5c5SAndroid Build Coastguard Worker     if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
76*8975f5c5SAndroid Build Coastguard Worker     {
77*8975f5c5SAndroid Build Coastguard Worker         skipTest("http://crbug.com/921004 Timing out on Intel");
78*8975f5c5SAndroid Build Coastguard Worker     }
79*8975f5c5SAndroid Build Coastguard Worker }
80*8975f5c5SAndroid Build Coastguard Worker 
initializeBenchmark()81*8975f5c5SAndroid Build Coastguard Worker void InterleavedAttributeDataBenchmark::initializeBenchmark()
82*8975f5c5SAndroid Build Coastguard Worker {
83*8975f5c5SAndroid Build Coastguard Worker     const auto &params = GetParam();
84*8975f5c5SAndroid Build Coastguard Worker 
85*8975f5c5SAndroid Build Coastguard Worker     // Compile point sprite shaders
86*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVS[] =
87*8975f5c5SAndroid Build Coastguard Worker         "attribute vec4 aPosition;"
88*8975f5c5SAndroid Build Coastguard Worker         "attribute vec4 aColor;"
89*8975f5c5SAndroid Build Coastguard Worker         "varying vec4 vColor;"
90*8975f5c5SAndroid Build Coastguard Worker         "void main()"
91*8975f5c5SAndroid Build Coastguard Worker         "{"
92*8975f5c5SAndroid Build Coastguard Worker         "    gl_PointSize = 25.0;"
93*8975f5c5SAndroid Build Coastguard Worker         "    gl_Position  = aPosition;"
94*8975f5c5SAndroid Build Coastguard Worker         "    vColor = aColor;"
95*8975f5c5SAndroid Build Coastguard Worker         "}";
96*8975f5c5SAndroid Build Coastguard Worker 
97*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] =
98*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;"
99*8975f5c5SAndroid Build Coastguard Worker         "varying vec4 vColor;"
100*8975f5c5SAndroid Build Coastguard Worker         "void main()"
101*8975f5c5SAndroid Build Coastguard Worker         "{"
102*8975f5c5SAndroid Build Coastguard Worker         "    gl_FragColor = vColor;"
103*8975f5c5SAndroid Build Coastguard Worker         "}";
104*8975f5c5SAndroid Build Coastguard Worker 
105*8975f5c5SAndroid Build Coastguard Worker     mPointSpriteProgram = CompileProgram(kVS, kFS);
106*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(0u, mPointSpriteProgram);
107*8975f5c5SAndroid Build Coastguard Worker 
108*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
109*8975f5c5SAndroid Build Coastguard Worker 
110*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < ArraySize(mPositionColorBuffer); i++)
111*8975f5c5SAndroid Build Coastguard Worker     {
112*8975f5c5SAndroid Build Coastguard Worker         // Set up initial data for pointsprite positions and colors
113*8975f5c5SAndroid Build Coastguard Worker         std::vector<uint8_t> positionColorData(mBytesPerSprite * params.numSprites);
114*8975f5c5SAndroid Build Coastguard Worker         for (unsigned int j = 0; j < params.numSprites; j++)
115*8975f5c5SAndroid Build Coastguard Worker         {
116*8975f5c5SAndroid Build Coastguard Worker             float pointSpriteX =
117*8975f5c5SAndroid Build Coastguard Worker                 (static_cast<float>(rand() % getWindow()->getWidth()) / getWindow()->getWidth()) *
118*8975f5c5SAndroid Build Coastguard Worker                     2.0f -
119*8975f5c5SAndroid Build Coastguard Worker                 1.0f;
120*8975f5c5SAndroid Build Coastguard Worker             float pointSpriteY =
121*8975f5c5SAndroid Build Coastguard Worker                 (static_cast<float>(rand() % getWindow()->getHeight()) / getWindow()->getHeight()) *
122*8975f5c5SAndroid Build Coastguard Worker                     2.0f -
123*8975f5c5SAndroid Build Coastguard Worker                 1.0f;
124*8975f5c5SAndroid Build Coastguard Worker             GLubyte pointSpriteRed   = static_cast<GLubyte>(rand() % 255);
125*8975f5c5SAndroid Build Coastguard Worker             GLubyte pointSpriteGreen = static_cast<GLubyte>(rand() % 255);
126*8975f5c5SAndroid Build Coastguard Worker             GLubyte pointSpriteBlue  = static_cast<GLubyte>(rand() % 255);
127*8975f5c5SAndroid Build Coastguard Worker 
128*8975f5c5SAndroid Build Coastguard Worker             // Add position data for the pointsprite
129*8975f5c5SAndroid Build Coastguard Worker             *reinterpret_cast<float *>(
130*8975f5c5SAndroid Build Coastguard Worker                 &(positionColorData[j * mBytesPerSprite + 0 * sizeof(float) + 0])) =
131*8975f5c5SAndroid Build Coastguard Worker                 pointSpriteX;  // X
132*8975f5c5SAndroid Build Coastguard Worker             *reinterpret_cast<float *>(
133*8975f5c5SAndroid Build Coastguard Worker                 &(positionColorData[j * mBytesPerSprite + 1 * sizeof(float) + 0])) =
134*8975f5c5SAndroid Build Coastguard Worker                 pointSpriteY;  // Y
135*8975f5c5SAndroid Build Coastguard Worker 
136*8975f5c5SAndroid Build Coastguard Worker             // Add color data for the pointsprite
137*8975f5c5SAndroid Build Coastguard Worker             positionColorData[j * mBytesPerSprite + 2 * sizeof(float) + 0] = pointSpriteRed;    // R
138*8975f5c5SAndroid Build Coastguard Worker             positionColorData[j * mBytesPerSprite + 2 * sizeof(float) + 1] = pointSpriteGreen;  // G
139*8975f5c5SAndroid Build Coastguard Worker             positionColorData[j * mBytesPerSprite + 2 * sizeof(float) + 2] = pointSpriteBlue;   // B
140*8975f5c5SAndroid Build Coastguard Worker         }
141*8975f5c5SAndroid Build Coastguard Worker 
142*8975f5c5SAndroid Build Coastguard Worker         // Generate the GL buffer with the position/color data
143*8975f5c5SAndroid Build Coastguard Worker         glGenBuffers(1, &mPositionColorBuffer[i]);
144*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, mPositionColorBuffer[i]);
145*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, params.numSprites * mBytesPerSprite, &(positionColorData[0]),
146*8975f5c5SAndroid Build Coastguard Worker                      GL_STATIC_DRAW);
147*8975f5c5SAndroid Build Coastguard Worker     }
148*8975f5c5SAndroid Build Coastguard Worker 
149*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
150*8975f5c5SAndroid Build Coastguard Worker }
151*8975f5c5SAndroid Build Coastguard Worker 
destroyBenchmark()152*8975f5c5SAndroid Build Coastguard Worker void InterleavedAttributeDataBenchmark::destroyBenchmark()
153*8975f5c5SAndroid Build Coastguard Worker {
154*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(mPointSpriteProgram);
155*8975f5c5SAndroid Build Coastguard Worker 
156*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < ArraySize(mPositionColorBuffer); i++)
157*8975f5c5SAndroid Build Coastguard Worker     {
158*8975f5c5SAndroid Build Coastguard Worker         glDeleteBuffers(1, &mPositionColorBuffer[i]);
159*8975f5c5SAndroid Build Coastguard Worker     }
160*8975f5c5SAndroid Build Coastguard Worker }
161*8975f5c5SAndroid Build Coastguard Worker 
drawBenchmark()162*8975f5c5SAndroid Build Coastguard Worker void InterleavedAttributeDataBenchmark::drawBenchmark()
163*8975f5c5SAndroid Build Coastguard Worker {
164*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
165*8975f5c5SAndroid Build Coastguard Worker 
166*8975f5c5SAndroid Build Coastguard Worker     for (size_t k = 0; k < 20; k++)
167*8975f5c5SAndroid Build Coastguard Worker     {
168*8975f5c5SAndroid Build Coastguard Worker         for (size_t i = 0; i < ArraySize(mPositionColorBuffer); i++)
169*8975f5c5SAndroid Build Coastguard Worker         {
170*8975f5c5SAndroid Build Coastguard Worker             // Firstly get the attribute locations for the program
171*8975f5c5SAndroid Build Coastguard Worker             glUseProgram(mPointSpriteProgram);
172*8975f5c5SAndroid Build Coastguard Worker             GLint positionLocation = glGetAttribLocation(mPointSpriteProgram, "aPosition");
173*8975f5c5SAndroid Build Coastguard Worker             ASSERT_NE(positionLocation, -1);
174*8975f5c5SAndroid Build Coastguard Worker             GLint colorLocation = glGetAttribLocation(mPointSpriteProgram, "aColor");
175*8975f5c5SAndroid Build Coastguard Worker             ASSERT_NE(colorLocation, -1);
176*8975f5c5SAndroid Build Coastguard Worker 
177*8975f5c5SAndroid Build Coastguard Worker             // Bind the position data from one buffer
178*8975f5c5SAndroid Build Coastguard Worker             glBindBuffer(GL_ARRAY_BUFFER, mPositionColorBuffer[i]);
179*8975f5c5SAndroid Build Coastguard Worker             glEnableVertexAttribArray(positionLocation);
180*8975f5c5SAndroid Build Coastguard Worker             glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE,
181*8975f5c5SAndroid Build Coastguard Worker                                   static_cast<GLsizei>(mBytesPerSprite), 0);
182*8975f5c5SAndroid Build Coastguard Worker 
183*8975f5c5SAndroid Build Coastguard Worker             // But bind the color data from the other buffer.
184*8975f5c5SAndroid Build Coastguard Worker             glBindBuffer(GL_ARRAY_BUFFER,
185*8975f5c5SAndroid Build Coastguard Worker                          mPositionColorBuffer[(i + 1) % ArraySize(mPositionColorBuffer)]);
186*8975f5c5SAndroid Build Coastguard Worker             glEnableVertexAttribArray(colorLocation);
187*8975f5c5SAndroid Build Coastguard Worker             glVertexAttribPointer(colorLocation, 3, GL_UNSIGNED_BYTE, GL_TRUE,
188*8975f5c5SAndroid Build Coastguard Worker                                   static_cast<GLsizei>(mBytesPerSprite),
189*8975f5c5SAndroid Build Coastguard Worker                                   reinterpret_cast<void *>(2 * sizeof(float)));
190*8975f5c5SAndroid Build Coastguard Worker 
191*8975f5c5SAndroid Build Coastguard Worker             // Then draw the colored pointsprites
192*8975f5c5SAndroid Build Coastguard Worker             glDrawArrays(GL_POINTS, 0, GetParam().numSprites);
193*8975f5c5SAndroid Build Coastguard Worker 
194*8975f5c5SAndroid Build Coastguard Worker             glDisableVertexAttribArray(positionLocation);
195*8975f5c5SAndroid Build Coastguard Worker             glDisableVertexAttribArray(colorLocation);
196*8975f5c5SAndroid Build Coastguard Worker         }
197*8975f5c5SAndroid Build Coastguard Worker     }
198*8975f5c5SAndroid Build Coastguard Worker 
199*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
200*8975f5c5SAndroid Build Coastguard Worker }
201*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(InterleavedAttributeDataBenchmark,Run)202*8975f5c5SAndroid Build Coastguard Worker TEST_P(InterleavedAttributeDataBenchmark, Run)
203*8975f5c5SAndroid Build Coastguard Worker {
204*8975f5c5SAndroid Build Coastguard Worker     run();
205*8975f5c5SAndroid Build Coastguard Worker }
206*8975f5c5SAndroid Build Coastguard Worker 
D3D11Params()207*8975f5c5SAndroid Build Coastguard Worker InterleavedAttributeDataParams D3D11Params()
208*8975f5c5SAndroid Build Coastguard Worker {
209*8975f5c5SAndroid Build Coastguard Worker     InterleavedAttributeDataParams params;
210*8975f5c5SAndroid Build Coastguard Worker     params.eglParameters = egl_platform::D3D11();
211*8975f5c5SAndroid Build Coastguard Worker     return params;
212*8975f5c5SAndroid Build Coastguard Worker }
213*8975f5c5SAndroid Build Coastguard Worker 
MetalParams()214*8975f5c5SAndroid Build Coastguard Worker InterleavedAttributeDataParams MetalParams()
215*8975f5c5SAndroid Build Coastguard Worker {
216*8975f5c5SAndroid Build Coastguard Worker     InterleavedAttributeDataParams params;
217*8975f5c5SAndroid Build Coastguard Worker     params.eglParameters = egl_platform::METAL();
218*8975f5c5SAndroid Build Coastguard Worker     return params;
219*8975f5c5SAndroid Build Coastguard Worker }
220*8975f5c5SAndroid Build Coastguard Worker 
OpenGLOrGLESParams()221*8975f5c5SAndroid Build Coastguard Worker InterleavedAttributeDataParams OpenGLOrGLESParams()
222*8975f5c5SAndroid Build Coastguard Worker {
223*8975f5c5SAndroid Build Coastguard Worker     InterleavedAttributeDataParams params;
224*8975f5c5SAndroid Build Coastguard Worker     params.eglParameters = egl_platform::OPENGL_OR_GLES();
225*8975f5c5SAndroid Build Coastguard Worker     return params;
226*8975f5c5SAndroid Build Coastguard Worker }
227*8975f5c5SAndroid Build Coastguard Worker 
VulkanParams()228*8975f5c5SAndroid Build Coastguard Worker InterleavedAttributeDataParams VulkanParams()
229*8975f5c5SAndroid Build Coastguard Worker {
230*8975f5c5SAndroid Build Coastguard Worker     InterleavedAttributeDataParams params;
231*8975f5c5SAndroid Build Coastguard Worker     params.eglParameters = egl_platform::VULKAN();
232*8975f5c5SAndroid Build Coastguard Worker     return params;
233*8975f5c5SAndroid Build Coastguard Worker }
234*8975f5c5SAndroid Build Coastguard Worker 
235*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(InterleavedAttributeDataBenchmark,
236*8975f5c5SAndroid Build Coastguard Worker                        D3D11Params(),
237*8975f5c5SAndroid Build Coastguard Worker                        MetalParams(),
238*8975f5c5SAndroid Build Coastguard Worker                        OpenGLOrGLESParams(),
239*8975f5c5SAndroid Build Coastguard Worker                        VulkanParams());
240*8975f5c5SAndroid Build Coastguard Worker 
241*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
242