Skip to content

Commit a723701

Browse files
committed
update example latest
2 parents e8db5fe + 123a17b commit a723701

16 files changed

+284
-1325
lines changed

include/nbl/asset/utils/ISPIRVOptimizer.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ class ISPIRVOptimizer final : public core::IReferenceCounted
2424
EOP_SIMPLIFICATION,
2525
EOP_VECTOR_DCE,
2626
EOP_DEAD_INSERT_ELIM,
27-
EOP_AGGRESSIVE_DCE,
2827
EOP_DEAD_BRANCH_ELIM,
2928
EOP_BLOCK_MERGE,
3029
EOP_LOCAL_MULTI_STORE_ELIM,
@@ -34,11 +33,13 @@ class ISPIRVOptimizer final : public core::IReferenceCounted
3433
EOP_REDUCE_LOAD_SIZE,
3534
EOP_STRENGTH_REDUCTION,
3635
EOP_IF_CONVERSION,
36+
EOP_STRIP_DEBUG_INFO,
37+
EOP_AGGRESSIVE_DCE,
3738

3839
EOP_COUNT
3940
};
4041

41-
ISPIRVOptimizer(std::initializer_list<E_OPTIMIZER_PASS> _passes) : m_passes(std::move(_passes)) {}
42+
ISPIRVOptimizer(std::span<const E_OPTIMIZER_PASS> _passes) : m_passes(_passes.begin(), _passes.end()) {}
4243

4344
core::smart_refctd_ptr<ICPUBuffer> optimize(const uint32_t* _spirv, uint32_t _dwordCount, system::logger_opt_ptr logger) const;
4445
core::smart_refctd_ptr<ICPUBuffer> optimize(const ICPUBuffer* _spirv, system::logger_opt_ptr logger) const;
@@ -50,4 +51,4 @@ class ISPIRVOptimizer final : public core::IReferenceCounted
5051

5152
}
5253

53-
#endif
54+
#endif

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
{

include/nbl/video/CVulkanSwapchain.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,14 @@ class CVulkanSwapchain final : public ISwapchain
2020

2121
void setObjectDebugName(const char* label) const override;
2222

23-
inline const void* getNativeHandle() const {return &m_vkSwapchainKHR;}
23+
inline const void* getNativeHandle() const override {return &m_vkSwapchainKHR;}
2424
inline VkSwapchainKHR getInternalObject() const {return m_vkSwapchainKHR;}
25+
26+
// returns the maximum number of time acquire can be called without releasing the image index through present.
27+
inline uint8_t getMaxBlockingAcquiresBeforePresent() const override { return m_maxBlockingAcquiresBeforePresent; }
28+
29+
// returns the maximum number of acquires you can request without waiting for previous acquire semaphores to signal.
30+
uint8_t getMaxAcquiresInFlight() const override { return getImageCount(); }
2531

2632
private:
2733
CVulkanSwapchain(
@@ -32,7 +38,8 @@ class CVulkanSwapchain final : public ISwapchain
3238
const VkSwapchainKHR swapchain,
3339
const VkSemaphore* const _acquireAdaptorSemaphores,
3440
const VkSemaphore* const _prePresentSemaphores,
35-
const VkSemaphore* const _presentAdaptorSemaphores
41+
const VkSemaphore* const _presentAdaptorSemaphores,
42+
const uint8_t maxAcquiresBeforePresent
3643
);
3744
~CVulkanSwapchain();
3845

@@ -51,6 +58,7 @@ class CVulkanSwapchain final : public ISwapchain
5158
uint64_t m_perImageAcquireCount[ISwapchain::MaxImages] = { 0 };
5259
// nasty way to fight UB of the Vulkan spec
5360
bool m_needToWaitIdle = true;
61+
uint8_t m_maxBlockingAcquiresBeforePresent = 0u;
5462
};
5563

5664
}

include/nbl/video/ISwapchain.h

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -464,15 +464,21 @@ class ISwapchain : public IBackendObject
464464
// Vulkan: const VkSwapchainKHR*
465465
virtual const void* getNativeHandle() const = 0;
466466

467-
// only public because MultiTimelineEventHandlerST needs to know about it
468-
class DeferredFrameSemaphoreDrop final
469-
{
467+
// returns the maximum number of time acquires with infinite timeout which can be called before releasing the image index through present.
468+
virtual uint8_t getMaxBlockingAcquiresBeforePresent() const = 0u;
469+
470+
// returns the maximum number of acquires you can request without waiting for previous acquire semaphores to signal.
471+
virtual uint8_t getMaxAcquiresInFlight() const = 0u;
472+
473+
// only public because MultiTimelineEventHandlerST needs to know about it
474+
class DeferredFrameSemaphoreDrop final
475+
{
470476
using sema_refctd_ptr = core::smart_refctd_ptr<ISemaphore>;
471-
core::smart_refctd_dynamic_array<sema_refctd_ptr> m_otherSemaphores = nullptr;
477+
core::smart_refctd_dynamic_array<sema_refctd_ptr> m_otherSemaphores = nullptr;
472478

473-
public:
474-
inline DeferredFrameSemaphoreDrop(const std::span<const IQueue::SSubmitInfo::SSemaphoreInfo> _semaphores)
475-
{
479+
public:
480+
inline DeferredFrameSemaphoreDrop(const std::span<const IQueue::SSubmitInfo::SSemaphoreInfo> _semaphores)
481+
{
476482
const auto otherCount = _semaphores.size()-1;
477483
// first semaphore always serves as the timeline and will be refcounted in the event handler
478484
if (otherCount==0)
@@ -481,34 +487,34 @@ class ISwapchain : public IBackendObject
481487

482488
for (auto i=0ull; i<otherCount; i++)
483489
m_otherSemaphores->operator[](i) = sema_refctd_ptr(_semaphores[i].semaphore);
484-
}
490+
}
485491
DeferredFrameSemaphoreDrop(const DeferredFrameSemaphoreDrop& other) = delete;
486-
inline DeferredFrameSemaphoreDrop(DeferredFrameSemaphoreDrop&& other) : m_otherSemaphores(nullptr)
487-
{
488-
this->operator=(std::move(other));
489-
}
492+
inline DeferredFrameSemaphoreDrop(DeferredFrameSemaphoreDrop&& other) : m_otherSemaphores(nullptr)
493+
{
494+
this->operator=(std::move(other));
495+
}
490496

491497
DeferredFrameSemaphoreDrop& operator=(const DeferredFrameSemaphoreDrop& other) = delete;
492-
inline DeferredFrameSemaphoreDrop& operator=(DeferredFrameSemaphoreDrop&& other)
493-
{
498+
inline DeferredFrameSemaphoreDrop& operator=(DeferredFrameSemaphoreDrop&& other)
499+
{
494500
m_otherSemaphores = std::move(other.m_otherSemaphores);
495-
other.m_otherSemaphores = nullptr;
496-
return *this;
497-
}
498-
499-
struct single_poll_t {};
500-
static inline single_poll_t single_poll;
501-
inline bool operator()(single_poll_t _single_poll)
502-
{
503-
operator()();
504-
return true;
505-
}
501+
other.m_otherSemaphores = nullptr;
502+
return *this;
503+
}
504+
505+
struct single_poll_t {};
506+
static inline single_poll_t single_poll;
507+
inline bool operator()(single_poll_t _single_poll)
508+
{
509+
operator()();
510+
return true;
511+
}
506512

507513
inline void operator()()
508514
{
509515
m_otherSemaphores = nullptr;
510516
}
511-
};
517+
};
512518

513519
protected:
514520
ISwapchain(core::smart_refctd_ptr<const ILogicalDevice>&& dev, SCreationParams&& params, const uint8_t imageCount, core::smart_refctd_ptr<ISwapchain>&& oldSwapchain);

0 commit comments

Comments
 (0)