Skip to content

Commit e9add60

Browse files
committed
Make stuff in IDescriptorSetLayout protected.
1 parent 05720aa commit e9add60

File tree

4 files changed

+71
-132
lines changed

4 files changed

+71
-132
lines changed

include/nbl/asset/ICPUDescriptorSetLayout.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ namespace asset
2222

2323
class NBL_API ICPUDescriptorSetLayout : public IDescriptorSetLayout<ICPUSampler>, public IAsset
2424
{
25+
using base_t = asset::IDescriptorSetLayout<ICPUSampler>;
26+
2527
public:
2628
_NBL_STATIC_INLINE_CONSTEXPR uint32_t IMMUTABLE_SAMPLER_HIERARCHYLEVELS_BELOW = 1u;
2729

28-
using IDescriptorSetLayout<ICPUSampler>::IDescriptorSetLayout;
30+
ICPUDescriptorSetLayout(const SBinding* const _begin, const SBinding* const _end) : base_t(_begin, _end) {}
2931

3032
core::smart_refctd_ptr<IAsset> clone(uint32_t _depth = ~0u) const override
3133
{

include/nbl/asset/IDescriptorSetLayout.h

Lines changed: 56 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -102,40 +102,9 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
102102
// Use this if you want an immutable sampler that is baked into the DS layout itself.
103103
// If its `nullptr` then the sampler used is mutable and can be specified while writing the image descriptor to a binding while updating the DS.
104104
const core::smart_refctd_ptr<sampler_type>* samplers;
105-
106-
bool operator<(const SBinding& rhs) const
107-
{
108-
if (binding == rhs.binding)
109-
{
110-
// should really assert here
111-
if (type == rhs.type)
112-
{
113-
if (count == rhs.count)
114-
{
115-
if (stageFlags.value == rhs.stageFlags.value)
116-
{
117-
if (createFlags.value == rhs.createFlags.value)
118-
{
119-
for (uint32_t i = 0u; i < count; i++)
120-
{
121-
if (samplers[i] == rhs.samplers[i])
122-
continue;
123-
return samplers[i] < rhs.samplers[i];
124-
}
125-
return false;
126-
}
127-
return createFlags.value < rhs.createFlags.value;
128-
}
129-
return stageFlags.value < rhs.stageFlags.value;
130-
}
131-
return count < rhs.count;
132-
}
133-
return type < rhs.type;
134-
}
135-
return binding < rhs.binding;
136-
}
137105
};
138106

107+
// Maps a binding to a local (to descriptor set layout) offset.
139108
class CBindingRedirect
140109
{
141110
public:
@@ -198,9 +167,8 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
198167
return (index == 0u) ? 0u : m_storageOffsets[index - 1];
199168
}
200169

201-
202-
// The follwoing are merely convienience functions for one off use.
203-
// If you already have an index (the result of `searchForBinding`) lying around use the above functions for quick lookups.
170+
// The follwoing are merely convenience functions for one off use.
171+
// If you already have an index (the result of `searchForBinding`) lying around use the above functions for quick lookups, and to avoid unnecessary binary searches.
204172

205173
inline core::bitflag<IShader::E_SHADER_STAGE> getStageFlags(const binding_number_t binding) const
206174
{
@@ -341,92 +309,6 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
341309
}
342310
}
343311

344-
IDescriptorSetLayout(const SBinding* const _begin, const SBinding* const _end)
345-
{
346-
core::vector<CBindingRedirect::SBuildInfo> buildInfo_descriptors[asset::EDT_COUNT];
347-
core::vector<CBindingRedirect::SBuildInfo> buildInfo_immutableSamplers;
348-
core::vector<CBindingRedirect::SBuildInfo> buildInfo_mutableSamplers;
349-
350-
for (auto b = _begin; b != _end; ++b)
351-
{
352-
buildInfo_descriptors[b->type].emplace_back(b->binding, b->createFlags, b->stageFlags, b->count);
353-
354-
if (b->type == EDT_COMBINED_IMAGE_SAMPLER)
355-
{
356-
if (b->samplers)
357-
buildInfo_immutableSamplers.emplace_back(b->binding, b->createFlags, b->stageFlags, b->count);
358-
else
359-
buildInfo_mutableSamplers.emplace_back(b->binding, b->createFlags, b->stageFlags, b->count);
360-
}
361-
}
362-
363-
for (auto type = 0u; type < asset::EDT_COUNT; ++type)
364-
m_descriptorRedirects[type] = CBindingRedirect(std::move(buildInfo_descriptors[type]));
365-
366-
m_immutableSamplerRedirect = CBindingRedirect(std::move(buildInfo_immutableSamplers));
367-
m_mutableSamplerRedirect = CBindingRedirect(std::move(buildInfo_mutableSamplers));
368-
369-
const uint32_t immutableSamplerCount = m_immutableSamplerRedirect.getTotalCount();
370-
m_samplers = immutableSamplerCount ? core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<core::smart_refctd_ptr<sampler_type>>>(immutableSamplerCount) : nullptr;
371-
372-
for (auto b = _begin; b != _end; ++b)
373-
{
374-
if (b->type == EDT_COMBINED_IMAGE_SAMPLER && b->samplers)
375-
{
376-
const auto localOffset = m_immutableSamplerRedirect.getStorageOffset(CBindingRedirect::binding_number_t(b->binding)).data;
377-
assert(localOffset != m_immutableSamplerRedirect.Invalid);
378-
379-
auto* dst = m_samplers->begin() + localOffset;
380-
std::copy_n(b->samplers, b->count, dst);
381-
}
382-
}
383-
#if 0
384-
size_t bndCount = _end-_begin;
385-
size_t immSamplersOffset = 0u;
386-
for (size_t i = 0ull; i < bndCount; ++i)
387-
{
388-
auto& bnd_out = m_bindings->operator[](i);
389-
const auto& bnd_in = _begin[i];
390-
391-
bnd_out.binding = bnd_in.binding;
392-
bnd_out.type = bnd_in.type;
393-
bnd_out.count = bnd_in.count;
394-
bnd_out.stageFlags = bnd_in.stageFlags;
395-
bnd_out.samplers = nullptr;
396-
if (bnd_in.type==EDT_COMBINED_IMAGE_SAMPLER && bnd_in.samplers)
397-
{
398-
++immSamplersOffset;//add 1 so that bnd_out.samplers is never 0/nullptr when the binding SHOULD have imm samplers
399-
//otherwise if (bnd.samplers) won't work
400-
bnd_out.samplers = reinterpret_cast<const core::smart_refctd_ptr<sampler_type>*>(immSamplersOffset);
401-
--immSamplersOffset;//going back to prev state
402-
for (uint32_t s = 0ull; s < bnd_in.count; ++s)
403-
m_samplers->operator[](immSamplersOffset+s) = bnd_in.samplers[s];
404-
immSamplersOffset += bnd_in.count;
405-
}
406-
}
407-
408-
if (m_bindings)
409-
{
410-
for (size_t i = 0ull; i < m_bindings->size(); ++i)
411-
{
412-
auto& bnd = m_bindings->operator[](i);
413-
414-
static_assert(sizeof(size_t) == sizeof(bnd.samplers), "Bad reinterpret_cast!");
415-
if (bnd.type == EDT_COMBINED_IMAGE_SAMPLER && bnd.samplers)
416-
bnd.samplers = m_samplers->data() + reinterpret_cast<size_t>(bnd.samplers) - 1ull;
417-
}
418-
419-
// TODO: check for overlapping bindings (bad `SBinding` definitions)
420-
std::sort(m_bindings->begin(), m_bindings->end());
421-
}
422-
#endif
423-
}
424-
425-
virtual ~IDescriptorSetLayout() = default;
426-
427-
core::smart_refctd_dynamic_array<core::smart_refctd_ptr<sampler_type>> m_samplers = nullptr;
428-
429-
public:
430312
bool isIdenticallyDefined(const IDescriptorSetLayout<sampler_type>* _other) const
431313
{
432314
if (!_other || getTotalBindingCount() != _other->getTotalBindingCount())
@@ -470,7 +352,6 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
470352
}
471353
}
472354

473-
// TODO(achal): I'm not sure, should I keep these around?
474355
inline uint32_t getTotalMutableSamplerCount() const { return m_mutableSamplerRedirect.getTotalCount(); }
475356
inline uint32_t getTotalDescriptorCount(const E_DESCRIPTOR_TYPE type) const { return m_descriptorRedirects[type].getTotalCount(); }
476357

@@ -487,11 +368,63 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
487368
inline const CBindingRedirect& getImmutableSamplerRedirect() const { return m_immutableSamplerRedirect; }
488369
inline const CBindingRedirect& getMutableSamplerRedirect() const { return m_mutableSamplerRedirect; }
489370

371+
inline core::SRange<const core::smart_refctd_ptr<sampler_type>> getImmutableSamplers() const
372+
{
373+
if (!m_samplers)
374+
return { nullptr, nullptr };
375+
376+
return { m_samplers->cbegin(), m_samplers->cend() };
377+
}
378+
490379
protected:
491-
// Maps a binding number to a local (to descriptor set layout) offset, for a given descriptor type.
380+
IDescriptorSetLayout(const SBinding* const _begin, const SBinding* const _end)
381+
{
382+
core::vector<CBindingRedirect::SBuildInfo> buildInfo_descriptors[asset::EDT_COUNT];
383+
core::vector<CBindingRedirect::SBuildInfo> buildInfo_immutableSamplers;
384+
core::vector<CBindingRedirect::SBuildInfo> buildInfo_mutableSamplers;
385+
386+
for (auto b = _begin; b != _end; ++b)
387+
{
388+
buildInfo_descriptors[b->type].emplace_back(b->binding, b->createFlags, b->stageFlags, b->count);
389+
390+
if (b->type == EDT_COMBINED_IMAGE_SAMPLER)
391+
{
392+
if (b->samplers)
393+
buildInfo_immutableSamplers.emplace_back(b->binding, b->createFlags, b->stageFlags, b->count);
394+
else
395+
buildInfo_mutableSamplers.emplace_back(b->binding, b->createFlags, b->stageFlags, b->count);
396+
}
397+
}
398+
399+
for (auto type = 0u; type < asset::EDT_COUNT; ++type)
400+
m_descriptorRedirects[type] = CBindingRedirect(std::move(buildInfo_descriptors[type]));
401+
402+
m_immutableSamplerRedirect = CBindingRedirect(std::move(buildInfo_immutableSamplers));
403+
m_mutableSamplerRedirect = CBindingRedirect(std::move(buildInfo_mutableSamplers));
404+
405+
const uint32_t immutableSamplerCount = m_immutableSamplerRedirect.getTotalCount();
406+
m_samplers = immutableSamplerCount ? core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<core::smart_refctd_ptr<sampler_type>>>(immutableSamplerCount) : nullptr;
407+
408+
for (auto b = _begin; b != _end; ++b)
409+
{
410+
if (b->type == EDT_COMBINED_IMAGE_SAMPLER && b->samplers)
411+
{
412+
const auto localOffset = m_immutableSamplerRedirect.getStorageOffset(CBindingRedirect::binding_number_t(b->binding)).data;
413+
assert(localOffset != m_immutableSamplerRedirect.Invalid);
414+
415+
auto* dst = m_samplers->begin() + localOffset;
416+
std::copy_n(b->samplers, b->count, dst);
417+
}
418+
}
419+
}
420+
421+
virtual ~IDescriptorSetLayout() = default;
422+
492423
CBindingRedirect m_descriptorRedirects[asset::EDT_COUNT];
493424
CBindingRedirect m_immutableSamplerRedirect;
494425
CBindingRedirect m_mutableSamplerRedirect;
426+
427+
core::smart_refctd_dynamic_array<core::smart_refctd_ptr<sampler_type>> m_samplers = nullptr;
495428
};
496429

497430
}

include/nbl/video/utilities/IGPUObjectFromAssetConverter.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,7 +1331,7 @@ auto IGPUObjectFromAssetConverter::create(const asset::ICPUDescriptorSetLayout**
13311331
auto res = core::make_refctd_dynamic_array<created_gpu_object_array<asset::ICPUDescriptorSetLayout> >(assetCount);
13321332

13331333
// This is a descriptor set layout function, we only care about immutable samplers here.
1334-
core::vector<asset::ICPUSampler*> cpuSamplers;
1334+
core::vector<const asset::ICPUSampler*> cpuSamplers;
13351335
size_t maxSamplers = 0ull;
13361336
size_t maxBindingsPerLayout = 0ull;
13371337
size_t maxSamplersPerLayout = 0ull;
@@ -1347,9 +1347,10 @@ auto IGPUObjectFromAssetConverter::create(const asset::ICPUDescriptorSetLayout**
13471347

13481348
for (auto dsl : core::SRange<const asset::ICPUDescriptorSetLayout*>(_begin, _end))
13491349
{
1350-
if (dsl->m_samplers)
1350+
const auto& samplers = dsl->getImmutableSamplers();
1351+
if (!samplers.empty())
13511352
{
1352-
for (auto& sampler : *dsl->m_samplers)
1353+
for (auto& sampler : samplers)
13531354
cpuSamplers.push_back(sampler.get());
13541355
}
13551356
}

src/nbl/video/CVulkanCommandBuffer.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -479,12 +479,15 @@ bool CVulkanCommandBuffer::bindDescriptorSets_impl(asset::E_PIPELINE_BIND_POINT
479479

480480
if (dynamicOffsets) // count dynamic offsets per set, if there are any
481481
{
482-
auto bindings = pDescriptorSets[i]->getLayout()->getBindings();
483-
for (const auto& binding : bindings)
482+
auto addDynamicOffsetCount = [&dynamicOffsetCountPerSet, i](const IGPUDescriptorSetLayout::CBindingRedirect& descriptorBindingRedirect)
484483
{
485-
if ((binding.type == asset::EDT_STORAGE_BUFFER_DYNAMIC) || (binding.type == asset::EDT_UNIFORM_BUFFER_DYNAMIC))
486-
dynamicOffsetCountPerSet[i] += binding.count;
487-
}
484+
const auto declaredBindingCount = descriptorBindingRedirect.getBindingCount();
485+
for (uint32_t b = 0; b < declaredBindingCount; ++b)
486+
dynamicOffsetCountPerSet[i] += descriptorBindingRedirect.getCount(b);
487+
};
488+
489+
addDynamicOffsetCount(pDescriptorSets[i]->getLayout()->getDescriptorRedirect(asset::EDT_STORAGE_BUFFER_DYNAMIC));
490+
addDynamicOffsetCount(pDescriptorSets[i]->getLayout()->getDescriptorRedirect(asset::EDT_UNIFORM_BUFFER_DYNAMIC));
488491
}
489492
}
490493
}

0 commit comments

Comments
 (0)