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

Unified Diff: tools/gpu/gl/GLTestContext.cpp

Issue 2388433003: skpbench: add option for gpu timing (Closed)
Patch Set: Created 4 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: tools/gpu/gl/GLTestContext.cpp
diff --git a/tools/gpu/gl/GLTestContext.cpp b/tools/gpu/gl/GLTestContext.cpp
index 68980922cdc4c986ef1c3fae325a2ec6dfd9a8bf..c42de1f915b28c2b4496ba348fa4a9ef2e594814 100644
--- a/tools/gpu/gl/GLTestContext.cpp
+++ b/tools/gpu/gl/GLTestContext.cpp
@@ -6,9 +6,12 @@
*/
#include "GLTestContext.h"
+#include "SkGpuTimer.h"
#include "gl/GrGLUtil.h"
+#include <string>
namespace sk_gpu_test {
+
class GLTestContext::GLFenceSync : public SkGpuFenceSync {
public:
static GLFenceSync* CreateIfSupported(const GLTestContext*);
@@ -20,9 +23,9 @@ public:
private:
GLFenceSync() {}
- static const GrGLenum GL_SYNC_GPU_COMMANDS_COMPLETE = 0x9117;
- static const GrGLenum GL_WAIT_FAILED = 0x911d;
- static const GrGLbitfield GL_SYNC_FLUSH_COMMANDS_BIT = 0x00000001;
+ 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.
+ constexpr static GrGLenum GL_WAIT_FAILED = 0x911d;
+ constexpr static GrGLbitfield GL_SYNC_FLUSH_COMMANDS_BIT = 0x00000001;
typedef struct __GLsync *GLsync;
@@ -37,42 +40,6 @@ private:
typedef SkGpuFenceSync INHERITED;
};
-GLTestContext::GLTestContext() : TestContext() {}
-
-GLTestContext::~GLTestContext() {
- SkASSERT(nullptr == fGL.get());
-}
-
-void GLTestContext::init(const GrGLInterface* gl, SkGpuFenceSync* fenceSync) {
- SkASSERT(!fGL.get());
- fGL.reset(gl);
- fFenceSync = fenceSync ? fenceSync : GLFenceSync::CreateIfSupported(this);
-}
-
-void GLTestContext::teardown() {
- fGL.reset(nullptr);
- INHERITED::teardown();
-}
-
-void GLTestContext::testAbandon() {
- INHERITED::testAbandon();
- if (fGL) {
- fGL->abandon();
- }
-}
-
-void GLTestContext::submit() {
- if (fGL) {
- GR_GL_CALL(fGL.get(), Flush());
- }
-}
-
-void GLTestContext::finish() {
- if (fGL) {
- GR_GL_CALL(fGL.get(), Finish());
- }
-}
-
GLTestContext::GLFenceSync* GLTestContext::GLFenceSync::CreateIfSupported(const GLTestContext* ctx) {
SkAutoTDelete<GLFenceSync> ret(new GLFenceSync);
@@ -122,6 +89,188 @@ void GLTestContext::GLFenceSync::deleteFence(SkPlatformGpuFence fence) const {
fGLDeleteSync(glsync);
}
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class GLGpuTimer : public SkGpuTimer {
+public:
+ static GLGpuTimer* CreateIfSupported(const GLTestContext*);
+
+ QueryStatus checkQueryStatus(SkPlatformGpuTimerQuery) override;
+ std::chrono::nanoseconds getTimeElapsed(SkPlatformGpuTimerQuery) override;
+ void deleteQuery(SkPlatformGpuTimerQuery) override;
+
+private:
+ GLGpuTimer(bool disjointSupport, const GLTestContext*, const char* ext = "");
+
+ template<typename Proc> void loadProc(Proc GLGpuTimer::* proc, const GLTestContext* ctx,
+ const std::string& name, const std::string& ext = "") {
+ const std::string& fullname = name + ext;
+ this->*proc = reinterpret_cast<Proc>(ctx->onPlatformGetProcAddress(fullname.c_str()));
+ }
+
+ bool validate() const {
+ return fGLGetIntegerv && fGLGenQueries && fGLDeleteQueries && fGLBeginQuery && fGLEndQuery
+ && fGLQueryCounter && fGLGetQueryiv && fGLGetQueryObjectiv && fGLGetQueryObjectui64v;
+ }
+
+ SkPlatformGpuTimerQuery onQueueTimerStart() const override;
+ void onQueueTimerStop(SkPlatformGpuTimerQuery) const override;
+
+ constexpr static GrGLenum GL_QUERY_COUNTER_BITS = 0x8864;
+ constexpr static GrGLenum GL_CURRENT_QUERY = 0x8865;
+ constexpr static GrGLenum GL_QUERY_RESULT = 0x8866;
+ constexpr static GrGLenum GL_QUERY_RESULT_AVAILABLE = 0x8867;
+ constexpr static GrGLenum GL_TIME_ELAPSED = 0x88bf;
+ constexpr static GrGLenum GL_TIMESTAMP = 0x8e28;
+ constexpr static GrGLenum GL_GPU_DISJOINT = 0x8fbb;
+
+ typedef void (GR_GL_FUNCTION_TYPE* GLGetIntegervProc) (GrGLenum, GrGLint*);
+ typedef void (GR_GL_FUNCTION_TYPE* GLGenQueriesProc) (GrGLsizei, GrGLuint*);
+ typedef void (GR_GL_FUNCTION_TYPE* GLDeleteQueriesProc) (GrGLsizei, const GrGLuint*);
+ typedef void (GR_GL_FUNCTION_TYPE* GLBeginQueryProc) (GrGLenum, GrGLuint);
+ typedef void (GR_GL_FUNCTION_TYPE* GLEndQueryProc) (GrGLenum);
+ typedef void (GR_GL_FUNCTION_TYPE* GLQueryCounterProc) (GrGLuint, GrGLenum);
+ typedef void (GR_GL_FUNCTION_TYPE* GLGetQueryivProc) (GrGLenum, GrGLenum, GrGLint *);
+ typedef void (GR_GL_FUNCTION_TYPE* GLGetQueryObjectivProc) (GrGLuint, GrGLenum, GrGLint*);
+ typedef void (GR_GL_FUNCTION_TYPE* GLGetQueryObjectui64vProc) (GrGLuint, GrGLenum, GrGLuint64*);
+
+ GLGetIntegervProc fGLGetIntegerv;
+ GLGenQueriesProc fGLGenQueries;
+ GLDeleteQueriesProc fGLDeleteQueries;
+ GLBeginQueryProc fGLBeginQuery;
+ GLEndQueryProc fGLEndQuery;
+ GLQueryCounterProc fGLQueryCounter;
+ GLGetQueryivProc fGLGetQueryiv;
+ GLGetQueryObjectivProc fGLGetQueryObjectiv;
+ GLGetQueryObjectui64vProc fGLGetQueryObjectui64v;
+};
+
+GLGpuTimer* GLGpuTimer::CreateIfSupported(const GLTestContext* ctx) {
+ SkAutoTDelete<GLGpuTimer> ret;
+ const GrGLInterface* gl = ctx->gl();
+ if (gl->fExtensions.has("GL_EXT_disjoint_timer_query")) {
+ ret.reset(new GLGpuTimer(true, ctx, "EXT"));
+ } else if (kGL_GrGLStandard == gl->fStandard &&
+ (GrGLGetVersion(gl) > GR_GL_VER(3,3) || gl->fExtensions.has("GL_ARB_timer_query"))) {
+ ret.reset(new GLGpuTimer(false, ctx));
+ } else if (gl->fExtensions.has("GL_EXT_timer_query")) {
+ ret.reset(new GLGpuTimer(false, ctx, "EXT"));
+ }
+ return ret && ret->validate() ? ret.release() : nullptr;
+}
+
+GLGpuTimer::GLGpuTimer(bool disjointSupport, const GLTestContext* ctx, const char* ext)
+ : SkGpuTimer(disjointSupport) {
+ this->loadProc(&GLGpuTimer::fGLGetIntegerv, ctx, "glGetIntegerv");
+ this->loadProc(&GLGpuTimer::fGLGenQueries, ctx, "glGenQueries", ext);
+ this->loadProc(&GLGpuTimer::fGLDeleteQueries, ctx, "glDeleteQueries", ext);
+ this->loadProc(&GLGpuTimer::fGLBeginQuery, ctx, "glBeginQuery", ext);
+ this->loadProc(&GLGpuTimer::fGLEndQuery, ctx, "glEndQuery", ext);
+ this->loadProc(&GLGpuTimer::fGLQueryCounter, ctx, "glQueryCounter", ext);
+ this->loadProc(&GLGpuTimer::fGLGetQueryiv, ctx, "glGetQueryiv", ext);
+ this->loadProc(&GLGpuTimer::fGLGetQueryObjectiv, ctx, "glGetQueryObjectiv", ext);
+ this->loadProc(&GLGpuTimer::fGLGetQueryObjectui64v, ctx, "glGetQueryObjectui64v", ext);
+}
+
+SkPlatformGpuTimerQuery GLGpuTimer::onQueueTimerStart() const {
+ GrGLuint queryID;
+ fGLGenQueries(1, &queryID);
+ if (!queryID) {
+ return SK_InvalidGpuTimerQuery;
+ }
+ if (this->disjointSupport()) {
+ // Clear the disjoint flag.
+ GrGLint disjoint;
+ fGLGetIntegerv(GL_GPU_DISJOINT, &disjoint);
+ }
+ fGLBeginQuery(GL_TIME_ELAPSED, queryID);
+ return static_cast<SkPlatformGpuTimerQuery>(queryID);
+}
+
+void GLGpuTimer::onQueueTimerStop(SkPlatformGpuTimerQuery platformTimer) const {
+ if (SK_InvalidGpuTimerQuery == platformTimer) {
+ return;
+ }
+ fGLEndQuery(GL_TIME_ELAPSED);
+}
+
+SkGpuTimer::QueryStatus GLGpuTimer::checkQueryStatus(SkPlatformGpuTimerQuery platformTimer) {
+ const GrGLuint queryID = static_cast<GrGLuint>(platformTimer);
+ if (!queryID) {
+ return QueryStatus::kInvalid;
+ }
+
+ // Check if the timer has completed. We should really use the 32-bit version of glGetQueryObject
+ // here, but it doesn't seem to work on Pixel C.
+ GrGLuint64 available = 0;
+ fGLGetQueryObjectui64v(queryID, GL_QUERY_RESULT_AVAILABLE, &available);
+ if (!available) {
+ return QueryStatus::kPending;
+ }
+
+ if (this->disjointSupport()) {
+ GrGLint disjoint = 1;
+ fGLGetIntegerv(GL_GPU_DISJOINT, &disjoint);
+ if (disjoint) {
+ return QueryStatus::kDisjoint;
+ }
+ }
+
+ return QueryStatus::kAccurate;
+}
+
+std::chrono::nanoseconds GLGpuTimer::getTimeElapsed(SkPlatformGpuTimerQuery platformTimer) {
+ SkASSERT(this->checkQueryStatus(platformTimer) >= QueryStatus::kDisjoint);
+ const GrGLuint queryID = static_cast<GrGLuint>(platformTimer);
+ GrGLuint64 nanoseconds;
+ fGLGetQueryObjectui64v(queryID, GL_QUERY_RESULT, &nanoseconds);
+ return std::chrono::nanoseconds(nanoseconds);
+}
+
+void GLGpuTimer::deleteQuery(SkPlatformGpuTimerQuery platformTimer) {
+ const GrGLuint queryID = static_cast<GrGLuint>(platformTimer);
+ fGLDeleteQueries(1, &queryID);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+GLTestContext::GLTestContext() : TestContext() {}
+
+GLTestContext::~GLTestContext() {
+ SkASSERT(nullptr == fGL.get());
+}
+
+void GLTestContext::init(const GrGLInterface* gl, SkGpuFenceSync* fenceSync) {
+ SkASSERT(!fGL.get());
+ fGL.reset(gl);
+ fFenceSync = fenceSync ? fenceSync : GLFenceSync::CreateIfSupported(this);
+ fGpuTimer = GLGpuTimer::CreateIfSupported(this);
+}
+
+void GLTestContext::teardown() {
+ fGL.reset(nullptr);
+ INHERITED::teardown();
+}
+
+void GLTestContext::testAbandon() {
+ INHERITED::testAbandon();
+ if (fGL) {
+ fGL->abandon();
+ }
+}
+
+void GLTestContext::submit() {
+ if (fGL) {
+ GR_GL_CALL(fGL.get(), Flush());
+ }
+}
+
+void GLTestContext::finish() {
+ if (fGL) {
+ GR_GL_CALL(fGL.get(), Finish());
+ }
+}
+
GrGLint GLTestContext::createTextureRectangle(int width, int height, GrGLenum internalFormat,
GrGLenum externalFormat, GrGLenum externalType,
GrGLvoid* data) {
@@ -149,4 +298,5 @@ GrGLint GLTestContext::createTextureRectangle(int width, int height, GrGLenum in
externalFormat, externalType, data));
return id;
}
+
} // namespace sk_gpu_test

Powered by Google App Engine
This is Rietveld 408576698