Adding diagnostics to track down the 'black rectangles of death'

This commit is contained in:
Brad Davis 2015-11-02 21:55:35 -08:00
parent 61109d09af
commit 764ecba2a8
5 changed files with 99 additions and 5 deletions

View file

@ -73,6 +73,7 @@ namespace render {
avatarPtr->setDisplayingLookatTarget(renderLookAtTarget); avatarPtr->setDisplayingLookatTarget(renderLookAtTarget);
if (avatarPtr->isInitialized() && args) { if (avatarPtr->isInitialized() && args) {
PROFILE_RANGE_BATCH(*args->_batch, "renderAvatarPayload");
avatarPtr->render(args, qApp->getCamera()->getPosition()); avatarPtr->render(args, qApp->getCamera()->getPosition());
} }
} }
@ -334,6 +335,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
} }
auto& batch = *renderArgs->_batch; auto& batch = *renderArgs->_batch;
PROFILE_RANGE_BATCH(batch, __FUNCTION__);
if (glm::distance(DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition(), _position) < 10.0f) { if (glm::distance(DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition(), _position) < 10.0f) {
auto geometryCache = DependencyManager::get<GeometryCache>(); auto geometryCache = DependencyManager::get<GeometryCache>();
@ -360,6 +362,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
} }
if (havePosition && haveRotation) { if (havePosition && haveRotation) {
PROFILE_RANGE_BATCH(batch, __FUNCTION__":leftHandPointer");
Transform pointerTransform; Transform pointerTransform;
pointerTransform.setTranslation(position); pointerTransform.setTranslation(position);
pointerTransform.setRotation(rotation); pointerTransform.setRotation(rotation);
@ -383,6 +386,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
} }
if (havePosition && haveRotation) { if (havePosition && haveRotation) {
PROFILE_RANGE_BATCH(batch, __FUNCTION__":rightHandPointer");
Transform pointerTransform; Transform pointerTransform;
pointerTransform.setTranslation(position); pointerTransform.setTranslation(position);
pointerTransform.setRotation(rotation); pointerTransform.setRotation(rotation);
@ -455,6 +459,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
bool renderBounding = Menu::getInstance()->isOptionChecked(MenuOption::RenderBoundingCollisionShapes); bool renderBounding = Menu::getInstance()->isOptionChecked(MenuOption::RenderBoundingCollisionShapes);
if (renderBounding && shouldRenderHead(renderArgs) && _skeletonModel.isRenderable()) { if (renderBounding && shouldRenderHead(renderArgs) && _skeletonModel.isRenderable()) {
PROFILE_RANGE_BATCH(batch, __FUNCTION__":skeletonBoundingCollisionShapes");
_skeletonModel.renderBoundingCollisionShapes(*renderArgs->_batch, 0.7f); _skeletonModel.renderBoundingCollisionShapes(*renderArgs->_batch, 0.7f);
} }
@ -464,6 +469,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
static const float INDICATOR_RADIUS = 0.03f; static const float INDICATOR_RADIUS = 0.03f;
static const glm::vec4 LOOK_AT_INDICATOR_COLOR = { 0.8f, 0.0f, 0.0f, 0.75f }; static const glm::vec4 LOOK_AT_INDICATOR_COLOR = { 0.8f, 0.0f, 0.0f, 0.75f };
glm::vec3 position = glm::vec3(_position.x, getDisplayNamePosition().y + INDICATOR_OFFSET, _position.z); glm::vec3 position = glm::vec3(_position.x, getDisplayNamePosition().y + INDICATOR_OFFSET, _position.z);
PROFILE_RANGE_BATCH(batch, __FUNCTION__":renderFocusIndicator");
Transform transform; Transform transform;
transform.setTranslation(position); transform.setTranslation(position);
transform.postScale(INDICATOR_RADIUS); transform.postScale(INDICATOR_RADIUS);
@ -472,6 +478,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
// If the avatar is looking at me, indicate that they are // If the avatar is looking at me, indicate that they are
if (getHead()->isLookingAtMe() && Menu::getInstance()->isOptionChecked(MenuOption::ShowWhosLookingAtMe)) { if (getHead()->isLookingAtMe() && Menu::getInstance()->isOptionChecked(MenuOption::ShowWhosLookingAtMe)) {
PROFILE_RANGE_BATCH(batch, __FUNCTION__":renderLookingAtMe");
const glm::vec3 LOOKING_AT_ME_COLOR = { 1.0f, 1.0f, 1.0f }; const glm::vec3 LOOKING_AT_ME_COLOR = { 1.0f, 1.0f, 1.0f };
const float LOOKING_AT_ME_ALPHA_START = 0.8f; const float LOOKING_AT_ME_ALPHA_START = 0.8f;
const float LOOKING_AT_ME_DURATION = 0.5f; // seconds const float LOOKING_AT_ME_DURATION = 0.5f; // seconds
@ -517,6 +524,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
const float MIN_VOICE_SPHERE_DISTANCE = 12.0f; const float MIN_VOICE_SPHERE_DISTANCE = 12.0f;
if (Menu::getInstance()->isOptionChecked(MenuOption::BlueSpeechSphere) if (Menu::getInstance()->isOptionChecked(MenuOption::BlueSpeechSphere)
&& distanceToTarget > MIN_VOICE_SPHERE_DISTANCE) { && distanceToTarget > MIN_VOICE_SPHERE_DISTANCE) {
PROFILE_RANGE_BATCH(batch, __FUNCTION__":renderVoiceSphere");
// render voice intensity sphere for avatars that are farther away // render voice intensity sphere for avatars that are farther away
const float MAX_SPHERE_ANGLE = 10.0f * RADIANS_PER_DEGREE; const float MAX_SPHERE_ANGLE = 10.0f * RADIANS_PER_DEGREE;
@ -684,6 +692,7 @@ void Avatar::renderBillboard(RenderArgs* renderArgs) {
glm::vec2 texCoordBottomRight(1.0f, 1.0f); glm::vec2 texCoordBottomRight(1.0f, 1.0f);
gpu::Batch& batch = *renderArgs->_batch; gpu::Batch& batch = *renderArgs->_batch;
PROFILE_RANGE_BATCH(batch, __FUNCTION__);
batch.setResourceTexture(0, _billboardTexture->getGPUTexture()); batch.setResourceTexture(0, _billboardTexture->getGPUTexture());
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, true); DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, true);
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
@ -766,6 +775,8 @@ Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, cons
} }
void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::vec3& textPosition) const { void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::vec3& textPosition) const {
PROFILE_RANGE_BATCH(batch, __FUNCTION__);
bool shouldShowReceiveStats = DependencyManager::get<AvatarManager>()->shouldShowReceiveStats() && !isMyAvatar(); bool shouldShowReceiveStats = DependencyManager::get<AvatarManager>()->shouldShowReceiveStats() && !isMyAvatar();
// If we have nothing to draw, or it's totally transparent, or it's too close or behind the camera, return // If we have nothing to draw, or it's totally transparent, or it's too close or behind the camera, return
@ -816,17 +827,24 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, co
// Test on extent above insures abs(height) > 0.0f // Test on extent above insures abs(height) > 0.0f
textTransform.postScale(1.0f / height); textTransform.postScale(1.0f / height);
batch.setModelTransform(textTransform); batch.setModelTransform(textTransform);
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, false, true, true, true); {
DependencyManager::get<GeometryCache>()->renderBevelCornersRect(batch, left, bottom, width, height, PROFILE_RANGE_BATCH(batch, __FUNCTION__":renderBevelCornersRect");
bevelDistance, backgroundColor); DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, false, true, true, true);
DependencyManager::get<GeometryCache>()->renderBevelCornersRect(batch, left, bottom, width, height,
bevelDistance, backgroundColor);
}
// Render actual name // Render actual name
QByteArray nameUTF8 = renderedDisplayName.toLocal8Bit(); QByteArray nameUTF8 = renderedDisplayName.toLocal8Bit();
// Render text slightly in front to avoid z-fighting // Render text slightly in front to avoid z-fighting
textTransform.postTranslate(glm::vec3(0.0f, 0.0f, SLIGHTLY_IN_FRONT * renderer->getFontSize())); textTransform.postTranslate(glm::vec3(0.0f, 0.0f, SLIGHTLY_IN_FRONT * renderer->getFontSize()));
batch.setModelTransform(textTransform); batch.setModelTransform(textTransform);
renderer->draw(batch, text_x, -text_y, nameUTF8.data(), textColor); {
PROFILE_RANGE_BATCH(batch, __FUNCTION__":renderText");
renderer->draw(batch, text_x, -text_y, nameUTF8.data(), textColor);
}
} }
} }
@ -1089,6 +1107,7 @@ void Avatar::renderJointConnectingCone(gpu::Batch& batch, glm::vec3 position1, g
points << p1a << p1b << p2a << p1b << p2a << p2b; points << p1a << p1b << p2a << p1b << p2a << p2b;
} }
PROFILE_RANGE_BATCH(batch, __FUNCTION__);
// TODO: this is really inefficient constantly recreating these vertices buffers. It would be // TODO: this is really inefficient constantly recreating these vertices buffers. It would be
// better if the avatars cached these buffers for each of the joints they are rendering // better if the avatars cached these buffers for each of the joints they are rendering
geometryCache->updateVertices(_jointConesID, points, color); geometryCache->updateVertices(_jointConesID, points, color);

View file

@ -22,6 +22,14 @@ ProfileRange::ProfileRange(const char *name) {
ProfileRange::~ProfileRange() { ProfileRange::~ProfileRange() {
nvtxRangePop(); nvtxRangePop();
} }
ProfileRangeBatch::ProfileRangeBatch(gpu::Batch& batch, const char *name) : _batch(batch) {
_batch.pushProfileRange(name);
}
ProfileRangeBatch::~ProfileRangeBatch() {
_batch.popProfileRange();
}
#endif #endif
#define ADD_COMMAND(call) _commands.push_back(COMMAND_##call); _commandOffsets.push_back(_params.size()); #define ADD_COMMAND(call) _commands.push_back(COMMAND_##call); _commandOffsets.push_back(_params.size());
@ -391,3 +399,17 @@ QDebug& operator<<(QDebug& debug, const Batch::CacheState& cacheState) {
return debug; return debug;
} }
// Debugging
void Batch::pushProfileRange(const char* name) {
#if defined(NSIGHT_FOUND)
ADD_COMMAND(pushProfileRange);
_params.push_back(_profileRanges.cache(name));
#endif
}
void Batch::popProfileRange() {
#if defined(NSIGHT_FOUND)
ADD_COMMAND(popProfileRange);
#endif
}

View file

@ -229,6 +229,10 @@ public:
// Reset the stage caches and states // Reset the stage caches and states
void resetStages(); void resetStages();
// Debugging
void pushProfileRange(const char* name);
void popProfileRange();
// TODO: As long as we have gl calls explicitely issued from interface // TODO: As long as we have gl calls explicitely issued from interface
// code, we need to be able to record and batch these calls. THe long // code, we need to be able to record and batch these calls. THe long
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API // term strategy is to get rid of any GL calls in favor of the HIFI GPU API
@ -324,6 +328,9 @@ public:
COMMAND_glColor4f, COMMAND_glColor4f,
COMMAND_pushProfileRange,
COMMAND_popProfileRange,
NUM_COMMANDS, NUM_COMMANDS,
}; };
typedef std::vector<Command> Commands; typedef std::vector<Command> Commands;
@ -389,6 +396,7 @@ public:
typedef Cache<PipelinePointer>::Vector PipelineCaches; typedef Cache<PipelinePointer>::Vector PipelineCaches;
typedef Cache<FramebufferPointer>::Vector FramebufferCaches; typedef Cache<FramebufferPointer>::Vector FramebufferCaches;
typedef Cache<QueryPointer>::Vector QueryCaches; typedef Cache<QueryPointer>::Vector QueryCaches;
typedef Cache<std::string>::Vector ProfileRangeCaches;
typedef Cache<std::function<void()>>::Vector LambdaCache; typedef Cache<std::function<void()>>::Vector LambdaCache;
// Cache Data in a byte array if too big to fit in Param // Cache Data in a byte array if too big to fit in Param
@ -416,6 +424,7 @@ public:
FramebufferCaches _framebuffers; FramebufferCaches _framebuffers;
QueryCaches _queries; QueryCaches _queries;
LambdaCache _lambdas; LambdaCache _lambdas;
ProfileRangeCaches _profileRanges;
NamedBatchDataMap _namedData; NamedBatchDataMap _namedData;
@ -429,6 +438,25 @@ protected:
} }
#if defined(NSIGHT_FOUND)
class ProfileRangeBatch {
public:
ProfileRangeBatch(gpu::Batch& batch, const char *name);
~ProfileRangeBatch();
private:
gpu::Batch& _batch;
};
#define PROFILE_RANGE_BATCH(batch, name) ProfileRangeBatch profileRangeThis(batch, name);
#else
#define PROFILE_RANGE_BATCH(batch, name)
#endif
QDebug& operator<<(QDebug& debug, const gpu::Batch::CacheState& cacheState); QDebug& operator<<(QDebug& debug, const gpu::Batch::CacheState& cacheState);
#endif #endif

View file

@ -15,6 +15,11 @@
#include <list> #include <list>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
#if defined(NSIGHT_FOUND)
#include "nvToolsExt.h"
#endif
using namespace gpu; using namespace gpu;
GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
@ -69,6 +74,9 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::GLBackend::do_glUniformMatrix4fv), (&::gpu::GLBackend::do_glUniformMatrix4fv),
(&::gpu::GLBackend::do_glColor4f), (&::gpu::GLBackend::do_glColor4f),
(&::gpu::GLBackend::do_pushProfileRange),
(&::gpu::GLBackend::do_popProfileRange),
}; };
void GLBackend::init() { void GLBackend::init() {
@ -710,3 +718,17 @@ void GLBackend::do_glColor4f(Batch& batch, uint32 paramOffset) {
} }
(void) CHECK_GL_ERROR(); (void) CHECK_GL_ERROR();
} }
void GLBackend::do_pushProfileRange(Batch& batch, uint32 paramOffset) {
#if defined(NSIGHT_FOUND)
auto name = batch._profileRanges.get(batch._params[paramOffset]._uint);
nvtxRangePush(name.c_str());
#endif
}
void GLBackend::do_popProfileRange(Batch& batch, uint32 paramOffset) {
#if defined(NSIGHT_FOUND)
nvtxRangePop();
#endif
}

View file

@ -479,6 +479,9 @@ protected:
void do_glColor4f(Batch& batch, uint32 paramOffset); void do_glColor4f(Batch& batch, uint32 paramOffset);
void do_pushProfileRange(Batch& batch, uint32 paramOffset);
void do_popProfileRange(Batch& batch, uint32 paramOffset);
typedef void (GLBackend::*CommandCall)(Batch&, uint32); typedef void (GLBackend::*CommandCall)(Batch&, uint32);
static CommandCall _commandCalls[Batch::NUM_COMMANDS]; static CommandCall _commandCalls[Batch::NUM_COMMANDS];
}; };