@@ -33,7 +33,7 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
33
33
{
34
34
system::path absolutePath = {};
35
35
std::string contents = {};
36
- std::array< uint64_t , 4 > hash = {}; // TODO: we're not yet using IFile::getPrecomputedHash(), so for builtins we can maybe use that in the future
36
+ core:: blake3_hash_t hash = {}; // TODO: we're not yet using IFile::getPrecomputedHash(), so for builtins we can maybe use that in the future
37
37
// Could be used in the future for early rejection of cache hit
38
38
// nbl::system::IFileBase::time_point_t lastWriteTime = {};
39
39
@@ -183,9 +183,8 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
183
183
184
184
public:
185
185
// Used to check compatibility of Caches before reading
186
- constexpr static inline std::string_view VERSION = " 1.0 .0" ;
186
+ constexpr static inline std::string_view VERSION = " 1.1 .0" ;
187
187
188
- using hash_t = std::array<uint64_t ,4 >;
189
188
static auto const SHADER_BUFFER_SIZE_BYTES = sizeof (uint64_t ) / sizeof (uint8_t ); // It's obviously 8
190
189
191
190
struct SEntry
@@ -196,11 +195,9 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
196
195
{
197
196
public:
198
197
// Perf note: hashing while preprocessor lexing is likely to be slower than just hashing the whole array like this
199
- inline SPreprocessingDependency (const system::path& _requestingSourceDir, const std::string_view& _identifier, const std::string_view& _contents, bool _standardInclude, std::array<uint64_t , 4 > _hash) :
200
- requestingSourceDir(_requestingSourceDir), identifier(_identifier), contents(_contents), standardInclude(_standardInclude), hash(_hash)
201
- {
202
- assert (!_contents.empty ());
203
- }
198
+ inline SPreprocessingDependency (const system::path& _requestingSourceDir, const std::string_view& _identifier, bool _standardInclude, core::blake3_hash_t _hash) :
199
+ requestingSourceDir(_requestingSourceDir), identifier(_identifier), standardInclude(_standardInclude), hash(_hash)
200
+ {}
204
201
205
202
inline SPreprocessingDependency (SPreprocessingDependency&) = default;
206
203
inline SPreprocessingDependency& operator =(SPreprocessingDependency&) = delete ;
@@ -218,11 +215,8 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
218
215
// path or identifier
219
216
system::path requestingSourceDir = " " ;
220
217
std::string identifier = " " ;
221
- // file contents
222
- // TODO: change to `core::vector<uint8_t>` a compressed blob of LZMA, and store all contents together in the `SEntry`
223
- std::string contents = " " ;
224
218
// hash of the contents - used to check against a found_t
225
- std::array< uint64_t , 4 > hash = {};
219
+ core:: blake3_hash_t hash = {};
226
220
// If true, then `getIncludeStandard` was used to find, otherwise `getIncludeRelative`
227
221
bool standardInclude = false ;
228
222
};
@@ -248,6 +242,7 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
248
242
private:
249
243
friend class SCompilerArgs ;
250
244
friend class SEntry ;
245
+ friend class CCache ;
251
246
friend void to_json (nlohmann::json&, const SPreprocessorArgs&);
252
247
friend void from_json (const nlohmann::json&, SPreprocessorArgs&);
253
248
@@ -271,7 +266,7 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
271
266
std::string sourceIdentifier;
272
267
std::vector<SMacroDefinition> extraDefines;
273
268
};
274
- // TODO: SPreprocessorArgs could just be folded into `SCompilerArgs` to have less classes and operators
269
+ // TODO: SPreprocessorArgs could just be folded into `SCompilerArgs` to have less classes and decompressShader
275
270
struct SCompilerArgs final
276
271
{
277
272
public:
@@ -290,6 +285,7 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
290
285
291
286
private:
292
287
friend class SEntry ;
288
+ friend class CCache ;
293
289
friend void to_json (nlohmann::json&, const SCompilerArgs&);
294
290
friend void from_json (const nlohmann::json&, SCompilerArgs&);
295
291
@@ -351,33 +347,40 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
351
347
352
348
// Now add the mainFileContents and produce both lookup and early equality rejection hashes
353
349
hashable.insert (hashable.end (), mainFileContents.begin (), mainFileContents.end ());
354
- hash = nbl::core::XXHash_256 (hashable. data (), hashable. size ());
355
- lookupHash = hash[ 0 ] ;
356
- for ( auto i = 1u ; i < 4 ; i++) {
357
- core::hash_combine< uint64_t >(lookupHash, hash[i] );
358
- }
350
+
351
+ core::blake3_hasher hasher ;
352
+ hasher. update (hashable. data (), hashable. size ());
353
+ hash = static_cast < core::blake3_hash_t >(hasher );
354
+ lookupHash = std::hash<core:: blake3_hash_t >{}(hash);
359
355
}
360
356
361
357
// Needed to get the vector deserialization automatically
362
358
inline SEntry () {}
363
359
364
360
// Making the copy constructor deep-copy everything but the shader
365
- inline SEntry (const SEntry& other)
366
- : mainFileContents(other.mainFileContents), compilerArgs(other.compilerArgs), hash(other.hash), lookupHash(other.lookupHash),
367
- dependencies(other.dependencies), cpuShader(other.cpuShader) {}
361
+ inline SEntry (const SEntry& other)
362
+ : mainFileContents(other.mainFileContents), compilerArgs(other.compilerArgs), hash(other.hash),
363
+ lookupHash(other.lookupHash), dependencies(other.dependencies), spirv(other.spirv),
364
+ uncompressedContentHash(other.uncompressedContentHash), uncompressedSize(other.uncompressedSize) {}
368
365
369
366
inline SEntry& operator =(SEntry& other) = delete ;
370
367
inline SEntry (SEntry&& other) = default;
371
368
// Used for late initialization while looking up a cache, so as not to always initialize an entry even if caching was not requested
372
369
inline SEntry& operator =(SEntry&& other) = default ;
373
370
371
+ bool setContent (const asset::ICPUBuffer* uncompressedSpirvBuffer, dependency_container_t && dependencies);
372
+
373
+ core::smart_refctd_ptr<ICPUShader> decompressShader () const ;
374
+
374
375
// TODO: make some of these private
375
376
std::string mainFileContents;
376
377
SCompilerArgs compilerArgs;
377
- std::array< uint64_t , 4 > hash;
378
+ core:: blake3_hash_t hash;
378
379
size_t lookupHash;
379
380
dependency_container_t dependencies;
380
- core::smart_refctd_ptr<asset::ICPUShader> cpuShader;
381
+ core::smart_refctd_ptr<asset::ICPUBuffer> spirv;
382
+ core::blake3_hash_t uncompressedContentHash;
383
+ size_t uncompressedSize;
381
384
};
382
385
383
386
inline void insert (SEntry&& entry)
@@ -429,52 +432,13 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
429
432
430
433
};
431
434
432
- using EntrySet = core::unordered_multiset <SEntry, Hash, KeyEqual>;
435
+ using EntrySet = core::unordered_set <SEntry, Hash, KeyEqual>;
433
436
EntrySet m_container;
434
437
435
438
NBL_API2 EntrySet::const_iterator find_impl (const SEntry& mainFile, const CIncludeFinder* finder) const ;
436
439
};
437
440
438
- inline core::smart_refctd_ptr<ICPUShader> compileToSPIRV (const std::string_view code, const SCompilerOptions& options) const
439
- {
440
- CCache::SEntry entry;
441
- std::vector<CCache::SEntry::SPreprocessingDependency> dependencies;
442
- if (options.readCache || options.writeCache )
443
- entry = std::move (CCache::SEntry (code, options));
444
-
445
- if (options.readCache )
446
- {
447
- auto found = options.readCache ->find_impl (entry, options.preprocessorOptions .includeFinder );
448
- if (found != options.readCache ->m_container .end ())
449
- {
450
- if (options.writeCache )
451
- {
452
- CCache::SEntry writeEntry = *found;
453
- options.writeCache ->insert (std::move (writeEntry));
454
- }
455
- return found->cpuShader ;
456
- }
457
- }
458
-
459
- auto retVal = compileToSPIRV_impl (code, options, options.writeCache ? &dependencies : nullptr );
460
-
461
- if (!retVal)
462
- return nullptr ;
463
-
464
- // compute the SPIR-V shader content hash
465
- {
466
- auto backingBuffer = retVal->getContent ();
467
- const_cast <ICPUBuffer*>(backingBuffer)->setContentHash (backingBuffer->computeContentHash ());
468
- }
469
-
470
- if (options.writeCache )
471
- {
472
- entry.dependencies = std::move (dependencies);
473
- entry.cpuShader = retVal;
474
- options.writeCache ->insert (std::move (entry));
475
- }
476
- return retVal;
477
- }
441
+ core::smart_refctd_ptr<ICPUShader> compileToSPIRV (const std::string_view code, const SCompilerOptions& options) const ;
478
442
479
443
inline core::smart_refctd_ptr<ICPUShader> compileToSPIRV (const char * code, const SCompilerOptions& options) const
480
444
{
0 commit comments