1717#include " nbl/builtin/hlsl/enums.hlsl"
1818
1919#include < functional>
20+ #include < mutex>
21+ #include < unordered_set>
2022
2123namespace nbl ::asset
2224{
@@ -26,6 +28,25 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
2628 public:
2729 IShaderCompiler (core::smart_refctd_ptr<system::ISystem>&& system);
2830
31+ enum class IncludeRootOrigin : uint8_t
32+ {
33+ User,
34+ Builtin,
35+ Generated
36+ };
37+
38+ enum class HeaderClass : uint8_t
39+ {
40+ User,
41+ System
42+ };
43+
44+ struct IncludeClassification
45+ {
46+ IncludeRootOrigin origin = IncludeRootOrigin::User;
47+ HeaderClass headerClass = HeaderClass::User;
48+ };
49+
2950 class NBL_API2 IIncludeLoader : public core::IReferenceCounted
3051 {
3152 public:
@@ -34,12 +55,13 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
3455 system::path absolutePath = {};
3556 std::string contents = {};
3657 core::blake3_hash_t hash = {}; // TODO: we're not yet using IFile::getPrecomputedHash(), so for builtins we can maybe use that in the future
58+ IncludeClassification classification = {};
3759 // Could be used in the future for early rejection of cache hit
3860 // nbl::system::IFileBase::time_point_t lastWriteTime = {};
3961
4062 explicit inline operator bool () const {return !absolutePath.empty ();}
4163 };
42- virtual found_t getInclude (const system::path& searchPath, const std::string& includeName) const = 0;
64+ virtual found_t getInclude (const system::path& searchPath, const std::string& includeName, bool needHash = true ) const = 0;
4365 };
4466
4567 class NBL_API2 IIncludeGenerator : public core::IReferenceCounted
@@ -65,7 +87,7 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
6587 public:
6688 CFileSystemIncludeLoader (core::smart_refctd_ptr<system::ISystem>&& system);
6789
68- IIncludeLoader::found_t getInclude (const system::path& searchPath, const std::string& includeName) const override ;
90+ IIncludeLoader::found_t getInclude (const system::path& searchPath, const std::string& includeName, bool needHash = true ) const override ;
6991
7092 protected:
7193 core::smart_refctd_ptr<system::ISystem> m_system;
@@ -74,37 +96,88 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
7496 class NBL_API2 CIncludeFinder : public core::IReferenceCounted
7597 {
7698 public:
99+ struct SSessionCache
100+ {
101+ struct Stats
102+ {
103+ uint64_t lookupFound = 0ull ;
104+ uint64_t lookupMissing = 0ull ;
105+ uint64_t lookupMiss = 0ull ;
106+ uint64_t storeFound = 0ull ;
107+ uint64_t storeMissing = 0ull ;
108+ };
109+
110+ enum class LookupResult : uint8_t
111+ {
112+ Miss,
113+ Missing,
114+ Found
115+ };
116+
117+ explicit SSessionCache (const bool threadSafe = false ) : threadSafe(threadSafe) {}
118+
119+ void clear ();
120+ LookupResult lookup (const std::string& key, IIncludeLoader::found_t & result) const ;
121+ void store (const std::string& key, IIncludeLoader::found_t result);
122+ Stats snapshotStats () const ;
123+
124+ bool threadSafe = false ;
125+
126+ mutable std::mutex mutex;
127+ mutable Stats stats;
128+ core::unordered_map<std::string, IIncludeLoader::found_t > found;
129+ core::unordered_set<std::string> missing;
130+ };
131+
77132 CIncludeFinder (core::smart_refctd_ptr<system::ISystem>&& system);
78133
79134 // ! includes within <>
80135 // @param requestingSourceDir: the directory where the incude was requested
81136 // @param includeName: the string within <> of the include preprocessing directive
82- IIncludeLoader::found_t getIncludeStandard (const system::path& requestingSourceDir, const std::string& includeName) const ;
137+ IIncludeLoader::found_t getIncludeStandard (const system::path& requestingSourceDir, const std::string& includeName, bool needHash = true , SSessionCache* readSessionCache = nullptr , SSessionCache* writeSessionCache = nullptr ) const ;
83138
84139 // ! includes within ""
85140 // @param requestingSourceDir: the directory where the incude was requested
86141 // @param includeName: the string within "" of the include preprocessing directive
87- IIncludeLoader::found_t getIncludeRelative (const system::path& requestingSourceDir, const std::string& includeName) const ;
142+ IIncludeLoader::found_t getIncludeRelative (const system::path& requestingSourceDir, const std::string& includeName, bool needHash = true , SSessionCache* readSessionCache = nullptr , SSessionCache* writeSessionCache = nullptr ) const ;
88143
89144 inline core::smart_refctd_ptr<CFileSystemIncludeLoader> getDefaultFileSystemLoader () const { return m_defaultFileSystemLoader; }
90145
91- void addSearchPath (const std::string& searchPath, const core::smart_refctd_ptr<IIncludeLoader>& loader);
146+ void addSearchPath (const std::string& searchPath, const core::smart_refctd_ptr<IIncludeLoader>& loader, IncludeClassification classification = {} );
92147
93- void addGenerator (const core::smart_refctd_ptr<IIncludeGenerator>& generator);
148+ void addGenerator (const core::smart_refctd_ptr<IIncludeGenerator>& generator, IncludeClassification classification = {IncludeRootOrigin::Generated,HeaderClass::System});
149+
150+ bool isKnownGlobalInclude (std::string_view includeName) const ;
151+ IIncludeLoader::found_t classifyFound (IIncludeLoader::found_t found) const ;
94152
95153 protected:
96- IIncludeLoader::found_t trySearchPaths (const std::string& includeName) const ;
154+ IIncludeLoader::found_t trySearchPaths (const std::string& includeName, bool needHash ) const ;
97155
98156 IIncludeLoader::found_t tryIncludeGenerators (const std::string& includeName) const ;
157+ void registerHeaderRoot (std::string rootPath, IncludeClassification classification);
99158
100159 struct LoaderSearchPath
101160 {
102161 core::smart_refctd_ptr<IIncludeLoader> loader = nullptr ;
103162 std::string searchPath = {};
163+ IncludeClassification classification = {};
164+ };
165+
166+ struct GeneratorEntry
167+ {
168+ core::smart_refctd_ptr<IIncludeGenerator> generator = nullptr ;
169+ IncludeClassification classification = {IncludeRootOrigin::Generated,HeaderClass::System};
170+ };
171+
172+ struct HeaderRoot
173+ {
174+ std::string path = {};
175+ IncludeClassification classification = {};
104176 };
105177
106178 std::vector<LoaderSearchPath> m_loaders;
107- std::vector<core::smart_refctd_ptr<IIncludeGenerator>> m_generators;
179+ std::vector<GeneratorEntry> m_generators;
180+ std::vector<HeaderRoot> m_headerRoots;
108181 core::smart_refctd_ptr<CFileSystemIncludeLoader> m_defaultFileSystemLoader;
109182 };
110183
@@ -134,9 +207,12 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
134207 std::string_view sourceIdentifier = " " ;
135208 system::logger_opt_ptr logger = nullptr ;
136209 const CIncludeFinder* includeFinder = nullptr ;
210+ CIncludeFinder::SSessionCache* readIncludeSessionCache = nullptr ;
211+ CIncludeFinder::SSessionCache* writeIncludeSessionCache = nullptr ;
137212 std::span<const SMacroDefinition> extraDefines = {};
138213 E_SPIRV_VERSION targetSpirvVersion = E_SPIRV_VERSION::ESV_1_6;
139214 bool depfile = false ;
215+ bool preserveComments = false ;
140216 system::path depfilePath = {};
141217 std::function<void (std::string_view)> onPartialOutputOnFailure = {};
142218 };
0 commit comments