summaryrefslogtreecommitdiff
path: root/indra/newview/llviewertexture.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llviewertexture.cpp')
-rw-r--r--indra/newview/llviewertexture.cpp129
1 files changed, 70 insertions, 59 deletions
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 36b6787ace..5ba0a86e68 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -87,6 +87,7 @@ S32 LLViewerTexture::sRawCount = 0;
S32 LLViewerTexture::sAuxCount = 0;
LLFrameTimer LLViewerTexture::sEvaluationTimer;
F32 LLViewerTexture::sDesiredDiscardBias = 0.f;
+U32 LLViewerTexture::sBiasTexturesUpdated = 0;
S32 LLViewerTexture::sMaxSculptRez = 128; //max sculpt image size
constexpr S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64;
@@ -107,12 +108,6 @@ LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTextur
const F64 log_2 = log(2.0);
-#if ADDRESS_SIZE == 32
-const U32 DESIRED_NORMAL_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT / 2;
-#else
-const U32 DESIRED_NORMAL_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT;
-#endif
-
//----------------------------------------------------------------------------------------------
//namespace: LLViewerTextureAccess
//----------------------------------------------------------------------------------------------
@@ -494,7 +489,12 @@ void LLViewerTexture::updateClass()
}
LLViewerMediaTexture::updateClass();
-
+ // This is a divisor used to determine how much VRAM from our overall VRAM budget to use.
+ // This is **cumulative** on whatever the detected or manually set VRAM budget is.
+ // If we detect 2048MB of VRAM, this will, by default, only use 1024.
+ // If you set 1024MB of VRAM, this will, by default, use 512.
+ // -Geenz 2025-03-03
+ static LLCachedControl<U32> tex_vram_divisor(gSavedSettings, "RenderTextureVRAMDivisor", 2);
static LLCachedControl<U32> max_vram_budget(gSavedSettings, "RenderMaxVRAMBudget", 0);
F64 texture_bytes_alloc = LLImageGL::getTextureBytesAllocated() / 1024.0 / 512.0;
@@ -504,7 +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;
+ // 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
@@ -556,18 +560,20 @@ void LLViewerTexture::updateClass()
// don't execute above until the slam to 1.5 has a chance to take effect
sEvaluationTimer.reset();
- // lower discard bias over time when free memory is available
- if (sDesiredDiscardBias > 1.f && over_pct < 0.f)
+ // lower discard bias over time when at least 10% of budget is free
+ const F32 FREE_PERCENTAGE_TRESHOLD = -0.1f;
+ if (sDesiredDiscardBias > 1.f && over_pct < FREE_PERCENTAGE_TRESHOLD)
{
static LLCachedControl<F32> high_mem_discard_decrement(gSavedSettings, "RenderHighMemMinDiscardDecrement", .1f);
- F32 decrement = high_mem_discard_decrement - llmin(over_pct, 0.f);
+ F32 decrement = high_mem_discard_decrement - llmin(over_pct - FREE_PERCENTAGE_TRESHOLD, 0.f);
sDesiredDiscardBias -= decrement * gFrameIntervalSeconds;
}
}
// set to max discard bias if the window has been backgrounded for a while
static F32 last_desired_discard_bias = 1.f;
+ static F32 last_texture_update_count_bias = 1.f;
static bool was_backgrounded = false;
static LLFrameTimer backgrounded_timer;
static LLCachedControl<F32> minimized_discard_time(gSavedSettings, "TextureDiscardMinimizedTime", 1.f);
@@ -603,6 +609,21 @@ void LLViewerTexture::updateClass()
}
sDesiredDiscardBias = llclamp(sDesiredDiscardBias, 1.f, 4.f);
+ if (last_texture_update_count_bias < sDesiredDiscardBias)
+ {
+ // bias increased, reset texture update counter to
+ // let updates happen at an increased rate.
+ last_texture_update_count_bias = sDesiredDiscardBias;
+ sBiasTexturesUpdated = 0;
+ }
+ else if (last_texture_update_count_bias > sDesiredDiscardBias + 0.1f)
+ {
+ // bias decreased, 0.1f is there to filter out small fluctuations
+ // and not reset sBiasTexturesUpdated too often.
+ // Bias jumps to 1.5 at low memory, so getting stuck at 1.1 is not
+ // a problem.
+ last_texture_update_count_bias = sDesiredDiscardBias;
+ }
LLViewerTexture::sFreezeImageUpdates = false;
}
@@ -1086,6 +1107,7 @@ void LLViewerFetchedTexture::init(bool firstinit)
mOrigHeight = 0;
mHasAux = false;
mNeedsAux = false;
+ mLastWorkerDiscardLevel = -1;
mRequestedDiscardLevel = -1;
mRequestedDownloadPriority = 0.f;
mFullyLoaded = false;
@@ -1238,12 +1260,11 @@ void LLViewerFetchedTexture::loadFromFastCache()
if (mBoostLevel == LLGLTexture::BOOST_THUMBNAIL)
{
- S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_THUMBNAIL_DIMENSIONS;
- S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_THUMBNAIL_DIMENSIONS;
- if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))
+ if (mRawImage && (mRawImage->getWidth() > DEFAULT_THUMBNAIL_DIMENSIONS || mRawImage->getHeight() > DEFAULT_THUMBNAIL_DIMENSIONS))
{
- // scale oversized icon, no need to give more work to gl
- mRawImage->scale(expected_width, expected_height);
+ // Scale oversized thumbnail
+ // thumbnails aren't supposed to go over DEFAULT_THUMBNAIL_DIMENSIONS
+ mRawImage->scale(DEFAULT_THUMBNAIL_DIMENSIONS, DEFAULT_THUMBNAIL_DIMENSIONS);
}
}
@@ -1685,6 +1706,16 @@ void LLViewerFetchedTexture::processTextureStats()
static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false);
+ U32 max_tex_res = MAX_IMAGE_SIZE_DEFAULT;
+ if (mBoostLevel < LLGLTexture::BOOST_HIGH)
+ {
+ // restrict texture resolution to download based on RenderMaxTextureResolution
+ static LLCachedControl<U32> max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048);
+ // sanity clamp debug setting to avoid settings hack shenanigans
+ max_tex_res = (U32)llclamp((U32)max_texture_resolution, 512, MAX_IMAGE_SIZE_DEFAULT);
+ mMaxVirtualSize = llmin(mMaxVirtualSize, (F32)(max_tex_res * max_tex_res));
+ }
+
if (textures_fullres)
{
mDesiredDiscardLevel = 0;
@@ -1706,10 +1737,9 @@ void LLViewerFetchedTexture::processTextureStats()
}
else
{
- U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096
if(!mKnownDrawWidth || !mKnownDrawHeight || (S32)mFullWidth <= mKnownDrawWidth || (S32)mFullHeight <= mKnownDrawHeight)
{
- if (mFullWidth > desired_size || mFullHeight > desired_size)
+ if (mFullWidth > max_tex_res || mFullHeight > max_tex_res)
{
mDesiredDiscardLevel = 1;
}
@@ -1927,9 +1957,9 @@ bool LLViewerFetchedTexture::processFetchResults(S32& desired_discard, S32 curre
bool LLViewerFetchedTexture::updateFetch()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false);
+ static LLCachedControl<bool> textures_decode_disabled(gSavedSettings, "TextureDecodeDisabled", false);
- if(textures_decode_disabled) // don't fetch the surface textures in wireframe mode
+ if (textures_decode_disabled) // don't fetch the surface textures in wireframe mode
{
return false;
}
@@ -1964,7 +1994,7 @@ bool LLViewerFetchedTexture::updateFetch()
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - callback pending");
return false; // process any raw image data in callbacks before replacing
}
- if(mInFastCacheList)
+ if (mInFastCacheList)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - in fast cache");
return false;
@@ -1989,7 +2019,7 @@ bool LLViewerFetchedTexture::updateFetch()
if (mAuxRawImage.notNull()) sAuxCount--;
// keep in mind that fetcher still might need raw image, don't modify original
bool finished = LLAppViewer::getTextureFetch()->getRequestFinished(getID(), fetch_discard, mFetchState, mRawImage, mAuxRawImage,
- mLastHttpGetStatus);
+ mLastHttpGetStatus);
if (mRawImage.notNull()) sRawCount++;
if (mAuxRawImage.notNull())
{
@@ -2005,7 +2035,7 @@ bool LLViewerFetchedTexture::updateFetch()
else
{
mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
- mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
+ mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
}
if (!processFetchResults(desired_discard, current_discard, fetch_discard, decode_priority))
@@ -2016,7 +2046,7 @@ bool LLViewerFetchedTexture::updateFetch()
if (mIsFetching)
{
static const F32 MAX_HOLD_TIME = 5.0f; //seconds to wait before canceling fecthing if decode_priority is 0.f.
- if(decode_priority > 0.0f || mStopFetchingTimer.getElapsedTimeF32() > MAX_HOLD_TIME)
+ if (decode_priority > 0.0f || mStopFetchingTimer.getElapsedTimeF32() > MAX_HOLD_TIME)
{
mStopFetchingTimer.reset();
LLAppViewer::getTextureFetch()->updateRequestPriority(mID, decode_priority);
@@ -2032,7 +2062,7 @@ bool LLViewerFetchedTexture::updateFetch()
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - priority <= 0");
make_request = false;
}
- else if(mDesiredDiscardLevel > getMaxDiscardLevel())
+ else if (mDesiredDiscardLevel > getMaxDiscardLevel())
{
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - desired > max");
make_request = false;
@@ -2073,7 +2103,7 @@ bool LLViewerFetchedTexture::updateFetch()
if (make_request)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - make request");
- S32 w=0, h=0, c=0;
+ S32 w = 0, h = 0, c = 0;
if (getDiscardLevel() >= 0)
{
w = mGLTexturep->getWidth(0);
@@ -2091,18 +2121,19 @@ bool LLViewerFetchedTexture::updateFetch()
S32 fetch_request_response = -1;
S32 worker_discard = -1;
fetch_request_response = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority,
- w, h, c, desired_discard, needsAux(), mCanUseHTTP);
+ w, h, c, desired_discard, needsAux(), mCanUseHTTP);
if (fetch_request_response >= 0) // positive values and 0 are discard values
{
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - request created");
mHasFetcher = true;
mIsFetching = true;
+ mLastWorkerDiscardLevel = worker_discard;
// in some cases createRequest can modify discard, as an example
// bake textures are always at discard 0
mRequestedDiscardLevel = llmin(desired_discard, fetch_request_response);
mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
- mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
+ mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
}
else if (fetch_request_response == LLTextureFetch::CREATE_REQUEST_ERROR_TRANSITION)
{
@@ -2116,7 +2147,7 @@ bool LLViewerFetchedTexture::updateFetch()
S32 decoded_discard;
bool decoded;
S32 fetch_state = LLAppViewer::getTextureFetch()->getLastFetchState(mID, desired_discard, decoded_discard, decoded);
- if (fetch_state > 1 && decoded && decoded_discard >=0 && decoded_discard <= desired_discard)
+ if (fetch_state > 1 && decoded && decoded_discard >= 0 && decoded_discard <= desired_discard)
{
// worker actually has the image
if (mRawImage.notNull()) sRawCount--;
@@ -2740,11 +2771,9 @@ void LLViewerFetchedTexture::saveRawImage()
}
else if (mBoostLevel == LLGLTexture::BOOST_THUMBNAIL)
{
- S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_THUMBNAIL_DIMENSIONS;
- S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_THUMBNAIL_DIMENSIONS;
- if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)
+ if (mRawImage->getWidth() > DEFAULT_THUMBNAIL_DIMENSIONS || mRawImage->getHeight() > DEFAULT_THUMBNAIL_DIMENSIONS)
{
- mSavedRawImage = new LLImageRaw(expected_width, expected_height, mRawImage->getComponents());
+ mSavedRawImage = new LLImageRaw(DEFAULT_THUMBNAIL_DIMENSIONS, DEFAULT_THUMBNAIL_DIMENSIONS, mRawImage->getComponents());
mSavedRawImage->copyScaled(mRawImage);
}
else
@@ -2913,8 +2942,6 @@ LLViewerLODTexture::LLViewerLODTexture(const std::string& url, FTType f_type, co
void LLViewerLODTexture::init(bool firstinit)
{
mTexelsPerImage = 64*64;
- mDiscardVirtualSize = 0.f;
- mCalculatedDiscardLevel = -1.f;
}
//virtual
@@ -2939,12 +2966,14 @@ void LLViewerLODTexture::processTextureStats()
static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false);
- { // restrict texture resolution to download based on RenderMaxTextureResolution
+ F32 max_tex_res = MAX_IMAGE_SIZE_DEFAULT;
+ if (mBoostLevel < LLGLTexture::BOOST_HIGH)
+ {
+ // restrict texture resolution to download based on RenderMaxTextureResolution
static LLCachedControl<U32> max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048);
// sanity clamp debug setting to avoid settings hack shenanigans
- F32 tex_res = (F32)llclamp((S32)max_texture_resolution, 512, 2048);
- tex_res *= tex_res;
- mMaxVirtualSize = llmin(mMaxVirtualSize, tex_res);
+ max_tex_res = (F32)llclamp((S32)max_texture_resolution, 512, MAX_IMAGE_SIZE_DEFAULT);
+ mMaxVirtualSize = llmin(mMaxVirtualSize, max_tex_res * max_tex_res);
}
if (textures_fullres)
@@ -2993,19 +3022,12 @@ void LLViewerLODTexture::processTextureStats()
{
// Calculate the required scale factor of the image using pixels per texel
discard_level = (F32)(log(mTexelsPerImage / mMaxVirtualSize) / log_4);
- mDiscardVirtualSize = mMaxVirtualSize;
- mCalculatedDiscardLevel = discard_level;
}
discard_level = floorf(discard_level);
F32 min_discard = 0.f;
- U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096
- if (mBoostLevel <= LLGLTexture::BOOST_SCULPTED)
- {
- desired_size = DESIRED_NORMAL_TEXTURE_SIZE;
- }
- if (mFullWidth > desired_size || mFullHeight > desired_size)
+ if (mFullWidth > max_tex_res || mFullHeight > max_tex_res)
min_discard = 1.f;
discard_level = llclamp(discard_level, min_discard, (F32)MAX_DISCARD_LEVEL);
@@ -3543,18 +3565,7 @@ void LLViewerMediaTexture::setPlaying(bool playing)
for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
{
LLFace* facep = *iter;
- const LLTextureEntry* te = facep->getTextureEntry();
- if (te->getGLTFMaterial())
- {
- // PBR material, switch emissive and basecolor
- switchTexture(LLRender::EMISSIVE_MAP, *iter);
- switchTexture(LLRender::BASECOLOR_MAP, *iter);
- }
- else
- {
- // blinn-phong material, switch diffuse map only
- switchTexture(LLRender::DIFFUSE_MAP, *iter);
- }
+ switchTexture(LLRender::DIFFUSE_MAP, facep);
}
}
else //stop playing this media