mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 18:30:42 +02:00
First draft of monitoring the memeory consumption
This commit is contained in:
parent
de96e34f7e
commit
138a996013
10 changed files with 184 additions and 35 deletions
20
examples/utilities/tools/render/renderStats.js
Normal file
20
examples/utilities/tools/render/renderStats.js
Normal 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(); });
|
40
examples/utilities/tools/render/stats.qml
Normal file
40
examples/utilities/tools/render/stats.qml
Normal 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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -268,7 +268,7 @@ public:
|
||||||
void run() override {
|
void run() override {
|
||||||
while (!_quit) {
|
while (!_quit) {
|
||||||
QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS);
|
QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS);
|
||||||
#ifdef NDEBUG
|
#ifdef ____NDEBUG
|
||||||
auto now = usecTimestampNow();
|
auto now = usecTimestampNow();
|
||||||
auto lastHeartbeatAge = now - _heartbeat;
|
auto lastHeartbeatAge = now - _heartbeat;
|
||||||
if (lastHeartbeatAge > MAX_HEARTBEAT_AGE_USECS) {
|
if (lastHeartbeatAge > MAX_HEARTBEAT_AGE_USECS) {
|
||||||
|
|
|
@ -72,12 +72,16 @@ public:
|
||||||
static GLuint getBufferID(const Buffer& buffer);
|
static GLuint getBufferID(const Buffer& buffer);
|
||||||
|
|
||||||
class GLTexture : public GPUObject {
|
class GLTexture : public GPUObject {
|
||||||
|
GLuint _size;
|
||||||
public:
|
public:
|
||||||
Stamp _storageStamp;
|
Stamp _storageStamp;
|
||||||
Stamp _contentStamp;
|
Stamp _contentStamp;
|
||||||
GLuint _texture;
|
GLuint _texture;
|
||||||
GLenum _target;
|
GLenum _target;
|
||||||
GLuint _size;
|
|
||||||
|
|
||||||
|
void setSize(GLuint size);
|
||||||
|
GLuint size() const { return _size; }
|
||||||
|
|
||||||
GLTexture();
|
GLTexture();
|
||||||
~GLTexture();
|
~GLTexture();
|
||||||
|
|
|
@ -19,12 +19,29 @@ GLBackend::GLTexture::GLTexture() :
|
||||||
_texture(0),
|
_texture(0),
|
||||||
_target(GL_TEXTURE_2D),
|
_target(GL_TEXTURE_2D),
|
||||||
_size(0)
|
_size(0)
|
||||||
{}
|
{
|
||||||
|
Texture::_numGPUTextures++;
|
||||||
|
}
|
||||||
|
|
||||||
GLBackend::GLTexture::~GLTexture() {
|
GLBackend::GLTexture::~GLTexture() {
|
||||||
if (_texture != 0) {
|
if (_texture != 0) {
|
||||||
glDeleteTextures(1, &_texture);
|
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 {
|
class GLTexelFormat {
|
||||||
|
@ -483,7 +500,7 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) {
|
||||||
|
|
||||||
object->_storageStamp = texture.getStamp();
|
object->_storageStamp = texture.getStamp();
|
||||||
object->_contentStamp = texture.getDataStamp();
|
object->_contentStamp = texture.getDataStamp();
|
||||||
object->_size = (GLuint)texture.getSize();
|
object->setSize((GLuint)texture.getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, boundTex);
|
glBindTexture(GL_TEXTURE_2D, boundTex);
|
||||||
|
@ -561,7 +578,7 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) {
|
||||||
|
|
||||||
object->_storageStamp = texture.getStamp();
|
object->_storageStamp = texture.getStamp();
|
||||||
object->_contentStamp = texture.getDataStamp();
|
object->_contentStamp = texture.getDataStamp();
|
||||||
object->_size = (GLuint)texture.getSize();
|
object->setSize((GLuint)texture.getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, boundTex);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, boundTex);
|
||||||
|
|
|
@ -17,12 +17,24 @@
|
||||||
|
|
||||||
using namespace gpu;
|
using namespace gpu;
|
||||||
|
|
||||||
std::atomic<Texture::Size> Texture::_textureSystemMemoryUsage{ 0 };
|
std::atomic<int> Texture::_numTextures{ 0 };
|
||||||
std::atomic<Texture::Size> Texture::_textureVideoMemoryUsage{ 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() {
|
Texture::Size Texture::getCurrentSystemMemoryUsage() {
|
||||||
return _textureSystemMemoryUsage.load();
|
return _textureSystemMemoryUsage.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Texture::getCurrentNumGPUTextures() {
|
||||||
|
return _numGPUTextures.load();
|
||||||
|
}
|
||||||
|
|
||||||
Texture::Size Texture::getCurrentVideoMemoryUsage() {
|
Texture::Size Texture::getCurrentVideoMemoryUsage() {
|
||||||
return _textureVideoMemoryUsage.load();
|
return _textureVideoMemoryUsage.load();
|
||||||
}
|
}
|
||||||
|
@ -43,8 +55,6 @@ void Texture::updateSystemMemoryUsage(Size prevObjectSize, Size newObjectSize) {
|
||||||
} else {
|
} else {
|
||||||
addSystemMemoryUsage(newObjectSize - prevObjectSize);
|
addSystemMemoryUsage(newObjectSize - prevObjectSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(gpulogging) << "Texture::SysMem = " << getCurrentSystemMemoryUsage();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::addVideoMemoryUsage(Size memorySize) {
|
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 {
|
void Texture::Storage::notifyMipFaceGPULoaded(uint16 level, uint8 face) const {
|
||||||
PixelsPointer mipFace = getMipFace(level, face);
|
PixelsPointer mipFace = getMipFace(level, face);
|
||||||
// if (mipFace && (_type != TEX_CUBE)) {
|
// if (mipFace && (_type != TEX_CUBE)) {
|
||||||
if (mipFaced) {
|
if (mipFace) {
|
||||||
mipFace->notifyGPULoaded();
|
mipFace->notifyGPULoaded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,10 +239,12 @@ Texture* Texture::createFromStorage(Storage* storage) {
|
||||||
Texture::Texture():
|
Texture::Texture():
|
||||||
Resource()
|
Resource()
|
||||||
{
|
{
|
||||||
|
_numTextures++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::~Texture()
|
Texture::~Texture()
|
||||||
{
|
{
|
||||||
|
_numTextures--;
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::Size Texture::resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices) {
|
Texture::Size Texture::resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices) {
|
||||||
|
|
|
@ -139,9 +139,12 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
class Texture : public Resource {
|
class Texture : public Resource {
|
||||||
|
static std::atomic<int> _numTextures;
|
||||||
static std::atomic<Size> _textureSystemMemoryUsage;
|
static std::atomic<Size> _textureSystemMemoryUsage;
|
||||||
|
public:
|
||||||
|
static std::atomic<int> _numGPUTextures;
|
||||||
static std::atomic<Size> _textureVideoMemoryUsage;
|
static std::atomic<Size> _textureVideoMemoryUsage;
|
||||||
|
private:
|
||||||
static void addSystemMemoryUsage(Size memorySize);
|
static void addSystemMemoryUsage(Size memorySize);
|
||||||
static void subSystemMemoryUsage(Size memorySize);
|
static void subSystemMemoryUsage(Size memorySize);
|
||||||
static void updateSystemMemoryUsage(Size prevObjectSize, Size newObjectSize);
|
static void updateSystemMemoryUsage(Size prevObjectSize, Size newObjectSize);
|
||||||
|
@ -151,7 +154,9 @@ class Texture : public Resource {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
static int getCurrentNumTextures();
|
||||||
static Size getCurrentSystemMemoryUsage();
|
static Size getCurrentSystemMemoryUsage();
|
||||||
|
static int getCurrentNumGPUTextures();
|
||||||
static Size getCurrentVideoMemoryUsage();
|
static Size getCurrentVideoMemoryUsage();
|
||||||
|
|
||||||
class Usage {
|
class Usage {
|
||||||
|
|
|
@ -23,6 +23,7 @@ using namespace render;
|
||||||
Engine::Engine() :
|
Engine::Engine() :
|
||||||
_sceneContext(std::make_shared<SceneContext>()),
|
_sceneContext(std::make_shared<SceneContext>()),
|
||||||
_renderContext(std::make_shared<RenderContext>()) {
|
_renderContext(std::make_shared<RenderContext>()) {
|
||||||
|
addJob<EngineStats>("Stats");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::load() {
|
void Engine::load() {
|
||||||
|
@ -57,4 +58,19 @@ void Engine::run() {
|
||||||
for (auto job : _jobs) {
|
for (auto job : _jobs) {
|
||||||
job.run(_sceneContext, _renderContext);
|
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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,34 +19,69 @@
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
||||||
// The render engine holds all render tasks, and is itself a render task.
|
// 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 -
|
// State flows through tasks to jobs via the render and scene contexts -
|
||||||
// the engine should not be known from its jobs.
|
// the engine should not be known from its jobs.
|
||||||
class Engine : public Task {
|
class Engine : public Task {
|
||||||
public:
|
public:
|
||||||
Engine();
|
|
||||||
~Engine() = default;
|
|
||||||
|
|
||||||
// Load any persisted settings, and set up the presets
|
Engine();
|
||||||
// This should be run after adding all jobs, and before building ui
|
~Engine() = default;
|
||||||
void load();
|
|
||||||
|
|
||||||
// Register the scene
|
// Load any persisted settings, and set up the presets
|
||||||
void registerScene(const ScenePointer& scene) { _sceneContext->_scene = scene; }
|
// This should be run after adding all jobs, and before building ui
|
||||||
|
void load();
|
||||||
|
|
||||||
// Push a RenderContext
|
// Register the scene
|
||||||
void setRenderContext(const RenderContext& renderContext) { (*_renderContext) = renderContext; }
|
void registerScene(const ScenePointer& scene) { _sceneContext->_scene = scene; }
|
||||||
RenderContextPointer getRenderContext() const { return _renderContext; }
|
|
||||||
|
|
||||||
// Render a frame
|
// Push a RenderContext
|
||||||
// A frame must have a scene registered and a context set to render
|
void setRenderContext(const RenderContext& renderContext) { (*_renderContext) = renderContext; }
|
||||||
void run();
|
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>;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
d//
|
//
|
||||||
// ScriptEngine.cpp
|
// ScriptEngine.cpp
|
||||||
// libraries/script-engine/src
|
// libraries/script-engine/src
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue