From be07dee32540c817f70e437cb3482695c53184b3 Mon Sep 17 00:00:00 2001 From: Rye Date: Thu, 23 Oct 2025 02:28:53 -0400 Subject: Fix low memory notification appearing incorrectly on non-windows platforms when changing graphics quality levels Signed-off-by: Rye --- indra/newview/llfeaturemanager.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'indra/newview/llfeaturemanager.cpp') diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index ba54d93c75..ac19c08be8 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -464,10 +464,9 @@ bool LLFeatureManager::loadGPUClass() mGPUClass = GPU_CLASS_5; } - #if LL_WINDOWS - const F32Gigabytes MIN_PHYSICAL_MEMORY(2); - LLMemory::updateMemoryInfo(); + #if LL_WINDOWS || LL_LINUX + const F32Gigabytes MIN_PHYSICAL_MEMORY(2); F32Gigabytes physical_mem = LLMemory::getMaxMemKB(); if (MIN_PHYSICAL_MEMORY > physical_mem && mGPUClass > GPU_CLASS_1) { -- cgit v1.3 From 5a875a61881b4109a0d33caa6039a84372b33a95 Mon Sep 17 00:00:00 2001 From: Rye Date: Tue, 28 Oct 2025 08:00:07 -0400 Subject: Rework anisotropic filtering options into a dropdown with levels for better performance tuning of low end gpu Signed-off-by: Rye --- indra/llrender/llimagegl.cpp | 1 - indra/llrender/llimagegl.h | 1 - indra/llrender/llrender.cpp | 7 ++- indra/llrender/llrender.h | 1 + indra/newview/app_settings/settings.xml | 13 +++++- indra/newview/featuretable.txt | 30 +++++++----- indra/newview/featuretable_linux.txt | 30 +++++++----- indra/newview/featuretable_mac.txt | 29 +++++++----- indra/newview/llappviewer.cpp | 2 +- indra/newview/llfeaturemanager.cpp | 5 +- .../llfloaterpreferencesgraphicsadvanced.cpp | 20 ++++++++ indra/newview/llviewercontrol.cpp | 18 ++++++-- .../en/floater_preferences_graphics_advanced.xml | 54 +++++++++++++++++----- 13 files changed, 155 insertions(+), 56 deletions(-) (limited to 'indra/newview/llfeaturemanager.cpp') diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 7757c9a13a..3165cb313b 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -138,7 +138,6 @@ U32 LLImageGL::sUniqueCount = 0; U32 LLImageGL::sBindCount = 0; S32 LLImageGL::sCount = 0; -bool LLImageGL::sGlobalUseAnisotropic = false; F32 LLImageGL::sLastFrameTime = 0.f; LLImageGL* LLImageGL::sDefaultGLTexture = NULL ; bool LLImageGL::sCompressTextures = false; diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 6b4492c09e..773b647d69 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -285,7 +285,6 @@ public: // Global memory statistics static U32 sBindCount; // Tracks number of texture binds for current frame static U32 sUniqueCount; // Tracks number of unique texture binds for current frame - static bool sGlobalUseAnisotropic; static LLImageGL* sDefaultGLTexture ; static bool sAutomatedTest; static bool sCompressTextures; //use GL texture compression diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 970a9f6975..0d7ebd4a25 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -71,6 +71,7 @@ S32 gGLViewport[4]; U32 LLRender::sUICalls = 0; U32 LLRender::sUIVerts = 0; U32 LLTexUnit::sWhiteTexture = 0; +F32 LLRender::sAnisotropicFilteringLevel = 0.f; bool LLRender::sGLCoreProfile = false; bool LLRender::sNsightDebugSupport = false; LLVector2 LLRender::sUIGLScaleFactor = LLVector2(1.f, 1.f); @@ -524,9 +525,11 @@ void LLTexUnit::setTextureFilteringOptionFast(LLTexUnit::eTextureFilterOptions o if (gGLManager.mHasAnisotropic) { - if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC) + if (option == TFO_ANISOTROPIC && LLRender::sAnisotropicFilteringLevel > 1.f) { - glTexParameterf(sGLTextureType[tex_type], GL_TEXTURE_MAX_ANISOTROPY, gGLManager.mMaxAnisotropy); + F32 aniso_level = llclamp(LLRender::sAnisotropicFilteringLevel, 1.f, gGLManager.mMaxAnisotropy); + glTexParameterf(sGLTextureType[tex_type], GL_TEXTURE_MAX_ANISOTROPY, aniso_level); + } else { diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index bc1fb3ce40..4bfc5723ee 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -489,6 +489,7 @@ public: public: static U32 sUICalls; static U32 sUIVerts; + static F32 sAnisotropicFilteringLevel; static bool sGLCoreProfile; static bool sNsightDebugSupport; static LLVector2 sUIGLScaleFactor; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 94c7a97ccc..05e3e7aaa2 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -7241,7 +7241,7 @@ RenderAnisotropic Comment - Render textures using anisotropic filtering + [OBSOLETE] Render textures using anisotropic filtering Persist 1 Type @@ -7249,6 +7249,17 @@ Value 0 + RenderAnisotropicLevel + + Comment + Anisotropic filtering strength(0(Disable), 2x, 4x, 8x, 16x + Persist + 1 + Type + U32 + Value + 0 + RenderAppleUseMultGL Comment diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 1090dd8ffb..eca58938cf 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 74 +version 75 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -27,7 +27,7 @@ version 74 // NOTE: All settings are set to the MIN of applied values, including 'all'! // list all -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 16 RenderAvatarLODFactor 1 1.0 RenderAvatarPhysicsLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 @@ -92,7 +92,7 @@ RenderReflectionProbeCount 1 256 // Low Graphics Settings // list Low -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderAvatarLODFactor 1 0 RenderAvatarPhysicsLODFactor 1 0 RenderAvatarMaxNonImpostors 1 3 @@ -135,7 +135,7 @@ RenderReflectionProbeCount 1 1 // Medium Low Graphics Settings // list LowMid -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 2 RenderAvatarLODFactor 1 0.5 RenderAvatarMaxComplexity 1 100000 RenderAvatarPhysicsLODFactor 1 0.75 @@ -178,7 +178,7 @@ RenderReflectionProbeCount 1 32 // Medium Graphics Settings (standard) // list Mid -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 2 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 200000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -220,7 +220,7 @@ RenderReflectionProbeCount 1 64 // Medium High Graphics Settings // list MidHigh -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 4 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 250000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -262,7 +262,7 @@ RenderReflectionProbeCount 1 64 // High Graphics Settings (SSAO + sun shadows) // list High -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 4 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 300000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -301,10 +301,10 @@ RenderMaxTextureResolution 1 2048 RenderReflectionProbeCount 1 128 // -// High Ultra Graphics Settings (deferred + SSAO + all shadows) +// High Ultra Graphics Settings (SSAO + all shadows) // list HighUltra -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 4 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 350000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -346,7 +346,7 @@ RenderReflectionProbeCount 1 256 // Ultra graphics (REALLY PURTY!) // list Ultra -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 8 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarPhysicsLODFactor 1 1.0 @@ -399,11 +399,17 @@ RenderDisableVintageMode 1 0 list VRAMGT512 RenderCompressTextures 1 0 +// +// AF Missing or AF < 2 +// +list AnisotropicMissing +RenderAnisotropicLevel 0 0 + // // "Default" setups for safe, low, medium, high // list safe -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarMaxComplexity 1 80000 RenderLocalLightCount 1 0 @@ -419,7 +425,7 @@ RenderMaxTextureResolution 1 2048 RenderReflectionProbeCount 0 0 list Intel -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderFSAAType 1 0 RenderFSAASamples 1 0 RenderGLContextCoreProfile 1 0 diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index c53e828020..a160161ef1 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,4 +1,4 @@ -version 33 +version 34 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -27,7 +27,7 @@ version 33 // NOTE: All settings are set to the MIN of applied values, including 'all'! // list all -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 16 RenderAvatarLODFactor 1 1.0 RenderAvatarPhysicsLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 @@ -92,7 +92,7 @@ RenderReflectionProbeCount 1 256 // Low Graphics Settings // list Low -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderAvatarLODFactor 1 0 RenderAvatarPhysicsLODFactor 1 0 RenderAvatarMaxNonImpostors 1 3 @@ -135,7 +135,7 @@ RenderReflectionProbeCount 1 1 // Medium Low Graphics Settings // list LowMid -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderAvatarLODFactor 1 0.5 RenderAvatarMaxComplexity 1 100000 RenderAvatarPhysicsLODFactor 1 0.75 @@ -178,7 +178,7 @@ RenderReflectionProbeCount 1 32 // Medium Graphics Settings (standard) // list Mid -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 2 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 200000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -220,7 +220,7 @@ RenderReflectionProbeCount 1 64 // Medium High Graphics Settings // list MidHigh -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 2 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 250000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -262,7 +262,7 @@ RenderReflectionProbeCount 1 64 // High Graphics Settings (SSAO + sun shadows) // list High -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 4 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 300000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -301,10 +301,10 @@ RenderMaxTextureResolution 1 2048 RenderReflectionProbeCount 1 128 // -// High Ultra Graphics Settings (deferred + SSAO + all shadows) +// High Ultra Graphics Settings (SSAO + all shadows) // list HighUltra -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 4 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 350000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -346,7 +346,7 @@ RenderReflectionProbeCount 1 256 // Ultra graphics (REALLY PURTY!) // list Ultra -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 8 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarPhysicsLODFactor 1 1.0 @@ -399,11 +399,17 @@ RenderDisableVintageMode 1 0 list VRAMGT512 RenderCompressTextures 1 0 +// +// AF Missing or AF < 2 +// +list AnisotropicMissing +RenderAnisotropicLevel 0 0 + // // "Default" setups for safe, low, medium, high // list safe -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarMaxComplexity 1 80000 RenderLocalLightCount 1 0 @@ -419,7 +425,7 @@ RenderMaxTextureResolution 1 2048 RenderReflectionProbeCount 0 0 list Intel -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderFSAAType 1 0 RenderFSAASamples 1 0 RenderGLContextCoreProfile 1 0 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index c3e2dd0c41..b75df5e3f2 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 73 +version 74 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -27,7 +27,7 @@ version 73 // NOTE: All settings are set to the MIN of applied values, including 'all'! // list all -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 16 RenderAvatarLODFactor 1 1.0 RenderAvatarPhysicsLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 @@ -92,7 +92,7 @@ RenderReflectionProbeCount 1 256 // Low Graphics Settings // list Low -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderAvatarLODFactor 1 0 RenderAvatarPhysicsLODFactor 1 0 RenderAvatarMaxNonImpostors 1 3 @@ -135,7 +135,7 @@ RenderReflectionProbeCount 1 1 // Medium Low Graphics Settings // list LowMid -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderAvatarLODFactor 1 0.5 RenderAvatarMaxComplexity 1 100000 RenderAvatarPhysicsLODFactor 1 0.75 @@ -178,7 +178,7 @@ RenderReflectionProbeCount 1 32 // Medium Graphics Settings (standard) // list Mid -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 2 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 200000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -220,7 +220,7 @@ RenderReflectionProbeCount 1 64 // Medium High Graphics Settings // list MidHigh -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 2 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 250000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -262,7 +262,7 @@ RenderReflectionProbeCount 1 64 // High Graphics Settings (SSAO + sun shadows) // list High -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 2 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 300000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -304,7 +304,7 @@ RenderReflectionProbeCount 1 128 // High Ultra Graphics Settings (SSAO + all shadows) // list HighUltra -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 2 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarMaxComplexity 1 350000 @@ -346,7 +346,7 @@ RenderReflectionProbeCount 1 256 // Ultra graphics (REALLY PURTY!) // list Ultra -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 4 RenderAvatarLODFactor 1 1.0 RenderAvatarPhysicsLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 @@ -400,11 +400,18 @@ RenderDisableVintageMode 1 0 list VRAMGT512 RenderCompressTextures 1 0 +// +// +// AF Missing or AF < 2 +// +list AnisotropicMissing +RenderAnisotropicLevel 0 0 + // // "Default" setups for safe, low, medium, high // list safe -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarMaxComplexity 1 80000 RenderLocalLightCount 1 0 @@ -434,7 +441,7 @@ RenderGLMultiThreadedMedia 1 0 RenderAppleUseMultGL 1 0 list Intel -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderFSAASamples 1 0 RenderGLMultiThreadedTextures 1 0 RenderGLMultiThreadedMedia 1 0 diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f2e1326e96..f3970ed1a8 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -547,7 +547,7 @@ static void settings_to_globals() LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLContextCoreProfile"); #endif LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport"); - LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic"); + LLRender::sAnisotropicFilteringLevel = static_cast(gSavedSettings.getU32("RenderAnisotropicLevel")); LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures"); LLVOVolume::sLODFactor = llclamp(gSavedSettings.getF32("RenderVolumeLODFactor"), 0.01f, MAX_LOD_FACTOR); LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f; diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index ac19c08be8..e0a3cf04ec 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -260,7 +260,6 @@ bool LLFeatureManager::loadFeatureTables() // *TODO - if I or anyone else adds something else to the skipped list // make this data driven. Put it in the feature table and parse it // correctly - mSkippedFeatures.insert("RenderAnisotropic"); mSkippedFeatures.insert("RenderGamma"); mSkippedFeatures.insert("RenderVBOEnable"); mSkippedFeatures.insert("RenderFogRatio"); @@ -709,6 +708,10 @@ void LLFeatureManager::applyBaseMasks() { maskFeatures("VRAMLT2GB"); } + if (!gGLManager.mHasAnisotropic || 2.f > gGLManager.mMaxAnisotropy) + { + maskFeatures("AnisotropicMissing"); + } if (gGLManager.mGLVersion < 3.99f) { maskFeatures("GL3"); diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp index 85c027c84e..96c2e1e1e4 100644 --- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp +++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp @@ -340,6 +340,12 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings() tonemapMix->setEnabled(is_not_vintage); exposureSlider->setEnabled(is_not_vintage); cas_slider->setEnabled(is_not_vintage); + + LLComboBox* ctrl_anisotropic = getChild("anisotropic_filter"); + if (!LLFeatureManager::instance().isFeatureAvailable("RenderAnisotropicLevel")) + { + ctrl_anisotropic->setEnabled(false); + } } void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() @@ -384,6 +390,20 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() getChildView("antialiasing restart")->setVisible(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred")); + LLComboBox* af_combo = getChild("anisotropic_filter"); + if (2.f > gGLManager.mMaxAnisotropy) { + af_combo->remove("2x"); + } + if (4.f > gGLManager.mMaxAnisotropy) { + af_combo->remove("4x"); + } + if (8.f > gGLManager.mMaxAnisotropy) { + af_combo->remove("8x"); + } + if (16.f > gGLManager.mMaxAnisotropy) { + af_combo->remove("16x"); + } + // now turn off any features that are unavailable disableUnavailableSettings(); } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 75cc76fee6..411eb3a47e 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -293,9 +293,14 @@ static bool handleLUTBufferChanged(const LLSD& newvalue) return true; } -static bool handleAnisotropicChanged(const LLSD& newvalue) +static bool handleAnisotropicFilteringChanged(const LLSD& newval) { - LLImageGL::sGlobalUseAnisotropic = newvalue.asBoolean(); + F32 val = static_cast(newval.asReal()); + if (val > gGLManager.mMaxAnisotropy) + { + val = llclamp(val, 0.f, gGLManager.mMaxAnisotropy); + } + LLRender::sAnisotropicFilteringLevel = val; LLImageGL::dirtyTexOptions(); return true; } @@ -317,6 +322,12 @@ static bool handleVSyncChanged(const LLSD& newvalue) return true; } +static bool validateAnisotropicFiltering(const LLSD& val) +{ + S32 filter_level = val.asInteger(); + return filter_level == 0 || filter_level == 2 || filter_level == 4 || filter_level == 8 || filter_level == 16; +} + static bool handleVolumeLODChanged(const LLSD& newvalue) { LLVOVolume::sLODFactor = llclamp((F32) newvalue.asReal(), 0.01f, MAX_LOD_FACTOR); @@ -832,7 +843,8 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged); - setting_setup_signal_listener(gSavedSettings, "RenderAnisotropic", handleAnisotropicChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAnisotropicLevel", handleAnisotropicFilteringChanged); + gSavedSettings.getControl("RenderAnisotropicLevel")->getValidateSignal()->connect(boost::bind(&validateAnisotropicFiltering, _2)); setting_setup_signal_listener(gSavedSettings, "RenderShadowResolutionScale", handleShadowsResized); setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged); 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 2a18134491..3ba772e8d7 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 @@ -360,17 +360,6 @@ Hardware - - - + + Anisotropic Filtering: + + + + + + + + + Date: Tue, 25 Aug 2026 20:18:58 +0300 Subject: #6153 Make hardware test more robust --- indra/llcommon/llprocess.cpp | 5 ++ indra/llcommon/llprocess.h | 4 ++ indra/newview/app_settings/cmd_line.xml | 6 ++ indra/newview/llappviewer.cpp | 43 +++++++++--- indra/newview/llappviewerwin32.cpp | 18 ++++- indra/newview/llcommandlineparser.cpp | 2 +- indra/newview/llfeaturemanager.cpp | 114 +++++++++++++++++++++++++++++++- 7 files changed, 178 insertions(+), 14 deletions(-) (limited to 'indra/newview/llfeaturemanager.cpp') diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp index e43f386af2..86e1f48377 100644 --- a/indra/llcommon/llprocess.cpp +++ b/indra/llcommon/llprocess.cpp @@ -1109,6 +1109,11 @@ bool LLProcess::kill(const LLProcessPtr& ptr, const std::string& who) return !ptr || ptr->kill(who); } +void LLProcess::pump() +{ + tick(); +} + LLProcess::id LLProcess::getProcessID() const { if (!mChild) diff --git a/indra/llcommon/llprocess.h b/indra/llcommon/llprocess.h index 26f9a27837..a016b6a258 100644 --- a/indra/llcommon/llprocess.h +++ b/indra/llcommon/llprocess.h @@ -234,6 +234,10 @@ public: bool kill(const std::string& who = ""); static bool kill(const LLProcessPtr& p, const std::string& who = ""); + /// Manually drive pending I/O and check process state. + /// Use this when the mainloop is not yet running or was terminated. + void pump(); + #if LL_WINDOWS typedef int id; typedef HANDLE handle; diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index e16a5c7e76..bf7f9bab1f 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -90,6 +90,12 @@ ConnectAsGod + gpubenchmark + + desc + Run GPU memory bandwidth benchmark, print result to stdout, and exit. Used internally by the viewer to isolate benchmark from the main process. + + graphicslevel desc diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 35a2cc1852..d155e7340b 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -300,6 +300,13 @@ extern bool gDebugGL; extern bool gHiDPISupport; #endif +#if LL_WINDOWS +extern bool gGPUBenchmarkMode; +#else +static constexpr bool gGPUBenchmarkMode = false; +#endif // LL_WINDOWS + + //////////////////////////////////////////////////////////// // All from the last globals push... @@ -2373,11 +2380,17 @@ void LLAppViewer::initLoggingAndGetLastDuration() if (mSecondInstance) { - LLFile::mkdir(gDirUtilp->getDumpLogsDirPath()); + if (!gGPUBenchmarkMode) + { + LLFile::mkdir(gDirUtilp->getDumpLogsDirPath()); - LLUUID uid; - uid.generate(); - LLError::logToFile(gDirUtilp->getDumpLogsDirPath(uid.asString() + ".log")); + LLUUID uid; + uid.generate(); + // Is this even useful? + // Originally this wa used to store states, but I don't think it's practical with bugsplat attributes. + // So it just spams files now. + LLError::logToFile(gDirUtilp->getDumpLogsDirPath(uid.asString() + ".log")); + } } else { @@ -3081,12 +3094,15 @@ bool LLAppViewer::initConfiguration() // Display splash screen. Must be after above check for previous // crash as this dialog is always frontmost. - std::string splash_msg; - LLStringUtil::format_map_t args; - args["[APP_NAME]"] = LLTrans::getString("SECOND_LIFE"); - splash_msg = LLTrans::getString("StartupLoading", args); - LLSplashScreen::show(); - LLSplashScreen::update(splash_msg); + if (!gGPUBenchmarkMode) + { + std::string splash_msg; + LLStringUtil::format_map_t args; + args["[APP_NAME]"] = LLTrans::getString("SECOND_LIFE"); + splash_msg = LLTrans::getString("StartupLoading", args); + LLSplashScreen::show(); + LLSplashScreen::update(splash_msg); + } //LLVolumeMgr::initClass(); LLVolumeMgr* volume_manager = new LLVolumeMgr(); @@ -4139,6 +4155,13 @@ bool LLAppViewer::getMarkerData(const std::string& marker_name, std::string& dat void LLAppViewer::processMarkerFiles() { + if (gGPUBenchmarkMode) + { + // Skipping marker file processing in GPU benchmark mode + mSecondInstance = true; + initLoggingAndGetLastDuration(); + return; + } //We've got 4 things to test for here // - Other Process Running (SecondLife.exec_marker present, locked) // - Freeze (SecondLife.exec_marker present, not locked) diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 159c3af8a0..2080d0b7bf 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -234,6 +234,8 @@ namespace } #endif // LL_BUGSPLAT +extern bool gGPUBenchmarkMode; + namespace { void (*gOldTerminateHandler)() = NULL; @@ -515,12 +517,21 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, gIconResource = MAKEINTRESOURCE(IDI_LL_ICON); gIconSmallResource = MAKEINTRESOURCE(IDI_LL_ICON_SMALL); + // Benchmark subprocess mode before full init for LLFeatureManager::loadGPUClass(). + { + std::wstring cmdLineStr(pCmdLine ? pCmdLine : L""); + if (cmdLineStr.find(L"--gpubenchmark") != std::wstring::npos) + { + gGPUBenchmarkMode = true; + } + } + LLAppViewerWin32* viewer_app_ptr = new LLAppViewerWin32(ll_convert_wide_to_string(pCmdLine).c_str()); gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler); // Set a debug info flag to indicate if multiple instances are running. - bool found_other_instance = !create_app_mutex(); + bool found_other_instance = gGPUBenchmarkMode || !create_app_mutex(); gDebugInfo["FoundOtherInstanceAtStartup"] = LLSD::Boolean(found_other_instance); bool ok = viewer_app_ptr->init(); @@ -940,7 +951,10 @@ void LLAppViewerWin32::initLoggingAndGetLastDuration() void LLAppViewerWin32::initConsole() { // pop up debug console - mIsConsoleAllocated = create_console(); + if (!gGPUBenchmarkMode) + { + mIsConsoleAllocated = create_console(); + } return LLAppViewer::initConsole(); } diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp index 84d3ff90d5..7e7d528199 100644 --- a/indra/newview/llcommandlineparser.cpp +++ b/indra/newview/llcommandlineparser.cpp @@ -60,7 +60,7 @@ namespace // List of command-line switches that can't map-to settings variables. // Going forward, we want every new command-line switch to map-to some // settings variable. This list is used to validate that. - const std::set unmapped_options = { "help", "set", "setdefault", "settings", "sessionsettings", "usersessionsettings" }; + const std::set unmapped_options = { "help", "set", "setdefault", "settings", "sessionsettings", "usersessionsettings", "gpubenchmark" }; po::options_description gOptionsDesc; po::positional_options_description gPositionalOptions; diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 8140aaab22..3dbb93c453 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -377,6 +377,83 @@ F32 gpu_benchmark(); #if LL_WINDOWS +bool gGPUBenchmarkMode = false; + +// Runs gpu_benchmark() in a subprocess (exe with --gpubenchmark). +static F32 subprocess_gpu_benchmark() +{ + LLProcess::Params params; + params.executable = gDirUtilp->getExecutablePathAndName(); + params.args.add("--gpubenchmark"); + params.desc = "GPU benchmark"; + params.autokill = true; // killed via job object if parent crashes + params.attached = true; // killed on LLProcessPtr destruction (timeout) + params.files.add(LLProcess::FileParam()); // stdin: default + params.files.add(LLProcess::FileParam().type("pipe")); // stdout: pipe + params.files.add(LLProcess::FileParam()); // stderr: default + + LLProcessPtr child; + try + { + child = LLProcess::create(params); + } + catch (const std::exception& e) + { + LL_WARNS("RenderInit") << "subprocess_gpu_benchmark: failed to launch: " + << e.what() << LL_ENDL; + return -1.f; + } + + if (!child) + { + LL_WARNS("RenderInit") << "subprocess_gpu_benchmark: LLProcess::create returned null." << LL_ENDL; + return -1.f; + } + + LLProcess::ReadPipe& out = child->getReadPipe(LLProcess::STDOUT); + + const F32 POLL_INTERVAL_S = 0.25f; + const F32 TOTAL_TIMEOUT_S = 120.f; // covers full viewer init + benchmark + LLTimer timer; + timer.start(); + + while (timer.getElapsedTimeF32() < TOTAL_TIMEOUT_S) + { + child->pump(); + + // Result is a single float followed by '\n' + if (out.contains('\n')) + { + std::string line = out.getline(); + float parsed = 0.f; + if (sscanf_s(line.c_str(), "%f", &parsed) == 1 && parsed > 0.f) + { + LL_INFOS("RenderInit") << "subprocess_gpu_benchmark: result = " + << parsed << " GB/sec" << LL_ENDL; + // Let LLProcessPtr destructor handle cleanup + return parsed; + } + LL_WARNS("RenderInit") << "subprocess_gpu_benchmark: unparseable output: '" + << line << "'" << LL_ENDL; + return -1.f; + } + + // If child already exited without writing anything, bail + if (!child->isRunning()) + { + LL_WARNS("RenderInit") << "subprocess_gpu_benchmark: process exited without result." << LL_ENDL; + return -1.f; + } + + ms_sleep((U32)(POLL_INTERVAL_S * 1000)); + } + + // Timeout: attached=true means LLProcessPtr destructor kills it + LL_WARNS("RenderInit") << "GPU benchmark subprocess timed out after " + << (int)TOTAL_TIMEOUT_S << " seconds; killing." << LL_ENDL; + return -1.f; +} + F32 logExceptionBenchmark() { // FIXME: gpu_benchmark uses many C++ classes on the stack to control state. @@ -457,7 +534,27 @@ bool LLFeatureManager::loadGPUClass() try { #if LL_WINDOWS - gbps = logExceptionBenchmark(); + if (gGPUBenchmarkMode) + { + // We ARE the benchmark subprocess; run directly in-process. + // logExceptionBenchmark wraps with SEH so structured exceptions + // (e.g. access violations inside the driver) are still caught. + gbps = logExceptionBenchmark(); + } + else + { + // Normal path: run benchmark in an isolated subprocess so a + // driver hang can be killed without freezing the main viewer. + gbps = subprocess_gpu_benchmark(); + if (gbps == -1.f + && gGLManager.getRawGLString().find("Radeon") != std::string::npos + && checkRDNA35()) + { + // Certain AMD GPUs have known issues with shader profiling and occlusion queries that can lead to hangs. + // If test returned -1, we are likely on a bad driver. + gSavedSettings.setBOOL("UseOcclusion", false); + } + } #else gbps = gpu_benchmark(); #endif @@ -468,6 +565,21 @@ bool LLFeatureManager::loadGPUClass() LL_WARNS("RenderInit") << "GPU benchmark failed: " << e.what() << LL_ENDL; } +#if LL_WINDOWS + // If we are the benchmark subprocess, write the raw result to stdout + // so the parent process can read it, then exit immediately. + if (gGPUBenchmarkMode) + { + LL_WARNS("RenderInit") << "Passing " << gbps << " to parent" << LL_ENDL; + char buf[64]; + int len = snprintf(buf, sizeof(buf), "%.6f\n", gbps); + DWORD written = 0; + WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, (DWORD)len, &written, NULL); + FlushFileBuffers(GetStdHandle(STD_OUTPUT_HANDLE)); + ExitProcess(0); + } +#endif + mGPUMemoryBandwidth = gbps; // bias by CPU speed -- cgit v1.3