diff --git a/.gitignore b/.gitignore index 4b9a7a4cd6..b47f28773e 100755 --- a/.gitignore +++ b/.gitignore @@ -111,3 +111,5 @@ compile_commands.json # ignore tracy for now indra/tracy firestorm.code-workspace + +.cache/clangd/index/ diff --git a/indra/newview/fsperfstats.cpp b/indra/newview/fsperfstats.cpp index aebb1a600a..aeb8880927 100644 --- a/indra/newview/fsperfstats.cpp +++ b/indra/newview/fsperfstats.cpp @@ -49,11 +49,12 @@ namespace FSPerfStats std::atomic tunedAvatars{0}; U32 targetFPS; // desired FPS U64 renderAvatarMaxART_ns{(U64)(ART_UNLIMITED_NANOS)}; // highest render time we'll allow without culling features - U32 fpsTuningStrategy{0}; // linked to FSTuningFPSStrategy U32 lastGlobalPrefChange{0}; std::mutex bufferToggleLock{}; bool autoTune{false}; + Tunables tunables; + std::atomic StatsRecorder::writeBuffer{0}; bool StatsRecorder::collectionEnabled{true}; LLUUID StatsRecorder::focusAv{LLUUID::null}; @@ -61,6 +62,14 @@ namespace FSPerfStats std::array StatsRecorder::max{ {} }; std::array StatsRecorder::sum{ {} }; + void Tunables::applyUpdates() + { + assert_main_thread(); + if( tuningFlag & NonImposters ){ gSavedSettings.setU32("IndirectMaxNonImpostors", nonImposters); }; + if( tuningFlag & ReflectionDetail ){ gSavedSettings.setS32("RenderReflectionDetail", reflectionDetail); }; + if( tuningFlag & FarClip ){ gSavedSettings.setF32("RenderFarClip", farClip); }; + resetChanges(); + } StatsRecorder::StatsRecorder():q(1024*16),t(&StatsRecorder::run) { @@ -175,7 +184,7 @@ namespace FSPerfStats sum[writeBuffer][i].fill(0); } - // and now adjust the visuals. + // and now adjust the proxy vars so that the main thread can adjust the visuals. if(autoTune) { updateAvatarParams(); @@ -280,6 +289,7 @@ namespace FSPerfStats static LLCachedControl impostorDistance(gSavedSettings, "FSAutoTuneImpostorFarAwayDistance"); static LLCachedControl impostorDistanceTuning(gSavedSettings, "FSAutoTuneImpostorByDistEnabled"); static LLCachedControl maxNonImpostors (gSavedSettings, "IndirectMaxNonImpostors"); + static LLCachedControl fpsTuningStrategy (gSavedSettings, "FSTuningFPSStrategy"); if(impostorDistanceTuning) { @@ -288,7 +298,7 @@ namespace FSPerfStats auto count = countNearbyAvatars(std::min(drawDistance, impostorDistance)); if( count != maxNonImpostors ) { - gSavedSettings.setU32("IndirectMaxNonImpostors", (count < LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER)?count : LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER); + tunables.updateNonImposters( (count < LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER)?count : LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER ); LL_DEBUGS("AutoTune") << "There are " << count << "avatars within " << std::min(drawDistance, impostorDistance) << "m of the camera" << LL_ENDL; } } @@ -339,13 +349,13 @@ namespace FSPerfStats // we cannnot do this by avatar adjustment alone. if((gFrameCount - FSPerfStats::lastGlobalPrefChange) > 10) // give changes a short time to take effect. { - if(FSPerfStats::fpsTuningStrategy == 1) + if(fpsTuningStrategy == 1) { // 1 - hack the water to opaque. all non opaque have a significant hit, this is a big boost for (arguably) a minor visual hit. // the other reflection options make comparatively little change and iof this overshoots we'll be stepping back up later if(LLPipeline::RenderReflectionDetail != -2) { - gSavedSettings.setS32("RenderReflectionDetail", -2); + FSPerfStats::tunables.updateReflectionDetail(-2); FSPerfStats::lastGlobalPrefChange = gFrameCount; return; } @@ -355,7 +365,7 @@ namespace FSPerfStats auto new_dd = (drawDistance-10>userMinDrawDistance)?(drawDistance - 10) : userMinDrawDistance; if(new_dd != drawDistance) { - gSavedSettings.setF32("RenderFarClip", new_dd); + FSPerfStats::tunables.updateFarClip( new_dd ); FSPerfStats::lastGlobalPrefChange = gFrameCount; return; } @@ -404,15 +414,14 @@ namespace FSPerfStats } if( drawDistance < userTargetDrawDistance ) { - gSavedSettings.setF32("RenderFarClip", drawDistance + 10.); + FSPerfStats::tunables.updateFarClip( drawDistance + 10. ); } if( (target_frame_time_raw * 1.5) > tot_frame_time_raw && FSPerfStats::tunedAvatars == 0 && drawDistance >= userTargetDrawDistance) { // if everything else is "max" and we have 50% headroom let's knock the water quality up a notch at a time. - auto water = gSavedSettings.getS32("RenderReflectionDetail"); - gSavedSettings.setS32("RenderReflectionDetail", water+1); + FSPerfStats::tunables.updateReflectionDetail( gSavedSettings.getS32("RenderReflectionDetail") + 1 ); } } updateSettingsFromRenderCostLimit(); diff --git a/indra/newview/fsperfstats.h b/indra/newview/fsperfstats.h index 49a7e8e6d1..7ada042a6a 100644 --- a/indra/newview/fsperfstats.h +++ b/indra/newview/fsperfstats.h @@ -74,7 +74,6 @@ namespace FSPerfStats extern std::atomic tunedAvatars; extern U32 targetFPS; // desired FPS extern U64 renderAvatarMaxART_ns; - extern U32 fpsTuningStrategy; extern U32 lastGlobalPrefChange; extern std::mutex bufferToggleLock; extern bool autoTune; @@ -116,6 +115,28 @@ namespace FSPerfStats bool isHUD; }; + struct Tunables + { + static constexpr U32 Nothing{0}; + static constexpr U32 NonImposters{1}; + static constexpr U32 ReflectionDetail{2}; + static constexpr U32 FarClip{4}; + + U32 tuningFlag{0}; + U32 nonImposters; + S32 reflectionDetail; + F32 farClip; + + void updateFarClip(F32 nv){farClip=nv; tuningFlag |= FarClip;}; + void updateNonImposters(U32 nv){nonImposters=nv; tuningFlag |= NonImposters;}; + void updateReflectionDetail(S32 nv){reflectionDetail=nv; tuningFlag |= ReflectionDetail;}; + + void applyUpdates(); + void resetChanges(){tuningFlag=Nothing;}; + }; + + extern Tunables tunables; + class StatsRecorder{ using Queue = moodycamel::BlockingConcurrentQueue; public: diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index d44a8b1919..a8b9a118d0 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1644,6 +1644,12 @@ bool LLAppViewer::doFrame() { // Perfstats collection Frame boundary { + // and now adjust the visuals from previous frame. + if(FSPerfStats::autoTune && FSPerfStats::tunables.tuningFlag != FSPerfStats::Tunables::Nothing) + { + FSPerfStats::tunables.applyUpdates(); + } + FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_FRAME); LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index a7227c7f58..3b1f3179d3 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -1112,11 +1112,7 @@ void handleRenderAvatarMaxARTChanged(const LLSD& newValue) { FSPerfStats::StatsRecorder::updateRenderCostLimitFromSettings(); } -void handleFPSTuningStrategyChanged(const LLSD& newValue) -{ - const auto newval = gSavedSettings.getU32("FSTuningFPSStrategy"); - FSPerfStats::fpsTuningStrategy = newval; -} + void handlePerformanceStatsEnabledChanged(const LLSD& newValue) { const auto newval = gSavedSettings.getBOOL("FSPerfStatsCaptureEnabled"); @@ -1383,7 +1379,6 @@ void settings_setup_listeners() gSavedSettings.getControl("FSTargetFPS")->getSignal()->connect(boost::bind(&handleTargetFPSChanged, _2)); gSavedSettings.getControl("FSAutoTuneFPS")->getSignal()->connect(boost::bind(&handleAutoTuneFPSChanged, _2)); gSavedSettings.getControl("FSRenderAvatarMaxART")->getSignal()->connect(boost::bind(&handleRenderAvatarMaxARTChanged, _2)); - gSavedSettings.getControl("FSTuningFPSStrategy")->getSignal()->connect(boost::bind(&handleFPSTuningStrategyChanged, _2)); gSavedSettings.getControl("FSPerfStatsCaptureEnabled")->getSignal()->connect(boost::bind(&handlePerformanceStatsEnabledChanged, _2)); // }