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/llcommon/llframetimer.cpp | 11 ++++------- indra/llcommon/llprofiler.h | 6 ++++-- 2 files changed, 8 insertions(+), 9 deletions(-) (limited to 'indra/llcommon') 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.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(+) (limited to 'indra/llcommon') 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.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(-) (limited to 'indra/llcommon') 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.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(+) (limited to 'indra/llcommon') 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.3