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