Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(200)

Side by Side Diff: bench/GLVec4ScalarBench.cpp

Issue 1225383002: Added a GLBench for testing performance of vec4 vs scalar for coverage in generated shaders. (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "Benchmark.h"
9 #include "SkCanvas.h"
10 #include "SkImageEncoder.h"
tomhudson 2015/07/10 19:23:54 You don't seem to need any of these 3 includes any
wangyix 2015/07/13 17:29:52 Done.
11
12 #if SK_SUPPORT_GPU
13 #include "GLBench.h"
14 #include "gl/GrGLGLSL.h"
15 #include "gl/GrGLInterface.h"
16 #include "gl/GrGLShaderVar.h"
17 #include "gl/GrGLUtil.h"
18 #include "glsl/GrGLSLCaps.h"
19
20 #include <stdio.h>
21
22 /*
tomhudson 2015/07/10 19:23:54 Please make this /** so doxygen can pick it up. Al
wangyix 2015/07/13 17:29:53 Done.
23 * This is a native GL benchmark for instanced arrays vs vertex buffer objects. To benchmark this
24 * functionality, we draw n * kDrawMultipier triangles per run. If this number is less than
25 * kNumTri then we do a single draw, either with instances, or drawArrays. Othe rwise we do
26 * multiple draws.
27 *
28 * Additionally, there is a divisor, which if > 0 will act as a multiplier for t he number of draws
29 * issued.
30 */
31
32 class GLVec4ScalarBench : public GLBench {
33 public:
34 /*
35 * Use float or vec4 as GLSL data type for the output coverage
36 */
37 enum CoverageSetup {
38 kUseScalar_CoverageSetup,
39 kUseVec4_CoverageSetup,
40 };
41
42 /*
43 * drawDiv will act as a multiplier for the number of draws we issue if > 0. ie, 2 will issue
44 * 2x as many draws, 4 will issue 4x as many draws etc. There is a limit ho wever, which is
45 * kDrawMultipier.
tomhudson 2015/07/10 19:23:54 Outdated comment; cut. If the class comment is goo
wangyix 2015/07/13 17:29:52 Done.
46 */
47 GLVec4ScalarBench(CoverageSetup coverageSetup, uint32_t numStages)
48 : fCoverageSetup(coverageSetup)
49 , fNumStages(numStages)
50 , fProgram(0)
51 , fVAO(0) {
tomhudson 2015/07/10 19:23:55 Why explicitly clear fVAO but not fVBO?
wangyix 2015/07/13 17:29:53 Done.
52 fName = CoverageSetupToStr(coverageSetup, numStages);
53 }
54
55 protected:
56 const char* onGetName() override {
57 return fName.c_str();
58 }
59
60 const GrGLContext* onGetGLContext(const GrGLContext*) override;
tomhudson 2015/07/13 16:00:13 Once we've started reviewing, it's good for the re
wangyix 2015/07/13 17:29:52 Yep that was the reason. The override was specific
61 void setup(const GrGLContext*) override;
62 void glDraw(const int loops, const GrGLContext*) override;
63 void teardown(const GrGLInterface*) override;
64
65 private:
66 void setupSingleVbo(const GrGLInterface*, const SkMatrix*);
67 GrGLuint setupShader(const GrGLContext*, bool useVec4ForCoverage);
68
69
70 static SkString CoverageSetupToStr(CoverageSetup vboSetup, uint32_t numStage s) {
tomhudson 2015/07/10 19:23:55 Consider tweaking the function name, since you're
wangyix 2015/07/13 17:29:52 Done.
71 SkString name("GLVec4ScalarBench");
72 switch (vboSetup) {
73 default:
74 case kUseScalar_CoverageSetup:
75 name.appendf("_scalar_%u_stage", numStages);
76 break;
77 case kUseVec4_CoverageSetup:
78 name.appendf("_vec4_%u_stage", numStages);
79 break;
80 }
81 return name;
82 }
83
84 static const GrGLuint kScreenWidth = 800;
85 static const GrGLuint kScreenHeight = 600;
86 static const uint32_t kNumTriPerDraw = 512;
87 static const uint32_t kVerticesPerTri = 3;
88
89 SkString fName;
90 CoverageSetup fCoverageSetup;
91 uint32_t fNumStages;
92 GrGLuint fVBO;
tomhudson 2015/07/10 19:23:54 Consider writing out name instead of using abbrevi
wangyix 2015/07/13 17:29:52 Vao and Vbo are extremely common occurrences in Op
93 GrGLuint fProgram;
94 GrGLuint fVAO;
tomhudson 2015/07/10 19:23:55 ... particularly when two abbreviations are very c
wangyix 2015/07/13 17:29:52 Done.
95 GrGLuint fTexture;
tomhudson 2015/07/10 19:23:55 It makes the name a bit long, but you might want t
wangyix 2015/07/13 17:29:52 Done.
96 };
97
98 //////////////////////////////////////////////////////////////////////////////// ///////////////////
99
100 GrGLuint GLVec4ScalarBench::setupShader(const GrGLContext* ctx, bool useVec4ForC overage) {
tomhudson 2015/07/10 19:23:55 Instead of passing the bool here, pass the enum! T
wangyix 2015/07/13 17:29:52 Done.
101 const char* version = GrGLGetGLSLVersionDecl(*ctx);
102
103 // setup vertex shader
tomhudson 2015/07/10 19:23:54 I'd like to see a "// This shader draws 4 overlapp
wangyix 2015/07/13 17:29:53 Done.
104 GrGLShaderVar aPosition("a_position", kVec2f_GrSLType, GrShaderVar::kAttribu te_TypeModifier);
105 GrGLShaderVar oPosition("o_position", kVec2f_GrSLType, GrShaderVar::kVarying Out_TypeModifier);
106 GrGLShaderVar aColor("a_color", kVec3f_GrSLType, GrShaderVar::kAttribute_Typ eModifier);
107 GrGLShaderVar oColor("o_color", kVec3f_GrSLType, GrShaderVar::kVaryingOut_Ty peModifier);
108
109 SkString vshaderTxt(version);
110 aPosition.appendDecl(*ctx, &vshaderTxt);
111 vshaderTxt.append(";\n");
112 aColor.appendDecl(*ctx, &vshaderTxt);
113 vshaderTxt.append(";\n");
114 oPosition.appendDecl(*ctx, &vshaderTxt);
115 vshaderTxt.append(";\n");
116 oColor.appendDecl(*ctx, &vshaderTxt);
117 vshaderTxt.append(";\n");
118
119 vshaderTxt.append(
120 "void main()\n"
121 "{\n"
122 " gl_Position = vec4(a_position, 0.f, 1.f);\n"
123 " o_position = a_position;\n"
124 " o_color = a_color;\n"
125 "}\n");
126
127 const GrGLInterface* gl = ctx->interface();
128
129 // setup fragment shader
130 GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_T ypeModifier);
131 SkString fshaderTxt(version);
132 GrGLAppendGLSLDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, gl->f Standard,
133 &fshaderTxt);
134 oPosition.setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier);
135 oPosition.appendDecl(*ctx, &fshaderTxt);
136 fshaderTxt.append(";\n");
137 oColor.setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier);
138 oColor.appendDecl(*ctx, &fshaderTxt);
139 fshaderTxt.append(";\n");
140
141 const char* fsOutName;
142 if (ctx->caps()->glslCaps()->mustDeclareFragmentShaderOutput()) {
143 oFragColor.appendDecl(*ctx, &fshaderTxt);
144 fshaderTxt.append(";\n");
145 fsOutName = oFragColor.c_str();
146 } else {
147 fsOutName = "gl_FragColor";
148 }
149
150 if (useVec4ForCoverage) {
151 fshaderTxt.appendf(
152 "void main()\n"
153 "{\n"
154 " vec4 outputColor;\n"
155 " vec4 outputCoverage;\n"
156 " outputColor = vec4(%s, 1.0);\n"
157 " outputCoverage = vec4(1.0);\n",
158 oColor.getName().c_str());
159 } else {
160 fshaderTxt.appendf(
161 "void main()\n"
162 "{\n"
163 " vec4 outputColor;\n"
164 " float outputCoverage;\n"
165 " outputColor = vec4(%s, 1.0);\n"
166 " outputCoverage = 1.0;\n",
167 oColor.getName().c_str());
168 }
169 float radius = 1.0f;
170 for (uint32_t i = 0; i < fNumStages; i++) {
tomhudson 2015/07/10 19:23:54 Why pass in fConverageSetup (or a bool derived fro
wangyix 2015/07/13 17:29:52 Done.
171 float centerX = 1.0f - radius;
172 float centerY = 1.0f - radius;
173 if (useVec4ForCoverage) {
174 fshaderTxt.appendf(
175 " {\n"
176 " float d = length(%s - vec2(%f, %f));\n"
177 " float edgeAlpha = clamp(100.0 * (%f - d), 0.0, 1.0);\n"
178 " outputCoverage = 0.5 * outputCoverage + 0.5 * vec4(edge Alpha);\n"
179 " }\n",
180 oPosition.getName().c_str(),
181 centerX, centerY,
182 radius
183 );
184 } else {
185 fshaderTxt.appendf(
186 " {\n"
187 " float d = length(%s - vec2(%f, %f));\n"
188 " float edgeAlpha = clamp(100.0 * (%f - d), 0.0, 1.0);\n"
189 " outputCoverage = 0.5 * outputCoverage + 0.5 * edgeAlpha ;\n"
190 " }\n",
191 oPosition.getName().c_str(),
192 centerX, centerY,
193 radius
194 );
195 }
196 radius *= 0.8f;
197 }
198 fshaderTxt.appendf(
199 " {\n"
200 " %s = outputColor * outputCoverage;\n"
201 " }\n"
202 "}\n",
203 fsOutName);
204
205 //printf("\n%s\n", fshaderTxt.c_str());
tomhudson 2015/07/10 19:23:55 Remove commented-out code.
wangyix 2015/07/13 17:29:53 Done.
206
207 return CreateProgram(gl, vshaderTxt.c_str(), fshaderTxt.c_str());
208 }
209
210 template<typename Func>
211 static void setup_matrices(int numQuads, Func f) {
212 // We draw a really small triangle so we are not fill rate limited
213 for (int i = 0 ; i < numQuads; i++) {
214 SkMatrix m = SkMatrix::I();
215 m.setScale(0.01f, 0.01f);
216 f(m);
217 }
218 }
219
220 //////////////////////////////////////////////////////////////////////////////// ///////////////////
221
222 const GrGLContext* GLVec4ScalarBench::onGetGLContext(const GrGLContext* ctx) {
223 // We only care about gpus with drawArraysInstanced support
224 if (!ctx->interface()->fFunctions.fDrawArraysInstanced) {
225 return NULL;
226 }
227 return ctx;
228 }
229
230 struct Vertex {
231 SkPoint fPositions;
232 GrGLfloat fColors[3];
233 };
234
235 void GLVec4ScalarBench::setupSingleVbo(const GrGLInterface* gl,
236 const SkMatrix* viewMatrices) {
tomhudson 2015/07/10 19:23:54 Nit: fix indentation
wangyix 2015/07/13 17:29:53 Done.
237 // Constants for our various shader programs
tomhudson 2015/07/10 19:23:55 This comment is not very high-value. Omit?
wangyix 2015/07/13 17:29:52 Done.
238 Vertex vertices[kVerticesPerTri * kNumTriPerDraw];
239 for (uint32_t i = 0; i < kNumTriPerDraw; i++) {
240 Vertex* v = &vertices[i * kVerticesPerTri];
241 if (i % 2 == 0) {
242 v[0].fPositions.set(-1.0f, -1.0f);
243 v[1].fPositions.set( 1.0f, -1.0f);
244 v[2].fPositions.set( 1.0f, 1.0f);
245 } else {
246 v[0].fPositions.set(-1.0f, -1.0f);
247 v[1].fPositions.set( 1.0f, 1.0f);
248 v[2].fPositions.set( -1.0f, 1.0f);
249 }
250 SkPoint* position = reinterpret_cast<SkPoint*>(v);
251 viewMatrices[i].mapPointsWithStride(position, sizeof(Vertex), kVerticesP erTri);
252
253 // set colors
tomhudson 2015/07/10 19:23:55 Bad evil comment. Expurgate!
wangyix 2015/07/13 17:29:53 Done.
254 GrGLfloat color[3] = {1.0f, 0.0f, 1.0f};
255 for (uint32_t j = 0; j < kVerticesPerTri; j++) {
256 v->fColors[0] = color[0];
257 v->fColors[1] = color[1];
258 v->fColors[2] = color[2];
259 v++;
260 }
261 }
262
263 // setup VBO
tomhudson 2015/07/10 19:23:54 Low-value comment. What is it? Or why are we doing
wangyix 2015/07/13 17:29:53 Done.
264 GR_GL_CALL(gl, GenBuffers(1, &fVBO));
265 GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, fVBO));
266 GR_GL_CALL(gl, EnableVertexAttribArray(0));
267 GR_GL_CALL(gl, EnableVertexAttribArray(1));
268 GR_GL_CALL(gl, VertexAttribPointer(0, 2, GR_GL_FLOAT, GR_GL_FALSE, sizeof(Ve rtex),
269 (GrGLvoid*)0));
270 GR_GL_CALL(gl, VertexAttribPointer(1, 3, GR_GL_FLOAT, GR_GL_FALSE, sizeof(Ve rtex),
271 (GrGLvoid*)(sizeof(SkPoint))));
272 GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(vertices), vertices, GR _GL_STATIC_DRAW));
273 }
274
275 void GLVec4ScalarBench::setup(const GrGLContext* ctx) {
276 const GrGLInterface* gl = ctx->interface();
277 fTexture = SetupFramebuffer(gl, kScreenWidth, kScreenHeight);
278
279 fProgram = this->setupShader(ctx, fCoverageSetup == kUseVec4_CoverageSetup);
280
281 // setup matrices
tomhudson 2015/07/10 19:23:55 Useless comment. What matrices? Why? Or eliminate!
wangyix 2015/07/13 17:29:52 Done.
282 int index = 0;
283 SkMatrix viewMatrices[kNumTriPerDraw];
284 setup_matrices(kNumTriPerDraw, [&index, &viewMatrices](const SkMatrix& m) {
285 viewMatrices[index++] = m;
286 });
287
288 // setup VAO
289 GR_GL_CALL(gl, GenVertexArrays(1, &fVAO));
290 GR_GL_CALL(gl, BindVertexArray(fVAO));
291
292 this->setupSingleVbo(gl, viewMatrices);
293
294 // set us up to draw
295 GR_GL_CALL(gl, UseProgram(fProgram));
296 GR_GL_CALL(gl, BindVertexArray(fVAO));
297 }
298
299 void GLVec4ScalarBench::glDraw(const int loops, const GrGLContext* ctx) {
300 const GrGLInterface* gl = ctx->interface();
301
302 for (int i = 0; i < loops; i++) {
303 GR_GL_CALL(gl, DrawArrays(GR_GL_TRIANGLES, 0, kVerticesPerTri * kNumTriP erDraw));
304 }
305
306
307 #if 0
308 //const char* filename = "/data/local/tmp/out.png";
tomhudson 2015/07/10 19:23:55 Delete commented-out code. In theory you could pro
tomhudson 2015/07/13 16:00:13 Again: How is your #0 different than the command-l
wangyix 2015/07/13 17:29:53 Using -w when running nanobench does not write out
309 SkString filename("out");
310 filename.appendf("_%s.png", this->getName());
311 DumpImage(gl, kScreenWidth, kScreenHeight, filename.c_str());
312 #endif
313 }
314
315 void GLVec4ScalarBench::teardown(const GrGLInterface* gl) {
316 GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, 0));
317 GR_GL_CALL(gl, BindVertexArray(0));
318 GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0));
319 GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, 0));
320 GR_GL_CALL(gl, DeleteTextures(1, &fTexture));
321 GR_GL_CALL(gl, DeleteProgram(fProgram));
322 GR_GL_CALL(gl, DeleteBuffers(1, &fVBO));
323 GR_GL_CALL(gl, DeleteVertexArrays(1, &fVAO));
324 }
325
326 ///////////////////////////////////////////////////////////////////////////////
327
328 DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseScalar_CoverageSe tup, 1) )
329 DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseVec4_CoverageSetu p, 1) )
330 DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseScalar_CoverageSe tup, 2) )
331 DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseVec4_CoverageSetu p, 2) )
332 DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseScalar_CoverageSe tup, 4) )
333 DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseVec4_CoverageSetu p, 4) )
334 DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseScalar_CoverageSe tup, 6) )
335 DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseVec4_CoverageSetu p, 6) )
336 DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseScalar_CoverageSe tup, 8) )
337 DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseVec4_CoverageSetu p, 8) )
338
339 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698