From 32c7d3064f04899547ee4dea48969c6ceb8554e9 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Fri, 21 Mar 2025 09:33:23 -0400 Subject: Dynamic Probe Allocation (#3787) * #3788 Support dynamic probe allocation. * #3738 Mitigate probe flashing * #3735 Mitigate realtime probes flashing --- indra/newview/llreflectionmapmanager.cpp | 86 +++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 23 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') 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 probe_count(gSavedSettings, "RenderReflectionProbeCount", 256U); - bool countReset = mReflectionProbeCount != probe_count; + static LLCachedControl sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1); + static LLCachedControl 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 render_hdr(gSavedSettings, "RenderHDREnabled", true); @@ -286,9 +322,6 @@ void LLReflectionMapManager::update() bool did_update = false; - static LLCachedControl sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1); - static LLCachedControl 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 probe_count(gSavedSettings, "RenderReflectionProbeCount", 256U); - U32 count = probe_count(); - static LLCachedControl 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 -- cgit v1.2.3 From 5e5d466628f3576bb48b63f143502ea914f79bca Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Mon, 24 Mar 2025 17:59:13 -0400 Subject: Readd probe count setting (#3793) * Readd max probe count. Disable dynamic probe allocation by default (for now). --- indra/newview/llreflectionmapmanager.cpp | 90 +++++++++++++++++++------------- 1 file changed, 53 insertions(+), 37 deletions(-) (limited to 'indra/newview/llreflectionmapmanager.cpp') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 34c6034e9e..f2abc7b8b7 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -224,48 +224,54 @@ void LLReflectionMapManager::update() static LLCachedControl sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1); static LLCachedControl sLevel(gSavedSettings, "RenderReflectionProbeLevel", 3); + static LLCachedControl sReflectionProbeCount(gSavedSettings, "RenderReflectionProbeCount", 256U); + static LLCachedControl sProbeDynamicAllocation(gSavedSettings, "RenderReflectionProbeDynamicAllocation", -1); + mResetFade = llmin((F32)(mResetFade + gFrameIntervalSeconds * 2.f), 1.f); - // Once every 20 frames, update the dynamic probe count. - if (gFrameCount % 20) { U32 probe_count_temp = mDynamicProbeCount; - if (sLevel == 0) - { - mDynamicProbeCount = 1; - } - else if (sLevel == 1) + if (sProbeDynamicAllocation > -1) { - mDynamicProbeCount = (U32)mProbes.size(); + 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; + } - } - else if (sLevel == 2) - { - mDynamicProbeCount = llmax((U32)mProbes.size(), 128); + if (sProbeDynamicAllocation > 1) + { + // Round mDynamicProbeCount to the nearest increment of 16 + mDynamicProbeCount = ((mDynamicProbeCount + sProbeDynamicAllocation / 2) / sProbeDynamicAllocation) * 16; + mDynamicProbeCount = llclamp(mDynamicProbeCount, 1, sReflectionProbeCount); + } + else + { + mDynamicProbeCount = llclamp(mDynamicProbeCount + sProbeDynamicAllocation, 1, sReflectionProbeCount); + } } else { - mDynamicProbeCount = 256; + mDynamicProbeCount = sReflectionProbeCount; } - // Round mDynamicProbeCount to the nearest increment of 32 - mDynamicProbeCount = ((mDynamicProbeCount + 16) / 32) * 32; - mDynamicProbeCount = llclamp(mDynamicProbeCount, 1, LL_MAX_REFLECTION_PROBE_COUNT); + mDynamicProbeCount = llmin(mDynamicProbeCount, 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; + if (mDynamicProbeCount != probe_count_temp) + mResetFade = 1.f; } - if (mGlobalFadeTarget < mResetFade) - mResetFade = llmax(mGlobalFadeTarget, mResetFade - (F32)gFrameIntervalSeconds * 2); - else - mResetFade = llmin(mGlobalFadeTarget, mResetFade + (F32)gFrameIntervalSeconds * 2); - - if (mResetFade == mGlobalFadeTarget) - { - initReflectionMaps(); - } + initReflectionMaps(); static LLCachedControl render_hdr(gSavedSettings, "RenderHDREnabled", true); @@ -356,6 +362,7 @@ void LLReflectionMapManager::update() probe->mCubeArray = nullptr; probe->mCubeIndex = -1; probe->mComplete = false; + probe->mFadeIn = 0; } } @@ -1418,8 +1425,6 @@ void LLReflectionMapManager::initReflectionMaps() } gEXRImage = nullptr; - mGlobalFadeTarget = 1.f; - mResetFade = -0.125f; mReset = false; mReflectionProbeCount = mDynamicProbeCount; mProbeResolution = probe_resolution; @@ -1429,15 +1434,25 @@ void LLReflectionMapManager::initReflectionMaps() mTexture->getWidth() != mProbeResolution || mReflectionProbeCount + 2 != mTexture->getCount()) { - mTexture = new LLCubeMapArray(); + if (mTexture) + { + mTexture = new LLCubeMapArray(*mTexture, mProbeResolution, mReflectionProbeCount + 2); - static LLCachedControl render_hdr(gSavedSettings, "RenderHDREnabled", true); + mIrradianceMaps = new LLCubeMapArray(*mIrradianceMaps, LL_IRRADIANCE_MAP_RESOLUTION, mReflectionProbeCount); + } + else + { + mTexture = new LLCubeMapArray(); + + static LLCachedControl render_hdr(gSavedSettings, "RenderHDREnabled", true); - // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source) - mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2, true, render_hdr); + // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation + // source) + mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2, true, render_hdr); - mIrradianceMaps = new LLCubeMapArray(); - mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, false, render_hdr); + mIrradianceMaps = new LLCubeMapArray(); + mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, false, render_hdr); + } } // reset probe state @@ -1457,6 +1472,7 @@ void LLReflectionMapManager::initReflectionMaps() probe->mCubeArray = nullptr; probe->mCubeIndex = -1; probe->mNeighbors.clear(); + probe->mFadeIn = 0; } mCubeFree.clear(); -- cgit v1.2.3