mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
BUilding a more complete set of tools to monitor performances
This commit is contained in:
parent
9fb1a9a2a8
commit
9b58d50fd4
8 changed files with 244 additions and 111 deletions
|
@ -13,6 +13,7 @@ import QtQuick.Controls 1.4
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
width: parent.width
|
||||||
height: 100
|
height: 100
|
||||||
property string title
|
property string title
|
||||||
property var config
|
property var config
|
||||||
|
@ -34,12 +35,15 @@ Item {
|
||||||
if (inputs.length > input_VALUE_OFFSET) {
|
if (inputs.length > input_VALUE_OFFSET) {
|
||||||
for (var i = input_VALUE_OFFSET; i < inputs.length; i++) {
|
for (var i = input_VALUE_OFFSET; i < inputs.length; i++) {
|
||||||
var varProps = inputs[i].split("-")
|
var varProps = inputs[i].split("-")
|
||||||
_values.push( {
|
_values.push( {
|
||||||
value: varProps[1],
|
value: varProps[1],
|
||||||
valueMax: 1,
|
valueMax: 1,
|
||||||
|
numSamplesConstantMax: 0,
|
||||||
valueHistory: new Array(),
|
valueHistory: new Array(),
|
||||||
label: varProps[0],
|
label: varProps[0],
|
||||||
color: varProps[2]
|
color: varProps[2],
|
||||||
|
scale: (varProps.length > 3 ? varProps[3] : 1),
|
||||||
|
unit: (varProps.length > 4 ? varProps[4] : valueUnit)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,25 +63,40 @@ Item {
|
||||||
var UPDATE_CANVAS_RATE = 20;
|
var UPDATE_CANVAS_RATE = 20;
|
||||||
tick++;
|
tick++;
|
||||||
|
|
||||||
valueMax = 0
|
|
||||||
|
var currentValueMax = 0
|
||||||
for (var i = 0; i < _values.length; i++) {
|
for (var i = 0; i < _values.length; i++) {
|
||||||
var currentVal = stats.config[_values[i].value];
|
|
||||||
if (_values[i].valueMax < currentVal) {
|
var currentVal = stats.config[_values[i].value] * _values[i].scale;
|
||||||
_values[i].valueMax = currentVal;
|
|
||||||
}
|
|
||||||
_values[i].valueHistory.push(currentVal)
|
_values[i].valueHistory.push(currentVal)
|
||||||
|
_values[i].numSamplesConstantMax++;
|
||||||
|
|
||||||
if (_values[i].valueHistory.length > VALUE_HISTORY_SIZE) {
|
if (_values[i].valueHistory.length > VALUE_HISTORY_SIZE) {
|
||||||
var lostValue = _values[i].valueHistory.shift();
|
var lostValue = _values[i].valueHistory.shift();
|
||||||
if (lostValue >= _values[i].valueMax) {
|
if (lostValue >= _values[i].valueMax) {
|
||||||
_values[i].valueMax *= 0.99
|
_values[i].valueMax *= 0.99
|
||||||
|
_values[i].numSamplesConstantMax = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valueMax < _values[i].valueMax) {
|
if (_values[i].valueMax < currentVal) {
|
||||||
valueMax = _values[i].valueMax
|
_values[i].valueMax = currentVal;
|
||||||
|
_values[i].numSamplesConstantMax = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_values[i].numSamplesConstantMax > VALUE_HISTORY_SIZE) {
|
||||||
|
_values[i].numSamplesConstantMax = 0
|
||||||
|
_values[i].valueMax *= 0.95 // lower slowly the current max if no new above max since a while
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentValueMax < _values[i].valueMax) {
|
||||||
|
currentValueMax = _values[i].valueMax
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((valueMax < currentValueMax) || (tick % VALUE_HISTORY_SIZE == 0)) {
|
||||||
|
valueMax = currentValueMax;
|
||||||
|
}
|
||||||
|
|
||||||
if (tick % UPDATE_CANVAS_RATE == 0) {
|
if (tick % UPDATE_CANVAS_RATE == 0) {
|
||||||
mycanvas.requestPaint()
|
mycanvas.requestPaint()
|
||||||
|
@ -91,20 +110,23 @@ Item {
|
||||||
onPaint: {
|
onPaint: {
|
||||||
var lineHeight = 12;
|
var lineHeight = 12;
|
||||||
|
|
||||||
function displayValue(val) {
|
function displayValue(val, unit) {
|
||||||
return (val / root.valueScale).toFixed(root.valueNumDigits) + " " + root.valueUnit
|
return (val / root.valueScale).toFixed(root.valueNumDigits) + " " + unit
|
||||||
}
|
}
|
||||||
|
|
||||||
function pixelFromVal(val) {
|
function pixelFromVal(val, valScale) {
|
||||||
return lineHeight + (height - lineHeight) * (1 - (0.9) * val / valueMax);
|
return lineHeight + (height - lineHeight) * (1 - (0.9) * val / valueMax);
|
||||||
}
|
}
|
||||||
|
function valueFromPixel(pixY) {
|
||||||
|
return ((pixY - lineHeight) / (height - lineHeight) - 1) * valueMax / (-0.9);
|
||||||
|
}
|
||||||
function plotValueHistory(ctx, valHistory, color) {
|
function plotValueHistory(ctx, valHistory, color) {
|
||||||
var widthStep= width / (valHistory.length - 1);
|
var widthStep= width / (valHistory.length - 1);
|
||||||
|
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.strokeStyle= color; // Green path
|
ctx.strokeStyle= color; // Green path
|
||||||
ctx.lineWidth="2";
|
ctx.lineWidth="2";
|
||||||
ctx.moveTo(0, pixelFromVal(valHistory[i]));
|
ctx.moveTo(0, pixelFromVal(valHistory[0]));
|
||||||
|
|
||||||
for (var i = 1; i < valHistory.length; i++) {
|
for (var i = 1; i < valHistory.length; i++) {
|
||||||
ctx.lineTo(i * widthStep, pixelFromVal(valHistory[i]));
|
ctx.lineTo(i * widthStep, pixelFromVal(valHistory[i]));
|
||||||
|
@ -116,27 +138,40 @@ Item {
|
||||||
ctx.fillStyle = val.color;
|
ctx.fillStyle = val.color;
|
||||||
var bestValue = val.valueHistory[val.valueHistory.length -1];
|
var bestValue = val.valueHistory[val.valueHistory.length -1];
|
||||||
ctx.textAlign = "right";
|
ctx.textAlign = "right";
|
||||||
ctx.fillText(displayValue(bestValue), width, height - num * lineHeight);
|
ctx.fillText(displayValue(bestValue, val.unit), width, (num + 2) * lineHeight * 1.5);
|
||||||
ctx.textAlign = "left";
|
ctx.textAlign = "left";
|
||||||
ctx.fillText(val.label, 0, height - num * lineHeight);
|
ctx.fillText(val.label, 0, (num + 2) * lineHeight * 1.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayTitle(ctx, text, maxVal) {
|
function displayTitle(ctx, text, maxVal) {
|
||||||
ctx.fillStyle = "grey";
|
ctx.fillStyle = "grey";
|
||||||
ctx.textAlign = "right";
|
ctx.textAlign = "right";
|
||||||
ctx.fillText(displayValue(maxVal), width, lineHeight);
|
ctx.fillText(displayValue(valueFromPixel(lineHeight), root.valueUnit), width, lineHeight);
|
||||||
|
|
||||||
ctx.fillStyle = "white";
|
ctx.fillStyle = "white";
|
||||||
ctx.textAlign = "left";
|
ctx.textAlign = "left";
|
||||||
ctx.fillText(text, 0, lineHeight);
|
ctx.fillText(text, 0, lineHeight);
|
||||||
}
|
}
|
||||||
|
function displayBackground(ctx) {
|
||||||
|
ctx.fillStyle = Qt.rgba(0, 0, 0, 0.6);
|
||||||
|
ctx.fillRect(0, 0, width, height);
|
||||||
|
|
||||||
|
ctx.strokeStyle= "grey";
|
||||||
|
ctx.lineWidth="2";
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(0, lineHeight + 1);
|
||||||
|
ctx.lineTo(width, lineHeight + 1);
|
||||||
|
ctx.moveTo(0, height);
|
||||||
|
ctx.lineTo(width, height);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
var ctx = getContext("2d");
|
var ctx = getContext("2d");
|
||||||
ctx.clearRect(0, 0, width, height);
|
ctx.clearRect(0, 0, width, height);
|
||||||
ctx.fillStyle = Qt.rgba(0, 0, 0, 0.4);
|
|
||||||
ctx.fillRect(0, 0, width, height);
|
|
||||||
|
|
||||||
ctx.font="12px Verdana";
|
ctx.font="12px Verdana";
|
||||||
|
|
||||||
|
displayBackground(ctx);
|
||||||
|
|
||||||
for (var i = 0; i < _values.length; i++) {
|
for (var i = 0; i < _values.length; i++) {
|
||||||
plotValueHistory(ctx, _values[i].valueHistory, _values[i].color)
|
plotValueHistory(ctx, _values[i].valueHistory, _values[i].color)
|
||||||
|
|
|
@ -12,40 +12,58 @@ import QtQuick 2.5
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
|
|
||||||
|
|
||||||
Column {
|
Item {
|
||||||
id: statsUI
|
id: statsUI
|
||||||
width: 300
|
anchors.fill:parent
|
||||||
spacing: 8
|
|
||||||
Column {
|
|
||||||
spacing: 8
|
|
||||||
|
|
||||||
property var config: Render.getConfig("Stats")
|
Column {
|
||||||
id: stats
|
id: stats
|
||||||
|
spacing: 8
|
||||||
|
anchors.fill:parent
|
||||||
|
|
||||||
|
property var config: Render.getConfig("Stats")
|
||||||
|
|
||||||
|
function evalEvenHeight() {
|
||||||
|
// Why do we have to do that manually ? cannot seem to find a qml / anchor / layout mode that does that ?
|
||||||
|
return (height - spacing * (children.length - 1)) / children.length
|
||||||
|
}
|
||||||
|
|
||||||
PlotPerf {
|
PlotPerf {
|
||||||
title: "Num Buffers"
|
title: "Num Buffers"
|
||||||
width:statsUI.width
|
|
||||||
config: stats.config
|
config: stats.config
|
||||||
|
height: parent.evalEvenHeight()
|
||||||
parameters: "1::0:CPU-numBuffers-#00B4EF:GPU-numGPUBuffers-#1AC567"
|
parameters: "1::0:CPU-numBuffers-#00B4EF:GPU-numGPUBuffers-#1AC567"
|
||||||
}
|
}
|
||||||
PlotPerf {
|
PlotPerf {
|
||||||
title: "Memory Usage"
|
title: "gpu::Buffer Memory"
|
||||||
width:statsUI.width
|
|
||||||
config: stats.config
|
config: stats.config
|
||||||
|
height: parent.evalEvenHeight()
|
||||||
parameters: "1048576:Mb:1:CPU-bufferSysmemUsage-#00B4EF:GPU-bufferVidmemUsage-#1AC567"
|
parameters: "1048576:Mb:1:CPU-bufferSysmemUsage-#00B4EF:GPU-bufferVidmemUsage-#1AC567"
|
||||||
}
|
}
|
||||||
|
|
||||||
PlotPerf {
|
PlotPerf {
|
||||||
title: "Num Textures"
|
title: "Num Textures"
|
||||||
width:statsUI.width
|
|
||||||
config: stats.config
|
config: stats.config
|
||||||
parameters: "1::0:CPU-numTextures-#00B4EF:GPU-numGPUTextures-#1AC567:Frame-numFrameTextures-#E2334D"
|
height: parent.evalEvenHeight()
|
||||||
|
parameters: "1::0:CPU-numTextures-#00B4EF:GPU-numGPUTextures-#1AC567:Frame-frameTextureCount-#E2334D"
|
||||||
}
|
}
|
||||||
PlotPerf {
|
PlotPerf {
|
||||||
title: "Memory Usage"
|
title: "gpu::Texture Memory"
|
||||||
width:statsUI.width
|
|
||||||
config: stats.config
|
config: stats.config
|
||||||
|
height: parent.evalEvenHeight()
|
||||||
parameters: "1048576:Mb:1:CPU-textureSysmemUsage-#00B4EF:GPU-textureVidmemUsage-#1AC567"
|
parameters: "1048576:Mb:1:CPU-textureSysmemUsage-#00B4EF:GPU-textureVidmemUsage-#1AC567"
|
||||||
}
|
}
|
||||||
|
PlotPerf {
|
||||||
|
title: "Drawcalls"
|
||||||
|
config: stats.config
|
||||||
|
height: parent.evalEvenHeight()
|
||||||
|
parameters: "1::0:frame-frameDrawcallCount-#E2334D:rate-frameDrawcallRate-#1AC567-0.001-K/s"
|
||||||
|
}
|
||||||
|
PlotPerf {
|
||||||
|
title: "Triangles"
|
||||||
|
config: stats.config
|
||||||
|
height: parent.evalEvenHeight()
|
||||||
|
parameters: "1000:K:0:frame-frameTriangleCount-#E2334D:rate-frameTriangleRate-#1AC567-0.001-MT/s"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ public:
|
||||||
|
|
||||||
int _DSNumDrawcalls = 0;
|
int _DSNumDrawcalls = 0;
|
||||||
int _DSNumTriangles = 0;
|
int _DSNumTriangles = 0;
|
||||||
|
|
||||||
ContextStats() {}
|
ContextStats() {}
|
||||||
ContextStats(const ContextStats& stats) = default;
|
ContextStats(const ContextStats& stats) = default;
|
||||||
};
|
};
|
||||||
|
|
|
@ -324,7 +324,10 @@ void GLBackend::do_draw(Batch& batch, size_t paramOffset) {
|
||||||
uint32 numVertices = batch._params[paramOffset + 1]._uint;
|
uint32 numVertices = batch._params[paramOffset + 1]._uint;
|
||||||
uint32 startVertex = batch._params[paramOffset + 0]._uint;
|
uint32 startVertex = batch._params[paramOffset + 0]._uint;
|
||||||
glDrawArrays(mode, startVertex, numVertices);
|
glDrawArrays(mode, startVertex, numVertices);
|
||||||
(void) CHECK_GL_ERROR();
|
_stats._DSNumTriangles += numVertices / 3;
|
||||||
|
_stats._DSNumDrawcalls++;
|
||||||
|
|
||||||
|
(void)CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::do_drawIndexed(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_drawIndexed(Batch& batch, size_t paramOffset) {
|
||||||
|
@ -339,6 +342,9 @@ void GLBackend::do_drawIndexed(Batch& batch, size_t paramOffset) {
|
||||||
GLvoid* indexBufferByteOffset = reinterpret_cast<GLvoid*>(startIndex * typeByteSize + _input._indexBufferOffset);
|
GLvoid* indexBufferByteOffset = reinterpret_cast<GLvoid*>(startIndex * typeByteSize + _input._indexBufferOffset);
|
||||||
|
|
||||||
glDrawElements(mode, numIndices, glType, indexBufferByteOffset);
|
glDrawElements(mode, numIndices, glType, indexBufferByteOffset);
|
||||||
|
_stats._DSNumTriangles += numIndices / 3;
|
||||||
|
_stats._DSNumDrawcalls++;
|
||||||
|
|
||||||
(void) CHECK_GL_ERROR();
|
(void) CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,6 +356,9 @@ void GLBackend::do_drawInstanced(Batch& batch, size_t paramOffset) {
|
||||||
uint32 startVertex = batch._params[paramOffset + 1]._uint;
|
uint32 startVertex = batch._params[paramOffset + 1]._uint;
|
||||||
|
|
||||||
glDrawArraysInstancedARB(mode, startVertex, numVertices, numInstances);
|
glDrawArraysInstancedARB(mode, startVertex, numVertices, numInstances);
|
||||||
|
_stats._DSNumTriangles += (numInstances * numVertices) / 3;
|
||||||
|
_stats._DSNumDrawcalls += numInstances;
|
||||||
|
|
||||||
(void) CHECK_GL_ERROR();
|
(void) CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,6 +381,9 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, size_t paramOffset) {
|
||||||
glDrawElementsInstanced(mode, numIndices, glType, indexBufferByteOffset, numInstances);
|
glDrawElementsInstanced(mode, numIndices, glType, indexBufferByteOffset, numInstances);
|
||||||
Q_UNUSED(startInstance);
|
Q_UNUSED(startInstance);
|
||||||
#endif
|
#endif
|
||||||
|
_stats._DSNumTriangles += (numInstances * numIndices) / 3;
|
||||||
|
_stats._DSNumDrawcalls += numInstances;
|
||||||
|
|
||||||
(void)CHECK_GL_ERROR();
|
(void)CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,6 +394,7 @@ void GLBackend::do_multiDrawIndirect(Batch& batch, size_t paramOffset) {
|
||||||
GLenum mode = _primitiveToGLmode[(Primitive)batch._params[paramOffset + 1]._uint];
|
GLenum mode = _primitiveToGLmode[(Primitive)batch._params[paramOffset + 1]._uint];
|
||||||
|
|
||||||
glMultiDrawArraysIndirect(mode, reinterpret_cast<GLvoid*>(_input._indirectBufferOffset), commandCount, (GLsizei)_input._indirectBufferStride);
|
glMultiDrawArraysIndirect(mode, reinterpret_cast<GLvoid*>(_input._indirectBufferOffset), commandCount, (GLsizei)_input._indirectBufferStride);
|
||||||
|
_stats._DSNumDrawcalls += commandCount;
|
||||||
#else
|
#else
|
||||||
// FIXME implement the slow path
|
// FIXME implement the slow path
|
||||||
#endif
|
#endif
|
||||||
|
@ -396,6 +409,8 @@ void GLBackend::do_multiDrawIndexedIndirect(Batch& batch, size_t paramOffset) {
|
||||||
GLenum indexType = _elementTypeToGLType[_input._indexBufferType];
|
GLenum indexType = _elementTypeToGLType[_input._indexBufferType];
|
||||||
|
|
||||||
glMultiDrawElementsIndirect(mode, indexType, reinterpret_cast<GLvoid*>(_input._indirectBufferOffset), commandCount, (GLsizei)_input._indirectBufferStride);
|
glMultiDrawElementsIndirect(mode, indexType, reinterpret_cast<GLvoid*>(_input._indirectBufferOffset), commandCount, (GLsizei)_input._indirectBufferStride);
|
||||||
|
_stats._DSNumDrawcalls += commandCount;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// FIXME implement the slow path
|
// FIXME implement the slow path
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include <gpu/Context.h>
|
#include <gpu/Context.h>
|
||||||
|
|
||||||
|
#include "EngineStats.h"
|
||||||
|
|
||||||
using namespace render;
|
using namespace render;
|
||||||
|
|
||||||
|
@ -61,28 +62,3 @@ void Engine::run() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <gpu/Texture.h>
|
|
||||||
void EngineStats::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
|
||||||
const size_t KILO_BYTES = 1024;
|
|
||||||
// Update the stats
|
|
||||||
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
|
|
||||||
|
|
||||||
config->numBuffers = gpu::Buffer::getCurrentNumBuffers();
|
|
||||||
config->numGPUBuffers = gpu::Buffer::getCurrentNumGPUBuffers();
|
|
||||||
config->bufferSysmemUsage = gpu::Buffer::getCurrentSystemMemoryUsage();
|
|
||||||
config->bufferVidmemUsage = gpu::Buffer::getCurrentVideoMemoryUsage();
|
|
||||||
|
|
||||||
config->numTextures = gpu::Texture::getCurrentNumTextures();
|
|
||||||
config->numGPUTextures = gpu::Texture::getCurrentNumGPUTextures();
|
|
||||||
config->textureSysmemUsage = gpu::Texture::getCurrentSystemMemoryUsage();
|
|
||||||
config->textureVidmemUsage = gpu::Texture::getCurrentVideoMemoryUsage();
|
|
||||||
|
|
||||||
gpu::ContextStats gpuStats(_gpuStats);
|
|
||||||
renderContext->args->_context->getStats(_gpuStats);
|
|
||||||
|
|
||||||
config->numFrameTextures = _gpuStats._RSNumTextureBounded - gpuStats._RSNumTextureBounded;
|
|
||||||
|
|
||||||
config->numFrameTriangles = _gpuStats._DSNumTriangles - gpuStats._DSNumTriangles;
|
|
||||||
|
|
||||||
config->emitDirty();
|
|
||||||
}
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#define hifi_render_Engine_h
|
#define hifi_render_Engine_h
|
||||||
|
|
||||||
#include <SettingHandle.h>
|
#include <SettingHandle.h>
|
||||||
#include <gpu/Context.h>
|
|
||||||
|
|
||||||
#include "Context.h"
|
#include "Context.h"
|
||||||
#include "Task.h"
|
#include "Task.h"
|
||||||
|
@ -49,57 +48,6 @@ namespace render {
|
||||||
};
|
};
|
||||||
using EnginePointer = std::shared_ptr<Engine>;
|
using EnginePointer = std::shared_ptr<Engine>;
|
||||||
|
|
||||||
|
|
||||||
// A simple job collecting global stats on the Engine / Scene / GPU
|
|
||||||
class EngineStatsConfig : public Job::Config{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
Q_PROPERTY(int numBuffers MEMBER numBuffers NOTIFY dirty)
|
|
||||||
Q_PROPERTY(int numGPUBuffers MEMBER numGPUBuffers NOTIFY dirty)
|
|
||||||
Q_PROPERTY(qint64 bufferSysmemUsage MEMBER bufferSysmemUsage NOTIFY dirty)
|
|
||||||
Q_PROPERTY(qint64 bufferVidmemUsage MEMBER bufferVidmemUsage NOTIFY dirty)
|
|
||||||
|
|
||||||
Q_PROPERTY(int numTextures MEMBER numTextures NOTIFY dirty)
|
|
||||||
Q_PROPERTY(int numGPUTextures MEMBER numGPUTextures NOTIFY dirty)
|
|
||||||
Q_PROPERTY(qint64 textureSysmemUsage MEMBER textureSysmemUsage NOTIFY dirty)
|
|
||||||
Q_PROPERTY(qint64 textureVidmemUsage MEMBER textureVidmemUsage NOTIFY dirty)
|
|
||||||
Q_PROPERTY(int numFrameTextures MEMBER numFrameTextures NOTIFY dirty)
|
|
||||||
public:
|
|
||||||
EngineStatsConfig() : Job::Config(true) {}
|
|
||||||
|
|
||||||
int numBuffers{ 0 };
|
|
||||||
int numGPUBuffers{ 0 };
|
|
||||||
qint64 bufferSysmemUsage{ 0 };
|
|
||||||
qint64 bufferVidmemUsage{ 0 };
|
|
||||||
|
|
||||||
int numTextures{ 0 };
|
|
||||||
int numGPUTextures{ 0 };
|
|
||||||
qint64 textureSysmemUsage{ 0 };
|
|
||||||
qint64 textureVidmemUsage{ 0 };
|
|
||||||
|
|
||||||
int numFrameTriangles{ 0 };
|
|
||||||
int numFrameTextures{ 0 };
|
|
||||||
|
|
||||||
void emitDirty() { emit dirty(); }
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void dirty();
|
|
||||||
};
|
|
||||||
|
|
||||||
class EngineStats {
|
|
||||||
public:
|
|
||||||
using Config = EngineStatsConfig;
|
|
||||||
using JobModel = Job::Model<EngineStats, Config>;
|
|
||||||
|
|
||||||
EngineStats() {}
|
|
||||||
|
|
||||||
gpu::ContextStats _gpuStats;
|
|
||||||
|
|
||||||
void configure(const Config& configuration) {}
|
|
||||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // hifi_render_Engine_h
|
#endif // hifi_render_Engine_h
|
||||||
|
|
50
libraries/render/src/render/EngineStats.cpp
Normal file
50
libraries/render/src/render/EngineStats.cpp
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
//
|
||||||
|
// EngineStats.cpp
|
||||||
|
// render/src/render
|
||||||
|
//
|
||||||
|
// Created by Sam Gateau on 3/27/16.
|
||||||
|
// Copyright 2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
#include "EngineStats.h"
|
||||||
|
|
||||||
|
#include <gpu/Texture.h>
|
||||||
|
|
||||||
|
using namespace render;
|
||||||
|
|
||||||
|
void EngineStats::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||||
|
// Tick time
|
||||||
|
|
||||||
|
quint64 msecsElapsed = _frameTimer.restart();
|
||||||
|
double frequency = 1000.0 / msecsElapsed;
|
||||||
|
|
||||||
|
|
||||||
|
// Update the stats
|
||||||
|
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
|
||||||
|
|
||||||
|
config->numBuffers = gpu::Buffer::getCurrentNumBuffers();
|
||||||
|
config->numGPUBuffers = gpu::Buffer::getCurrentNumGPUBuffers();
|
||||||
|
config->bufferSysmemUsage = gpu::Buffer::getCurrentSystemMemoryUsage();
|
||||||
|
config->bufferVidmemUsage = gpu::Buffer::getCurrentVideoMemoryUsage();
|
||||||
|
|
||||||
|
config->numTextures = gpu::Texture::getCurrentNumTextures();
|
||||||
|
config->numGPUTextures = gpu::Texture::getCurrentNumGPUTextures();
|
||||||
|
config->textureSysmemUsage = gpu::Texture::getCurrentSystemMemoryUsage();
|
||||||
|
config->textureVidmemUsage = gpu::Texture::getCurrentVideoMemoryUsage();
|
||||||
|
|
||||||
|
gpu::ContextStats gpuStats(_gpuStats);
|
||||||
|
renderContext->args->_context->getStats(_gpuStats);
|
||||||
|
|
||||||
|
config->frameDrawcallCount = _gpuStats._DSNumDrawcalls - gpuStats._DSNumDrawcalls;
|
||||||
|
config->frameDrawcallRate = config->frameDrawcallCount * frequency;
|
||||||
|
|
||||||
|
config->frameTriangleCount = _gpuStats._DSNumTriangles - gpuStats._DSNumTriangles;
|
||||||
|
config->frameTriangleRate = config->frameTriangleCount * frequency;
|
||||||
|
|
||||||
|
config->frameTextureCount = _gpuStats._RSNumTextureBounded - gpuStats._RSNumTextureBounded;
|
||||||
|
config->frameTextureRate = config->frameTextureCount * frequency;
|
||||||
|
|
||||||
|
config->emitDirty();
|
||||||
|
}
|
91
libraries/render/src/render/EngineStats.h
Normal file
91
libraries/render/src/render/EngineStats.h
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
//
|
||||||
|
// EngineStats.h
|
||||||
|
// render/src/render
|
||||||
|
//
|
||||||
|
// Created by Sam Gateau on 3/27/16.
|
||||||
|
// Copyright 2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_render_EngineStats_h
|
||||||
|
#define hifi_render_EngineStats_h
|
||||||
|
|
||||||
|
#include <gpu/Context.h>
|
||||||
|
|
||||||
|
#include <QElapsedTimer>
|
||||||
|
|
||||||
|
#include "Engine.h"
|
||||||
|
|
||||||
|
namespace render {
|
||||||
|
|
||||||
|
// A simple job collecting global stats on the Engine / Scene / GPU
|
||||||
|
class EngineStatsConfig : public Job::Config{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(int numBuffers MEMBER numBuffers NOTIFY dirty)
|
||||||
|
Q_PROPERTY(int numGPUBuffers MEMBER numGPUBuffers NOTIFY dirty)
|
||||||
|
Q_PROPERTY(qint64 bufferSysmemUsage MEMBER bufferSysmemUsage NOTIFY dirty)
|
||||||
|
Q_PROPERTY(qint64 bufferVidmemUsage MEMBER bufferVidmemUsage NOTIFY dirty)
|
||||||
|
|
||||||
|
Q_PROPERTY(int numTextures MEMBER numTextures NOTIFY dirty)
|
||||||
|
Q_PROPERTY(int numGPUTextures MEMBER numGPUTextures NOTIFY dirty)
|
||||||
|
Q_PROPERTY(qint64 textureSysmemUsage MEMBER textureSysmemUsage NOTIFY dirty)
|
||||||
|
Q_PROPERTY(qint64 textureVidmemUsage MEMBER textureVidmemUsage NOTIFY dirty)
|
||||||
|
|
||||||
|
Q_PROPERTY(int frameDrawcallCount MEMBER frameDrawcallCount NOTIFY dirty)
|
||||||
|
Q_PROPERTY(int frameDrawcallRate MEMBER frameDrawcallRate NOTIFY dirty)
|
||||||
|
|
||||||
|
Q_PROPERTY(int frameTriangleCount MEMBER frameTriangleCount NOTIFY dirty)
|
||||||
|
Q_PROPERTY(int frameTriangleRate MEMBER frameTriangleRate NOTIFY dirty)
|
||||||
|
|
||||||
|
Q_PROPERTY(int frameTextureCount MEMBER frameTextureCount NOTIFY dirty)
|
||||||
|
Q_PROPERTY(int frameTextureRate MEMBER frameTextureRate NOTIFY dirty)
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
EngineStatsConfig() : Job::Config(true) {}
|
||||||
|
|
||||||
|
int numBuffers{ 0 };
|
||||||
|
int numGPUBuffers{ 0 };
|
||||||
|
qint64 bufferSysmemUsage{ 0 };
|
||||||
|
qint64 bufferVidmemUsage{ 0 };
|
||||||
|
|
||||||
|
int numTextures{ 0 };
|
||||||
|
int numGPUTextures{ 0 };
|
||||||
|
qint64 textureSysmemUsage{ 0 };
|
||||||
|
qint64 textureVidmemUsage{ 0 };
|
||||||
|
|
||||||
|
int frameDrawcallCount{ 0 };
|
||||||
|
int frameDrawcallRate{ 0 };
|
||||||
|
|
||||||
|
int frameTriangleCount{ 0 };
|
||||||
|
int frameTriangleRate{ 0 };
|
||||||
|
|
||||||
|
int frameTextureCount{ 0 };
|
||||||
|
int frameTextureRate{ 0 };
|
||||||
|
|
||||||
|
void emitDirty() { emit dirty(); }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void dirty();
|
||||||
|
};
|
||||||
|
|
||||||
|
class EngineStats {
|
||||||
|
public:
|
||||||
|
using Config = EngineStatsConfig;
|
||||||
|
using JobModel = Job::Model<EngineStats, Config>;
|
||||||
|
|
||||||
|
EngineStats() { _frameTimer.start(); }
|
||||||
|
|
||||||
|
gpu::ContextStats _gpuStats;
|
||||||
|
|
||||||
|
void configure(const Config& configuration) {}
|
||||||
|
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
|
||||||
|
|
||||||
|
QElapsedTimer _frameTimer;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue