Further work on GPU stats

This commit is contained in:
Robert Osfield 2007-01-22 21:16:51 +00:00
parent 52e86aaea3
commit 71f307c5b2
2 changed files with 153 additions and 109 deletions

View File

@ -397,11 +397,7 @@ public:
}
}
#if 0
bool aquireGPUStats = numCamrasWithTimerQuerySupport==cameras.size();
#else
bool aquireGPUStats = false;
#endif
float leftPos = 10.0f;
float startBlocks = aquireGPUStats ? 250.0f : 150.0f;
@ -413,8 +409,6 @@ public:
osg::Vec4 colorUpdate( 0.0f,1.0f,0.0f,1.0f);
// frame rate stats
{
osg::Geode* geode = new osg::Geode();
@ -632,33 +626,6 @@ public:
drawValue->setDrawCallback(new TextDrawCallback(stats,"Draw traversal time taken",-1, 1000.0));
if (aquireGPUStats)
{
pos.x() = drawValue->getBound().xMax() + 30.0f;
osg::ref_ptr<osgText::Text> gpuLabel = new osgText::Text;
geode->addDrawable( gpuLabel.get() );
gpuLabel->setColor(colorGPU);
gpuLabel->setFont(font);
gpuLabel->setCharacterSize(characterSize);
gpuLabel->setPosition(pos);
gpuLabel->setText("GPU: ");
pos.x() = gpuLabel->getBound().xMax();
osg::ref_ptr<osgText::Text> gpuValue = new osgText::Text;
geode->addDrawable( gpuValue.get() );
gpuValue->setColor(colorGPU);
gpuValue->setFont(font);
gpuValue->setCharacterSize(characterSize);
gpuValue->setPosition(pos);
gpuValue->setText("0.0");
gpuValue->setDrawCallback(new TextDrawCallback(stats,"GPU draw time taken",-1, 1000.0));
}
pos.x() = startBlocks;
osg::Geometry* geometry = createGeometry(pos, characterSize *0.8, colorDraw, 10);
geometry->setDrawCallback(new BlockDrawCallback(startBlocks, viewerStats, stats, "Draw traversal begin time", "Draw traversal end time", -1, 10, 10000.0));
@ -667,6 +634,41 @@ public:
pos.y() -= characterSize*1.5f;
}
if (aquireGPUStats)
{
pos.x() = leftPos;
osg::ref_ptr<osgText::Text> gpuLabel = new osgText::Text;
geode->addDrawable( gpuLabel.get() );
gpuLabel->setColor(colorGPU);
gpuLabel->setFont(font);
gpuLabel->setCharacterSize(characterSize);
gpuLabel->setPosition(pos);
gpuLabel->setText("GPU: ");
pos.x() = gpuLabel->getBound().xMax();
osg::ref_ptr<osgText::Text> gpuValue = new osgText::Text;
geode->addDrawable( gpuValue.get() );
gpuValue->setColor(colorGPU);
gpuValue->setFont(font);
gpuValue->setCharacterSize(characterSize);
gpuValue->setPosition(pos);
gpuValue->setText("0.0");
gpuValue->setDrawCallback(new TextDrawCallback(stats,"GPU draw time taken",-1, 1000.0));
pos.x() = startBlocks;
osg::Geometry* geometry = createGeometry(pos, characterSize *0.8, colorGPU, 10);
geometry->setDrawCallback(new BlockDrawCallback(startBlocks, viewerStats, stats, "GPU draw begin time", "GPU draw end time", -1, 10, 10000.0));
geode->addDrawable(geometry);
pos.y() -= characterSize*1.5f;
}
pos.x() = leftPos;

View File

@ -453,11 +453,81 @@ struct ViewerRenderingOperation : public osg::GraphicsOperation
_sceneView(sceneView),
_databasePager(databasePager),
_startTick(startTick),
_checkForQuery(false)
_initialized(false),
_aquireGPUStats(false),
_extensions(0)
{
_sceneView->getCullVisitor()->setDatabaseRequestHandler(_databasePager.get());
}
typedef std::pair<GLuint, int> QueryFrameNumberPair;
typedef std::list<QueryFrameNumberPair> QueryFrameNumberList;
typedef std::vector<GLuint> QueryList;
inline void checkQuery(osg::Stats* stats)
{
for(QueryFrameNumberList::iterator itr = _queryFrameNumberList.begin();
itr != _queryFrameNumberList.end();
)
{
GLuint query = itr->first;
GLint available = 0;
_extensions->glGetQueryObjectiv(query, GL_QUERY_RESULT_AVAILABLE, &available);
if (available)
{
GLuint64EXT timeElapsed = 0;
_extensions->glGetQueryObjectui64v(query, GL_QUERY_RESULT, &timeElapsed);
double timeElapsedSeconds = double(timeElapsed)*1e-9;
double currentTime = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
double estimatedEndTime = (_previousQueryTime + currentTime) * 0.5;
double estimatedBeginTime = estimatedEndTime - timeElapsedSeconds;
stats->setAttribute(itr->second, "GPU draw begin time", estimatedBeginTime);
stats->setAttribute(itr->second, "GPU draw end time", estimatedEndTime);
stats->setAttribute(itr->second, "GPU draw time taken", timeElapsedSeconds);
itr = _queryFrameNumberList.erase(itr);
_availableQueryObjects.push_back(query);
}
else
{
++itr;
}
}
_previousQueryTime = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
}
inline GLuint createQueryObject()
{
if (_availableQueryObjects.empty())
{
GLuint query;
_extensions->glGenQueries(1, &query);
return query;
}
else
{
GLuint query = _availableQueryObjects.back();
_availableQueryObjects.pop_back();
return query;
}
}
inline void beginQuery(int frameNumber)
{
GLuint query = createQueryObject();
_extensions->glBeginQuery(GL_TIME_ELAPSED, query);
_queryFrameNumberList.push_back(QueryFrameNumberPair(query, frameNumber));
}
inline void endQuery()
{
_extensions->glEndQuery(GL_TIME_ELAPSED);
}
virtual void operator () (osg::GraphicsContext*)
{
if (!_sceneView) return;
@ -468,87 +538,54 @@ struct ViewerRenderingOperation : public osg::GraphicsOperation
osg::State* state = _sceneView->getState();
const osg::FrameStamp* fs = state->getFrameStamp();
int frameNumber = fs ? fs->getFrameNumber() : 0;
// osg::notify(osg::NOTICE)<<"Frame number "<<frameNumber<<std::endl;
osg::Timer_t beforeCullTick = osg::Timer::instance()->tick();
_sceneView->cull();
osg::Timer_t afterCullTick = osg::Timer::instance()->tick();
const osg::Drawable::Extensions* extensions = stats ? osg::Drawable::getExtensions(state->getContextID(),true) : 0;
#if 0
bool aquireGPUStats = extensions && extensions->isTimerQuerySupported();
#else
bool aquireGPUStats = false;
#endif
if (aquireGPUStats)
if (!_initialized)
{
if (_checkForQuery)
{
// Wait for all results to become available
GLint available = 0;
extensions->glGetQueryObjectiv(_query, GL_QUERY_RESULT_AVAILABLE, &available);
if (!available)
{
osg::notify(osg::INFO)<<"Stats not available - forcing a glFinish"<<std::endl;
glFinish();
extensions->glGetQueryObjectiv(_query, GL_QUERY_RESULT_AVAILABLE, &available);
}
if (available)
{
GLuint64EXT timeElapsed = 0;
extensions->glGetQueryObjectui64v(_query, GL_QUERY_RESULT, &timeElapsed);
stats->setAttribute(frameNumber-1, "GPU draw time taken", double(timeElapsed)*1e-9);
}
else
{
osg::notify(osg::INFO)<<"Stats not available - query has been lost."<<std::endl;
// regenerate the query object as it seems to have been lost
extensions->glGenQueries(1, &_query);
}
}
else
{
// Create a query object.
extensions->glGenQueries(1, &_query);
}
extensions->glBeginQuery(GL_TIME_ELAPSED, _query);
_sceneView->draw();
double availableTime = 0.004; // 4 ms
if (_databasePager.valid())
{
_databasePager->compileGLObjects(*(_sceneView->getState()), availableTime);
}
_sceneView->flushDeletedGLObjects(availableTime);
extensions->glEndQuery(GL_TIME_ELAPSED);
_checkForQuery = true;
_initialized = true;
_extensions = stats ? osg::Drawable::getExtensions(state->getContextID(),true) : 0;
_aquireGPUStats = _extensions && _extensions->isTimerQuerySupported();
_previousQueryTime = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
}
else
{
_sceneView->draw();
// _aquireGPUStats = false;
double availableTime = 0.004; // 4 ms
if (_databasePager.valid())
{
_databasePager->compileGLObjects(*(state), availableTime);
}
_sceneView->flushDeletedGLObjects(availableTime);
if (_aquireGPUStats)
{
checkQuery(stats);
}
// do cull taversal
osg::Timer_t beforeCullTick = osg::Timer::instance()->tick();
_sceneView->cull();
osg::Timer_t afterCullTick = osg::Timer::instance()->tick();
// do draw traveral
if (_aquireGPUStats)
{
checkQuery(stats);
beginQuery(frameNumber);
}
_sceneView->draw();
double availableTime = 0.004; // 4 ms
if (_databasePager.valid())
{
_databasePager->compileGLObjects(*(_sceneView->getState()), availableTime);
}
_sceneView->flushDeletedGLObjects(availableTime);
if (_aquireGPUStats)
{
endQuery();
checkQuery(stats);
}
osg::Timer_t afterDrawTick = osg::Timer::instance()->tick();
if (stats)
{
stats->setAttribute(frameNumber, "Cull traversal begin time", osg::Timer::instance()->delta_s(_startTick, beforeCullTick));
@ -566,8 +603,13 @@ struct ViewerRenderingOperation : public osg::GraphicsOperation
osg::observer_ptr<osgDB::DatabasePager> _databasePager;
osg::Timer_t _startTick;
bool _checkForQuery;
GLuint _query;
bool _initialized;
bool _aquireGPUStats;
const osg::Drawable::Extensions* _extensions;
QueryFrameNumberList _queryFrameNumberList;
QueryList _availableQueryObjects;
double _previousQueryTime;
};
void Viewer::setUpRenderingSupport()