summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorJonathan "Geenz" Goodman <geenz@lindenlab.com>2025-03-21 09:33:23 -0400
committerGitHub <noreply@github.com>2025-03-21 09:33:23 -0400
commit32c7d3064f04899547ee4dea48969c6ceb8554e9 (patch)
tree3e3fa3af0921e5422b988696c61a4718d6be1b59 /indra
parent3c96bd2c69865cba00a7e8f30afde23d2dadce78 (diff)
Dynamic Probe Allocation (#3787)
* #3788 Support dynamic probe allocation. * #3738 Mitigate probe flashing * #3735 Mitigate realtime probes flashing
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl1
-rw-r--r--indra/newview/featuretable.txt14
-rw-r--r--indra/newview/featuretable_mac.txt10
-rw-r--r--indra/newview/llreflectionmap.cpp3
-rw-r--r--indra/newview/llreflectionmapmanager.cpp86
-rw-r--r--indra/newview/llreflectionmapmanager.h11
-rw-r--r--indra/newview/lltextureview.cpp4
-rw-r--r--indra/newview/llviewertexture.cpp7
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml17
9 files changed, 87 insertions, 66 deletions
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
index 205d4bff6d..5089b9e31e 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
@@ -154,6 +154,7 @@ void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, ou
if (classic_mode < 1)
{
amblit = srgb_to_linear(amblit);
+ amblit = vec3(dot(amblit, vec3(0.2126, 0.7152, 0.0722)));
sunlit = srgb_to_linear(sunlit);
}
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index 883963d558..443a7ae914 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -86,7 +86,6 @@ RenderTonemapType 1 1
RenderTonemapMix 1 1
RenderDisableVintageMode 1 1
RenderMaxTextureResolution 1 2048
-RenderReflectionProbeCount 1 256
//
// Low Graphics Settings
@@ -129,7 +128,6 @@ RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderDisableVintageMode 1 0
RenderMaxTextureResolution 1 512
-RenderReflectionProbeCount 1 1
//
// Medium Low Graphics Settings
@@ -172,7 +170,6 @@ RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderDisableVintageMode 1 0
RenderMaxTextureResolution 1 1024
-RenderReflectionProbeCount 1 16
//
// Medium Graphics Settings (standard)
@@ -214,7 +211,6 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
-RenderReflectionProbeCount 1 32
//
// Medium High Graphics Settings
@@ -245,7 +241,7 @@ RenderFSAASamples 1 1
RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 1
RenderScreenSpaceReflections 1 0
-RenderReflectionProbeLevel 1 2
+RenderReflectionProbeLevel 1 1
RenderMirrors 1 0
RenderHeroProbeResolution 1 512
RenderHeroProbeDistance 1 6
@@ -256,7 +252,6 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
-RenderReflectionProbeCount 1 64
//
// High Graphics Settings (SSAO + sun shadows)
@@ -287,7 +282,7 @@ RenderFSAASamples 1 2
RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 1
RenderScreenSpaceReflections 1 0
-RenderReflectionProbeLevel 1 3
+RenderReflectionProbeLevel 1 2
RenderMirrors 1 0
RenderHeroProbeResolution 1 512
RenderHeroProbeDistance 1 8
@@ -298,7 +293,6 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
-RenderReflectionProbeCount 1 128
//
// High Ultra Graphics Settings (deferred + SSAO + all shadows)
@@ -340,7 +334,6 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
-RenderReflectionProbeCount 1 256
//
// Ultra graphics (REALLY PURTY!)
@@ -382,7 +375,6 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
-RenderReflectionProbeCount 1 256
//
// Class Unknown Hardware (unknown)
@@ -416,7 +408,6 @@ RenderReflectionProbeDetail 0 -1
RenderMirrors 0 0
RenderDisableVintageMode 1 0
RenderMaxTextureResolution 1 2048
-RenderReflectionProbeCount 0 0
list Intel
RenderAnisotropic 1 0
@@ -438,7 +429,6 @@ RenderMirrors 0 0
RenderGLMultiThreadedTextures 0 0
RenderGLMultiThreadedMedia 0 0
RenderDisableVintageMode 1 0
-RenderReflectionProbeCount 0 0
list TexUnit16orLess
RenderTerrainPBRDetail 1 -1
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 103d24a26d..dc9473b042 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -86,7 +86,6 @@ RenderTonemapMix 1 1
RenderDisableVintageMode 1 1
RenderDownScaleMethod 1 0
RenderMaxTextureResolution 1 2048
-RenderReflectionProbeCount 1 256
//
// Low Graphics Settings
@@ -129,7 +128,6 @@ RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderDisableVintageMode 1 0
RenderMaxTextureResolution 1 512
-RenderReflectionProbeCount 1 1
//
// Medium Low Graphics Settings
@@ -172,7 +170,6 @@ RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderDisableVintageMode 1 0
RenderMaxTextureResolution 1 1024
-RenderReflectionProbeCount 1 16
//
// Medium Graphics Settings (standard)
@@ -214,7 +211,6 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
-RenderReflectionProbeCount 1 32
//
// Medium High Graphics Settings
@@ -256,7 +252,6 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
-RenderReflectionProbeCount 1 64
//
// High Graphics Settings (SSAO + sun shadows)
@@ -298,7 +293,6 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
-RenderReflectionProbeCount 1 128
//
// High Ultra Graphics Settings (SSAO + all shadows)
@@ -340,7 +334,6 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
-RenderReflectionProbeCount 1 256
//
// Ultra graphics (REALLY PURTY!)
@@ -382,7 +375,6 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
-RenderReflectionProbeCount 1 256
//
// Class Unknown Hardware (unknown)
@@ -415,7 +407,6 @@ RenderShadowDetail 0 0
RenderMirrors 0 0
RenderDisableVintageMode 1 0
RenderMaxTextureResolution 1 2048
-RenderReflectionProbeCount 0 0
list TexUnit8orLess
RenderDeferredSSAO 0 0
@@ -456,7 +447,6 @@ RenderReflectionProbeDetail 0 0
RenderReflectionsEnabled 0 0
RenderMirrors 0 0
RenderDisableVintageMode 1 0
-RenderReflectionProbeCount 0 0
list VaryingVectors16orLess
RenderTerrainPBRPlanarSampleCount 1 1
diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp
index f3adb52d5e..910509928d 100644
--- a/indra/newview/llreflectionmap.cpp
+++ b/indra/newview/llreflectionmap.cpp
@@ -52,6 +52,9 @@ LLReflectionMap::~LLReflectionMap()
void LLReflectionMap::update(U32 resolution, U32 face, bool force_dynamic, F32 near_clip, bool useClipPlane, LLPlane clipPlane)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ if (!mCubeArray.notNull())
+ return;
+
mLastUpdateTime = gFrameTimeSeconds;
llassert(mCubeArray.notNull());
llassert(mCubeIndex != -1);
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index 48b73531ea..34c6034e9e 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -144,13 +144,14 @@ static void touch_default_probe(LLReflectionMap* probe)
LLReflectionMapManager::LLReflectionMapManager()
{
+ mDynamicProbeCount = LL_MAX_REFLECTION_PROBE_COUNT;
initCubeFree();
}
void LLReflectionMapManager::initCubeFree()
{
// start at 1 because index 0 is reserved for mDefaultProbe
- for (int i = 1; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i)
+ for (U32 i = 1; i < mDynamicProbeCount; ++i)
{
mCubeFree.push_back(i);
}
@@ -221,15 +222,50 @@ void LLReflectionMapManager::update()
resume();
}
- static LLCachedControl<U32> probe_count(gSavedSettings, "RenderReflectionProbeCount", 256U);
- bool countReset = mReflectionProbeCount != probe_count;
+ static LLCachedControl<S32> sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1);
+ static LLCachedControl<S32> sLevel(gSavedSettings, "RenderReflectionProbeLevel", 3);
- if (countReset)
+ // Once every 20 frames, update the dynamic probe count.
+ if (gFrameCount % 20)
{
- mResetFade = -0.5f;
+ U32 probe_count_temp = mDynamicProbeCount;
+ if (sLevel == 0)
+ {
+ mDynamicProbeCount = 1;
+ }
+ else if (sLevel == 1)
+ {
+ mDynamicProbeCount = (U32)mProbes.size();
+
+ }
+ else if (sLevel == 2)
+ {
+ mDynamicProbeCount = llmax((U32)mProbes.size(), 128);
+ }
+ else
+ {
+ mDynamicProbeCount = 256;
+ }
+
+ // Round mDynamicProbeCount to the nearest increment of 32
+ mDynamicProbeCount = ((mDynamicProbeCount + 16) / 32) * 32;
+ mDynamicProbeCount = llclamp(mDynamicProbeCount, 1, LL_MAX_REFLECTION_PROBE_COUNT);
+
+ if (mDynamicProbeCount < probe_count_temp * 1.1 && mDynamicProbeCount > probe_count_temp * 0.9)
+ mDynamicProbeCount = probe_count_temp;
+ else
+ mGlobalFadeTarget = 0.f;
}
- initReflectionMaps();
+ if (mGlobalFadeTarget < mResetFade)
+ mResetFade = llmax(mGlobalFadeTarget, mResetFade - (F32)gFrameIntervalSeconds * 2);
+ else
+ mResetFade = llmin(mGlobalFadeTarget, mResetFade + (F32)gFrameIntervalSeconds * 2);
+
+ if (mResetFade == mGlobalFadeTarget)
+ {
+ initReflectionMaps();
+ }
static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true);
@@ -286,9 +322,6 @@ void LLReflectionMapManager::update()
bool did_update = false;
- static LLCachedControl<S32> sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1);
- static LLCachedControl<S32> sLevel(gSavedSettings, "RenderReflectionProbeLevel", 3);
-
bool realtime = sDetail >= (S32)LLReflectionMapManager::DetailLevel::REALTIME;
LLReflectionMap* closestDynamic = nullptr;
@@ -343,12 +376,7 @@ void LLReflectionMapManager::update()
}
}
- if (countReset)
- {
- mResetFade = -0.5f;
- }
-
- mResetFade = llmin((F32)(mResetFade + gFrameIntervalSeconds), 1.f);
+ mResetFade = llmin((F32)(mResetFade + gFrameIntervalSeconds * 2.f), 1.f);
for (unsigned int i = 0; i < mProbes.size(); ++i)
{
@@ -520,6 +548,16 @@ LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group)
return probe;
}
+U32 LLReflectionMapManager::probeCount()
+{
+ return mDynamicProbeCount;
+}
+
+U32 LLReflectionMapManager::probeMemory()
+{
+ return (mDynamicProbeCount * 6 * (mProbeResolution * mProbeResolution) * 4) / 1024 / 1024 + (mDynamicProbeCount * 6 * (LL_IRRADIANCE_MAP_RESOLUTION * LL_IRRADIANCE_MAP_RESOLUTION) * 4) / 1024 / 1024;
+}
+
struct CompareProbeDepth
{
bool operator()(const LLReflectionMap* lhs, const LLReflectionMap* rhs)
@@ -1058,7 +1096,11 @@ void LLReflectionMapManager::updateUniforms()
bool is_ambiance_pass = gCubeSnapshot && !isRadiancePass();
F32 ambscale = is_ambiance_pass ? 0.f : 1.f;
+ ambscale *= mResetFade;
+ ambscale = llmax(0, ambscale);
F32 radscale = is_ambiance_pass ? 0.5f : 1.f;
+ radscale *= mResetFade;
+ radscale = llmax(0, radscale);
for (auto* refmap : mReflectionMaps)
{
@@ -1129,8 +1171,8 @@ void LLReflectionMapManager::updateUniforms()
}
mProbeData.refParams[count].set(
- llmax(minimum_ambiance, refmap->getAmbiance())*ambscale * llmax(mResetFade, 0.f), // ambiance scale
- radscale * llmax(mResetFade, 0.f), // radiance scale
+ llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, // ambiance scale
+ radscale, // radiance scale
refmap->mFadeIn, // fade in weight
oa.getF32ptr()[2] - refmap->mRadius); // z near
@@ -1365,12 +1407,9 @@ void LLReflectionMapManager::renderDebug()
void LLReflectionMapManager::initReflectionMaps()
{
- static LLCachedControl<U32> probe_count(gSavedSettings, "RenderReflectionProbeCount", 256U);
- U32 count = probe_count();
-
static LLCachedControl<U32> ref_probe_res(gSavedSettings, "RenderReflectionProbeResolution", 128U);
U32 probe_resolution = nhpo2(llclamp(ref_probe_res(), (U32)64, (U32)512));
- if (mTexture.isNull() || mReflectionProbeCount != count || mProbeResolution != probe_resolution || mReset)
+ if (mTexture.isNull() || mReflectionProbeCount != mDynamicProbeCount || mProbeResolution != probe_resolution || mReset)
{
if(mProbeResolution != probe_resolution)
{
@@ -1379,9 +1418,10 @@ void LLReflectionMapManager::initReflectionMaps()
}
gEXRImage = nullptr;
-
+ mGlobalFadeTarget = 1.f;
+ mResetFade = -0.125f;
mReset = false;
- mReflectionProbeCount = count;
+ mReflectionProbeCount = mDynamicProbeCount;
mProbeResolution = probe_resolution;
mMaxProbeLOD = log2f((F32)mProbeResolution) - 1.f; // number of mips - 1
diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h
index 9f88776ac2..0719c28134 100644
--- a/indra/newview/llreflectionmapmanager.h
+++ b/indra/newview/llreflectionmapmanager.h
@@ -38,7 +38,7 @@ class LLViewerObject;
#define LL_MAX_REFLECTION_PROBE_COUNT 256
// reflection probe resolution
-#define LL_IRRADIANCE_MAP_RESOLUTION 64
+#define LL_IRRADIANCE_MAP_RESOLUTION 16
// reflection probe mininum scale
#define LL_REFLECTION_PROBE_MINIMUM_SCALE 1.f;
@@ -159,6 +159,9 @@ public:
// with false when done.
void forceDefaultProbeAndUpdateUniforms(bool force = true);
+ U32 probeCount();
+ U32 probeMemory();
+
private:
friend class LLPipeline;
friend class LLHeroProbeManager;
@@ -166,6 +169,9 @@ private:
// initialize mCubeFree array to default values
void initCubeFree();
+ // Just does a bulk clear of all of the cubemaps.
+ void clearCubeMaps();
+
// delete the probe with the given index in mProbes
void deleteProbe(U32 i);
@@ -240,6 +246,8 @@ private:
// number of reflection probes to use for rendering
U32 mReflectionProbeCount;
+ U32 mDynamicProbeCount;
+
// resolution of reflection probes
U32 mProbeResolution = 128;
@@ -253,6 +261,7 @@ private:
bool mReset = false;
float mResetFade = 1.f;
+ float mGlobalFadeTarget = 1.f;
// if true, only update the default probe
bool mPaused = false;
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 78d930c05c..8560a01c4b 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -559,10 +559,12 @@ void LLGLTexMemBar::draw()
gGL.color4f(0.f, 0.f, 0.f, 0.25f);
gl_rect_2d(-10, getRect().getHeight() + line_height*2 + 1, getRect().getWidth()+2, getRect().getHeight()+2);
- text = llformat("Est. Free: %d MB Sys Free: %d MB FBO: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
+ text = llformat("Est. Free: %d MB Sys Free: %d MB FBO: %d MB Probe#: %d Probe Mem: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
(S32)LLViewerTexture::sFreeVRAMMegabytes,
LLMemory::getAvailableMemKB()/1024,
LLRenderTarget::sBytesAllocated/(1024*1024),
+ gPipeline.mReflectionMapManager.probeCount(),
+ gPipeline.mReflectionMapManager.probeMemory(),
discard_bias,
cache_usage,
cache_max_usage);
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 0782192858..4a9dd1c1b6 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -504,8 +504,11 @@ void LLViewerTexture::updateClass()
// NOTE: our metrics miss about half the vram we use, so this biases high but turns out to typically be within 5% of the real number
F32 used = (F32)ll_round(texture_bytes_alloc + vertex_bytes_alloc);
- F32 budget = max_vram_budget == 0 ? (F32)gGLManager.mVRAM : (F32)max_vram_budget;
- budget /= tex_vram_divisor;
+ // For debugging purposes, it's useful to be able to set the VRAM budget manually.
+ // But when manual control is not enabled, use the VRAM divisor.
+ // While we're at it, assume we have 1024 to play with at minimum when the divisor is in use. Works more elegantly with the logic below this.
+ // -Geenz 2025-03-21
+ F32 budget = max_vram_budget == 0 ? llmax(1024, (F32)gGLManager.mVRAM / tex_vram_divisor) : (F32)max_vram_budget;
// Try to leave at least half a GB for everyone else and for bias,
// but keep at least 768MB for ourselves
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index 34ed3fa80d..78d13293a8 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
@@ -859,23 +859,6 @@
</combo_box>
<slider
- control_name="RenderReflectionProbeCount"
- decimal_digits="0"
- follows="left|top"
- height="16"
- increment="1"
- initial_value="256"
- label="Max. Reflection Probes:"
- label_width="145"
- layout="topleft"
- left="420"
- min_val="1"
- max_val="256"
- name="MaxProbes"
- top_delta="24"
- width="260" />
-
- <slider
control_name="RenderExposure"
decimal_digits="1"
follows="left|top"