@@ -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