Skip to content

Commit 05720aa

Browse files
committed
Remove the AoS m_bindings from IDescriptorSetLayout<SamplerType>.
1 parent db9f337 commit 05720aa

File tree

2 files changed

+131
-93
lines changed

2 files changed

+131
-93
lines changed

include/nbl/asset/ICPUDescriptorSetLayout.h

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -32,43 +32,54 @@ class NBL_API ICPUDescriptorSetLayout : public IDescriptorSetLayout<ICPUSampler>
3232
auto cp = core::make_smart_refctd_ptr<ICPUDescriptorSetLayout>(nullptr, nullptr);
3333
clone_common(cp.get());
3434

35-
if (_depth > 0u && m_bindings)
35+
for (uint32_t t = 0; t < asset::EDT_COUNT; ++t)
36+
cp->m_descriptorRedirects[t] = m_descriptorRedirects[t].clone();
37+
cp->m_immutableSamplerRedirect = m_immutableSamplerRedirect.clone();
38+
cp->m_mutableSamplerRedirect = m_mutableSamplerRedirect.clone();
39+
40+
if (m_samplers)
3641
{
37-
cp->m_bindings = core::make_refctd_dynamic_array<decltype(m_bindings)>(m_bindings->size());
38-
cp->m_samplers = m_samplers ? core::make_refctd_dynamic_array<decltype(m_samplers)>(m_samplers->size()) : nullptr;
42+
cp->m_samplers = core::make_refctd_dynamic_array<decltype(m_samplers)>(m_samplers->size());
3943

40-
for (size_t i = 0ull; i < m_bindings->size(); ++i)
41-
{
42-
(*cp->m_bindings)[i] = (*m_bindings)[i];
43-
if ((*cp->m_bindings)[i].samplers)
44-
(*cp->m_bindings)[i].samplers = cp->m_samplers->begin() + ((*cp->m_bindings)[i].samplers - m_samplers->begin());
45-
}
46-
if (cp->m_samplers)
44+
if (_depth > 0u)
4745
{
4846
for (size_t i = 0ull; i < m_samplers->size(); ++i)
4947
(*cp->m_samplers)[i] = core::smart_refctd_ptr_static_cast<ICPUSampler>((*m_samplers)[i]->clone(_depth - 1u));
5048
}
51-
}
52-
else
53-
{
54-
cp->m_bindings = m_bindings;
55-
cp->m_samplers = m_samplers;
49+
else
50+
{
51+
std::copy(m_samplers->begin(), m_samplers->end(), cp->m_samplers->begin());
52+
}
5653
}
5754

5855
return cp;
5956
}
6057

61-
size_t conservativeSizeEstimate() const override { return m_bindings->size()*sizeof(SBinding)+m_samplers->size()*sizeof(void*); }
58+
size_t conservativeSizeEstimate() const override
59+
{
60+
size_t result = 0ull;
61+
for (uint32_t t = 0; t < asset::EDT_COUNT; ++t)
62+
result += m_descriptorRedirects[t].conservativeSizeEstimate();
63+
result += m_immutableSamplerRedirect.conservativeSizeEstimate();
64+
result += m_mutableSamplerRedirect.conservativeSizeEstimate();
65+
66+
result += m_samplers->size() * sizeof(void*);
67+
68+
return result;
69+
}
70+
6271
void convertToDummyObject(uint32_t referenceLevelsBelowToConvert=0u) override
6372
{
6473
convertToDummyObject_common(referenceLevelsBelowToConvert);
6574

6675
if (referenceLevelsBelowToConvert)
6776
{
6877
--referenceLevelsBelowToConvert;
69-
if (m_samplers)
70-
for (auto it=m_samplers->begin(); it!=m_samplers->end(); it++)
71-
it->get()->convertToDummyObject(referenceLevelsBelowToConvert);
78+
if (m_samplers)
79+
{
80+
for (auto it=m_samplers->begin(); it!=m_samplers->end(); it++)
81+
it->get()->convertToDummyObject(referenceLevelsBelowToConvert);
82+
}
7283
}
7384
}
7485

@@ -78,16 +89,20 @@ class NBL_API ICPUDescriptorSetLayout : public IDescriptorSetLayout<ICPUSampler>
7889
bool canBeRestoredFrom(const IAsset* _other) const override
7990
{
8091
auto* other = static_cast<const ICPUDescriptorSetLayout*>(_other);
81-
if (m_bindings->size() != other->m_bindings->size())
92+
if (getTotalBindingCount() != other->getTotalBindingCount())
8293
return false;
8394
if ((!m_samplers) != (!other->m_samplers))
8495
return false;
8596
if (m_samplers && m_samplers->size() != other->m_samplers->size())
8697
return false;
8798
if (m_samplers)
99+
{
88100
for (uint32_t i = 0u; i < m_samplers->size(); ++i)
101+
{
89102
if (!(*m_samplers)[i]->canBeRestoredFrom((*other->m_samplers)[i].get()))
90103
return false;
104+
}
105+
}
91106

92107
return true;
93108
}
@@ -102,17 +117,23 @@ class NBL_API ICPUDescriptorSetLayout : public IDescriptorSetLayout<ICPUSampler>
102117

103118
--_levelsBelow;
104119
if (m_samplers)
105-
for (uint32_t i = 0u; i < m_samplers->size(); ++i)
106-
restoreFromDummy_impl_call((*m_samplers)[i].get(), (*other->m_samplers)[i].get(), _levelsBelow);
120+
{
121+
for (uint32_t i = 0u; i < m_samplers->size(); ++i)
122+
restoreFromDummy_impl_call((*m_samplers)[i].get(), (*other->m_samplers)[i].get(), _levelsBelow);
123+
}
107124
}
108125

109126
bool isAnyDependencyDummy_impl(uint32_t _levelsBelow) const override
110127
{
111128
--_levelsBelow;
112129
if (m_samplers)
130+
{
113131
for (uint32_t i = 0u; i < m_samplers->size(); ++i)
132+
{
114133
if ((*m_samplers)[i]->isAnyDependencyDummy(_levelsBelow))
115134
return true;
135+
}
136+
}
116137
return false;
117138
}
118139

include/nbl/asset/IDescriptorSetLayout.h

Lines changed: 88 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -153,49 +153,49 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
153153
uint32_t data;
154154
};
155155

156-
inline uint32_t getBindingCount() const { return count; }
156+
inline uint32_t getBindingCount() const { return m_count; }
157157

158-
// Returns index into the binding property arrays below (including `storageOffsets`), for the given binding number `binding`.
159-
// Assumes `bindingNumbers` is sorted and that there are no duplicate values in it.
158+
// Returns index into the binding property arrays below (including `m_storageOffsets`), for the given binding number `binding`.
159+
// Assumes `m_bindingNumbers` is sorted and that there are no duplicate values in it.
160160
inline uint32_t searchForBinding(const binding_number_t binding) const
161161
{
162-
if (!bindingNumbers)
162+
if (!m_bindingNumbers)
163163
return Invalid;
164164

165-
assert(storageOffsets && (count != 0u));
165+
assert(m_storageOffsets && (m_count != 0u));
166166

167-
auto found = std::lower_bound(bindingNumbers, bindingNumbers + count, binding, [](binding_number_t a, binding_number_t b) -> bool {return a.data < b.data; });
167+
auto found = std::lower_bound(m_bindingNumbers, m_bindingNumbers + m_count, binding, [](binding_number_t a, binding_number_t b) -> bool {return a.data < b.data; });
168168

169-
if ((found >= bindingNumbers + count) || (found->data != binding.data))
169+
if ((found >= m_bindingNumbers + m_count) || (found->data != binding.data))
170170
return Invalid;
171171

172-
const uint32_t foundIndex = found - bindingNumbers;
173-
assert(foundIndex < count);
172+
const uint32_t foundIndex = found - m_bindingNumbers;
173+
assert(foundIndex < m_count);
174174
return foundIndex;
175175
}
176176

177177
inline binding_number_t getBindingNumber(const uint32_t index) const
178178
{
179-
assert(index < count);
180-
return bindingNumbers[index];
179+
assert(index < m_count);
180+
return m_bindingNumbers[index];
181181
}
182182

183183
inline core::bitflag<IShader::E_SHADER_STAGE> getStageFlags(const uint32_t index) const
184184
{
185-
assert(index < count);
186-
return stageFlags[index];
185+
assert(index < m_count);
186+
return m_stageFlags[index];
187187
}
188188

189189
inline uint32_t getCount(const uint32_t index) const
190190
{
191-
assert(index < count);
192-
return (index == 0u) ? storageOffsets[index].data : storageOffsets[index].data - storageOffsets[index - 1].data;
191+
assert(index < m_count);
192+
return (index == 0u) ? m_storageOffsets[index].data : m_storageOffsets[index].data - m_storageOffsets[index - 1].data;
193193
}
194194

195195
inline storage_offset_t getStorageOffset(const uint32_t index) const
196196
{
197-
assert(index < count);
198-
return (index == 0u) ? 0u : storageOffsets[index - 1];
197+
assert(index < m_count);
198+
return (index == 0u) ? 0u : m_storageOffsets[index - 1];
199199
}
200200

201201

@@ -229,7 +229,7 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
229229
return getStorageOffset(index);
230230
}
231231

232-
inline uint32_t getTotalCount() const { return (count == 0ull) ? 0u : storageOffsets[count - 1].data; }
232+
inline uint32_t getTotalCount() const { return (m_count == 0ull) ? 0u : m_storageOffsets[m_count - 1].data; }
233233

234234
private:
235235
friend class IDescriptorSetLayout;
@@ -245,81 +245,87 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
245245

246246
inline CBindingRedirect() = default;
247247

248-
CBindingRedirect(core::vector<SBuildInfo>&& info) : count(static_cast<uint32_t>(info.size()))
248+
CBindingRedirect(core::vector<SBuildInfo>&& info) : m_count(static_cast<uint32_t>(info.size()))
249249
{
250-
if (count <= 0)
250+
if (m_count <= 0)
251251
return;
252252

253-
const size_t requiredMemSize = count * (
254-
sizeof(binding_number_t) +
255-
sizeof(core::bitflag<typename SBinding::E_CREATE_FLAGS>) +
256-
sizeof(core::bitflag<IShader::E_SHADER_STAGE>) +
257-
sizeof(storage_offset_t));
253+
init();
254+
255+
std::sort(info.begin(), info.end());
258256

259-
data = std::make_unique<uint8_t[]>(requiredMemSize);
257+
for (size_t i = 0; i < info.size(); ++i)
260258
{
261-
uint64_t offset = 0ull;
259+
m_bindingNumbers[i].data = info[i].binding;
260+
m_createFlags[i] = info[i].createFlags;
261+
m_stageFlags[i] = info[i].stageFlags;
262+
m_storageOffsets[i].data = info[i].count;
263+
}
264+
265+
std::inclusive_scan(m_storageOffsets, m_storageOffsets + m_count, m_storageOffsets,
266+
[](storage_offset_t a, storage_offset_t b) -> storage_offset_t { return storage_offset_t{ a.data + b.data }; }, storage_offset_t{ 0u });
267+
}
262268

263-
bindingNumbers = reinterpret_cast<binding_number_t*>(data.get() + offset);
264-
offset += count * sizeof(binding_number_t);
269+
inline void init()
270+
{
271+
const size_t requiredMemSize = getRequiredMemorySize();
272+
m_data = std::make_unique<uint8_t[]>(requiredMemSize);
273+
{
274+
assert(m_count > 0);
265275

266-
createFlags = reinterpret_cast<core::bitflag<typename SBinding::E_CREATE_FLAGS>*>(data.get() + offset);
267-
offset += count * sizeof(core::bitflag<typename SBinding::E_CREATE_FLAGS>);
276+
uint64_t offset = 0ull;
268277

269-
stageFlags = reinterpret_cast<core::bitflag<IShader::E_SHADER_STAGE>*>(data.get() + offset);
270-
offset += count * sizeof(core::bitflag<IShader::E_SHADER_STAGE>);
278+
m_bindingNumbers = reinterpret_cast<binding_number_t*>(m_data.get() + offset);
279+
offset += m_count * sizeof(binding_number_t);
271280

272-
storageOffsets = reinterpret_cast<storage_offset_t*>(data.get() + offset);
273-
offset += count * sizeof(storage_offset_t);
281+
m_createFlags = reinterpret_cast<core::bitflag<typename SBinding::E_CREATE_FLAGS>*>(m_data.get() + offset);
282+
offset += m_count * sizeof(core::bitflag<typename SBinding::E_CREATE_FLAGS>);
274283

275-
assert(offset == requiredMemSize);
276-
}
284+
m_stageFlags = reinterpret_cast<core::bitflag<IShader::E_SHADER_STAGE>*>(m_data.get() + offset);
285+
offset += m_count * sizeof(core::bitflag<IShader::E_SHADER_STAGE>);
277286

278-
std::sort(info.begin(), info.end());
287+
m_storageOffsets = reinterpret_cast<storage_offset_t*>(m_data.get() + offset);
288+
offset += m_count * sizeof(storage_offset_t);
279289

280-
for (size_t i = 0; i < info.size(); ++i)
281-
{
282-
bindingNumbers[i].data = info[i].binding;
283-
createFlags[i] = info[i].createFlags;
284-
stageFlags[i] = info[i].stageFlags;
285-
storageOffsets[i].data = info[i].count;
290+
assert(offset == requiredMemSize);
286291
}
292+
}
287293

288-
std::inclusive_scan(storageOffsets, storageOffsets + count, storageOffsets,
289-
[](storage_offset_t a, storage_offset_t b) -> storage_offset_t { return storage_offset_t{ a.data + b.data }; }, storage_offset_t{ 0u });
294+
inline size_t getRequiredMemorySize() const
295+
{
296+
const size_t result = m_count * (
297+
sizeof(binding_number_t) +
298+
sizeof(core::bitflag<typename SBinding::E_CREATE_FLAGS>) +
299+
sizeof(core::bitflag<IShader::E_SHADER_STAGE>) +
300+
sizeof(storage_offset_t));
301+
return result;
290302
}
291303

292304
friend class ICPUDescriptorSetLayout;
293-
#if 0
294305
inline CBindingRedirect clone() const
295306
{
296307
CBindingRedirect result;
297-
result.count = count;
298-
299-
const size_t requiredMemSize = dataAllocator.get_total_size();
300-
assert(requiredMemSize == dataAllocator.get_allocated_size());
301-
result.data = std::make_unique<uint8_t[]>(requiredMemSize);
302-
result.dataAllocator = core::LinearAddressAllocator<uint32_t>(nullptr, 0u, 0u, 1u, requiredMemSize);
308+
result.m_count = m_count;
303309

304-
memcpy(result.data.get(), data.get(), requiredMemSize);
305-
306-
result.bindingNumbers = reinterpret_cast<binding_number_t*>(result.data.get() + result.dataAllocator.alloc_addr(result.count * sizeof(binding_number_t), 1u));
307-
result.createFlags = reinterpret_cast<core::bitflag<typename SBinding::E_CREATE_FLAGS>*>(result.data.get() + result.dataAllocator.alloc_addr(result.count * sizeof(core::bitflag<typename SBinding::E_CREATE_FLAGS>), 1u));
308-
result.stageFlags = reinterpret_cast<core::bitflag<IShader::E_SHADER_STAGE>*>(result.data.get() + result.dataAllocator.alloc_addr(result.count * sizeof(core::bitflag<IShader::E_SHADER_STAGE>), 1u));
309-
result.storageOffsets = reinterpret_cast<storage_offset_t*>(result.data.get() + result.dataAllocator.alloc_addr(result.count * sizeof(storage_offset_t), 1u));
310+
if (result.m_count > 0)
311+
{
312+
result.init();
313+
memcpy(result.m_data.get(), m_data.get(), getRequiredMemorySize());
314+
}
310315

311316
return result;
312317
}
313-
#endif
314318

315-
uint32_t count = 0u;
319+
inline size_t conservativeSizeEstimate() const { return getRequiredMemorySize() + sizeof(*this); }
320+
321+
uint32_t m_count = 0u;
316322

317-
binding_number_t* bindingNumbers = nullptr;
318-
core::bitflag<typename SBinding::E_CREATE_FLAGS>* createFlags = nullptr;
319-
core::bitflag<IShader::E_SHADER_STAGE>* stageFlags = nullptr;
320-
storage_offset_t* storageOffsets = nullptr;
323+
binding_number_t* m_bindingNumbers = nullptr;
324+
core::bitflag<typename SBinding::E_CREATE_FLAGS>* m_createFlags = nullptr;
325+
core::bitflag<IShader::E_SHADER_STAGE>* m_stageFlags = nullptr;
326+
storage_offset_t* m_storageOffsets = nullptr;
321327

322-
std::unique_ptr<uint8_t[]> data = nullptr;
328+
std::unique_ptr<uint8_t[]> m_data = nullptr;
323329
};
324330

325331
// utility functions
@@ -335,8 +341,7 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
335341
}
336342
}
337343

338-
IDescriptorSetLayout(const SBinding* const _begin, const SBinding* const _end) :
339-
m_bindings((_end-_begin) ? core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<SBinding>>(_end-_begin) : nullptr)
344+
IDescriptorSetLayout(const SBinding* const _begin, const SBinding* const _end)
340345
{
341346
core::vector<CBindingRedirect::SBuildInfo> buildInfo_descriptors[asset::EDT_COUNT];
342347
core::vector<CBindingRedirect::SBuildInfo> buildInfo_immutableSamplers;
@@ -364,6 +369,18 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
364369
const uint32_t immutableSamplerCount = m_immutableSamplerRedirect.getTotalCount();
365370
m_samplers = immutableSamplerCount ? core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<core::smart_refctd_ptr<sampler_type>>>(immutableSamplerCount) : nullptr;
366371

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
367384
size_t bndCount = _end-_begin;
368385
size_t immSamplersOffset = 0u;
369386
for (size_t i = 0ull; i < bndCount; ++i)
@@ -402,12 +419,12 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
402419
// TODO: check for overlapping bindings (bad `SBinding` definitions)
403420
std::sort(m_bindings->begin(), m_bindings->end());
404421
}
422+
#endif
405423
}
406424

407425
virtual ~IDescriptorSetLayout() = default;
408426

409-
core::smart_refctd_dynamic_array<SBinding> m_bindings; // TODO(achal): Shoudn't need this anymore.
410-
core::smart_refctd_dynamic_array<core::smart_refctd_ptr<sampler_type>> m_samplers;
427+
core::smart_refctd_dynamic_array<core::smart_refctd_ptr<sampler_type>> m_samplers = nullptr;
411428

412429
public:
413430
bool isIdenticallyDefined(const IDescriptorSetLayout<sampler_type>* _other) const
@@ -425,7 +442,7 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
425442

426443
for (uint32_t i = 0u; i < bindingCount; ++i)
427444
{
428-
const bool equal = (lhs.bindingNumbers[i].data == rhs.bindingNumbers[i].data) && (lhs.createFlags[i].value == rhs.createFlags[i].value) && (lhs.stageFlags[i].value == rhs.stageFlags[i].value) && (lhs.getCount(i) == rhs.getCount(i));
445+
const bool equal = (lhs.m_bindingNumbers[i].data == rhs.m_bindingNumbers[i].data) && (lhs.m_createFlags[i].value == rhs.m_createFlags[i].value) && (lhs.m_stageFlags[i].value == rhs.m_stageFlags[i].value) && (lhs.getCount(i) == rhs.getCount(i));
429446
if (!equal)
430447
return false;
431448
}

0 commit comments

Comments
 (0)