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 // PointSpritesBenchmark:
7 // Performance test for ANGLE point sprites.
8 //
9 //
10 #include "ANGLEPerfTest.h"
11
12 #include <iostream>
13 #include <sstream>
14
15 #include "util/random_utils.h"
16 #include "util/shader_utils.h"
17
18 using namespace angle;
19
20 namespace
21 {
22 constexpr unsigned int kIterationsPerStep = 100;
23
24 struct PointSpritesParams final : public RenderTestParams
25 {
PointSpritesParams__anon5d91fb180111::PointSpritesParams26 PointSpritesParams()
27 {
28 iterationsPerStep = kIterationsPerStep;
29
30 // Common default params
31 majorVersion = 2;
32 minorVersion = 0;
33 windowWidth = 1280;
34 windowHeight = 720;
35 count = 10;
36 size = 3.0f;
37 numVaryings = 3;
38 }
39
40 std::string story() const override;
41
42 unsigned int count;
43 float size;
44 unsigned int numVaryings;
45 };
46
operator <<(std::ostream & os,const PointSpritesParams & params)47 std::ostream &operator<<(std::ostream &os, const PointSpritesParams ¶ms)
48 {
49 os << params.backendAndStory().substr(1);
50 return os;
51 }
52
53 class PointSpritesBenchmark : public ANGLERenderTest,
54 public ::testing::WithParamInterface<PointSpritesParams>
55 {
56 public:
57 PointSpritesBenchmark();
58
59 void initializeBenchmark() override;
60 void destroyBenchmark() override;
61 void drawBenchmark() override;
62
63 private:
64 GLuint mProgram;
65 GLuint mBuffer;
66 RNG mRNG;
67 };
68
story() const69 std::string PointSpritesParams::story() const
70 {
71 std::stringstream strstr;
72
73 strstr << RenderTestParams::story() << "_" << count << "_" << size << "px"
74 << "_" << numVaryings << "vars";
75
76 return strstr.str();
77 }
78
PointSpritesBenchmark()79 PointSpritesBenchmark::PointSpritesBenchmark()
80 : ANGLERenderTest("PointSprites", GetParam()), mRNG(1)
81 {}
82
initializeBenchmark()83 void PointSpritesBenchmark::initializeBenchmark()
84 {
85 const auto ¶ms = GetParam();
86
87 std::stringstream vstrstr;
88
89 // Verify "numVaryings" is within MAX_VARYINGS limit
90 GLint maxVaryings;
91 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
92
93 if (params.numVaryings > static_cast<unsigned int>(maxVaryings))
94 {
95 FAIL() << "Varying count (" << params.numVaryings << ")"
96 << " exceeds maximum varyings: " << maxVaryings << std::endl;
97 }
98
99 vstrstr << "attribute vec2 vPosition;\n"
100 "uniform float uPointSize;\n";
101
102 for (unsigned int varCount = 0; varCount < params.numVaryings; varCount++)
103 {
104 vstrstr << "varying vec4 v" << varCount << ";\n";
105 }
106
107 vstrstr << "void main()\n"
108 "{\n";
109
110 for (unsigned int varCount = 0; varCount < params.numVaryings; varCount++)
111 {
112 vstrstr << " v" << varCount << " = vec4(1.0);\n";
113 }
114
115 vstrstr << " gl_Position = vec4(vPosition, 0, 1.0);\n"
116 " gl_PointSize = uPointSize;\n"
117 "}";
118
119 std::stringstream fstrstr;
120
121 fstrstr << "precision mediump float;\n";
122
123 for (unsigned int varCount = 0; varCount < params.numVaryings; varCount++)
124 {
125 fstrstr << "varying vec4 v" << varCount << ";\n";
126 }
127
128 fstrstr << "void main()\n"
129 "{\n"
130 " vec4 colorOut = vec4(1.0, 0.0, 0.0, 1.0);\n";
131
132 for (unsigned int varCount = 0; varCount < params.numVaryings; varCount++)
133 {
134 fstrstr << " colorOut.r += v" << varCount << ".r;\n";
135 }
136
137 fstrstr << " gl_FragColor = colorOut;\n"
138 "}\n";
139
140 mProgram = CompileProgram(vstrstr.str().c_str(), fstrstr.str().c_str());
141 ASSERT_NE(0u, mProgram);
142
143 // Use the program object
144 glUseProgram(mProgram);
145
146 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
147
148 std::vector<float> vertexPositions(params.count * 2);
149 for (size_t pointIndex = 0; pointIndex < vertexPositions.size(); ++pointIndex)
150 {
151 vertexPositions[pointIndex] = mRNG.randomNegativeOneToOne();
152 }
153
154 glGenBuffers(1, &mBuffer);
155 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
156 glBufferData(GL_ARRAY_BUFFER, vertexPositions.size() * sizeof(float), &vertexPositions[0],
157 GL_STATIC_DRAW);
158
159 GLint positionLocation = glGetAttribLocation(mProgram, "vPosition");
160 ASSERT_NE(-1, positionLocation);
161
162 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
163 glEnableVertexAttribArray(positionLocation);
164
165 // Set the viewport
166 glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
167
168 GLint pointSizeLocation = glGetUniformLocation(mProgram, "uPointSize");
169 ASSERT_NE(-1, pointSizeLocation);
170
171 glUniform1f(pointSizeLocation, params.size);
172
173 ASSERT_GL_NO_ERROR();
174 }
175
destroyBenchmark()176 void PointSpritesBenchmark::destroyBenchmark()
177 {
178 glDeleteProgram(mProgram);
179 glDeleteBuffers(1, &mBuffer);
180 }
181
drawBenchmark()182 void PointSpritesBenchmark::drawBenchmark()
183 {
184 glClear(GL_COLOR_BUFFER_BIT);
185
186 const auto ¶ms = GetParam();
187
188 for (unsigned int it = 0; it < params.iterationsPerStep; it++)
189 {
190 // TODO(jmadill): Indexed point rendering. ANGLE is bad at this.
191 glDrawArrays(GL_POINTS, 0, params.count);
192 }
193
194 ASSERT_GL_NO_ERROR();
195 }
196
D3D11Params()197 PointSpritesParams D3D11Params()
198 {
199 PointSpritesParams params;
200 params.eglParameters = egl_platform::D3D11();
201 return params;
202 }
203
MetalParams()204 PointSpritesParams MetalParams()
205 {
206 PointSpritesParams params;
207 params.eglParameters = egl_platform::METAL();
208 return params;
209 }
210
OpenGLOrGLESParams()211 PointSpritesParams OpenGLOrGLESParams()
212 {
213 PointSpritesParams params;
214 params.eglParameters = egl_platform::OPENGL_OR_GLES();
215 return params;
216 }
217
VulkanParams()218 PointSpritesParams VulkanParams()
219 {
220 PointSpritesParams params;
221 params.eglParameters = egl_platform::VULKAN();
222 return params;
223 }
224
225 } // namespace
226
TEST_P(PointSpritesBenchmark,Run)227 TEST_P(PointSpritesBenchmark, Run)
228 {
229 run();
230 }
231
232 ANGLE_INSTANTIATE_TEST(PointSpritesBenchmark,
233 D3D11Params(),
234 MetalParams(),
235 OpenGLOrGLESParams(),
236 VulkanParams());
237