From a4c9fb003f36955cecb0b987b5ddf9a04edd0f90 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Fri, 3 Sep 2021 17:20:22 -0700 Subject: SL-15709: Windows: Include Tracy source directly; don't use a library --- indra/cmake/LLCommon.cmake | 1 - indra/cmake/Tracy.cmake | 3 --- indra/llcommon/llframetimer.cpp | 11 ++++------- indra/llcommon/llprofiler.h | 6 ++++-- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index b6f310fe12..34499aaa36 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -33,7 +33,6 @@ else (LINUX) ${BOOST_CONTEXT_LIBRARY} ${BOOST_THREAD_LIBRARY} ${BOOST_SYSTEM_LIBRARY} - ${TRACY_LIBRARY} ) endif (LINUX) diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index dfa3e83039..1b8c3db2e2 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -12,17 +12,14 @@ if (USE_TRACY) if (WINDOWS) MESSAGE(STATUS "Including Tracy for Windows: '${TRACY_INCLUDE_DIR}'") - set(TRACY_LIBRARY tracy) endif (WINDOWS) if (DARWIN) MESSAGE(STATUS "Including Tracy for Darwin: '${TRACY_INCLUDE_DIR}'") - set(TRACY_LIBRARY "") endif (DARWIN) if (LINUX) MESSAGE(STATUS "Including Tracy for Linux: '${TRACY_INCLUDE_DIR}'") - set(TRACY_LIBRARY "") endif (LINUX) else (USE_TRACY) # Tracy.cmake should not set LLCOMMON_INCLUDE_DIRS, let LLCommon.cmake do that diff --git a/indra/llcommon/llframetimer.cpp b/indra/llcommon/llframetimer.cpp index e293a557c0..c54029e8b4 100644 --- a/indra/llcommon/llframetimer.cpp +++ b/indra/llcommon/llframetimer.cpp @@ -29,13 +29,10 @@ #include "llframetimer.h" -// On Windows we build a static lib and link with that -// On macOS we don't bother building a stand alone lib, just include the one source file we need for Tracy support -#if LL_DARWIN - #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER - #include "TracyClient.cpp" - #endif // LL_PROFILER_CONFIGURATION -#endif // LL_DARWIN +// We don't bother building a stand alone lib; we just need to include the one source file for Tracy support +#if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER + #include "TracyClient.cpp" +#endif // LL_PROFILER_CONFIGURATION // Static members //LLTimer LLFrameTimer::sInternalTimer; diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index 4674985e06..062c9360dd 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -39,8 +39,10 @@ #if defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION > LL_PROFILER_CONFIG_NONE) #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER #define TRACY_ENABLE 1 - #define TRACY_NO_BROADCAST 1 - #define TRACY_ONLY_LOCALHOST 1 +// Normally these would be enabled but we want to be able to build any viewer with Tracy enabled and run the Tracy server on another machine +// They must be undefined in order to work across multiple machines +// #define TRACY_NO_BROADCAST 1 +// #define TRACY_ONLY_LOCALHOST 1 #define TRACY_ONLY_IPV4 1 #include "Tracy.hpp" #endif -- cgit v1.2.3 From fc612fd8a0057daa7436c8d2285ccee0c634378a Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Mon, 13 Sep 2021 12:41:57 -0500 Subject: SL-15975 Add Tracy-only profile macros that are no-ops when Tracy is disabled. --- indra/llcommon/llprofiler.h | 6 ++++++ indra/newview/lldrawpoolavatar.cpp | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index 062c9360dd..62e649913b 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -51,16 +51,22 @@ #define LL_PROFILER_FRAME_END FrameMark #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); + #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, name, true ); + #define LL_PROFILE_ZONE_SCOPED ZoneScoped #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_FAST_TIMER #define LL_PROFILER_FRAME_END #define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name) #define LL_RECORD_BLOCK_TIME(name) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + #define LL_PROFILE_ZONE_NAMED(name) // LL_PROFILE_ZONE_NAMED is a no-op when Tracy is disabled + #define LL_PROFILE_ZONE_SCOPED // LL_PROFILE_ZONE_SCOPED is a no-op when Tracy is disabled #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER #define LL_PROFILER_FRAME_END FrameMark #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN( ___tracy_scoped_zone, #timer_stat, true ) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); + #define LL_PROFILE_ZONE_SCOPED ZoneScoped #endif #else #define LL_PROFILER_FRAME_END diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 687b13d2c8..c04142ab47 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1840,6 +1840,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLVolume* volume, LLVolumeFace& vol_face) { + LL_PROFILE_ZONE_SCOPED; + LLVector4a* weights = vol_face.mWeights; if (!weights) { @@ -2352,8 +2354,10 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) //update rigged vertex buffers for (U32 type = 0; type < NUM_RIGGED_PASSES; ++type) { + LL_PROFILE_ZONE_NAMED("Pass"); for (U32 i = 0; i < mRiggedFace[type].size(); ++i) { + LL_PROFILE_ZONE_NAMED("Face"); LLFace* face = mRiggedFace[type][i]; LLDrawable* drawable = face->getDrawable(); if (!drawable) -- cgit v1.2.3 From 84da92663aad221db19927de26922417e7cb45c6 Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Tue, 14 Sep 2021 20:18:58 -0500 Subject: SL-15961 Convert LLMeshRepository::mSkinMap into unordered_map and reduce number of per-frame lookups to said map. --- indra/llcommon/lluuid.h | 11 +++++++ indra/newview/lldrawpoolavatar.cpp | 65 ++++++++++++++++++-------------------- indra/newview/lldrawpoolavatar.h | 3 +- indra/newview/llmeshrepository.cpp | 40 +++++++++++------------ indra/newview/llmeshrepository.h | 3 +- 5 files changed, 65 insertions(+), 57 deletions(-) diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h index fe7482ba29..86a396ab06 100644 --- a/indra/llcommon/lluuid.h +++ b/indra/llcommon/lluuid.h @@ -184,6 +184,17 @@ struct boost::hash } }; +// Adapt boost hash to std hash +namespace std +{ + template<> struct hash + { + std::size_t operator()(LLUUID const& s) const noexcept + { + return boost::hash()(s); + } + }; +} #endif diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index c04142ab47..6c4844f9ee 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1836,7 +1836,7 @@ void LLDrawPoolAvatar::getRiggedGeometry( void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLVOAvatar* avatar, LLFace* face, - const LLMeshSkinInfo* skin, + const LLVOVolume* vobj, LLVolume* volume, LLVolumeFace& vol_face) { @@ -1848,14 +1848,14 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( return; } + if (!vobj || vobj->isNoLOD()) + { + return; + } + LLPointer buffer = face->getVertexBuffer(); LLDrawable* drawable = face->getDrawable(); - if (drawable->getVOVolume() && drawable->getVOVolume()->isNoLOD()) - { - return; - } - const U32 max_joints = LLSkinningUtil::getMaxJointCount(); #if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS @@ -1895,23 +1895,26 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( } #endif - // FIXME ugly const cast - LLSkinningUtil::scrubInvalidJoints(avatar, const_cast(skin)); - - U32 data_mask = face->getRiggedVertexBufferDataMask(); + U32 data_mask = face->getRiggedVertexBufferDataMask(); + const LLMeshSkinInfo* skin = nullptr; - if (!vol_face.mWeightsScrubbed) - { - LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin); - vol_face.mWeightsScrubbed = TRUE; - } - if (buffer.isNull() || buffer->getTypeMask() != data_mask || buffer->getNumVerts() != vol_face.mNumVertices || buffer->getNumIndices() != vol_face.mNumIndices || (drawable && drawable->isState(LLDrawable::REBUILD_ALL))) { + LL_PROFILE_ZONE_NAMED("Rigged VBO Rebuild"); + skin = vobj->getSkinInfo(); + // FIXME ugly const cast + LLSkinningUtil::scrubInvalidJoints(avatar, const_cast(skin)); + + if (!vol_face.mWeightsScrubbed) + { + LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin); + vol_face.mWeightsScrubbed = TRUE; + } + if (drawable && drawable->isState(LLDrawable::REBUILD_ALL)) { //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues @@ -1937,18 +1940,13 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( } } - if (buffer.isNull() || - buffer->getNumVerts() != vol_face.mNumVertices || - buffer->getNumIndices() != vol_face.mNumIndices) - { - // Allocation failed - return; - } - - if (!buffer.isNull() && - sShaderLevel <= 0 && - face->mLastSkinTime < avatar->getLastSkinTime()) + if (sShaderLevel <= 0 && + face->mLastSkinTime < avatar->getLastSkinTime() && + !buffer.isNull() && + buffer->getNumVerts() == vol_face.mNumVertices && + buffer->getNumIndices() == vol_face.mNumIndices) { + LL_PROFILE_ZONE_NAMED("Software Skinning"); //perform software vertex skinning for this face LLStrider position; LLStrider normal; @@ -1965,6 +1963,11 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL; + if (skin == nullptr) + { + skin = vobj->getSkinInfo(); + } + //build matrix palette LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; U32 count = LLSkinningUtil::getMeshJointCount(skin); @@ -2380,16 +2383,10 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) continue; } - const LLMeshSkinInfo* skin = vobj->getSkinInfo(); - if (!skin) - { - continue; - } - stop_glerror(); LLVolumeFace& vol_face = volume->getVolumeFace(te); - updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face); + updateRiggedFaceVertexBuffer(avatar, face, vobj, volume, vol_face); } } } diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 92a8538958..9b26266ced 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -30,6 +30,7 @@ #include "lldrawpool.h" class LLVOAvatar; +class LLVOVolume; class LLGLSLShader; class LLFace; class LLMeshSkinInfo; @@ -253,7 +254,7 @@ typedef enum void getRiggedGeometry(LLFace* face, LLPointer& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face); void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* facep, - const LLMeshSkinInfo* skin, + const LLVOVolume* vobj, LLVolume* volume, LLVolumeFace& vol_face); void updateRiggedVertexBuffers(LLVOAvatar* avatar); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 2c1c1191da..8ac64dbd15 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -4046,28 +4046,26 @@ S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj) { LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); + if (mesh_id.notNull()) + { + skin_map::iterator iter = mSkinMap.find(mesh_id); + if (iter != mSkinMap.end()) + { + return &(iter->second); + } - if (mesh_id.notNull()) - { - skin_map::iterator iter = mSkinMap.find(mesh_id); - if (iter != mSkinMap.end()) - { - return &(iter->second); - } - - //no skin info known about given mesh, try to fetch it - { - LLMutexLock lock(mMeshMutex); - //add volume to list of loading meshes - skin_load_map::iterator iter = mLoadingSkins.find(mesh_id); - if (iter == mLoadingSkins.end()) - { //no request pending for this skin info - mPendingSkinRequests.push(mesh_id); - } - mLoadingSkins[mesh_id].insert(requesting_obj->getID()); - } - } - + //no skin info known about given mesh, try to fetch it + { + LLMutexLock lock(mMeshMutex); + //add volume to list of loading meshes + skin_load_map::iterator iter = mLoadingSkins.find(mesh_id); + if (iter == mLoadingSkins.end()) + { //no request pending for this skin info + mPendingSkinRequests.push(mesh_id); + } + mLoadingSkins[mesh_id].insert(requesting_obj->getID()); + } + } return NULL; } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 81e49cb1d8..c1698194cb 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -27,6 +27,7 @@ #ifndef LL_MESH_REPOSITORY_H #define LL_MESH_REPOSITORY_H +#include #include "llassettype.h" #include "llmodel.h" #include "lluuid.h" @@ -613,7 +614,7 @@ public: typedef std::map > mesh_load_map; mesh_load_map mLoadingMeshes[4]; - typedef std::map skin_map; + typedef std::unordered_map skin_map; skin_map mSkinMap; typedef std::map decomposition_map; -- cgit v1.2.3 From 6f03dc8d048ca82e49592b3358f7b1f2a74137ec Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Tue, 14 Sep 2021 20:50:55 -0500 Subject: SL-15038 Added Tracy instrumentation to name tags and chat bubbles. --- indra/newview/llhudnametag.cpp | 2 ++ indra/newview/llvoavatar.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 9d49c30a49..55a4b5a457 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -224,6 +224,7 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector4a& start, const LLVector4 void LLHUDNameTag::render() { + LL_PROFILE_ZONE_SCOPED; if (sDisplayText) { LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); @@ -731,6 +732,7 @@ void LLHUDNameTag::updateSize() void LLHUDNameTag::updateAll() { + LL_PROFILE_ZONE_SCOPED; // iterate over all text objects, calculate their restoration forces, // and add them to the visible set if they are on screen and close enough sVisibleTextObjects.clear(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index e085a945a8..ba9f8d14cb 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -3136,6 +3136,8 @@ void LLVOAvatar::idleUpdateWindEffect() void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) { + LL_PROFILE_ZONE_SCOPED; + // update chat bubble //-------------------------------------------------------------------- // draw text label over character's head -- cgit v1.2.3 From 6c6eb59e947631275b2149208e4b46977dfa0309 Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Wed, 15 Sep 2021 10:11:25 -0600 Subject: SL-15962 Add hooks for tracy memory profiling --- indra/llcommon/linden_common.h | 8 ++++++++ indra/llcommon/llcommon.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h index 45ac43910c..b2c5be6b76 100644 --- a/indra/llcommon/linden_common.h +++ b/indra/llcommon/linden_common.h @@ -27,6 +27,14 @@ #ifndef LL_LINDEN_COMMON_H #define LL_LINDEN_COMMON_H +#include "llprofiler.h" +#if (TRACY_ENABLE) // hooks for memory profiling +void *tracy_aligned_malloc(size_t size, size_t alignment); +void tracy_aligned_free(void *memblock); +#define _aligned_malloc(X, Y) tracy_aligned_malloc((X), (Y)) +#define _aligned_free(X) tracy_aligned_free((X)) +#endif + // *NOTE: Please keep includes here to a minimum! // // Files included here are included in every library .cpp file and diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index 96be913d17..da61e7539a 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -33,6 +33,48 @@ #include "lltracethreadrecorder.h" #include "llcleanup.h" +#if (TRACY_ENABLE) +// Override new/delet for tracy memory profiling +void *operator new(size_t size) +{ + auto ptr = (malloc) (size); + if (!ptr) + { + throw std::bad_alloc(); + return nullptr; + } + TracyAlloc(ptr, size); + return ptr; +} + +void operator delete(void *ptr) noexcept +{ + TracyFree(ptr); + (free)(ptr); +} + +// C-style malloc/free can't be so easily overridden, so we define tracy versions and use +// a pre-processor #define in linden_common.h to redirect to them. The parens around the native +// functions below prevents recursive substitution by the preprocessor. +// +// Unaligned mallocs are rare in LL code but hooking them causes problems in 3p lib code (looking at +// you, Havok), so we'll only capture the aligned version. + +void *tracy_aligned_malloc(size_t size, size_t alignment) +{ + auto ptr = (_aligned_malloc) (size, alignment); + if (ptr) TracyAlloc(ptr, size); + return ptr; +} + +void tracy_aligned_free(void *memblock) +{ + TracyFree(memblock); + (_aligned_free)(memblock); +} + +#endif + //static BOOL LLCommon::sAprInitialized = FALSE; -- cgit v1.2.3