From 0a1690418f1ce6b66635bafe3f8dfecda69c9f8c Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Wed, 27 May 2026 20:37:50 -0400 Subject: Some additional texture streaming tweaks - more intelligently discard rather than assuming 1x1 is where we need to be at 1 --- indra/newview/app_settings/settings.xml | 24 +++++++++++++++++++++++- indra/newview/llviewercontrol.cpp | 6 ++++++ indra/newview/llviewertexture.cpp | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 38de81a51f..e4f5f0b6d4 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -8060,7 +8060,7 @@ RenderTextureQuality Comment - Texture quality preset: 0=Low, 1=Medium, 2=High, 3=Ultra. Drives RenderMaxTextureResolution, the four TextureChannel* exponents, and TextureDistanceDiscardPower. + Texture quality preset: 0=Low, 1=Medium, 2=High, 3=Ultra. Drives RenderMaxTextureResolution, the four TextureChannel* exponents, TextureDistanceDiscardPower, and TextureScreenSizeOversample. Persist 1 Type @@ -12147,6 +12147,28 @@ Value 1.0 + TextureScreenSizeOversample + + Comment + Texels per screen pixel kept by the per-texture pixel-area discard cap. 1.0 = 1:1 with on-screen contribution; higher = sharper distant textures, more VRAM. Driven by RenderTextureQuality. + Persist + 1 + Type + F32 + Value + 1.5 + + TextureScreenSizeOversampleUnderPressure + + Comment + Floor that TextureScreenSizeOversample collapses toward as the pressure multiplier walks up. Pinned to this value above TextureMemoryHighWaterMark. Lower = allow distant textures to drop below their on-screen contribution under pressure. + Persist + 1 + Type + F32 + Value + 0.5 + TextureStalenessIntervalSeconds Comment diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index a4a7f1fd20..bb868b950b 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -124,25 +124,30 @@ static bool handleRenderTextureQualityChanged(const LLSD& newvalue) F32 ch_specular = 0.5f; F32 ch_emissive = 0.75f; F32 distance_power = 0.5f; + F32 screen_oversample = 1.5f; switch (quality) { case 0: // Low max_res = 1024; ch_normal = 0.5f; ch_basecolor = 0.75f; ch_specular = 0.1f; ch_emissive = 0.5f; distance_power = 0.15f; + screen_oversample = 0.75f; break; case 1: // Medium ch_normal = 0.75f; ch_basecolor = 0.75f; ch_specular = 0.3f; ch_emissive = 0.75f; distance_power = 0.25f; + screen_oversample = 1.0f; break; case 2: // High // channel defaults above distance_power = 0.35f; + screen_oversample = 1.5f; break; case 3: // Ultra default: ch_normal = 1.f; ch_basecolor = 1.f; ch_specular = 1.f; ch_emissive = 1.f; distance_power = 0.5f; + screen_oversample = 2.0f; break; } gSavedSettings.setU32("RenderMaxTextureResolution", max_res); @@ -151,6 +156,7 @@ static bool handleRenderTextureQualityChanged(const LLSD& newvalue) gSavedSettings.setF32("TextureChannelSpecular", ch_specular); gSavedSettings.setF32("TextureChannelEmissive", ch_emissive); gSavedSettings.setF32("TextureDistanceDiscardPower", distance_power); + gSavedSettings.setF32("TextureScreenSizeOversample", screen_oversample); return true; } diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 82f4cc8341..2504278467 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -98,6 +98,21 @@ F32 LLViewerTexture::getMemoryPressureProgress() F32 cap = llmax((F32)max_mult, 1.0001f); return llclampf((sMemoryPressureMultiplier - 1.f) / (cap - 1.f)); } + +// Effective oversample factor for the per-texture pixel-area discard cap. +// Trends from TextureScreenSizeOversample toward +// TextureScreenSizeOversampleUnderPressure as the pressure multiplier +// walks its 0..1 range; pinned to the floor above the high water mark. +static F32 pixelCapOversampleForPressure() +{ + static LLCachedControl over_base(gSavedSettings, "TextureScreenSizeOversample", 1.5f); + static LLCachedControl over_pressure(gSavedSettings, "TextureScreenSizeOversampleUnderPressure", 0.5f); + F32 base = llmax((F32)over_base, 0.1f); + F32 floor = llclamp((F32)over_pressure, 0.1f, base); + if (LLViewerTexture::sAboveHighWater) return floor; + F32 progress = LLViewerTexture::getMemoryPressureProgress(); + return base + (floor - base) * progress; +} U32 LLViewerTexture::sBiasTexturesUpdated = 0; S32 LLViewerTexture::sMaxSculptRez = 128; //max sculpt image size @@ -3365,6 +3380,24 @@ void LLViewerLODTexture::processTextureStats() mDesiredDiscardLevel = llmin(effective_cap, (S32)discard_level); + // Pixel-area discard cap. Don't let mDesiredDiscardLevel push the + // GL resolution below the texture's largest on-screen contribution + // x an oversample factor (sharper when we have memory headroom, + // looser under pressure). Avatar bakes exempt. + if (!isAgentAvatarBoost(mBoostLevel) && mMaxOnScreenSize > 0.f && mTexelsPerImage > 0) + { + static const F64 log_4 = log(4.0); + F32 oversample = pixelCapOversampleForPressure(); + F32 visible_texels = mMaxOnScreenSize * oversample * oversample; + visible_texels = llclamp(visible_texels, (F32)MIN_IMAGE_AREA, (F32)mTexelsPerImage); + if ((F32)mTexelsPerImage > visible_texels) + { + S32 d_pixel_cap = (S32)floor(log((F32)mTexelsPerImage / visible_texels) / log_4); + d_pixel_cap = llclamp(d_pixel_cap, 0, dim_max_for_image_i); + mDesiredDiscardLevel = llmin((S32)mDesiredDiscardLevel, d_pixel_cap); + } + } + // Apply the setMinDiscardLevel cap, relaxed under VRAM pressure // (cap_relax = 1 - 1/mult: 0 at mult=1, ~0.5 at mult=2, ~0.9 at // mult=10). Caps of 0 (thumbnails) and avatar bakes are preserved. -- cgit v1.3