diff options
| author | RunitaiLinden <davep@lindenlab.com> | 2023-05-01 17:05:09 -0500 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-05-01 17:05:09 -0500 | 
| commit | 334d71e9107ae3c4d35b181f2ed6e5c9ff1de519 (patch) | |
| tree | 6a6b64de2c9736c62695f7c5709159ca6e9e0455 /indra/newview | |
| parent | 04604a921d35cf877073828f98a05ae83d03c96e (diff) | |
SL-19656 Rewrite avatar and attachment render metrics to not interfere with render pipe and be representative of actual render cost instead of driver synchronization time.
* SL-19656 Rewrite avatar and attachment render metrics to not interfere with render pipe and be representative of actual render cost instead of driver synchronization time.
* SL-19656 Remove now dead code (trackAttachments et al).
* SL-19656 Fix for crash on GL <= 3.2
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/lldrawpool.cpp | 70 | ||||
| -rw-r--r-- | indra/newview/lldrawpoolalpha.cpp | 36 | ||||
| -rw-r--r-- | indra/newview/lldrawpoolavatar.cpp | 5 | ||||
| -rw-r--r-- | indra/newview/lldrawpoolbump.cpp | 36 | ||||
| -rw-r--r-- | indra/newview/lldrawpoolmaterials.cpp | 14 | ||||
| -rw-r--r-- | indra/newview/llfloaterperformance.cpp | 246 | ||||
| -rw-r--r-- | indra/newview/llfloaterperformance.h | 4 | ||||
| -rw-r--r-- | indra/newview/llperfstats.cpp | 13 | ||||
| -rw-r--r-- | indra/newview/llperfstats.h | 73 | ||||
| -rw-r--r-- | indra/newview/llviewerjointmesh.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.h | 4 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 3 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.h | 39 | ||||
| -rw-r--r-- | indra/newview/llvovolume.cpp | 22 | ||||
| -rw-r--r-- | indra/newview/llworld.cpp | 8 | ||||
| -rw-r--r-- | indra/newview/llworld.h | 4 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 125 | ||||
| -rw-r--r-- | indra/newview/pipeline.h | 3 | 
18 files changed, 324 insertions, 391 deletions
| diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 34d8f8b9ce..187e290066 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -52,8 +52,6 @@  #include "llglcommonfunc.h"  #include "llvoavatar.h"  #include "llviewershadermgr.h" -#include "llperfstats.h" -  S32 LLDrawPool::sNumDrawPools = 0; @@ -387,22 +385,11 @@ void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, bool texture)      LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;  	LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; -    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats   	for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	  	{  		LLDrawInfo *pparams = *k;  		if (pparams)           { -#if 0 // TODO SL-19656 figure out how to reenable trackAttachments() -            if(pparams->mFace) -            { -                LLViewerObject* vobj = pparams->mFace->getViewerObject(); -                if(vobj->isAttachment()) -                { -                    trackAttachments(vobj, false, &ratPtr); -                } -            } -#endif              pushBatch(*pparams, texture);  		}  	} @@ -415,23 +402,11 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, bool textu      LLVOAvatar* lastAvatar = nullptr;      U64 lastMeshId = 0; -    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats       for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)      {          LLDrawInfo* pparams = *k;          if (pparams)           { -#if 0 // TODO SL-19656 figure out how to reenable trackAttachments() -            if(pparams->mFace) -            { -                LLViewerObject* vobj = pparams->mFace->getViewerObject(); -                if(vobj->isAttachment()) -                { -                    trackAttachments( vobj, true ,&ratPtr); -                } -            } -#endif -              if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)              {                  uploadMatrixPalette(*pparams); @@ -447,7 +422,6 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, bool textu  void LLRenderPass::pushBatches(U32 type, bool texture, bool batch_textures)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; -    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};      auto* begin = gPipeline.beginRenderMap(type);      auto* end = gPipeline.endRenderMap(type);      for (LLCullResult::drawinfo_iterator i = begin; i != end; ) @@ -455,16 +429,6 @@ void LLRenderPass::pushBatches(U32 type, bool texture, bool batch_textures)          LLDrawInfo* pparams = *i;          LLCullResult::increment_iterator(i, end); -#if 0 // TODO SL-19656 figure out how to reenable trackAttachments() -            if(pparams->mFace) -            { -                LLViewerObject* vobj = pparams->mFace->getViewerObject(); -                if(vobj->isAttachment()) -                { -                    trackAttachments( vobj, false, &ratPtr); -                } -            } -#endif  		pushBatch(*pparams, texture, batch_textures);  	}  } @@ -476,23 +440,11 @@ void LLRenderPass::pushRiggedBatches(U32 type, bool texture, bool batch_textures      U64 lastMeshId = 0;      auto* begin = gPipeline.beginRenderMap(type);      auto* end = gPipeline.endRenderMap(type); -    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats       for (LLCullResult::drawinfo_iterator i = begin; i != end; )      {          LLDrawInfo* pparams = *i;          LLCullResult::increment_iterator(i, end); -#if 0 // TODO SL-19656 figure out how to reenable trackAttachments() -            if(pparams->mFace) -            { -                LLViewerObject* vobj = pparams->mFace->getViewerObject(); -                if(vobj->isAttachment()) -                { -                    trackAttachments( vobj, true, &ratPtr); -                } -            } -#endif -          if (pparams->mAvatar.notNull() && (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash))          {              uploadMatrixPalette(*pparams); @@ -507,23 +459,12 @@ void LLRenderPass::pushRiggedBatches(U32 type, bool texture, bool batch_textures  void LLRenderPass::pushMaskBatches(U32 type, bool texture, bool batch_textures)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; -    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};      auto* begin = gPipeline.beginRenderMap(type);      auto* end = gPipeline.endRenderMap(type);  	for (LLCullResult::drawinfo_iterator i = begin; i != end; )  	{          LLDrawInfo* pparams = *i;          LLCullResult::increment_iterator(i, end); -#if 0 // TODO SL-19656 figure out how to reenable trackAttachments() -            if((*pparams).mFace) -            { -                LLViewerObject* vobj = (*pparams).mFace->getViewerObject(); -                if(vobj->isAttachment()) -                { -                    trackAttachments( vobj, false, &ratPtr); -                } -            } -#endif  		LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);  		pushBatch(*pparams, texture, batch_textures);  	} @@ -534,7 +475,6 @@ void LLRenderPass::pushRiggedMaskBatches(U32 type, bool texture, bool batch_text      LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;      LLVOAvatar* lastAvatar = nullptr;      U64 lastMeshId = 0; -    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};      auto* begin = gPipeline.beginRenderMap(type);      auto* end = gPipeline.endRenderMap(type);      for (LLCullResult::drawinfo_iterator i = begin; i != end; ) @@ -544,16 +484,6 @@ void LLRenderPass::pushRiggedMaskBatches(U32 type, bool texture, bool batch_text          LLCullResult::increment_iterator(i, end);          llassert(pparams); -#if 0 // TODO SL-19656 figure out how to reenable trackAttachments() -        if((*pparams).mFace) -        { -            LLViewerObject* vobj = (*pparams).mFace->getViewerObject(); -            if(vobj->isAttachment()) -            { -                trackAttachments( vobj, true, &ratPtr); -            } -        } -#endif          if (LLGLSLShader::sCurBoundShaderPtr)          { diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index da4c963a97..404039189b 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -49,7 +49,6 @@  #include "llspatialpartition.h"  #include "llglcommonfunc.h"  #include "llvoavatar.h" -#include "llperfstats.h"  #include "llenvironment.h" @@ -349,22 +348,10 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)              {                  LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA+pass]; // <-- hacky + pass to use PASS_ALPHA_RIGGED on second pass  -                std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection                  for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)                  {                      LLDrawInfo& params = **k; -# if 0 // TODO SL-19656 figure out how to reenable trackAttachments() -                    if(params.mFace) -                    { -                        LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); -                        if(vobj->isAttachment()) -                        { -                            trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); -                        } -                    } -#endif -                      bool rigged = (params.mAvatar != nullptr);                      gHighlightProgram.bind(rigged);                      gGL.diffuseColor4f(1, 0, 0, 1); @@ -548,17 +535,9 @@ void LLDrawPoolAlpha::renderRiggedEmissives(std::vector<LLDrawInfo*>& emissives)      LLVOAvatar* lastAvatar = nullptr;      U64 lastMeshId = 0; -    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection      for (LLDrawInfo* draw : emissives)      {          LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("Emissives"); -# if 0 // TODO SL-19656 figure out how to reenable trackAttachments() -        auto vobj = draw->mFace?draw->mFace->getViewerObject():nullptr; -        if(vobj && vobj->isAttachment()) -        { -            trackAttachments( vobj, draw->mFace->isState(LLFace::RIGGED), &ratPtr ); -        } -#endif          bool tex_setup = TexSetup(draw, false);          if (lastAvatar != draw->mAvatar || lastMeshId != draw->mSkinInfo->mHash) @@ -687,7 +666,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)  			LLSpatialGroup::drawmap_elem_t& draw_info = rigged ? group->mDrawMap[LLRenderPass::PASS_ALPHA_RIGGED] : group->mDrawMap[LLRenderPass::PASS_ALPHA]; -            std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection              for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	  			{  				LLDrawInfo& params = **k; @@ -700,18 +678,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)                  LLRenderPass::applyModelMatrix(params); -# if 0 // TODO SL-19656 figure out how to reenable trackAttachments() -                if(params.mFace) -                { -                    LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); - -                    if(vobj->isAttachment()) -                    { -                        trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); -                    } -                } -#endif -                  LLMaterial* mat = NULL;                  LLGLTFMaterial *gltf_mat = params.mGLTFMaterial;  @@ -905,8 +871,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)  				}  			} -            ratPtr.reset(); // force the final batch to terminate to avoid double counting on the subsidiary batches for FB and Emmissives -              // render emissive faces into alpha channel for bloom effects              if (!depth_only)              { diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index c398087b20..19b23609a6 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -52,7 +52,6 @@  #include "llviewerpartsim.h"  #include "llviewercontrol.h" // for gSavedSettings  #include "llviewertexturelist.h" -#include "llperfstats.h"  static U32 sShaderLevel = 0; @@ -370,9 +369,8 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)  	{  		return;  	} -    LLPerfStats::RecordAvatarTime T(avatarp->getID(), LLPerfStats::StatType_t::RENDER_SHADOWS); -	LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance(); +    LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();  	BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();      // no shadows if the shadows are causing this avatar to breach the limit.      if (avatarp->isTooSlow() || impostor || (oa == LLVOAvatar::AOA_INVISIBLE)) @@ -741,7 +739,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  	{  		return;  	} -    LLPerfStats::RecordAvatarTime T(avatarp->getID(), LLPerfStats::StatType_t::RENDER_GEOMETRY);  	if (!single_avatar && !avatarp->isFullyLoaded() )  	{ diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index a548740ec4..9ed776f49e 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -49,7 +49,6 @@  #include "llspatialpartition.h"  #include "llviewershadermgr.h"  #include "llmodel.h" -#include "llperfstats.h"  //#include "llimagebmp.h"  //#include "../tools/imdebug/imdebug.h" @@ -406,19 +405,10 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, bool texture =  {					  	LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];	 -    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};      for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)   	{  		LLDrawInfo& params = **k; -#if 0 // TODO SL-19656 figure out how to reenable trackAttachments() -        LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); -        if( vobj && vobj->isAttachment() ) -        { -            trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); -        } -#endif -  		applyModelMatrix(params);  		params.mVertexBuffer->setBuffer(); @@ -568,25 +558,12 @@ void LLDrawPoolBump::renderDeferred(S32 pass)          LLVOAvatar* avatar = nullptr;          U64 skin = 0; -        std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};          for (LLCullResult::drawinfo_iterator i = begin; i != end; )          {              LLDrawInfo& params = **i;              LLCullResult::increment_iterator(i, end); -#if 0 // TODO SL-19656 figure out how to reenable trackAttachments() -            if(params.mFace) -            { -                LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); - -                if(vobj && vobj->isAttachment()) -                { -                    trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); -                } -            } -#endif -              LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff);              LLDrawPoolBump::bindBumpMap(params, bump_channel); @@ -1215,23 +1192,10 @@ void LLDrawPoolBump::pushBumpBatches(U32 type)      LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);      LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); -    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};  	for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)	  	{  		LLDrawInfo& params = **i; -#if 0 // TODO SL-19656 figure out how to reenable trackAttachments() -        if(params.mFace) -        { -            LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); - -            if( vobj && vobj->isAttachment() ) -            { -                trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); -            } -        } -#endif -  		if (LLDrawPoolBump::bindBumpMap(params))  		{              if (mRigged) diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index e025651cce..6a7e05ac74 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -32,7 +32,6 @@  #include "pipeline.h"  #include "llglcommonfunc.h"  #include "llvoavatar.h" -#include "llperfstats.h"  LLDrawPoolMaterials::LLDrawPoolMaterials()  :  LLRenderPass(LLDrawPool::POOL_MATERIALS) @@ -151,7 +150,6 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)  	LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);  	LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); -    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};      F32 lastIntensity = 0.f;      F32 lastFullbright = 0.f;      F32 lastMinimumAlpha = 0.f; @@ -201,18 +199,6 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)          LLCullResult::increment_iterator(i, end); -#if 0 // TODO SL-19656 figure out how to reenable trackAttachments() -        if(params.mFace) -        { -            LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); - -            if( vobj && vobj->isAttachment() ) -            { -                trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); -            } -        } -#endif -          if (specular > -1 && params.mSpecColor != lastSpecular)          {              lastSpecular = params.mSpecColor; diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp index 3321374f65..25b744a5ab 100644 --- a/indra/newview/llfloaterperformance.cpp +++ b/indra/newview/llfloaterperformance.cpp @@ -57,8 +57,6 @@ const S32 BAR_RIGHT_PAD = 5;  const S32 BAR_BOTTOM_PAD = 9;  constexpr auto AvType       {LLPerfStats::ObjType_t::OT_AVATAR}; -constexpr auto AttType      {LLPerfStats::ObjType_t::OT_ATTACHMENT}; -constexpr auto HudType      {LLPerfStats::ObjType_t::OT_HUD};  class LLExceptionsContextMenu : public LLListContextMenu  { @@ -83,8 +81,7 @@ protected:  LLFloaterPerformance::LLFloaterPerformance(const LLSD& key)  :   LLFloater(key), -    mUpdateTimer(new LLTimer()), -    mNearbyMaxComplexity(0) +    mUpdateTimer(new LLTimer())  {      mContextMenu = new LLExceptionsContextMenu(this);  } @@ -247,47 +244,82 @@ void LLFloaterPerformance::populateHUDList()      mHUDList->clearRows();      mHUDList->updateColumns(true); -    hud_complexity_list_t complexity_list = LLHUDRenderNotifier::getInstance()->getHUDComplexityList(); - -    hud_complexity_list_t::iterator iter = complexity_list.begin(); -    hud_complexity_list_t::iterator end = complexity_list.end(); - -    auto huds_max_render_time_raw = LLPerfStats::StatsRecorder::getMax(HudType, LLPerfStats::StatType_t::RENDER_GEOMETRY); -    for (iter = complexity_list.begin(); iter != end; ++iter) -    { -        LLHUDComplexity hud_object_complexity = *iter; - -        auto hud_render_time_raw = LLPerfStats::StatsRecorder::get(HudType, hud_object_complexity.objectId, LLPerfStats::StatType_t::RENDER_GEOMETRY); - -        LLSD item; -        item["special_id"] = hud_object_complexity.objectId; -        item["target"] = LLNameListCtrl::SPECIAL; -        LLSD& row = item["columns"]; -        row[0]["column"] = "complex_visual"; -        row[0]["type"] = "bar"; -        LLSD& value = row[0]["value"]; -        value["ratio"] = (F32)hud_render_time_raw / huds_max_render_time_raw; -        value["bottom"] = BAR_BOTTOM_PAD; -        value["left_pad"] = BAR_LEFT_PAD; -        value["right_pad"] = BAR_RIGHT_PAD; - -        row[1]["column"] = "complex_value"; -        row[1]["type"] = "text"; -        row[1]["value"] = llformat( "%.f", llmax(LLPerfStats::raw_to_us(hud_render_time_raw), (double)1)); -        row[1]["font"]["name"] = "SANSSERIF"; -  -        row[2]["column"] = "name"; -        row[2]["type"] = "text"; -        row[2]["value"] = hud_object_complexity.objectName; -        row[2]["font"]["name"] = "SANSSERIF"; - -        LLScrollListItem* obj = mHUDList->addElement(item); -        if (obj) +    LLVOAvatar* avatar = gAgentAvatarp; + +    gPipeline.profileAvatar(avatar, true); + +    LLVOAvatar::attachment_map_t::iterator iter; +    LLVOAvatar::attachment_map_t::iterator begin = avatar->mAttachmentPoints.begin(); +    LLVOAvatar::attachment_map_t::iterator end = avatar->mAttachmentPoints.end(); + +    // get max gpu render time of all attachments +    F32 max_gpu_time = -1.f; + +    for (iter = begin; iter != end; ++iter) +    { +        LLViewerJointAttachment* attachment = iter->second; +        for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +            attachment_iter != attachment->mAttachedObjects.end(); +            ++attachment_iter) +        { +            LLViewerObject* attached_object = attachment_iter->get(); +            if (attached_object && attached_object->isHUDAttachment()) +            { +                max_gpu_time = llmax(max_gpu_time, attached_object->mGPURenderTime); +            } +        } +    } + + +    for (iter = begin; iter != end; ++iter) +    { +        if (!iter->second)          { -            LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1)); -            if (value_text) +            continue; +        } + +        LLViewerJointAttachment* attachment = iter->second; +        for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +            attachment_iter != attachment->mAttachedObjects.end(); +            ++attachment_iter) +        { +            LLViewerObject* attached_object = attachment_iter->get(); +            if (attached_object && attached_object->isHUDAttachment())              { -                value_text->setAlignment(LLFontGL::HCENTER); +                F32 gpu_time = attached_object->mGPURenderTime; + +                LLSD item; +                item["special_id"] = attached_object->getID(); +                item["target"] = LLNameListCtrl::SPECIAL; +                LLSD& row = item["columns"]; +                row[0]["column"] = "complex_visual"; +                row[0]["type"] = "bar"; +                LLSD& value = row[0]["value"]; +                value["ratio"] = gpu_time / max_gpu_time; +                value["bottom"] = BAR_BOTTOM_PAD; +                value["left_pad"] = BAR_LEFT_PAD; +                value["right_pad"] = BAR_RIGHT_PAD; + +                row[1]["column"] = "complex_value"; +                row[1]["type"] = "text"; +                // show gpu time in us +                row[1]["value"] = llformat("%.f", gpu_time * 1000.f); +                row[1]["font"]["name"] = "SANSSERIF"; + +                row[2]["column"] = "name"; +                row[2]["type"] = "text"; +                row[2]["value"] = attached_object->getAttachmentItemName(); +                row[2]["font"]["name"] = "SANSSERIF"; + +                LLScrollListItem* obj = mHUDList->addElement(item); +                if (obj) +                { +                    LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1)); +                    if (value_text) +                    { +                        value_text->setAlignment(LLFontGL::HCENTER); +                    } +                }              }          }      } @@ -303,50 +335,82 @@ void LLFloaterPerformance::populateObjectList()      mObjectList->clearRows();      mObjectList->updateColumns(true); -    object_complexity_list_t complexity_list = LLAvatarRenderNotifier::getInstance()->getObjectComplexityList(); +    LLVOAvatar* avatar = gAgentAvatarp; -    object_complexity_list_t::iterator iter = complexity_list.begin(); -    object_complexity_list_t::iterator end = complexity_list.end(); +    gPipeline.profileAvatar(avatar, true); -    // for consistency we lock the buffer while we build the list. In theory this is uncontended as the buffer should only toggle on end of frame -    { -        std::lock_guard<std::mutex> guard{ LLPerfStats::bufferToggleLock }; -        auto att_max_render_time_raw = LLPerfStats::StatsRecorder::getMax(AttType, LLPerfStats::StatType_t::RENDER_COMBINED); +    LLVOAvatar::attachment_map_t::iterator iter; +    LLVOAvatar::attachment_map_t::iterator begin = avatar->mAttachmentPoints.begin(); +    LLVOAvatar::attachment_map_t::iterator end = avatar->mAttachmentPoints.end(); -        for (iter = complexity_list.begin(); iter != end; ++iter) -        { -            LLObjectComplexity object_complexity = *iter; +    // get max gpu render time of all attachments +    F32 max_gpu_time = -1.f; -            auto attach_render_time_raw = LLPerfStats::StatsRecorder::get(AttType, object_complexity.objectId, LLPerfStats::StatType_t::RENDER_COMBINED); -            LLSD item; -            item["special_id"] = object_complexity.objectId; -            item["target"] = LLNameListCtrl::SPECIAL; -            LLSD& row = item["columns"]; -            row[0]["column"] = "complex_visual"; -            row[0]["type"] = "bar"; -            LLSD& value = row[0]["value"]; -            value["ratio"] = ((F32)attach_render_time_raw) / att_max_render_time_raw; -            value["bottom"] = BAR_BOTTOM_PAD; -            value["left_pad"] = BAR_LEFT_PAD; -            value["right_pad"] = BAR_RIGHT_PAD; - -            row[1]["column"] = "complex_value"; -            row[1]["type"] = "text"; -            row[1]["value"] = llformat("%.f", llmax(LLPerfStats::raw_to_us(attach_render_time_raw), (double)1)); -            row[1]["font"]["name"] = "SANSSERIF"; +    for (iter = begin; iter != end; ++iter) +    { +        LLViewerJointAttachment* attachment = iter->second; +        for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +            attachment_iter != attachment->mAttachedObjects.end(); +            ++attachment_iter) +        { +            LLViewerObject* attached_object = attachment_iter->get(); +            if (attached_object && !attached_object->isHUDAttachment()) +            { +                max_gpu_time = llmax(max_gpu_time, attached_object->mGPURenderTime); +            } +        } +    } -            row[2]["column"] = "name"; -            row[2]["type"] = "text"; -            row[2]["value"] = object_complexity.objectName; -            row[2]["font"]["name"] = "SANSSERIF"; +    { +        for (iter = begin; iter != end; ++iter) +        { +            if (!iter->second) +            { +                continue; +            } -            LLScrollListItem* obj = mObjectList->addElement(item); -            if (obj) +            LLViewerJointAttachment* attachment = iter->second; +            for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +                attachment_iter != attachment->mAttachedObjects.end(); +                ++attachment_iter)              { -                LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1)); -                if (value_text) +                LLViewerObject* attached_object = attachment_iter->get(); +                if (attached_object && !attached_object->isHUDAttachment())                  { -                    value_text->setAlignment(LLFontGL::HCENTER); +                    F32 gpu_time = attached_object->mGPURenderTime; + +                    LLSD item; +                    item["special_id"] = attached_object->getID(); +                    item["target"] = LLNameListCtrl::SPECIAL; +                    LLSD& row = item["columns"]; +                    row[0]["column"] = "complex_visual"; +                    row[0]["type"] = "bar"; +                    LLSD& value = row[0]["value"]; +                    value["ratio"] = gpu_time / max_gpu_time; +                    value["bottom"] = BAR_BOTTOM_PAD; +                    value["left_pad"] = BAR_LEFT_PAD; +                    value["right_pad"] = BAR_RIGHT_PAD; + +                    row[1]["column"] = "complex_value"; +                    row[1]["type"] = "text"; +                    // show gpu time in us +                    row[1]["value"] = llformat("%.f", gpu_time * 1000.f); +                    row[1]["font"]["name"] = "SANSSERIF"; + +                    row[2]["column"] = "name"; +                    row[2]["type"] = "text"; +                    row[2]["value"] = attached_object->getAttachmentItemName(); +                    row[2]["font"]["name"] = "SANSSERIF"; + +                    LLScrollListItem* obj = mObjectList->addElement(item); +                    if (obj) +                    { +                        LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1)); +                        if (value_text) +                        { +                            value_text->setAlignment(LLFontGL::HCENTER); +                        } +                    }                  }              }          } @@ -358,6 +422,7 @@ void LLFloaterPerformance::populateObjectList()  void LLFloaterPerformance::populateNearbyList()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;      static LLCachedControl<bool> showTunedART(gSavedSettings, "ShowTunedART");      S32 prev_pos = mNearbyList->getScrollPos();      LLUUID prev_selected_id = mNearbyList->getStringUUIDSelectedItem(); @@ -366,22 +431,16 @@ void LLFloaterPerformance::populateNearbyList()      static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0);      std::vector<LLCharacter*> valid_nearby_avs; -    mNearbyMaxComplexity = LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs); +    mNearbyMaxGPUTime = LLWorld::getInstance()->getNearbyAvatarsAndMaxGPUTime(valid_nearby_avs);      std::vector<LLCharacter*>::iterator char_iter = valid_nearby_avs.begin(); -    LLPerfStats::bufferToggleLock.lock(); -    auto av_render_max_raw = LLPerfStats::StatsRecorder::getMax(AvType, LLPerfStats::StatType_t::RENDER_COMBINED); -    LLPerfStats::bufferToggleLock.unlock(); -      while (char_iter != valid_nearby_avs.end())      {          LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);          if (avatar && (LLVOAvatar::AOA_INVISIBLE != avatar->getOverallAppearance()))          { -            LLPerfStats::bufferToggleLock.lock(); -            auto render_av_raw  = LLPerfStats::StatsRecorder::get(AvType, avatar->getID(),LLPerfStats::StatType_t::RENDER_COMBINED); -            LLPerfStats::bufferToggleLock.unlock(); +            F32 render_av_gpu_ms = avatar->getGPURenderTime();              auto is_slow = avatar->isTooSlow();              LLSD item; @@ -392,7 +451,7 @@ void LLFloaterPerformance::populateNearbyList()              LLSD& value = row[0]["value"];              // The ratio used in the bar is the current cost, as soon as we take action this changes so we keep the               // pre-tune value for the numerical column and sorting. -            value["ratio"] = (double)render_av_raw / av_render_max_raw; +            value["ratio"] = render_av_gpu_ms / mNearbyMaxGPUTime;              value["bottom"] = BAR_BOTTOM_PAD;              value["left_pad"] = BAR_LEFT_PAD;              value["right_pad"] = BAR_RIGHT_PAD; @@ -405,14 +464,15 @@ void LLFloaterPerformance::populateNearbyList()              }              else              { -                row[1]["value"] = llformat( "%.f", LLPerfStats::raw_to_us( render_av_raw ) ); +                // use GPU time in us +                row[1]["value"] = llformat( "%.f", render_av_gpu_ms * 1000.f);              }              row[1]["font"]["name"] = "SANSSERIF"; -            row[2]["column"] = "name"; -            row[2]["type"] = "text"; -            row[2]["value"] = avatar->getFullname(); -            row[2]["font"]["name"] = "SANSSERIF"; +            row[3]["column"] = "name"; +            row[3]["type"] = "text"; +            row[3]["value"] = avatar->getFullname(); +            row[3]["font"]["name"] = "SANSSERIF";              LLScrollListItem* av_item = mNearbyList->addElement(item);              if(av_item) diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h index 00f904f6d6..620dbac5bb 100644 --- a/indra/newview/llfloaterperformance.h +++ b/indra/newview/llfloaterperformance.h @@ -94,7 +94,9 @@ private:      LLTimer* mUpdateTimer; -    S32 mNearbyMaxComplexity; +    // maximum GPU time of nearby avatars in ms according to LLWorld::getNearbyAvatarsAndMaxGPUTime +    // -1.f if no profile has happened yet +    F32 mNearbyMaxGPUTime = -1.f;      boost::signals2::connection	mMaxARTChangedSignal;  }; diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp index c63aae2089..b680d8761b 100644 --- a/indra/newview/llperfstats.cpp +++ b/indra/newview/llperfstats.cpp @@ -199,18 +199,7 @@ namespace LLPerfStats                  // LL_INFOS("scenestats") << "Scenestat: " << static_cast<size_t>(statEntry) << " before=" << avg << " new=" << val << " newavg=" << statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null][static_cast<size_t>(statEntry)] << LL_ENDL;              }          } -// Allow attachment times etc to update even when FPS limited or sleeping. -        auto& statsMap = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_ATTACHMENT)]; -        for(auto& stat_entry : statsMap) -        { -            auto val = stat_entry.second[static_cast<size_t>(ST::RENDER_COMBINED)]; -            if(val > SMOOTHING_PERIODS){ -                auto avg = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_ATTACHMENT)][stat_entry.first][static_cast<size_t>(ST::RENDER_COMBINED)]; -                stat_entry.second[static_cast<size_t>(ST::RENDER_COMBINED)] = avg + (val / SMOOTHING_PERIODS) - (avg / SMOOTHING_PERIODS); -            } -        } - - +                  auto& statsMapAv = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_AVATAR)];          for(auto& stat_entry : statsMapAv)          { diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h index dbb88a141d..a4768272b9 100644 --- a/indra/newview/llperfstats.h +++ b/indra/newview/llperfstats.h @@ -69,8 +69,6 @@ namespace LLPerfStats      enum class ObjType_t{          OT_GENERAL=0, // Also Unknown. Used for n/a type stats such as scenery          OT_AVATAR, -        OT_ATTACHMENT, -        OT_HUD,          OT_COUNT      };      enum class StatType_t{ @@ -260,31 +258,6 @@ namespace LLPerfStats                  doUpd(avKey, ot, type, val);                  return;              } - -            if (ot == ObjType_t::OT_ATTACHMENT) -            { -                if( !upd.isHUD ) // don't include HUD cost in self. -                { -                    LL_PROFILE_ZONE_NAMED("Att as Av") -                    // For all attachments that are not rigged we add them to the avatar (for all avatars) cost. -                    doUpd(avKey, ObjType_t::OT_AVATAR, type, val); -                } -                if( avKey == focusAv ) -                { -                    LL_PROFILE_ZONE_NAMED("Att as Att") -                // For attachments that are for the focusAv (self for now) we record them for the attachment/complexity view -                    if(upd.isHUD) -                    { -                        ot = ObjType_t::OT_HUD; -                    } -                    // LL_INFOS("perfstats") << "frame: " << gFrameCount << " Attachment update("<< (type==StatType_t::RENDER_GEOMETRY?"GEOMETRY":"SHADOW") << ": " << key.asString() << " = " << val << LL_ENDL; -                    doUpd(key, ot, type, val); -                } -                // else -                // { -                //     // LL_INFOS("perfstats") << "frame: " << gFrameCount << " non-self Att update("<< (type==StatType_t::RENDER_GEOMETRY?"GEOMETRY":"SHADOW") << ": " << key.asString() << " = " << val << " for av " << avKey.asString() << LL_ENDL; -                // } -            }          }          static inline void doUpd(const LLUUID& key, ObjType_t ot, StatType_t type, uint64_t val) @@ -409,51 +382,7 @@ namespace LLPerfStats      using RecordSceneTime = RecordTime<ObjType_t::OT_GENERAL>;      using RecordAvatarTime = RecordTime<ObjType_t::OT_AVATAR>; -    using RecordAttachmentTime = RecordTime<ObjType_t::OT_ATTACHMENT>; -    using RecordHudAttachmentTime = RecordTime<ObjType_t::OT_HUD>; -      -};// namespace LLPerfStats - -// helper functions -using RATptr = std::unique_ptr<LLPerfStats::RecordAttachmentTime>; -using RSTptr = std::unique_ptr<LLPerfStats::RecordSceneTime>; -template <typename T> -static inline void trackAttachments(const T * vobj, bool isRigged, RATptr* ratPtrp) -{ -    if( !vobj ){ ratPtrp->reset(); return;}; -     -    const T* rootAtt{vobj}; -    if (rootAtt->isAttachment()) -    { -        LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; - -        while( !rootAtt->isRootEdit() ) -        { -            rootAtt = (T*)(rootAtt->getParent()); -        } - -        auto avPtr = (T*)(rootAtt->getParent());  -        if(!avPtr){ratPtrp->reset(); return;} - -        auto& av = avPtr->getID(); -        auto& obj = rootAtt->getAttachmentItemID(); -        if (!*ratPtrp || (*ratPtrp)->stat.objID != obj || (*ratPtrp)->stat.avID != av) -        { -            if (*ratPtrp) -            { -                // deliberately reset to ensure destruction before construction of replacement. -                ratPtrp->reset(); -            }; -            *ratPtrp = std::make_unique<LLPerfStats::RecordAttachmentTime>(  -                av,  -                obj, -                ( LLPipeline::sShadowRender?LLPerfStats::StatType_t::RENDER_SHADOWS : LLPerfStats::StatType_t::RENDER_GEOMETRY ),  -                isRigged,  -                rootAtt->isHUDAttachment()); -        } -    } -    return; -}; +};// namespace LLPerfStats  #endif diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 00e1179896..5ce8f4023d 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -227,16 +227,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)  		return 0;  	} -    // render time capture -    // This path does not appear to have attachments. Prove this then remove. -    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; -    auto vobj = mFace->getViewerObject(); -    if( vobj && vobj->isAttachment() ) -    { -        trackAttachments( vobj, mFace->isState(LLFace::RIGGED), &ratPtr ); -        LL_WARNS("trackAttachments") << "Attachment render time is captuted." << LL_ENDL; -    } -  	U32 triangle_count = 0;  	S32 diffuse_channel = LLDrawPoolAvatar::sDiffuseChannel; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index fe27227e6b..cd2363a1b9 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -941,6 +941,10 @@ public:      // reflection probe state      bool mIsReflectionProbe = false;  // if true, this object should register itself with LLReflectionProbeManager      LLPointer<LLReflectionMap> mReflectionProbe = nullptr; // reflection probe coupled to this viewer object.  If not null, should be deregistered when this object is destroyed + +    // the amount of GPU time (in ms) it took to render this object according to LLPipeline::profileAvatar +    // -1.f if no profile data available +    F32 mGPURenderTime = -1.f;  };  /////////////////// diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 5b8f4767db..e38a6457f4 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -8357,7 +8357,7 @@ void LLVOAvatar::updateTooSlow()      {          // use the cached values.          render_time_raw = mRenderTime; -        render_geom_time_raw = mGeomTime;		 +        render_geom_time_raw = mGeomTime;      }  	bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf(); @@ -10984,6 +10984,7 @@ void LLVOAvatar::accountRenderComplexityForObject(  // Calculations for mVisualComplexity value  void LLVOAvatar::calculateUpdateRenderComplexity()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;      /*****************************************************************       * This calculation should not be modified by third party viewers,       * since it is used to limit rendering and should be uniform for diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 1502c25b4d..0bb19c4420 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -305,8 +305,27 @@ public:  	static const U32 VISUAL_COMPLEXITY_UNKNOWN;  	void			updateVisualComplexity(); -	U32				getVisualComplexity()			{ return mVisualComplexity;				};		// Numbers calculated here by rendering AV -	F32				getAttachmentSurfaceArea()		{ return mAttachmentSurfaceArea;		};		// estimated surface area of attachments +    // get the GPU time in ms of rendering this avatar including all attachments +    // returns -1 if this avatar has not been profiled using gPipeline.profileAvatar +    F32             getGPURenderTime() { return mGPURenderTime; } + +    // get the CPU time in ms of rendering this avatar including all attachments +    // return -1 if this avatar has not been profiled using gPipeline.mProfileAvatar +    F32             getCPURenderTime() { return mCPURenderTime; } + +    // get the number of samples passed during the avatar profile +    // return -1 if this avatar has not been profiled using gPipeline.mProfileAvatar +    S32             getGPUSamplesPassed() { return mGPUSamplesPassed; } + +    // get the number of triangles rendered during the avatar profile +    // return -1 if this avatar has not been profiled using gPipeline.mProfileAvatar +    S32             getGPUTrianglesRendered() { return mGPUTrianglesRendered; } + +    // DEPRECATED -- obsolete avatar render cost +	U32				getVisualComplexity()			{ return mVisualComplexity;				}; + +    // DEPRECATED -- obsolete surface area calculation +	F32				getAttachmentSurfaceArea()		{ return mAttachmentSurfaceArea;		};  	U32				getReportedVisualComplexity()					{ return mReportedVisualComplexity;				};	// Numbers as reported by the SL server  	void			setReportedVisualComplexity(U32 value)			{ mReportedVisualComplexity = value;			}; @@ -523,6 +542,7 @@ public:  	S32			mSpecialRenderMode; // special lighting  private: +    friend class LLPipeline;  	AvatarOverallAppearance mOverallAppearance;  	F32			mAttachmentSurfaceArea; //estimated surface area of attachments      U32			mAttachmentVisibleTriangleCount; @@ -535,7 +555,22 @@ private:  	S32	 		mUpdatePeriod;  	S32  		mNumInitFaces; //number of faces generated when creating the avatar drawable, does not inculde splitted faces due to long vertex buffer. +    // profile results + +    // GPU render time in ms +    F32 mGPURenderTime = -1.f; + +    // CPU render time in ms +    F32 mCPURenderTime = -1.f; + +    // number of samples passed according to GPU +    S32 mGPUSamplesPassed = -1; + +    // number of triangles rendered according to GPU +    S32 mGPUTrianglesRendered = -1; +  	// the isTooComplex method uses these mutable values to avoid recalculating too frequently +    // DEPRECATED -- obsolete avatar render cost values  	mutable U32  mVisualComplexity;  	mutable bool mVisualComplexityStale;  	U32          mReportedVisualComplexity; // from other viewers through the simulator diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 12ceb86e52..da5a505d3b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -88,7 +88,6 @@  #include "llcallstack.h"  #include "llsculptidsize.h"  #include "llavatarappearancedefines.h" -#include "llperfstats.h"   #include "llgltfmateriallist.h"  const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; @@ -5657,7 +5656,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)          LL_PROFILE_ZONE_NAMED("rebuildGeom - face list");  		//get all the faces into a list -        std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};  		for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin();                drawable_iter != group->getDataEnd(); ++drawable_iter)  		{ @@ -5693,11 +5691,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  				continue;  			} -            if(vobj->isAttachment()) -            { -                trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED),&ratPtr); -            } -  			LLVolume* volume = vobj->getVolume();  			if (volume)  			{ @@ -6095,8 +6088,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  			U32 buffer_count = 0; -            std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; -			for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) +            for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)  			{  				LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); @@ -6106,11 +6098,6 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  					if (!vobj) continue; -                    if (vobj->isAttachment()) -                    { -                        trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED), &ratPtr ); -                    } -					  					if (debugLoggingEnabled("AnimatedObjectsLinkset"))  					{  						if (vobj->isAnimatedObject() && vobj->isRiggedMesh()) @@ -6479,16 +6466,11 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  		U32 indices_index = 0;  		U16 index_offset = 0; -        std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr;          while (face_iter < i)  		{  			//update face indices for new buffer  			facep = *face_iter; -            LLViewerObject* vobj = facep->getViewerObject(); -            if(vobj && vobj->isAttachment()) -            { -                trackAttachments(vobj, LLPipeline::sShadowRender, &ratPtr); -            } +  			if (buffer.isNull())  			{  				// Bulk allocation failed diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 72c8cb371f..732ef1da6c 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -1424,10 +1424,10 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi  	}  } -S32 LLWorld::getNearbyAvatarsAndCompl(std::vector<LLCharacter*> &valid_nearby_avs) +F32 LLWorld::getNearbyAvatarsAndMaxGPUTime(std::vector<LLCharacter*> &valid_nearby_avs)  {      static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64); -    S32 nearby_max_complexity = 0; +    F32 nearby_max_complexity = 0;      F32 radius = render_far_clip * render_far_clip;      std::vector<LLCharacter*>::iterator char_iter = LLCharacter::sInstances.begin();      while (char_iter != LLCharacter::sInstances.end()) @@ -1441,8 +1441,8 @@ S32 LLWorld::getNearbyAvatarsAndCompl(std::vector<LLCharacter*> &valid_nearby_av                  char_iter++;                  continue;              } -            avatar->calculateUpdateRenderComplexity(); -            nearby_max_complexity = llmax(nearby_max_complexity, (S32)avatar->getVisualComplexity()); +            gPipeline.profileAvatar(avatar); +            nearby_max_complexity = llmax(nearby_max_complexity, avatar->getGPURenderTime());              valid_nearby_avs.push_back(*char_iter);          }          char_iter++; diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index b2be36d72c..f78cbcaa48 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -172,7 +172,9 @@ public:  	// or if the circuit to this simulator had been lost.  	bool isRegionListed(const LLViewerRegion* region) const; -    S32 getNearbyAvatarsAndCompl(std::vector<LLCharacter*> &valid_nearby_avs); +    // profile nearby avatars using gPipeline.profileAvatar and update their render times +    // return max GPU time +    F32 getNearbyAvatarsAndMaxGPUTime(std::vector<LLCharacter*> &valid_nearby_avs);  private:      void clearHoleWaterObjects(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 2912d0da82..df8b8a552a 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -10070,7 +10070,88 @@ void LLPipeline::renderRiggedGroups(LLRenderPass* pass, U32 type, bool texture)  static LLTrace::BlockTimerStatHandle FTM_GENERATE_IMPOSTOR("Generate Impostor"); -void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar) +void LLPipeline::profileAvatar(LLVOAvatar* avatar, bool profile_attachments) +{ +    if (gGLManager.mGLVersion < 3.25f) +    { // profiling requires GL 3.3 or later +        return; +    } +    LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr; + +    mRT->deferredScreen.bindTarget(); +    mRT->deferredScreen.clear(); + +    bool profile_enabled = LLGLSLShader::sProfileEnabled; +    LLGLSLShader::sProfileEnabled = true; + +    if (!profile_attachments) +    { +        // profile entire avatar all at once +         +        // use gDebugProgram as a proxy for getting profile results +        gDebugProgram.clearStats(); +        gDebugProgram.placeProfileQuery(); +        LLGLSLShader::sProfileEnabled = false; + +        LLTimer cpu_timer; + +        generateImpostor(avatar, false, true); + +        avatar->mCPURenderTime = (F32)cpu_timer.getElapsedTimeF32() * 1000.f; + +        LLGLSLShader::sProfileEnabled = true; +        gDebugProgram.readProfileQuery(); + +        avatar->mGPURenderTime = gDebugProgram.mTimeElapsed / 1000000.f; + +        avatar->mGPUSamplesPassed = gDebugProgram.mSamplesDrawn; +        avatar->mGPUTrianglesRendered = gDebugProgram.mTrianglesDrawn; +    } +    else  +    {  +        // profile attachments one at a time +        LLVOAvatar::attachment_map_t::iterator iter; +        LLVOAvatar::attachment_map_t::iterator begin = avatar->mAttachmentPoints.begin(); +        LLVOAvatar::attachment_map_t::iterator end = avatar->mAttachmentPoints.end(); + +        for (iter = begin; +            iter != end; +            ++iter) +        { +            LLViewerJointAttachment* attachment = iter->second; +            for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +                attachment_iter != attachment->mAttachedObjects.end(); +                ++attachment_iter) +            { +                LLViewerObject* attached_object = attachment_iter->get(); +                if (attached_object) +                { +                    gDebugProgram.clearStats(); +                    gDebugProgram.placeProfileQuery(); +                    LLGLSLShader::sProfileEnabled = false; + +                    generateImpostor(avatar, false, true, attached_object); +                    LLGLSLShader::sProfileEnabled = true; +                    gDebugProgram.readProfileQuery(); + +                    attached_object->mGPURenderTime = gDebugProgram.mTimeElapsed / 1000000.f; + +                    // TODO: maybe also record triangles and samples +                } +            } +        } +    } + +    LLGLSLShader::sProfileEnabled = profile_enabled; +    mRT->deferredScreen.flush(); + +    if (cur_shader) +    { +        cur_shader->bind(); +    } +} + +void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool for_profile, LLViewerObject* specific_attachment)  {      LL_RECORD_BLOCK_TIME(FTM_GENERATE_IMPOSTOR);      LL_PROFILE_GPU_ZONE("generateImpostor"); @@ -10090,11 +10171,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)  	assertInitialized();      // previews can't be muted or impostered -	bool visually_muted = !preview_avatar && avatar->isVisuallyMuted(); +	bool visually_muted = !for_profile && !preview_avatar && avatar->isVisuallyMuted();      LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID()                                << " is " << ( visually_muted ? "" : "not ") << "visually muted"                                << LL_ENDL; -	bool too_complex = !preview_avatar && avatar->isTooComplex(); +	bool too_complex = !for_profile && !preview_avatar && avatar->isTooComplex();      LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID()                                << " is " << ( too_complex ? "" : "not ") << "too complex"                                << LL_ENDL; @@ -10129,6 +10210,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)           );  	} +    if (specific_attachment && specific_attachment->isHUDAttachment()) +    { //enable HUD rendering +        setRenderTypeMask(RENDER_TYPE_HUD, END_RENDER_TYPES); +    } +  	S32 occlusion = sUseOcclusion;  	sUseOcclusion = 0; @@ -10185,20 +10271,30 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)          }          else          { -            LLVOAvatar::attachment_map_t::iterator iter; -            for (iter = avatar->mAttachmentPoints.begin(); -                iter != avatar->mAttachmentPoints.end(); -                ++iter) +            if (specific_attachment)              { -                LLViewerJointAttachment *attachment = iter->second; -                for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); -                    attachment_iter != attachment->mAttachedObjects.end(); -                    ++attachment_iter) +                markVisible(specific_attachment->mDrawable->getSpatialBridge(), *viewer_camera); +            } +            else +            { +                LLVOAvatar::attachment_map_t::iterator iter; +                LLVOAvatar::attachment_map_t::iterator begin = avatar->mAttachmentPoints.begin(); +                LLVOAvatar::attachment_map_t::iterator end = avatar->mAttachmentPoints.end(); + +                for (iter = begin; +                    iter != end; +                    ++iter)                  { -                    LLViewerObject* attached_object = attachment_iter->get(); -                    if (attached_object) +                    LLViewerJointAttachment* attachment = iter->second; +                    for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +                        attachment_iter != attachment->mAttachedObjects.end(); +                        ++attachment_iter)                      { -                        markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); +                        LLViewerObject* attached_object = attachment_iter->get(); +                        if (attached_object) +                        { +                            markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); +                        }                      }                  }              } @@ -10327,6 +10423,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)  	LLDrawPoolAvatar::sMinimumAlpha = old_alpha; +    if (!for_profile)  	{ //create alpha mask based on depth buffer (grey out if muted)  		if (LLPipeline::sRenderDeferred)  		{ diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index dbd1a34f61..45842a3948 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -132,7 +132,8 @@ public:      bool allocateShadowBuffer(U32 resX, U32 resY);  	void resetVertexBuffers(LLDrawable* drawable); -	void generateImpostor(LLVOAvatar* avatar, bool preview_avatar = false); +    void profileAvatar(LLVOAvatar* avatar, bool profile_attachments = false); +	void generateImpostor(LLVOAvatar* avatar, bool preview_avatar = false, bool for_profile = false, LLViewerObject* specific_attachment = nullptr);  	void bindScreenToTexture();  	void renderFinalize();  	void copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst); | 
