REvisiting the RangeTimer to measure the real gpu duration

This commit is contained in:
samcake 2016-07-15 09:12:16 -07:00
parent 89ec547161
commit 22ac95d463
7 changed files with 129 additions and 18 deletions

View file

@ -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();

View file

@ -66,6 +66,9 @@ namespace gpu {
int rangeIndex(int index) const { return (index % QUERY_QUEUE_SIZE); }
};
using RangeTimerPointer = std::shared_ptr<RangeTimer>;
};
#endif

View file

@ -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<Config>(renderContext->jobConfig);
config->gpuTime = _gpuTimer.getAverage();
}

View file

@ -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

View file

@ -100,6 +100,7 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
// GPU jobs: Start preparing the primary, deferred and lighting buffer
const auto primaryFramebuffer = addJob<PreparePrimaryFramebuffer>("PreparePrimaryBuffer");
const auto prepareDeferredInputs = SurfaceGeometryPass::Inputs(primaryFramebuffer, lightingModel).hasVarying();
const auto prepareDeferredOutputs = addJob<PrepareDeferred>("PrepareDeferred", prepareDeferredInputs);
const auto deferredFramebuffer = prepareDeferredOutputs.getN<PrepareDeferred::Outputs>(0);
@ -120,6 +121,8 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
const auto curvatureFramebuffer = surfaceGeometryPassOutputs.getN<SurfaceGeometryPass::Outputs>(1);
const auto linearDepthTexture = surfaceGeometryPassOutputs.getN<SurfaceGeometryPass::Outputs>(2);
const auto rangeTimer = addJob<BeginTimerGPU>("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<render::BlurGaussianDepthAware>("DiffuseCurvatureMid", diffuseCurvaturePassInputs);
@ -185,8 +188,11 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
// AA job to be revisited
addJob<Antialiasing>("Antialiasing", primaryFramebuffer);
addJob<EndTimerGPU>("RangeTimer", rangeTimer);
// Blit!
addJob<Blit>("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<Config>(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<Config>(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());

View file

@ -17,6 +17,44 @@
#include "LightingModel.h"
class BeginTimerGPU {
public:
using JobModel = render::Job::ModelO<BeginTimerGPU, gpu::RangeTimerPointer>;
BeginTimerGPU() : _gpuTimer(std::make_shared<gpu::RangeTimer>()) {}
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, gpu::RangeTimerPointer, Config>;
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 {

View file

@ -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<Config>(renderContext->jobConfig);
config->gpuTime = _gpuTimer.getAverage();
}
const gpu::PipelinePointer& SurfaceGeometryPass::getLinearDepthPipeline() {