First draft of monitoring the memeory consumption

This commit is contained in:
samcake 2016-03-23 15:46:17 -07:00
parent de96e34f7e
commit 138a996013
10 changed files with 184 additions and 35 deletions

View file

@ -0,0 +1,20 @@
//
// renderStats.js
// examples/utilities/tools/render
//
// Sam Gateau, created on 3/22/2016.
// 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
//
// Set up the qml ui
var qml = Script.resolvePath('stats.qml');
var window = new OverlayWindow({
title: 'Render Stats',
source: qml,
width: 300
});
window.setPosition(500, 50);
window.closed.connect(function() { Script.stop(); });

View file

@ -0,0 +1,40 @@
//
// stats.qml
// examples/utilities/tools/render
//
// Created by Zach Pomerantz on 2/8/2016
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.5
import QtQuick.Controls 1.4
Column {
spacing: 8
Column {
id: stats
property var config: Render.getConfig("Stats")
Repeater {
model: [
"num Textures:numTextures",
"Sysmem Usage:textureSysmemUsage",
"num GPU Textures:numGPUTextures",
"Vidmem Usage:textureVidmemUsage"
]
Row {
Label {
text: qsTr(modelData.split(":")[0])
}
property var value: stats.config[modelData.split(":")[1]]
Label {
text: value
horizontalAlignment: AlignRight
}
}
}
}
}

View file

@ -268,7 +268,7 @@ public:
void run() override {
while (!_quit) {
QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS);
#ifdef NDEBUG
#ifdef ____NDEBUG
auto now = usecTimestampNow();
auto lastHeartbeatAge = now - _heartbeat;
if (lastHeartbeatAge > MAX_HEARTBEAT_AGE_USECS) {

View file

@ -72,12 +72,16 @@ public:
static GLuint getBufferID(const Buffer& buffer);
class GLTexture : public GPUObject {
GLuint _size;
public:
Stamp _storageStamp;
Stamp _contentStamp;
GLuint _texture;
GLenum _target;
GLuint _size;
void setSize(GLuint size);
GLuint size() const { return _size; }
GLTexture();
~GLTexture();

View file

@ -19,12 +19,29 @@ GLBackend::GLTexture::GLTexture() :
_texture(0),
_target(GL_TEXTURE_2D),
_size(0)
{}
{
Texture::_numGPUTextures++;
}
GLBackend::GLTexture::~GLTexture() {
if (_texture != 0) {
glDeleteTextures(1, &_texture);
}
Texture::_textureVideoMemoryUsage.fetch_sub(_size);
Texture::_numGPUTextures--;
}
void GLBackend::GLTexture::setSize(GLuint size) {
if (_size == size) {
return;
}
if (size > _size) {
Texture::_textureVideoMemoryUsage.fetch_add(size - _size);
} else {
Texture::_textureVideoMemoryUsage.fetch_sub(_size - size);
}
_size = size;
}
class GLTexelFormat {
@ -483,7 +500,7 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) {
object->_storageStamp = texture.getStamp();
object->_contentStamp = texture.getDataStamp();
object->_size = (GLuint)texture.getSize();
object->setSize((GLuint)texture.getSize());
}
glBindTexture(GL_TEXTURE_2D, boundTex);
@ -561,7 +578,7 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) {
object->_storageStamp = texture.getStamp();
object->_contentStamp = texture.getDataStamp();
object->_size = (GLuint)texture.getSize();
object->setSize((GLuint)texture.getSize());
}
glBindTexture(GL_TEXTURE_CUBE_MAP, boundTex);

View file

@ -17,12 +17,24 @@
using namespace gpu;
std::atomic<Texture::Size> Texture::_textureSystemMemoryUsage{ 0 };
std::atomic<Texture::Size> Texture::_textureVideoMemoryUsage{ 0 };
std::atomic<int> Texture::_numTextures{ 0 };
std::atomic<int> Texture::_numGPUTextures{ 0 };
std::atomic<unsigned long long> Texture::_textureSystemMemoryUsage{ 0 };
std::atomic<unsigned long long> Texture::_textureVideoMemoryUsage{ 0 };
int Texture::getCurrentNumTextures() {
return _numTextures.load();
}
Texture::Size Texture::getCurrentSystemMemoryUsage() {
return _textureSystemMemoryUsage.load();
}
int Texture::getCurrentNumGPUTextures() {
return _numGPUTextures.load();
}
Texture::Size Texture::getCurrentVideoMemoryUsage() {
return _textureVideoMemoryUsage.load();
}
@ -43,8 +55,6 @@ void Texture::updateSystemMemoryUsage(Size prevObjectSize, Size newObjectSize) {
} else {
addSystemMemoryUsage(newObjectSize - prevObjectSize);
}
qCDebug(gpulogging) << "Texture::SysMem = " << getCurrentSystemMemoryUsage();
}
void Texture::addVideoMemoryUsage(Size memorySize) {
@ -122,7 +132,7 @@ const Texture::PixelsPointer Texture::Storage::getMipFace(uint16 level, uint8 fa
void Texture::Storage::notifyMipFaceGPULoaded(uint16 level, uint8 face) const {
PixelsPointer mipFace = getMipFace(level, face);
// if (mipFace && (_type != TEX_CUBE)) {
if (mipFaced) {
if (mipFace) {
mipFace->notifyGPULoaded();
}
}
@ -229,10 +239,12 @@ Texture* Texture::createFromStorage(Storage* storage) {
Texture::Texture():
Resource()
{
_numTextures++;
}
Texture::~Texture()
{
_numTextures--;
}
Texture::Size Texture::resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices) {

View file

@ -139,9 +139,12 @@ protected:
};
class Texture : public Resource {
static std::atomic<int> _numTextures;
static std::atomic<Size> _textureSystemMemoryUsage;
public:
static std::atomic<int> _numGPUTextures;
static std::atomic<Size> _textureVideoMemoryUsage;
private:
static void addSystemMemoryUsage(Size memorySize);
static void subSystemMemoryUsage(Size memorySize);
static void updateSystemMemoryUsage(Size prevObjectSize, Size newObjectSize);
@ -151,7 +154,9 @@ class Texture : public Resource {
public:
static int getCurrentNumTextures();
static Size getCurrentSystemMemoryUsage();
static int getCurrentNumGPUTextures();
static Size getCurrentVideoMemoryUsage();
class Usage {

View file

@ -23,6 +23,7 @@ using namespace render;
Engine::Engine() :
_sceneContext(std::make_shared<SceneContext>()),
_renderContext(std::make_shared<RenderContext>()) {
addJob<EngineStats>("Stats");
}
void Engine::load() {
@ -57,4 +58,19 @@ void Engine::run() {
for (auto job : _jobs) {
job.run(_sceneContext, _renderContext);
}
}
#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->numTextures = gpu::Texture::getCurrentNumTextures();
config->textureSysmemUsage = gpu::Texture::getCurrentSystemMemoryUsage();
config->numGPUTextures = gpu::Texture::getCurrentNumGPUTextures();
config->textureVidmemUsage = gpu::Texture::getCurrentVideoMemoryUsage();
config->emitDirty();
}

View file

@ -19,34 +19,69 @@
namespace render {
// The render engine holds all render tasks, and is itself a render task.
// State flows through tasks to jobs via the render and scene contexts -
// the engine should not be known from its jobs.
class Engine : public Task {
public:
Engine();
~Engine() = default;
// The render engine holds all render tasks, and is itself a render task.
// State flows through tasks to jobs via the render and scene contexts -
// the engine should not be known from its jobs.
class Engine : public Task {
public:
// Load any persisted settings, and set up the presets
// This should be run after adding all jobs, and before building ui
void load();
Engine();
~Engine() = default;
// Register the scene
void registerScene(const ScenePointer& scene) { _sceneContext->_scene = scene; }
// Load any persisted settings, and set up the presets
// This should be run after adding all jobs, and before building ui
void load();
// Push a RenderContext
void setRenderContext(const RenderContext& renderContext) { (*_renderContext) = renderContext; }
RenderContextPointer getRenderContext() const { return _renderContext; }
// Register the scene
void registerScene(const ScenePointer& scene) { _sceneContext->_scene = scene; }
// Render a frame
// A frame must have a scene registered and a context set to render
void run();
// Push a RenderContext
void setRenderContext(const RenderContext& renderContext) { (*_renderContext) = renderContext; }
RenderContextPointer getRenderContext() const { return _renderContext; }
// Render a frame
// A frame must have a scene registered and a context set to render
void run();
protected:
SceneContextPointer _sceneContext;
RenderContextPointer _renderContext;
};
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 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)
public:
EngineStatsConfig() : Job::Config(true) {}
int numTextures{ 0 };
int numGPUTextures{ 0 };
qint64 textureSysmemUsage{ 0 };
qint64 textureVidmemUsage{ 0 };
void emitDirty() { emit dirty(); }
signals:
void dirty();
};
class EngineStats {
public:
using Config = EngineStatsConfig;
using JobModel = Job::Model<EngineStats, Config>;
EngineStats() {}
void configure(const Config& configuration) {}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
};
protected:
SceneContextPointer _sceneContext;
RenderContextPointer _renderContext;
};
using EnginePointer = std::shared_ptr<Engine>;
}

View file

@ -1,4 +1,4 @@
d//
//
// ScriptEngine.cpp
// libraries/script-engine/src
//