From 24b26e3097fc781efd72f3a1507dba25aa9aa025 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 22 Mar 2016 19:18:46 -0700 Subject: [PATCH 01/13] first few elements --- libraries/gpu/src/gpu/Texture.cpp | 36 +++++++++++++++++++++++++++++-- libraries/gpu/src/gpu/Texture.h | 20 ++++++++++++++++- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 3f2415d240..8b219a55de 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -17,6 +17,30 @@ using namespace gpu; +std::atomic Texture::_textureSystemMemoryUsage; +std::atomic Texture::_textureVideoMemoryUsage; + +uint32_t Texture::getCurrentSystemMemoryUsage() { + return _textureSystemMemoryUsage.load(); +} +uint32_t Texture::getCurrentVideoMemoryUsage() { + return _textureVideoMemoryUsage.load(); +} + +void Texture::addSystemMemoryUsage(uint32_t memorySize) { + _textureSystemMemoryUsage.fetch_add(memorySize); +} +void Texture::subSystemMemoryUsage(uint32_t memorySize) { + _textureSystemMemoryUsage.fetch_sub(memorySize); +} + +void Texture::addVideoMemoryUsage(uint32_t memorySize) { + _textureVideoMemoryUsage.fetch_add(memorySize); +} +void Texture::subVideoMemoryUsage(uint32_t memorySize) { + _textureVideoMemoryUsage.fetch_sub(memorySize); +} + uint8 Texture::NUM_FACES_PER_TYPE[NUM_TYPES] = {1, 1, 1, 6}; Texture::Pixels::Pixels(const Element& format, Size size, const Byte* bytes) : @@ -28,6 +52,15 @@ Texture::Pixels::Pixels(const Element& format, Size size, const Byte* bytes) : Texture::Pixels::~Pixels() { } +Texture::Size Texture::Pixels::resize(Size pSize) { + return _sysmem.resize(pSize); +} + +void Texture::Pixels::notifyGPULoaded() { + _isGPULoaded = true; + _sysmem.resize(0); +} + void Texture::Storage::assignTexture(Texture* texture) { _texture = texture; if (_texture) { @@ -60,8 +93,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)) { - mipFace->_isGPULoaded = true; - mipFace->_sysmem.resize(0); + mipFace->notifyGPULoaded(); } } diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index e05dc84c25..106b179f69 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -15,6 +15,7 @@ #include //min max and more #include +#include #include @@ -138,8 +139,20 @@ protected: }; class Texture : public Resource { + static std::atomic _textureSystemMemoryUsage; + static std::atomic _textureVideoMemoryUsage; + + void addSystemMemoryUsage(uint32_t memorySize); + void subSystemMemoryUsage(uint32_t memorySize); + + void addVideoMemoryUsage(uint32_t memorySize); + void subVideoMemoryUsage(uint32_t memorySize); + public: + uint32_t getCurrentSystemMemoryUsage(); + uint32_t getCurrentVideoMemoryUsage(); + class Usage { public: enum FlagBit { @@ -194,8 +207,13 @@ public: Pixels(const Element& format, Size size, const Byte* bytes); ~Pixels(); - Sysmem _sysmem; + Size getSize() const { return _sysmem.getSize(); } + Size resize(Size pSize); + void notifyGPULoaded(); + + protected: Element _format; + Sysmem _sysmem; bool _isGPULoaded; }; typedef std::shared_ptr< Pixels > PixelsPointer; From b29ef7b037dcb04110f1fec77469d2af0ffaee3d Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 23 Mar 2016 09:45:38 -0700 Subject: [PATCH 02/13] IMplementing a memory counter --- libraries/gpu/src/gpu/GLBackendTexture.cpp | 16 ++-- libraries/gpu/src/gpu/Texture.cpp | 84 +++++++++++++------- libraries/gpu/src/gpu/Texture.h | 26 +++--- libraries/script-engine/src/ScriptEngine.cpp | 2 +- 4 files changed, 81 insertions(+), 47 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index a70904a4bf..fe3c6cd6d1 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -427,8 +427,8 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { if (needUpdate) { if (texture.isStoredMipFaceAvailable(0)) { Texture::PixelsPointer mip = texture.accessStoredMipFace(0); - const GLvoid* bytes = mip->_sysmem.read(); - Element srcFormat = mip->_format; + const GLvoid* bytes = mip->readData(); + Element srcFormat = mip->getFormat(); GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(texture.getTexelFormat(), srcFormat); @@ -458,8 +458,8 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { if (texture.isStoredMipFaceAvailable(0)) { Texture::PixelsPointer mip = texture.accessStoredMipFace(0); - bytes = mip->_sysmem.read(); - srcFormat = mip->_format; + bytes = mip->readData(); + srcFormat = mip->getFormat(); object->_contentStamp = texture.getDataStamp(); } @@ -507,11 +507,11 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { for (int f = 0; f < NUM_FACES; f++) { if (texture.isStoredMipFaceAvailable(0, f)) { Texture::PixelsPointer mipFace = texture.accessStoredMipFace(0, f); - Element srcFormat = mipFace->_format; + Element srcFormat = mipFace->getFormat(); GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(texture.getTexelFormat(), srcFormat); glTexSubImage2D(FACE_LAYOUT[f], 0, texelFormat.internalFormat, texture.getWidth(), texture.getWidth(), 0, - texelFormat.format, texelFormat.type, (GLvoid*) (mipFace->_sysmem.read())); + texelFormat.format, texelFormat.type, (GLvoid*) (mipFace->readData())); // At this point the mip pixels have been loaded, we can notify texture.notifyMipFaceGPULoaded(0, f); @@ -536,11 +536,11 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { for (int f = 0; f < NUM_FACES; f++) { if (texture.isStoredMipFaceAvailable(0, f)) { Texture::PixelsPointer mipFace = texture.accessStoredMipFace(0, f); - Element srcFormat = mipFace->_format; + Element srcFormat = mipFace->getFormat(); GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(texture.getTexelFormat(), srcFormat); glTexImage2D(FACE_LAYOUT[f], 0, texelFormat.internalFormat, texture.getWidth(), texture.getWidth(), 0, - texelFormat.format, texelFormat.type, (GLvoid*) (mipFace->_sysmem.read())); + texelFormat.format, texelFormat.type, (GLvoid*) (mipFace->readData())); // At this point the mip pixels have been loaded, we can notify texture.notifyMipFaceGPULoaded(0, f); diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 8b219a55de..7f697c223d 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -12,53 +12,82 @@ #include "Texture.h" #include - -#include +#include "GPULogging.h" +//#include using namespace gpu; -std::atomic Texture::_textureSystemMemoryUsage; -std::atomic Texture::_textureVideoMemoryUsage; +std::atomic Texture::_textureSystemMemoryUsage{ 0 }; +std::atomic Texture::_textureVideoMemoryUsage{ 0 }; -uint32_t Texture::getCurrentSystemMemoryUsage() { +Texture::Size Texture::getCurrentSystemMemoryUsage() { return _textureSystemMemoryUsage.load(); } -uint32_t Texture::getCurrentVideoMemoryUsage() { +Texture::Size Texture::getCurrentVideoMemoryUsage() { return _textureVideoMemoryUsage.load(); } -void Texture::addSystemMemoryUsage(uint32_t memorySize) { +void Texture::addSystemMemoryUsage(Size memorySize) { _textureSystemMemoryUsage.fetch_add(memorySize); } -void Texture::subSystemMemoryUsage(uint32_t memorySize) { +void Texture::subSystemMemoryUsage(Size memorySize) { _textureSystemMemoryUsage.fetch_sub(memorySize); } -void Texture::addVideoMemoryUsage(uint32_t memorySize) { +void Texture::updateSystemMemoryUsage(Size prevObjectSize, Size newObjectSize) { + if (prevObjectSize == newObjectSize) { + return; + } + if (prevObjectSize > newObjectSize) { + subSystemMemoryUsage(prevObjectSize - newObjectSize); + } else { + addSystemMemoryUsage(newObjectSize - prevObjectSize); + } + + qCDebug(gpulogging) << "Texture::SysMem = " << getCurrentSystemMemoryUsage(); +} + +void Texture::addVideoMemoryUsage(Size memorySize) { _textureVideoMemoryUsage.fetch_add(memorySize); } -void Texture::subVideoMemoryUsage(uint32_t memorySize) { +void Texture::subVideoMemoryUsage(Size memorySize) { _textureVideoMemoryUsage.fetch_sub(memorySize); } uint8 Texture::NUM_FACES_PER_TYPE[NUM_TYPES] = {1, 1, 1, 6}; Texture::Pixels::Pixels(const Element& format, Size size, const Byte* bytes) : - _sysmem(size, bytes), _format(format), + _sysmem(size, bytes), _isGPULoaded(false) { + Texture::updateSystemMemoryUsage(0, _sysmem.getSize()); } Texture::Pixels::~Pixels() { + Texture::updateSystemMemoryUsage(_sysmem.getSize(), 0); } Texture::Size Texture::Pixels::resize(Size pSize) { - return _sysmem.resize(pSize); + auto prevSize = _sysmem.getSize(); + auto newSize = _sysmem.resize(pSize); + Texture::updateSystemMemoryUsage(prevSize, newSize); + return newSize; +} + +Texture::Size Texture::Pixels::setData(const Element& format, Size size, const Byte* bytes ) { + _format = format; + auto prevSize = _sysmem.getSize(); + auto newSize = _sysmem.setData(size, bytes); + Texture::updateSystemMemoryUsage(prevSize, newSize); + _isGPULoaded = false; + return newSize; } void Texture::Pixels::notifyGPULoaded() { _isGPULoaded = true; - _sysmem.resize(0); + auto prevSize = _sysmem.getSize(); + auto newSize = _sysmem.resize(0); + Texture::updateSystemMemoryUsage(prevSize, newSize); } void Texture::Storage::assignTexture(Texture* texture) { @@ -92,14 +121,15 @@ 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)) { - mipFace->notifyGPULoaded(); + // if (mipFace && (_type != TEX_CUBE)) { + if (mipFaced) { + mipFace->notifyGPULoaded(); } } bool Texture::Storage::isMipAvailable(uint16 level, uint8 face) const { PixelsPointer mipFace = getMipFace(level, face); - return (mipFace && mipFace->_sysmem.getSize()); + return (mipFace && mipFace->getSize()); } bool Texture::Storage::allocateMip(uint16 level) { @@ -135,9 +165,7 @@ bool Texture::Storage::assignMipData(uint16 level, const Element& format, Size s auto faceBytes = bytes; Size allocated = 0; for (auto& face : mip) { - face->_format = format; - allocated += face->_sysmem.setData(sizePerFace, faceBytes); - face->_isGPULoaded = false; + allocated += face->setData(format, sizePerFace, faceBytes); faceBytes += sizePerFace; } @@ -154,9 +182,7 @@ bool Texture::Storage::assignMipFaceData(uint16 level, const Element& format, Si Size allocated = 0; if (face < mip.size()) { auto mipFace = mip[face]; - mipFace->_format = format; - allocated += mipFace->_sysmem.setData(size, bytes); - mipFace->_isGPULoaded = false; + allocated += mipFace->setData(format, size, bytes); bumpStamp(); } @@ -396,7 +422,7 @@ uint16 Texture::autoGenerateMips(uint16 maxMip) { uint16 Texture::getStoredMipWidth(uint16 level) const { PixelsPointer mipFace = accessStoredMipFace(level); - if (mipFace && mipFace->_sysmem.getSize()) { + if (mipFace && mipFace->getSize()) { return evalMipWidth(level); } return 0; @@ -404,7 +430,7 @@ uint16 Texture::getStoredMipWidth(uint16 level) const { uint16 Texture::getStoredMipHeight(uint16 level) const { PixelsPointer mip = accessStoredMipFace(level); - if (mip && mip->_sysmem.getSize()) { + if (mip && mip->getSize()) { return evalMipHeight(level); } return 0; @@ -412,7 +438,7 @@ uint16 Texture::getStoredMipHeight(uint16 level) const { uint16 Texture::getStoredMipDepth(uint16 level) const { PixelsPointer mipFace = accessStoredMipFace(level); - if (mipFace && mipFace->_sysmem.getSize()) { + if (mipFace && mipFace->getSize()) { return evalMipDepth(level); } return 0; @@ -420,7 +446,7 @@ uint16 Texture::getStoredMipDepth(uint16 level) const { uint32 Texture::getStoredMipNumTexels(uint16 level) const { PixelsPointer mipFace = accessStoredMipFace(level); - if (mipFace && mipFace->_sysmem.getSize()) { + if (mipFace && mipFace->getSize()) { return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level); } return 0; @@ -428,7 +454,7 @@ uint32 Texture::getStoredMipNumTexels(uint16 level) const { uint32 Texture::getStoredMipSize(uint16 level) const { PixelsPointer mipFace = accessStoredMipFace(level); - if (mipFace && mipFace->_sysmem.getSize()) { + if (mipFace && mipFace->getSize()) { return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level) * getTexelFormat().getSize(); } return 0; @@ -674,8 +700,8 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector< // for each face of cube texture for(int face=0; face < gpu::Texture::NUM_CUBE_FACES; face++) { - auto numComponents = cubeTexture.accessStoredMipFace(0,face)->_format.getScalarCount(); - auto data = cubeTexture.accessStoredMipFace(0,face)->_sysmem.readData(); + auto numComponents = cubeTexture.accessStoredMipFace(0,face)->getFormat().getScalarCount(); + auto data = cubeTexture.accessStoredMipFace(0,face)->readData(); if (data == nullptr) { continue; } diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 106b179f69..b5a6f5ed7c 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -139,19 +139,20 @@ protected: }; class Texture : public Resource { - static std::atomic _textureSystemMemoryUsage; - static std::atomic _textureVideoMemoryUsage; + static std::atomic _textureSystemMemoryUsage; + static std::atomic _textureVideoMemoryUsage; - void addSystemMemoryUsage(uint32_t memorySize); - void subSystemMemoryUsage(uint32_t memorySize); + static void addSystemMemoryUsage(Size memorySize); + static void subSystemMemoryUsage(Size memorySize); + static void updateSystemMemoryUsage(Size prevObjectSize, Size newObjectSize); - void addVideoMemoryUsage(uint32_t memorySize); - void subVideoMemoryUsage(uint32_t memorySize); + static void addVideoMemoryUsage(Size memorySize); + static void subVideoMemoryUsage(Size memorySize); public: - uint32_t getCurrentSystemMemoryUsage(); - uint32_t getCurrentVideoMemoryUsage(); + static Size getCurrentSystemMemoryUsage(); + static Size getCurrentVideoMemoryUsage(); class Usage { public: @@ -207,14 +208,21 @@ public: Pixels(const Element& format, Size size, const Byte* bytes); ~Pixels(); + const Byte* readData() const { return _sysmem.readData(); } Size getSize() const { return _sysmem.getSize(); } Size resize(Size pSize); + Size setData(const Element& format, Size size, const Byte* bytes ); + + const Element& getFormat() const { return _format; } + void notifyGPULoaded(); - + protected: Element _format; Sysmem _sysmem; bool _isGPULoaded; + + friend class Texture; }; typedef std::shared_ptr< Pixels > PixelsPointer; diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 61ebfe4515..e17332a20f 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -1,4 +1,4 @@ -// +d// // ScriptEngine.cpp // libraries/script-engine/src // From 138a9960137d2f4343a872e9735eb4762df1e52c Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 23 Mar 2016 15:46:17 -0700 Subject: [PATCH 03/13] First draft of monitoring the memeory consumption --- .../utilities/tools/render/renderStats.js | 20 +++++ examples/utilities/tools/render/stats.qml | 40 +++++++++ interface/src/Application.cpp | 2 +- libraries/gpu/src/gpu/GLBackend.h | 6 +- libraries/gpu/src/gpu/GLBackendTexture.cpp | 23 +++++- libraries/gpu/src/gpu/Texture.cpp | 22 +++-- libraries/gpu/src/gpu/Texture.h | 7 +- libraries/render/src/render/Engine.cpp | 16 ++++ libraries/render/src/render/Engine.h | 81 +++++++++++++------ libraries/script-engine/src/ScriptEngine.cpp | 2 +- 10 files changed, 184 insertions(+), 35 deletions(-) create mode 100644 examples/utilities/tools/render/renderStats.js create mode 100644 examples/utilities/tools/render/stats.qml diff --git a/examples/utilities/tools/render/renderStats.js b/examples/utilities/tools/render/renderStats.js new file mode 100644 index 0000000000..da12ad1b31 --- /dev/null +++ b/examples/utilities/tools/render/renderStats.js @@ -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(); }); \ No newline at end of file diff --git a/examples/utilities/tools/render/stats.qml b/examples/utilities/tools/render/stats.qml new file mode 100644 index 0000000000..eb7bb44a73 --- /dev/null +++ b/examples/utilities/tools/render/stats.qml @@ -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 + } + + } + } + } +} diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 65a8f83871..61d92cebe7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -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) { diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 39b54c109b..d93962f5a1 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -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(); diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index fe3c6cd6d1..6a96c5a651 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -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); diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 7f697c223d..7a0e198ec9 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -17,12 +17,24 @@ using namespace gpu; -std::atomic Texture::_textureSystemMemoryUsage{ 0 }; -std::atomic Texture::_textureVideoMemoryUsage{ 0 }; +std::atomic Texture::_numTextures{ 0 }; +std::atomic Texture::_numGPUTextures{ 0 }; +std::atomic Texture::_textureSystemMemoryUsage{ 0 }; +std::atomic 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) { diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index b5a6f5ed7c..06b0077458 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -139,9 +139,12 @@ protected: }; class Texture : public Resource { + static std::atomic _numTextures; static std::atomic _textureSystemMemoryUsage; +public: + static std::atomic _numGPUTextures; static std::atomic _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 { diff --git a/libraries/render/src/render/Engine.cpp b/libraries/render/src/render/Engine.cpp index 806c964ec0..2118c3c734 100644 --- a/libraries/render/src/render/Engine.cpp +++ b/libraries/render/src/render/Engine.cpp @@ -23,6 +23,7 @@ using namespace render; Engine::Engine() : _sceneContext(std::make_shared()), _renderContext(std::make_shared()) { + addJob("Stats"); } void Engine::load() { @@ -57,4 +58,19 @@ void Engine::run() { for (auto job : _jobs) { job.run(_sceneContext, _renderContext); } + +} + +#include +void EngineStats::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + const size_t KILO_BYTES = 1024; + // Update the stats + auto config = std::static_pointer_cast(renderContext->jobConfig); + + config->numTextures = gpu::Texture::getCurrentNumTextures(); + config->textureSysmemUsage = gpu::Texture::getCurrentSystemMemoryUsage(); + config->numGPUTextures = gpu::Texture::getCurrentNumGPUTextures(); + config->textureVidmemUsage = gpu::Texture::getCurrentVideoMemoryUsage(); + + config->emitDirty(); } diff --git a/libraries/render/src/render/Engine.h b/libraries/render/src/render/Engine.h index 1af0e6d76f..71c52c5910 100644 --- a/libraries/render/src/render/Engine.h +++ b/libraries/render/src/render/Engine.h @@ -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; + + + // 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() {} + + void configure(const Config& configuration) {} + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + }; -protected: - SceneContextPointer _sceneContext; - RenderContextPointer _renderContext; -}; -using EnginePointer = std::shared_ptr; } diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index e17332a20f..61ebfe4515 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -1,4 +1,4 @@ -d// +// // ScriptEngine.cpp // libraries/script-engine/src // From 851cbb1c4611334e68c5f861db56f51f16b7d149 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 23 Mar 2016 16:07:41 -0700 Subject: [PATCH 04/13] change --- examples/utilities/tools/render/stats.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/utilities/tools/render/stats.qml b/examples/utilities/tools/render/stats.qml index eb7bb44a73..bc70358c54 100644 --- a/examples/utilities/tools/render/stats.qml +++ b/examples/utilities/tools/render/stats.qml @@ -19,7 +19,7 @@ Column { Repeater { model: [ - "num Textures:numTextures", + "num Textures:numTextures:1", "Sysmem Usage:textureSysmemUsage", "num GPU Textures:numGPUTextures", "Vidmem Usage:textureVidmemUsage" From 6d6f0398f53fb442ced4a97f67b8544354889877 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 23 Mar 2016 17:52:06 -0700 Subject: [PATCH 05/13] TRying to create a graph :) --- examples/utilities/tools/render/stats.qml | 37 +++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/examples/utilities/tools/render/stats.qml b/examples/utilities/tools/render/stats.qml index bc70358c54..7140f81270 100644 --- a/examples/utilities/tools/render/stats.qml +++ b/examples/utilities/tools/render/stats.qml @@ -11,6 +11,7 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 + Column { spacing: 8 Column { @@ -28,12 +29,44 @@ Column { Label { text: qsTr(modelData.split(":")[0]) } - property var value: stats.config[modelData.split(":")[1]] + property var value: stats.config[modelData.split(":")[1]] + property var valueHistory : new Array() + property var valueMax : 1000 + property var tick : 0 Label { text: value horizontalAlignment: AlignRight } - + Canvas { + id: mycanvas + width: 100 + height: 200 + onPaint: { + tick++; + valueHistory.push(value) + if (valueHistory.length > 100) { + valueHistory.shift(); + } + var ctx = getContext("2d"); + if (tick % 2) { + ctx.fillStyle = Qt.rgba(0, 1, 0, 0.5); + } else { + ctx.fillStyle = Qt.rgba(0, 0, 0, 0.5); + } + ctx.fillRect(0, 0, width, height); + var widthStep= width / valueHistory.length; + ctx.lineWidth="5"; + ctx.beginPath(); + ctx.strokeStyle="green"; // Green path + ctx.moveTo(0,height); + + for (var i = 0; i < valueHistory.length; i++) { + ctx.lineTo(i * widthStep, height * (1 - valueHistory[i] / valueMax) ); + } + ctx.lineTo(width, height); + ctx.stroke(); // Draw it + } + } } } } From 0c8556528b495c8ac119a70a12acb9ee11c88604 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 24 Mar 2016 17:25:58 -0700 Subject: [PATCH 06/13] Polishing the PerfPlot qml to display usefull things --- examples/utilities/tools/render/PlotPerf.qml | 130 +++++++++++++++++++ examples/utilities/tools/render/stats.qml | 59 ++------- 2 files changed, 139 insertions(+), 50 deletions(-) create mode 100644 examples/utilities/tools/render/PlotPerf.qml diff --git a/examples/utilities/tools/render/PlotPerf.qml b/examples/utilities/tools/render/PlotPerf.qml new file mode 100644 index 0000000000..dc5c16bf79 --- /dev/null +++ b/examples/utilities/tools/render/PlotPerf.qml @@ -0,0 +1,130 @@ +// +// PlotPerf.qml +// examples/utilities/tools/render +// +// Created by Sam Gateau on 3//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 + +Item { + id: root + width: 400 + height: 100 + property var config + property string parameters + + property var trigger: config["numTextures"] + + property var inputs: parameters.split(":") + property var valueScale: +inputs[0] + property var valueUnit: inputs[1] + property var valueNumDigits: inputs[2] + property var valueMax : 1 + + property var _values : new Array() + property var tick : 0 + + function createValues() { + if (inputs.length > 3) { + for (var i = 3; i < inputs.length; i++) { + var varProps = inputs[i].split("-") + _values.push( { + value: varProps[1], + valueMax: 1, + valueHistory: new Array(), + label: varProps[0], + color: varProps[2] + }) + } + } + print("in creator" + JSON.stringify(_values)); + + } + + Component.onCompleted: { + createValues(); + print(JSON.stringify(_values)); + + } + + function pullFreshValues() { + //print("pullFreshValues"); + var VALUE_HISTORY_SIZE = 100; + var UPDATE_CANVAS_RATE = 20; + tick++; + + valueMax = 0 + for (var i = 0; i < _values.length; i++) { + var currentVal = stats.config[_values[i].value]; + if (_values[i].valueMax < currentVal) { + _values[i].valueMax = currentVal; + } + _values[i].valueHistory.push(currentVal) + if (_values[i].valueHistory.length > VALUE_HISTORY_SIZE) { + var lostValue = _values[i].valueHistory.shift(); + if (lostValue >= _values[i].valueMax) { + _values[i].valueMax *= 0.99 + } + } + + if (valueMax < _values[i].valueMax) { + valueMax = _values[i].valueMax + } + } + + + if (tick % UPDATE_CANVAS_RATE == 0) { + mycanvas.requestPaint() + } + } + onTriggerChanged: pullFreshValues() + + Canvas { + id: mycanvas + width: 300 + height: 100 + onPaint: { + function displayValue(val) { + return (val / root.valueScale).toFixed(root.valueNumDigits) + " " + root.valueUnit + } + + function pixelFromVal(val) { + return height * (1 - (0.9) * val / valueMax); + } + function plotValueHistory(ctx, valHistory, color) { + var widthStep= width / (valHistory.length - 1); + + ctx.beginPath(); + ctx.strokeStyle= color; // Green path + ctx.lineWidth="4"; + ctx.moveTo(0, pixelFromVal(valHistory[i])); + + for (var i = 1; i < valHistory.length; i++) { + ctx.lineTo(i * widthStep, pixelFromVal(valHistory[i])); + } + + ctx.stroke(); + } + function plotValueLegend(ctx, val, num) { + var lineHeight = 12; + ctx.font="14px Verdana"; + ctx.fillStyle = val.color; + ctx.fillText(displayValue(val.valueHistory[val.valueHistory.length -1]), 0, height - num * lineHeight); + } + var ctx = getContext("2d"); + ctx.clearRect(0, 0, width, height); + ctx.fillStyle = Qt.rgba(0, 0, 0, 0.4); + ctx.fillRect(0, 0, width, height); + + for (var i = 0; i < _values.length; i++) { + plotValueHistory(ctx, _values[i].valueHistory, _values[i].color) + plotValueLegend(ctx, _values[i], i) + } + } + } +} diff --git a/examples/utilities/tools/render/stats.qml b/examples/utilities/tools/render/stats.qml index 7140f81270..6edd3b7ae0 100644 --- a/examples/utilities/tools/render/stats.qml +++ b/examples/utilities/tools/render/stats.qml @@ -15,59 +15,18 @@ import QtQuick.Controls 1.4 Column { spacing: 8 Column { + spacing: 4 + id: stats property var config: Render.getConfig("Stats") - Repeater { - model: [ - "num Textures:numTextures:1", - "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]] - property var valueHistory : new Array() - property var valueMax : 1000 - property var tick : 0 - Label { - text: value - horizontalAlignment: AlignRight - } - Canvas { - id: mycanvas - width: 100 - height: 200 - onPaint: { - tick++; - valueHistory.push(value) - if (valueHistory.length > 100) { - valueHistory.shift(); - } - var ctx = getContext("2d"); - if (tick % 2) { - ctx.fillStyle = Qt.rgba(0, 1, 0, 0.5); - } else { - ctx.fillStyle = Qt.rgba(0, 0, 0, 0.5); - } - ctx.fillRect(0, 0, width, height); - var widthStep= width / valueHistory.length; - ctx.lineWidth="5"; - ctx.beginPath(); - ctx.strokeStyle="green"; // Green path - ctx.moveTo(0,height); - - for (var i = 0; i < valueHistory.length; i++) { - ctx.lineTo(i * widthStep, height * (1 - valueHistory[i] / valueMax) ); - } - ctx.lineTo(width, height); - ctx.stroke(); // Draw it - } - } - } + PlotPerf { + config: stats.config + parameters: "1::0:num Textures-numTextures-blue:num GPU Textures-numGPUTextures-green" + } + PlotPerf { + config: stats.config + parameters: "1048576:Mb:1:Sysmem-textureSysmemUsage-blue:Vidmem-textureVidmemUsage-green" } } } From 9fb1a9a2a8347f69958e0c58ed81845745d33a84 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 25 Mar 2016 03:02:18 -0700 Subject: [PATCH 07/13] Merge and many more counters --- examples/utilities/tools/render/PlotPerf.qml | 47 ++++++++++---- .../utilities/tools/render/renderStats.js | 3 +- examples/utilities/tools/render/stats.qml | 27 ++++++-- libraries/gpu/src/gpu/Context.cpp | 5 ++ libraries/gpu/src/gpu/Context.h | 21 ++++++ libraries/gpu/src/gpu/GLBackend.h | 19 +----- libraries/gpu/src/gpu/GLBackendBuffer.cpp | 21 +++++- libraries/gpu/src/gpu/GLBackendPipeline.cpp | 3 + libraries/gpu/src/gpu/Resource.cpp | 65 ++++++++++++++++++- libraries/gpu/src/gpu/Resource.h | 15 +++++ libraries/gpu/src/gpu/Texture.cpp | 7 -- libraries/gpu/src/gpu/Texture.h | 4 -- libraries/render/src/render/Engine.cpp | 14 +++- libraries/render/src/render/Engine.h | 23 ++++++- 14 files changed, 219 insertions(+), 55 deletions(-) diff --git a/examples/utilities/tools/render/PlotPerf.qml b/examples/utilities/tools/render/PlotPerf.qml index dc5c16bf79..00b7848936 100644 --- a/examples/utilities/tools/render/PlotPerf.qml +++ b/examples/utilities/tools/render/PlotPerf.qml @@ -13,8 +13,8 @@ import QtQuick.Controls 1.4 Item { id: root - width: 400 height: 100 + property string title property var config property string parameters @@ -24,14 +24,15 @@ Item { property var valueScale: +inputs[0] property var valueUnit: inputs[1] property var valueNumDigits: inputs[2] + property var input_VALUE_OFFSET: 3 property var valueMax : 1 property var _values : new Array() property var tick : 0 function createValues() { - if (inputs.length > 3) { - for (var i = 3; i < inputs.length; i++) { + if (inputs.length > input_VALUE_OFFSET) { + for (var i = input_VALUE_OFFSET; i < inputs.length; i++) { var varProps = inputs[i].split("-") _values.push( { value: varProps[1], @@ -83,25 +84,26 @@ Item { } } onTriggerChanged: pullFreshValues() - + Canvas { id: mycanvas - width: 300 - height: 100 + anchors.fill:parent onPaint: { + var lineHeight = 12; + function displayValue(val) { return (val / root.valueScale).toFixed(root.valueNumDigits) + " " + root.valueUnit } function pixelFromVal(val) { - return height * (1 - (0.9) * val / valueMax); + return lineHeight + (height - lineHeight) * (1 - (0.9) * val / valueMax); } function plotValueHistory(ctx, valHistory, color) { var widthStep= width / (valHistory.length - 1); ctx.beginPath(); ctx.strokeStyle= color; // Green path - ctx.lineWidth="4"; + ctx.lineWidth="2"; ctx.moveTo(0, pixelFromVal(valHistory[i])); for (var i = 1; i < valHistory.length; i++) { @@ -110,21 +112,38 @@ Item { ctx.stroke(); } - function plotValueLegend(ctx, val, num) { - var lineHeight = 12; - ctx.font="14px Verdana"; - ctx.fillStyle = val.color; - ctx.fillText(displayValue(val.valueHistory[val.valueHistory.length -1]), 0, height - num * lineHeight); + function displayValueLegend(ctx, val, num) { + ctx.fillStyle = val.color; + var bestValue = val.valueHistory[val.valueHistory.length -1]; + ctx.textAlign = "right"; + ctx.fillText(displayValue(bestValue), width, height - num * lineHeight); + ctx.textAlign = "left"; + ctx.fillText(val.label, 0, height - num * lineHeight); } + + function displayTitle(ctx, text, maxVal) { + ctx.fillStyle = "grey"; + ctx.textAlign = "right"; + ctx.fillText(displayValue(maxVal), width, lineHeight); + + ctx.fillStyle = "white"; + ctx.textAlign = "left"; + ctx.fillText(text, 0, lineHeight); + } + var ctx = getContext("2d"); 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"; + for (var i = 0; i < _values.length; i++) { plotValueHistory(ctx, _values[i].valueHistory, _values[i].color) - plotValueLegend(ctx, _values[i], i) + displayValueLegend(ctx, _values[i], i) } + + displayTitle(ctx, title, valueMax) } } } diff --git a/examples/utilities/tools/render/renderStats.js b/examples/utilities/tools/render/renderStats.js index da12ad1b31..2e8487ca34 100644 --- a/examples/utilities/tools/render/renderStats.js +++ b/examples/utilities/tools/render/renderStats.js @@ -14,7 +14,8 @@ var qml = Script.resolvePath('stats.qml'); var window = new OverlayWindow({ title: 'Render Stats', source: qml, - width: 300 + width: 300, + height: 200 }); window.setPosition(500, 50); window.closed.connect(function() { Script.stop(); }); \ No newline at end of file diff --git a/examples/utilities/tools/render/stats.qml b/examples/utilities/tools/render/stats.qml index 6edd3b7ae0..47c0f98568 100644 --- a/examples/utilities/tools/render/stats.qml +++ b/examples/utilities/tools/render/stats.qml @@ -13,20 +13,39 @@ import QtQuick.Controls 1.4 Column { + id: statsUI + width: 300 spacing: 8 Column { - spacing: 4 + spacing: 8 - id: stats property var config: Render.getConfig("Stats") + id: stats PlotPerf { + title: "Num Buffers" + width:statsUI.width config: stats.config - parameters: "1::0:num Textures-numTextures-blue:num GPU Textures-numGPUTextures-green" + parameters: "1::0:CPU-numBuffers-#00B4EF:GPU-numGPUBuffers-#1AC567" } PlotPerf { + title: "Memory Usage" + width:statsUI.width config: stats.config - parameters: "1048576:Mb:1:Sysmem-textureSysmemUsage-blue:Vidmem-textureVidmemUsage-green" + parameters: "1048576:Mb:1:CPU-bufferSysmemUsage-#00B4EF:GPU-bufferVidmemUsage-#1AC567" + } + + PlotPerf { + title: "Num Textures" + width:statsUI.width + config: stats.config + parameters: "1::0:CPU-numTextures-#00B4EF:GPU-numGPUTextures-#1AC567:Frame-numFrameTextures-#E2334D" + } + PlotPerf { + title: "Memory Usage" + width:statsUI.width + config: stats.config + parameters: "1048576:Mb:1:CPU-textureSysmemUsage-#00B4EF:GPU-textureVidmemUsage-#1AC567" } } } diff --git a/libraries/gpu/src/gpu/Context.cpp b/libraries/gpu/src/gpu/Context.cpp index dd26ab2823..6148994a1b 100644 --- a/libraries/gpu/src/gpu/Context.cpp +++ b/libraries/gpu/src/gpu/Context.cpp @@ -74,6 +74,11 @@ void Context::downloadFramebuffer(const FramebufferPointer& srcFramebuffer, cons _backend->downloadFramebuffer(srcFramebuffer, region, destImage); } + +void Context::getStats(ContextStats& stats) const { + _backend->getStats(stats); +} + const Backend::TransformCamera& Backend::TransformCamera::recomputeDerived(const Transform& xformView) const { _projectionInverse = glm::inverse(_projection); diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index d584f54acc..c4ad35020a 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -27,6 +27,21 @@ class QImage; namespace gpu { +struct ContextStats { +public: + int _ISNumFormatChanges = 0; + int _ISNumInputBufferChanges = 0; + int _ISNumIndexBufferChanges = 0; + + int _RSNumTextureBounded = 0; + + int _DSNumDrawcalls = 0; + int _DSNumTriangles = 0; + + ContextStats() {} + ContextStats(const ContextStats& stats) = default; +}; + struct StereoState { bool _enable{ false }; bool _skybox{ false }; @@ -100,9 +115,11 @@ public: return reinterpret_cast(object.gpuObject.getGPUObject()); } + void getStats(ContextStats& stats) const { stats = _stats; } protected: StereoState _stereo; + ContextStats _stats; }; class Context { @@ -125,6 +142,7 @@ public: ~Context(); void render(Batch& batch); + void enableStereo(bool enable = true); bool isStereo(); void setStereoProjections(const mat4 eyeProjections[2]); @@ -137,6 +155,9 @@ public: // It s here for convenience to easily capture a snapshot void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage); + // Repporting stats of the context + void getStats(ContextStats& stats) const; + protected: Context(const Context& context); diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index d93962f5a1..c8e3be81d1 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -67,6 +67,8 @@ public: GLBuffer(); ~GLBuffer(); + + void setSize(GLuint size); }; static GLBuffer* syncGPUObject(const Buffer& buffer); static GLuint getBufferID(const Buffer& buffer); @@ -234,26 +236,11 @@ public: void do_setStateBlend(State::BlendFunction blendFunction); void do_setStateColorWriteMask(uint32 mask); - - // Repporting stats of the context - class Stats { - public: - int _ISNumFormatChanges = 0; - int _ISNumInputBufferChanges = 0; - int _ISNumIndexBufferChanges = 0; - - Stats() {} - Stats(const Stats& stats) = default; - }; - - void getStats(Stats& stats) const { stats = _stats; } - + protected: void renderPassTransfer(Batch& batch); void renderPassDraw(Batch& batch); - Stats _stats; - // Draw Stage void do_draw(Batch& batch, size_t paramOffset); void do_drawIndexed(Batch& batch, size_t paramOffset); diff --git a/libraries/gpu/src/gpu/GLBackendBuffer.cpp b/libraries/gpu/src/gpu/GLBackendBuffer.cpp index 49aeeca38e..56dd907b2e 100755 --- a/libraries/gpu/src/gpu/GLBackendBuffer.cpp +++ b/libraries/gpu/src/gpu/GLBackendBuffer.cpp @@ -16,12 +16,29 @@ GLBackend::GLBuffer::GLBuffer() : _stamp(0), _buffer(0), _size(0) -{} +{ + Buffer::_numGPUBuffers++; +} GLBackend::GLBuffer::~GLBuffer() { if (_buffer != 0) { glDeleteBuffers(1, &_buffer); } + Buffer::_bufferVideoMemoryUsage.fetch_sub(_size); + Buffer::_numGPUBuffers--; +} + +void GLBackend::GLBuffer::setSize(GLuint size) { + if (_size == size) { + return; + } + if (size > _size) { + Buffer::_bufferVideoMemoryUsage.fetch_add(size - _size); + } else { + Buffer::_bufferVideoMemoryUsage.fetch_sub(_size - size); + } + + _size = size; } GLBackend::GLBuffer* GLBackend::syncGPUObject(const Buffer& buffer) { @@ -46,7 +63,7 @@ GLBackend::GLBuffer* GLBackend::syncGPUObject(const Buffer& buffer) { glBufferData(GL_ARRAY_BUFFER, buffer.getSysmem().getSize(), buffer.getSysmem().readData(), GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); object->_stamp = buffer.getSysmem().getStamp(); - object->_size = (GLuint)buffer.getSysmem().getSize(); + object->setSize((GLuint)buffer.getSysmem().getSize()); //} (void) CHECK_GL_ERROR(); diff --git a/libraries/gpu/src/gpu/GLBackendPipeline.cpp b/libraries/gpu/src/gpu/GLBackendPipeline.cpp index 8c9647e0f2..046f1ff0e5 100755 --- a/libraries/gpu/src/gpu/GLBackendPipeline.cpp +++ b/libraries/gpu/src/gpu/GLBackendPipeline.cpp @@ -251,6 +251,9 @@ void GLBackend::do_setResourceTexture(Batch& batch, size_t paramOffset) { return; } + // One more True texture bound + _stats._RSNumTextureBounded++; + // Always make sure the GLObject is in sync GLTexture* object = GLBackend::syncGPUObject(*resourceTexture); if (object) { diff --git a/libraries/gpu/src/gpu/Resource.cpp b/libraries/gpu/src/gpu/Resource.cpp index 197263f392..d0527d6d3a 100644 --- a/libraries/gpu/src/gpu/Resource.cpp +++ b/libraries/gpu/src/gpu/Resource.cpp @@ -232,19 +232,66 @@ Resource::Size Resource::Sysmem::append(Size size, const Byte* bytes) { return 0; } +std::atomic Buffer::_numBuffers{ 0 }; +std::atomic Buffer::_numGPUBuffers{ 0 }; +std::atomic Buffer::_bufferSystemMemoryUsage{ 0 }; +std::atomic Buffer::_bufferVideoMemoryUsage{ 0 }; + + +int Buffer::getCurrentNumBuffers() { + return _numBuffers.load(); +} + +Buffer::Size Buffer::getCurrentSystemMemoryUsage() { + return _bufferSystemMemoryUsage.load(); +} + +int Buffer::getCurrentNumGPUBuffers() { + return _numGPUBuffers.load(); +} + +Buffer::Size Buffer::getCurrentVideoMemoryUsage() { + return _bufferVideoMemoryUsage.load(); +} + +void Buffer::addSystemMemoryUsage(Size memorySize) { + _bufferSystemMemoryUsage.fetch_add(memorySize); +} +void Buffer::subSystemMemoryUsage(Size memorySize) { + _bufferSystemMemoryUsage.fetch_sub(memorySize); +} + +void Buffer::updateSystemMemoryUsage(Size prevObjectSize, Size newObjectSize) { + if (prevObjectSize == newObjectSize) { + return; + } + if (prevObjectSize > newObjectSize) { + subSystemMemoryUsage(prevObjectSize - newObjectSize); + } else { + addSystemMemoryUsage(newObjectSize - prevObjectSize); + } +} + + Buffer::Buffer() : Resource(), _sysmem(new Sysmem()) { + _numBuffers++; + } Buffer::Buffer(Size size, const Byte* bytes) : Resource(), _sysmem(new Sysmem(size, bytes)) { + _numBuffers++; + Buffer::updateSystemMemoryUsage(0, _sysmem->getSize()); } Buffer::Buffer(const Buffer& buf) : Resource(), _sysmem(new Sysmem(buf.getSysmem())) { + _numBuffers++; + Buffer::updateSystemMemoryUsage(0, _sysmem->getSize()); } Buffer& Buffer::operator=(const Buffer& buf) { @@ -253,18 +300,27 @@ Buffer& Buffer::operator=(const Buffer& buf) { } Buffer::~Buffer() { + _numBuffers--; + if (_sysmem) { + Buffer::updateSystemMemoryUsage(_sysmem->getSize(), 0); delete _sysmem; _sysmem = NULL; } } Buffer::Size Buffer::resize(Size size) { - return editSysmem().resize(size); + auto prevSize = editSysmem().getSize(); + auto newSize = editSysmem().resize(size); + Buffer::updateSystemMemoryUsage(prevSize, newSize); + return newSize; } Buffer::Size Buffer::setData(Size size, const Byte* data) { - return editSysmem().setData(size, data); + auto prevSize = editSysmem().getSize(); + auto newSize = editSysmem().setData(size, data); + Buffer::updateSystemMemoryUsage(prevSize, newSize); + return newSize; } Buffer::Size Buffer::setSubData(Size offset, Size size, const Byte* data) { @@ -272,6 +328,9 @@ Buffer::Size Buffer::setSubData(Size offset, Size size, const Byte* data) { } Buffer::Size Buffer::append(Size size, const Byte* data) { - return editSysmem().append( size, data); + auto prevSize = editSysmem().getSize(); + auto newSize = editSysmem().append( size, data); + Buffer::updateSystemMemoryUsage(prevSize, newSize); + return newSize; } diff --git a/libraries/gpu/src/gpu/Resource.h b/libraries/gpu/src/gpu/Resource.h index 3517b67203..d40e9131a1 100644 --- a/libraries/gpu/src/gpu/Resource.h +++ b/libraries/gpu/src/gpu/Resource.h @@ -16,6 +16,7 @@ #include "Format.h" #include +#include #include #ifdef _DEBUG @@ -109,7 +110,21 @@ protected: }; class Buffer : public Resource { + static std::atomic _numBuffers; + static std::atomic _bufferSystemMemoryUsage; public: + static std::atomic _numGPUBuffers; + static std::atomic _bufferVideoMemoryUsage; +private: + static void addSystemMemoryUsage(Size memorySize); + static void subSystemMemoryUsage(Size memorySize); + static void updateSystemMemoryUsage(Size prevObjectSize, Size newObjectSize); + +public: + static int getCurrentNumBuffers(); + static Size getCurrentSystemMemoryUsage(); + static int getCurrentNumGPUBuffers(); + static Size getCurrentVideoMemoryUsage(); Buffer(); Buffer(Size size, const Byte* bytes); diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 7a0e198ec9..cb0ef20c6c 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -57,13 +57,6 @@ void Texture::updateSystemMemoryUsage(Size prevObjectSize, Size newObjectSize) { } } -void Texture::addVideoMemoryUsage(Size memorySize) { - _textureVideoMemoryUsage.fetch_add(memorySize); -} -void Texture::subVideoMemoryUsage(Size memorySize) { - _textureVideoMemoryUsage.fetch_sub(memorySize); -} - uint8 Texture::NUM_FACES_PER_TYPE[NUM_TYPES] = {1, 1, 1, 6}; Texture::Pixels::Pixels(const Element& format, Size size, const Byte* bytes) : diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 06b0077458..087f305224 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -15,7 +15,6 @@ #include //min max and more #include -#include #include @@ -149,9 +148,6 @@ private: static void subSystemMemoryUsage(Size memorySize); static void updateSystemMemoryUsage(Size prevObjectSize, Size newObjectSize); - static void addVideoMemoryUsage(Size memorySize); - static void subVideoMemoryUsage(Size memorySize); - public: static int getCurrentNumTextures(); diff --git a/libraries/render/src/render/Engine.cpp b/libraries/render/src/render/Engine.cpp index 2118c3c734..b4ee713e74 100644 --- a/libraries/render/src/render/Engine.cpp +++ b/libraries/render/src/render/Engine.cpp @@ -67,10 +67,22 @@ void EngineStats::run(const SceneContextPointer& sceneContext, const RenderConte // Update the stats auto config = std::static_pointer_cast(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->textureSysmemUsage = gpu::Texture::getCurrentSystemMemoryUsage(); 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(); } diff --git a/libraries/render/src/render/Engine.h b/libraries/render/src/render/Engine.h index 71c52c5910..4fd29b5d66 100644 --- a/libraries/render/src/render/Engine.h +++ b/libraries/render/src/render/Engine.h @@ -13,10 +13,10 @@ #define hifi_render_Engine_h #include +#include #include "Context.h" #include "Task.h" - namespace render { // The render engine holds all render tasks, and is itself a render task. @@ -53,18 +53,33 @@ namespace render { // 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(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: @@ -78,6 +93,8 @@ namespace render { EngineStats() {} + gpu::ContextStats _gpuStats; + void configure(const Config& configuration) {} void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); }; From 9b58d50fd4ed96dc04f365baf2ea457e67e28ee1 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 25 Mar 2016 15:28:06 -0700 Subject: [PATCH 08/13] BUilding a more complete set of tools to monitor performances --- examples/utilities/tools/render/PlotPerf.qml | 73 ++++++++++++---- examples/utilities/tools/render/stats.qml | 44 +++++++--- libraries/gpu/src/gpu/Context.h | 2 +- libraries/gpu/src/gpu/GLBackend.cpp | 17 +++- libraries/render/src/render/Engine.cpp | 26 +----- libraries/render/src/render/Engine.h | 52 ----------- libraries/render/src/render/EngineStats.cpp | 50 +++++++++++ libraries/render/src/render/EngineStats.h | 91 ++++++++++++++++++++ 8 files changed, 244 insertions(+), 111 deletions(-) create mode 100644 libraries/render/src/render/EngineStats.cpp create mode 100644 libraries/render/src/render/EngineStats.h diff --git a/examples/utilities/tools/render/PlotPerf.qml b/examples/utilities/tools/render/PlotPerf.qml index 00b7848936..c907b847a8 100644 --- a/examples/utilities/tools/render/PlotPerf.qml +++ b/examples/utilities/tools/render/PlotPerf.qml @@ -13,6 +13,7 @@ import QtQuick.Controls 1.4 Item { id: root + width: parent.width height: 100 property string title property var config @@ -34,12 +35,15 @@ Item { if (inputs.length > input_VALUE_OFFSET) { for (var i = input_VALUE_OFFSET; i < inputs.length; i++) { var varProps = inputs[i].split("-") - _values.push( { + _values.push( { value: varProps[1], valueMax: 1, + numSamplesConstantMax: 0, valueHistory: new Array(), 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; tick++; - valueMax = 0 + + var currentValueMax = 0 for (var i = 0; i < _values.length; i++) { - var currentVal = stats.config[_values[i].value]; - if (_values[i].valueMax < currentVal) { - _values[i].valueMax = currentVal; - } + + var currentVal = stats.config[_values[i].value] * _values[i].scale; _values[i].valueHistory.push(currentVal) + _values[i].numSamplesConstantMax++; + if (_values[i].valueHistory.length > VALUE_HISTORY_SIZE) { var lostValue = _values[i].valueHistory.shift(); if (lostValue >= _values[i].valueMax) { _values[i].valueMax *= 0.99 + _values[i].numSamplesConstantMax = 0 } } - if (valueMax < _values[i].valueMax) { - valueMax = _values[i].valueMax + if (_values[i].valueMax < currentVal) { + _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) { mycanvas.requestPaint() @@ -91,20 +110,23 @@ Item { onPaint: { var lineHeight = 12; - function displayValue(val) { - return (val / root.valueScale).toFixed(root.valueNumDigits) + " " + root.valueUnit + function displayValue(val, unit) { + return (val / root.valueScale).toFixed(root.valueNumDigits) + " " + unit } - function pixelFromVal(val) { + function pixelFromVal(val, valScale) { 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) { var widthStep= width / (valHistory.length - 1); ctx.beginPath(); ctx.strokeStyle= color; // Green path ctx.lineWidth="2"; - ctx.moveTo(0, pixelFromVal(valHistory[i])); + ctx.moveTo(0, pixelFromVal(valHistory[0])); for (var i = 1; i < valHistory.length; i++) { ctx.lineTo(i * widthStep, pixelFromVal(valHistory[i])); @@ -116,27 +138,40 @@ Item { ctx.fillStyle = val.color; var bestValue = val.valueHistory[val.valueHistory.length -1]; 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.fillText(val.label, 0, height - num * lineHeight); + ctx.fillText(val.label, 0, (num + 2) * lineHeight * 1.5); } function displayTitle(ctx, text, maxVal) { ctx.fillStyle = "grey"; ctx.textAlign = "right"; - ctx.fillText(displayValue(maxVal), width, lineHeight); + ctx.fillText(displayValue(valueFromPixel(lineHeight), root.valueUnit), width, lineHeight); ctx.fillStyle = "white"; ctx.textAlign = "left"; 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"); 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"; + + displayBackground(ctx); for (var i = 0; i < _values.length; i++) { plotValueHistory(ctx, _values[i].valueHistory, _values[i].color) diff --git a/examples/utilities/tools/render/stats.qml b/examples/utilities/tools/render/stats.qml index 47c0f98568..9c0ac3e14d 100644 --- a/examples/utilities/tools/render/stats.qml +++ b/examples/utilities/tools/render/stats.qml @@ -12,40 +12,58 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 -Column { +Item { id: statsUI - width: 300 - spacing: 8 - Column { - spacing: 8 + anchors.fill:parent - property var config: Render.getConfig("Stats") + Column { 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 { title: "Num Buffers" - width:statsUI.width config: stats.config + height: parent.evalEvenHeight() parameters: "1::0:CPU-numBuffers-#00B4EF:GPU-numGPUBuffers-#1AC567" } PlotPerf { - title: "Memory Usage" - width:statsUI.width + title: "gpu::Buffer Memory" config: stats.config + height: parent.evalEvenHeight() parameters: "1048576:Mb:1:CPU-bufferSysmemUsage-#00B4EF:GPU-bufferVidmemUsage-#1AC567" } PlotPerf { title: "Num Textures" - width:statsUI.width 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 { - title: "Memory Usage" - width:statsUI.width + title: "gpu::Texture Memory" config: stats.config + height: parent.evalEvenHeight() 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" + } } } diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index c4ad35020a..c2cd1f239e 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -37,7 +37,7 @@ public: int _DSNumDrawcalls = 0; int _DSNumTriangles = 0; - + ContextStats() {} ContextStats(const ContextStats& stats) = default; }; diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 2c25255a80..e847ad1a42 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -324,7 +324,10 @@ void GLBackend::do_draw(Batch& batch, size_t paramOffset) { uint32 numVertices = batch._params[paramOffset + 1]._uint; uint32 startVertex = batch._params[paramOffset + 0]._uint; 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) { @@ -339,6 +342,9 @@ void GLBackend::do_drawIndexed(Batch& batch, size_t paramOffset) { GLvoid* indexBufferByteOffset = reinterpret_cast(startIndex * typeByteSize + _input._indexBufferOffset); glDrawElements(mode, numIndices, glType, indexBufferByteOffset); + _stats._DSNumTriangles += numIndices / 3; + _stats._DSNumDrawcalls++; + (void) CHECK_GL_ERROR(); } @@ -350,6 +356,9 @@ void GLBackend::do_drawInstanced(Batch& batch, size_t paramOffset) { uint32 startVertex = batch._params[paramOffset + 1]._uint; glDrawArraysInstancedARB(mode, startVertex, numVertices, numInstances); + _stats._DSNumTriangles += (numInstances * numVertices) / 3; + _stats._DSNumDrawcalls += numInstances; + (void) CHECK_GL_ERROR(); } @@ -372,6 +381,9 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, size_t paramOffset) { glDrawElementsInstanced(mode, numIndices, glType, indexBufferByteOffset, numInstances); Q_UNUSED(startInstance); #endif + _stats._DSNumTriangles += (numInstances * numIndices) / 3; + _stats._DSNumDrawcalls += numInstances; + (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]; glMultiDrawArraysIndirect(mode, reinterpret_cast(_input._indirectBufferOffset), commandCount, (GLsizei)_input._indirectBufferStride); + _stats._DSNumDrawcalls += commandCount; #else // FIXME implement the slow path #endif @@ -396,6 +409,8 @@ void GLBackend::do_multiDrawIndexedIndirect(Batch& batch, size_t paramOffset) { GLenum indexType = _elementTypeToGLType[_input._indexBufferType]; glMultiDrawElementsIndirect(mode, indexType, reinterpret_cast(_input._indirectBufferOffset), commandCount, (GLsizei)_input._indirectBufferStride); + _stats._DSNumDrawcalls += commandCount; + #else // FIXME implement the slow path #endif diff --git a/libraries/render/src/render/Engine.cpp b/libraries/render/src/render/Engine.cpp index b4ee713e74..b0329faa3e 100644 --- a/libraries/render/src/render/Engine.cpp +++ b/libraries/render/src/render/Engine.cpp @@ -17,6 +17,7 @@ #include +#include "EngineStats.h" using namespace render; @@ -61,28 +62,3 @@ void Engine::run() { } -#include -void EngineStats::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - const size_t KILO_BYTES = 1024; - // Update the stats - auto config = std::static_pointer_cast(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(); -} diff --git a/libraries/render/src/render/Engine.h b/libraries/render/src/render/Engine.h index 4fd29b5d66..d2bb42e5ff 100644 --- a/libraries/render/src/render/Engine.h +++ b/libraries/render/src/render/Engine.h @@ -13,7 +13,6 @@ #define hifi_render_Engine_h #include -#include #include "Context.h" #include "Task.h" @@ -49,57 +48,6 @@ namespace render { }; using EnginePointer = std::shared_ptr; - - // 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() {} - - gpu::ContextStats _gpuStats; - - void configure(const Config& configuration) {} - void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); - }; - - } #endif // hifi_render_Engine_h diff --git a/libraries/render/src/render/EngineStats.cpp b/libraries/render/src/render/EngineStats.cpp new file mode 100644 index 0000000000..63a25229ea --- /dev/null +++ b/libraries/render/src/render/EngineStats.cpp @@ -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 + +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(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(); +} diff --git a/libraries/render/src/render/EngineStats.h b/libraries/render/src/render/EngineStats.h new file mode 100644 index 0000000000..d9f7e7ac9a --- /dev/null +++ b/libraries/render/src/render/EngineStats.h @@ -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 + +#include + +#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() { _frameTimer.start(); } + + gpu::ContextStats _gpuStats; + + void configure(const Config& configuration) {} + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + + QElapsedTimer _frameTimer; + }; +} + +#endif \ No newline at end of file From 5190878db21b28047a81b14f77c9528b002ca1cf Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 25 Mar 2016 16:18:04 -0700 Subject: [PATCH 09/13] removing a debug trick --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cb312047c2..b9effa444b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -269,7 +269,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) { From 73613040841858e85e1b95abab03f3c285c62d89 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 25 Mar 2016 18:38:52 -0700 Subject: [PATCH 10/13] Cleaning up for review --- examples/utilities/tools/render/PlotPerf.qml | 10 ++-- examples/utilities/tools/render/stats.qml | 14 ++--- libraries/gpu/src/gpu/GLBackendBuffer.cpp | 10 ++-- libraries/gpu/src/gpu/GLBackendTexture.cpp | 10 ++-- libraries/gpu/src/gpu/Resource.cpp | 58 +++++++++----------- libraries/gpu/src/gpu/Resource.h | 24 ++++---- libraries/gpu/src/gpu/Texture.cpp | 56 +++++++++---------- libraries/gpu/src/gpu/Texture.h | 25 ++++----- libraries/render/src/render/EngineStats.cpp | 22 +++++--- libraries/render/src/render/EngineStats.h | 56 +++++++++---------- 10 files changed, 137 insertions(+), 148 deletions(-) diff --git a/examples/utilities/tools/render/PlotPerf.qml b/examples/utilities/tools/render/PlotPerf.qml index c907b847a8..0e100e4e72 100644 --- a/examples/utilities/tools/render/PlotPerf.qml +++ b/examples/utilities/tools/render/PlotPerf.qml @@ -19,7 +19,9 @@ Item { property var config property string parameters - property var trigger: config["numTextures"] + // THis is my hack to get the name of the first property and assign it to a trigger var in order to get + // a signal called whenever the value changed + property var trigger: config[parameters.split(":")[3].split("-")[0]] property var inputs: parameters.split(":") property var valueScale: +inputs[0] @@ -36,11 +38,11 @@ Item { for (var i = input_VALUE_OFFSET; i < inputs.length; i++) { var varProps = inputs[i].split("-") _values.push( { - value: varProps[1], + value: varProps[0], valueMax: 1, numSamplesConstantMax: 0, valueHistory: new Array(), - label: varProps[0], + label: varProps[1], color: varProps[2], scale: (varProps.length > 3 ? varProps[3] : 1), unit: (varProps.length > 4 ? varProps[4] : valueUnit) @@ -67,7 +69,7 @@ Item { var currentValueMax = 0 for (var i = 0; i < _values.length; i++) { - var currentVal = stats.config[_values[i].value] * _values[i].scale; + var currentVal = config[_values[i].value] * _values[i].scale; _values[i].valueHistory.push(currentVal) _values[i].numSamplesConstantMax++; diff --git a/examples/utilities/tools/render/stats.qml b/examples/utilities/tools/render/stats.qml index 9c0ac3e14d..142b5e25e2 100644 --- a/examples/utilities/tools/render/stats.qml +++ b/examples/utilities/tools/render/stats.qml @@ -32,38 +32,38 @@ Item { title: "Num Buffers" config: stats.config height: parent.evalEvenHeight() - parameters: "1::0:CPU-numBuffers-#00B4EF:GPU-numGPUBuffers-#1AC567" + parameters: "1::0:bufferCPUCount-CPU-#00B4EF:bufferGPUCount-GPU-#1AC567" } PlotPerf { title: "gpu::Buffer Memory" - config: stats.config + config: stats.config height: parent.evalEvenHeight() - parameters: "1048576:Mb:1:CPU-bufferSysmemUsage-#00B4EF:GPU-bufferVidmemUsage-#1AC567" + parameters: "1048576:Mb:1:bufferCPUMemoryUsage-CPU-#00B4EF:bufferGPUMemoryUsage-GPU-#1AC567" } PlotPerf { title: "Num Textures" config: stats.config height: parent.evalEvenHeight() - parameters: "1::0:CPU-numTextures-#00B4EF:GPU-numGPUTextures-#1AC567:Frame-frameTextureCount-#E2334D" + parameters: "1::0:textureCPUCount-CPU-#00B4EF:textureGPUCount-GPU-#1AC567:frameTextureCount-Frame-#E2334D" } PlotPerf { title: "gpu::Texture Memory" config: stats.config height: parent.evalEvenHeight() - parameters: "1048576:Mb:1:CPU-textureSysmemUsage-#00B4EF:GPU-textureVidmemUsage-#1AC567" + parameters: "1048576:Mb:1:textureCPUMemoryUsage-CPU-#00B4EF:textureGPUMemoryUsage-GPU-#1AC567" } PlotPerf { title: "Drawcalls" config: stats.config height: parent.evalEvenHeight() - parameters: "1::0:frame-frameDrawcallCount-#E2334D:rate-frameDrawcallRate-#1AC567-0.001-K/s" + parameters: "1::0:frameDrawcallCount-frame-#E2334D:frameDrawcallRate-rate-#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" + parameters: "1000:K:0:frameTriangleCount-frame-#E2334D:frameTriangleRate-rate-#1AC567-0.001-MT/s" } } } diff --git a/libraries/gpu/src/gpu/GLBackendBuffer.cpp b/libraries/gpu/src/gpu/GLBackendBuffer.cpp index 56dd907b2e..8b8af386bb 100755 --- a/libraries/gpu/src/gpu/GLBackendBuffer.cpp +++ b/libraries/gpu/src/gpu/GLBackendBuffer.cpp @@ -17,15 +17,15 @@ GLBackend::GLBuffer::GLBuffer() : _buffer(0), _size(0) { - Buffer::_numGPUBuffers++; + Buffer::_bufferGPUCount++; } GLBackend::GLBuffer::~GLBuffer() { if (_buffer != 0) { glDeleteBuffers(1, &_buffer); } - Buffer::_bufferVideoMemoryUsage.fetch_sub(_size); - Buffer::_numGPUBuffers--; + Buffer::_bufferGPUMemoryUsage.fetch_sub(_size); + Buffer::_bufferGPUCount--; } void GLBackend::GLBuffer::setSize(GLuint size) { @@ -33,9 +33,9 @@ void GLBackend::GLBuffer::setSize(GLuint size) { return; } if (size > _size) { - Buffer::_bufferVideoMemoryUsage.fetch_add(size - _size); + Buffer::_bufferGPUMemoryUsage.fetch_add(size - _size); } else { - Buffer::_bufferVideoMemoryUsage.fetch_sub(_size - size); + Buffer::_bufferGPUMemoryUsage.fetch_sub(_size - size); } _size = size; diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index 6a96c5a651..bc25048a3f 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -20,15 +20,15 @@ GLBackend::GLTexture::GLTexture() : _target(GL_TEXTURE_2D), _size(0) { - Texture::_numGPUTextures++; + Texture::_textureGPUCount++; } GLBackend::GLTexture::~GLTexture() { if (_texture != 0) { glDeleteTextures(1, &_texture); } - Texture::_textureVideoMemoryUsage.fetch_sub(_size); - Texture::_numGPUTextures--; + Texture::_textureGPUMemoryUsage.fetch_sub(_size); + Texture::_textureGPUCount--; } void GLBackend::GLTexture::setSize(GLuint size) { @@ -36,9 +36,9 @@ void GLBackend::GLTexture::setSize(GLuint size) { return; } if (size > _size) { - Texture::_textureVideoMemoryUsage.fetch_add(size - _size); + Texture::_textureGPUMemoryUsage.fetch_add(size - _size); } else { - Texture::_textureVideoMemoryUsage.fetch_sub(_size - size); + Texture::_textureGPUMemoryUsage.fetch_sub(_size - size); } _size = size; diff --git a/libraries/gpu/src/gpu/Resource.cpp b/libraries/gpu/src/gpu/Resource.cpp index d0527d6d3a..f10d95c03b 100644 --- a/libraries/gpu/src/gpu/Resource.cpp +++ b/libraries/gpu/src/gpu/Resource.cpp @@ -232,43 +232,35 @@ Resource::Size Resource::Sysmem::append(Size size, const Byte* bytes) { return 0; } -std::atomic Buffer::_numBuffers{ 0 }; -std::atomic Buffer::_numGPUBuffers{ 0 }; -std::atomic Buffer::_bufferSystemMemoryUsage{ 0 }; -std::atomic Buffer::_bufferVideoMemoryUsage{ 0 }; +std::atomic Buffer::_bufferCPUCount{ 0 }; +std::atomic Buffer::_bufferGPUCount{ 0 }; +std::atomic Buffer::_bufferCPUMemoryUsage{ 0 }; +std::atomic Buffer::_bufferGPUMemoryUsage{ 0 }; - -int Buffer::getCurrentNumBuffers() { - return _numBuffers.load(); +uint32_t Buffer::getBufferCPUCount() { + return _bufferCPUCount.load(); } -Buffer::Size Buffer::getCurrentSystemMemoryUsage() { - return _bufferSystemMemoryUsage.load(); +Buffer::Size Buffer::getBufferCPUMemoryUsage() { + return _bufferCPUMemoryUsage.load(); } -int Buffer::getCurrentNumGPUBuffers() { - return _numGPUBuffers.load(); +uint32_t Buffer::getBufferGPUCount() { + return _bufferGPUCount.load(); } -Buffer::Size Buffer::getCurrentVideoMemoryUsage() { - return _bufferVideoMemoryUsage.load(); +Buffer::Size Buffer::getBufferGPUMemoryUsage() { + return _bufferGPUMemoryUsage.load(); } -void Buffer::addSystemMemoryUsage(Size memorySize) { - _bufferSystemMemoryUsage.fetch_add(memorySize); -} -void Buffer::subSystemMemoryUsage(Size memorySize) { - _bufferSystemMemoryUsage.fetch_sub(memorySize); -} - -void Buffer::updateSystemMemoryUsage(Size prevObjectSize, Size newObjectSize) { +void Buffer::updateBufferCPUMemoryUsage(Size prevObjectSize, Size newObjectSize) { if (prevObjectSize == newObjectSize) { return; } if (prevObjectSize > newObjectSize) { - subSystemMemoryUsage(prevObjectSize - newObjectSize); + _bufferCPUMemoryUsage.fetch_sub(prevObjectSize - newObjectSize); } else { - addSystemMemoryUsage(newObjectSize - prevObjectSize); + _bufferCPUMemoryUsage.fetch_add(newObjectSize - prevObjectSize); } } @@ -276,22 +268,22 @@ void Buffer::updateSystemMemoryUsage(Size prevObjectSize, Size newObjectSize) { Buffer::Buffer() : Resource(), _sysmem(new Sysmem()) { - _numBuffers++; + _bufferCPUCount++; } Buffer::Buffer(Size size, const Byte* bytes) : Resource(), _sysmem(new Sysmem(size, bytes)) { - _numBuffers++; - Buffer::updateSystemMemoryUsage(0, _sysmem->getSize()); + _bufferCPUCount++; + Buffer::updateBufferCPUMemoryUsage(0, _sysmem->getSize()); } Buffer::Buffer(const Buffer& buf) : Resource(), _sysmem(new Sysmem(buf.getSysmem())) { - _numBuffers++; - Buffer::updateSystemMemoryUsage(0, _sysmem->getSize()); + _bufferCPUCount++; + Buffer::updateBufferCPUMemoryUsage(0, _sysmem->getSize()); } Buffer& Buffer::operator=(const Buffer& buf) { @@ -300,10 +292,10 @@ Buffer& Buffer::operator=(const Buffer& buf) { } Buffer::~Buffer() { - _numBuffers--; + _bufferCPUCount--; if (_sysmem) { - Buffer::updateSystemMemoryUsage(_sysmem->getSize(), 0); + Buffer::updateBufferCPUMemoryUsage(_sysmem->getSize(), 0); delete _sysmem; _sysmem = NULL; } @@ -312,14 +304,14 @@ Buffer::~Buffer() { Buffer::Size Buffer::resize(Size size) { auto prevSize = editSysmem().getSize(); auto newSize = editSysmem().resize(size); - Buffer::updateSystemMemoryUsage(prevSize, newSize); + Buffer::updateBufferCPUMemoryUsage(prevSize, newSize); return newSize; } Buffer::Size Buffer::setData(Size size, const Byte* data) { auto prevSize = editSysmem().getSize(); auto newSize = editSysmem().setData(size, data); - Buffer::updateSystemMemoryUsage(prevSize, newSize); + Buffer::updateBufferCPUMemoryUsage(prevSize, newSize); return newSize; } @@ -330,7 +322,7 @@ Buffer::Size Buffer::setSubData(Size offset, Size size, const Byte* data) { Buffer::Size Buffer::append(Size size, const Byte* data) { auto prevSize = editSysmem().getSize(); auto newSize = editSysmem().append( size, data); - Buffer::updateSystemMemoryUsage(prevSize, newSize); + Buffer::updateBufferCPUMemoryUsage(prevSize, newSize); return newSize; } diff --git a/libraries/gpu/src/gpu/Resource.h b/libraries/gpu/src/gpu/Resource.h index d40e9131a1..176e33a428 100644 --- a/libraries/gpu/src/gpu/Resource.h +++ b/libraries/gpu/src/gpu/Resource.h @@ -110,21 +110,19 @@ protected: }; class Buffer : public Resource { - static std::atomic _numBuffers; - static std::atomic _bufferSystemMemoryUsage; -public: - static std::atomic _numGPUBuffers; - static std::atomic _bufferVideoMemoryUsage; -private: - static void addSystemMemoryUsage(Size memorySize); - static void subSystemMemoryUsage(Size memorySize); - static void updateSystemMemoryUsage(Size prevObjectSize, Size newObjectSize); + static std::atomic _bufferCPUCount; + static std::atomic _bufferCPUMemoryUsage; + static void updateBufferCPUMemoryUsage(Size prevObjectSize, Size newObjectSize); public: - static int getCurrentNumBuffers(); - static Size getCurrentSystemMemoryUsage(); - static int getCurrentNumGPUBuffers(); - static Size getCurrentVideoMemoryUsage(); + static std::atomic _bufferGPUCount; + static std::atomic _bufferGPUMemoryUsage; + +public: + static uint32_t getBufferCPUCount(); + static Size getBufferCPUMemoryUsage(); + static uint32_t getBufferGPUCount(); + static Size getBufferGPUMemoryUsage(); Buffer(); Buffer(Size size, const Byte* bytes); diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index cb0ef20c6c..15ad4eea97 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -17,63 +17,57 @@ using namespace gpu; -std::atomic Texture::_numTextures{ 0 }; -std::atomic Texture::_numGPUTextures{ 0 }; -std::atomic Texture::_textureSystemMemoryUsage{ 0 }; -std::atomic Texture::_textureVideoMemoryUsage{ 0 }; +std::atomic Texture::_textureCPUCount{ 0 }; +std::atomic Texture::_textureGPUCount{ 0 }; +std::atomic Texture::_textureCPUMemoryUsage{ 0 }; +std::atomic Texture::_textureGPUMemoryUsage{ 0 }; -int Texture::getCurrentNumTextures() { - return _numTextures.load(); +uint32_t Texture::getTextureCPUCount() { + return _textureCPUCount.load(); } -Texture::Size Texture::getCurrentSystemMemoryUsage() { - return _textureSystemMemoryUsage.load(); +Texture::Size Texture::getTextureCPUMemoryUsage() { + return _textureCPUMemoryUsage.load(); } -int Texture::getCurrentNumGPUTextures() { - return _numGPUTextures.load(); +uint32_t Texture::getTextureGPUCount() { + return _textureGPUCount.load(); } -Texture::Size Texture::getCurrentVideoMemoryUsage() { - return _textureVideoMemoryUsage.load(); +Texture::Size Texture::getTextureGPUMemoryUsage() { + return _textureGPUMemoryUsage.load(); } -void Texture::addSystemMemoryUsage(Size memorySize) { - _textureSystemMemoryUsage.fetch_add(memorySize); -} -void Texture::subSystemMemoryUsage(Size memorySize) { - _textureSystemMemoryUsage.fetch_sub(memorySize); -} - -void Texture::updateSystemMemoryUsage(Size prevObjectSize, Size newObjectSize) { +void Texture::updateTextureCPUMemoryUsage(Size prevObjectSize, Size newObjectSize) { if (prevObjectSize == newObjectSize) { return; } if (prevObjectSize > newObjectSize) { - subSystemMemoryUsage(prevObjectSize - newObjectSize); + _textureCPUMemoryUsage.fetch_sub(prevObjectSize - newObjectSize); } else { - addSystemMemoryUsage(newObjectSize - prevObjectSize); + _textureCPUMemoryUsage.fetch_add(newObjectSize - prevObjectSize); } } + uint8 Texture::NUM_FACES_PER_TYPE[NUM_TYPES] = {1, 1, 1, 6}; Texture::Pixels::Pixels(const Element& format, Size size, const Byte* bytes) : _format(format), _sysmem(size, bytes), _isGPULoaded(false) { - Texture::updateSystemMemoryUsage(0, _sysmem.getSize()); + Texture::updateTextureCPUMemoryUsage(0, _sysmem.getSize()); } Texture::Pixels::~Pixels() { - Texture::updateSystemMemoryUsage(_sysmem.getSize(), 0); + Texture::updateTextureCPUMemoryUsage(_sysmem.getSize(), 0); } Texture::Size Texture::Pixels::resize(Size pSize) { auto prevSize = _sysmem.getSize(); auto newSize = _sysmem.resize(pSize); - Texture::updateSystemMemoryUsage(prevSize, newSize); + Texture::updateTextureCPUMemoryUsage(prevSize, newSize); return newSize; } @@ -81,7 +75,7 @@ Texture::Size Texture::Pixels::setData(const Element& format, Size size, const B _format = format; auto prevSize = _sysmem.getSize(); auto newSize = _sysmem.setData(size, bytes); - Texture::updateSystemMemoryUsage(prevSize, newSize); + Texture::updateTextureCPUMemoryUsage(prevSize, newSize); _isGPULoaded = false; return newSize; } @@ -90,7 +84,7 @@ void Texture::Pixels::notifyGPULoaded() { _isGPULoaded = true; auto prevSize = _sysmem.getSize(); auto newSize = _sysmem.resize(0); - Texture::updateSystemMemoryUsage(prevSize, newSize); + Texture::updateTextureCPUMemoryUsage(prevSize, newSize); } void Texture::Storage::assignTexture(Texture* texture) { @@ -232,12 +226,12 @@ Texture* Texture::createFromStorage(Storage* storage) { Texture::Texture(): Resource() { - _numTextures++; + _textureCPUCount++; } Texture::~Texture() { - _numTextures--; + _textureCPUCount--; } Texture::Size Texture::resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices) { @@ -355,7 +349,7 @@ bool Texture::assignStoredMip(uint16 level, const Element& format, Size size, co } } - // THen check that the mem buffer passed make sense with its format + // THen check that the mem texture passed make sense with its format Size expectedSize = evalStoredMipSize(level, format); if (size == expectedSize) { _storage->assignMipData(level, format, size, bytes); @@ -386,7 +380,7 @@ bool Texture::assignStoredMipFace(uint16 level, const Element& format, Size size } } - // THen check that the mem buffer passed make sense with its format + // THen check that the mem texture passed make sense with its format Size expectedSize = evalStoredMipFaceSize(level, format); if (size == expectedSize) { _storage->assignMipFaceData(level, format, size, bytes, face); diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 087f305224..c498b5cc22 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -138,22 +138,19 @@ protected: }; class Texture : public Resource { - static std::atomic _numTextures; - static std::atomic _textureSystemMemoryUsage; -public: - static std::atomic _numGPUTextures; - static std::atomic _textureVideoMemoryUsage; -private: - static void addSystemMemoryUsage(Size memorySize); - static void subSystemMemoryUsage(Size memorySize); - static void updateSystemMemoryUsage(Size prevObjectSize, Size newObjectSize); + static std::atomic _textureCPUCount; + static std::atomic _textureCPUMemoryUsage; + static void updateTextureCPUMemoryUsage(Size prevObjectSize, Size newObjectSize); public: + static std::atomic _textureGPUCount; + static std::atomic _textureGPUMemoryUsage; - static int getCurrentNumTextures(); - static Size getCurrentSystemMemoryUsage(); - static int getCurrentNumGPUTextures(); - static Size getCurrentVideoMemoryUsage(); +public: + static uint32_t getTextureCPUCount(); + static Size getTextureCPUMemoryUsage(); + static uint32_t getTextureGPUCount(); + static Size getTextureGPUMemoryUsage(); class Usage { public: @@ -475,7 +472,7 @@ typedef std::shared_ptr TexturePointer; typedef std::vector< TexturePointer > Textures; - // TODO: For now TextureView works with Buffer as a place holder for the Texture. + // TODO: For now TextureView works with Texture as a place holder for the Texture. // The overall logic should be about the same except that the Texture will be a real GL Texture under the hood class TextureView { public: diff --git a/libraries/render/src/render/EngineStats.cpp b/libraries/render/src/render/EngineStats.cpp index 63a25229ea..60cb309786 100644 --- a/libraries/render/src/render/EngineStats.cpp +++ b/libraries/render/src/render/EngineStats.cpp @@ -24,15 +24,21 @@ void EngineStats::run(const SceneContextPointer& sceneContext, const RenderConte // Update the stats auto config = std::static_pointer_cast(renderContext->jobConfig); - config->numBuffers = gpu::Buffer::getCurrentNumBuffers(); - config->numGPUBuffers = gpu::Buffer::getCurrentNumGPUBuffers(); - config->bufferSysmemUsage = gpu::Buffer::getCurrentSystemMemoryUsage(); - config->bufferVidmemUsage = gpu::Buffer::getCurrentVideoMemoryUsage(); + quint32 textureCPUCount{ 0 }; + quint32 textureGPUCount{ 0 }; + qint64 textureCPUMemoryUsage{ 0 }; + qint64 textureGPUMemoryUsage{ 0 }; - config->numTextures = gpu::Texture::getCurrentNumTextures(); - config->numGPUTextures = gpu::Texture::getCurrentNumGPUTextures(); - config->textureSysmemUsage = gpu::Texture::getCurrentSystemMemoryUsage(); - config->textureVidmemUsage = gpu::Texture::getCurrentVideoMemoryUsage(); + + config->bufferCPUCount = gpu::Buffer::getBufferCPUCount(); + config->bufferGPUCount = gpu::Buffer::getBufferGPUCount(); + config->bufferCPUMemoryUsage = gpu::Buffer::getBufferCPUMemoryUsage(); + config->bufferGPUMemoryUsage = gpu::Buffer::getBufferGPUMemoryUsage(); + + config->textureCPUCount = gpu::Texture::getTextureCPUCount(); + config->textureGPUCount = gpu::Texture::getTextureGPUCount(); + config->textureCPUMemoryUsage = gpu::Texture::getTextureCPUMemoryUsage(); + config->textureGPUMemoryUsage = gpu::Texture::getTextureGPUMemoryUsage(); gpu::ContextStats gpuStats(_gpuStats); renderContext->args->_context->getStats(_gpuStats); diff --git a/libraries/render/src/render/EngineStats.h b/libraries/render/src/render/EngineStats.h index d9f7e7ac9a..85946922b0 100644 --- a/libraries/render/src/render/EngineStats.h +++ b/libraries/render/src/render/EngineStats.h @@ -24,47 +24,47 @@ namespace render { 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(quint32 bufferCPUCount MEMBER bufferCPUCount NOTIFY dirty) + Q_PROPERTY(quint32 bufferGPUCount MEMBER bufferGPUCount NOTIFY dirty) + Q_PROPERTY(qint64 bufferCPUMemoryUsage MEMBER bufferCPUMemoryUsage NOTIFY dirty) + Q_PROPERTY(qint64 bufferGPUMemoryUsage MEMBER bufferGPUMemoryUsage 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(quint32 textureCPUCount MEMBER textureCPUCount NOTIFY dirty) + Q_PROPERTY(quint32 textureGPUCount MEMBER textureGPUCount NOTIFY dirty) + Q_PROPERTY(qint64 textureCPUMemoryUsage MEMBER textureCPUMemoryUsage NOTIFY dirty) + Q_PROPERTY(qint64 textureGPUMemoryUsage MEMBER textureGPUMemoryUsage NOTIFY dirty) - Q_PROPERTY(int frameDrawcallCount MEMBER frameDrawcallCount NOTIFY dirty) - Q_PROPERTY(int frameDrawcallRate MEMBER frameDrawcallRate NOTIFY dirty) + Q_PROPERTY(quint32 frameDrawcallCount MEMBER frameDrawcallCount NOTIFY dirty) + Q_PROPERTY(quint32 frameDrawcallRate MEMBER frameDrawcallRate NOTIFY dirty) - Q_PROPERTY(int frameTriangleCount MEMBER frameTriangleCount NOTIFY dirty) - Q_PROPERTY(int frameTriangleRate MEMBER frameTriangleRate NOTIFY dirty) + Q_PROPERTY(quint32 frameTriangleCount MEMBER frameTriangleCount NOTIFY dirty) + Q_PROPERTY(quint32 frameTriangleRate MEMBER frameTriangleRate NOTIFY dirty) - Q_PROPERTY(int frameTextureCount MEMBER frameTextureCount NOTIFY dirty) - Q_PROPERTY(int frameTextureRate MEMBER frameTextureRate NOTIFY dirty) + Q_PROPERTY(quint32 frameTextureCount MEMBER frameTextureCount NOTIFY dirty) + Q_PROPERTY(quint32 frameTextureRate MEMBER frameTextureRate NOTIFY dirty) public: EngineStatsConfig() : Job::Config(true) {} - int numBuffers{ 0 }; - int numGPUBuffers{ 0 }; - qint64 bufferSysmemUsage{ 0 }; - qint64 bufferVidmemUsage{ 0 }; + quint32 bufferCPUCount{ 0 }; + quint32 bufferGPUCount{ 0 }; + qint64 bufferCPUMemoryUsage{ 0 }; + qint64 bufferGPUMemoryUsage{ 0 }; - int numTextures{ 0 }; - int numGPUTextures{ 0 }; - qint64 textureSysmemUsage{ 0 }; - qint64 textureVidmemUsage{ 0 }; + quint32 textureCPUCount{ 0 }; + quint32 textureGPUCount{ 0 }; + qint64 textureCPUMemoryUsage{ 0 }; + qint64 textureGPUMemoryUsage{ 0 }; - int frameDrawcallCount{ 0 }; - int frameDrawcallRate{ 0 }; + quint32 frameDrawcallCount{ 0 }; + quint32 frameDrawcallRate{ 0 }; - int frameTriangleCount{ 0 }; - int frameTriangleRate{ 0 }; + quint32 frameTriangleCount{ 0 }; + quint32 frameTriangleRate{ 0 }; - int frameTextureCount{ 0 }; - int frameTextureRate{ 0 }; + quint32 frameTextureCount{ 0 }; + quint32 frameTextureRate{ 0 }; void emitDirty() { emit dirty(); } From 5a3896b1de88d5934c12171f2e568031a6ebe055 Mon Sep 17 00:00:00 2001 From: samcake Date: Sun, 27 Mar 2016 09:35:13 -0700 Subject: [PATCH 11/13] FIxing warnigns --- libraries/gpu/src/gpu/GLBackend.h | 7 ++++--- libraries/render/src/render/EngineStats.cpp | 7 ------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index c8e3be81d1..d4efe7fe99 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -74,19 +74,20 @@ public: static GLuint getBufferID(const Buffer& buffer); class GLTexture : public GPUObject { - GLuint _size; public: Stamp _storageStamp; Stamp _contentStamp; GLuint _texture; GLenum _target; + GLTexture(); + ~GLTexture(); void setSize(GLuint size); GLuint size() const { return _size; } - GLTexture(); - ~GLTexture(); + private: + GLuint _size; }; static GLTexture* syncGPUObject(const Texture& texture); static GLuint getTextureID(const TexturePointer& texture, bool sync = true); diff --git a/libraries/render/src/render/EngineStats.cpp b/libraries/render/src/render/EngineStats.cpp index 60cb309786..ee96e0cd86 100644 --- a/libraries/render/src/render/EngineStats.cpp +++ b/libraries/render/src/render/EngineStats.cpp @@ -20,16 +20,9 @@ void EngineStats::run(const SceneContextPointer& sceneContext, const RenderConte quint64 msecsElapsed = _frameTimer.restart(); double frequency = 1000.0 / msecsElapsed; - // Update the stats auto config = std::static_pointer_cast(renderContext->jobConfig); - quint32 textureCPUCount{ 0 }; - quint32 textureGPUCount{ 0 }; - qint64 textureCPUMemoryUsage{ 0 }; - qint64 textureGPUMemoryUsage{ 0 }; - - config->bufferCPUCount = gpu::Buffer::getBufferCPUCount(); config->bufferGPUCount = gpu::Buffer::getBufferGPUCount(); config->bufferCPUMemoryUsage = gpu::Buffer::getBufferCPUMemoryUsage(); From b5028acde1a878098ab5eba8962af2ad878a51be Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 28 Mar 2016 11:45:07 -0700 Subject: [PATCH 12/13] CLeaning up the location of the global variables, moved them to the gpu::COntext class as static --- libraries/gpu/src/gpu/Context.cpp | 65 ++++++++++++++++++++++ libraries/gpu/src/gpu/Context.h | 36 ++++++++++++ libraries/gpu/src/gpu/GLBackendBuffer.cpp | 16 ++---- libraries/gpu/src/gpu/GLBackendTexture.cpp | 16 ++---- libraries/gpu/src/gpu/Resource.cpp | 35 ++++++------ libraries/gpu/src/gpu/Resource.h | 4 -- libraries/gpu/src/gpu/Texture.cpp | 42 +++++++------- libraries/gpu/src/gpu/Texture.h | 5 -- 8 files changed, 146 insertions(+), 73 deletions(-) diff --git a/libraries/gpu/src/gpu/Context.cpp b/libraries/gpu/src/gpu/Context.cpp index 6148994a1b..b14c461bc5 100644 --- a/libraries/gpu/src/gpu/Context.cpp +++ b/libraries/gpu/src/gpu/Context.cpp @@ -107,3 +107,68 @@ Backend::TransformCamera Backend::TransformCamera::getEyeCamera(int eye, const S return result; } + +// Counters for Buffer and Texture usage in GPU/Context +std::atomic Context::_bufferGPUCount{ 0 }; +std::atomic Context::_bufferGPUMemoryUsage{ 0 }; + +std::atomic Context::_textureGPUCount{ 0 }; +std::atomic Context::_textureGPUMemoryUsage{ 0 }; + +void Context::incrementBufferGPUCount() { + _bufferGPUCount++; +} +void Context::decrementBufferGPUCount() { + _bufferGPUCount--; +} +void Context::updateBufferGPUMemoryUsage(Size prevObjectSize, Size newObjectSize) { + if (prevObjectSize == newObjectSize) { + return; + } + if (newObjectSize > prevObjectSize) { + _bufferGPUMemoryUsage.fetch_add(newObjectSize - prevObjectSize); + } else { + _bufferGPUMemoryUsage.fetch_sub(prevObjectSize - newObjectSize); + } +} + +void Context::incrementTextureGPUCount() { + _textureGPUCount++; +} +void Context::decrementTextureGPUCount() { + _textureGPUCount--; +} +void Context::updateTextureGPUMemoryUsage(Size prevObjectSize, Size newObjectSize) { + if (prevObjectSize == newObjectSize) { + return; + } + if (newObjectSize > prevObjectSize) { + _textureGPUMemoryUsage.fetch_add(newObjectSize - prevObjectSize); + } else { + _textureGPUMemoryUsage.fetch_sub(prevObjectSize - newObjectSize); + } +} + +uint32_t Context::getBufferGPUCount() { + return _bufferGPUCount.load(); +} + +Context::Size Context::getBufferGPUMemoryUsage() { + return _bufferGPUMemoryUsage.load(); +} + +uint32_t Context::getTextureGPUCount() { + return _textureGPUCount.load(); +} + +Context::Size Context::getTextureGPUMemoryUsage() { + return _textureGPUMemoryUsage.load(); +} + +void Backend::incrementBufferGPUCount() { Context::incrementBufferGPUCount(); } +void Backend::decrementBufferGPUCount() { Context::decrementBufferGPUCount(); } +void Backend::updateBufferGPUMemoryUsage(Resource::Size prevObjectSize, Resource::Size newObjectSize) { Context::updateBufferGPUMemoryUsage(prevObjectSize, newObjectSize); } +void Backend::incrementTextureGPUCount() { Context::incrementTextureGPUCount(); } +void Backend::decrementTextureGPUCount() { Context::decrementTextureGPUCount(); } +void Backend::updateTextureGPUMemoryUsage(Resource::Size prevObjectSize, Resource::Size newObjectSize) { Context::updateTextureGPUMemoryUsage(prevObjectSize, newObjectSize); } + diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index c2cd1f239e..b898bddef9 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -117,6 +117,17 @@ public: void getStats(ContextStats& stats) const { stats = _stats; } + + + // These should only be accessed by Backend implementation to repport the buffer and texture allocations, + // they are NOT public calls + static void incrementBufferGPUCount(); + static void decrementBufferGPUCount(); + static void updateBufferGPUMemoryUsage(Resource::Size prevObjectSize, Resource::Size newObjectSize); + static void incrementTextureGPUCount(); + static void decrementTextureGPUCount(); + static void updateTextureGPUMemoryUsage(Resource::Size prevObjectSize, Resource::Size newObjectSize); + protected: StereoState _stereo; ContextStats _stats; @@ -124,6 +135,7 @@ protected: class Context { public: + using Size = Resource::Size; typedef Backend* (*CreateBackend)(); typedef bool (*MakeProgram)(Shader& shader, const Shader::BindingSet& bindings); @@ -158,6 +170,13 @@ public: // Repporting stats of the context void getStats(ContextStats& stats) const; + + static uint32_t getBufferGPUCount(); + static Size getBufferGPUMemoryUsage(); + + static uint32_t getTextureGPUCount(); + static Size getTextureGPUMemoryUsage(); + protected: Context(const Context& context); @@ -174,6 +193,23 @@ protected: static std::once_flag _initialized; friend class Shader; + + // These should only be accessed by the Backend, they are NOT public calls + static void incrementBufferGPUCount(); + static void decrementBufferGPUCount(); + static void updateBufferGPUMemoryUsage(Size prevObjectSize, Size newObjectSize); + static void incrementTextureGPUCount(); + static void decrementTextureGPUCount(); + static void updateTextureGPUMemoryUsage(Size prevObjectSize, Size newObjectSize); + + // Buffer and Texture Counters + static std::atomic _bufferGPUCount; + static std::atomic _bufferGPUMemoryUsage; + + static std::atomic _textureGPUCount; + static std::atomic _textureGPUMemoryUsage; + + friend class Backend; }; typedef std::shared_ptr ContextPointer; diff --git a/libraries/gpu/src/gpu/GLBackendBuffer.cpp b/libraries/gpu/src/gpu/GLBackendBuffer.cpp index 8b8af386bb..080d743104 100755 --- a/libraries/gpu/src/gpu/GLBackendBuffer.cpp +++ b/libraries/gpu/src/gpu/GLBackendBuffer.cpp @@ -17,27 +17,19 @@ GLBackend::GLBuffer::GLBuffer() : _buffer(0), _size(0) { - Buffer::_bufferGPUCount++; + Backend::incrementBufferGPUCount(); } GLBackend::GLBuffer::~GLBuffer() { if (_buffer != 0) { glDeleteBuffers(1, &_buffer); } - Buffer::_bufferGPUMemoryUsage.fetch_sub(_size); - Buffer::_bufferGPUCount--; + Backend::updateBufferGPUMemoryUsage(_size, 0); + Backend::decrementBufferGPUCount(); } void GLBackend::GLBuffer::setSize(GLuint size) { - if (_size == size) { - return; - } - if (size > _size) { - Buffer::_bufferGPUMemoryUsage.fetch_add(size - _size); - } else { - Buffer::_bufferGPUMemoryUsage.fetch_sub(_size - size); - } - + Backend::updateBufferGPUMemoryUsage(_size, size); _size = size; } diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index bc25048a3f..09714b5542 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -20,27 +20,19 @@ GLBackend::GLTexture::GLTexture() : _target(GL_TEXTURE_2D), _size(0) { - Texture::_textureGPUCount++; + Backend::incrementTextureGPUCount(); } GLBackend::GLTexture::~GLTexture() { if (_texture != 0) { glDeleteTextures(1, &_texture); } - Texture::_textureGPUMemoryUsage.fetch_sub(_size); - Texture::_textureGPUCount--; + Backend::updateTextureGPUMemoryUsage(_size, 0); + Backend::decrementTextureGPUCount(); } void GLBackend::GLTexture::setSize(GLuint size) { - if (_size == size) { - return; - } - if (size > _size) { - Texture::_textureGPUMemoryUsage.fetch_add(size - _size); - } else { - Texture::_textureGPUMemoryUsage.fetch_sub(_size - size); - } - + Backend::updateTextureGPUMemoryUsage(_size, size); _size = size; } diff --git a/libraries/gpu/src/gpu/Resource.cpp b/libraries/gpu/src/gpu/Resource.cpp index f10d95c03b..c793a92b72 100644 --- a/libraries/gpu/src/gpu/Resource.cpp +++ b/libraries/gpu/src/gpu/Resource.cpp @@ -16,6 +16,8 @@ #include #include +#include "Context.h" + using namespace gpu; class AllocationDebugger { @@ -233,25 +235,7 @@ Resource::Size Resource::Sysmem::append(Size size, const Byte* bytes) { } std::atomic Buffer::_bufferCPUCount{ 0 }; -std::atomic Buffer::_bufferGPUCount{ 0 }; std::atomic Buffer::_bufferCPUMemoryUsage{ 0 }; -std::atomic Buffer::_bufferGPUMemoryUsage{ 0 }; - -uint32_t Buffer::getBufferCPUCount() { - return _bufferCPUCount.load(); -} - -Buffer::Size Buffer::getBufferCPUMemoryUsage() { - return _bufferCPUMemoryUsage.load(); -} - -uint32_t Buffer::getBufferGPUCount() { - return _bufferGPUCount.load(); -} - -Buffer::Size Buffer::getBufferGPUMemoryUsage() { - return _bufferGPUMemoryUsage.load(); -} void Buffer::updateBufferCPUMemoryUsage(Size prevObjectSize, Size newObjectSize) { if (prevObjectSize == newObjectSize) { @@ -264,6 +248,21 @@ void Buffer::updateBufferCPUMemoryUsage(Size prevObjectSize, Size newObjectSize) } } +uint32_t Buffer::getBufferCPUCount() { + return _bufferCPUCount.load(); +} + +Buffer::Size Buffer::getBufferCPUMemoryUsage() { + return _bufferCPUMemoryUsage.load(); +} + +uint32_t Buffer::getBufferGPUCount() { + return Context::getBufferGPUCount(); +} + +Buffer::Size Buffer::getBufferGPUMemoryUsage() { + return Context::getBufferGPUMemoryUsage(); +} Buffer::Buffer() : Resource(), diff --git a/libraries/gpu/src/gpu/Resource.h b/libraries/gpu/src/gpu/Resource.h index 176e33a428..98ad0a2d28 100644 --- a/libraries/gpu/src/gpu/Resource.h +++ b/libraries/gpu/src/gpu/Resource.h @@ -114,10 +114,6 @@ class Buffer : public Resource { static std::atomic _bufferCPUMemoryUsage; static void updateBufferCPUMemoryUsage(Size prevObjectSize, Size newObjectSize); -public: - static std::atomic _bufferGPUCount; - static std::atomic _bufferGPUMemoryUsage; - public: static uint32_t getBufferCPUCount(); static Size getBufferCPUMemoryUsage(); diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 15ad4eea97..df93cd76a5 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -13,31 +13,13 @@ #include #include "GPULogging.h" -//#include +#include "Context.h" using namespace gpu; std::atomic Texture::_textureCPUCount{ 0 }; -std::atomic Texture::_textureGPUCount{ 0 }; std::atomic Texture::_textureCPUMemoryUsage{ 0 }; -std::atomic Texture::_textureGPUMemoryUsage{ 0 }; - -uint32_t Texture::getTextureCPUCount() { - return _textureCPUCount.load(); -} - -Texture::Size Texture::getTextureCPUMemoryUsage() { - return _textureCPUMemoryUsage.load(); -} - -uint32_t Texture::getTextureGPUCount() { - return _textureGPUCount.load(); -} - -Texture::Size Texture::getTextureGPUMemoryUsage() { - return _textureGPUMemoryUsage.load(); -} void Texture::updateTextureCPUMemoryUsage(Size prevObjectSize, Size newObjectSize) { if (prevObjectSize == newObjectSize) { @@ -50,6 +32,22 @@ void Texture::updateTextureCPUMemoryUsage(Size prevObjectSize, Size newObjectSiz } } +uint32_t Texture::getTextureCPUCount() { + return _textureCPUCount.load(); +} + +Texture::Size Texture::getTextureCPUMemoryUsage() { + return _textureCPUMemoryUsage.load(); +} + +uint32_t Texture::getTextureGPUCount() { + return Context::getTextureGPUCount(); +} + +Texture::Size Texture::getTextureGPUMemoryUsage() { + return Context::getTextureGPUMemoryUsage(); + +} uint8 Texture::NUM_FACES_PER_TYPE[NUM_TYPES] = {1, 1, 1, 6}; @@ -118,9 +116,9 @@ 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 (mipFace) { - mipFace->notifyGPULoaded(); + // Free the mips + if (mipFace) { + mipFace->notifyGPULoaded(); } } diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index c498b5cc22..80fbc867e3 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -141,11 +141,6 @@ class Texture : public Resource { static std::atomic _textureCPUCount; static std::atomic _textureCPUMemoryUsage; static void updateTextureCPUMemoryUsage(Size prevObjectSize, Size newObjectSize); - -public: - static std::atomic _textureGPUCount; - static std::atomic _textureGPUMemoryUsage; - public: static uint32_t getTextureCPUCount(); static Size getTextureCPUMemoryUsage(); From aa085f69559e020e82632bd68918abae9a6579c0 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 28 Mar 2016 11:52:31 -0700 Subject: [PATCH 13/13] Putting members of the ENgineStats class NOT public so they can keep their name proudly --- libraries/render/src/render/EngineStats.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libraries/render/src/render/EngineStats.h b/libraries/render/src/render/EngineStats.h index 85946922b0..478d94855e 100644 --- a/libraries/render/src/render/EngineStats.h +++ b/libraries/render/src/render/EngineStats.h @@ -73,18 +73,16 @@ namespace render { }; class EngineStats { + gpu::ContextStats _gpuStats; + QElapsedTimer _frameTimer; public: using Config = EngineStatsConfig; using JobModel = Job::Model; EngineStats() { _frameTimer.start(); } - gpu::ContextStats _gpuStats; - void configure(const Config& configuration) {} void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); - - QElapsedTimer _frameTimer; }; }