diff --git a/autobuild.xml b/autobuild.xml index 77c5f985cf..54de295254 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -261,35 +261,69 @@ version 1.2.15 - Tracy + tracy + canonical_repo + https://bitbucket.org/lindenlab/3p-tracy copyright - Copyright (c) 2017-2021, Bartosz Taudul + Copyright (c) 2017-2021, Bartosz Taudul (wolf@nereid.pl) description - A real time, nanosecond resolution, remote telemetry, hybrid frame and sampling profiler for games and other applications. + Tracy Profiler Library license - BSD + bsd license_file - LICENSES/Tracy.txt + LICENSES/tracy_license.txt name - Tracy + tracy platforms - common + darwin64 archive hash - b0a0fc6b7bda02fe14cccea2dd342058 + da7317e4a81609f624f84780f28b07de url - http://3p.firestormviewer.org/Tracy-0.7.6-windows-210902110.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86972/801630/tracy-v0.7.8.563351-darwin64-563351.tar.bz2 name - common + darwin64 + + windows + + archive + + hash + 47c696cd2966c5cc3c8ba6115dd1f886 + hash_algorithm + md5 + url + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86973/801641/tracy-v0.7.8.563351-windows-563351.tar.bz2 + + name + windows + + windows64 + + archive + + hash + b649ee6591e67d2341e886b3fc3484a7 + hash_algorithm + md5 + url + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86974/801642/tracy-v0.7.8.563351-windows64-563351.tar.bz2 + + name + windows64 + source + https://bitbucket.org/lindenlab/3p-tracy + source_type + git version - 0.7.6 + v0.7.8.563351 apr_suite @@ -3261,6 +3295,70 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors version 4.10.0000.32327.5fc3fe7c.539691 + tracy + + canonical_repo + https://bitbucket.org/lindenlab/3p-tracy + copyright + Copyright (c) 2017-2021, Bartosz Taudul (wolf@nereid.pl) + description + Tracy Profiler Library + license + bsd + license_file + LICENSES/tracy_license.txt + name + tracy + platforms + + darwin64 + + archive + + hash + da7317e4a81609f624f84780f28b07de + url + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86972/801630/tracy-v0.7.8.563351-darwin64-563351.tar.bz2 + + name + darwin64 + + windows + + archive + + hash + 47c696cd2966c5cc3c8ba6115dd1f886 + hash_algorithm + md5 + url + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86973/801641/tracy-v0.7.8.563351-windows-563351.tar.bz2 + + name + windows + + windows64 + + archive + + hash + b649ee6591e67d2341e886b3fc3484a7 + hash_algorithm + md5 + url + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86974/801642/tracy-v0.7.8.563351-windows64-563351.tar.bz2 + + name + windows64 + + + source + https://bitbucket.org/lindenlab/3p-tracy + source_type + git + version + v0.7.8.563351 + tut copyright diff --git a/build.sh b/build.sh index 8d49e5a137..d92a4e6785 100755 --- a/build.sh +++ b/build.sh @@ -132,7 +132,11 @@ pre_build() fi set -x - "$autobuild" configure --quiet -c $variant -- \ + # honor autobuild_configure_parameters same as sling-buildscripts + eval_autobuild_configure_parameters=$(eval $(echo echo $autobuild_configure_parameters)) + + "$autobuild" configure --quiet -c $variant \ + ${eval_autobuild_configure_parameters:---} \ -DPACKAGE:BOOL=ON \ -DHAVOK:BOOL="$HAVOK" \ -DRELEASE_CRASH_REPORTING:BOOL="$RELEASE_CRASH_REPORTING" \ @@ -182,7 +186,11 @@ build() if $build_viewer then begin_section "autobuild $variant" - "$autobuild" build --no-configure -c $variant || fatal "failed building $variant" + # honor autobuild_build_parameters same as sling-buildscripts + eval_autobuild_build_parameters=$(eval $(echo echo $autobuild_build_parameters)) + "$autobuild" build --no-configure -c $variant \ + $eval_autobuild_build_parameters \ + || fatal "failed building $variant" echo true >"$build_dir"/build_ok end_section "autobuild $variant" diff --git a/doc/contributions.txt b/doc/contributions.txt index 947fe19cfb..ca516f0fce 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -272,6 +272,7 @@ Beq Janus SL-13583 SL-14766 SL-14927 + SL-15709 Beth Walcher Bezilon Kasei Biancaluce Robbiani diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 67297ffb48..069c8e53d2 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -77,12 +77,12 @@ endif (USE_AVX_OPTIMIZATION) add_subdirectory(cmake) # Tracy Profiler support -option(USE_TRACY_PROFILER "Tracy Profiler support" OFF) -if (USE_TRACY_PROFILER) +option(USE_TRACY "Tracy Profiler support" OFF) +if (USE_TRACY) message(STATUS "Compiling with Tracy profiler") -else (USE_TRACY_PROFILER) +else (USE_TRACY) message(STATUS "Compiling without Tracy profiler") -endif (USE_TRACY_PROFILER) +endif (USE_TRACY) # Tracy Profiler support add_subdirectory(${LIBS_OPEN_PREFIX}llaudio) diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index 8c209fdb7e..843cb7905c 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -39,7 +39,8 @@ else (LINUX) ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_THREAD_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} ) + ${BOOST_SYSTEM_LIBRARY} + ) endif (LINUX) set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a static library.") diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index b3bfb6fc65..832a5936a7 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -1,16 +1,29 @@ -# Tracy Profiler support. -if (USE_TRACY_PROFILER) - include(Prebuilt) - use_prebuilt_binary(Tracy) - if (WINDOWS) - # set(TRACY_LIBRARIES - # ${ARCH_PREBUILT_DIRS_RELEASE}/Tracy.lib - add_definitions(-DTRACY_ENABLE=1 -DTRACY_NO_FASTTIMERS -DWINVER=0x0601 ) - set(TRACY_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tracy) - elseif (DARWIN) - message(FATAL_ERROR "Tracy is not yet implemented in FS for OSX.") - else (WINDOWS) - add_definitions(-DTRACY_ENABLE=1 -DTRACY_NO_FASTTIMERS ) - set(TRACY_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tracy) - endif (WINDOWS) -endif (USE_TRACY_PROFILER) +# -*- cmake -*- +include(Prebuilt) + +set(USE_TRACY OFF CACHE BOOL "Use Tracy profiler.") + +if (USE_TRACY) + set(TRACY_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tracy) + +# See: indra/llcommon/llprofiler.h + add_definitions(-DLL_PROFILER_CONFIGURATION=2) + use_prebuilt_binary(tracy) + + # if (WINDOWS) + # MESSAGE(STATUS "Including Tracy for Windows: '${TRACY_INCLUDE_DIR}'") + # endif (WINDOWS) + + # if (DARWIN) + # MESSAGE(STATUS "Including Tracy for Darwin: '${TRACY_INCLUDE_DIR}'") + # endif (DARWIN) + + # if (LINUX) + # MESSAGE(STATUS "Including Tracy for Linux: '${TRACY_INCLUDE_DIR}'") + # endif (LINUX) +else (USE_TRACY) + # Tracy.cmake should not set LLCOMMON_INCLUDE_DIRS, let LLCommon.cmake do that + set(TRACY_INCLUDE_DIR "") + set(TRACY_LIBRARY "") +endif (USE_TRACY) + diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 9664617fa4..bb259280f4 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -13,6 +13,7 @@ include(GoogleBreakpad) include(Copy3rdPartyLibs) include(ZLIB) include(URIPARSER) +include(Tracy) include_directories( ${EXPAT_INCLUDE_DIRS} @@ -21,6 +22,7 @@ include_directories( ${ZLIB_INCLUDE_DIRS} ${BREAKPAD_INCLUDE_DIRECTORIES} ${URIPARSER_INCLUDE_DIRS} + ${TRACY_INCLUDE_DIR} ) # add_executable(lltreeiterators lltreeiterators.cpp) @@ -199,6 +201,7 @@ set(llcommon_HEADER_FILES llmortician.h llnametable.h llpointer.h + llprofiler.h llpounceable.h llpredicate.h llpreprocessor.h @@ -261,9 +264,10 @@ set(llcommon_HEADER_FILES # Add all nd* files. memory pool, intrinsics, ... # Tracy Profiler support list(APPEND llcommon_SOURCE_FILES fstelemetry.cpp) -if (USE_TRACY_PROFILER) - list(APPEND llcommon_SOURCE_FILES fstracyclient.cpp) -endif() +#if (USE_TRACY) +# MESSAGE(STATUS "Linking fstracyclient.cpp") +# list(APPEND llcommon_SOURCE_FILES fstracyclient.cpp) +#endif() SET( llcommon_ND_SOURCE_FILES nd/ndexceptions.cpp @@ -343,6 +347,7 @@ target_link_libraries( ${BOOST_SYSTEM_LIBRARY} ${GOOGLE_PERFTOOLS_LIBRARIES} ${URIPARSER_LIBRARIES} + ${TRACY_LIBRARY} ) if (DARWIN) diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h index e5a913a6a9..a228fd22be 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 && !defined(LL_PROFILER_ENABLE_TRACY_OPENGL) // 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..5d4a623bf6 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -33,6 +33,47 @@ #include "lltracethreadrecorder.h" #include "llcleanup.h" +#if (TRACY_ENABLE) +// Override new/delete for tracy memory profiling +void *operator new(size_t size) +{ + auto ptr = (malloc) (size); + if (!ptr) + { + throw std::bad_alloc(); + } + 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 = ll_aligned_malloc_fallback(size, alignment); + if (ptr) TracyAlloc(ptr, size); + return ptr; +} + +void tracy_aligned_free(void *memblock) +{ + TracyFree(memblock); + ll_aligned_free_fallback(memblock); +} + +#endif + //static BOOL LLCommon::sAprInitialized = FALSE; diff --git a/indra/llcommon/lleventfilter.cpp b/indra/llcommon/lleventfilter.cpp index 4cded7f88e..f9aef14b1b 100644 --- a/indra/llcommon/lleventfilter.cpp +++ b/indra/llcommon/lleventfilter.cpp @@ -67,6 +67,8 @@ LLEventMatching::LLEventMatching(LLEventPump& source, const LLSD& pattern): bool LLEventMatching::post(const LLSD& event) { + LL_PROFILE_ZONE_SCOPED + if (! llsd_matches(mPattern, event).empty()) return false; @@ -88,6 +90,8 @@ LLEventTimeoutBase::LLEventTimeoutBase(LLEventPump& source): void LLEventTimeoutBase::actionAfter(F32 seconds, const Action& action) { + LL_PROFILE_ZONE_SCOPED + setCountdown(seconds); mAction = action; if (! mMainloop.connected()) @@ -126,6 +130,8 @@ public: void operator()() { + LL_PROFILE_ZONE_SCOPED + mPump.post(mEvent); } @@ -136,6 +142,8 @@ private: void LLEventTimeoutBase::eventAfter(F32 seconds, const LLSD& event) { + LL_PROFILE_ZONE_SCOPED + actionAfter(seconds, EventAfter(*this, event)); } @@ -152,6 +160,8 @@ void LLEventTimeoutBase::cancel() bool LLEventTimeoutBase::tick(const LLSD&) { + LL_PROFILE_ZONE_SCOPED + if (countdownElapsed()) { cancel(); @@ -189,7 +199,9 @@ LLEventTimer* LLEventTimeout::post_every(F32 period, const std::string& pump, co { return LLEventTimer::run_every( period, - [pump, data](){ LLEventPumps::instance().obtain(pump).post(data); }); + [pump, data](){ + LL_PROFILE_ZONE_SCOPED + LLEventPumps::instance().obtain(pump).post(data); }); } LLEventTimer* LLEventTimeout::post_at(const LLDate& time, const std::string& pump, const LLSD& data) @@ -221,6 +233,8 @@ LLEventBatch::LLEventBatch(LLEventPump& source, std::size_t size): void LLEventBatch::flush() { + LL_PROFILE_ZONE_SCOPED + // copy and clear mBatch BEFORE posting to avoid weird circularity effects LLSD batch(mBatch); mBatch.clear(); @@ -229,6 +243,8 @@ void LLEventBatch::flush() bool LLEventBatch::post(const LLSD& event) { + LL_PROFILE_ZONE_SCOPED + mBatch.append(event); // calling setSize(same) performs the very check we want setSize(mBatchSize); @@ -267,6 +283,8 @@ void LLEventThrottleBase::flush() // post() anything but an isUndefined(). This is what mPosts is for. if (mPosts) { + LL_PROFILE_ZONE_SCOPED + mPosts = 0; alarmCancel(); // This is not to set our alarm; we are not yet requesting @@ -288,6 +306,8 @@ LLSD LLEventThrottleBase::pending() const bool LLEventThrottleBase::post(const LLSD& event) { + LL_PROFILE_ZONE_SCOPED + // Always capture most recent post() event data. If caller wants to // aggregate multiple events, let them retrieve pending() and modify // before calling post(). @@ -411,6 +431,8 @@ LLEventBatchThrottle::LLEventBatchThrottle(LLEventPump& source, F32 interval, st bool LLEventBatchThrottle::post(const LLSD& event) { + LL_PROFILE_ZONE_SCOPED + // simply retrieve pending value and append the new event to it LLSD partial = pending(); partial.append(event); @@ -447,6 +469,8 @@ LLEventLogProxy::LLEventLogProxy(LLEventPump& source, const std::string& name, b bool LLEventLogProxy::post(const LLSD& event) /* override */ { + LL_PROFILE_ZONE_SCOPED + auto counter = mCounter++; auto eventplus = event; if (eventplus.type() == LLSD::TypeMap) diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h index 48c2570732..7613850fb2 100644 --- a/indra/llcommon/lleventfilter.h +++ b/indra/llcommon/lleventfilter.h @@ -429,6 +429,8 @@ public: // path, then stores it to mTarget. virtual bool post(const LLSD& event) { + LL_PROFILE_ZONE_SCOPED + // Extract the element specified by 'mPath' from 'event'. To perform a // generic type-appropriate store through mTarget, construct an // LLSDParam and store that, thus engaging LLSDParam's custom diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h index e380c108f4..8ed37365a4 100644 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h @@ -95,6 +95,8 @@ struct LLStopWhenHandled template result_type operator()(InputIterator first, InputIterator last) const { + LL_PROFILE_ZONE_SCOPED + for (InputIterator si = first; si != last; ++si) { try diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index f77d880fc4..ac7d731805 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -38,27 +38,10 @@ #define LL_FAST_TIMER_ON 1 #define LL_FASTTIMER_USE_RDTSC 1 -// Add Tracy profiler support -/* -#define LL_RECORD_BLOCK_TIME(timer_stat) \ -const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(timer_stat)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); -*/ -#include "fstelemetry.h" -#ifdef TRACY_ENABLE -// #undef TRACY_NO_FASTTIMERS // Uncomment if you want FASTTIMERS as well. -#ifdef TRACY_NO_FASTTIMERS -#define LL_RECORD_BLOCK_TIME(timer_stat) \ -FSZoneN( #timer_stat ); -#else // TRACY_NO_FASTTIMERS -#define LL_RECORD_BLOCK_TIME(timer_stat) \ -FSZoneN( #timer_stat ); \ -const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(timer_stat)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); -#endif // TRACY_NO_FASTTIMERS -#else // TRACY_ENABLE -#define LL_RECORD_BLOCK_TIME(timer_stat) \ -const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(timer_stat)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); -#endif // TRACY_ENABLE -// +// NOTE: Also see llprofiler.h +#if !defined(LL_PROFILER_CONFIGURATION) +#define LL_RECORD_BLOCK_TIME(timer_stat) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(timer_stat)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); +#endif // LL_PROFILER_CONFIGURATION namespace LLTrace { diff --git a/indra/llcommon/llframetimer.cpp b/indra/llcommon/llframetimer.cpp index 1e9920746b..c54029e8b4 100644 --- a/indra/llcommon/llframetimer.cpp +++ b/indra/llcommon/llframetimer.cpp @@ -29,6 +29,11 @@ #include "llframetimer.h" +// 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; U64 LLFrameTimer::sStartTotalTime = totalTime(); diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h new file mode 100644 index 0000000000..427cdc60ad --- /dev/null +++ b/indra/llcommon/llprofiler.h @@ -0,0 +1,139 @@ +/** + * @file llprofiler.h + * @brief Wrapper for Tracy and/or other profilers + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_PROFILER_H +#define LL_PROFILER_H + +#define LL_PROFILER_CONFIG_NONE 0 // No profiling +#define LL_PROFILER_CONFIG_FAST_TIMER 1 // Profiling on: Only Fast Timers +#define LL_PROFILER_CONFIG_TRACY 2 // Profiling on: Only Tracy +#define LL_PROFILER_CONFIG_TRACY_FAST_TIMER 3 // Profiling on: Fast Timers + Tracy + +#ifndef LL_PROFILER_CONFIGURATION +#define LL_PROFILER_CONFIGURATION LL_PROFILER_CONFIG_FAST_TIMER +#endif + +#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 +// 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" + + // Mutually exclusive with detailed memory tracing + #define LL_PROFILER_ENABLE_TRACY_OPENGL 0 + #endif + + #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY + #define LL_PROFILER_FRAME_END FrameMark + #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) + #define LL_PROFILER_THREAD_BEGIN(name) FrameMarkStart( name ) // C string + #define LL_PROFILER_THREAD_END(name) FrameMarkEnd( name ) // C string + // revert change that obscures custom FTM zones. + // #define LL_RECORD_BLOCK_TIME(name) ZoneScoped // Want descriptive names; was: ZoneNamedN( ___tracy_scoped_zone, #name, true ); + #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_NAMED_COLOR(name,color) ZoneNamedNC( ___tracy_scopped_zone, name, color, true ) // RGB + #define LL_PROFILE_ZONE_SCOPED ZoneScoped + + #define LL_PROFILE_ZONE_NUM( val ) ZoneValue( val ) + #define LL_PROFILE_ZONE_TEXT( text, size ) ZoneText( text, size ) + + #define LL_PROFILE_ZONE_ERR(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0XFF0000 ) // RGB yellow + #define LL_PROFILE_ZONE_INFO(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0X00FFFF ) // RGB cyan + #define LL_PROFILE_ZONE_WARN(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0x0FFFF00 ) // RGB red + + // Additional FS Tracy macros + #define LL_PROFILE_ZONE_COLOR(color) ZoneNamedC( ___tracy_scoped_zone, color, true ) // Additional Tracy macro + #define LL_PROFILE_PLOT( name, value ) TracyPlot( name, value) + #define LL_PROFILE_PLOT_SQ( name, prev, value ) TracyPlot(name,prev);TracyPlot( name, value) + #define LL_PROFILE_IS_CONNECTED TracyIsConnected + // + #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_PROFILER_THREAD_BEGIN(name) (void)(name); // Not supported + #define LL_PROFILER_THREAD_END(name) (void)(name); // Not supported + + #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 + // Fix mismatch across ifdef + // #define LL_PROFILE_ZONE_COLOR(name,color) + #define LL_PROFILE_ZONE_COLOR(color) + // + + #define LL_PROFILE_ZONE_NUM( val ) (void)( val ); // Not supported + #define LL_PROFILE_ZONE_TEXT( text, size ) (void)( text ); void( size ); // Not supported + + #define LL_PROFILE_ZONE_ERR(name) (void)(name); // Not supported + #define LL_PROFILE_ZONE_INFO(name) (void)(name); // Not supported + #define LL_PROFILE_ZONE_WARN(name) (void)(name); // Not supported + // Additional FS Tracy macros + #define LL_PROFILE_ZONE_NAMED_COLOR(name,color) + #define LL_PROFILE_PLOT( name, value ) + #define LL_PROFILE_PLOT_SQ( name, prev, value ) + #define LL_PROFILE_IS_CONNECTED + // + #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_PROFILER_THREAD_BEGIN(name) FrameMarkStart( name ) // C string + #define LL_PROFILER_THREAD_END(name) FrameMarkEnd( name ) // C string + + // revert change that obscures custom FTM zones. + // #define LL_RECORD_BLOCK_TIME(name) ZoneScoped const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN( ___tracy_scoped_zone, #name, 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_NAMED_COLOR(name,color) ZoneNamedNC( ___tracy_scopped_zone, name, color, true ) // RGB + #define LL_PROFILE_ZONE_SCOPED ZoneScoped + + #define LL_PROFILE_ZONE_NUM( val ) ZoneValue( val ) + #define LL_PROFILE_ZONE_TEXT( text, size ) ZoneText( text, size ) + + #define LL_PROFILE_ZONE_ERR(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0XFF0000 ) // RGB yellow + #define LL_PROFILE_ZONE_INFO(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0X00FFFF ) // RGB cyan + #define LL_PROFILE_ZONE_WARN(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0x0FFFF00 ) // RGB red + // Additional FS Tracy macros + #define LL_PROFILE_ZONE_COLOR(color) ZoneNamedC( ___tracy_scoped_zone, color, true ) + #define LL_PROFILE_PLOT( name, value ) TracyPlot( name, value) + #define LL_PROFILE_PLOT_SQ( name, prev, value ) TracyPlot( name, prev );TracyPlot( name, value ) + #define LL_PROFILE_IS_CONNECTED TracyIsConnected + // + #endif +#else + #define LL_PROFILER_FRAME_END + #define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name) +#endif // LL_PROFILER + +#endif // LL_PROFILER_H diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 3f3ef2be8a..66111a7602 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -112,6 +112,8 @@ void LLQueuedThread::shutdown() // virtual S32 LLQueuedThread::update(F32 max_time_ms) { + LL_PROFILE_ZONE_SCOPED + if (!mStarted) { if (!mThreaded) @@ -125,6 +127,8 @@ S32 LLQueuedThread::update(F32 max_time_ms) S32 LLQueuedThread::updateQueue(F32 max_time_ms) { + LL_PROFILE_ZONE_SCOPED + F64 max_time = (F64)max_time_ms * .001; LLTimer timer; S32 pending = 1; @@ -147,11 +151,14 @@ S32 LLQueuedThread::updateQueue(F32 max_time_ms) break; } } + return pending; } void LLQueuedThread::incQueue() { + LL_PROFILE_ZONE_SCOPED + // Something has been added to the queue if (!isPaused()) { @@ -166,6 +173,8 @@ void LLQueuedThread::incQueue() // May be called from any thread S32 LLQueuedThread::getPending() { + LL_PROFILE_ZONE_SCOPED + S32 res; lockData(); res = mRequestQueue.size(); @@ -176,6 +185,8 @@ S32 LLQueuedThread::getPending() // MAIN thread void LLQueuedThread::waitOnPending() { + LL_PROFILE_ZONE_SCOPED + while(1) { update(0); @@ -195,6 +206,8 @@ void LLQueuedThread::waitOnPending() // MAIN thread void LLQueuedThread::printQueueStats() { + LL_PROFILE_ZONE_SCOPED + lockData(); if (!mRequestQueue.empty()) { @@ -211,6 +224,8 @@ void LLQueuedThread::printQueueStats() // MAIN thread LLQueuedThread::handle_t LLQueuedThread::generateHandle() { + LL_PROFILE_ZONE_SCOPED + lockData(); while ((mNextHandle == nullHandle()) || (mRequestHash.find(mNextHandle))) { @@ -224,6 +239,8 @@ LLQueuedThread::handle_t LLQueuedThread::generateHandle() // MAIN thread bool LLQueuedThread::addRequest(QueuedRequest* req) { + LL_PROFILE_ZONE_SCOPED + if (mStatus == QUITTING) { return false; @@ -246,6 +263,8 @@ bool LLQueuedThread::addRequest(QueuedRequest* req) // MAIN thread bool LLQueuedThread::waitForResult(LLQueuedThread::handle_t handle, bool auto_complete) { + LL_PROFILE_ZONE_SCOPED + llassert (handle != nullHandle()); bool res = false; bool waspaused = isPaused(); @@ -281,12 +300,15 @@ bool LLQueuedThread::waitForResult(LLQueuedThread::handle_t handle, bool auto_co { pause(); } + return res; } // MAIN thread LLQueuedThread::QueuedRequest* LLQueuedThread::getRequest(handle_t handle) { + LL_PROFILE_ZONE_SCOPED + if (handle == nullHandle()) { return 0; @@ -299,6 +321,8 @@ LLQueuedThread::QueuedRequest* LLQueuedThread::getRequest(handle_t handle) LLQueuedThread::status_t LLQueuedThread::getRequestStatus(handle_t handle) { + LL_PROFILE_ZONE_SCOPED + status_t res = STATUS_EXPIRED; lockData(); QueuedRequest* req = (QueuedRequest*)mRequestHash.find(handle); @@ -312,6 +336,8 @@ LLQueuedThread::status_t LLQueuedThread::getRequestStatus(handle_t handle) void LLQueuedThread::abortRequest(handle_t handle, bool autocomplete) { + LL_PROFILE_ZONE_SCOPED + lockData(); QueuedRequest* req = (QueuedRequest*)mRequestHash.find(handle); if (req) @@ -324,6 +350,8 @@ void LLQueuedThread::abortRequest(handle_t handle, bool autocomplete) // MAIN thread void LLQueuedThread::setFlags(handle_t handle, U32 flags) { + LL_PROFILE_ZONE_SCOPED + lockData(); QueuedRequest* req = (QueuedRequest*)mRequestHash.find(handle); if (req) @@ -335,6 +363,8 @@ void LLQueuedThread::setFlags(handle_t handle, U32 flags) void LLQueuedThread::setPriority(handle_t handle, U32 priority) { + LL_PROFILE_ZONE_SCOPED + lockData(); QueuedRequest* req = (QueuedRequest*)mRequestHash.find(handle); if (req) @@ -357,6 +387,8 @@ void LLQueuedThread::setPriority(handle_t handle, U32 priority) bool LLQueuedThread::completeRequest(handle_t handle) { + LL_PROFILE_ZONE_SCOPED + bool res = false; lockData(); QueuedRequest* req = (QueuedRequest*)mRequestHash.find(handle); @@ -401,6 +433,8 @@ bool LLQueuedThread::check() S32 LLQueuedThread::processNextRequest() { + LL_PROFILE_ZONE_SCOPED + QueuedRequest *req; // Get next request from pool lockData(); @@ -517,9 +551,11 @@ void LLQueuedThread::run() mIdleThread = FALSE; + LL_PROFILER_THREAD_BEGIN(mName.c_str()) threadedUpdate(); - + int pending_work = processNextRequest(); + LL_PROFILER_THREAD_END(mName.c_str()) if (pending_work == 0) { diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index d5cc14ff55..97ef79fb64 100644 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -214,6 +214,8 @@ BOOL compare_llsd_with_template( const LLSD& template_llsd, LLSD& resultant_llsd) { + LL_PROFILE_ZONE_SCOPED + if ( llsd_to_test.isUndefined() && template_llsd.isDefined() ) @@ -335,6 +337,8 @@ bool filter_llsd_with_template( const LLSD & template_llsd, LLSD & resultant_llsd) { + LL_PROFILE_ZONE_SCOPED + if (llsd_to_test.isUndefined() && template_llsd.isDefined()) { resultant_llsd = template_llsd; @@ -529,6 +533,8 @@ class TypeLookup public: TypeLookup() { + LL_PROFILE_ZONE_SCOPED + for (const Data *di(boost::begin(typedata)), *dend(boost::end(typedata)); di != dend; ++di) { mMap[di->type] = di->name; @@ -537,6 +543,8 @@ public: std::string lookup(LLSD::Type type) const { + LL_PROFILE_ZONE_SCOPED + MapType::const_iterator found = mMap.find(type); if (found != mMap.end()) { @@ -587,6 +595,8 @@ static std::string match_types(LLSD::Type expect, // prototype.type() LLSD::Type actual, // type we're checking const std::string& pfx) // as for llsd_matches { + LL_PROFILE_ZONE_SCOPED + // Trivial case: if the actual type is exactly what we expect, we're good. if (actual == expect) return ""; @@ -624,6 +634,8 @@ static std::string match_types(LLSD::Type expect, // prototype.type() // see docstring in .h file std::string llsd_matches(const LLSD& prototype, const LLSD& data, const std::string& pfx) { + LL_PROFILE_ZONE_SCOPED + // An undefined prototype means that any data is valid. // An undefined slot in an array or map prototype means that any data // may fill that slot. @@ -756,6 +768,8 @@ std::string llsd_matches(const LLSD& prototype, const LLSD& data, const std::str bool llsd_equals(const LLSD& lhs, const LLSD& rhs, int bits) { + LL_PROFILE_ZONE_SCOPED + // We're comparing strict equality of LLSD representation rather than // performing any conversions. So if the types aren't equal, the LLSD // values aren't equal. @@ -864,6 +878,8 @@ namespace llsd LLSD& drill(LLSD& blob, const LLSD& rawPath) { + LL_PROFILE_ZONE_SCOPED + // Treat rawPath uniformly as an array. If it's not already an array, // store it as the only entry in one. (But let's say Undefined means an // empty array.) @@ -889,6 +905,8 @@ LLSD& drill(LLSD& blob, const LLSD& rawPath) // path entry that's bad. for (LLSD::Integer i = 0; i < path.size(); ++i) { + LL_PROFILE_ZONE_NUM( i ) + const LLSD& key{path[i]}; if (key.isString()) { @@ -917,6 +935,8 @@ LLSD& drill(LLSD& blob, const LLSD& rawPath) LLSD drill(const LLSD& blob, const LLSD& path) { + LL_PROFILE_ZONE_SCOPED + // non-const drill() does exactly what we want. Temporarily cast away // const-ness and use that. return drill(const_cast(blob), path); @@ -929,6 +949,8 @@ LLSD drill(const LLSD& blob, const LLSD& path) // filter may be include to exclude/include keys in a map. LLSD llsd_clone(LLSD value, LLSD filter) { + LL_PROFILE_ZONE_SCOPED + LLSD clone; bool has_filter(filter.isMap()); diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 8c5ff50a56..56bc3346e3 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -35,7 +35,6 @@ #include "lltrace.h" #include "lltracethreadrecorder.h" #include "llexception.h" -#include "fstelemetry.h" // allow thread naming #if LL_LINUX #include @@ -136,6 +135,8 @@ void LLThread::threadRun() set_thread_name(-1, mName.c_str()); #endif + LL_PROFILER_SET_THREAD_NAME( mName.c_str() ); + // this is the first point at which we're actually running in the new thread mID = currentID(); @@ -143,14 +144,16 @@ void LLThread::threadRun() mRecorder = new LLTrace::ThreadRecorder(*LLTrace::get_master_thread_recorder()); // - Add threadnames to telemetry LL_INFOS("THREAD") << "Started thread " << mName << LL_ENDL; - FSThreadName( mName.c_str() ); + LL_PROFILER_SET_THREAD_NAME( mName.c_str() ); // // Run the user supplied function do { try { + LL_PROFILER_THREAD_BEGIN(mName.c_str()) run(); + LL_PROFILER_THREAD_END(mName.c_str()) } catch (const LLContinueError &e) { @@ -335,6 +338,8 @@ bool LLThread::runCondition(void) // Stop thread execution if requested until unpaused. void LLThread::checkPause() { + LL_PROFILER_THREAD_BEGIN(mName.c_str()) + mDataLock->lock(); // This is in a while loop because the pthread API allows for spurious wakeups. @@ -347,6 +352,8 @@ void LLThread::checkPause() } mDataLock->unlock(); + + LL_PROFILER_THREAD_END(mName.c_str()) } //============================================================================ @@ -378,12 +385,16 @@ void LLThread::yield() void LLThread::wake() { + LL_PROFILER_THREAD_BEGIN(mName.c_str()) + mDataLock->lock(); if(!shouldSleep()) { mRunCondition->signal(); } mDataLock->unlock(); + + LL_PROFILER_THREAD_END(mName.c_str()) } void LLThread::wakeLocked() diff --git a/indra/llfilesystem/llfilesystem.cpp b/indra/llfilesystem/llfilesystem.cpp index a64070eb9d..b55fbca044 100644 --- a/indra/llfilesystem/llfilesystem.cpp +++ b/indra/llfilesystem/llfilesystem.cpp @@ -57,7 +57,7 @@ LLFileSystem::~LLFileSystem() // static bool LLFileSystem::getExists(const LLUUID& file_id, const LLAssetType::EType file_type) { - FSZoneC(tracy::Color::Gold); // measure cache performance + LL_PROFILE_ZONE_COLOR(tracy::Color::Gold); // measure cache performance std::string id_str; file_id.toString(id_str); const std::string extra_info = ""; @@ -83,7 +83,7 @@ bool LLFileSystem::getExists(const LLUUID& file_id, const LLAssetType::EType fil // static bool LLFileSystem::removeFile(const LLUUID& file_id, const LLAssetType::EType file_type, int suppress_error /*= 0*/) { - FSZoneC(tracy::Color::Gold); // measure cache performance + LL_PROFILE_ZONE_COLOR(tracy::Color::Gold); // measure cache performance std::string id_str; file_id.toString(id_str); const std::string extra_info = ""; @@ -98,7 +98,7 @@ bool LLFileSystem::removeFile(const LLUUID& file_id, const LLAssetType::EType fi bool LLFileSystem::renameFile(const LLUUID& old_file_id, const LLAssetType::EType old_file_type, const LLUUID& new_file_id, const LLAssetType::EType new_file_type) { - FSZoneC(tracy::Color::Gold); // measure cache performance + LL_PROFILE_ZONE_COLOR(tracy::Color::Gold); // measure cache performance std::string old_id_str; old_file_id.toString(old_id_str); const std::string extra_info = ""; @@ -126,7 +126,7 @@ bool LLFileSystem::renameFile(const LLUUID& old_file_id, const LLAssetType::ETyp // static S32 LLFileSystem::getFileSize(const LLUUID& file_id, const LLAssetType::EType file_type) { - FSZoneC(tracy::Color::Gold); // measure cache performance + LL_PROFILE_ZONE_COLOR(tracy::Color::Gold); // measure cache performance std::string id_str; file_id.toString(id_str); const std::string extra_info = ""; @@ -152,7 +152,7 @@ S32 LLFileSystem::getFileSize(const LLUUID& file_id, const LLAssetType::EType fi BOOL LLFileSystem::read(U8* buffer, S32 bytes) { - FSZoneC(tracy::Color::Gold); // measure cache performance + LL_PROFILE_ZONE_COLOR(tracy::Color::Gold); // measure cache performance // Cache fixes //BOOL success = TRUE; BOOL success = FALSE; @@ -217,19 +217,19 @@ BOOL LLFileSystem::read(U8* buffer, S32 bytes) S32 LLFileSystem::getLastBytesRead() { - FSZoneC(tracy::Color::Gold); // measure cache performance + LL_PROFILE_ZONE_COLOR(tracy::Color::Gold); // measure cache performance return mBytesRead; } BOOL LLFileSystem::eof() { - FSZoneC(tracy::Color::Gold); // measure cache performance + LL_PROFILE_ZONE_COLOR(tracy::Color::Gold); // measure cache performance return mPosition >= getSize(); } BOOL LLFileSystem::write(const U8* buffer, S32 bytes) { - FSZoneC(tracy::Color::Gold); // measure cache performance + LL_PROFILE_ZONE_COLOR(tracy::Color::Gold); // measure cache performance std::string id_str; mFileID.toString(id_str); const std::string extra_info = ""; @@ -341,7 +341,7 @@ BOOL LLFileSystem::write(const U8* buffer, S32 bytes) BOOL LLFileSystem::seek(S32 offset, S32 origin) { - FSZoneC(tracy::Color::Gold); // measure cache performance + LL_PROFILE_ZONE_COLOR(tracy::Color::Gold); // measure cache performance if (-1 == origin) { origin = mPosition; @@ -372,26 +372,26 @@ BOOL LLFileSystem::seek(S32 offset, S32 origin) S32 LLFileSystem::tell() const { - FSZoneC(tracy::Color::Gold); // measure cache performance + LL_PROFILE_ZONE_COLOR(tracy::Color::Gold); // measure cache performance return mPosition; } S32 LLFileSystem::getSize() { - FSZoneC(tracy::Color::Gold); // measure cache performance + LL_PROFILE_ZONE_COLOR(tracy::Color::Gold); // measure cache performance return LLFileSystem::getFileSize(mFileID, mFileType); } S32 LLFileSystem::getMaxSize() { - FSZoneC(tracy::Color::Gold); // measure cache performance + LL_PROFILE_ZONE_COLOR(tracy::Color::Gold); // measure cache performance // offer up a huge size since we don't care what the max is return INT_MAX; } BOOL LLFileSystem::rename(const LLUUID& new_id, const LLAssetType::EType new_type) { - FSZoneC(tracy::Color::Gold); // measure cache performance + LL_PROFILE_ZONE_COLOR(tracy::Color::Gold); // measure cache performance LLFileSystem::renameFile(mFileID, mFileType, new_id, new_type); mFileID = new_id; @@ -402,7 +402,7 @@ BOOL LLFileSystem::rename(const LLUUID& new_id, const LLAssetType::EType new_typ BOOL LLFileSystem::remove() { - FSZoneC(tracy::Color::Gold); // measure cache performance + LL_PROFILE_ZONE_COLOR(tracy::Color::Gold); // measure cache performance LLFileSystem::removeFile(mFileID, mFileType); return TRUE; diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index 468140e408..be44103c11 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -135,11 +135,11 @@ LLImageDecodeThread::~LLImageDecodeThread() // virtual S32 LLImageDecodeThread::update(F32 max_time_ms) { - FSZoneC(tracy::Color::Blue); // instrument image decodes + LL_PROFILE_ZONE_COLOR(tracy::Color::Blue); // instrument image decodes LLMutexLock lock(mCreationMutex); // instrument image decodes { - FSZoneC(tracy::Color::Blue1); + LL_PROFILE_ZONE_COLOR(tracy::Color::Blue1); // for (creation_list_t::iterator iter = mCreationList.begin(); iter != mCreationList.end(); ++iter) @@ -163,7 +163,7 @@ S32 LLImageDecodeThread::update(F32 max_time_ms) // instrument image decodes } { - FSZoneC(tracy::Color::Blue2); + LL_PROFILE_ZONE_COLOR(tracy::Color::Blue2); // S32 res = LLQueuedThread::update(max_time_ms); // FSPlot("img_decode_pending", (int64_t)res); // instrument image decodes @@ -174,7 +174,7 @@ S32 LLImageDecodeThread::update(F32 max_time_ms) LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image, U32 priority, S32 discard, BOOL needs_aux, Responder* responder) { - FSZoneC(tracy::Color::Orange); // instrument the image decode pipeline + LL_PROFILE_ZONE_COLOR(tracy::Color::Orange); // instrument the image decode pipeline // De-couple texture threading from mainloop // LLMutexLock lock(mCreationMutex); // handle_t handle = generateHandle(); @@ -185,7 +185,7 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* // if this is an actual problem we move the fallback to here and place the unfulfilled request into the legacy queue if (s_ChildThreads > 0) { - FSZoneNC("DecodeDecoupled", tracy::Color::Orange); // instrument the image decode pipeline + LL_PROFILE_ZONE_NAMED_COLOR("DecodeDecoupled", tracy::Color::Orange); // instrument the image decode pipeline ImageRequest* req = new ImageRequest(handle, image, priority, discard, needs_aux, responder, this); @@ -198,7 +198,7 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* } else { - FSZoneNC("DecodeQueued", tracy::Color::Orange); // instrument the image decode pipeline + LL_PROFILE_ZONE_NAMED_COLOR("DecodeQueued", tracy::Color::Orange); // instrument the image decode pipeline LLMutexLock lock(mCreationMutex); mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder)); } @@ -270,7 +270,7 @@ bool LLImageDecodeThread::ImageRequest::processRequestIntern() { // allow longer timeout for async and add instrumentation // const F32 decode_time_slice = .1f; - FSZoneC(tracy::Color::DarkOrange); + LL_PROFILE_ZONE_COLOR(tracy::Color::DarkOrange); F32 decode_time_slice = .1f; if(mFlags & FLAG_ASYNC) { @@ -280,7 +280,7 @@ bool LLImageDecodeThread::ImageRequest::processRequestIntern() bool done = true; if (!mDecodedRaw && mFormattedImage.notNull()) { - FSZoneC(tracy::Color::DarkOrange1); // instrument the image decode pipeline + LL_PROFILE_ZONE_COLOR(tracy::Color::DarkOrange1); // instrument the image decode pipeline // Decode primary channels if (mDecodedImageRaw.isNull()) { @@ -319,7 +319,7 @@ bool LLImageDecodeThread::ImageRequest::processRequestIntern() } if (done && mNeedsAux && !mDecodedAux && mFormattedImage.notNull()) { - FSZoneC(tracy::Color::DarkOrange2); // instrument the image decode pipeline + LL_PROFILE_ZONE_COLOR(tracy::Color::DarkOrange2); // instrument the image decode pipeline // Decode aux channel if (!mDecodedImageAux) { diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index f46bcacb64..08f03c7bdb 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -25,7 +25,7 @@ */ #include "linden_common.h" -#include "fstelemetry.h" // instrument image decodes +// #include "fstelemetry.h" // instrument image decodes #include "llimagej2coj.h" #define OPENJPEG2 @@ -259,7 +259,7 @@ bool LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int block bool LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) { // texture comment metadata reader - FSZone; // instrument image decodes + LL_PROFILE_ZONE_SCOPED; // instrument image decodes U8* c_data = base.getData(); S32 c_size = base.getDataSize(); S32 position = 0; diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 7ee9c4f777..f763ec2226 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -32,7 +32,7 @@ #include "llpointer.h" #include "llmath.h" #include "llkdumem.h" -#include "fstelemetry.h" // instrument image decodes +// #include "fstelemetry.h" // instrument image decodes #define kdu_xxxx "kdu_block_coding.h" #include "include_kdu_xxxx.h" @@ -287,7 +287,7 @@ void transfer_bytes(kdu_byte *dest, kdu_line_buf &src, int gap, int precision); // as well, when that still existed, with keep_codestream true and MODE_FAST. void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode) { - FSZone; // instrument image decodes + LL_PROFILE_ZONE_SCOPED; // instrument image decodes S32 data_size = base.getDataSize(); S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size); @@ -442,7 +442,7 @@ bool LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc // decodeImpl() usage matters for production. bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region) { - FSZone; // instrument image decodes + LL_PROFILE_ZONE_SCOPED; // instrument image decodes base.resetLastError(); // *FIX: kdu calls our callback function if there's an error, and then bombs. @@ -526,7 +526,7 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco // Returns true to mean done, whether successful or not. bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) { - FSZone; // instrument image decodes + LL_PROFILE_ZONE_SCOPED; // instrument image decodes ECodeStreamMode mode = MODE_FAST; LLTimer decode_timer; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 7c6a5a46c4..7c63cc43ad 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -400,6 +400,7 @@ public: virtual void visit(const LLOctreeNode* branch) { //this is a depth first traversal, so it's safe to assum all children have complete //bounding data + LL_PROFILE_ZONE_SCOPED LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); @@ -843,6 +844,8 @@ S32 LLProfile::getNumPoints(const LLProfileParams& params, BOOL path_open,F32 de BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split, BOOL is_sculpted, S32 sculpt_size) { + LL_PROFILE_ZONE_SCOPED + if ((!mDirty) && (!is_sculpted)) { return FALSE; @@ -1323,6 +1326,8 @@ S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale) { + LL_PROFILE_ZONE_SCOPED + // Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane. static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; @@ -1557,6 +1562,8 @@ S32 LLPath::getNumPoints(const LLPathParams& params, F32 detail) BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, BOOL is_sculpted, S32 sculpt_size) { + LL_PROFILE_ZONE_SCOPED + if ((!mDirty) && (!is_sculpted)) { return FALSE; @@ -2136,6 +2143,8 @@ LLVolume::~LLVolume() BOOL LLVolume::generate() { + LL_PROFILE_ZONE_SCOPED + LL_CHECK_MEMORY llassert_always(mProfilep); @@ -2394,6 +2403,8 @@ bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) { + LL_PROFILE_ZONE_SCOPED + //input stream is now pointing at a zlib compressed block of LLSD //decompress block LLSD mdl; @@ -2799,6 +2810,8 @@ S32 LLVolume::getNumFaces() const void LLVolume::createVolumeFaces() { + LL_PROFILE_ZONE_SCOPED + if (mGenerateSingleFace) { // do nothing @@ -3793,6 +3806,8 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, const LLMatrix3& norm_mat_in, S32 face_mask) { + LL_PROFILE_ZONE_SCOPED + LLMatrix4a mat; mat.loadu(mat_in); @@ -4919,6 +4934,8 @@ void LLVolumeFace::freeData() BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) { + LL_PROFILE_ZONE_SCOPED + //tree for this face is no longer valid delete mOctree; mOctree = NULL; @@ -5597,6 +5614,8 @@ bool LLVolumeFace::cacheOptimize() void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVector4a& size) { + LL_PROFILE_ZONE_SCOPED + if (mOctree) { return; @@ -6380,6 +6399,8 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe void LLVolumeFace::createTangents() { + LL_PROFILE_ZONE_SCOPED + if (!mTangents) { allocateTangents(mNumVertices); @@ -6575,6 +6596,8 @@ void LLVolumeFace::fillFromLegacyData(std::vector& v, BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { + LL_PROFILE_ZONE_SCOPED + LL_CHECK_MEMORY BOOL flat = mTypeMask & FLAT_MASK; @@ -7067,6 +7090,8 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) { + LL_PROFILE_ZONE_SCOPED + //LLVector4a *tan1 = new LLVector4a[vertexCount * 2]; LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a)); // new(tan1) LLVector4a; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 27adc67d68..d68032362e 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -818,4 +818,23 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); #define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD #endif +#if defined(TRACY_ENABLE) && LL_PROFILER_ENABLE_TRACY_OPENGL + // Tracy uses the following: + // glGenQueries + // glGetQueryiv + // glGetQueryObjectiv + #define glGenQueries glGenQueriesARB + #define glGetQueryiv glGetQueryivARB + #define glGetQueryObjectiv glGetQueryObjectivARB + #include + + #define LL_PROFILER_GPU_ZONEC(name,color) TracyGpuZoneC(name,color); + #define LL_PROFILER_GPU_COLLECT TracyGpuCollect + #define LL_PROFILER_GPU_CONTEXT TracyGpuContext +#else + #define LL_PROFILER_GPU_ZONEC(name,color) (void)name;(void)color; + #define LL_PROFILER_GPU_COLLECT + #define LL_PROFILER_GPU_CONTEXT +#endif + #endif // LL_LLGLHEADERS_H diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index d616156bfe..92e1017e0c 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -437,11 +437,13 @@ void LLRenderTarget::bindTarget() GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3}; + LL_PROFILER_GPU_ZONEC( "gl.DrawBuffersARB", 0x4000FF ) glDrawBuffersARB(mTex.size(), drawbuffers); } if (mTex.empty()) { //no color buffer to draw to + LL_PROFILER_GPU_ZONEC( "gl.DrawBuffer", 0x0000FF ) glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); } diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 26b958fc99..5af5b87320 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -684,6 +684,7 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector& pos, con glNormalPointer(GL_FLOAT, 0, norm[start_pos].mV); } LLGLSLShader::startProfile(); + LL_PROFILER_GPU_ZONEC( "gl.DrawArrays", 0xFF0000 ) glDrawArrays(sGLMode[mode], 0, count); LLGLSLShader::stopProfile(count, mode); } @@ -820,6 +821,7 @@ void LLVertexBuffer::drawElements(U32 mode, const S32 num_vertices, const LLVect } LLGLSLShader::startProfile(); + LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x80FF80 ) glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp); LLGLSLShader::stopProfile(num_indices, mode); } @@ -931,6 +933,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi stop_glerror(); LLGLSLShader::startProfile(); + LL_PROFILER_GPU_ZONEC( "gl.DrawRangeElements", 0xFFFF00 ) glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, idx); LLGLSLShader::stopProfile(count, mode); @@ -982,6 +985,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const stop_glerror(); LLGLSLShader::startProfile(); + LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0xA0FFA0 ) glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT, ((U16*) getIndicesPointer()) + indices_offset); LLGLSLShader::stopProfile(count, mode); @@ -1030,6 +1034,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const stop_glerror(); LLGLSLShader::startProfile(); stop_glerror(); + LL_PROFILER_GPU_ZONEC( "gl.DrawArrays", 0xFF4040 ) glDrawArrays(sGLMode[mode], first, count); stop_glerror(); LLGLSLShader::stopProfile(count, mode); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index d2d24bb730..0628e1fbd9 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -1751,6 +1751,8 @@ const S32 max_format = (S32)num_formats - 1; return FALSE; } + LL_PROFILER_GPU_CONTEXT + if (!gGLManager.initGL()) { close(); @@ -3519,6 +3521,8 @@ BOOL LLWindowWin32::resetDisplayResolution() void LLWindowWin32::swapBuffers() { SwapBuffers(mhDC); + + LL_PROFILER_GPU_COLLECT } //-TT Window Title Access diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 9397168fe7..652d758b3f 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -47,6 +47,7 @@ include(OpenGL) include(OpenSSL) include(PNG) include(TemplateCheck) +include(Tracy) include(UI) include(UnixInstall) include(ViewerMiscLibs) @@ -106,6 +107,7 @@ include_directories( ${LLAPPEARANCE_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} + ${TRACY_INCLUDE_DIR} ) include_directories(SYSTEM @@ -699,7 +701,6 @@ set(viewer_SOURCE_FILES llsyntaxid.cpp llsyswellitem.cpp llsyswellwindow.cpp - lltelemetry.cpp llteleporthistory.cpp llteleporthistorystorage.cpp lltextureatlas.cpp @@ -2524,6 +2525,7 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${LLPHYSICS_LIBRARIES} ${LLPHYSICSEXTENSIONS_LIBRARIES} ${LLAPPEARANCE_LIBRARIES} + ${TRACY_LIBRARY} ${GROWL_LIBRARY} ) diff --git a/indra/newview/installers/darwin/firestorm-beta-dmg/Applications-alias.r b/indra/newview/installers/darwin/firestorm-beta-dmg/Applications-alias.r old mode 100644 new mode 100755 diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 5ed386fc5d..d82c2b9098 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -91,7 +91,6 @@ #include "llsdutil_math.h" #include "lllocationhistory.h" #include "llfasttimerview.h" -#include "lltelemetry.h" #include "llvector4a.h" #include "llviewermenufile.h" #include "llvoicechannel.h" @@ -285,7 +284,7 @@ #include "fsradar.h" #include "fsassetblacklist.h" -#include "fstelemetry.h" // Tracy profiler support +// #include "fstelemetry.h" // Tracy profiler support #if LL_LINUX && LL_GTK #include "glib.h" @@ -1570,7 +1569,8 @@ void LLAppViewer::initMaxHeapSize() } static LLTrace::BlockTimerStatHandle FTM_MESSAGES("System Messages"); -static LLTrace::BlockTimerStatHandle FTM_SLEEP("Sleep"); +static LLTrace::BlockTimerStatHandle FTM_SLEEP1("Sleep1"); +static LLTrace::BlockTimerStatHandle FTM_SLEEP2("Sleep2"); static LLTrace::BlockTimerStatHandle FTM_YIELD("Yield"); static LLTrace::BlockTimerStatHandle FTM_TEXTURE_CACHE("Texture Cache"); @@ -1631,6 +1631,8 @@ bool LLAppViewer::frame() bool LLAppViewer::doFrame() { + LL_RECORD_BLOCK_TIME(FTM_FRAME); + LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); LLSD newFrame; // telemetry enabling. @@ -1663,11 +1665,12 @@ bool LLAppViewer::doFrame() LLTimer frameTimer; nd::etw::logFrame(); // Write the start of each frame. Even if our Provider (Firestorm) would be enabled, this has only light impact. Does nothing on OSX and Linux. - - LL_RECORD_BLOCK_TIME(FTM_FRAME); - LLTrace::BlockTimer::processTimes(); - LLTrace::get_frame_recording().nextPeriod(); - LLTrace::BlockTimer::logStats(); + { + LL_PROFILE_ZONE_NAMED( "df blocktimer" ) + LLTrace::BlockTimer::processTimes(); + LLTrace::get_frame_recording().nextPeriod(); + LLTrace::BlockTimer::logStats(); + } LLTrace::get_thread_recorder()->pullFromChildren(); @@ -1675,6 +1678,7 @@ bool LLAppViewer::doFrame() LL_CLEAR_CALLSTACKS(); { + LL_PROFILE_ZONE_NAMED( "df processMiscNativeEvents" ) // MaxFPS Viewer-Chui merge error // Check if we need to restore rendering masks. if (restore_rendering_masks) @@ -1708,7 +1712,10 @@ bool LLAppViewer::doFrame() gViewerWindow->getWindow()->processMiscNativeEvents(); } - pingMainloopTimeout("Main:GatherInput"); + { + LL_PROFILE_ZONE_NAMED( "df gatherInput" ) + pingMainloopTimeout("Main:GatherInput"); + } if (gViewerWindow) { @@ -1732,10 +1739,17 @@ bool LLAppViewer::doFrame() } } - // canonical per-frame event - mainloop.post(newFrame); - // give listeners a chance to run - llcoro::suspend(); + { + LL_PROFILE_ZONE_NAMED( "df mainloop" ) + // canonical per-frame event + mainloop.post(newFrame); + } + + { + LL_PROFILE_ZONE_NAMED( "df suspend" ) + // give listeners a chance to run + llcoro::suspend(); + } if (!LLApp::isExiting()) { @@ -1752,6 +1766,7 @@ bool LLAppViewer::doFrame() && (gHeadlessClient || !gViewerWindow->getShowProgress()) && !gFocusMgr.focusLocked()) { + LL_PROFILE_ZONE_NAMED( "df JoystickKeyboard" ) joystick->scanJoystick(); gKeyboard->scanKeyboard(); gViewerInput.scanMouse(); @@ -1767,11 +1782,17 @@ bool LLAppViewer::doFrame() // Update state based on messages, user input, object idle. { + LL_PROFILE_ZONE_NAMED( "df pauseMainloopTimeout" ) pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! + } + { LL_RECORD_BLOCK_TIME(FTM_IDLE); idle(); + } + { + LL_PROFILE_ZONE_NAMED( "df resumeMainloopTimeout" ) resumeMainloopTimeout(); } @@ -1787,6 +1808,7 @@ bool LLAppViewer::doFrame() // *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18 if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow) { + LL_PROFILE_ZONE_NAMED( "df Display" ) pingMainloopTimeout("Main:Display"); gGLActive = TRUE; @@ -1800,35 +1822,44 @@ bool LLAppViewer::doFrame() // U64 elapsed_time = LLTimer::getTotalTime() - last_call; // if (elapsed_time < mMinMicroSecPerFrame) // { - // LL_RECORD_BLOCK_TIME(FTM_SLEEP); + // LL_PROFILE_ZONE_WARN("Sleep1") // // llclamp for when time function gets funky // U64 sleep_time = llclamp(mMinMicroSecPerFrame - elapsed_time, (U64)1, (U64)1e6); + // LL_PROFILE_ZONE_NAMED( "df Snapshot" ) // micro_sleep(sleep_time, 0); // } //} //last_call = LLTimer::getTotalTime(); // - pingMainloopTimeout("Main:Snapshot"); - LLFloaterSnapshot::update(); // take snapshots - LLFloaterOutfitSnapshot::update(); - gGLActive = FALSE; } + { + LL_PROFILE_ZONE_NAMED( "df Snapshot" ) + pingMainloopTimeout("Main:Snapshot"); + LLFloaterSnapshot::update(); // take snapshots + LLFloaterOutfitSnapshot::update(); + gGLActive = FALSE; + } } - pingMainloopTimeout("Main:Sleep"); + { + LL_PROFILE_ZONE_NAMED( "df pauseMainloopTimeout2" ) + pingMainloopTimeout("Main:Sleep"); - pauseMainloopTimeout(); + pauseMainloopTimeout(); + } // Sleep and run background threads { - LL_RECORD_BLOCK_TIME(FTM_SLEEP); + //LL_RECORD_BLOCK_TIME(SLEEP2); + LL_PROFILE_ZONE_WARN( "Sleep2" ) // yield some time to the os based on command line option static LLCachedControl yield_time(gSavedSettings, "YieldTime", -1); if(yield_time >= 0) { LL_RECORD_BLOCK_TIME(FTM_YIELD); + LL_PROFILE_ZONE_NUM( yield_time ) ms_sleep(yield_time); } @@ -1872,7 +1903,7 @@ bool LLAppViewer::doFrame() F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f); // instrument image decodes { - FSZoneN("updateTextureThreads"); + LL_PROFILE_ZONE_NAMED("updateTextureThreads"); // FSPlot("max_time_ms",max_time); // work_pending += updateTextureThreads(max_time); @@ -1892,22 +1923,29 @@ bool LLAppViewer::doFrame() total_io_pending += io_pending ; } - gMeshRepo.update() ; + + { + LL_PROFILE_ZONE_NAMED( "df gMeshRepo" ) + gMeshRepo.update() ; + } if(!total_work_pending) //pause texture fetching threads if nothing to process. { + LL_PROFILE_ZONE_NAMED( "df getTextureCache" ) LLAppViewer::getTextureCache()->pause(); LLAppViewer::getImageDecodeThread()->pause(); LLAppViewer::getTextureFetch()->pause(); } if(!total_io_pending) //pause file threads if nothing to process. { + LL_PROFILE_ZONE_NAMED( "df LLVFSThread" ) LLLFSThread::sLocal->pause(); } //texture fetching debugger if(LLTextureFetchDebugger::isEnabled()) { + LL_PROFILE_ZONE_NAMED( "df tex_fetch_debugger_instance" ) LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = LLFloaterReg::findTypedInstance("tex_fetch_debugger"); if(tex_fetch_debugger_instance) @@ -1926,15 +1964,16 @@ bool LLAppViewer::doFrame() S32 milliseconds_to_sleep = llclamp((S32)((min_frame_time - frameTimer.getElapsedTimeF64()) * 1000.f), 0, 1000); if (milliseconds_to_sleep > 0) { - LL_RECORD_BLOCK_TIME(FTM_SLEEP); + LL_RECORD_BLOCK_TIME(FTM_SLEEP2); ms_sleep(milliseconds_to_sleep); } } frameTimer.reset(); // - - resumeMainloopTimeout(); - + { + LL_PROFILE_ZONE_NAMED( "df resumeMainloopTimeout" ) + resumeMainloopTimeout(); + } pingMainloopTimeout("Main:End"); } } @@ -1959,8 +1998,8 @@ bool LLAppViewer::doFrame() LL_INFOS() << "Exiting main_loop" << LL_ENDL; } - FSFrameMark; // Tracy support delineate Frame - LLPROFILE_UPDATE(); + + LL_PROFILER_FRAME_END return ! LLApp::isRunning(); } diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 9092edb115..dcabf9ec18 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -451,6 +451,10 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, PWSTR pCmdLine, int nCmdShow) { + // Call Tracy first thing to have it allocate memory + // https://github.com/wolfpld/tracy/issues/196 + LL_PROFILER_FRAME_END + const S32 MAX_HEAPS = 255; DWORD heap_enable_lfh_error[MAX_HEAPS]; S32 num_heaps = 0; diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index d7ebf28354..94e04987e4 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -104,6 +104,8 @@ LLDrawable::LLDrawable(LLViewerObject *vobj, bool new_entry) void LLDrawable::init(bool new_entry) { + LL_PROFILE_ZONE_SCOPED + // mXform mParent = NULL; mRenderType = 0; @@ -241,6 +243,8 @@ void LLDrawable::markDead() LLVOVolume* LLDrawable::getVOVolume() const { + LL_PROFILE_ZONE_SCOPED + LLViewerObject* objectp = mVObjp; if ( !isDead() && objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) { @@ -344,6 +348,7 @@ static LLTrace::BlockTimerStatHandle FTM_ALLOCATE_FACE("Allocate Face"); LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED LLFace *face; { @@ -372,6 +377,8 @@ LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep) LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED + LLFace *face; { @@ -396,6 +403,8 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep) LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp) { + LL_PROFILE_ZONE_SCOPED + LLFace *face; face = new LLFace(this, mVObjp); @@ -417,6 +426,8 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp) { + LL_PROFILE_ZONE_SCOPED + LLFace *face; face = new LLFace(this, mVObjp); @@ -439,6 +450,8 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED + if (newFaces == (S32)mFaces.size()) { return; @@ -462,6 +475,8 @@ void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerText void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED + if (newFaces <= (S32)mFaces.size() && newFaces >= (S32)mFaces.size()/2) { return; @@ -485,6 +500,8 @@ void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewer void LLDrawable::mergeFaces(LLDrawable* src) { + LL_PROFILE_ZONE_SCOPED + U32 face_count = mFaces.size() + src->mFaces.size(); mFaces.reserve(face_count); @@ -518,6 +535,8 @@ void LLDrawable::updateMaterial() void LLDrawable::makeActive() { + LL_PROFILE_ZONE_SCOPED + #if !LL_RELEASE_FOR_DOWNLOAD if (mVObjp.notNull()) { @@ -581,6 +600,8 @@ void LLDrawable::makeActive() void LLDrawable::makeStatic(BOOL warning_enabled) { + LL_PROFILE_ZONE_SCOPED + if (isState(ACTIVE) && !isState(ACTIVE_CHILD) && !mVObjp->isAttachment() && @@ -627,6 +648,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled) // Returns "distance" between target destination and resulting xfrom F32 LLDrawable::updateXform(BOOL undamped) { + LL_PROFILE_ZONE_SCOPED + BOOL damped = !undamped; // Position @@ -778,6 +801,8 @@ void LLDrawable::moveUpdatePipeline(BOOL moved) void LLDrawable::movePartition() { + LL_PROFILE_ZONE_SCOPED + LLSpatialPartition* part = getSpatialPartition(); if (part) { @@ -822,6 +847,8 @@ BOOL LLDrawable::updateMoveUndamped() void LLDrawable::updatePartition() { + LL_PROFILE_ZONE_SCOPED + if (!getVOVolume()) { movePartition(); @@ -839,6 +866,8 @@ void LLDrawable::updatePartition() BOOL LLDrawable::updateMoveDamped() { + LL_PROFILE_ZONE_SCOPED + F32 dist_squared = updateXform(FALSE); mGeneration++; @@ -862,6 +891,8 @@ BOOL LLDrawable::updateMoveDamped() void LLDrawable::updateDistance(LLCamera& camera, bool force_update) { + LL_PROFILE_ZONE_SCOPED + if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) { LL_WARNS() << "Attempted to update distance for non-world camera." << LL_ENDL; @@ -972,6 +1003,8 @@ void LLDrawable::updateTexture() BOOL LLDrawable::updateGeometry(BOOL priority) { + LL_PROFILE_ZONE_SCOPED + llassert(mVObjp.notNull()); BOOL res = mVObjp->updateGeometry(this); return res; @@ -1049,6 +1082,8 @@ const LLVector3& LLDrawable::getBounds(LLVector3& min, LLVector3& max) const void LLDrawable::updateSpatialExtents() { + LL_PROFILE_ZONE_SCOPED + if (mVObjp) { const LLVector4a* exts = getSpatialExtents(); @@ -1179,6 +1214,8 @@ void LLDrawable::setGroup(LLViewerOctreeGroup *groupp) LLSpatialPartition* LLDrawable::getSpatialPartition() { + LL_PROFILE_ZONE_SCOPED + LLSpatialPartition* retval = NULL; if (!mVObjp || @@ -1262,6 +1299,8 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat LLDrawable(root->getVObj(), true), LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB, regionp) { + LL_PROFILE_ZONE_SCOPED + mBridge = this; mDrawable = root; root->setSpatialBridge(this); @@ -1307,6 +1346,8 @@ void LLSpatialBridge::destroyTree() void LLSpatialBridge::updateSpatialExtents() { + LL_PROFILE_ZONE_SCOPED + LLSpatialGroup* root = (LLSpatialGroup*) mOctree->getListener(0); { @@ -1470,6 +1511,8 @@ public: void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector* results, BOOL for_select) { + LL_PROFILE_ZONE_SCOPED + if (!gPipeline.hasRenderType(mDrawableType)) { return; @@ -1567,6 +1610,8 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector* void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update) { + LL_PROFILE_ZONE_SCOPED + if (mDrawable == NULL) { markDead(); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 80d45d6fb3..ccd3a21ecd 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -128,6 +128,8 @@ LLDrawPoolAvatar::~LLDrawPoolAvatar() // virtual BOOL LLDrawPoolAvatar::isDead() { + LL_PROFILE_ZONE_SCOPED + if (!LLFacePool::isDead()) { return FALSE; @@ -145,11 +147,15 @@ BOOL LLDrawPoolAvatar::isDead() S32 LLDrawPoolAvatar::getShaderLevel() const { + LL_PROFILE_ZONE_SCOPED + return (S32) LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR); } void LLDrawPoolAvatar::prerender() { + LL_PROFILE_ZONE_SCOPED + mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR); sShaderLevel = mShaderLevel; @@ -176,6 +182,8 @@ void LLDrawPoolAvatar::prerender() LLMatrix4& LLDrawPoolAvatar::getModelView() { + LL_PROFILE_ZONE_SCOPED + static LLMatrix4 ret; ret.initRows(LLVector4(gGLModelView+0), @@ -264,6 +272,8 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass) void LLDrawPoolAvatar::renderDeferred(S32 pass) { + LL_PROFILE_ZONE_SCOPED + render(pass); } @@ -274,6 +284,8 @@ S32 LLDrawPoolAvatar::getNumPostDeferredPasses() void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass) { + LL_PROFILE_ZONE_SCOPED + switch (pass) { case 0: @@ -302,6 +314,8 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass) void LLDrawPoolAvatar::beginPostDeferredAlpha() { + LL_PROFILE_ZONE_SCOPED + sSkipOpaque = TRUE; sShaderLevel = mShaderLevel; sVertexProgram = &gDeferredAvatarAlphaProgram; @@ -316,6 +330,8 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha() void LLDrawPoolAvatar::beginDeferredRiggedAlpha() { + LL_PROFILE_ZONE_SCOPED + sVertexProgram = &gDeferredSkinnedAlphaProgram; gPipeline.bindDeferredShader(*sVertexProgram); sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); @@ -324,6 +340,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedAlpha() void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass) { + LL_PROFILE_ZONE_SCOPED + switch (pass) { case 0: pass = 1; break; @@ -350,6 +368,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass) void LLDrawPoolAvatar::endDeferredRiggedAlpha() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); gPipeline.unbindDeferredShader(*sVertexProgram); sDiffuseChannel = 0; @@ -360,6 +380,8 @@ void LLDrawPoolAvatar::endDeferredRiggedAlpha() void LLDrawPoolAvatar::endPostDeferredPass(S32 pass) { + LL_PROFILE_ZONE_SCOPED + switch (pass) { case 0: @@ -388,6 +410,8 @@ void LLDrawPoolAvatar::endPostDeferredPass(S32 pass) void LLDrawPoolAvatar::endPostDeferredAlpha() { + LL_PROFILE_ZONE_SCOPED + // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done sRenderingSkinned = FALSE; sSkipOpaque = FALSE; @@ -399,6 +423,8 @@ void LLDrawPoolAvatar::endPostDeferredAlpha() void LLDrawPoolAvatar::renderPostDeferred(S32 pass) { + LL_PROFILE_ZONE_SCOPED + static const S32 actual_pass[] = { //map post deferred pass numbers to what render() expects 2, //skinned @@ -658,6 +684,8 @@ void LLDrawPoolAvatar::renderShadow(S32 pass) S32 LLDrawPoolAvatar::getNumPasses() { + LL_PROFILE_ZONE_SCOPED + if (LLPipeline::sImpostorRender) { return 8; @@ -671,6 +699,8 @@ S32 LLDrawPoolAvatar::getNumPasses() S32 LLDrawPoolAvatar::getNumDeferredPasses() { + LL_PROFILE_ZONE_SCOPED + if (LLPipeline::sImpostorRender) { return 19; @@ -791,6 +821,8 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass) void LLDrawPoolAvatar::beginImpostor() { + LL_PROFILE_ZONE_SCOPED + if (!LLPipeline::sReflectionRender) { LLVOAvatar::sRenderDistance = llclamp(LLVOAvatar::sRenderDistance, 16.f, 256.f); @@ -809,6 +841,8 @@ void LLDrawPoolAvatar::beginImpostor() void LLDrawPoolAvatar::endImpostor() { + LL_PROFILE_ZONE_SCOPED + if (LLGLSLShader::sNoFixedFunction) { gImpostorProgram.unbind(); @@ -818,6 +852,8 @@ void LLDrawPoolAvatar::endImpostor() void LLDrawPoolAvatar::beginRigid() { + LL_PROFILE_ZONE_SCOPED + if (gPipeline.canUseVertexShaders()) { if (LLPipeline::sUnderWaterRender) @@ -851,6 +887,8 @@ void LLDrawPoolAvatar::beginRigid() void LLDrawPoolAvatar::endRigid() { + LL_PROFILE_ZONE_SCOPED + sShaderLevel = mShaderLevel; if (sVertexProgram != NULL) { @@ -860,6 +898,8 @@ void LLDrawPoolAvatar::endRigid() void LLDrawPoolAvatar::beginDeferredImpostor() { + LL_PROFILE_ZONE_SCOPED + if (!LLPipeline::sReflectionRender) { LLVOAvatar::sRenderDistance = llclamp(LLVOAvatar::sRenderDistance, 16.f, 256.f); @@ -876,6 +916,8 @@ void LLDrawPoolAvatar::beginDeferredImpostor() void LLDrawPoolAvatar::endDeferredImpostor() { + LL_PROFILE_ZONE_SCOPED + sShaderLevel = mShaderLevel; sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL); sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP); @@ -887,6 +929,8 @@ void LLDrawPoolAvatar::endDeferredImpostor() void LLDrawPoolAvatar::beginDeferredRigid() { + LL_PROFILE_ZONE_SCOPED + sVertexProgram = &gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); sVertexProgram->bind(); @@ -903,6 +947,8 @@ void LLDrawPoolAvatar::beginDeferredRigid() void LLDrawPoolAvatar::endDeferredRigid() { + LL_PROFILE_ZONE_SCOPED + sShaderLevel = mShaderLevel; sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); sVertexProgram->unbind(); @@ -912,6 +958,8 @@ void LLDrawPoolAvatar::endDeferredRigid() void LLDrawPoolAvatar::beginSkinned() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -978,6 +1026,8 @@ void LLDrawPoolAvatar::beginSkinned() void LLDrawPoolAvatar::endSkinned() { + LL_PROFILE_ZONE_SCOPED + // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done if (sShaderLevel > 0) { @@ -1002,6 +1052,8 @@ void LLDrawPoolAvatar::endSkinned() void LLDrawPoolAvatar::beginRiggedSimple() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -1042,6 +1094,8 @@ void LLDrawPoolAvatar::beginRiggedSimple() void LLDrawPoolAvatar::endRiggedSimple() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) { @@ -1052,27 +1106,37 @@ void LLDrawPoolAvatar::endRiggedSimple() void LLDrawPoolAvatar::beginRiggedAlpha() { + LL_PROFILE_ZONE_SCOPED + beginRiggedSimple(); } void LLDrawPoolAvatar::endRiggedAlpha() { + LL_PROFILE_ZONE_SCOPED + endRiggedSimple(); } void LLDrawPoolAvatar::beginRiggedFullbrightAlpha() { + LL_PROFILE_ZONE_SCOPED + beginRiggedFullbright(); } void LLDrawPoolAvatar::endRiggedFullbrightAlpha() { + LL_PROFILE_ZONE_SCOPED + endRiggedFullbright(); } void LLDrawPoolAvatar::beginRiggedGlow() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -1120,11 +1184,15 @@ void LLDrawPoolAvatar::beginRiggedGlow() void LLDrawPoolAvatar::endRiggedGlow() { + LL_PROFILE_ZONE_SCOPED + endRiggedFullbright(); } void LLDrawPoolAvatar::beginRiggedFullbright() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -1183,6 +1251,8 @@ void LLDrawPoolAvatar::beginRiggedFullbright() void LLDrawPoolAvatar::endRiggedFullbright() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) { @@ -1193,6 +1263,8 @@ void LLDrawPoolAvatar::endRiggedFullbright() void LLDrawPoolAvatar::beginRiggedShinySimple() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -1233,6 +1305,8 @@ void LLDrawPoolAvatar::beginRiggedShinySimple() void LLDrawPoolAvatar::endRiggedShinySimple() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) { @@ -1244,6 +1318,8 @@ void LLDrawPoolAvatar::endRiggedShinySimple() void LLDrawPoolAvatar::beginRiggedFullbrightShiny() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -1310,6 +1386,8 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny() void LLDrawPoolAvatar::endRiggedFullbrightShiny() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) { @@ -1322,6 +1400,8 @@ void LLDrawPoolAvatar::endRiggedFullbrightShiny() void LLDrawPoolAvatar::beginDeferredRiggedSimple() { + LL_PROFILE_ZONE_SCOPED + sVertexProgram = &gDeferredSkinnedDiffuseProgram; sDiffuseChannel = 0; sVertexProgram->bind(); @@ -1337,6 +1417,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedSimple() void LLDrawPoolAvatar::endDeferredRiggedSimple() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); sVertexProgram->unbind(); sVertexProgram = NULL; @@ -1344,6 +1426,8 @@ void LLDrawPoolAvatar::endDeferredRiggedSimple() void LLDrawPoolAvatar::beginDeferredRiggedBump() { + LL_PROFILE_ZONE_SCOPED + sVertexProgram = &gDeferredSkinnedBumpProgram; sVertexProgram->bind(); if (LLPipeline::sRenderingHUDs) @@ -1360,6 +1444,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedBump() void LLDrawPoolAvatar::endDeferredRiggedBump() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP); sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); @@ -1371,6 +1457,8 @@ void LLDrawPoolAvatar::endDeferredRiggedBump() void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass) { + LL_PROFILE_ZONE_SCOPED + if (pass == 1 || pass == 5 || pass == 9 || @@ -1401,6 +1489,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass) void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass) { + LL_PROFILE_ZONE_SCOPED + if (pass == 1 || pass == 5 || pass == 9 || @@ -1421,6 +1511,8 @@ void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass) void LLDrawPoolAvatar::beginDeferredSkinned() { + LL_PROFILE_ZONE_SCOPED + sShaderLevel = mShaderLevel; sVertexProgram = &gDeferredAvatarProgram; sRenderingSkinned = TRUE; @@ -1442,6 +1534,8 @@ void LLDrawPoolAvatar::beginDeferredSkinned() void LLDrawPoolAvatar::endDeferredSkinned() { + LL_PROFILE_ZONE_SCOPED + // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done sRenderingSkinned = FALSE; sVertexProgram->unbind(); @@ -1848,6 +1942,8 @@ bool LLDrawPoolAvatar::getRiggedGeometry( LLVolume* volume, const LLVolumeFace& vol_face) { + LL_PROFILE_ZONE_SCOPED + // FIRE-14261 try to skip broken or out of bounds faces if (vol_face.mNumVertices > 65536 || vol_face.mNumVertices < 0 || vol_face.mNumIndices < 0) { @@ -1962,6 +2058,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLVolume* volume, LLVolumeFace& vol_face) { + LL_PROFILE_ZONE_SCOPED; + LLVector4a* weights = vol_face.mWeights; if (!weights) { @@ -2221,6 +2319,8 @@ LLMatrix4a* LLDrawPoolAvatar::getCacheSkinningMats(LLDrawable* drawable, const L void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) { + LL_PROFILE_ZONE_SCOPED + if (!avatar->shouldRenderRigged()) { return; @@ -2527,16 +2627,22 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) void LLDrawPoolAvatar::renderDeferredRiggedSimple(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_DEFERRED_SIMPLE); } void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_DEFERRED_BUMP); } void LLDrawPoolAvatar::renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, pass); } @@ -2549,8 +2655,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) @@ -2589,27 +2697,37 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) void LLDrawPoolAvatar::renderRiggedSimple(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_SIMPLE); } void LLDrawPoolAvatar::renderRiggedFullbright(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_FULLBRIGHT); } void LLDrawPoolAvatar::renderRiggedShinySimple(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_SHINY); } void LLDrawPoolAvatar::renderRiggedFullbrightShiny(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_FULLBRIGHT_SHINY); } void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + if (!mRiggedFace[RIGGED_ALPHA].empty()) { LLGLEnable blend(GL_BLEND); @@ -2627,6 +2745,8 @@ void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar) void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + if (!mRiggedFace[RIGGED_FULLBRIGHT_ALPHA].empty()) { LLGLEnable blend(GL_BLEND); @@ -2644,6 +2764,8 @@ void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar) void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + if (!mRiggedFace[RIGGED_GLOW].empty()) { LLGLEnable blend(GL_BLEND); @@ -2671,6 +2793,8 @@ void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar) //----------------------------------------------------------------------------- LLViewerTexture *LLDrawPoolAvatar::getDebugTexture() { + LL_PROFILE_ZONE_SCOPED + if (mReferences.empty()) { return NULL; @@ -2694,6 +2818,8 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type) { + LL_PROFILE_ZONE_SCOPED + llassert (facep->isState(LLFace::RIGGED)); llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV); if (facep->getPool() && facep->getPool() != this) @@ -2716,6 +2842,8 @@ void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type) void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep) { + LL_PROFILE_ZONE_SCOPED + llassert (facep->isState(LLFace::RIGGED)); llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV); if (facep->getPool() != this) @@ -2756,7 +2884,7 @@ LLVertexBufferAvatar::LLVertexBufferAvatar() : LLVertexBuffer(sDataMask, GL_STREAM_DRAW_ARB) //avatars are always stream draw due to morph targets { - + LL_PROFILE_ZONE_SCOPED } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 316951c316..e0de8364f3 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -248,6 +248,8 @@ void LLFace::setPool(LLFacePool* pool) void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED + if (!new_pool) { LL_ERRS() << "Setting pool to null!" << LL_ENDL; @@ -336,6 +338,8 @@ void LLFace::setSpecularMap(LLViewerTexture* tex) void LLFace::dirtyTexture() { + LL_PROFILE_ZONE_SCOPED + LLDrawable* drawablep = getDrawable(); if (mVObjp.notNull() && mVObjp->getVolume()) @@ -558,6 +562,8 @@ void LLFace::updateCenterAgent() void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) { + LL_PROFILE_ZONE_SCOPED + if (mDrawablep == NULL || mDrawablep->getSpatialGroup() == NULL) { return; @@ -616,6 +622,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) glTexCoordPointer(2, GL_FLOAT, 8, vol_face.mTexCoords); } gGL.syncMatrices(); + LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x00FF00 ); glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices); glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Use a vbo for the static LLVertexBuffer::drawArray/Element functions; by Drake Arconis/Shyotl Kuhr @@ -639,6 +646,8 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) void renderFace(LLDrawable* drawable, LLFace *face) { + LL_PROFILE_ZONE_SCOPED + LLVOVolume* vobj = drawable->getVOVolume(); if (vobj) { @@ -934,6 +943,8 @@ bool less_than_max_mag(const LLVector4a& vec) BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, const LLMatrix4& mat_vert_in, BOOL global_volume) { + LL_PROFILE_ZONE_SCOPED + //get bounding box if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED)) { @@ -2507,6 +2518,8 @@ F32 LLFace::getTextureVirtualSize() BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) { + LL_PROFILE_ZONE_SCOPED + //VECTORIZE THIS //get area of circle around face LLVector4a center; @@ -2786,6 +2799,8 @@ const LLMatrix4& LLFace::getRenderMatrix() const S32 LLFace::renderElements(const U16 *index_array) const { + LL_PROFILE_ZONE_SCOPED + S32 ret = 0; if (isState(GLOBAL)) @@ -2805,6 +2820,8 @@ S32 LLFace::renderElements(const U16 *index_array) const S32 LLFace::renderIndexed() { + LL_PROFILE_ZONE_SCOPED + if(mDrawablep == NULL || mDrawPoolp == NULL) { return 0; @@ -2815,6 +2832,8 @@ S32 LLFace::renderIndexed() S32 LLFace::renderIndexed(U32 mask) { + LL_PROFILE_ZONE_SCOPED + if (mVertexBuffer.isNull()) { return 0; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 2f0a78b1b2..762898377a 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -509,7 +509,9 @@ LLSpatialGroup* LLSpatialGroup::getParent() } BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) - { +{ + LL_PROFILE_ZONE_SCOPED + if(!drawablep) { return FALSE; @@ -597,6 +599,8 @@ public: void LLSpatialGroup::setState(U32 state, S32 mode) { + LL_PROFILE_ZONE_SCOPED + llassert(state <= LLSpatialGroup::STATE_MASK); if (mode > STATE_MODE_SINGLE) @@ -644,6 +648,8 @@ public: void LLSpatialGroup::clearState(U32 state, S32 mode) { + LL_PROFILE_ZONE_SCOPED + llassert(state <= LLSpatialGroup::STATE_MASK); if (mode > STATE_MODE_SINGLE) @@ -730,6 +736,8 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) { + LL_PROFILE_ZONE_SCOPED + LLVector4a eye; LLVector4a origin; origin.load3(camera.getOrigin().mV); @@ -821,6 +829,8 @@ F32 LLSpatialGroup::getUpdateUrgency() const BOOL LLSpatialGroup::changeLOD() { + LL_PROFILE_ZONE_SCOPED + if (hasState(ALPHA_DIRTY | OBJECT_DIRTY)) { //a rebuild is going to happen, update distance and LoD @@ -913,6 +923,8 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) { + LL_PROFILE_ZONE_SCOPED + if (child->getListenerCount() == 0) { new LLSpatialGroup(child, getSpatialPartition()); @@ -2767,13 +2779,19 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) glVertexPointer(3, GL_FLOAT, 16, phys_volume->mHullPoints); gGL.diffuseColor4fv(line_color.mV); gGL.syncMatrices(); + { + LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x20FF20 ) glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices); + } gGL.diffuseColor4fv(color.mV); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices); + { + LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x40FF40 ) + glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices); // Use a vbo for the static LLVertexBuffer::drawArray/Element functions; by Drake Arconis/Shyotl Kuhr } + } // } else @@ -3301,6 +3319,7 @@ void renderRaycast(LLDrawable* drawablep) gGL.diffuseColor4f(0,1,1,0.5f); glVertexPointer(3, GL_FLOAT, sizeof(LLVector4a), face.mPositions); gGL.syncMatrices(); + LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x60FF60 ); glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices); // Use a vbo for the static LLVertexBuffer::drawArray/Element functions; by Drake Arconis/Shyotl Kuhr } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 9343e9b707..269eaeb381 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -182,7 +182,6 @@ #include "pipeline.h" #include "llappviewer.h" #include "llfasttimerview.h" -#include "lltelemetry.h" #include "llfloatermap.h" #include "llweb.h" #include "llvoiceclient.h" @@ -805,8 +804,6 @@ bool idle_startup() } #if LL_WINDOWS - LLPROFILE_STARTUP(); - // On the windows dev builds, unpackaged, the message.xml file will // be located in indra/build-vc**/newview//app_settings. std::string message_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"message.xml"); diff --git a/indra/newview/lltelemetry.cpp b/indra/newview/lltelemetry.cpp deleted file mode 100644 index 0c63e2fede..0000000000 --- a/indra/newview/lltelemetry.cpp +++ /dev/null @@ -1,145 +0,0 @@ - /** - * @file lltelemetry.cpp - * @brief Wrapper for Rad Game Tools Telemetry - * - * $LicenseInfo:firstyear=2020&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2020, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "lltelemetry.h" - -#if LLPROFILE_USE_RAD_TELEMETRY_PROFILER - #if LL_WINDOWS - #include "llwin32headers.h" - - // build-vc120-64\packages\lib\release - // build-vc150-64\packages\lib\release - #ifdef _MSC_VER - #pragma comment(lib,"rad_tm_win64.lib") - #else - #pragma message "NOTE: Rad GameTools Telemetry requested but non-MSVC compiler not yet supported on Windows" - #endif - #endif // LL_WINDOWS - - #if LL_DARWIN - #pragma message "NOTE: Rad Game Tools Telemetry requested but not yet supported on Darwin" - #endif - - #if LL_LINUX - #pragma message "NOTE: Rad Game Tools Telemetry requested but not yet supported on Linux" - #endif - -// -// local consts -// -static const tm_int32 TELEMETRY_BUFFER_SIZE = 8 * 1024 * 1024; - -// -// local globals -// -static char *gTelemetryBufferPtr = NULL; // Telemetry - -static const char *tm_status[ TMERR_INIT_NETWORKING_FAILED + 1 ] = -{ - "Telemetry pass: connected" // TM_OK - , "Telemetry FAIL: disabled via #define NTELEMETRY" // TMERR_DISABLED - , "Telemetry FAIL: invalid paramater" // TMERR_INVALID_PARAM - , "Telemetry FAIL: DLL not found" // TMERR_NULL_API - , "Telemetry FAIL: out of resources" // TMERR_OUT_OF_RESOURCES - , "Telemetry FAIL: tmInitialize() not called" // TMERR_UNINITIALIZED - , "Telemetry FAIL: bad hostname" // TMERR_BAD_HOSTNAME - , "Telemetry FAIL: couldn't connect to server" // TMERR_COULD_NOT_CONNECT - , "Telemetry FAIL: unknown network error" // TMERR_UNKNOWN_NETWORK - , "Telemetry FAIL: tmShutdown() already called" // TMERR_ALREADY_SHUTDOWN - , "Telemetry FAIL: memory buffer too small" // TMERR_ARENA_TOO_SMALL - , "Telemetry FAIL: server handshake error" // TMERR_BAD_HANDSHAKE - , "Telemetry FAIL: unaligned parameters" // TMERR_UNALIGNED - , "Telemetry FAIL: network not initialized" // TMERR_NETWORK_NOT_INITIALIZED -- WSAStartup not called before tmOpen() - , "Telemetry FAIL: bad version" // TMERR_BAD_VERSION - , "Telemetry FAIL: timer too large" // TMERR_BAD_TIMER - , "Telemetry FAIL: tmOpen() already called" // TMERR_ALREADY_OPENED - , "Telemetry FAIL: tmInitialize() already called" // TMERR_ALREADY_INITIALIZED - , "Telemetry FAIL: could't open file" // TMERR_FILE_OPEN_FAILED - , "Telemetry FAIL: tmOpen() failed networking" // TMERR_INIT_NETWORKING_FAILED -}; - -// -// exported functionality -// - -void telemetry_shutdown() -{ - #if LL_WINDOWS - if (gTelemetryBufferPtr) - { - tmClose(0); - tmShutdown(); - - delete[] gTelemetryBufferPtr; - gTelemetryBufferPtr = NULL; - } - #endif -} - -void telemetry_startup() -{ - #if LL_WINDOWS - tmLoadLibrary(TM_RELEASE); // Loads .dll - - gTelemetryBufferPtr = new char[ TELEMETRY_BUFFER_SIZE ]; - tmInitialize(TELEMETRY_BUFFER_SIZE, gTelemetryBufferPtr); - - tm_error telemetry_status = tmOpen( - 0, // unused - "SecondLife", // app name - __DATE__ " " __TIME__, // build identifier - "localhost", // server name (or filename) - TMCT_TCP, // connection type (or TMCT_FILE) - 4719, // port - TMOF_INIT_NETWORKING, // open flags - 250 ); // timeout ms - - if (telemetry_status == TMERR_UNKNOWN) - { - LL_ERRS() << "Telemetry FAIL: unknown error" << LL_ENDL; - } - else if (telemetry_status && (telemetry_status <= TMERR_INIT_NETWORKING_FAILED)) - { - LL_INFOS() << tm_status[ telemetry_status ] << LL_ENDL; - free(gTelemetryBufferPtr); - gTelemetryBufferPtr = NULL; - } - #endif // LL_WINDOWS -} - -// Called after we render a frame -void telemetry_update() -{ - #if LL_WINDOWS - if (gTelemetryBufferPtr) - { - tmTick(0); - } - #endif -} -#endif // LLPROFILE_USE_RAD_TELEMETRY_PROFILER diff --git a/indra/newview/lltelemetry.h b/indra/newview/lltelemetry.h deleted file mode 100644 index a73e5fcfa2..0000000000 --- a/indra/newview/lltelemetry.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @file lltelemetry.h - * @brief Wrapper for Rad Game Tools Telemetry - * - * $LicenseInfo:firstyear=2020&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2020, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -/* -To use: - -1. Uncomment #define LLPROFILE_USE_RAD_TELEMETRY_PROFILER below - -2. Include this header file - #include "lltelemetry.h" - -3. Add zones to the functions you wish to profile - void onFoo() - { - LLPROFILE_ZONE("Foo"); - } -*/ -//#define LLPROFILE_USE_RAD_TELEMETRY_PROFILER 1 - -// Default NO local telemetry profiling -#ifndef LLPROFILE_USE_RAD_TELEMETRY_PROFILER - #define LLPROFILE_USE_RAD_TELEMETRY_PROFILER 0 - #define LLPROFILE_SHUTDOWN( ...) {} - #define LLPROFILE_STARTUP( ...) {} - #define LLPROFILE_UPDATE( ...) {} - - #define LLPROFILE_AUTO_CPU_MARKER_COLOR(r, g, b) - #define LLPROFILE_ENTER(name) - #define LLPROFILE_ENTER_FORMAT(format, ...) - #define LLPROFILE_FUNCTION - #define LLPROFILE_LEAVE() - #define LLPROFILE_THREAD_NAME(name) - #define LLPROFILE_ZONE(name) - #define LLPROFILE_ZONE_FORMAT(format, ...) -#else - #include - - #define LLPROFILE_SHUTDOWN telemetry_shutdown - #define LLPROFILE_STARTUP telemetry_startup - #define LLPROFILE_UPDATE telemetry_update - - #define LLPROFILE_AUTO_CPU_MARKER_COLOR(r, g, b) tmZoneColor(r, g, b) - #define LLPROFILE_ENTER(name) tmEnter(0, 0, name) - #define LLPROFILE_ENTER_FORMAT(format, ...) tmEnter(0, 0, format, __VA_ARGS__) - #define LLPROFILE_FUNCTION tmFunction(0, 0) - #define LLPROFILE_LEAVE() tmLeave(0) - #define LLPROFILE_THREAD_NAME(name) tmThreadName(0, 0, name) - #define LLPROFILE_ZONE(name) tmZone(0, 0, name) - #define LLPROFILE_ZONE_FORMAT(format, ...) tmZone(0, 0, format, __VA_ARGS__) -#endif // LLPROFILE_USE_RAD_TELEMETRY_PROFILER - -// -// exported functionality -// - -extern void telemetry_startup(); -extern void telemetry_shutdown(); -extern void telemetry_update(); // called after every frame update diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index e23d990184..ccede3eefe 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1399,7 +1399,7 @@ bool setup_hud_matrices(const LLRect& screen_region) void render_ui(F32 zoom_factor, int subfield) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); LLGLState::checkStates(); @@ -1414,7 +1414,7 @@ void render_ui(F32 zoom_factor, int subfield) if(LLSceneMonitor::getInstance()->needsUpdate()) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_SCENE_MON); + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_SCENE_MON); gGL.pushMatrix(); gViewerWindow->setup2DRender(); LLSceneMonitor::getInstance()->compare(); @@ -1422,62 +1422,70 @@ void render_ui(F32 zoom_factor, int subfield) gGL.popMatrix(); } - // Finalize scene - gPipeline.renderFinalize(); + // Finalize scene + gPipeline.renderFinalize(); - {// give unique scope + { + // SL-15709 + // NOTE: Tracy only allows one ZoneScoped per function. + // Solutions are: + // 1. Use a new scope + // 2. Use named zones + // 3. Use transient zones LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD); - render_hud_elements(); + render_hud_elements(); // [RLVa:KB] - Checked: RLVa-2.2 (@setoverlay) if (RlvActions::hasBehaviour(RLV_BHVR_SETOVERLAY)) { LLVfxManager::instance().runEffect(EVisualEffect::RlvOverlay); } // [/RLVa:KB] - render_hud_attachments(); - } // unique scope - LLGLSDefault gls_default; - LLGLSUIDefault gls_ui; - { - gPipeline.disableLights(); - } + render_hud_attachments(); - { - gGL.color4f(1,1,1,1); - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + LLGLSDefault gls_default; + LLGLSUIDefault gls_ui; { - if (!gDisconnected) + gPipeline.disableLights(); + } + + { + gGL.color4f(1,1,1,1); + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D); - render_ui_3d(); + if (!gDisconnected) + { + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D); + render_ui_3d(); + LLGLState::checkStates(); + } + else + { + render_disconnected_background(); + } + + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D); + render_ui_2d(); LLGLState::checkStates(); } - else + gGL.flush(); + { - render_disconnected_background(); + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_DEBUG_TEXT); + gViewerWindow->setup2DRender(); + gViewerWindow->updateDebugText(); + gViewerWindow->drawDebugText(); } - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D); - render_ui_2d(); - LLGLState::checkStates(); + LLVertexBuffer::unbind(); } - gGL.flush(); + if (!gSnapshot) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_DEBUG_TEXT); - gViewerWindow->setup2DRender(); - gViewerWindow->updateDebugText(); - gViewerWindow->drawDebugText(); + set_current_modelview(saved_view); + gGL.popMatrix(); } - LLVertexBuffer::unbind(); - } - - if (!gSnapshot) - { - set_current_modelview(saved_view); - gGL.popMatrix(); - } + } // Tracy integration } static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap"); diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 0a45c71c97..91d15e2100 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -177,6 +177,8 @@ U64 LLViewerObjectList::getIndex(const U32 local_id, BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp) { + LL_PROFILE_ZONE_SCOPED + if(objectp && objectp->getRegion()) { U32 local_id = objectp->mLocalID; @@ -336,6 +338,8 @@ static LLTrace::BlockTimerStatHandle FTM_PROCESS_OBJECTS("Process Objects"); LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* entry, LLViewerRegion* regionp) { + LL_PROFILE_ZONE_SCOPED + LLDataPacker *cached_dpp = entry->getDP(); if (!cached_dpp) @@ -937,6 +941,7 @@ static LLTrace::BlockTimerStatHandle FTM_IDLE_COPY("Idle Copy"); void LLViewerObjectList::update(LLAgent &agent) { + LL_PROFILE_ZONE_SCOPED // Speed up debug settings static LLCachedControl velocityInterpolate(gSavedSettings, "VelocityInterpolate"); static LLCachedControl pingInterpolate(gSavedSettings, "PingInterpolate"); @@ -1421,6 +1426,7 @@ void LLViewerObjectList::clearDebugText() void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) { + LL_PROFILE_ZONE_SCOPED // FIRE-30694 DeadObject Spam - handle new_dead_object properly and closer to source // bool new_dead_object = true; if (mDeadObjects.find(objectp->mID) != mDeadObjects.end()) @@ -1721,6 +1727,8 @@ void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp) void LLViewerObjectList::updateActive(LLViewerObject *objectp) { + LL_PROFILE_ZONE_SCOPED + if (objectp->isDead()) { return; // We don't update dead objects! @@ -2113,6 +2121,8 @@ void LLViewerObjectList::renderObjectBounds(const LLVector3 ¢er) void LLViewerObjectList::generatePickList(LLCamera &camera) { + LL_PROFILE_ZONE_SCOPED + LLViewerObject *objectp; S32 i; // Reset all of the GL names to zero. @@ -2390,6 +2400,8 @@ LLViewerObject *LLViewerObjectList::replaceObject(const LLUUID &id, const LLPCod S32 LLViewerObjectList::findReferences(LLDrawable *drawablep) const { + LL_PROFILE_ZONE_SCOPED + LLViewerObject *objectp; S32 num_refs = 0; @@ -2453,6 +2465,8 @@ void LLViewerObjectList::orphanize(LLViewerObject *childp, U32 parent_id, U32 ip void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port) { + LL_PROFILE_ZONE_SCOPED + if (objectp->isDead()) { LL_WARNS() << "Trying to find orphans for dead obj " << objectp->mID diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 7ce1730b26..9e27f8ebfc 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -6363,128 +6363,135 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_VB);// move out one scope (but are these even useful as dupes?) if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY)) { - // LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_VB);// move out one scope (but are these even useful as dupes?) - LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers + LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_VB); + { + // SL-15709 -- NOTE: Tracy only allows one ZoneScoped per function. + // Solutions are: + // 1. Use a new scope + // 2. Use named zones + // 3. Use transient zones + LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers - group->mBuilt = 1.f; + group->mBuilt = 1.f; - S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ; + S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ; - const U32 MAX_BUFFER_COUNT = 4096; - LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT]; - - U32 buffer_count = 0; + const U32 MAX_BUFFER_COUNT = 4096; + LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT]; - for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) - { - LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + U32 buffer_count = 0; - if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) - { - LLVOVolume* vobj = drawablep->getVOVolume(); - // avoid unfortunate sleep during trylock by static check - //if(debugLoggingEnabled("AnimatedObjectsLinkset")) - static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset"); - if (debug_logging_on) - // - { - if (vobj->isAnimatedObject() && vobj->isRiggedMesh()) - { - std::string vobj_name = llformat("Vol%p", vobj); - F32 est_tris = vobj->getEstTrianglesMax(); - LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuildMesh, tris " << est_tris << LL_ENDL; - } - } - if (vobj->isNoLOD()) continue; - - vobj->preRebuild(); - - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) - { - vobj->updateRelativeXform(true); - } - - LLVolume* volume = vobj->getVolume(); - for (S32 i = 0; i < drawablep->getNumFaces(); ++i) - { - LLFace* face = drawablep->getFace(i); - if (face) - { - LLVertexBuffer* buff = face->getVertexBuffer(); - if (buff) - { - llassert(!face->isState(LLFace::RIGGED)); - - if (!face->getGeometryVolume(*volume, face->getTEOffset(), - vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex())) - { //something's gone wrong with the vertex buffer accounting, rebuild this group - group->dirtyGeom(); - gPipeline.markRebuild(group, TRUE); - } - - - if (buff->isLocked() && buffer_count < MAX_BUFFER_COUNT) - { - locked_buffer[buffer_count++] = buff; - } - } - } - } - - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) - { - vobj->updateRelativeXform(); - } - - - drawablep->clearState(LLDrawable::REBUILD_ALL); - } - } - - { - LL_RECORD_BLOCK_TIME(FTM_REBUILD_MESH_FLUSH); - for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter) - { - (*iter)->flush(); - } - - // don't forget alpha - if(group != NULL && - !group->mVertexBuffer.isNull() && - group->mVertexBuffer->isLocked()) - { - group->mVertexBuffer->flush(); - } - } - - //if not all buffers are unmapped - if(num_mapped_vertex_buffer != LLVertexBuffer::sMappedCount) - { - LL_WARNS() << "Not all mapped vertex buffers are unmapped!" << LL_ENDL ; for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - if(!drawablep) + + if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) { - continue; - } - for (S32 i = 0; i < drawablep->getNumFaces(); ++i) - { - LLFace* face = drawablep->getFace(i); - if (face) + LLVOVolume* vobj = drawablep->getVOVolume(); + // avoid unfortunate sleep during trylock by static check + //if(debugLoggingEnabled("AnimatedObjectsLinkset")) + static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset"); + if (debug_logging_on) + // { - LLVertexBuffer* buff = face->getVertexBuffer(); - if (buff && buff->isLocked()) + if (vobj->isAnimatedObject() && vobj->isRiggedMesh()) { - buff->flush(); + std::string vobj_name = llformat("Vol%p", vobj); + F32 est_tris = vobj->getEstTrianglesMax(); + LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuildMesh, tris " << est_tris << LL_ENDL; + } + } + if (vobj->isNoLOD()) continue; + + vobj->preRebuild(); + + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(true); + } + + LLVolume* volume = vobj->getVolume(); + for (S32 i = 0; i < drawablep->getNumFaces(); ++i) + { + LLFace* face = drawablep->getFace(i); + if (face) + { + LLVertexBuffer* buff = face->getVertexBuffer(); + if (buff) + { + llassert(!face->isState(LLFace::RIGGED)); + + if (!face->getGeometryVolume(*volume, face->getTEOffset(), + vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex())) + { //something's gone wrong with the vertex buffer accounting, rebuild this group + group->dirtyGeom(); + gPipeline.markRebuild(group, TRUE); + } + + + if (buff->isLocked() && buffer_count < MAX_BUFFER_COUNT) + { + locked_buffer[buffer_count++] = buff; + } + } + } + } + + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(); + } + + drawablep->clearState(LLDrawable::REBUILD_ALL); + } + } + + { + LL_RECORD_BLOCK_TIME(FTM_REBUILD_MESH_FLUSH); + for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter) + { + (*iter)->flush(); + } + + // don't forget alpha + if(group != NULL && + !group->mVertexBuffer.isNull() && + group->mVertexBuffer->isLocked()) + { + group->mVertexBuffer->flush(); + } + } + + //if not all buffers are unmapped + if(num_mapped_vertex_buffer != LLVertexBuffer::sMappedCount) + { + LL_WARNS() << "Not all mapped vertex buffers are unmapped!" << LL_ENDL ; + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) + { + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + if(!drawablep) + { + continue; + } + for (S32 i = 0; i < drawablep->getNumFaces(); ++i) + { + LLFace* face = drawablep->getFace(i); + if (face) + { + LLVertexBuffer* buff = face->getVertexBuffer(); + if (buff && buff->isLocked()) + { + buff->flush(); + } } } } - } + } + + group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); } - group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); - } + } // Tracy integration // llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO)); } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index be66720237..972338a7d5 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4753,53 +4753,80 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) { LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred"); - // LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); remove duplicate zone scope - - LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS); - - LLGLEnable cull(GL_CULL_FACE); - - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) + LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); { - LLDrawPool *poolp = *iter; - if (hasRenderType(poolp->getType())) + // SL-15709 -- NOTE: Tracy only allows one ZoneScoped per function. + // Solutions are: + // 1. Use a new scope + // 2. Use named zones + // 3. Use transient zones + LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS); + + LLGLEnable cull(GL_CULL_FACE); + + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) { - poolp->prerender(); - } - } - - LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); - - LLVertexBuffer::unbind(); - - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); - - U32 cur_type = 0; - - gGL.setColorMask(true, true); - - pool_set_t::iterator iter1 = mPools.begin(); - - while ( iter1 != mPools.end() ) - { - LLDrawPool *poolp = *iter1; - - cur_type = poolp->getType(); - - pool_set_t::iterator iter2 = iter1; - if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0) - { - LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER); - - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - - for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ ) + LLDrawPool *poolp = *iter; + if (hasRenderType(poolp->getType())) { - LLVertexBuffer::unbind(); - poolp->beginDeferredPass(i); + poolp->prerender(); + } + } + + LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); + + LLVertexBuffer::unbind(); + + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); + + U32 cur_type = 0; + + gGL.setColorMask(true, true); + + pool_set_t::iterator iter1 = mPools.begin(); + + while ( iter1 != mPools.end() ) + { + LLDrawPool *poolp = *iter1; + + cur_type = poolp->getType(); + + pool_set_t::iterator iter2 = iter1; + if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0) + { + LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER); + + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + + for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ ) + { + LLVertexBuffer::unbind(); + poolp->beginDeferredPass(i); + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + + if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); } + } + poolp->endDeferredPass(i); + LLVertexBuffer::unbind(); + + if (gDebugGL || gDebugPipeline) + { + LLGLState::checkStates(); + } + } + } + else + { + // Skip all pools of this type for (iter2 = iter1; iter2 != mPools.end(); iter2++) { LLDrawPool *p = *iter2; @@ -4807,39 +4834,19 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) { break; } - - if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); } - } - poolp->endDeferredPass(i); - LLVertexBuffer::unbind(); - - if (gDebugGL || gDebugPipeline) - { - LLGLState::checkStates(); } } + iter1 = iter2; + stop_glerror(); } - else - { - // Skip all pools of this type - for (iter2 = iter1; iter2 != mPools.end(); iter2++) - { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) - { - break; - } - } - } - iter1 = iter2; - stop_glerror(); - } - gGLLastMatrix = NULL; - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.loadMatrix(gGLModelView); - gGL.setColorMask(true, false); + gGL.setColorMask(true, false); + + } // Tracy ZoneScoped } void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion) @@ -11460,6 +11467,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) if (LLPipeline::sRenderDeferred) { GLuint buff = GL_COLOR_ATTACHMENT0; + LL_PROFILER_GPU_ZONEC( "gl.DrawBuffersARB", 0x8000FF ); glDrawBuffersARB(1, &buff); } diff --git a/scripts/configure_firestorm.sh b/scripts/configure_firestorm.sh index ed28c392c7..3f5f4b1f2f 100755 --- a/scripts/configure_firestorm.sh +++ b/scripts/configure_firestorm.sh @@ -469,9 +469,9 @@ if [ $WANTS_CONFIG -eq $TRUE ] ; then AVX2_OPTIMIZATION="-DUSE_AVX2_OPTIMIZATION:BOOL=OFF" fi if [ $WANTS_TRACY -eq $TRUE ] ; then - TRACY_PROFILER="-DUSE_TRACY_PROFILER:BOOL=ON" + TRACY_PROFILER="-DUSE_TRACY:BOOL=ON" else - TRACY_PROFILER="-DUSE_TRACY_PROFILER:BOOL=OFF" + TRACY_PROFILER="-DUSE_TRACY:BOOL=OFF" fi if [ $WANTS_TESTBUILD -eq $TRUE ] ; then TESTBUILD="-DTESTBUILD:BOOL=ON -DTESTBUILDPERIOD:STRING=$TESTBUILD_PERIOD"