diff options
author | csmartdalton <csmartdalton@google.com> | 2016-10-05 08:42:03 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-10-05 08:42:03 -0700 |
commit | c6618dd1dadeac8b47b81fbee108c42cca8ab166 (patch) | |
tree | 749fdc785cffc5639d0b6d1ba375d6b9904aae83 /tools/gpu/gl | |
parent | a86952a5ef9e757832a016506709ce4827b059ec (diff) |
skpbench: add option for gpu timing
Adds a gpu timing option with a GL implementation.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2388433003
Committed: https://skia.googlesource.com/skia/+/c06720d06faab3b01eba1b8693e0ac791f06dc96
Review-Url: https://codereview.chromium.org/2388433003
Diffstat (limited to 'tools/gpu/gl')
-rw-r--r-- | tools/gpu/gl/GLTestContext.cpp | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/tools/gpu/gl/GLTestContext.cpp b/tools/gpu/gl/GLTestContext.cpp index 1b077d5a02..20a9908381 100644 --- a/tools/gpu/gl/GLTestContext.cpp +++ b/tools/gpu/gl/GLTestContext.cpp @@ -6,6 +6,8 @@ */ #include "GLTestContext.h" + +#include "GpuTimer.h" #include "gl/GrGLUtil.h" namespace { @@ -78,6 +80,135 @@ void GLFenceSync::deleteFence(sk_gpu_test::PlatformFence fence) const { fGLDeleteSync(glsync); } +class GLGpuTimer : public sk_gpu_test::GpuTimer { +public: + static GLGpuTimer* CreateIfSupported(const sk_gpu_test::GLTestContext*); + + QueryStatus checkQueryStatus(sk_gpu_test::PlatformTimerQuery) override; + std::chrono::nanoseconds getTimeElapsed(sk_gpu_test::PlatformTimerQuery) override; + void deleteQuery(sk_gpu_test::PlatformTimerQuery) override; + +private: + GLGpuTimer(bool disjointSupport, const sk_gpu_test::GLTestContext*, const char* ext = ""); + + bool validate() const; + + sk_gpu_test::PlatformTimerQuery onQueueTimerStart() const override; + void onQueueTimerStop(sk_gpu_test::PlatformTimerQuery) const override; + + static constexpr GrGLenum GL_QUERY_RESULT = 0x8866; + static constexpr GrGLenum GL_QUERY_RESULT_AVAILABLE = 0x8867; + static constexpr GrGLenum GL_TIME_ELAPSED = 0x88bf; + static constexpr 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* GLGetQueryObjectuivProc) (GrGLuint, GrGLenum, GrGLuint*); + typedef void (GR_GL_FUNCTION_TYPE* GLGetQueryObjectui64vProc) (GrGLuint, GrGLenum, GrGLuint64*); + + GLGetIntegervProc fGLGetIntegerv; + GLGenQueriesProc fGLGenQueries; + GLDeleteQueriesProc fGLDeleteQueries; + GLBeginQueryProc fGLBeginQuery; + GLEndQueryProc fGLEndQuery; + GLGetQueryObjectuivProc fGLGetQueryObjectuiv; + GLGetQueryObjectui64vProc fGLGetQueryObjectui64v; + + + typedef sk_gpu_test::GpuTimer INHERITED; +}; + +GLGpuTimer* GLGpuTimer::CreateIfSupported(const sk_gpu_test::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 sk_gpu_test::GLTestContext* ctx, const char* ext) + : INHERITED(disjointSupport) { + ctx->getGLProcAddress(&fGLGetIntegerv, "glGetIntegerv"); + ctx->getGLProcAddress(&fGLGenQueries, "glGenQueries", ext); + ctx->getGLProcAddress(&fGLDeleteQueries, "glDeleteQueries", ext); + ctx->getGLProcAddress(&fGLBeginQuery, "glBeginQuery", ext); + ctx->getGLProcAddress(&fGLEndQuery, "glEndQuery", ext); + ctx->getGLProcAddress(&fGLGetQueryObjectuiv, "glGetQueryObjectuiv", ext); + ctx->getGLProcAddress(&fGLGetQueryObjectui64v, "glGetQueryObjectui64v", ext); +} + +bool GLGpuTimer::validate() const { + return fGLGetIntegerv && fGLGenQueries && fGLDeleteQueries && fGLBeginQuery && fGLEndQuery && + fGLGetQueryObjectuiv && fGLGetQueryObjectui64v; +} + +sk_gpu_test::PlatformTimerQuery GLGpuTimer::onQueueTimerStart() const { + GrGLuint queryID; + fGLGenQueries(1, &queryID); + if (!queryID) { + return sk_gpu_test::kInvalidTimerQuery; + } + if (this->disjointSupport()) { + // Clear the disjoint flag. + GrGLint disjoint; + fGLGetIntegerv(GL_GPU_DISJOINT, &disjoint); + } + fGLBeginQuery(GL_TIME_ELAPSED, queryID); + return static_cast<sk_gpu_test::PlatformTimerQuery>(queryID); +} + +void GLGpuTimer::onQueueTimerStop(sk_gpu_test::PlatformTimerQuery platformTimer) const { + if (sk_gpu_test::kInvalidTimerQuery == platformTimer) { + return; + } + fGLEndQuery(GL_TIME_ELAPSED); +} + +sk_gpu_test::GpuTimer::QueryStatus +GLGpuTimer::checkQueryStatus(sk_gpu_test::PlatformTimerQuery platformTimer) { + const GrGLuint queryID = static_cast<GrGLuint>(platformTimer); + if (!queryID) { + return QueryStatus::kInvalid; + } + GrGLuint available = 0; + fGLGetQueryObjectuiv(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(sk_gpu_test::PlatformTimerQuery 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(sk_gpu_test::PlatformTimerQuery platformTimer) { + const GrGLuint queryID = static_cast<GrGLuint>(platformTimer); + fGLDeleteQueries(1, &queryID); +} + +GR_STATIC_ASSERT(sizeof(GrGLuint) <= sizeof(sk_gpu_test::PlatformTimerQuery)); + } // anonymous namespace namespace sk_gpu_test { @@ -92,6 +223,7 @@ void GLTestContext::init(const GrGLInterface* gl, FenceSync* fenceSync) { SkASSERT(!fGL.get()); fGL.reset(gl); fFenceSync = fenceSync ? fenceSync : GLFenceSync::CreateIfSupported(this); + fGpuTimer = GLGpuTimer::CreateIfSupported(this); } void GLTestContext::teardown() { |