On-screen Profiler / Debug visualizations in progress

Fixed a bug that caused framerate to drop drastically by executing an additional render pass.
This commit is contained in:
2013-03-21 19:58:35 -07:00
parent 98df6e7e87
commit a23b39a178
24 changed files with 147 additions and 42 deletions

View File

@@ -114,7 +114,7 @@ void KRAmbientZone::render(KRCamera *pCamera, std::vector<KRLight *> &lights, co
std::vector<KRMesh *> sphereModels = getContext().getModelManager()->getModel("__sphere");
if(sphereModels.size()) {
for(int i=0; i < sphereModels[0]->getSubmeshCount(); i++) {
sphereModels[0]->renderSubmesh(i);
sphereModels[0]->renderSubmesh(i, renderPass, getName(), "visualize_overlay");
}
}

View File

@@ -225,7 +225,7 @@ void KRAudioSource::render(KRCamera *pCamera, std::vector<KRLight *> &lights, co
std::vector<KRMesh *> sphereModels = getContext().getModelManager()->getModel("__sphere");
if(sphereModels.size()) {
for(int i=0; i < sphereModels[0]->getSubmeshCount(); i++) {
sphereModels[0]->renderSubmesh(i);
sphereModels[0]->renderSubmesh(i, renderPass, getName(), "visualize_overlay");
}
}

View File

@@ -64,7 +64,7 @@ void KRBone::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRV
std::vector<KRMesh *> sphereModels = getContext().getModelManager()->getModel("__sphere");
if(sphereModels.size()) {
for(int i=0; i < sphereModels[0]->getSubmeshCount(); i++) {
sphereModels[0]->renderSubmesh(i);
sphereModels[0]->renderSubmesh(i, renderPass, getName(), "visualize_overlay");
}
}

View File

@@ -179,7 +179,9 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0));
} else {
// ----====---- Generate Shadowmaps for Lights ----====----
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, true);
if(settings.m_cShadowBuffers > 0) {
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, true);
}
// ----====---- Opaque Geometry, Forward Rendering ----====----
// Set render target
@@ -831,11 +833,11 @@ std::string KRCamera::getDebugText()
stream << "Textures\t" << texture_count_active << "\t" << texture_count << "\t" << (texture_mem_active / 1024) << " Kb\t" << (texture_mem_used / 1024) << " Kb\t" << (texture_mem_throughput / 1024) << " Kb / frame\n";
stream << "VBO's\t" << vbo_count_active << "\t" << vbo_count_active + vbo_count_pooled << "\t" << (vbo_mem_active / 1024) <<" Kb\t" << (vbo_mem_used / 1024) << " Kb\t" << (vbo_mem_throughput / 1024) << " Kb / frame\n";
stream << "\nTOTAL\t\t\t" << (total_mem_active / 1024) << " Kb\t" << (total_mem_used / 1024) << " Kb\t" << (total_mem_throughput / 1024) << " Kb / frame";
stream << "\nGPU Total\t\t\t" << (total_mem_active / 1024) << " Kb\t" << (total_mem_used / 1024) << " Kb\t" << (total_mem_throughput / 1024) << " Kb / frame";
}
break;
case 2: // ----====---- Show active textures ----====----
case 2: // ----====---- List Active Textures ----====----
{
bool first = true;
int texture_count = 0;
@@ -850,21 +852,70 @@ std::string KRCamera::getDebugText()
stream << texture->getName();
stream << "\t";
stream << texture->getMemSize() / 1024;
stream << "kB";
stream << " kB";
stream << "\t";
stream << texture->getMaxMipMap();
if(texture->getCurrentLodMaxDim() != texture->getMaxMipMap()) {
stream << "px => ";
if(texture->hasMipmaps() && texture->getCurrentLodMaxDim() != texture->getMaxMipMap()) {
stream << " px => ";
stream << texture->getCurrentLodMaxDim();
}
stream << "px";
stream << " px";
texture_count++;
}
stream << "\n\nTOTAL: ";
stream << texture_count;
stream << " textures\t";
stream << (m_pContext->getTextureManager()->getMemActive() / 1024) << " Kb\t" << (m_pContext->getTextureManager()->getMemoryTransferedThisFrame() / 1024) << " Kb / Frame";
stream << (m_pContext->getTextureManager()->getMemActive() / 1024) << " Kb";
}
break;
case 3: // ----====---- List Draw Calls ----====----
{
std::vector<KRMeshManager::draw_call_info> draw_calls = m_pContext->getModelManager()->getDrawCalls();
long draw_call_count = 0;
long vertex_count = 0;
stream << "\tVerts\tPass\tObject\tMaterial";
for(std::vector<KRMeshManager::draw_call_info>::iterator itr = draw_calls.begin(); itr != draw_calls.end(); itr++) {
draw_call_count++;
stream << "\n" << draw_call_count << "\t" << (*itr).vertex_count << "\t";
switch((*itr).pass) {
case KRNode::RENDER_PASS_FORWARD_OPAQUE:
stream << "opaq";
break;
case KRNode::RENDER_PASS_DEFERRED_GBUFFER:
stream << "d gb";
break;
case KRNode::RENDER_PASS_DEFERRED_LIGHTS:
stream << "d light";
break;
case KRNode::RENDER_PASS_DEFERRED_OPAQUE:
stream << "d opaq";
break;
case KRNode::RENDER_PASS_FORWARD_TRANSPARENT:
stream << "trans";
break;
case KRNode::RENDER_PASS_PARTICLE_OCCLUSION:
stream << "p occl";
break;
case KRNode::RENDER_PASS_ADDITIVE_PARTICLES:
stream << "a part";
break;
case KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE:
stream << "vol add";
break;
case KRNode::RENDER_PASS_GENERATE_SHADOWMAPS:
stream << "g shadow";
break;
case KRNode::RENDER_PASS_SHADOWMAP:
stream << "shadow";
break;
}
stream << "\t" << (*itr).object_name << "\t" << (*itr).material_name;
vertex_count += (*itr).vertex_count;
}
stream << "\n\n\t\tTOTAL:\t" << draw_call_count << " draw calls\t" << vertex_count << " vertices";
}
break;
}

View File

@@ -202,6 +202,7 @@ void KRContext::endFrame(float deltaTime)
{
m_pTextureManager->endFrame(deltaTime);
m_pAnimationManager->endFrame(deltaTime);
m_pModelManager->endFrame(deltaTime);
rotateBuffers(true);
m_current_frame++;
m_absolute_time += deltaTime;
@@ -216,3 +217,4 @@ float KRContext::getAbsoluteTime() const
{
return m_absolute_time;
}

View File

@@ -69,6 +69,7 @@ public:
long getCurrentFrame() const;
float getAbsoluteTime() const;
private:
KRBundleManager *m_pBundleManager;
KRSceneManager *m_pSceneManager;
@@ -87,7 +88,6 @@ private:
long m_current_frame;
float m_absolute_time;
mach_timebase_info_data_t m_timebase_info;
};

View File

@@ -622,7 +622,7 @@ void kraken::set_parameter(const std::string &parameter_name, float parameter_va
1.0f, 10.0f, 2.0f, 1.0f, 1.0f, 1.0f, 5.0f, 1.0f, 0.5f, 1.0f,
2.0f, 2.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 10.0f, 1000.0f, 1.0f, 5.0f, 1000.0f, 1.0f, 5.0f, 3.0f,
1000.0f, 1000.0f, 0.01f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f
1000.0f, 1000.0f, 0.01f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f
};
return maxValues[i];

View File

@@ -268,7 +268,7 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KR
std::vector<KRMesh *> sphereModels = getContext().getModelManager()->getModel("__sphere");
if(sphereModels.size()) {
for(int i=0; i < sphereModels[0]->getSubmeshCount(); i++) {
sphereModels[0]->renderSubmesh(i);
sphereModels[0]->renderSubmesh(i, renderPass, getName(), "occlusion_test");
}
}

View File

@@ -37,7 +37,7 @@
#include "KRcontext.h"
KRMaterial::KRMaterial(KRContext &context, const char *szName) : KRResource(context, szName) {
strcpy(m_szName, szName);
m_name = szName;
m_pAmbientMap = NULL;
m_pDiffuseMap = NULL;
m_pSpecularMap = NULL;
@@ -80,7 +80,7 @@ bool KRMaterial::save(KRDataBlock &data) {
stream.precision(std::numeric_limits<long double>::digits10);
stream.setf(std::ios::fixed,std::ios::floatfield);
stream << "newmtl " << m_szName;
stream << "newmtl " << m_name;
stream << "\nka " << m_ambientColor.x << " " << m_ambientColor.y << " " << m_ambientColor.z;
stream << "\nkd " << m_diffuseColor.x << " " << m_diffuseColor.y << " " << m_diffuseColor.z;
stream << "\nks " << m_specularColor.x << " " << m_specularColor.y << " " << m_specularColor.z;
@@ -406,6 +406,8 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC
return true;
}
char *KRMaterial::getName() {
return m_szName;
const std::string &KRMaterial::getName() const
{
return m_name;
}

View File

@@ -81,12 +81,12 @@ public:
bool isTransparent();
char *getName();
const std::string &getName() const;
bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRCamera *pCamera, std::vector<KRLight *> &lights, const std::vector<KRBone *> &bones, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass);
private:
char m_szName[256];
std::string m_name;
KRTexture *m_pAmbientMap; // mtl map_Ka value
KRTexture *m_pDiffuseMap; // mtl map_Kd value

View File

@@ -131,7 +131,7 @@ void KRMesh::loadPack(KRDataBlock *data) {
m_maxPoint = KRVector3(pHeader->maxx, pHeader->maxy, pHeader->maxz);
}
void KRMesh::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector<KRBone *> &bones) {
void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector<KRBone *> &bones) {
//fprintf(stderr, "Rendering model: %s\n", m_name.c_str());
if(renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
@@ -171,7 +171,7 @@ void KRMesh::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRV
if(!pMaterial->isTransparent()) {
// Exclude transparent and semi-transparent meshes from shadow maps
renderSubmesh(iSubmesh);
renderSubmesh(iSubmesh, renderPass, object_name, pMaterial->getName());
}
}
@@ -189,19 +189,19 @@ void KRMesh::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRV
switch(pMaterial->getAlphaMode()) {
case KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE: // Non-transparent materials
case KRMaterial::KRMATERIAL_ALPHA_MODE_TEST: // Alpha in diffuse texture is interpreted as punch-through when < 0.5
renderSubmesh(iSubmesh);
renderSubmesh(iSubmesh, renderPass, object_name, pMaterial->getName());
break;
case KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE: // Blended alpha with backface culling
renderSubmesh(iSubmesh);
renderSubmesh(iSubmesh, renderPass, object_name, pMaterial->getName());
break;
case KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE: // Blended alpha rendered in two passes. First pass renders backfaces; second pass renders frontfaces.
// Render back faces first
GLDEBUG(glCullFace(GL_BACK));
renderSubmesh(iSubmesh);
renderSubmesh(iSubmesh, renderPass, object_name, pMaterial->getName());
// Render front faces second
GLDEBUG(glCullFace(GL_BACK));
renderSubmesh(iSubmesh);
renderSubmesh(iSubmesh, renderPass, object_name, pMaterial->getName());
break;
}
}
@@ -249,7 +249,7 @@ vector<KRMesh::Submesh *> KRMesh::getSubmeshes() {
return m_submeshes;
}
void KRMesh::renderSubmesh(int iSubmesh) {
void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const std::string &object_name, const std::string &material_name) {
unsigned char *pVertexData = getVertexData();
pack_header *pHeader = getHeader();
@@ -294,6 +294,7 @@ void KRMesh::renderSubmesh(int iSubmesh) {
default:
break;
}
m_pContext->getModelManager()->log_draw_call(renderPass, object_name, material_name, (MAX_VBO_SIZE - iVertex));
cVertexes -= (MAX_VBO_SIZE - iVertex);
iVertex = 0;
@@ -311,6 +312,7 @@ void KRMesh::renderSubmesh(int iSubmesh) {
default:
break;
}
m_pContext->getModelManager()->log_draw_call(renderPass, object_name, material_name, cVertexes);
cVertexes = 0;
}

View File

@@ -83,7 +83,7 @@ public:
} model_format_t;
void render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector<KRBone *> &bones);
void render(const std::string &object_name, KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector<KRBone *> &bones);
std::string m_lodBaseName;
@@ -97,7 +97,7 @@ public:
void convert(model_format_t model_format);
void optimize();
void renderSubmesh(int iSubmesh);
void renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const std::string &object_name, const std::string &material_name);
GLfloat getMaxDimension();

View File

@@ -50,6 +50,8 @@ KRMeshManager::KRMeshManager(KRContext &context) : KRContextObject(context) {
// addModel(new KRMeshCube(context)); // FINDME - HACK! This needs to be fixed, as it currently segfaults
addModel(new KRMeshSphere(context));
m_draw_call_logging_enabled = false;
m_draw_call_log_used = false;
}
KRMeshManager::~KRMeshManager() {
@@ -403,6 +405,18 @@ KRMeshManager::RandomParticleVertexData *KRMeshManager::getRandomParticles()
void KRMeshManager::startFrame(float deltaTime)
{
m_memoryTransferredThisFrame = 0;
if(m_draw_call_log_used) {
// Only log draw calls on the next frame if the draw call log was used on last frame
m_draw_call_log_used = false;
m_draw_call_logging_enabled = true;
}
m_draw_calls.clear();
}
void KRMeshManager::endFrame(float deltaTime)
{
}
long KRMeshManager::getMemoryTransferedThisFrame()
@@ -420,3 +434,21 @@ int KRMeshManager::getPoolVBOCount()
{
return m_vbosPool.size();
}
void KRMeshManager::log_draw_call(KRNode::RenderPass pass, const std::string &object_name, const std::string &material_name, int vertex_count)
{
if(m_draw_call_logging_enabled) {
draw_call_info info;
info.pass = pass;
strncpy(info.object_name, object_name.c_str(), 256);
strncpy(info.material_name, material_name.c_str(), 256);
info.vertex_count = vertex_count;
m_draw_calls.push_back(info);
}
}
std::vector<KRMeshManager::draw_call_info> KRMeshManager::getDrawCalls()
{
m_draw_call_log_used = true;
return m_draw_calls;
}

View File

@@ -35,6 +35,7 @@
#include "KREngine-common.h"
#include "KRContextObject.h"
#include "KRDataBlock.h"
#include "KRNode.h"
class KRContext;
class KRMesh;
@@ -49,6 +50,7 @@ public:
void rotateBuffers(bool new_frame);
void startFrame(float deltaTime);
void endFrame(float deltaTime);
KRMesh *loadModel(const char *szName, KRDataBlock *pData);
std::vector<KRMesh *> getModel(const char *szName);
@@ -99,6 +101,16 @@ public:
int getActiveVBOCount();
int getPoolVBOCount();
struct draw_call_info {
KRNode::RenderPass pass;
char object_name[256];
char material_name[256];
int vertex_count;
};
void log_draw_call(KRNode::RenderPass pass, const std::string &object_name, const std::string &material_name, int vertex_count);
std::vector<draw_call_info> getDrawCalls();
private:
std::multimap<std::string, KRMesh *> m_models; // Multiple models with the same name/key may be inserted, representing multiple LOD levels of the model
@@ -121,6 +133,10 @@ private:
VolumetricLightingVertexData *m_volumetricLightingVertexData;
long m_memoryTransferredThisFrame;
std::vector<draw_call_info> m_draw_calls;
bool m_draw_call_logging_enabled;
bool m_draw_call_log_used;
};

View File

@@ -98,7 +98,7 @@ void KRModel::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KR
KRNode::render(pCamera, lights, viewport, renderPass);
if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE && renderPass != KRNode::RENDER_PASS_GENERATE_SHADOWMAPS) {
loadModel();
if(m_models.size() > 0) {
@@ -136,7 +136,7 @@ void KRModel::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KR
matModel = KRQuaternion(KRVector3::Forward(), KRVector3::Normalize(camera_pos - model_center)).rotationMatrix() * matModel;
}
pModel->render(pCamera, lights, viewport, matModel, m_pLightMap, renderPass, m_bones[pModel]);
pModel->render(getName(), pCamera, lights, viewport, matModel, m_pLightMap, renderPass, m_bones[pModel]);
}
}
}

View File

@@ -262,7 +262,7 @@ const std::vector<KRNode *> &KRNode::getChildren() {
return m_childNodes;
}
const std::string &KRNode::getName() {
const std::string &KRNode::getName() const {
return m_name;
}

View File

@@ -50,7 +50,7 @@ public:
virtual void loadXML(tinyxml2::XMLElement *e);
virtual std::string getElementName();
const std::string &getName();
const std::string &getName() const;
void addChild(KRNode *child);
const std::vector<KRNode *> &getChildren();

View File

@@ -113,7 +113,7 @@ void KRReverbZone::render(KRCamera *pCamera, std::vector<KRLight *> &lights, con
std::vector<KRMesh *> sphereModels = getContext().getModelManager()->getModel("__sphere");
if(sphereModels.size()) {
for(int i=0; i < sphereModels[0]->getSubmeshCount(); i++) {
sphereModels[0]->renderSubmesh(i);
sphereModels[0]->renderSubmesh(i, renderPass, getName(), "visualize_overlay");
}
}

View File

@@ -238,7 +238,7 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &
int light_point_count = 0;
int light_spot_count = 0;
// TODO - Need to support multiple lights and more light types in forward rendering
if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_DEFERRED_GBUFFER && renderPass != KRNode::RENDER_PASS_DEFERRED_OPAQUE) {
if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_DEFERRED_GBUFFER && renderPass != KRNode::RENDER_PASS_DEFERRED_OPAQUE && renderPass != KRNode::RENDER_PASS_GENERATE_SHADOWMAPS) {
for(std::vector<KRLight *>::const_iterator light_itr=lights.begin(); light_itr != lights.end(); light_itr++) {
KRLight *light = (*light_itr);
KRDirectionalLight *directional_light = dynamic_cast<KRDirectionalLight *>(light);

View File

@@ -63,7 +63,7 @@ KRShader *KRShaderManager::getShader(const std::string &shader_name, KRCamera *p
int light_directional_count = 0;
int light_point_count = 0;
int light_spot_count = 0;
if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_DEFERRED_GBUFFER && renderPass != KRNode::RENDER_PASS_DEFERRED_OPAQUE) {
if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_DEFERRED_GBUFFER && renderPass != KRNode::RENDER_PASS_DEFERRED_OPAQUE && renderPass != KRNode::RENDER_PASS_GENERATE_SHADOWMAPS) {
for(std::vector<KRLight *>::const_iterator light_itr=lights.begin(); light_itr != lights.end(); light_itr++) {
KRLight *light = (*light_itr);
KRDirectionalLight *directional_light = dynamic_cast<KRDirectionalLight *>(light);

View File

@@ -146,3 +146,7 @@ int KRTexture::getMaxMipMap() {
int KRTexture::getMinMipMap() {
return m_min_lod_max_dim;
}
bool KRTexture::hasMipmaps() {
return m_max_lod_max_dim != m_min_lod_max_dim;
}

View File

@@ -64,7 +64,8 @@ public:
int getCurrentLodMaxDim();
int getMaxMipMap();
int getMinMipMap();
bool hasMipmaps();
protected:
virtual bool createGLTexture(int lod_max_dim) = 0;
GLuint getHandle();

View File

@@ -79,9 +79,6 @@ void KRTexture2D::bind() {
}
}
bool KRTexture2D::hasMipmaps() {
return m_max_lod_max_dim != m_min_lod_max_dim;
}
bool KRTexture2D::save(const std::string& path)
{

View File

@@ -46,8 +46,6 @@ public:
virtual bool save(const std::string& path);
virtual bool save(KRDataBlock &data);
bool hasMipmaps();
virtual bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed) = 0;
virtual void bind();