diff options
Diffstat (limited to 'indra/newview/llperfstats.cpp')
-rw-r--r-- | indra/newview/llperfstats.cpp | 108 |
1 files changed, 55 insertions, 53 deletions
diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp index 64e66d520b..37bb59a65c 100644 --- a/indra/newview/llperfstats.cpp +++ b/indra/newview/llperfstats.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llperfstats.cpp * @brief Statistics collection to support autotune and perf flaoter. * * $LicenseInfo:firstyear=2022&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2022, 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$ */ @@ -47,7 +47,7 @@ namespace LLPerfStats std::atomic<int64_t> tunedAvatars{0}; std::atomic<U64> renderAvatarMaxART_ns{(U64)(ART_UNLIMITED_NANOS)}; // highest render time we'll allow without culling features bool belowTargetFPS{false}; - U32 lastGlobalPrefChange{0}; + U32 lastGlobalPrefChange{0}; U32 lastSleepedFrame{0}; U64 meanFrameTime{0}; std::mutex bufferToggleLock{}; @@ -57,11 +57,11 @@ namespace LLPerfStats Tunables tunables; - std::atomic<int> StatsRecorder::writeBuffer{0}; - bool StatsRecorder::collectionEnabled{true}; + std::atomic<int> StatsRecorder::writeBuffer{0}; + bool StatsRecorder::collectionEnabled{true}; LLUUID StatsRecorder::focusAv{LLUUID::null}; bool StatsRecorder::autotuneInit{false}; - std::array<StatsRecorder::StatsTypeMatrix,2> StatsRecorder::statsDoubleBuffer{ {} }; + std::array<StatsRecorder::StatsTypeMatrix,2> StatsRecorder::statsDoubleBuffer{ {} }; std::array<StatsRecorder::StatsSummaryArray,2> StatsRecorder::max{ {} }; std::array<StatsRecorder::StatsSummaryArray,2> StatsRecorder::sum{ {} }; @@ -69,7 +69,7 @@ namespace LLPerfStats { assert_main_thread(); // these following variables are proxies for pipeline statics we do not need a two way update (no llviewercontrol handler) - if( tuningFlag & NonImpostors ){ gSavedSettings.setU32("IndirectMaxNonImpostors", nonImpostors); }; + if( tuningFlag & NonImpostors ){ gSavedSettings.setU32("RenderAvatarMaxNonImpostors", nonImpostors); }; if( tuningFlag & ReflectionDetail ){ gSavedSettings.setS32("RenderReflectionDetail", reflectionDetail); }; if( tuningFlag & FarClip ){ gSavedSettings.setF32("RenderFarClip", farClip); }; if( tuningFlag & UserMinDrawDistance ){ gSavedSettings.setF32("AutoTuneRenderFarClipMin", userMinDrawDistance); }; @@ -91,7 +91,7 @@ namespace LLPerfStats const auto newval = gSavedSettings.getF32("RenderAvatarMaxART"); if(newval < log10(LLPerfStats::ART_UNLIMITED_NANOS/1000)) { - LLPerfStats::renderAvatarMaxART_ns = pow(10,newval)*1000; + LLPerfStats::renderAvatarMaxART_ns = (U64)pow(10,newval)*1000; } else { @@ -99,7 +99,7 @@ namespace LLPerfStats } } - // static + // static void Tunables::updateSettingsFromRenderCostLimit() { if( userARTCutoffSliderValue != log10( ( (F32)LLPerfStats::renderAvatarMaxART_ns )/1000 ) ) @@ -112,13 +112,13 @@ namespace LLPerfStats { updateUserARTCutoffSlider(log10( (F32)LLPerfStats::ART_UNLIMITED_NANOS/1000 ) ); } - } + } } void Tunables::initialiseFromSettings() { assert_main_thread(); - // the following variables are two way and have "push" in llviewercontrol + // the following variables are two way and have "push" in llviewercontrol LLPerfStats::tunables.userMinDrawDistance = gSavedSettings.getF32("AutoTuneRenderFarClipMin"); LLPerfStats::tunables.userTargetDrawDistance = gSavedSettings.getF32("AutoTuneRenderFarClipTarget"); LLPerfStats::tunables.userImpostorDistance = gSavedSettings.getF32("AutoTuneImpostorFarAwayDistance"); @@ -131,14 +131,14 @@ namespace LLPerfStats if(gSavedSettings.getBOOL("AutoTuneLock") && !gSavedSettings.getU32("KeepAutoTuneLock")) { - gSavedSettings.setBOOL("AutoTuneLock", FALSE); + gSavedSettings.setBOOL("AutoTuneLock", false); } LLPerfStats::tunables.userAutoTuneEnabled = LLPerfStats::tunables.userAutoTuneLock; if (LLPerfStats::tunables.userAutoTuneEnabled && !gSavedSettings.getBOOL("AutoTuneFPS")) { - gSavedSettings.setBOOL("AutoTuneFPS", TRUE); + gSavedSettings.setBOOL("AutoTuneFPS", true); } // Note: The Max ART slider is logarithmic and thus we have an intermediate proxy value @@ -166,8 +166,8 @@ namespace LLPerfStats auto& lastStats = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null]; static constexpr std::initializer_list<StatType_t> sceneStatsToAvg = { - StatType_t::RENDER_FRAME, - StatType_t::RENDER_DISPLAY, + StatType_t::RENDER_FRAME, + StatType_t::RENDER_DISPLAY, StatType_t::RENDER_HUDS, StatType_t::RENDER_UI, StatType_t::RENDER_SWAP, @@ -177,8 +177,8 @@ namespace LLPerfStats #if 0 static constexpr std::initializer_list<StatType_t> avatarStatsToAvg = { - StatType_t::RENDER_GEOMETRY, - StatType_t::RENDER_SHADOWS, + StatType_t::RENDER_GEOMETRY, + StatType_t::RENDER_SHADOWS, StatType_t::RENDER_COMBINED, StatType_t::RENDER_IDLE }; #endif @@ -194,7 +194,7 @@ namespace LLPerfStats if(!unreliable) { - // only use these stats when things are reliable. + // only use these stats when things are reliable. for(auto & statEntry : sceneStatsToAvg) { @@ -204,13 +204,13 @@ namespace LLPerfStats // LL_INFOS("scenestats") << "Scenestat: " << static_cast<size_t>(statEntry) << " before=" << avg << " new=" << val << " newavg=" << statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null][static_cast<size_t>(statEntry)] << LL_ENDL; } } - + // swap the buffers if(enabled()) { std::lock_guard<std::mutex> lock{bufferToggleLock}; writeBuffer ^= 1; - }; // note we are relying on atomic updates here. The risk is low and would cause minor errors in the stats display. + }; // note we are relying on atomic updates here. The risk is low and would cause minor errors in the stats display. // clean the write maps in all cases. auto& statsTypeMatrix = statsDoubleBuffer[writeBuffer]; @@ -238,7 +238,7 @@ namespace LLPerfStats } // clear buffers when we change region or need a hard reset. - // static + // static void StatsRecorder::clearStatsBuffers() { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; @@ -265,7 +265,7 @@ namespace LLPerfStats { std::lock_guard<std::mutex> lock{bufferToggleLock}; writeBuffer ^= 1; - }; + }; // repeat before we start processing new stuff for(auto& statsMap : statsTypeMatrix) { @@ -288,7 +288,7 @@ namespace LLPerfStats void updateClass() { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; - + sTotalAvatarTime = LLVOAvatar::getTotalGPURenderTime(); sAverageAvatarTime = LLVOAvatar::getAverageGPURenderTime(); sMaxAvatarTime = LLVOAvatar::getMaxGPURenderTime(); @@ -299,11 +299,11 @@ namespace LLPerfStats { const auto our_pos = gAgentCamera.getCameraPositionGlobal(); - std::vector<LLVector3d> positions; - uuid_vec_t avatar_ids; - LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, our_pos, distance); - return positions.size(); - } + std::vector<LLVector3d> positions; + uuid_vec_t avatar_ids; + LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, our_pos, (F32)distance); + return static_cast<int>(positions.size()); + } const U32 NUM_PERIODS = 50; void StatsRecorder::updateMeanFrameTime(U64 cur_frame_time_raw) @@ -314,7 +314,7 @@ namespace LLPerfStats { frame_time_deque.pop_back(); } - + std::vector<U64> buf(frame_time_deque.begin(), frame_time_deque.end()); std::sort(buf.begin(), buf.end()); @@ -347,8 +347,8 @@ namespace LLPerfStats if( tot_sleep_time_raw != 0 ) { - // Note: we do not average sleep - // if at some point we need to, the averaging will need to take this into account or + // Note: we do not average sleep + // if at some point we need to, the averaging will need to take this into account or // we forever think we're in the background due to residuals. LL_DEBUGS() << "No tuning when not in focus" << LL_ENDL; LLPerfStats::lastSleepedFrame = gFrameCount; @@ -375,10 +375,10 @@ namespace LLPerfStats { // if we have less than the user's "max Non-Impostors" avatars within the desired range then adjust the limit. // also adjusts back up again for nearby crowds. - auto count = countNearbyAvatars(std::min(LLPipeline::RenderFarClip, tunables.userImpostorDistance)); + auto count = countNearbyAvatars((S32)std::min(LLPipeline::RenderFarClip, tunables.userImpostorDistance)); if( count != tunables.nonImpostors ) { - tunables.updateNonImposters( (count < LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER)?count : LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER ); + tunables.updateNonImposters(((U32)count < LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER) ? count : 0); LL_DEBUGS("AutoTune") << "There are " << count << "avatars within " << std::min(LLPipeline::RenderFarClip, tunables.userImpostorDistance) << "m of the camera" << LL_ENDL; } } @@ -386,7 +386,7 @@ namespace LLPerfStats auto av_render_max_raw = ms_to_raw(sMaxAvatarTime); // Is our target frame time lower than current? If so we need to take action to reduce draw overheads. // cumulative avatar time (includes idle processing, attachments and base av) - auto tot_avatar_time_raw = ms_to_raw(sTotalAvatarTime); + auto tot_avatar_time_raw = ms_to_raw(sTotalAvatarTime); // The frametime budget we have based on the target FPS selected auto target_frame_time_raw = (U64)llround(LLPerfStats::cpu_hertz / (target_fps == 0 ? 1 : target_fps)); @@ -398,7 +398,7 @@ namespace LLPerfStats // This could be problematic. tot_frame_time_raw -= tot_limit_time_raw; }*/ - + F64 time_buf = target_frame_time_raw * 0.1; // 1) Is the target frame time lower than current? @@ -411,7 +411,7 @@ namespace LLPerfStats return; } - if(belowTargetFPS == false) + if (!belowTargetFPS) { // this is the first frame under. hold fire to add a little hysteresis belowTargetFPS = true; @@ -457,7 +457,7 @@ namespace LLPerfStats // Note: moved from outside "if changefrequency elapsed" to stop fallthrough and allow scenery changes time to take effect. target_avatar_time_raw = 0; } - else + else { // we made a settings change recently so let's give it time. return; @@ -476,7 +476,7 @@ namespace LLPerfStats // max render this frame may be higher than the last (cos new entrants and jitter) so make sure we are heading in the right direction if( new_render_limit_ns > renderAvatarMaxART_ns ) { - new_render_limit_ns = renderAvatarMaxART_ns; + new_render_limit_ns = (double)renderAvatarMaxART_ns; } if (new_render_limit_ns > LLPerfStats::ART_MIN_ADJUST_DOWN_NANOS) @@ -484,23 +484,23 @@ namespace LLPerfStats new_render_limit_ns -= LLPerfStats::ART_MIN_ADJUST_DOWN_NANOS; } - // bounce at the bottom to prevent "no limit" - new_render_limit_ns = std::max((U64)new_render_limit_ns, (U64)LLPerfStats::ART_MINIMUM_NANOS); + // bounce at the bottom to prevent "no limit" + new_render_limit_ns = (double)std::max((U64)new_render_limit_ns, (U64)LLPerfStats::ART_MINIMUM_NANOS); // assign the new value - if(renderAvatarMaxART_ns != new_render_limit_ns) + if (renderAvatarMaxART_ns != new_render_limit_ns) { - renderAvatarMaxART_ns = new_render_limit_ns; + renderAvatarMaxART_ns = (U64)new_render_limit_ns; tunables.updateSettingsFromRenderCostLimit(); } // LL_DEBUGS() << "AUTO_TUNE: avatar_budget adjusted to:" << new_render_limit_ns << LL_ENDL; } // LL_DEBUGS() << "AUTO_TUNE: Target frame time:"<< LLPerfStats::raw_to_us(target_frame_time_raw) << "usecs (non_avatar is " << LLPerfStats::raw_to_us(non_avatar_time_raw) << "usecs) Max cost limited=" << renderAvatarMaxART_ns << LL_ENDL; } - else if(( LLPerfStats::raw_to_ns(target_frame_time_raw) > (LLPerfStats::raw_to_ns(tot_frame_time_raw) + renderAvatarMaxART_ns) ) || + else if ((LLPerfStats::raw_to_ns(target_frame_time_raw) > (LLPerfStats::raw_to_ns(tot_frame_time_raw) + renderAvatarMaxART_ns)) || (tunables.vsyncEnabled && (target_fps == LLPerfStats::vsync_max_fps) && (target_frame_time_raw > getMeanTotalFrameTime()))) { - if(belowTargetFPS == true) + if (belowTargetFPS) { // we reached target, force a pause lastGlobalPrefChange = gFrameCount; @@ -508,15 +508,17 @@ namespace LLPerfStats } // once we're over the FPS target we slow down further - if((gFrameCount - lastGlobalPrefChange) > settingsChangeFrequency*3) + if ((gFrameCount - lastGlobalPrefChange) > settingsChangeFrequency * 3) { - if(!tunables.userAutoTuneLock) + if (!tunables.userAutoTuneLock) { // we've reached the target and stayed long enough to consider stable. // turn off if we are not locked. tunables.updateUserAutoTuneEnabled(false); } - if(renderAvatarMaxART_ns != 0 && LLPerfStats::tunedAvatars > 0 && (tunables.userFPSTuningStrategy != TUNE_SCENE_ONLY) ) + if (renderAvatarMaxART_ns > 0 && + LLPerfStats::tunedAvatars > 0 && + tunables.userFPSTuningStrategy != TUNE_SCENE_ONLY) { // if we have more time to spare let's shift up little in the hope we'll restore an avatar. U64 up_step = LLPerfStats::tunedAvatars > 2 ? LLPerfStats::ART_MIN_ADJUST_UP_NANOS : LLPerfStats::ART_MIN_ADJUST_UP_NANOS * 2; @@ -524,15 +526,15 @@ namespace LLPerfStats tunables.updateSettingsFromRenderCostLimit(); return; } - if(tunables.userFPSTuningStrategy != TUNE_AVATARS_ONLY) + if (tunables.userFPSTuningStrategy != TUNE_AVATARS_ONLY) { - if( LLPipeline::RenderFarClip < tunables.userTargetDrawDistance ) + if (LLPipeline::RenderFarClip < tunables.userTargetDrawDistance) { LLPerfStats::tunables.updateFarClip( std::min(LLPipeline::RenderFarClip + DD_STEP, tunables.userTargetDrawDistance) ); LLPerfStats::lastGlobalPrefChange = gFrameCount; return; } - if( (tot_frame_time_raw * 1.5) < target_frame_time_raw ) + if ((tot_frame_time_raw * 1.5) < target_frame_time_raw) { // if everything else is "max" and we have >50% headroom let's knock the water quality up a notch at a time. # if 0 // RenderReflectionDetail went away |