Skip to content

Commit 32f20c7

Browse files
committed
Merge branch 'ali_shader_cache'
2 parents c586e4b + 8497a5e commit 32f20c7

File tree

4 files changed

+164
-110
lines changed

4 files changed

+164
-110
lines changed

include/nbl/asset/utils/IShaderCompiler.h

Lines changed: 28 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
3333
{
3434
system::path absolutePath = {};
3535
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
3737
// Could be used in the future for early rejection of cache hit
3838
//nbl::system::IFileBase::time_point_t lastWriteTime = {};
3939

@@ -183,9 +183,8 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
183183

184184
public:
185185
// 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";
187187

188-
using hash_t = std::array<uint64_t,4>;
189188
static auto const SHADER_BUFFER_SIZE_BYTES = sizeof(uint64_t) / sizeof(uint8_t); // It's obviously 8
190189

191190
struct SEntry
@@ -196,11 +195,9 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
196195
{
197196
public:
198197
// 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+
{}
204201

205202
inline SPreprocessingDependency(SPreprocessingDependency&) = default;
206203
inline SPreprocessingDependency& operator=(SPreprocessingDependency&) = delete;
@@ -218,11 +215,8 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
218215
// path or identifier
219216
system::path requestingSourceDir = "";
220217
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 = "";
224218
// hash of the contents - used to check against a found_t
225-
std::array<uint64_t, 4> hash = {};
219+
core::blake3_hash_t hash = {};
226220
// If true, then `getIncludeStandard` was used to find, otherwise `getIncludeRelative`
227221
bool standardInclude = false;
228222
};
@@ -248,6 +242,7 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
248242
private:
249243
friend class SCompilerArgs;
250244
friend class SEntry;
245+
friend class CCache;
251246
friend void to_json(nlohmann::json&, const SPreprocessorArgs&);
252247
friend void from_json(const nlohmann::json&, SPreprocessorArgs&);
253248

@@ -271,7 +266,7 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
271266
std::string sourceIdentifier;
272267
std::vector<SMacroDefinition> extraDefines;
273268
};
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
275270
struct SCompilerArgs final
276271
{
277272
public:
@@ -290,6 +285,7 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
290285

291286
private:
292287
friend class SEntry;
288+
friend class CCache;
293289
friend void to_json(nlohmann::json&, const SCompilerArgs&);
294290
friend void from_json(const nlohmann::json&, SCompilerArgs&);
295291

@@ -351,33 +347,40 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
351347

352348
// Now add the mainFileContents and produce both lookup and early equality rejection hashes
353349
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);
359355
}
360356

361357
// Needed to get the vector deserialization automatically
362358
inline SEntry() {}
363359

364360
// 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) {}
368365

369366
inline SEntry& operator=(SEntry& other) = delete;
370367
inline SEntry(SEntry&& other) = default;
371368
// Used for late initialization while looking up a cache, so as not to always initialize an entry even if caching was not requested
372369
inline SEntry& operator=(SEntry&& other) = default;
373370

371+
bool setContent(const asset::ICPUBuffer* uncompressedSpirvBuffer, dependency_container_t&& dependencies);
372+
373+
core::smart_refctd_ptr<ICPUShader> decompressShader() const;
374+
374375
// TODO: make some of these private
375376
std::string mainFileContents;
376377
SCompilerArgs compilerArgs;
377-
std::array<uint64_t,4> hash;
378+
core::blake3_hash_t hash;
378379
size_t lookupHash;
379380
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;
381384
};
382385

383386
inline void insert(SEntry&& entry)
@@ -429,52 +432,13 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
429432

430433
};
431434

432-
using EntrySet = core::unordered_multiset<SEntry, Hash, KeyEqual>;
435+
using EntrySet = core::unordered_set<SEntry, Hash, KeyEqual>;
433436
EntrySet m_container;
434437

435438
NBL_API2 EntrySet::const_iterator find_impl(const SEntry& mainFile, const CIncludeFinder* finder) const;
436439
};
437440

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;
478442

479443
inline core::smart_refctd_ptr<ICPUShader> compileToSPIRV(const char* code, const SCompilerOptions& options) const
480444
{

0 commit comments

Comments
 (0)