summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2025-09-02 23:26:16 +0300
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2025-09-02 23:29:15 +0300
commit3ea1d87a42bfc6aba367b1285e7bb6bdf49f8364 (patch)
tree47c8adcad4d45fa6545c993e8b2b90f89d944c7c
parent3e4f112c03d4fb9f5483d4acf18f0654740ebf45 (diff)
#4587 Shaders sometimes do not match the shader settings
Ensure versions get matched reliably
-rw-r--r--indra/llrender/llshadermgr.cpp36
-rw-r--r--indra/llrender/llshadermgr.h4
-rw-r--r--indra/newview/llviewershadermgr.cpp11
3 files changed, 39 insertions, 12 deletions
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 4807c12226..0ec532a55b 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -989,16 +989,17 @@ bool LLShaderMgr::validateProgramObject(GLuint obj)
return success;
}
-void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version, const LLUUID& current_cache_version)
+void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version, const LLUUID& current_cache_version, bool second_instance)
{
+ LL_PROFILE_ZONE_SCOPED;
LL_INFOS() << "Initializing shader cache" << LL_ENDL;
mShaderCacheEnabled = gGLManager.mGLVersion >= 4.09 && enabled;
- if(!mShaderCacheEnabled || mShaderCacheInitialized)
+ if(!mShaderCacheEnabled || mShaderCacheVersion.notNull())
return;
- mShaderCacheInitialized = true;
+ mShaderCacheVersion = current_cache_version;
mShaderCacheDir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "shader_cache");
LLFile::mkdir(mShaderCacheDir);
@@ -1007,16 +1008,19 @@ void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version,
std::string meta_out_path = gDirUtilp->add(mShaderCacheDir, "shaderdata.llsd");
if (gDirUtilp->fileExists(meta_out_path))
{
+ LL_PROFILE_ZONE_NAMED("shader_cache");
LL_INFOS() << "Loading shader cache metadata" << LL_ENDL;
llifstream instream(meta_out_path);
LLSD in_data;
+ // todo: this is likely very expensive to parse, should use binary
LLSDSerialize::fromNotation(in_data, instream, LLSDSerialize::SIZE_UNLIMITED);
instream.close();
- if (old_cache_version == current_cache_version)
+ if (old_cache_version == current_cache_version
+ && in_data["version"].asUUID() == current_cache_version)
{
- for (const auto& data_pair : llsd::inMap(in_data))
+ for (const auto& data_pair : llsd::inMap(in_data["shaders"]))
{
ProgramBinaryData binary_info = ProgramBinaryData();
binary_info.mBinaryFormat = data_pair.second["binary_format"].asInteger();
@@ -1025,11 +1029,15 @@ void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version,
mShaderBinaryCache.insert_or_assign(LLUUID(data_pair.first), binary_info);
}
}
- else
+ else if (!second_instance)
{
LL_INFOS() << "Shader cache version mismatch detected. Purging." << LL_ENDL;
clearShaderCache();
}
+ else
+ {
+ LL_INFOS() << "Shader cache version mismatch detected." << LL_ENDL;
+ }
}
}
}
@@ -1046,10 +1054,22 @@ void LLShaderMgr::clearShaderCache()
void LLShaderMgr::persistShaderCacheMetadata()
{
if(!mShaderCacheEnabled) return;
+ if (mShaderCacheVersion.isNull())
+ {
+ LL_WARNS() << "Attempted to save shader cache with no version set" << LL_ENDL;
+ return;
+ }
LL_INFOS() << "Persisting shader cache metadata to disk" << LL_ENDL;
- LLSD out = LLSD::emptyMap();
+ LLSD out;
+ // Settings and shader cache get saved at different time, thus making
+ // RenderShaderCacheVersion unreliable when running multiple viewer
+ // instances, or for cases where viewer crashes before saving settings.
+ // Dupplicate version to the cache itself.
+ out["version"] = mShaderCacheVersion;
+ out["shaders"] = LLSD::emptyMap();
+ LLSD &shaders = out["shaders"];
static const F32 LRU_TIME = (60.f * 60.f) * 24.f * 7.f; // 14 days
const F32 current_time = (F32)LLTimer::getTotalSeconds();
@@ -1068,7 +1088,7 @@ void LLShaderMgr::persistShaderCacheMetadata()
data["binary_format"] = LLSD::Integer(shader_metadata.mBinaryFormat);
data["binary_size"] = LLSD::Integer(shader_metadata.mBinaryLength);
data["last_used"] = LLSD::Real(shader_metadata.mLastUsedTime);
- out[it->first.asString()] = data;
+ shaders[it->first.asString()] = data;
++it;
}
}
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 46788841a5..1b638e6e06 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -363,7 +363,7 @@ public:
// Implemented in the application to actually update out of date uniforms for a particular shader
virtual void updateShaderUniforms(LLGLSLShader * shader) = 0; // Pure Virtual
- void initShaderCache(bool enabled, const LLUUID& old_cache_version, const LLUUID& current_cache_version);
+ void initShaderCache(bool enabled, const LLUUID& old_cache_version, const LLUUID& current_cache_version, bool second_instance);
void clearShaderCache();
void persistShaderCacheMetadata();
@@ -387,7 +387,7 @@ public:
F32 mLastUsedTime = 0.0;
};
std::map<LLUUID, ProgramBinaryData> mShaderBinaryCache;
- bool mShaderCacheInitialized = false;
+ LLUUID mShaderCacheVersion;
bool mShaderCacheEnabled = false;
std::string mShaderCacheDir;
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index a0a9906724..a9c58d5a06 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -545,7 +545,11 @@ void LLViewerShaderMgr::setShaders()
gSavedSettings.setString("RenderShaderCacheVersion", current_cache_version.asString());
}
- initShaderCache(shader_cache_enabled, old_cache_version, current_cache_version);
+ initShaderCache(
+ shader_cache_enabled,
+ old_cache_version,
+ current_cache_version,
+ LLAppViewer::instance()->isSecondInstance());
}
static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
@@ -703,7 +707,10 @@ void LLViewerShaderMgr::setShaders()
loaded = loaded && loadShadersDeferred();
llassert(loaded);
- persistShaderCacheMetadata();
+ if (!LLAppViewer::instance()->isSecondInstance())
+ {
+ persistShaderCacheMetadata();
+ }
if (gViewerWindow)
{