From 5fbd18370fb90c14e2a6abd99bba37dd947943b8 Mon Sep 17 00:00:00 2001 From: Brian Osman Date: Tue, 10 Oct 2017 16:39:50 -0400 Subject: Add NV_fence support to get better timing from ANGLE ES2 Previously, we were reporting numbers that were far too low, because we were getting way ahead of the GPU, and then spending all of our time in finish (which isn't timed). That led to us picking very high loop counts, so our wall clock time to run nanobench was very high, and our reported times were very low. This fixes all of that, and removes all the spam about not having fence support. Change-Id: Ib9dfc043da82bf8ee6645b8627cfade66eb9864e Reviewed-on: https://skia-review.googlesource.com/58001 Reviewed-by: Brian Salomon Commit-Queue: Brian Osman --- tools/gpu/FenceSync.h | 2 ++ tools/gpu/gl/GLTestContext.cpp | 63 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/tools/gpu/FenceSync.h b/tools/gpu/FenceSync.h index b430f5dfa9..4fe724a15b 100644 --- a/tools/gpu/FenceSync.h +++ b/tools/gpu/FenceSync.h @@ -26,6 +26,8 @@ public: virtual bool waitFence(PlatformFence) const = 0; virtual void deleteFence(PlatformFence) const = 0; + virtual bool validate() const { return true; } + virtual ~FenceSync() {} }; diff --git a/tools/gpu/gl/GLTestContext.cpp b/tools/gpu/gl/GLTestContext.cpp index 4375346892..76e38b71b4 100644 --- a/tools/gpu/gl/GLTestContext.cpp +++ b/tools/gpu/gl/GLTestContext.cpp @@ -15,7 +15,7 @@ namespace { class GLFenceSync : public sk_gpu_test::FenceSync { public: - static std::unique_ptr MakeIfSupported(const sk_gpu_test::GLTestContext*); + static std::unique_ptr MakeIfSupported(const sk_gpu_test::GLTestContext*); sk_gpu_test::PlatformFence SK_WARN_UNUSED_RESULT insertFence() const override; bool waitFence(sk_gpu_test::PlatformFence fence) const override; @@ -24,7 +24,7 @@ public: private: GLFenceSync(const sk_gpu_test::GLTestContext*, const char* ext = ""); - bool validate() { return fGLFenceSync && fGLClientWaitSync && fGLDeleteSync; } + bool validate() const override { return fGLFenceSync && fGLClientWaitSync && fGLDeleteSync; } static constexpr GrGLenum GL_SYNC_GPU_COMMANDS_COMPLETE = 0x9117; static constexpr GrGLenum GL_WAIT_FAILED = 0x911d; @@ -44,8 +44,37 @@ private: typedef FenceSync INHERITED; }; -std::unique_ptr GLFenceSync::MakeIfSupported(const sk_gpu_test::GLTestContext* ctx) { - std::unique_ptr ret; +class GLNVFenceSync : public sk_gpu_test::FenceSync { +public: + GLNVFenceSync(const sk_gpu_test::GLTestContext*); + + sk_gpu_test::PlatformFence SK_WARN_UNUSED_RESULT insertFence() const override; + bool waitFence(sk_gpu_test::PlatformFence fence) const override; + void deleteFence(sk_gpu_test::PlatformFence fence) const override; + +private: + bool validate() const override { + return fGLGenFencesNV && fGLDeleteFencesNV && fGLSetFenceNV && fGLFinishFenceNV; + } + + static constexpr GrGLenum GL_ALL_COMPLETED_NV = 0x84F2; + + typedef GrGLvoid(GR_GL_FUNCTION_TYPE* GLGenFencesNVProc) (GrGLsizei, GrGLuint*); + typedef GrGLvoid(GR_GL_FUNCTION_TYPE* GLDeleteFencesNVProc) (GrGLsizei, const GrGLuint*); + typedef GrGLvoid(GR_GL_FUNCTION_TYPE* GLSetFenceNVProc) (GrGLuint, GrGLenum); + typedef GrGLvoid(GR_GL_FUNCTION_TYPE* GLFinishFenceNVProc) (GrGLuint); + + GLGenFencesNVProc fGLGenFencesNV; + GLDeleteFencesNVProc fGLDeleteFencesNV; + GLSetFenceNVProc fGLSetFenceNV; + GLFinishFenceNVProc fGLFinishFenceNV; + + typedef FenceSync INHERITED; +}; + +std::unique_ptr GLFenceSync::MakeIfSupported( + const sk_gpu_test::GLTestContext* ctx) { + std::unique_ptr ret; if (kGL_GrGLStandard == ctx->gl()->fStandard) { if (GrGLGetVersion(ctx->gl()) < GR_GL_VER(3,2) && !ctx->gl()->hasExtension("GL_ARB_sync")) { return nullptr; @@ -54,6 +83,8 @@ std::unique_ptr GLFenceSync::MakeIfSupported(const sk_gpu_test::GLT } else { if (ctx->gl()->hasExtension("GL_APPLE_sync")) { ret.reset(new GLFenceSync(ctx, "APPLE")); + } else if (ctx->gl()->hasExtension("GL_NV_fence")) { + ret.reset(new GLNVFenceSync(ctx)); } else if (GrGLGetVersion(ctx->gl()) >= GR_GL_VER(3, 0)) { ret.reset(new GLFenceSync(ctx)); } else { @@ -87,6 +118,30 @@ void GLFenceSync::deleteFence(sk_gpu_test::PlatformFence fence) const { fGLDeleteSync(glsync); } +GLNVFenceSync::GLNVFenceSync(const sk_gpu_test::GLTestContext* ctx) { + ctx->getGLProcAddress(&fGLGenFencesNV, "glGenFencesNV"); + ctx->getGLProcAddress(&fGLDeleteFencesNV, "glDeleteFencesNV"); + ctx->getGLProcAddress(&fGLSetFenceNV, "glSetFenceNV"); + ctx->getGLProcAddress(&fGLFinishFenceNV, "glFinishFenceNV"); +} + +sk_gpu_test::PlatformFence GLNVFenceSync::insertFence() const { + GrGLuint fence; + fGLGenFencesNV(1, &fence); + fGLSetFenceNV(fence, GL_ALL_COMPLETED_NV); + return fence; +} + +bool GLNVFenceSync::waitFence(sk_gpu_test::PlatformFence fence) const { + fGLFinishFenceNV(fence); + return true; +} + +void GLNVFenceSync::deleteFence(sk_gpu_test::PlatformFence fence) const { + GrGLuint glFence = static_cast(fence); + fGLDeleteFencesNV(1, &glFence); +} + class GLGpuTimer : public sk_gpu_test::GpuTimer { public: static std::unique_ptr MakeIfSupported(const sk_gpu_test::GLTestContext*); -- cgit v1.2.3