diff options
| author | Rye Mutt <rye@alchemyviewer.org> | 2023-05-17 19:30:27 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-05-17 18:30:27 -0500 | 
| commit | 87bda552688bb38fe255cc7e6069c1be6ac20834 (patch) | |
| tree | 0630569c338cf9c88627f0a6e10cd68bb66691cb /indra/newview | |
| parent | 446d0cbf7f19e459b90a06f4153b3f7f9df6f09a (diff) | |
Add a binary cache for compiled shaders using glProgramBinary (#216)
* Add a binary cache for compiled shaders using glProgramBinary
* Add additional sanity checking to shader binary save and load, hook up cache clear and menu option
* Fix default init of shader cache data struct and clear gl errors before glGetError calls
---------
Co-authored-by: RunitaiLinden <davep@lindenlab.com>
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/app_settings/settings.xml | 22 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/lldrawpoolalpha.cpp | 7 | ||||
| -rw-r--r-- | indra/newview/llviewermenu.cpp | 16 | ||||
| -rw-r--r-- | indra/newview/llviewershadermgr.cpp | 106 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/menu_viewer.xml | 19 | 
6 files changed, 98 insertions, 73 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 162a474f69..79639c9b32 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11014,6 +11014,28 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>RenderShaderCacheEnabled</key> +    <map> +      <key>Comment</key> +      <string>Enable binary shader cache</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map> +    <key>RenderShaderCacheVersion</key> +    <map> +      <key>Comment</key> +      <string>Current version hash for shader cache</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>String</string> +      <key>Value</key> +      <string>00000000-0000-0000-0000-000000000000</string> +    </map>      <key>ReplaySession</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index dfdf7a1b61..abef25e34f 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4446,6 +4446,7 @@ void LLAppViewer::purgeCache()  	LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL;  	LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE);  	LLVOCache::getInstance()->removeCache(LL_PATH_CACHE); +	LLViewerShaderMgr::instance()->clearShaderCache();  	std::string browser_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "cef_cache");  	if (LLFile::isdir(browser_cache))  	{ diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 7893caf3c0..a96d480c78 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -732,12 +732,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)                          {                              target_shader = &(gDeferredMaterialWaterProgram[mask]);                          } - -                        if (params.mAvatar != nullptr) -                        { -                            llassert(target_shader->mRiggedVariant != nullptr); -                            target_shader = target_shader->mRiggedVariant; -                        }                      }                      else if (!params.mFullbright)                      { @@ -750,6 +744,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)                      if (params.mAvatar != nullptr)                      { +                        llassert(target_shader->mRiggedVariant != nullptr);                          target_shader = target_shader->mRiggedVariant;                      } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index d0acac858c..921620190e 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2079,6 +2079,21 @@ class LLAdvancedPurgeDiskCache : public view_listener_t  }; +//////////////////////// +// PURGE SHADER CACHE // +//////////////////////// + + +class LLAdvancedPurgeShaderCache : public view_listener_t +{ +	bool handleEvent(const LLSD& userdata) +	{ +		LLViewerShaderMgr::instance()->clearShaderCache(); +		LLViewerShaderMgr::instance()->setShaders(); +		return true; +	} +}; +  ////////////////////  // EVENT Recorder //  /////////////////// @@ -9435,6 +9450,7 @@ void initialize_menus()  	view_listener_t::addMenu(new LLAdvancedClickRenderShadowOption(), "Advanced.ClickRenderShadowOption");  	view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile");  	view_listener_t::addMenu(new LLAdvancedClickRenderBenchmark(), "Advanced.ClickRenderBenchmark"); +	view_listener_t::addMenu(new LLAdvancedPurgeShaderCache(), "Advanced.ClearShaderCache");  	#ifdef TOGGLE_HACKED_GODLIKE_VIEWER  	view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode"); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 0dff88521e..5ea52aca79 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -32,6 +32,7 @@  #include "llfeaturemanager.h"  #include "llviewershadermgr.h"  #include "llviewercontrol.h" +#include "llversioninfo.h"  #include "llrender.h"  #include "llenvironment.h" @@ -368,6 +369,23 @@ void LLViewerShaderMgr::setShaders()          return;      } +	{ +		static LLCachedControl<bool> shader_cache_enabled(gSavedSettings, "RenderShaderCacheEnabled", true); +		static LLUUID old_cache_version; +		static LLUUID current_cache_version; +		if (current_cache_version.isNull()) +		{ +			HBXXH128 hash_obj; +			hash_obj.update(LLVersionInfo::instance().getVersion()); +			current_cache_version = hash_obj.digest(); + +			old_cache_version = LLUUID(gSavedSettings.getString("RenderShaderCacheVersion")); +			gSavedSettings.setString("RenderShaderCacheVersion", current_cache_version.asString()); +		} + +		initShaderCache(shader_cache_enabled, old_cache_version, current_cache_version); +	} +      static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);      // when using indexed texture rendering, leave 8 texture units available for shadow and reflection maps @@ -375,9 +393,6 @@ void LLViewerShaderMgr::setShaders()      reentrance = true; -    //setup preprocessor definitions -    LLShaderMgr::instance()->mDefinitions["NUM_TEX_UNITS"] = llformat("%d", gGLManager.mNumTextureImageUnits); -          // Make sure the compiled shader map is cleared before we recompile shaders.      mVertexShaderObjects.clear();      mFragmentShaderObjects.clear(); @@ -385,6 +400,8 @@ void LLViewerShaderMgr::setShaders()      initAttribsAndUniforms();      gPipeline.releaseGLBuffers(); +	unloadShaders(); +      LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");       if (gViewerWindow) @@ -521,6 +538,8 @@ void LLViewerShaderMgr::setShaders()      loaded = loaded && loadShadersDeferred();      llassert(loaded); +	persistShaderCacheMetadata(); +      if (gViewerWindow)      {          gViewerWindow->setCursor(UI_CURSOR_ARROW); @@ -532,61 +551,12 @@ void LLViewerShaderMgr::setShaders()  void LLViewerShaderMgr::unloadShaders()  { -	gOcclusionProgram.unload(); -    gSkinnedOcclusionProgram.unload(); -	gOcclusionCubeProgram.unload(); -	gDebugProgram.unload(); -    gSkinnedDebugProgram.unload(); -	gClipProgram.unload(); -	gBenchmarkProgram.unload(); -    gReflectionProbeDisplayProgram.unload(); -	gAlphaMaskProgram.unload(); -	gUIProgram.unload(); -	gPathfindingProgram.unload(); -	gPathfindingNoNormalsProgram.unload(); -	gGlowCombineProgram.unload(); -	gReflectionMipProgram.unload(); -    gRadianceGenProgram.unload(); -    gIrradianceGenProgram.unload(); -	gGlowCombineFXAAProgram.unload(); -	gTwoTextureCompareProgram.unload(); -	gOneTextureFilterProgram.unload(); -	gSolidColorProgram.unload(); - -	gObjectPreviewProgram.unload(); -    gPhysicsPreviewProgram.unload(); -	gImpostorProgram.unload(); -	gObjectBumpProgram.unload(); -    gSkinnedObjectBumpProgram.unload(); -    gSkinnedObjectFullbrightAlphaMaskProgram.unload(); -	 -	gObjectAlphaMaskNoColorProgram.unload(); -	gObjectAlphaMaskNoColorWaterProgram.unload(); -	 -	gWaterProgram.unload(); -    gWaterEdgeProgram.unload(); -	gUnderWaterProgram.unload(); - -	gGlowProgram.unload(); -	gGlowExtractProgram.unload(); -	gAvatarProgram.unload(); -	gAvatarWaterProgram.unload(); -	gAvatarEyeballProgram.unload(); -	gHighlightProgram.unload(); -    gSkinnedHighlightProgram.unload(); -	gHighlightNormalProgram.unload(); -	gHighlightSpecularProgram.unload(); - -	gPostScreenSpaceReflectionProgram.unload(); - -	gDeferredDiffuseProgram.unload(); -	gDeferredDiffuseAlphaMaskProgram.unload(); -    gDeferredSkinnedDiffuseAlphaMaskProgram.unload(); -	gDeferredNonIndexedDiffuseAlphaMaskProgram.unload(); -	gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload(); -	gDeferredSkinnedDiffuseProgram.unload(); -	gDeferredSkinnedBumpProgram.unload(); -	 +	while (!LLGLSLShader::sInstances.empty()) +	{ +		LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin()); +		shader->unload(); +	} +  	mShaderLevel[SHADER_LIGHTING] = 0;  	mShaderLevel[SHADER_OBJECT] = 0;  	mShaderLevel[SHADER_AVATAR] = 0; @@ -658,7 +628,7 @@ std::string LLViewerShaderMgr::loadBasicShaders()  	}  	shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl",        1 ) ); -	std::unordered_map<std::string, std::string> attribs; +	std::map<std::string, std::string> attribs;  	attribs["MAX_JOINTS_PER_MESH_OBJECT"] =   		boost::lexical_cast<std::string>(LLSkinningUtil::getMaxJointCount()); @@ -711,6 +681,8 @@ std::string LLViewerShaderMgr::loadBasicShaders()  		attribs["REF_SAMPLE_COUNT"] = "32";  	} +	LLGLSLShader::sGlobalDefines = attribs; +  	// We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.  	for (U32 i = 0; i < shaders.size(); i++)  	{ @@ -833,8 +805,8 @@ BOOL LLViewerShaderMgr::loadShadersWater()  		gWaterEdgeProgram.mShaderFiles.clear();  		gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));  		gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER)); -		gWaterEdgeProgram.addPermutation("WATER_EDGE", "1");          gWaterEdgeProgram.clearPermutations(); +		gWaterEdgeProgram.addPermutation("WATER_EDGE", "1");          if (LLPipeline::sRenderTransparentWater)          {              gWaterEdgeProgram.addPermutation("TRANSPARENT_WATER", "1"); @@ -1107,7 +1079,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ -		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader"; +		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask No Color Shader";  		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mFeatures.encodesNormal = true;  		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.clear();  		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER)); @@ -2098,6 +2070,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));  		gDeferredFullbrightAlphaMaskWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		gDeferredFullbrightAlphaMaskWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; +		gDeferredFullbrightAlphaMaskWaterProgram.clearPermutations();  		gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("HAS_ALPHA_MASK","1");  		gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("WATER_FOG","1");          success = make_rigged_variant(gDeferredFullbrightAlphaMaskWaterProgram, gDeferredSkinnedFullbrightAlphaMaskWaterProgram); @@ -2125,7 +2098,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()      if (success)      { -        gHUDFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader"; +        gHUDFullbrightShinyProgram.mName = "HUD FullbrightShiny Shader";          gHUDFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;          gHUDFullbrightShinyProgram.mFeatures.hasAtmospherics = true;          gHUDFullbrightShinyProgram.mFeatures.hasGamma = true; @@ -2421,6 +2394,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER));  		gDeferredTerrainWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		gDeferredTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; +		gDeferredTerrainWaterProgram.clearPermutations();  		gDeferredTerrainWaterProgram.addPermutation("WATER_FOG", "1");  		success = gDeferredTerrainWaterProgram.createShader(NULL, NULL);          llassert(success); @@ -2428,7 +2402,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ -		gDeferredAvatarProgram.mName = "Avatar Shader"; +		gDeferredAvatarProgram.mName = "Deferred Avatar Shader";  		gDeferredAvatarProgram.mFeatures.hasSkinning = true;  		gDeferredAvatarProgram.mFeatures.encodesNormal = true;  		gDeferredAvatarProgram.mShaderFiles.clear(); @@ -2441,7 +2415,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ -		gDeferredAvatarAlphaProgram.mName = "Avatar Alpha Shader"; +		gDeferredAvatarAlphaProgram.mName = "Deferred Avatar Alpha Shader";  		gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true;  		gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = false;  		gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false; @@ -2577,7 +2551,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{  		gDeferredPostProgram.mName = "Deferred Post Shader"; -		gFXAAProgram.mFeatures.isDeferred = true; +        gDeferredPostProgram.mFeatures.isDeferred = true;  		gDeferredPostProgram.mShaderFiles.clear();  		gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));  		gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER)); @@ -2612,7 +2586,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ -		gDeferredPostNoDoFProgram.mName = "Deferred Post Shader"; +		gDeferredPostNoDoFProgram.mName = "Deferred Post NoDoF Shader";  		gDeferredPostNoDoFProgram.mFeatures.isDeferred = true;  		gDeferredPostNoDoFProgram.mShaderFiles.clear();  		gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 3164c3e124..7a29d68a4c 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -3259,7 +3259,24 @@ function="World.EnvPreset"                   parameter="RenderAttachedParticles" />              </menu_item_check>            <menu_item_separator /> -           +          <menu_item_check +             label="Enable Shader Cache" +             name="Enable Shader Cache"> +            <menu_item_check.on_check +             function="CheckControl" +             parameter="RenderShaderCacheEnabled" /> +            <menu_item_check.on_click +             function="ToggleShaderControl" +             parameter="RenderShaderCacheEnabled" /> +          </menu_item_check> +          <menu_item_call +            enabled="true" +            label="Clear Shader Cache" +            name="Shader Cache Clear"> +            <menu_item_call.on_click +             function="Advanced.ClearShaderCache" /> +          </menu_item_call> +          <menu_item_separator />            <menu_item_call              enabled="true"              label="Clear Cache Immediately"  | 
