@@ -651,6 +651,68 @@ std::string normalizeIncludeLookupName(const std::string& includeName)
651651 return includeName.substr (1ull );
652652}
653653
654+ template <typename Func>
655+ auto withSessionCacheLock (IShaderCompiler::CIncludeFinder::SSessionCache* cache, Func&& func) -> decltype(func())
656+ {
657+ if (cache && cache->threadSafe )
658+ {
659+ std::lock_guard lock (cache->mutex );
660+ return func ();
661+ }
662+ return func ();
663+ }
664+
665+ std::string makeIncludeSessionCacheKey (const system::path& requestingSourceDir, std::string_view includeName, const bool needHash, const char mode)
666+ {
667+ const auto requestingDir = requestingSourceDir.generic_string ();
668+ std::string key;
669+ key.reserve (requestingDir.size () + includeName.size () + 4ull );
670+ key.push_back (mode);
671+ key.push_back (' \n ' );
672+ key.push_back (needHash ? ' H' : ' N' );
673+ key.push_back (' \n ' );
674+ key.append (requestingDir);
675+ key.push_back (' \n ' );
676+ key.append (includeName.data (), includeName.size ());
677+ return key;
678+ }
679+
680+ }
681+
682+ void IShaderCompiler::CIncludeFinder::SSessionCache::clear ()
683+ {
684+ withSessionCacheLock (this , [&]()
685+ {
686+ found.clear ();
687+ missing.clear ();
688+ });
689+ }
690+
691+ auto IShaderCompiler::CIncludeFinder::SSessionCache::lookup (const std::string& key, IIncludeLoader::found_t & result) const -> E_LOOKUP_RESULT
692+ {
693+ return withSessionCacheLock (const_cast <SSessionCache*>(this ), [&]() -> E_LOOKUP_RESULT
694+ {
695+ if (const auto foundIt = found.find (key); foundIt != found.end ())
696+ {
697+ result = foundIt->second ;
698+ return E_LOOKUP_RESULT::Found;
699+ }
700+ if (missing.contains (key))
701+ return E_LOOKUP_RESULT::Missing;
702+ return E_LOOKUP_RESULT::Miss;
703+ });
704+ }
705+
706+ void IShaderCompiler::CIncludeFinder::SSessionCache::store (const std::string& key, IIncludeLoader::found_t result)
707+ {
708+ withSessionCacheLock (this , [&]()
709+ {
710+ missing.erase (key);
711+ if (result)
712+ found.insert_or_assign (key, std::move (result));
713+ else
714+ missing.insert (key);
715+ });
654716}
655717
656718IShaderCompiler::CIncludeFinder::CIncludeFinder (core::smart_refctd_ptr<system::ISystem>&& system)
@@ -663,10 +725,21 @@ IShaderCompiler::CIncludeFinder::CIncludeFinder(core::smart_refctd_ptr<system::I
663725// @param requestingSourceDir: the directory where the incude was requested
664726// @param includeName: the string within <> of the include preprocessing directive
665727// @param
666- auto IShaderCompiler::CIncludeFinder::getIncludeStandard (const system::path& requestingSourceDir, const std::string& includeName, bool needHash) const -> IIncludeLoader::found_t
728+ auto IShaderCompiler::CIncludeFinder::getIncludeStandard (const system::path& requestingSourceDir, const std::string& includeName, bool needHash, SSessionCache* sessionCache ) const -> IIncludeLoader::found_t
667729{
668730 const auto lookupName = normalizeIncludeLookupName (includeName);
731+ const auto cacheKey = makeIncludeSessionCacheKey (requestingSourceDir, lookupName, needHash, ' S' );
669732 IShaderCompiler::IIncludeLoader::found_t retVal;
733+ switch (sessionCache ? sessionCache->lookup (cacheKey, retVal) : SSessionCache::E_LOOKUP_RESULT::Miss)
734+ {
735+ case SSessionCache::E_LOOKUP_RESULT::Found:
736+ return retVal;
737+ case SSessionCache::E_LOOKUP_RESULT::Missing:
738+ return {};
739+ case SSessionCache::E_LOOKUP_RESULT::Miss:
740+ break ;
741+ }
742+
670743 if (auto contents = tryIncludeGenerators (lookupName))
671744 retVal = std::move (contents);
672745 else if (auto contents = trySearchPaths (lookupName, needHash))
@@ -680,16 +753,29 @@ auto IShaderCompiler::CIncludeFinder::getIncludeStandard(const system::path& req
680753 hasher.update (reinterpret_cast <uint8_t *>(retVal.contents .data ()), retVal.contents .size () * (sizeof (char ) / sizeof (uint8_t )));
681754 retVal.hash = static_cast <core::blake3_hash_t >(hasher);
682755 }
756+ if (sessionCache)
757+ sessionCache->store (cacheKey, retVal);
683758 return retVal;
684759}
685760
686761// ! includes within ""
687762// @param requestingSourceDir: the directory where the incude was requested
688763// @param includeName: the string within "" of the include preprocessing directive
689- auto IShaderCompiler::CIncludeFinder::getIncludeRelative (const system::path& requestingSourceDir, const std::string& includeName, bool needHash) const -> IIncludeLoader::found_t
764+ auto IShaderCompiler::CIncludeFinder::getIncludeRelative (const system::path& requestingSourceDir, const std::string& includeName, bool needHash, SSessionCache* sessionCache ) const -> IIncludeLoader::found_t
690765{
691766 const auto lookupName = normalizeIncludeLookupName (includeName);
767+ const auto cacheKey = makeIncludeSessionCacheKey (requestingSourceDir, lookupName, needHash, ' R' );
692768 IShaderCompiler::IIncludeLoader::found_t retVal;
769+ switch (sessionCache ? sessionCache->lookup (cacheKey, retVal) : SSessionCache::E_LOOKUP_RESULT::Miss)
770+ {
771+ case SSessionCache::E_LOOKUP_RESULT::Found:
772+ return retVal;
773+ case SSessionCache::E_LOOKUP_RESULT::Missing:
774+ return {};
775+ case SSessionCache::E_LOOKUP_RESULT::Miss:
776+ break ;
777+ }
778+
693779 if (auto contents = m_defaultFileSystemLoader->getInclude (requestingSourceDir.string (), lookupName, needHash))
694780 retVal = std::move (contents);
695781 else retVal = std::move (trySearchPaths (lookupName, needHash));
@@ -700,6 +786,8 @@ auto IShaderCompiler::CIncludeFinder::getIncludeRelative(const system::path& req
700786 hasher.update (reinterpret_cast <uint8_t *>(retVal.contents .data ()), retVal.contents .size () * (sizeof (char ) / sizeof (uint8_t )));
701787 retVal.hash = static_cast <core::blake3_hash_t >(hasher);
702788 }
789+ if (sessionCache)
790+ sessionCache->store (cacheKey, retVal);
703791 return retVal;
704792}
705793
0 commit comments