[FIRE-35070] progressive loss of FPS when probe coverage none.

Addresses accumulation of probes over time leading to extremely low framerates during long sessions.

[FIRE-35070] Fix and refactor isRelevant

.
master
Beq 2025-06-21 03:25:16 +01:00
parent 4c710008c1
commit 1c3c08517a
6 changed files with 76 additions and 20 deletions

View File

@ -291,25 +291,54 @@ bool LLReflectionMap::isActive() const
bool LLReflectionMap::isRelevant() const
{
static LLCachedControl<S32> RenderReflectionProbeLevel(gSavedSettings, "RenderReflectionProbeLevel", 3);
static LLCachedControl<S32> sRenderReflectionProbeLevel(gSavedSettings, "RenderReflectionProbeLevel", (S32)ProbeLevel::FULL_SCENE_WITH_AUTO);
// <FS:Beq> [FIRE-35070] Correct isRelevant() logic for coverage == None and refactor to make it less fragile
// if (mViewerObject && RenderReflectionProbeLevel > 0)
// { // not an automatic probe
// return true;
// }
if (mViewerObject && RenderReflectionProbeLevel > 0)
{ // not an automatic probe
// if (RenderReflectionProbeLevel == 3)
// { // all automatics are relevant
// return true;
// }
// if (RenderReflectionProbeLevel == 2)
// { // terrain and water only, ignore probes that have a group
// return !mGroup;
// }
// // no automatic probes, yes manual probes
// return mViewerObject != nullptr;
// Implied logic: a probe has a group if it is either a manual or automatic, it has an object if it is manual
// hasGroup hasObject (in parenthesis means condition not checked)
// Manual true true
// Terrain/Water false (false)
// Automatic true false
const bool is_manual = mViewerObject != nullptr ;
const bool is_automatic = mGroup != nullptr && !is_manual;
const bool is_terrain = mGroup == nullptr;
switch (sRenderReflectionProbeLevel)
{
case (S32)ProbeLevel::NONE:
// no probes are relevant
return false;
case (S32)ProbeLevel::MANUAL_ONLY:
// only manual probes are relevant
return is_manual;
case (S32)ProbeLevel::MANUAL_AND_TERRAIN:
// manual probes and terrain/water probes are relevant
return !is_automatic;
case (S32)ProbeLevel::FULL_SCENE_WITH_AUTO:
// all probes are relevant
return true;
default:
LL_WARNS() << "Unknown RenderReflectionProbeLevel: " << (S32)sRenderReflectionProbeLevel()
<< " - returning false" << LL_ENDL;
return false;
}
if (RenderReflectionProbeLevel == 3)
{ // all automatics are relevant
return true;
}
if (RenderReflectionProbeLevel == 2)
{ // terrain and water only, ignore probes that have a group
return !mGroup;
}
// no automatic probes, yes manual probes
return mViewerObject != nullptr;
// </FS:Beq>
}

View File

@ -44,6 +44,13 @@ public:
IRRADIANCE,
REFLECTION
};
enum class ProbeLevel
{
NONE = 0,
MANUAL_ONLY,
MANUAL_AND_TERRAIN,
FULL_SCENE_WITH_AUTO
};
// allocate an environment map of the given resolution
LLReflectionMap();

View File

@ -628,6 +628,12 @@ void LLReflectionMapManager::getReflectionMaps(std::vector<LLReflectionMap*>& ma
LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* group)
{
// <FS:Beq> [FIRE-35070] Don't register probes if we're not using them
if( LLPipeline::sReflectionProbeLevel == (S32)LLReflectionMap::ProbeLevel::NONE)
{
return nullptr;
}
// </FS:Beq>
if (!group)
{
return nullptr;
@ -648,7 +654,10 @@ LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* gr
LLReflectionMap* LLReflectionMapManager::registerViewerObject(LLViewerObject* vobj)
{
if (!LLPipeline::sReflectionProbesEnabled)
// <FS:Beq> [FIRE-35070] Don't register manual probes if we're not using them
// if (!LLPipeline::sReflectionProbesEnabled)
if (LLPipeline::sReflectionProbeLevel == (S32)LLReflectionMap::ProbeLevel::NONE)
// </FS:Beq>
{
return nullptr;
}
@ -1387,8 +1396,7 @@ void renderReflectionProbe(LLReflectionMap* probe, std::map<LLSpatialGroup*, int
gGL.begin(gGL.POINTS);
gGL.vertex3fv(po);
gGL.end();
gGL.flush();
gGL.flush();
}
#if 0

View File

@ -1357,6 +1357,12 @@ U32 LLViewerRegion::getNumOfVisibleGroups() const
void LLViewerRegion::updateReflectionProbes(bool full_update)
{
// [FIRE-35070] Don't update reflection probes if disabled
if (LLPipeline::sReflectionProbeLevel == (S32)LLReflectionMap::ProbeLevel::NONE)
{
return; // no probes
}
// </FS:Beq>
if (!full_update && mReflectionMaps.empty())
{
return;

View File

@ -352,6 +352,7 @@ bool LLPipeline::sRenderAttachedLights = true;
bool LLPipeline::sRenderAttachedParticles = true;
bool LLPipeline::sRenderDeferred = false;
bool LLPipeline::sReflectionProbesEnabled = false;
S32 LLPipeline::sReflectionProbeLevel = (S32)LLReflectionMap::ProbeLevel::NONE; // <FS:Beq/> [FIRE-35070] Address progressive FPS loss.
S32 LLPipeline::sVisibleLightCount = 0;
bool LLPipeline::sRenderingHUDs;
F32 LLPipeline::sDistortionWaterClipPlaneMargin = 1.0125f;
@ -1263,8 +1264,10 @@ void LLPipeline::refreshCachedSettings()
RenderMirrors = gSavedSettings.getBOOL("RenderMirrors");
RenderHeroProbeUpdateRate = gSavedSettings.getS32("RenderHeroProbeUpdateRate");
RenderHeroProbeConservativeUpdateMultiplier = gSavedSettings.getS32("RenderHeroProbeConservativeUpdateMultiplier");
sReflectionProbesEnabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionsEnabled") && gSavedSettings.getBOOL("RenderReflectionsEnabled");
// <FS:Beq> [FIRE-35070] Instead of using the above we'll add a new static level variable to save some lookups. Making the above "work" with ProbeLevel will break everything.
sReflectionProbeLevel = gSavedSettings.getS32("RenderReflectionProbeLevel");
// <FS:Beq/>
RenderSpotLight = nullptr;
if (gNonInteractive)

View File

@ -690,6 +690,9 @@ public:
static bool sRenderAttachedParticles;
static bool sRenderDeferred;
static bool sReflectionProbesEnabled;
// <FS:Beq> [FIRE-35070] Address gradual slowdown issue
static S32 sReflectionProbeLevel;
// </FS:Beq>
static S32 sVisibleLightCount;
static bool sRenderingHUDs;
static F32 sDistortionWaterClipPlaneMargin;