FIRE-35081 - Updated logic

Cleaned up the logic to be 1, cleaner and 2, more performant.
Moved allocations outside the loop as well as the static texture_camera_boost setup as it should be only done once and not every time a face is on screen.
Cleaned up switch statements into couple of if statements as switch logic would be only good if only 1 level to be used.
master
minerjr 2025-02-22 10:46:40 -04:00
parent 7bd44050a6
commit 6a4ec7a0b4
1 changed files with 59 additions and 90 deletions

View File

@ -917,9 +917,11 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag
F32 bias = llclamp(max_discard - 2.f, 1.f, LLViewerTexture::sDesiredDiscardBias);
// convert bias into a vsize scaler
bias = (F32) llroundf(powf(4, bias - 1.f));
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
//bias = (F32) llroundf(powf(4, bias - 1.f));
// Pre-divied the bias so you can just use multiiply in the loop
bias = (F32) 1.0f / llroundf(powf(4, bias - 1.f));
// Apply new rules to bias discard, there are now 2 bias, off-screen and on-screen.
// On-screen Bias
// Only applied to LOD Textures and one that have Discard > 1 (0, 1 protected)
@ -934,11 +936,19 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag
// user complaints.
// Store a seperate max on screen vsize without bias applied.
F32 max_on_screen_vsize = 0.0f;
F32 on_screen_value = 0.0f;
F32 max_on_screen_vsize = 0.0f;
F32 importance_to_camera = 0.0f;
S32 on_screen_count = 0;
// Moved all the variables outside of the loop
bool current_on_screen = false;
F32 radius; // Moved outside the loop to save reallocation every loop
F32 cos_angle_to_view_dir; // Moved outside the loop to save reallocation every loop
F32 vsize = 0.0f; // Moved outside the loop to save reallocation every loop
F32 important_to_camera = 0.0f;
// </FS:minerjr> [FIRE-35081]
// boost resolution of textures that are important to the camera
// Can instead of using max for a min of 1.0, just subtract 1 from the boost and just do a 1 + (TextureCameraBoost - 1) * importanceToCamera)
static LLCachedControl<F32> texture_camera_boost(gSavedSettings, "TextureCameraBoost", 7.f);
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
{
@ -949,8 +959,11 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag
if (face && face->getViewerObject())
{
++face_count;
F32 radius;
F32 cos_angle_to_view_dir;
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
// Moved outside the loop to stop createing new memory every loop
//F32 radius;
//F32 cos_angle_to_view_dir;
// </FS:minerjr> [FIRE-35081]
if ((gFrameCount - face->mLastTextureUpdate) > 10)
{ // only call calcPixelArea at most once every 10 frames for a given face
@ -960,11 +973,15 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag
face->mLastTextureUpdate = gFrameCount;
}
F32 vsize = face->getPixelArea();
// Also moved allocation outside the loop
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
//F32 vsize = face->getPixelArea();
//on_screen = face->mInFrustum;
bool current_on_screen = face->mInFrustum; // Create a new var to store the current on screen status
on_screen = face->mInFrustum ? true : on_screen; // As we want to keep track of if we have an on screen image perminatly as the last face dictates if it scales or not.
vsize = face->getPixelArea();
current_on_screen = face->mInFrustum; // Create a new var to store the current on screen status
on_screen_count += current_on_screen; // Count the number of on sceen faces instead of using brach
important_to_camera = face->mImportanceToCamera; // Store so we don't have to do 2 indirects later on
// </FS:minerjr> [FIRE-35081]
// Scale desired texture resolution higher or lower depending on texture scale
@ -998,40 +1015,29 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag
max_vsize = llmax(max_vsize, vsize);
*/
// Store the vsize before the bias is applied
F32 on_screen_vsize = vsize;
// As we calculate both with and with-out bias, by doing this, you can skip the if statement in the middle of
// expensive loop
vsize /= bias;
// boost resolution of textures that are important to the camera
static LLCachedControl<F32> texture_camera_boost(gSavedSettings, "TextureCameraBoost", 8.f);
//vsize *= llmax(face->mImportanceToCamera * texture_camera_boost, 1.f);
// Use math to skip having to use a conditaional check
// Bools are stored as 0 false, 1 true, use to cheat
// Lerp instead of doing conditional input
// If the image is import to the camera, even a little then make the on screen true
on_screen = face->mImportanceToCamera > 0.0f ? true : on_screen; // This branching should be optimized away.
importance_to_camera = llmax(face->mImportanceToCamera * texture_camera_boost, 1.f);
on_screen_value = F32(current_on_screen);
vsize = lerp(vsize, vsize * importance_to_camera, on_screen_value);
// Apply the mImportanceToCamera to the on screen vsize
// Bools are stored as 0 false, 1 true, use to cheat
// Perform a LERP on the value between the on screen vsize and the importance * on screen vsize
on_screen_vsize = lerp(on_screen_vsize, on_screen_vsize * importance_to_camera, on_screen_value);
max_vsize = llmax(max_vsize, vsize);
// <FS:minerjr>
// If the image is import to the camera, even a little then make the on screen true
on_screen_count += S32(important_to_camera * 1000.0f);
importance_to_camera = 1.0f + important_to_camera * texture_camera_boost;// llmax(important_to_camera * texture_camera_boost, 1.f);
vsize = vsize + (vsize * importance_to_camera - vsize) * F32(current_on_screen); //lerp(vsize, vsize * importance_to_camera, F32(current_on_screen));
// Update the max on screen vsize based upon the on screen vsize
max_on_screen_vsize = llmax(max_on_screen_vsize, on_screen_vsize);
max_on_screen_vsize = llmax(max_on_screen_vsize, vsize);
max_vsize = llmax(max_vsize, vsize * bias);
// </FS:minerjr> [FIRE-35081]
}
}
}
// <FS:minerjr>
// Replaced all the checks for this bool to be only in this 1 place instead of in the loop.
// If the on screen counter is greater then 0, then there was at least 1 on screen texture
on_screen = bool(on_screen_count);
// <FS:minerjr>
if (face_count > 1024)
{ // this texture is used in so many places we should just boost it and not bother checking its vsize
// this is especially important because the above is not time sliced and can hit multiple ms for a single texture
@ -1048,66 +1054,29 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag
{
imagep->mMaxVirtualSize = 0.f;
}
}
}
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
//imagep->addTextureStats(max_vsize);
// Recaluclate the
on_screen_value = F32(on_screen);
// New logic block for the bias system
// Switch on the type of texture first
switch(imagep->getType())
// Fetched Textures (Non LOD normal textures) Or LOD Textures with a discard level of 0 or 1 or have a Bias < 2.0
if (imagep->getType() == LLViewerTexture::FETCHED_TEXTURE || (imagep->getType() == LLViewerTexture::LOD_TEXTURE && (imagep->getDiscardLevel() < 2 || LLViewerTexture::sDesiredDiscardBias < 2.0f)))
{
// All dynamic or local textures block
case LLViewerTexture::DYNAMIC_TEXTURE:
case LLViewerTexture::LOCAL_TEXTURE:
case LLViewerTexture::MEDIA_TEXTURE:
{
// Only apply the max on screen virtual size to textures that should not be scaled
imagep->addTextureStats(max_on_screen_vsize);
break;
}
// Fetched Textures (Non LOD normal textures)
case LLViewerTexture::FETCHED_TEXTURE:
{
// Only apply the bias when off screen, otherwise use the non bias caculated value
imagep->addTextureStats(lerp(max_vsize, max_on_screen_vsize, on_screen_value));
break;
}
// Handle the LOD texture
case LLViewerTexture::LOD_TEXTURE:
{
// Switch on the get discard level
switch(imagep->getDiscardLevel())
{
// We want the 2 best quality discards to always be good quality
case 0:
case 1:
{
// If the texture is really in screen, use the max on screen virtual size, otherwise the max virtual size (off-screen) use the Lerp to
// instead of if statement
imagep->addTextureStats(lerp(max_vsize, max_on_screen_vsize, on_screen_value));
break;
}
// All other discard levels (2 to MAX_DISCARD_LEVEL)
default:
{
// If the discard level is between 1 and 2
if (LLViewerTexture::sDesiredDiscardBias >= 1.0f && LLViewerTexture::sDesiredDiscardBias < 2.0f)
{
// Only apply the bias when off screen, otherwise use the non bias caculated value
imagep->addTextureStats(lerp(max_vsize, max_on_screen_vsize, on_screen_value));
}
else
{
// Apply the off screen texture max virtual size
imagep->addTextureStats(max_vsize);
}
break;
}
}
break;
}
// Perform Lerp without function call
max_vsize = max_vsize + (max_on_screen_vsize - max_vsize) * F32(on_screen);
// Only apply the bias when off screen, otherwise use the non bias caculated value
imagep->addTextureStats(max_vsize);
}
// All other LOD texture textures
else if (imagep->getType() == LLViewerTexture::LOD_TEXTURE)
{
// Apply the off screen texture max virtual size
imagep->addTextureStats(max_vsize);
}
// All dynamic or local textures block
else
{
// Only apply the max on screen virtual size to textures that should not be scaled
imagep->addTextureStats(max_on_screen_vsize);
}
// </FS:minerjr> [FIRE-35081]
}