Skip to content

Commit db9f337

Browse files
committed
Still in the process of eliminating the AoS SBindings from IDescriptorSetLayout<SamplerType>; remove LinearAddressAllocator from CBindingRedirect, add a CBindingRedirect for immutable samplers.
1 parent dbf917a commit db9f337

File tree

9 files changed

+218
-158
lines changed

9 files changed

+218
-158
lines changed

include/nbl/asset/ICPUDescriptorSet.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ class NBL_API ICPUDescriptorSet final : public IDescriptorSet<ICPUDescriptorSetL
195195
if (bindingNumberIndex == redirect.Invalid)
196196
return { {nullptr, nullptr}, {nullptr, nullptr} };
197197

198-
const auto descriptorOffset = redirect.getStorageOffset(binding, bindingNumberIndex).data;
199-
const auto descriptorCount = redirect.getDescriptorCount(binding, bindingNumberIndex);
198+
const auto descriptorOffset = redirect.getStorageOffset(bindingNumberIndex).data;
199+
const auto descriptorCount = redirect.getCount(bindingNumberIndex);
200200

201201
auto descriptorsBegin = m_descriptors[type]->begin() + descriptorOffset;
202202
auto descriptorInfosBegin = m_descriptorInfos[type]->begin() + descriptorOffset;
@@ -206,16 +206,16 @@ class NBL_API ICPUDescriptorSet final : public IDescriptorSet<ICPUDescriptorSetL
206206

207207
core::SRange<core::smart_refctd_ptr<ICPUSampler>> getMutableSamplers(const uint32_t binding) const
208208
{
209-
const auto& redirect = getLayout()->getSamplerRedirect();
209+
const auto& redirect = getLayout()->getMutableSamplerRedirect();
210210

211211
const auto bindingNumberIndex = redirect.searchForBinding(binding);
212212
if (bindingNumberIndex == redirect.Invalid)
213213
return { nullptr, nullptr };
214214

215-
const auto offset = redirect.getStorageOffset(binding, bindingNumberIndex).data;
215+
const auto offset = redirect.getStorageOffset(bindingNumberIndex).data;
216216
assert(offset != redirect.Invalid);
217217

218-
const auto count = redirect.getDescriptorCount(binding, bindingNumberIndex);
218+
const auto count = redirect.getCount(bindingNumberIndex);
219219

220220
auto samplersBegin = m_mutableSamplers->begin() + offset;
221221
return { samplersBegin, samplersBegin + count };

include/nbl/asset/IDescriptorSetLayout.h

Lines changed: 116 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -155,55 +155,82 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
155155

156156
inline uint32_t getBindingCount() const { return count; }
157157

158-
inline storage_offset_t getStorageOffset(const binding_number_t binding, uint32_t index = Invalid) const
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.
160+
inline uint32_t searchForBinding(const binding_number_t binding) const
159161
{
160-
if (index == Invalid)
161-
{
162-
index = searchForBinding(binding);
163-
if (index == Invalid)
164-
return Invalid;
165-
}
162+
if (!bindingNumbers)
163+
return Invalid;
166164

167-
return (index == 0u) ? 0u : storageOffsets[index - 1];
165+
assert(storageOffsets && (count != 0u));
166+
167+
auto found = std::lower_bound(bindingNumbers, bindingNumbers + count, binding, [](binding_number_t a, binding_number_t b) -> bool {return a.data < b.data; });
168+
169+
if ((found >= bindingNumbers + count) || (found->data != binding.data))
170+
return Invalid;
171+
172+
const uint32_t foundIndex = found - bindingNumbers;
173+
assert(foundIndex < count);
174+
return foundIndex;
168175
}
169176

170-
inline uint32_t getDescriptorCount(const binding_number_t binding, uint32_t index = Invalid) const
177+
inline binding_number_t getBindingNumber(const uint32_t index) const
171178
{
172-
if (index == Invalid)
173-
{
174-
index = searchForBinding(binding);
175-
if (index == Invalid)
176-
return Invalid;
177-
}
179+
assert(index < count);
180+
return bindingNumbers[index];
181+
}
178182

183+
inline core::bitflag<IShader::E_SHADER_STAGE> getStageFlags(const uint32_t index) const
184+
{
185+
assert(index < count);
186+
return stageFlags[index];
187+
}
188+
189+
inline uint32_t getCount(const uint32_t index) const
190+
{
191+
assert(index < count);
179192
return (index == 0u) ? storageOffsets[index].data : storageOffsets[index].data - storageOffsets[index - 1].data;
180193
}
181194

182-
inline uint32_t getTotalDescriptorCount() const { return (count == 0ull) ? 0u : storageOffsets[count - 1].data; }
195+
inline storage_offset_t getStorageOffset(const uint32_t index) const
196+
{
197+
assert(index < count);
198+
return (index == 0u) ? 0u : storageOffsets[index - 1];
199+
}
183200

184-
// TODO(achal): I shouldn't be needing these anymore.
185-
inline const binding_number_t* getBindingNumbers() const { return bindingNumbers; }
186-
inline const storage_offset_t* getStorageOffsets() const { return storageOffsets; }
187201

188-
// Returns index into the binding property arrays below (including `storageOffsets`), for the given binding number `binding`.
189-
// Assumes `bindingNumbers` is sorted and that there are no duplicate values in it.
190-
inline uint32_t searchForBinding(const binding_number_t binding) const
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.
204+
205+
inline core::bitflag<IShader::E_SHADER_STAGE> getStageFlags(const binding_number_t binding) const
191206
{
192-
if (!bindingNumbers)
207+
const auto index = searchForBinding(binding);
208+
if (index == Invalid)
193209
return Invalid;
194210

195-
assert(storageOffsets && (count != 0u));
211+
return getStageFlags(index);
212+
}
196213

197-
auto found = std::lower_bound(bindingNumbers, bindingNumbers + count, binding, [](binding_number_t a, binding_number_t b) -> bool {return a.data < b.data; });
214+
inline uint32_t getCount(const binding_number_t binding) const
215+
{
216+
const auto index = searchForBinding(binding);
217+
if (index == Invalid)
218+
return Invalid;
198219

199-
if ((found >= bindingNumbers + count) || (found->data != binding.data))
220+
return getDescriptorCount(index);
221+
}
222+
223+
inline storage_offset_t getStorageOffset(const binding_number_t binding) const
224+
{
225+
const auto index = searchForBinding(binding);
226+
if (index == Invalid)
200227
return Invalid;
201228

202-
const uint32_t foundIndex = found - bindingNumbers;
203-
assert(foundIndex < count);
204-
return foundIndex;
229+
return getStorageOffset(index);
205230
}
206231

232+
inline uint32_t getTotalCount() const { return (count == 0ull) ? 0u : storageOffsets[count - 1].data; }
233+
207234
private:
208235
friend class IDescriptorSetLayout;
209236
struct SBuildInfo
@@ -230,12 +257,23 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
230257
sizeof(storage_offset_t));
231258

232259
data = std::make_unique<uint8_t[]>(requiredMemSize);
233-
dataAllocator = core::LinearAddressAllocator<uint32_t>(nullptr, 0u, 0u, 1u, requiredMemSize);
260+
{
261+
uint64_t offset = 0ull;
262+
263+
bindingNumbers = reinterpret_cast<binding_number_t*>(data.get() + offset);
264+
offset += count * sizeof(binding_number_t);
265+
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>);
234268

235-
bindingNumbers = reinterpret_cast<binding_number_t*>(data.get() + dataAllocator.alloc_addr(count * sizeof(binding_number_t), 1u));
236-
createFlags = reinterpret_cast<core::bitflag<typename SBinding::E_CREATE_FLAGS>*>(data.get() + dataAllocator.alloc_addr(count * sizeof(core::bitflag<typename SBinding::E_CREATE_FLAGS>), 1u));
237-
stageFlags = reinterpret_cast<core::bitflag<IShader::E_SHADER_STAGE>*>(data.get() + dataAllocator.alloc_addr(count * sizeof(core::bitflag<IShader::E_SHADER_STAGE>), 1u));
238-
storageOffsets = reinterpret_cast<storage_offset_t*>(data.get() + dataAllocator.alloc_addr(count * sizeof(storage_offset_t), 1u));
269+
stageFlags = reinterpret_cast<core::bitflag<IShader::E_SHADER_STAGE>*>(data.get() + offset);
270+
offset += count * sizeof(core::bitflag<IShader::E_SHADER_STAGE>);
271+
272+
storageOffsets = reinterpret_cast<storage_offset_t*>(data.get() + offset);
273+
offset += count * sizeof(storage_offset_t);
274+
275+
assert(offset == requiredMemSize);
276+
}
239277

240278
std::sort(info.begin(), info.end());
241279

@@ -251,6 +289,29 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
251289
[](storage_offset_t a, storage_offset_t b) -> storage_offset_t { return storage_offset_t{ a.data + b.data }; }, storage_offset_t{ 0u });
252290
}
253291

292+
friend class ICPUDescriptorSetLayout;
293+
#if 0
294+
inline CBindingRedirect clone() const
295+
{
296+
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);
303+
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+
311+
return result;
312+
}
313+
#endif
314+
254315
uint32_t count = 0u;
255316

256317
binding_number_t* bindingNumbers = nullptr;
@@ -259,7 +320,6 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
259320
storage_offset_t* storageOffsets = nullptr;
260321

261322
std::unique_ptr<uint8_t[]> data = nullptr;
262-
core::LinearAddressAllocator<uint32_t> dataAllocator;
263323
};
264324

265325
// utility functions
@@ -279,26 +339,32 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
279339
m_bindings((_end-_begin) ? core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<SBinding>>(_end-_begin) : nullptr)
280340
{
281341
core::vector<CBindingRedirect::SBuildInfo> buildInfo_descriptors[asset::EDT_COUNT];
282-
core::vector<CBindingRedirect::SBuildInfo> buildInfo_samplers;
342+
core::vector<CBindingRedirect::SBuildInfo> buildInfo_immutableSamplers;
343+
core::vector<CBindingRedirect::SBuildInfo> buildInfo_mutableSamplers;
283344

284345
for (auto b = _begin; b != _end; ++b)
285346
{
286347
buildInfo_descriptors[b->type].emplace_back(b->binding, b->createFlags, b->stageFlags, b->count);
287-
if (b->type == EDT_COMBINED_IMAGE_SAMPLER && b->samplers == nullptr)
288-
buildInfo_samplers.emplace_back(b->binding, b->createFlags, b->stageFlags, b->count);
348+
349+
if (b->type == EDT_COMBINED_IMAGE_SAMPLER)
350+
{
351+
if (b->samplers)
352+
buildInfo_immutableSamplers.emplace_back(b->binding, b->createFlags, b->stageFlags, b->count);
353+
else
354+
buildInfo_mutableSamplers.emplace_back(b->binding, b->createFlags, b->stageFlags, b->count);
355+
}
289356
}
290357

291358
for (auto type = 0u; type < asset::EDT_COUNT; ++type)
292359
m_descriptorRedirects[type] = CBindingRedirect(std::move(buildInfo_descriptors[type]));
293-
m_samplerRedirects = CBindingRedirect(std::move(buildInfo_samplers));
294360

295-
const uint32_t immutableSamplerCount = m_descriptorRedirects[EDT_COMBINED_IMAGE_SAMPLER].getTotalDescriptorCount() - m_samplerRedirects.getTotalDescriptorCount();
296-
assert(static_cast<int32_t>(immutableSamplerCount) >= 0);
361+
m_immutableSamplerRedirect = CBindingRedirect(std::move(buildInfo_immutableSamplers));
362+
m_mutableSamplerRedirect = CBindingRedirect(std::move(buildInfo_mutableSamplers));
297363

364+
const uint32_t immutableSamplerCount = m_immutableSamplerRedirect.getTotalCount();
298365
m_samplers = immutableSamplerCount ? core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<core::smart_refctd_ptr<sampler_type>>>(immutableSamplerCount) : nullptr;
299366

300367
size_t bndCount = _end-_begin;
301-
302368
size_t immSamplersOffset = 0u;
303369
for (size_t i = 0ull; i < bndCount; ++i)
304370
{
@@ -359,7 +425,7 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
359425

360426
for (uint32_t i = 0u; i < bindingCount; ++i)
361427
{
362-
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.getDescriptorCount(lhs.bindingNumbers[i], i) == rhs.getDescriptorCount(rhs.bindingNumbers[i], i));
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));
363429
if (!equal)
364430
return false;
365431
}
@@ -387,11 +453,9 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
387453
}
388454
}
389455

390-
// TODO(achal): I shouldn't be needing these anymore.
391-
inline size_t getTotalMutableSamplerCount() const { return m_samplerRedirects.getTotalDescriptorCount(); }
392-
inline size_t getTotalDescriptorCount(const E_DESCRIPTOR_TYPE type) const { return m_descriptorRedirects[type].getTotalDescriptorCount(); }
393-
394-
core::SRange<const SBinding> getBindings() const { return {m_bindings->data(), m_bindings->data()+m_bindings->size()}; }
456+
// TODO(achal): I'm not sure, should I keep these around?
457+
inline uint32_t getTotalMutableSamplerCount() const { return m_mutableSamplerRedirect.getTotalCount(); }
458+
inline uint32_t getTotalDescriptorCount(const E_DESCRIPTOR_TYPE type) const { return m_descriptorRedirects[type].getTotalCount(); }
395459

396460
inline uint32_t getTotalBindingCount() const
397461
{
@@ -403,16 +467,14 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
403467
}
404468

405469
inline const CBindingRedirect& getDescriptorRedirect(const E_DESCRIPTOR_TYPE type) const { return m_descriptorRedirects[type]; }
406-
inline const CBindingRedirect& getSamplerRedirect() const { return m_samplerRedirects; }
407-
408-
// TODO(achal): I shouldn't be needing these anymore.
409-
inline uint32_t getDescriptorOffset(const E_DESCRIPTOR_TYPE type, const uint32_t binding) const { return m_descriptorRedirects[type].getStorageOffset(binding).data; }
410-
inline uint32_t getMutableSamplerOffset(const uint32_t binding) const { return m_samplerRedirects.getStorageOffset(binding).data; }
470+
inline const CBindingRedirect& getImmutableSamplerRedirect() const { return m_immutableSamplerRedirect; }
471+
inline const CBindingRedirect& getMutableSamplerRedirect() const { return m_mutableSamplerRedirect; }
411472

412473
protected:
413474
// Maps a binding number to a local (to descriptor set layout) offset, for a given descriptor type.
414475
CBindingRedirect m_descriptorRedirects[asset::EDT_COUNT];
415-
CBindingRedirect m_samplerRedirects;
476+
CBindingRedirect m_immutableSamplerRedirect;
477+
CBindingRedirect m_mutableSamplerRedirect;
416478
};
417479

418480
}

include/nbl/video/IGPUDescriptorSet.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class NBL_API IGPUDescriptorSet : public asset::IDescriptorSet<const IGPUDescrip
8888
// This assumes that descriptors of a particular type in the set will always be contiguous in pool's storage memory, regardless of which binding in the set they belong to.
8989
inline core::smart_refctd_ptr<asset::IDescriptor>* getDescriptors(const asset::E_DESCRIPTOR_TYPE type, const uint32_t binding) const
9090
{
91-
const auto localOffset = getLayout()->getDescriptorOffset(type, binding);
91+
const auto localOffset = getLayout()->getDescriptorRedirect(type).getStorageOffset(IGPUDescriptorSetLayout::CBindingRedirect::binding_number_t{ binding }).data;
9292
if (localOffset == ~0)
9393
return nullptr;
9494

@@ -101,8 +101,8 @@ class NBL_API IGPUDescriptorSet : public asset::IDescriptorSet<const IGPUDescrip
101101

102102
inline core::smart_refctd_ptr<IGPUSampler>* getMutableSamplers(const uint32_t binding) const
103103
{
104-
const auto localOffset = getLayout()->getMutableSamplerOffset(binding);
105-
if (localOffset == ~0u)
104+
const auto localOffset = getLayout()->getMutableSamplerRedirect().getStorageOffset(IGPUDescriptorSetLayout::CBindingRedirect::binding_number_t{ binding }).data;
105+
if (localOffset == getLayout()->getMutableSamplerRedirect().Invalid)
106106
return nullptr;
107107

108108
auto* samplers = getAllMutableSamplers();

include/nbl/video/ILogicalDevice.h

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -242,39 +242,22 @@ class NBL_API ILogicalDevice : public core::IReferenceCounted, public IDeviceMem
242242
const auto setCount = setCounts ? (*setCountsIt):1u;
243243
totalSetCount += setCount;
244244

245-
#if 0
246245
for (uint32_t t = 0u; t < asset::EDT_COUNT; ++t)
247246
{
248247
const auto type = static_cast<asset::E_DESCRIPTOR_TYPE>(t);
249-
const auto declaredBindingCount = (*curLayout)->getDescriptorRedirect(type).getBindingCount();
250-
auto ps = std::find_if(poolSizes.begin(), poolSizes.end(), [&](const IDescriptorPool::SDescriptorPoolSize& poolSize) { return poolSize.type == type; });
251-
for (uint32_t i = 0; i < declaredBindingCount; ++i)
252-
{
253-
254-
}
255-
256-
if (ps != poolSizes.end())
257-
{
258-
ps->count += setCount * binding.count;
259-
}
260-
else
261-
{
262-
poolSizes.push_back(IDescriptorPool::SDescriptorPoolSize{ type, setCount * binding.count });
263-
}
264-
}
265-
#endif
248+
const auto& redirect = (*curLayout)->getDescriptorRedirect(type);
249+
const auto declaredBindingCount = redirect.getBindingCount();
266250

267-
auto bindings = (*curLayout)->getBindings();
268-
for (const auto& binding : bindings)
269-
{
270-
auto ps = std::find_if(poolSizes.begin(), poolSizes.end(), [&](const IDescriptorPool::SDescriptorPoolSize& poolSize) { return poolSize.type == binding.type; });
251+
auto ps = std::find_if(poolSizes.begin(), poolSizes.end(), [&](const IDescriptorPool::SDescriptorPoolSize& poolSize) { return poolSize.type == type; });
271252
if (ps != poolSizes.end())
272253
{
273-
ps->count += setCount*binding.count;
254+
for (uint32_t i = 0; i < declaredBindingCount; ++i)
255+
ps->count += setCount * redirect.getCount(i);
274256
}
275257
else
276258
{
277-
poolSizes.push_back(IDescriptorPool::SDescriptorPoolSize { binding.type, setCount*binding.count });
259+
for (uint32_t i = 0; i < declaredBindingCount; ++i)
260+
poolSizes.push_back(IDescriptorPool::SDescriptorPoolSize{ type, setCount * redirect.getCount(i)});
278261
}
279262
}
280263

0 commit comments

Comments
 (0)