Add batch timing information vs gpu

This commit is contained in:
samcake 2016-08-29 17:54:17 -07:00
parent 165cb8bc39
commit 3755a3fc32
16 changed files with 230 additions and 98 deletions

View file

@ -25,69 +25,29 @@ EntityItemPointer RenderableLightEntityItem::factory(const EntityItemID& entityI
return entity;
}
RenderableLightEntityItem::RenderableLightEntityItem(const EntityItemID& entityItemID) : LightEntityItem(entityItemID),
_light(std::make_shared<model::Light>()),
_lightStamp(-1)
RenderableLightEntityItem::RenderableLightEntityItem(const EntityItemID& entityItemID) : LightEntityItem(entityItemID)
{
}
namespace render {
template <> const ItemKey payloadGetKey(const LightPayload::Pointer& payload) {
return ItemKey::Builder::light();
void RenderableLightEntityItem::updateLightFromEntity(render::PendingChanges& pendingChanges) {
if (!render::Item::isValidID(_myItem)) {
return;
}
template <> const Item::Bound payloadGetBound(const LightPayload::Pointer& payload) {
if (payload) {
return payload->_bound;
}
return render::Item::Bound();
}
template <> void payloadRender(const LightPayload::Pointer& payload, RenderArgs* args) {
if (args) {
if (payload) {
payload->render(args);
}
}
}
pendingChanges.updateItem<LightRenderItem>(_myItem, [this](LightRenderItem& data) {
data.updateLightFromEntity(this);
});
}
void RenderableLightEntityItem::updateLightFromEntity() {
_light->setPosition(getPosition());
_light->setOrientation(getRotation());
glm::vec3 dimensions = getDimensions();
float largestDiameter = glm::max(dimensions.x, dimensions.y, dimensions.z);
_light->setMaximumRadius(largestDiameter / 2.0f);
_light->setColor(toGlm(getXColor()));
float intensity = getIntensity() * (_isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f);
_light->setIntensity(intensity);
_light->setFalloffRadius(getFalloffRadius());
float exponent = getExponent();
float cutoff = glm::radians(getCutoff());
if (!_isSpotlight) {
_light->setType(model::Light::POINT);
} else {
_light->setType(model::Light::SPOT);
_light->setSpotAngle(cutoff);
_light->setSpotExponent(exponent);
}
}
/*
void RenderableLightEntityItem::render(RenderArgs* args) {
PerformanceTimer perfTimer("RenderableLightEntityItem::render");
assert(getType() == EntityTypes::Light);
checkFading();
updateLightFromEntity();
DependencyManager::get<DeferredLightingEffect>()->addLight(_light);
// DependencyManager::get<DeferredLightingEffect>()->addLight(_light);
#ifdef WANT_DEBUG
Q_ASSERT(args->_batch);
@ -96,6 +56,7 @@ void RenderableLightEntityItem::render(RenderArgs* args) {
DependencyManager::get<GeometryCache>()->renderWireSphere(batch, 0.5f, 15, 15, glm::vec4(color, 1.0f));
#endif
};
*/
bool RenderableLightEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance,
@ -109,3 +70,77 @@ bool RenderableLightEntityItem::findDetailedRayIntersection(const glm::vec3& ori
// fix this mechanism.
return _lightsArePickable;
}
namespace render {
template <> const ItemKey payloadGetKey(const LightRenderItem::Pointer& payload) {
return ItemKey::Builder::light();
}
template <> const Item::Bound payloadGetBound(const LightRenderItem::Pointer& payload) {
if (payload) {
return payload->_bound;
}
return render::Item::Bound();
}
template <> void payloadRender(const LightRenderItem::Pointer& payload, RenderArgs* args) {
if (args) {
if (payload) {
payload->render(args);
}
}
}
}
LightRenderItem::LightRenderItem() :
_light(std::make_shared<model::Light>())
{
}
void LightRenderItem::updateLightFromEntity(RenderableLightEntityItem* entity) {
_light->setPosition(entity->getPosition());
_light->setOrientation(entity->getRotation());
bool success;
_bound = entity->getAABox(success);
if (!success) {
_bound = render::Item::Bound();
}
glm::vec3 dimensions = entity->getDimensions();
float largestDiameter = glm::max(dimensions.x, dimensions.y, dimensions.z);
_light->setMaximumRadius(largestDiameter / 2.0f);
_light->setColor(toGlm(entity->getXColor()));
float intensity = entity->getIntensity();//* entity->getFadingRatio();
_light->setIntensity(intensity);
_light->setFalloffRadius(entity->getFalloffRadius());
float exponent = entity->getExponent();
float cutoff = glm::radians(entity->getCutoff());
if (!entity->getIsSpotlight()) {
_light->setType(model::Light::POINT);
} else {
_light->setType(model::Light::SPOT);
_light->setSpotAngle(cutoff);
_light->setSpotExponent(exponent);
}
}
void LightRenderItem::render(RenderArgs* args) {
//updateLightFromEntity();
DependencyManager::get<DeferredLightingEffect>()->addLight(_light);
}

View file

@ -16,6 +16,7 @@
#include <model/Light.h>
#include "RenderableEntityItem.h"
class RenderableLightEntityItem;
class LightRenderItem {
public:
@ -26,7 +27,11 @@ public:
render::Item::Bound _bound;
LightRenderItem();
void render(RenderArgs* args);
void updateLightFromEntity(RenderableLightEntityItem* entity);
};
namespace render {
@ -40,18 +45,22 @@ public:
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
RenderableLightEntityItem(const EntityItemID& entityItemID);
virtual void render(RenderArgs* args) override;
virtual bool supportsDetailedRayIntersection() const override { return true; }
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal,
void** intersectedObject, bool precisionPicking) const override;
void updateLightFromEntity();
void updateLightFromEntity(render::PendingChanges& pendingChanges);
virtual bool addToScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) override {
_myItem = scene->allocateID();
auto renderPayload = std::make_shared<LightRenderItem::Payload>();
auto renderItem = std::make_shared<LightRenderItem>();
renderItem->updateLightFromEntity(this);
auto renderPayload = std::make_shared<LightRenderItem::Payload>(renderItem);
render::Item::Status::Getters statusGetters;
makeEntityItemStatusGetters(self, statusGetters);
@ -69,6 +78,25 @@ public:
virtual void locationChanged(bool tellPhysics = true) override {
EntityItem::locationChanged(tellPhysics);
notifyChanged();
}
virtual void dimensionsChanged() override {
EntityItem::dimensionsChanged();
notifyChanged();
}
void checkFading() {
bool transparent = isTransparent();
if (transparent != _prevIsTransparent) {
notifyChanged();
_isFading = false;
_prevIsTransparent = transparent;
}
}
void notifyChanged() {
if (!render::Item::isValidID(_myItem)) {
return;
}
@ -76,28 +104,12 @@ public:
render::PendingChanges pendingChanges;
render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene();
pendingChanges.updateItem<RenderableEntityItemProxy>(_myItem, [](RenderableEntityItemProxy& data) {
});
updateLightFromEntity(pendingChanges);
scene->enqueuePendingChanges(pendingChanges);
}
virtual void dimensionsChanged() override {
EntityItem::dimensionsChanged();
_renderHelper.notifyChanged();
}
void checkFading() {
bool transparent = isTransparent();
if (transparent != _prevIsTransparent) {
_renderHelper.notifyChanged();
_isFading = false;
_prevIsTransparent = transparent;
}
}
private:
SimpleRenderableEntityItem _renderHelper;
bool _prevIsTransparent { isTransparent() };
render::ItemID _myItem { render::Item::INVALID_ITEM_ID };

View file

@ -446,6 +446,9 @@ public:
virtual void setProxyWindow(QWindow* proxyWindow) {}
virtual QObject* getEventHandler() { return nullptr; }
bool isFading() const { return _isFading; }
float getFadingRatio() const { return (isFading() ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f); }
protected:
void setSimulated(bool simulated) { _simulated = simulated; }

View file

@ -25,6 +25,7 @@ void GLBackend::do_beginQuery(const Batch& batch, size_t paramOffset) {
auto query = batch._queries.get(batch._params[paramOffset]._uint);
GLQuery* glquery = syncGPUObject(*query);
if (glquery) {
glGetInteger64v(GL_TIMESTAMP, (GLint64*) &glquery->_batchTimeRange);
if (timeElapsed) {
glBeginQuery(GL_TIME_ELAPSED, glquery->_endqo);
} else {
@ -43,6 +44,10 @@ void GLBackend::do_endQuery(const Batch& batch, size_t paramOffset) {
} else {
glQueryCounter(glquery->_endqo, GL_TIMESTAMP);
}
GLint64 now;
glGetInteger64v(GL_TIMESTAMP, &now);
glquery->_batchTimeRange = now - glquery->_batchTimeRange;
(void)CHECK_GL_ERROR();
}
}
@ -61,7 +66,7 @@ void GLBackend::do_getQuery(const Batch& batch, size_t paramOffset) {
glGetQueryObjectui64v(glquery->_endqo, GL_QUERY_RESULT, &end);
glquery->_result = end - start;
}
query->triggerReturnHandler(glquery->_result);
query->triggerReturnHandler(glquery->_result, ((double) glquery->_batchTimeRange) / 1000000.0);
}
(void)CHECK_GL_ERROR();
}

View file

@ -48,6 +48,7 @@ public:
const GLuint& _endqo = { _id };
const GLuint _beginqo = { 0 };
GLuint64 _result { (GLuint64)-1 };
GLuint64 _batchTimeRange;
protected:
GLQuery(const std::weak_ptr<GLBackend>& backend, const Query& query, GLuint endId, GLuint beginId) : Parent(backend, query, endId), _beginqo(beginId) {}

View file

@ -28,8 +28,14 @@ double Query::getElapsedTime() const {
return ((double)_queryResult) / 1000000.0;
}
void Query::triggerReturnHandler(uint64_t queryResult) {
double Query::getBatchPerformTime() const {
return _batchPerformTime;
}
void Query::triggerReturnHandler(uint64_t queryResult, double cpuTime) {
_queryResult = queryResult;
_batchPerformTime = cpuTime;
if (_returnHandler) {
_returnHandler(*this);
}
@ -41,7 +47,10 @@ RangeTimer::RangeTimer() {
_timerQueries.push_back(std::make_shared<gpu::Query>([&, i] (const Query& query) {
_tailIndex ++;
auto elapsedTime = query.getElapsedTime();
_movingAverage.addSample(elapsedTime);
_movingAverageGPU.addSample(elapsedTime);
auto elapsedTimeCPU = query.getBatchPerformTime();
_movingAverageCPU.addSample(elapsedTimeCPU);
}));
}
}
@ -66,6 +75,10 @@ void RangeTimer::end(gpu::Batch& batch) {
}
}
double RangeTimer::getAverage() const {
return _movingAverage.average;
double RangeTimer::getAverageGPU() const {
return _movingAverageGPU.average;
}
double RangeTimer::getAverageCPU() const {
return _movingAverageCPU.average;
}

View file

@ -32,12 +32,15 @@ namespace gpu {
double getElapsedTime() const;
double getBatchPerformTime() const;
const GPUObjectPointer gpuObject {};
void triggerReturnHandler(uint64_t queryResult);
void triggerReturnHandler(uint64_t queryResult, double cpuTime);
protected:
Handler _returnHandler;
uint64_t _queryResult = 0;
double _batchPerformTime { 0.0 };
};
typedef std::shared_ptr<Query> QueryPointer;
@ -53,7 +56,8 @@ namespace gpu {
void begin(gpu::Batch& batch);
void end(gpu::Batch& batch);
double getAverage() const;
double getAverageGPU() const;
double getAverageCPU() const;
protected:
@ -62,7 +66,8 @@ namespace gpu {
gpu::Queries _timerQueries;
int _headIndex = -1;
int _tailIndex = -1;
MovingAverage<double, QUERY_QUEUE_SIZE * 2> _movingAverage;
MovingAverage<double, QUERY_QUEUE_SIZE * 2> _movingAverageCPU;
MovingAverage<double, QUERY_QUEUE_SIZE * 2> _movingAverageGPU;
int rangeIndex(int index) const { return (index % QUERY_QUEUE_SIZE); }
};

View file

@ -432,7 +432,9 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
});
// Update the timer
std::static_pointer_cast<Config>(renderContext->jobConfig)->gpuTime = _gpuTimer.getAverage();
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
config->gpuTime = _gpuTimer.getAverageGPU();
config->gpuBatchTime = _gpuTimer.getAverageCPU();
}

View file

@ -69,6 +69,7 @@ class AmbientOcclusionEffectConfig : public render::Job::Config::Persistent {
Q_PROPERTY(int resolutionLevel MEMBER resolutionLevel WRITE setResolutionLevel)
Q_PROPERTY(int blurRadius MEMBER blurRadius WRITE setBlurRadius)
Q_PROPERTY(double gpuTime READ getGpuTime)
Q_PROPERTY(double gpuBatchTime READ getGpuBatchTime)
public:
AmbientOcclusionEffectConfig() : render::Job::Config::Persistent("Ambient Occlusion", false) {}
@ -85,6 +86,7 @@ public:
void setResolutionLevel(int level) { resolutionLevel = std::max(0, std::min(level, MAX_RESOLUTION_LEVEL)); emit dirty(); }
void setBlurRadius(int radius) { blurRadius = std::max(0, std::min(MAX_BLUR_RADIUS, radius)); emit dirty(); }
double getGpuTime() { return gpuTime; }
double getGpuBatchTime() { return gpuBatchTime; }
float radius{ 0.5f };
float perspectiveScale{ 1.0f };
@ -99,7 +101,8 @@ public:
bool ditheringEnabled{ true }; // randomize the distribution of taps per pixel, should always be true
bool borderingEnabled{ true }; // avoid evaluating information from non existing pixels out of the frame, should always be true
bool fetchMipsEnabled{ true }; // fetch taps in sub mips to otpimize cache, should always be true
double gpuTime{ 0.0 };
double gpuTime { 0.0 };
double gpuBatchTime { 0.0 };
signals:
void dirty();

View file

@ -733,5 +733,6 @@ void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderCo
});
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
config->gpuTime = _gpuTimer.getAverage();
config->gpuTime = _gpuTimer.getAverageGPU();
config->gpuBatchTime = _gpuTimer.getAverageCPU();
}

View file

@ -168,12 +168,15 @@ public:
class RenderDeferredConfig : public render::Job::Config {
Q_OBJECT
Q_PROPERTY(double gpuTime READ getGpuTime)
Q_PROPERTY(double gpuBatchTime READ getGpuBatchTime)
public:
RenderDeferredConfig() : render::Job::Config(true) {}
double getGpuTime() { return gpuTime; }
double getGpuBatchTime() { return gpuBatchTime; }
double gpuTime{ 0.0 };
double gpuTime { 0.0 };
double gpuBatchTime { 0.0 };
signals:
void dirty();

View file

@ -245,7 +245,7 @@ void EndGPURangeTimer::run(const render::SceneContextPointer& sceneContext, cons
});
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
config->gpuTime = timer->getAverage();
config->setTime(timer->getAverageGPU(), timer->getAverageCPU());
}

View file

@ -33,12 +33,19 @@ protected:
class GPURangeTimerConfig : public render::Job::Config {
Q_OBJECT
Q_PROPERTY(double gpuTime READ getGpuTime)
Q_PROPERTY(double gpuBatchTime READ getGpuBatchTime)
public:
double getGpuTime() { return gpuTime; }
double getGpuBatchTime() { return gpuBatchTime; }
void setTime(double gpu, double batch) {
gpuTime = gpu;
gpuBatchTime = batch;
}
protected:
friend class EndGPURangeTimer;
double gpuTime;
double gpuBatchTime;
};
class EndGPURangeTimer {
@ -143,16 +150,7 @@ protected:
gpu::PipelinePointer getOpaquePipeline();
};
class DrawBackgroundDeferredConfig : public render::Job::Config {
Q_OBJECT
Q_PROPERTY(double gpuTime READ getGpuTime)
public:
double getGpuTime() { return gpuTime; }
protected:
friend class DrawBackgroundDeferred;
double gpuTime;
};
using DrawBackgroundDeferredConfig = GPURangeTimerConfig;
class DrawBackgroundDeferred {
public:

View file

@ -201,7 +201,9 @@ void LinearDepthPass::run(const render::SceneContextPointer& sceneContext, const
});
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
config->gpuTime = _gpuTimer.getAverage();
config->gpuTime = _gpuTimer.getAverageGPU();
config->gpuBatchTime = _gpuTimer.getAverageCPU();
}
@ -524,8 +526,8 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
config->gpuTime = _gpuTimer.getAverage();
}
config->gpuTime = _gpuTimer.getAverageGPU();
config->gpuBatchTime = _gpuTimer.getAverageCPU(); }
const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() {

View file

@ -66,12 +66,16 @@ using LinearDepthFramebufferPointer = std::shared_ptr<LinearDepthFramebuffer>;
class LinearDepthPassConfig : public render::Job::Config {
Q_OBJECT
Q_PROPERTY(double gpuTime READ getGpuTime)
Q_PROPERTY(double gpuBatchTime READ getGpuBatchTime)
public:
LinearDepthPassConfig() : render::Job::Config(true) {}
double getGpuTime() { return gpuTime; }
double getGpuBatchTime() { return gpuBatchTime; }
double gpuTime{ 0.0 };
double gpuBatchTime { 0.0 };
signals:
void dirty();
@ -159,6 +163,8 @@ class SurfaceGeometryPassConfig : public render::Job::Config {
Q_PROPERTY(float diffuseDepthThreshold MEMBER diffuseDepthThreshold NOTIFY dirty)
Q_PROPERTY(double gpuTime READ getGpuTime)
Q_PROPERTY(double gpuBatchTime READ getGpuBatchTime)
public:
SurfaceGeometryPassConfig() : render::Job::Config(true) {}
@ -170,8 +176,10 @@ public:
float diffuseDepthThreshold{ 1.0f };
double getGpuTime() { return gpuTime; }
double getGpuBatchTime() { return gpuBatchTime; }
double gpuTime{ 0.0 };
double gpuTime { 0.0 };
double gpuBatchTime { 0.0 };
signals:
void dirty();

View file

@ -69,6 +69,47 @@ Item {
}
]
}
PlotPerf {
title: "Batch Timing"
height: parent.evalEvenHeight()
object: parent.drawOpaqueConfig
valueUnit: "ms"
valueScale: 1
valueNumDigits: "4"
plots: [
{
object: Render.getConfig("OpaqueRangeTimer"),
prop: "gpuBatchTime",
label: "Opaque",
color: "#FFFFFF"
},
{
object: Render.getConfig("LinearDepth"),
prop: "gpuBatchTime",
label: "LinearDepth",
color: "#00FF00"
},{
object: Render.getConfig("SurfaceGeometry"),
prop: "gpuBatchTime",
label: "SurfaceGeometry",
color: "#00FFFF"
},
{
object: Render.getConfig("RenderDeferred"),
prop: "gpuBatchTime",
label: "DeferredLighting",
color: "#FF00FF"
}
,
{
object: Render.getConfig("ToneAndPostRangeTimer"),
prop: "gpuBatchTime",
label: "tone and post",
color: "#FF0000"
}
]
}
}
}