Skip to content

Commit 9abd247

Browse files
committed
Merge branch 'master' into more_fft_utils
2 parents afcc423 + 32f20c7 commit 9abd247

28 files changed

+940
-632
lines changed

3rdparty/dxc/dxc

Submodule dxc updated 222 files

include/nbl/asset/ICPUComputePipeline.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class ICPUComputePipeline : public ICPUPipeline<IPipeline<ICPUPipelineLayout>,1>
2525
{
2626
if (!params.layout)
2727
return nullptr;
28-
auto retval = new ICPUComputePipeline(core::smart_refctd_ptr<ICPUPipelineLayout>(params.layout));
28+
auto retval = new ICPUComputePipeline(core::smart_refctd_ptr<const ICPUPipelineLayout>(params.layout));
2929
if (!retval->setSpecInfo(params.shader))
3030
{
3131
retval->drop();
@@ -48,7 +48,7 @@ class ICPUComputePipeline : public ICPUPipeline<IPipeline<ICPUPipelineLayout>,1>
4848
using base_t::base_t;
4949
virtual ~ICPUComputePipeline() = default;
5050

51-
base_t* clone_impl(core::smart_refctd_ptr<ICPUPipelineLayout>&& layout) const override
51+
base_t* clone_impl(core::smart_refctd_ptr<const ICPUPipelineLayout>&& layout) const override
5252
{
5353
return new ICPUComputePipeline(std::move(layout));
5454
}
@@ -57,7 +57,7 @@ class ICPUComputePipeline : public ICPUPipeline<IPipeline<ICPUPipelineLayout>,1>
5757
{
5858
if (ix!=0)
5959
return m_stages[0].shader.get();
60-
return m_layout.get();
60+
return const_cast<ICPUPipelineLayout*>(m_layout.get());
6161
}
6262

6363
inline int8_t stageToIndex(const ICPUShader::E_SHADER_STAGE stage) const override

include/nbl/asset/ICPUGraphicsPipeline.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class ICPUGraphicsPipeline final : public ICPUPipeline<IGraphicsPipeline<ICPUPip
6565
using base_t::base_t;
6666
~ICPUGraphicsPipeline() = default;
6767

68-
base_t* clone_impl(core::smart_refctd_ptr<ICPUPipelineLayout>&& layout) const override
68+
base_t* clone_impl(core::smart_refctd_ptr<const ICPUPipelineLayout>&& layout) const override
6969
{
7070
std::array<ICPUShader::SSpecInfo,GRAPHICS_SHADER_STAGE_COUNT> _shaders;
7171
for (auto i=0; i<GRAPHICS_SHADER_STAGE_COUNT; i++)
@@ -80,7 +80,7 @@ class ICPUGraphicsPipeline final : public ICPUPipeline<IGraphicsPipeline<ICPUPip
8080
inline IAsset* getDependant_impl(const size_t ix) override
8181
{
8282
if (ix==0)
83-
return m_layout.get();
83+
return const_cast<ICPUPipelineLayout*>(m_layout.get());
8484
if (ix==1)
8585
return m_renderpass.get();
8686
size_t stageCount = 0;

include/nbl/asset/ICPUPipeline.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ class ICPUPipeline : public IAsset, public PipelineNonAssetBase
5151
ICPUPipelineLayout* getLayout()
5252
{
5353
assert(isMutable());
54-
return PipelineNonAssetBase::m_layout.get();
54+
return const_cast<ICPUPipelineLayout*>(PipelineNonAssetBase::m_layout.get());
5555
}
5656
const ICPUPipelineLayout* getLayout() const { return PipelineNonAssetBase::m_layout.get(); }
5757

58-
inline void setLayout(core::smart_refctd_ptr<ICPUPipelineLayout>&& _layout)
58+
inline void setLayout(core::smart_refctd_ptr<const ICPUPipelineLayout>&& _layout)
5959
{
6060
assert(isMutable());
6161
PipelineNonAssetBase::m_layout = std::move(_layout);
@@ -117,7 +117,7 @@ class ICPUPipeline : public IAsset, public PipelineNonAssetBase
117117
using PipelineNonAssetBase::PipelineNonAssetBase;
118118
virtual ~ICPUPipeline() = default;
119119

120-
virtual this_t* clone_impl(core::smart_refctd_ptr<ICPUPipelineLayout>&& layout) const = 0;
120+
virtual this_t* clone_impl(core::smart_refctd_ptr<const ICPUPipelineLayout>&& layout) const = 0;
121121
virtual int8_t stageToIndex(const ICPUShader::E_SHADER_STAGE stage) const = 0;
122122

123123
struct ShaderStage {

include/nbl/asset/IGraphicsPipeline.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ class IGraphicsPipeline : public IPipeline<PipelineLayoutType>, public IGraphics
155155

156156
protected:
157157
explicit IGraphicsPipeline(const SCreationParams& _params) :
158-
IPipeline<PipelineLayoutType>(core::smart_refctd_ptr<PipelineLayoutType>(_params.layout)),
158+
IPipeline<PipelineLayoutType>(core::smart_refctd_ptr<const PipelineLayoutType>(_params.layout)),
159159
m_params(_params.cached), m_renderpass(core::smart_refctd_ptr<renderpass_t>(_params.renderpass)) {}
160160

161161
SCachedCreationParams m_params;

include/nbl/asset/IPipeline.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class IPipeline
3535
struct SCreationParams
3636
{
3737
public:
38-
PipelineLayout* layout = nullptr;
38+
const PipelineLayout* layout = nullptr;
3939

4040
protected:
4141
// This is not public to make sure that different pipelines only get the enums they support
@@ -107,9 +107,9 @@ class IPipeline
107107
inline const PipelineLayout* getLayout() const {return m_layout.get();}
108108

109109
protected:
110-
inline IPipeline(core::smart_refctd_ptr<PipelineLayout>&& _layout) : m_layout(std::move(_layout)) {}
110+
inline IPipeline(core::smart_refctd_ptr<const PipelineLayout>&& _layout) : m_layout(std::move(_layout)) {}
111111

112-
core::smart_refctd_ptr<PipelineLayout> m_layout;
112+
core::smart_refctd_ptr<const PipelineLayout> m_layout;
113113
};
114114

115115
}

include/nbl/asset/IPipelineLayout.h

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
#ifndef _NBL_ASSET_I_PIPELINE_LAYOUT_H_INCLUDED_
55
#define _NBL_ASSET_I_PIPELINE_LAYOUT_H_INCLUDED_
66

7+
#include "nbl/macros.h"
8+
#include "nbl/core/declarations.h"
79

810
#include <algorithm>
911
#include <array>
1012

11-
#include "nbl/macros.h"
12-
#include "nbl/core/declarations.h"
13+
#include "nbl/asset/IDescriptorSetLayout.h"
14+
#include "nbl/builtin/hlsl/binding_info.hlsl"
1315

1416

1517
namespace nbl::asset
@@ -21,7 +23,7 @@ namespace nbl::asset
2123
however they serve as a fast path with regard to data upload from the
2224
CPU and data access from the GPU.
2325
24-
Note that IrrlichtBaW limits push constant size to 128 bytes.
26+
Note that Nabla limits push constant size to 128 bytes.
2527
2628
Push Constants are an alternative to an UBO where it performs really poorly,
2729
mostly very small and very frequent updates. Examples of which are:
@@ -140,6 +142,54 @@ class IPipelineLayout
140142
return static_cast<int32_t>(i)-1;
141143
}
142144

145+
// utility function, if you compile shaders for specific layouts, not create layouts given shaders
146+
struct SBindingKey
147+
{
148+
using type_bitset_t = std::bitset<static_cast<size_t>(IDescriptor::E_TYPE::ET_COUNT)>;
149+
150+
hlsl::SBindingInfo binding = {};
151+
core::bitflag<IShader::E_SHADER_STAGE> requiredStages = IShader::E_SHADER_STAGE::ESS_UNKNOWN;
152+
// could have just initialized with `~type_bitset_t()` in C++23
153+
type_bitset_t allowedTypes = type_bitset_t((0x1u<<static_cast<size_t>(IDescriptor::E_TYPE::ET_COUNT))-1);
154+
};
155+
// TODO: add constraints for stage and creation flags, or just return the storage index & redirect?
156+
core::string getBindingInfoForHLSL(const SBindingKey& key) const
157+
{
158+
if (key.binding.set>=DESCRIPTOR_SET_COUNT)
159+
return "#error \"IPipelineLayout::SBindingKey::binding::set out of range!\"";
160+
const auto* layout = m_descSetLayouts[key.binding.set].get();
161+
if (!layout)
162+
return "#error \"IPipelineLayout::SBindingKey::binding::set layout is nullptr!\"";
163+
//
164+
using redirect_t = IDescriptorSetLayoutBase::CBindingRedirect;
165+
using storage_range_index_t = redirect_t::storage_range_index_t;
166+
const redirect_t* redirect;
167+
storage_range_index_t found;
168+
{
169+
const redirect_t::binding_number_t binding(key.binding.binding);
170+
for (auto t=0u; t<static_cast<size_t>(IDescriptor::E_TYPE::ET_COUNT); t++)
171+
if (key.allowedTypes.test(t))
172+
{
173+
redirect = &layout->getDescriptorRedirect(static_cast<IDescriptor::E_TYPE>(t));
174+
found = redirect->findBindingStorageIndex(binding);
175+
if (found)
176+
break;
177+
}
178+
if (!found && key.allowedTypes.test(static_cast<size_t>(IDescriptor::E_TYPE::ET_SAMPLER)))
179+
{
180+
redirect = &layout->getImmutableSamplerRedirect();
181+
found = redirect->findBindingStorageIndex(binding);
182+
}
183+
if (!found)
184+
return "#error \"Could not find `IPipelineLayout::SBindingKey::binding::binding` in `IPipelineLayout::SBindingKey::binding::set`'s layout!\"";
185+
}
186+
if (!redirect->getStageFlags(found).hasFlags(key.requiredStages))
187+
return "#error \"Binding found in the layout doesn't have all the `IPipelineLayout::SBindingKey::binding::requiredStages` flags!\"";
188+
const auto count = redirect->getCount(found);
189+
assert(count); // this layout should have never passed validation
190+
return "::nbl::hlsl::ConstevalBindingInfo<"+std::to_string(key.binding.set)+","+std::to_string(key.binding.binding)+","+std::to_string(count)+">";
191+
}
192+
143193
protected:
144194
IPipelineLayout(
145195
const std::span<const asset::SPushConstantRange> _pcRanges,

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
{
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (C) 2024 - DevSH Graphics Programming Sp. z O.O.
2+
// This file is part of the "Nabla Engine".
3+
// For conditions of distribution and use, see copyright notice in nabla.h
4+
#ifndef _NBL_BUILTIN_HLSL_BINDING_INFO_INCLUDED_
5+
#define _NBL_BUILTIN_HLSL_BINDING_INFO_INCLUDED_
6+
7+
#include "nbl/builtin/hlsl/cpp_compat.hlsl"
8+
9+
namespace nbl
10+
{
11+
namespace hlsl
12+
{
13+
14+
template<uint32_t set, uint32_t ix, uint32_t count=1>
15+
struct ConstevalBindingInfo
16+
{
17+
NBL_CONSTEXPR_STATIC_INLINE uint32_t Set = set;
18+
NBL_CONSTEXPR_STATIC_INLINE uint32_t Index = ix;
19+
NBL_CONSTEXPR_STATIC_INLINE uint32_t Count = count;
20+
};
21+
22+
// used for descriptor set layout lookups
23+
struct SBindingInfo
24+
{
25+
//! binding index for a given resource
26+
uint32_t binding : 29;
27+
//! descriptor set index for a resource
28+
uint32_t set : 3;
29+
};
30+
31+
}
32+
}
33+
#endif

0 commit comments

Comments
 (0)