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

Side by Side Diff: tools/gpu/gl/GLTestContext.cpp

Issue 2388433003: skpbench: add option for gpu timing (Closed)
Patch Set: Created 4 years, 2 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
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GLTestContext.h" 8 #include "GLTestContext.h"
9 #include "SkGpuTimer.h"
9 #include "gl/GrGLUtil.h" 10 #include "gl/GrGLUtil.h"
11 #include <string>
10 12
11 namespace sk_gpu_test { 13 namespace sk_gpu_test {
14
12 class GLTestContext::GLFenceSync : public SkGpuFenceSync { 15 class GLTestContext::GLFenceSync : public SkGpuFenceSync {
13 public: 16 public:
14 static GLFenceSync* CreateIfSupported(const GLTestContext*); 17 static GLFenceSync* CreateIfSupported(const GLTestContext*);
15 18
16 SkPlatformGpuFence SK_WARN_UNUSED_RESULT insertFence() const override; 19 SkPlatformGpuFence SK_WARN_UNUSED_RESULT insertFence() const override;
17 bool waitFence(SkPlatformGpuFence fence) const override; 20 bool waitFence(SkPlatformGpuFence fence) const override;
18 void deleteFence(SkPlatformGpuFence fence) const override; 21 void deleteFence(SkPlatformGpuFence fence) const override;
19 22
20 private: 23 private:
21 GLFenceSync() {} 24 GLFenceSync() {}
22 25
23 static const GrGLenum GL_SYNC_GPU_COMMANDS_COMPLETE = 0x9117; 26 constexpr static GrGLenum GL_SYNC_GPU_COMMANDS_COMPLETE = 0x9117;
bsalomon 2016/09/30 18:37:16 I believe we more commonly use "static constexpr"
csmartdalton 2016/10/03 16:52:24 Done.
24 static const GrGLenum GL_WAIT_FAILED = 0x911d; 27 constexpr static GrGLenum GL_WAIT_FAILED = 0x911d;
25 static const GrGLbitfield GL_SYNC_FLUSH_COMMANDS_BIT = 0x00000001; 28 constexpr static GrGLbitfield GL_SYNC_FLUSH_COMMANDS_BIT = 0x00000001;
26 29
27 typedef struct __GLsync *GLsync; 30 typedef struct __GLsync *GLsync;
28 31
29 typedef GLsync (GR_GL_FUNCTION_TYPE* GLFenceSyncProc) (GrGLenum, GrGLbitfiel d); 32 typedef GLsync (GR_GL_FUNCTION_TYPE* GLFenceSyncProc) (GrGLenum, GrGLbitfiel d);
30 typedef GrGLenum (GR_GL_FUNCTION_TYPE* GLClientWaitSyncProc) (GLsync, GrGLbi tfield, GrGLuint64); 33 typedef GrGLenum (GR_GL_FUNCTION_TYPE* GLClientWaitSyncProc) (GLsync, GrGLbi tfield, GrGLuint64);
31 typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GLDeleteSyncProc) (GLsync); 34 typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GLDeleteSyncProc) (GLsync);
32 35
33 GLFenceSyncProc fGLFenceSync; 36 GLFenceSyncProc fGLFenceSync;
34 GLClientWaitSyncProc fGLClientWaitSync; 37 GLClientWaitSyncProc fGLClientWaitSync;
35 GLDeleteSyncProc fGLDeleteSync; 38 GLDeleteSyncProc fGLDeleteSync;
36 39
37 typedef SkGpuFenceSync INHERITED; 40 typedef SkGpuFenceSync INHERITED;
38 }; 41 };
39 42
40 GLTestContext::GLTestContext() : TestContext() {}
41
42 GLTestContext::~GLTestContext() {
43 SkASSERT(nullptr == fGL.get());
44 }
45
46 void GLTestContext::init(const GrGLInterface* gl, SkGpuFenceSync* fenceSync) {
47 SkASSERT(!fGL.get());
48 fGL.reset(gl);
49 fFenceSync = fenceSync ? fenceSync : GLFenceSync::CreateIfSupported(this);
50 }
51
52 void GLTestContext::teardown() {
53 fGL.reset(nullptr);
54 INHERITED::teardown();
55 }
56
57 void GLTestContext::testAbandon() {
58 INHERITED::testAbandon();
59 if (fGL) {
60 fGL->abandon();
61 }
62 }
63
64 void GLTestContext::submit() {
65 if (fGL) {
66 GR_GL_CALL(fGL.get(), Flush());
67 }
68 }
69
70 void GLTestContext::finish() {
71 if (fGL) {
72 GR_GL_CALL(fGL.get(), Finish());
73 }
74 }
75
76 GLTestContext::GLFenceSync* GLTestContext::GLFenceSync::CreateIfSupported(const GLTestContext* ctx) { 43 GLTestContext::GLFenceSync* GLTestContext::GLFenceSync::CreateIfSupported(const GLTestContext* ctx) {
77 SkAutoTDelete<GLFenceSync> ret(new GLFenceSync); 44 SkAutoTDelete<GLFenceSync> ret(new GLFenceSync);
78 45
79 if (kGL_GrGLStandard == ctx->gl()->fStandard) { 46 if (kGL_GrGLStandard == ctx->gl()->fStandard) {
80 const GrGLubyte* versionStr; 47 const GrGLubyte* versionStr;
81 GR_GL_CALL_RET(ctx->gl(), versionStr, GetString(GR_GL_VERSION)); 48 GR_GL_CALL_RET(ctx->gl(), versionStr, GetString(GR_GL_VERSION));
82 GrGLVersion version = GrGLGetVersionFromString(reinterpret_cast<const ch ar*>(versionStr)); 49 GrGLVersion version = GrGLGetVersionFromString(reinterpret_cast<const ch ar*>(versionStr));
83 if (version < GR_GL_VER(3,2) && !ctx->gl()->hasExtension("GL_ARB_sync")) { 50 if (version < GR_GL_VER(3,2) && !ctx->gl()->hasExtension("GL_ARB_sync")) {
84 return nullptr; 51 return nullptr;
85 } 52 }
(...skipping 29 matching lines...) Expand all
115 bool GLTestContext::GLFenceSync::waitFence(SkPlatformGpuFence fence) const { 82 bool GLTestContext::GLFenceSync::waitFence(SkPlatformGpuFence fence) const {
116 GLsync glsync = static_cast<GLsync>(fence); 83 GLsync glsync = static_cast<GLsync>(fence);
117 return GL_WAIT_FAILED != fGLClientWaitSync(glsync, GL_SYNC_FLUSH_COMMANDS_BI T, -1); 84 return GL_WAIT_FAILED != fGLClientWaitSync(glsync, GL_SYNC_FLUSH_COMMANDS_BI T, -1);
118 } 85 }
119 86
120 void GLTestContext::GLFenceSync::deleteFence(SkPlatformGpuFence fence) const { 87 void GLTestContext::GLFenceSync::deleteFence(SkPlatformGpuFence fence) const {
121 GLsync glsync = static_cast<GLsync>(fence); 88 GLsync glsync = static_cast<GLsync>(fence);
122 fGLDeleteSync(glsync); 89 fGLDeleteSync(glsync);
123 } 90 }
124 91
92 //////////////////////////////////////////////////////////////////////////////// ////////////////////
93
94 class GLGpuTimer : public SkGpuTimer {
95 public:
96 static GLGpuTimer* CreateIfSupported(const GLTestContext*);
97
98 QueryStatus checkQueryStatus(SkPlatformGpuTimerQuery) override;
99 std::chrono::nanoseconds getTimeElapsed(SkPlatformGpuTimerQuery) override;
100 void deleteQuery(SkPlatformGpuTimerQuery) override;
101
102 private:
103 GLGpuTimer(bool disjointSupport, const GLTestContext*, const char* ext = "") ;
104
105 template<typename Proc> void loadProc(Proc GLGpuTimer::* proc, const GLTestC ontext* ctx,
106 const std::string& name, const std::st ring& ext = "") {
107 const std::string& fullname = name + ext;
108 this->*proc = reinterpret_cast<Proc>(ctx->onPlatformGetProcAddress(fulln ame.c_str()));
109 }
110
111 bool validate() const {
112 return fGLGetIntegerv && fGLGenQueries && fGLDeleteQueries && fGLBeginQu ery && fGLEndQuery
113 && fGLQueryCounter && fGLGetQueryiv && fGLGetQueryObjectiv && fGL GetQueryObjectui64v;
114 }
115
116 SkPlatformGpuTimerQuery onQueueTimerStart() const override;
117 void onQueueTimerStop(SkPlatformGpuTimerQuery) const override;
118
119 constexpr static GrGLenum GL_QUERY_COUNTER_BITS = 0x8864;
120 constexpr static GrGLenum GL_CURRENT_QUERY = 0x8865;
121 constexpr static GrGLenum GL_QUERY_RESULT = 0x8866;
122 constexpr static GrGLenum GL_QUERY_RESULT_AVAILABLE = 0x8867;
123 constexpr static GrGLenum GL_TIME_ELAPSED = 0x88bf;
124 constexpr static GrGLenum GL_TIMESTAMP = 0x8e28;
125 constexpr static GrGLenum GL_GPU_DISJOINT = 0x8fbb;
126
127 typedef void (GR_GL_FUNCTION_TYPE* GLGetIntegervProc) (GrGLenum, GrGLint*);
128 typedef void (GR_GL_FUNCTION_TYPE* GLGenQueriesProc) (GrGLsizei, GrGLuint*);
129 typedef void (GR_GL_FUNCTION_TYPE* GLDeleteQueriesProc) (GrGLsizei, const Gr GLuint*);
130 typedef void (GR_GL_FUNCTION_TYPE* GLBeginQueryProc) (GrGLenum, GrGLuint);
131 typedef void (GR_GL_FUNCTION_TYPE* GLEndQueryProc) (GrGLenum);
132 typedef void (GR_GL_FUNCTION_TYPE* GLQueryCounterProc) (GrGLuint, GrGLenum);
133 typedef void (GR_GL_FUNCTION_TYPE* GLGetQueryivProc) (GrGLenum, GrGLenum, Gr GLint *);
134 typedef void (GR_GL_FUNCTION_TYPE* GLGetQueryObjectivProc) (GrGLuint, GrGLen um, GrGLint*);
135 typedef void (GR_GL_FUNCTION_TYPE* GLGetQueryObjectui64vProc) (GrGLuint, GrG Lenum, GrGLuint64*);
136
137 GLGetIntegervProc fGLGetIntegerv;
138 GLGenQueriesProc fGLGenQueries;
139 GLDeleteQueriesProc fGLDeleteQueries;
140 GLBeginQueryProc fGLBeginQuery;
141 GLEndQueryProc fGLEndQuery;
142 GLQueryCounterProc fGLQueryCounter;
143 GLGetQueryivProc fGLGetQueryiv;
144 GLGetQueryObjectivProc fGLGetQueryObjectiv;
145 GLGetQueryObjectui64vProc fGLGetQueryObjectui64v;
146 };
147
148 GLGpuTimer* GLGpuTimer::CreateIfSupported(const GLTestContext* ctx) {
149 SkAutoTDelete<GLGpuTimer> ret;
150 const GrGLInterface* gl = ctx->gl();
151 if (gl->fExtensions.has("GL_EXT_disjoint_timer_query")) {
152 ret.reset(new GLGpuTimer(true, ctx, "EXT"));
153 } else if (kGL_GrGLStandard == gl->fStandard &&
154 (GrGLGetVersion(gl) > GR_GL_VER(3,3) || gl->fExtensions.has("GL_A RB_timer_query"))) {
155 ret.reset(new GLGpuTimer(false, ctx));
156 } else if (gl->fExtensions.has("GL_EXT_timer_query")) {
157 ret.reset(new GLGpuTimer(false, ctx, "EXT"));
158 }
159 return ret && ret->validate() ? ret.release() : nullptr;
160 }
161
162 GLGpuTimer::GLGpuTimer(bool disjointSupport, const GLTestContext* ctx, const cha r* ext)
163 : SkGpuTimer(disjointSupport) {
164 this->loadProc(&GLGpuTimer::fGLGetIntegerv, ctx, "glGetIntegerv");
165 this->loadProc(&GLGpuTimer::fGLGenQueries, ctx, "glGenQueries", ext);
166 this->loadProc(&GLGpuTimer::fGLDeleteQueries, ctx, "glDeleteQueries", ext);
167 this->loadProc(&GLGpuTimer::fGLBeginQuery, ctx, "glBeginQuery", ext);
168 this->loadProc(&GLGpuTimer::fGLEndQuery, ctx, "glEndQuery", ext);
169 this->loadProc(&GLGpuTimer::fGLQueryCounter, ctx, "glQueryCounter", ext);
170 this->loadProc(&GLGpuTimer::fGLGetQueryiv, ctx, "glGetQueryiv", ext);
171 this->loadProc(&GLGpuTimer::fGLGetQueryObjectiv, ctx, "glGetQueryObjectiv", ext);
172 this->loadProc(&GLGpuTimer::fGLGetQueryObjectui64v, ctx, "glGetQueryObjectui 64v", ext);
173 }
174
175 SkPlatformGpuTimerQuery GLGpuTimer::onQueueTimerStart() const {
176 GrGLuint queryID;
177 fGLGenQueries(1, &queryID);
178 if (!queryID) {
179 return SK_InvalidGpuTimerQuery;
180 }
181 if (this->disjointSupport()) {
182 // Clear the disjoint flag.
183 GrGLint disjoint;
184 fGLGetIntegerv(GL_GPU_DISJOINT, &disjoint);
185 }
186 fGLBeginQuery(GL_TIME_ELAPSED, queryID);
187 return static_cast<SkPlatformGpuTimerQuery>(queryID);
188 }
189
190 void GLGpuTimer::onQueueTimerStop(SkPlatformGpuTimerQuery platformTimer) const {
191 if (SK_InvalidGpuTimerQuery == platformTimer) {
192 return;
193 }
194 fGLEndQuery(GL_TIME_ELAPSED);
195 }
196
197 SkGpuTimer::QueryStatus GLGpuTimer::checkQueryStatus(SkPlatformGpuTimerQuery pla tformTimer) {
198 const GrGLuint queryID = static_cast<GrGLuint>(platformTimer);
199 if (!queryID) {
200 return QueryStatus::kInvalid;
201 }
202
203 // Check if the timer has completed. We should really use the 32-bit version of glGetQueryObject
204 // here, but it doesn't seem to work on Pixel C.
205 GrGLuint64 available = 0;
206 fGLGetQueryObjectui64v(queryID, GL_QUERY_RESULT_AVAILABLE, &available);
207 if (!available) {
208 return QueryStatus::kPending;
209 }
210
211 if (this->disjointSupport()) {
212 GrGLint disjoint = 1;
213 fGLGetIntegerv(GL_GPU_DISJOINT, &disjoint);
214 if (disjoint) {
215 return QueryStatus::kDisjoint;
216 }
217 }
218
219 return QueryStatus::kAccurate;
220 }
221
222 std::chrono::nanoseconds GLGpuTimer::getTimeElapsed(SkPlatformGpuTimerQuery plat formTimer) {
223 SkASSERT(this->checkQueryStatus(platformTimer) >= QueryStatus::kDisjoint);
224 const GrGLuint queryID = static_cast<GrGLuint>(platformTimer);
225 GrGLuint64 nanoseconds;
226 fGLGetQueryObjectui64v(queryID, GL_QUERY_RESULT, &nanoseconds);
227 return std::chrono::nanoseconds(nanoseconds);
228 }
229
230 void GLGpuTimer::deleteQuery(SkPlatformGpuTimerQuery platformTimer) {
231 const GrGLuint queryID = static_cast<GrGLuint>(platformTimer);
232 fGLDeleteQueries(1, &queryID);
233 }
234
235 //////////////////////////////////////////////////////////////////////////////// ////////////////////
236
237 GLTestContext::GLTestContext() : TestContext() {}
238
239 GLTestContext::~GLTestContext() {
240 SkASSERT(nullptr == fGL.get());
241 }
242
243 void GLTestContext::init(const GrGLInterface* gl, SkGpuFenceSync* fenceSync) {
244 SkASSERT(!fGL.get());
245 fGL.reset(gl);
246 fFenceSync = fenceSync ? fenceSync : GLFenceSync::CreateIfSupported(this);
247 fGpuTimer = GLGpuTimer::CreateIfSupported(this);
248 }
249
250 void GLTestContext::teardown() {
251 fGL.reset(nullptr);
252 INHERITED::teardown();
253 }
254
255 void GLTestContext::testAbandon() {
256 INHERITED::testAbandon();
257 if (fGL) {
258 fGL->abandon();
259 }
260 }
261
262 void GLTestContext::submit() {
263 if (fGL) {
264 GR_GL_CALL(fGL.get(), Flush());
265 }
266 }
267
268 void GLTestContext::finish() {
269 if (fGL) {
270 GR_GL_CALL(fGL.get(), Finish());
271 }
272 }
273
125 GrGLint GLTestContext::createTextureRectangle(int width, int height, GrGLenum in ternalFormat, 274 GrGLint GLTestContext::createTextureRectangle(int width, int height, GrGLenum in ternalFormat,
126 GrGLenum externalFormat, GrGLenum exte rnalType, 275 GrGLenum externalFormat, GrGLenum exte rnalType,
127 GrGLvoid* data) { 276 GrGLvoid* data) {
128 if (!(kGL_GrGLStandard == fGL->fStandard && GrGLGetVersion(fGL) >= GR_GL_VER (3, 1)) && 277 if (!(kGL_GrGLStandard == fGL->fStandard && GrGLGetVersion(fGL) >= GR_GL_VER (3, 1)) &&
129 !fGL->fExtensions.has("GL_ARB_texture_rectangle")) { 278 !fGL->fExtensions.has("GL_ARB_texture_rectangle")) {
130 return 0; 279 return 0;
131 } 280 }
132 281
133 if (GrGLGetGLSLVersion(fGL) < GR_GLSL_VER(1, 40)) { 282 if (GrGLGetGLSLVersion(fGL) < GR_GLSL_VER(1, 40)) {
134 return 0; 283 return 0;
135 } 284 }
136 285
137 GrGLuint id; 286 GrGLuint id;
138 GR_GL_CALL(fGL, GenTextures(1, &id)); 287 GR_GL_CALL(fGL, GenTextures(1, &id));
139 GR_GL_CALL(fGL, BindTexture(GR_GL_TEXTURE_RECTANGLE, id)); 288 GR_GL_CALL(fGL, BindTexture(GR_GL_TEXTURE_RECTANGLE, id));
140 GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_MAG_FIL TER, 289 GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_MAG_FIL TER,
141 GR_GL_NEAREST)); 290 GR_GL_NEAREST));
142 GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_MIN_FIL TER, 291 GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_MIN_FIL TER,
143 GR_GL_NEAREST)); 292 GR_GL_NEAREST));
144 GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_S, 293 GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_S,
145 GR_GL_CLAMP_TO_EDGE)); 294 GR_GL_CLAMP_TO_EDGE));
146 GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_T, 295 GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_T,
147 GR_GL_CLAMP_TO_EDGE)); 296 GR_GL_CLAMP_TO_EDGE));
148 GR_GL_CALL(fGL, TexImage2D(GR_GL_TEXTURE_RECTANGLE, 0, internalFormat, width , height, 0, 297 GR_GL_CALL(fGL, TexImage2D(GR_GL_TEXTURE_RECTANGLE, 0, internalFormat, width , height, 0,
149 externalFormat, externalType, data)); 298 externalFormat, externalType, data));
150 return id; 299 return id;
151 } 300 }
301
152 } // namespace sk_gpu_test 302 } // namespace sk_gpu_test
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698