• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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__anon1a905d180111::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     // Timing out on Intel. http://crbug.com/921004
76     if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
77     {
78         mSkipTest = true;
79     }
80 }
81 
initializeBenchmark()82 void InterleavedAttributeDataBenchmark::initializeBenchmark()
83 {
84     const auto &params = GetParam();
85 
86     // Compile point sprite shaders
87     constexpr char kVS[] =
88         "attribute vec4 aPosition;"
89         "attribute vec4 aColor;"
90         "varying vec4 vColor;"
91         "void main()"
92         "{"
93         "    gl_PointSize = 25.0;"
94         "    gl_Position  = aPosition;"
95         "    vColor = aColor;"
96         "}";
97 
98     constexpr char kFS[] =
99         "precision mediump float;"
100         "varying vec4 vColor;"
101         "void main()"
102         "{"
103         "    gl_FragColor = vColor;"
104         "}";
105 
106     mPointSpriteProgram = CompileProgram(kVS, kFS);
107     ASSERT_NE(0u, mPointSpriteProgram);
108 
109     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
110 
111     for (size_t i = 0; i < ArraySize(mPositionColorBuffer); i++)
112     {
113         // Set up initial data for pointsprite positions and colors
114         std::vector<uint8_t> positionColorData(mBytesPerSprite * params.numSprites);
115         for (unsigned int j = 0; j < params.numSprites; j++)
116         {
117             float pointSpriteX =
118                 (static_cast<float>(rand() % getWindow()->getWidth()) / getWindow()->getWidth()) *
119                     2.0f -
120                 1.0f;
121             float pointSpriteY =
122                 (static_cast<float>(rand() % getWindow()->getHeight()) / getWindow()->getHeight()) *
123                     2.0f -
124                 1.0f;
125             GLubyte pointSpriteRed   = static_cast<GLubyte>(rand() % 255);
126             GLubyte pointSpriteGreen = static_cast<GLubyte>(rand() % 255);
127             GLubyte pointSpriteBlue  = static_cast<GLubyte>(rand() % 255);
128 
129             // Add position data for the pointsprite
130             *reinterpret_cast<float *>(
131                 &(positionColorData[j * mBytesPerSprite + 0 * sizeof(float) + 0])) =
132                 pointSpriteX;  // X
133             *reinterpret_cast<float *>(
134                 &(positionColorData[j * mBytesPerSprite + 1 * sizeof(float) + 0])) =
135                 pointSpriteY;  // Y
136 
137             // Add color data for the pointsprite
138             positionColorData[j * mBytesPerSprite + 2 * sizeof(float) + 0] = pointSpriteRed;    // R
139             positionColorData[j * mBytesPerSprite + 2 * sizeof(float) + 1] = pointSpriteGreen;  // G
140             positionColorData[j * mBytesPerSprite + 2 * sizeof(float) + 2] = pointSpriteBlue;   // B
141         }
142 
143         // Generate the GL buffer with the position/color data
144         glGenBuffers(1, &mPositionColorBuffer[i]);
145         glBindBuffer(GL_ARRAY_BUFFER, mPositionColorBuffer[i]);
146         glBufferData(GL_ARRAY_BUFFER, params.numSprites * mBytesPerSprite, &(positionColorData[0]),
147                      GL_STATIC_DRAW);
148     }
149 
150     ASSERT_GL_NO_ERROR();
151 }
152 
destroyBenchmark()153 void InterleavedAttributeDataBenchmark::destroyBenchmark()
154 {
155     glDeleteProgram(mPointSpriteProgram);
156 
157     for (size_t i = 0; i < ArraySize(mPositionColorBuffer); i++)
158     {
159         glDeleteBuffers(1, &mPositionColorBuffer[i]);
160     }
161 }
162 
drawBenchmark()163 void InterleavedAttributeDataBenchmark::drawBenchmark()
164 {
165     glClear(GL_COLOR_BUFFER_BIT);
166 
167     for (size_t k = 0; k < 20; k++)
168     {
169         for (size_t i = 0; i < ArraySize(mPositionColorBuffer); i++)
170         {
171             // Firstly get the attribute locations for the program
172             glUseProgram(mPointSpriteProgram);
173             GLint positionLocation = glGetAttribLocation(mPointSpriteProgram, "aPosition");
174             ASSERT_NE(positionLocation, -1);
175             GLint colorLocation = glGetAttribLocation(mPointSpriteProgram, "aColor");
176             ASSERT_NE(colorLocation, -1);
177 
178             // Bind the position data from one buffer
179             glBindBuffer(GL_ARRAY_BUFFER, mPositionColorBuffer[i]);
180             glEnableVertexAttribArray(positionLocation);
181             glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE,
182                                   static_cast<GLsizei>(mBytesPerSprite), 0);
183 
184             // But bind the color data from the other buffer.
185             glBindBuffer(GL_ARRAY_BUFFER,
186                          mPositionColorBuffer[(i + 1) % ArraySize(mPositionColorBuffer)]);
187             glEnableVertexAttribArray(colorLocation);
188             glVertexAttribPointer(colorLocation, 3, GL_UNSIGNED_BYTE, GL_TRUE,
189                                   static_cast<GLsizei>(mBytesPerSprite),
190                                   reinterpret_cast<void *>(2 * sizeof(float)));
191 
192             // Then draw the colored pointsprites
193             glDrawArrays(GL_POINTS, 0, GetParam().numSprites);
194 
195             glDisableVertexAttribArray(positionLocation);
196             glDisableVertexAttribArray(colorLocation);
197         }
198     }
199 
200     ASSERT_GL_NO_ERROR();
201 }
202 
TEST_P(InterleavedAttributeDataBenchmark,Run)203 TEST_P(InterleavedAttributeDataBenchmark, Run)
204 {
205     run();
206 }
207 
D3D11Params()208 InterleavedAttributeDataParams D3D11Params()
209 {
210     InterleavedAttributeDataParams params;
211     params.eglParameters = egl_platform::D3D11();
212     return params;
213 }
214 
OpenGLOrGLESParams()215 InterleavedAttributeDataParams OpenGLOrGLESParams()
216 {
217     InterleavedAttributeDataParams params;
218     params.eglParameters = egl_platform::OPENGL_OR_GLES();
219     return params;
220 }
221 
VulkanParams()222 InterleavedAttributeDataParams VulkanParams()
223 {
224     InterleavedAttributeDataParams params;
225     params.eglParameters = egl_platform::VULKAN();
226     return params;
227 }
228 
229 ANGLE_INSTANTIATE_TEST(InterleavedAttributeDataBenchmark,
230                        D3D11Params(),
231                        OpenGLOrGLESParams(),
232                        VulkanParams());
233 
234 }  // anonymous namespace
235