From 22ac95d46396570a0c1dcb549a9788c84fa1b8b6 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 15 Jul 2016 09:12:16 -0700 Subject: [PATCH] REvisiting the RangeTimer to measure the real gpu duration --- .../gpu-gl/src/gpu/gl/GLBackendQuery.cpp | 26 ++++++++--- libraries/gpu/src/gpu/Query.h | 3 ++ .../src/DeferredLightingEffect.cpp | 12 ++++- .../render-utils/src/DeferredLightingEffect.h | 6 +++ .../render-utils/src/RenderDeferredTask.cpp | 34 +++++++++++--- .../render-utils/src/RenderDeferredTask.h | 44 +++++++++++++++++-- .../render-utils/src/SurfaceGeometryPass.cpp | 22 ++++++++-- 7 files changed, 129 insertions(+), 18 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendQuery.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackendQuery.cpp index 45e0d8d53f..5191b161cf 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendQuery.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackendQuery.cpp @@ -14,11 +14,17 @@ using namespace gpu; using namespace gpu::gl; +static bool timeElapsed = true; + void GLBackend::do_beginQuery(Batch& batch, size_t paramOffset) { auto query = batch._queries.get(batch._params[paramOffset]._uint); GLQuery* glquery = syncGPUObject(*query); if (glquery) { - glQueryCounter(glquery->_beginqo, GL_TIMESTAMP); + if (timeElapsed) { + glBeginQuery(GL_TIME_ELAPSED, glquery->_endqo); + } else { + glQueryCounter(glquery->_beginqo, GL_TIMESTAMP); + } (void)CHECK_GL_ERROR(); } } @@ -27,7 +33,11 @@ void GLBackend::do_endQuery(Batch& batch, size_t paramOffset) { auto query = batch._queries.get(batch._params[paramOffset]._uint); GLQuery* glquery = syncGPUObject(*query); if (glquery) { - glQueryCounter(glquery->_endqo, GL_TIMESTAMP); + if (timeElapsed) { + glEndQuery(GL_TIME_ELAPSED); + } else { + glQueryCounter(glquery->_endqo, GL_TIMESTAMP); + } (void)CHECK_GL_ERROR(); } } @@ -38,10 +48,14 @@ void GLBackend::do_getQuery(Batch& batch, size_t paramOffset) { if (glquery) { glGetQueryObjectui64v(glquery->_endqo, GL_QUERY_RESULT_AVAILABLE, &glquery->_result); if (glquery->_result == GL_TRUE) { - GLuint64 start, end; - glGetQueryObjectui64v(glquery->_beginqo, GL_QUERY_RESULT, &start); - glGetQueryObjectui64v(glquery->_endqo, GL_QUERY_RESULT, &end); - glquery->_result = end - start; + if (timeElapsed) { + glGetQueryObjectui64v(glquery->_endqo, GL_QUERY_RESULT, &glquery->_result); + } else { + GLuint64 start, end; + glGetQueryObjectui64v(glquery->_beginqo, GL_QUERY_RESULT, &start); + glGetQueryObjectui64v(glquery->_endqo, GL_QUERY_RESULT, &end); + glquery->_result = end - start; + } query->triggerReturnHandler(glquery->_result); } (void)CHECK_GL_ERROR(); diff --git a/libraries/gpu/src/gpu/Query.h b/libraries/gpu/src/gpu/Query.h index 8e4026fe0f..48b9d0a0d5 100644 --- a/libraries/gpu/src/gpu/Query.h +++ b/libraries/gpu/src/gpu/Query.h @@ -66,6 +66,9 @@ namespace gpu { int rangeIndex(int index) const { return (index % QUERY_QUEUE_SIZE); } }; + + using RangeTimerPointer = std::shared_ptr; + }; #endif diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 4f5544bab3..9d8c1ef200 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -694,12 +694,22 @@ void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderCo auto surfaceGeometryFramebuffer = inputs.get3(); auto lowCurvatureNormalFramebuffer = inputs.get4(); auto subsurfaceScatteringResource = inputs.get5(); + auto args = renderContext->args; - + gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { + _gpuTimer.begin(batch); + }); setupJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lowCurvatureNormalFramebuffer, subsurfaceScatteringResource); lightsJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel); cleanupJob.run(sceneContext, renderContext); + + gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { + _gpuTimer.end(batch); + }); + + auto config = std::static_pointer_cast(renderContext->jobConfig); + config->gpuTime = _gpuTimer.getAverage(); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index ff372aa5b4..b309299be9 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -163,9 +163,14 @@ public: class RenderDeferredConfig : public render::Job::Config { Q_OBJECT + Q_PROPERTY(double gpuTime READ getGpuTime) public: RenderDeferredConfig() : render::Job::Config(true) {} + double getGpuTime() { return gpuTime; } + + double gpuTime{ 0.0 }; + signals: void dirty(); }; @@ -188,6 +193,7 @@ public: RenderDeferredCleanup cleanupJob; protected: + gpu::RangeTimer _gpuTimer; }; #endif // hifi_DeferredLightingEffect_h diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 7959c371f9..6ad0ae4843 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -100,6 +100,7 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) { // GPU jobs: Start preparing the primary, deferred and lighting buffer const auto primaryFramebuffer = addJob("PreparePrimaryBuffer"); + const auto prepareDeferredInputs = SurfaceGeometryPass::Inputs(primaryFramebuffer, lightingModel).hasVarying(); const auto prepareDeferredOutputs = addJob("PrepareDeferred", prepareDeferredInputs); const auto deferredFramebuffer = prepareDeferredOutputs.getN(0); @@ -120,6 +121,8 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) { const auto curvatureFramebuffer = surfaceGeometryPassOutputs.getN(1); const auto linearDepthTexture = surfaceGeometryPassOutputs.getN(2); + const auto rangeTimer = addJob("BeginTimerRange"); + // TODO: Push this 2 diffusion stages into surfaceGeometryPass as they are working together const auto diffuseCurvaturePassInputs = BlurGaussianDepthAware::Inputs(curvatureFramebuffer, linearDepthTexture).hasVarying(); const auto midCurvatureNormalFramebuffer = addJob("DiffuseCurvatureMid", diffuseCurvaturePassInputs); @@ -185,8 +188,11 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) { // AA job to be revisited addJob("Antialiasing", primaryFramebuffer); + addJob("RangeTimer", rangeTimer); // Blit! addJob("Blit", primaryFramebuffer); + + } void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { @@ -204,21 +210,39 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend RenderArgs* args = renderContext->args; auto config = std::static_pointer_cast(renderContext->jobConfig); - gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { + /* gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { _gpuTimer.begin(batch); - }); + });*/ for (auto job : _jobs) { job.run(sceneContext, renderContext); } - gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { + /*gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { _gpuTimer.end(batch); - }); + });*/ - config->gpuTime = _gpuTimer.getAverage(); +// config->gpuTime = _gpuTimer.getAverage(); + } +void BeginTimerGPU::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, gpu::RangeTimerPointer& timer) { + timer = _gpuTimer; + gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) { + _gpuTimer->begin(batch); + }); +} + +void EndTimerGPU::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const gpu::RangeTimerPointer& timer) { + gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) { + timer->end(batch); + }); + + auto config = std::static_pointer_cast(renderContext->jobConfig); + config->gpuTime = timer->getAverage(); +} + + void DrawDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const Inputs& inputs) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 22a460cd88..032cd48b2e 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -17,6 +17,44 @@ #include "LightingModel.h" +class BeginTimerGPU { +public: + using JobModel = render::Job::ModelO; + + BeginTimerGPU() : _gpuTimer(std::make_shared()) {} + + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, gpu::RangeTimerPointer& timer); + +protected: + gpu::RangeTimerPointer _gpuTimer; +}; + + +class EndTimerGPUConfig : public render::Job::Config { + Q_OBJECT + Q_PROPERTY(double gpuTime READ getGpuTime) +public: + double getGpuTime() { return gpuTime; } + +protected: + friend class EndTimerGPU; + double gpuTime; +}; + +class EndTimerGPU { +public: + using Config = EndTimerGPUConfig; + using JobModel = render::Job::ModelI; + + EndTimerGPU() {} + + void configure(const Config& config) {} + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const gpu::RangeTimerPointer& timer); + +protected: +}; + + class DrawConfig : public render::Job::Config { Q_OBJECT Q_PROPERTY(int numDrawn READ getNumDrawn NOTIFY newStats) @@ -175,13 +213,13 @@ public: class RenderDeferredTaskConfig : public render::Task::Config { Q_OBJECT - Q_PROPERTY(double gpuTime READ getGpuTime) + Q_PROPERTY(quint64 gpuTime READ getGpuTime) public: - double getGpuTime() { return gpuTime; } + quint64 getGpuTime() { return gpuTime; } protected: friend class RenderDeferredTask; - double gpuTime; + quint64 gpuTime; }; class RenderDeferredTask : public render::Task { diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index c5d3f79bba..1d38a1bc4c 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -148,8 +148,14 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c auto linearDepthPipeline = getLinearDepthPipeline(); auto curvaturePipeline = getCurvaturePipeline(); - + + // gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { + // _gpuTimer.begin(batch); + // }); + + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { + _gpuTimer.begin(batch); batch.enableStereo(false); batch.setViewportTransform(args->_viewport); @@ -166,7 +172,9 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c batch.setPipeline(linearDepthPipeline); batch.setResourceTexture(SurfaceGeometryPass_DepthMapSlot, depthBuffer); batch.draw(gpu::TRIANGLE_STRIP, 4); - + + _gpuTimer.end(batch); + // Curvature pass batch.setFramebuffer(curvatureFBO); batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0)); @@ -176,8 +184,16 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setResourceTexture(SurfaceGeometryPass_DepthMapSlot, nullptr); batch.setResourceTexture(SurfaceGeometryPass_NormalMapSlot, nullptr); - }); + // _gpuTimer.end(batch); + }); + + // gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { + // _gpuTimer.end(batch); + // }); + + auto config = std::static_pointer_cast(renderContext->jobConfig); + config->gpuTime = _gpuTimer.getAverage(); } const gpu::PipelinePointer& SurfaceGeometryPass::getLinearDepthPipeline() {