Skip to content

Commit 22284fd

Browse files
committed
Halfway restoring ICPUDescriptorSet to sanity.
1 parent 05650dc commit 22284fd

File tree

7 files changed

+348
-367
lines changed

7 files changed

+348
-367
lines changed

include/nbl/asset/ICPUDescriptorSet.h

Lines changed: 75 additions & 291 deletions
Original file line numberDiff line numberDiff line change
@@ -25,318 +25,102 @@ namespace nbl::asset
2525
@see IDescriptorSet
2626
*/
2727

28-
class NBL_API ICPUDescriptorSet final : public IDescriptorSet<ICPUDescriptorSetLayout>, public IAsset, public impl::IEmulatedDescriptorSet<ICPUDescriptorSetLayout>
28+
class NBL_API ICPUDescriptorSet final : public IDescriptorSet<ICPUDescriptorSetLayout>, public IAsset
2929
{
30-
using impl_t = impl::IEmulatedDescriptorSet<ICPUDescriptorSetLayout>;
31-
32-
public:
33-
using base_t = IDescriptorSet<ICPUDescriptorSetLayout>;
34-
35-
//! Contructor preallocating memory for SDescriptorBindings which user can fill later (using non-const getDescriptors()).
36-
//! @see getDescriptors()
37-
ICPUDescriptorSet(core::smart_refctd_ptr<ICPUDescriptorSetLayout>&& _layout) : base_t(std::move(_layout)), IAsset(), impl_t(m_layout.get())
38-
{
39-
for (uint32_t t = 0u; t < static_cast<uint32_t>(IDescriptor::E_TYPE::ET_COUNT); ++t)
40-
{
41-
if (m_descriptors[t])
42-
m_descriptorInfos[t] = core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<ICPUDescriptorSet::SDescriptorInfo::SBufferImageInfo>>(m_descriptors[t]->size());
43-
}
44-
}
45-
46-
inline size_t conservativeSizeEstimate() const override
47-
{
48-
assert(!"Invalid code path.");
49-
return 0xdeadbeefull;
50-
}
51-
52-
core::smart_refctd_ptr<IAsset> clone(uint32_t _depth = ~0u) const override
53-
{
54-
auto layout = (_depth > 0u && m_layout) ? core::smart_refctd_ptr_static_cast<ICPUDescriptorSetLayout>(m_layout->clone(_depth - 1u)) : m_layout;
55-
auto cp = core::make_smart_refctd_ptr<ICPUDescriptorSet>(std::move(layout));
56-
clone_common(cp.get());
57-
58-
auto cloneDescriptor = [](const core::smart_refctd_ptr<IDescriptor>& _desc, uint32_t _depth) -> core::smart_refctd_ptr<IDescriptor>
59-
{
60-
if (!_desc)
61-
return nullptr;
62-
63-
IAsset* asset = nullptr;
64-
switch (_desc->getTypeCategory())
65-
{
66-
case IDescriptor::EC_BUFFER:
67-
asset = static_cast<ICPUBuffer*>(_desc.get()); break;
68-
case IDescriptor::EC_BUFFER_VIEW:
69-
asset = static_cast<ICPUBufferView*>(_desc.get()); break;
70-
case IDescriptor::EC_IMAGE:
71-
asset = static_cast<ICPUImageView*>(_desc.get()); break;
72-
}
73-
74-
auto cp = asset->clone(_depth);
75-
76-
switch (_desc->getTypeCategory())
77-
{
78-
case IDescriptor::EC_BUFFER:
79-
return core::smart_refctd_ptr_static_cast<ICPUBuffer>(std::move(cp));
80-
case IDescriptor::EC_BUFFER_VIEW:
81-
return core::smart_refctd_ptr_static_cast<ICPUBufferView>(std::move(cp));
82-
case IDescriptor::EC_IMAGE:
83-
return core::smart_refctd_ptr_static_cast<ICPUImageView>(std::move(cp));
84-
}
85-
return nullptr;
86-
};
87-
88-
for (uint32_t t = 0u; t < static_cast<uint32_t>(IDescriptor::E_TYPE::ET_COUNT); ++t)
89-
{
90-
const auto type = static_cast<IDescriptor::E_TYPE>(t);
91-
92-
for (uint32_t i = 0u; i < m_descriptors[t]->size(); ++i)
93-
{
94-
const auto& srcDescriptor = getDescriptorStorage(type)[i];
95-
const auto& srcDescriptorInfo = getDescriptorInfoStorage(type)[i];
96-
97-
auto& dstDescriptor = cp->getDescriptorStorage(type)[i];
98-
auto& dstDescriptorInfo = cp->getDescriptorInfoStorage(type)[i];
99-
100-
const auto descriptorCategory = srcDescriptor->getTypeCategory();
101-
if (descriptorCategory != IDescriptor::EC_IMAGE)
102-
dstDescriptorInfo.buffer = srcDescriptorInfo.buffer;
103-
else
104-
dstDescriptorInfo.image = srcDescriptorInfo.image;
105-
106-
if (_depth > 0u)
107-
dstDescriptor = cloneDescriptor(srcDescriptor, _depth - 1u);
108-
}
109-
}
110-
111-
for (uint32_t i = 0u; i < m_layout->getTotalMutableSamplerCount(); ++i)
112-
cp->getMutableSamplerStorage()[i] = core::smart_refctd_ptr_static_cast<ICPUSampler>(getMutableSamplerStorage()[i]->clone(_depth - 1u));
113-
114-
return cp;
115-
}
116-
117-
inline void convertToDummyObject(uint32_t referenceLevelsBelowToConvert=0u) override
118-
{
119-
convertToDummyObject_common(referenceLevelsBelowToConvert);
120-
121-
if (referenceLevelsBelowToConvert)
122-
{
123-
--referenceLevelsBelowToConvert;
124-
m_layout->convertToDummyObject(referenceLevelsBelowToConvert);
125-
126-
for (uint32_t t = 0u; t < static_cast<uint32_t>(IDescriptor::E_TYPE::ET_COUNT); ++t)
127-
{
128-
const auto type = static_cast<IDescriptor::E_TYPE>(t);
129-
const auto descriptorCount = m_layout->getTotalDescriptorCount(type);
130-
if (descriptorCount == 0ull)
131-
continue;
132-
133-
auto descriptors = m_descriptors[t]->begin();
134-
assert(descriptors);
135-
136-
for (uint32_t i = 0u; i < descriptorCount; ++i)
137-
{
138-
switch (descriptors[i]->getTypeCategory())
139-
{
140-
case IDescriptor::EC_BUFFER:
141-
static_cast<asset::ICPUBuffer*>(descriptors[i].get())->convertToDummyObject(referenceLevelsBelowToConvert);
142-
break;
143-
144-
case IDescriptor::EC_IMAGE:
145-
{
146-
static_cast<asset::ICPUImageView*>(descriptors[i].get())->convertToDummyObject(referenceLevelsBelowToConvert);
147-
const auto mutableSamplerCount = m_layout->getTotalMutableSamplerCount();
148-
for (uint32_t s = 0u; s < mutableSamplerCount; ++s)
149-
m_mutableSamplers->begin()[s]->convertToDummyObject(referenceLevelsBelowToConvert);
150-
} break;
151-
152-
case IDescriptor::EC_BUFFER_VIEW:
153-
static_cast<asset::ICPUBufferView*>(descriptors[i].get())->convertToDummyObject(referenceLevelsBelowToConvert);
154-
break;
155-
156-
default:
157-
assert(!"Invalid code path.");
158-
}
159-
}
160-
}
161-
}
162-
}
163-
164-
_NBL_STATIC_INLINE_CONSTEXPR auto AssetType = ET_DESCRIPTOR_SET;
165-
inline E_TYPE getAssetType() const override { return AssetType; }
166-
167-
inline ICPUDescriptorSetLayout* getLayout()
168-
{
169-
assert(!isImmutable_debug());
170-
return m_layout.get();
171-
}
172-
inline const ICPUDescriptorSetLayout* getLayout() const { return m_layout.get(); }
173-
174-
std::pair<core::SRange<core::smart_refctd_ptr<IDescriptor>>, core::SRange<SDescriptorInfo::SBufferImageInfo>> getDescriptors(const uint32_t binding, IDescriptor::E_TYPE type = IDescriptor::E_TYPE::ET_COUNT)
30+
using base_t = IDescriptorSet<ICPUDescriptorSetLayout>;
31+
32+
public:
33+
//! Contructor preallocating memory for SDescriptorInfos which user can fill later (using non-const getDescriptorInfos()).
34+
//! @see getDescriptorInfos()
35+
ICPUDescriptorSet(core::smart_refctd_ptr<ICPUDescriptorSetLayout>&& _layout) : base_t(std::move(_layout)), IAsset()
36+
{
37+
for (uint32_t t = 0u; t < static_cast<uint32_t>(IDescriptor::E_TYPE::ET_COUNT); ++t)
17538
{
176-
if (type == IDescriptor::E_TYPE::ET_COUNT)
177-
{
178-
for (uint32_t t = 0; t < static_cast<uint32_t>(IDescriptor::E_TYPE::ET_COUNT); ++t)
179-
{
180-
const auto possibleType = static_cast<IDescriptor::E_TYPE>(t);
181-
const auto& redirect = getLayout()->getDescriptorRedirect(possibleType);
182-
if (redirect.searchForBinding(binding) != redirect.Invalid)
183-
{
184-
type = possibleType;
185-
break;
186-
}
187-
}
188-
189-
if (type == IDescriptor::E_TYPE::ET_COUNT)
190-
return { {nullptr, nullptr}, {nullptr, nullptr} };
191-
}
192-
193-
const auto& redirect = getLayout()->getDescriptorRedirect(type);
194-
const auto bindingNumberIndex = redirect.searchForBinding(binding);
195-
if (bindingNumberIndex == redirect.Invalid)
196-
return { {nullptr, nullptr}, {nullptr, nullptr} };
197-
198-
const auto descriptorOffset = redirect.getStorageOffset(bindingNumberIndex).data;
199-
const auto descriptorCount = redirect.getCount(bindingNumberIndex);
200-
201-
auto descriptorsBegin = m_descriptors[static_cast<uint32_t>(type)]->begin() + descriptorOffset;
202-
auto descriptorInfosBegin = m_descriptorInfos[static_cast<uint32_t>(type)]->begin() + descriptorOffset;
203-
204-
return { {descriptorsBegin, descriptorsBegin+descriptorCount}, {descriptorInfosBegin, descriptorInfosBegin+descriptorCount} };
205-
}
206-
207-
core::SRange<core::smart_refctd_ptr<ICPUSampler>> getMutableSamplers(const uint32_t binding) const
208-
{
209-
const auto& redirect = getLayout()->getMutableSamplerRedirect();
210-
211-
const auto bindingNumberIndex = redirect.searchForBinding(binding);
212-
if (bindingNumberIndex == redirect.Invalid)
213-
return { nullptr, nullptr };
214-
215-
const auto offset = redirect.getStorageOffset(bindingNumberIndex).data;
216-
assert(offset != redirect.Invalid);
39+
const auto type = static_cast<IDescriptor::E_TYPE>(t);
40+
const uint32_t count = m_layout->getTotalDescriptorCount(type);
41+
if (count == 0u)
42+
continue;
21743

218-
const auto count = redirect.getCount(bindingNumberIndex);
219-
220-
auto samplersBegin = m_mutableSamplers->begin() + offset;
221-
return { samplersBegin, samplersBegin + count };
44+
m_descriptorInfos[t] = core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<ICPUDescriptorSet::SDescriptorInfo>>(count);
22245
}
46+
}
22347

224-
inline core::smart_refctd_ptr<IDescriptor>* getDescriptorStorage(const IDescriptor::E_TYPE type) const { return m_descriptors[static_cast<uint32_t>(type)]->begin(); }
225-
inline SDescriptorInfo::SBufferImageInfo* getDescriptorInfoStorage(const IDescriptor::E_TYPE type) const { return m_descriptorInfos[static_cast<uint32_t>(type)]->begin(); }
226-
inline core::smart_refctd_ptr<ICPUSampler>* getMutableSamplerStorage() const { return m_mutableSamplers->begin(); }
48+
_NBL_STATIC_INLINE_CONSTEXPR auto AssetType = ET_DESCRIPTOR_SET;
49+
inline E_TYPE getAssetType() const override { return AssetType; }
22750

228-
bool canBeRestoredFrom(const IAsset* _other) const override
229-
{
230-
auto* other = static_cast<const ICPUDescriptorSet*>(_other);
231-
return m_layout->canBeRestoredFrom(other->m_layout.get());
232-
}
51+
inline ICPUDescriptorSetLayout* getLayout()
52+
{
53+
assert(!isImmutable_debug());
54+
return m_layout.get();
55+
}
23356

234-
protected:
235-
void restoreFromDummy_impl(IAsset* _other, uint32_t _levelsBelow) override
236-
{
237-
auto* other = static_cast<ICPUDescriptorSet*>(_other);
57+
inline const ICPUDescriptorSetLayout* getLayout() const { return m_layout.get(); }
23858

239-
if (_levelsBelow)
240-
{
241-
--_levelsBelow;
242-
restoreFromDummy_impl_call(m_layout.get(), other->getLayout(), _levelsBelow);
59+
inline bool canBeRestoredFrom(const IAsset* _other) const override
60+
{
61+
auto* other = static_cast<const ICPUDescriptorSet*>(_other);
62+
return m_layout->canBeRestoredFrom(other->m_layout.get());
63+
}
24364

244-
for (uint32_t t = 0u; t < static_cast<uint32_t>(IDescriptor::E_TYPE::ET_COUNT); ++t)
245-
{
246-
const auto type = static_cast<IDescriptor::E_TYPE>(t);
247-
const auto descriptorCount = m_layout->getTotalDescriptorCount(type);
248-
if (descriptorCount == 0ull)
249-
continue;
65+
inline size_t conservativeSizeEstimate() const override
66+
{
67+
assert(!"Invalid code path.");
68+
return 0xdeadbeefull;
69+
}
25070

251-
auto descriptors = m_descriptors[t]->begin();
252-
assert(descriptors);
71+
inline SDescriptorInfo* getDescriptorInfoStorage(const IDescriptor::E_TYPE type) const { return m_descriptorInfos[static_cast<uint32_t>(type)]->begin(); }
25372

254-
auto otherDescriptors = other->m_descriptors[t]->begin();
73+
core::SRange<SDescriptorInfo> getDescriptorInfos(const uint32_t binding, IDescriptor::E_TYPE type = IDescriptor::E_TYPE::ET_COUNT);
25574

256-
for (uint32_t i = 0u; i < descriptorCount; ++i)
257-
{
258-
switch (descriptors[i]->getTypeCategory())
259-
{
260-
case IDescriptor::EC_BUFFER:
261-
restoreFromDummy_impl_call(static_cast<ICPUBuffer*>(descriptors[i].get()), static_cast<ICPUBuffer*>(otherDescriptors[i].get()), _levelsBelow);
262-
break;
75+
core::smart_refctd_ptr<IAsset> clone(uint32_t _depth = ~0u) const override;
26376

264-
case IDescriptor::EC_IMAGE:
265-
restoreFromDummy_impl_call(static_cast<ICPUImageView*>(descriptors[i].get()), static_cast<ICPUImageView*>(otherDescriptors[i].get()), _levelsBelow);
266-
break;
77+
void convertToDummyObject(uint32_t referenceLevelsBelowToConvert = 0u) override;
26778

268-
case IDescriptor::EC_BUFFER_VIEW:
269-
restoreFromDummy_impl_call(static_cast<ICPUBufferView*>(descriptors[i].get()), static_cast<ICPUBufferView*>(otherDescriptors[i].get()), _levelsBelow);
270-
break;
79+
protected:
80+
void restoreFromDummy_impl(IAsset* _other, uint32_t _levelsBelow) override;
27181

272-
default:
273-
assert(!"Invalid code path.");
274-
}
275-
}
276-
}
82+
bool isAnyDependencyDummy_impl(uint32_t _levelsBelow) const override;
27783

278-
for (uint32_t i = 0u; i < m_layout->getTotalMutableSamplerCount(); ++i)
279-
restoreFromDummy_impl_call(m_mutableSamplers->begin()[i].get(), other->m_mutableSamplers->begin()[i].get(), _levelsBelow);
280-
}
281-
}
84+
virtual ~ICPUDescriptorSet() = default;
28285

283-
bool isAnyDependencyDummy_impl(uint32_t _levelsBelow) const override
86+
private:
87+
static inline IDescriptor::E_CATEGORY getCategoryFromType(const IDescriptor::E_TYPE type)
88+
{
89+
auto category = IDescriptor::E_CATEGORY::EC_COUNT;
90+
switch (type)
28491
{
285-
--_levelsBelow;
286-
if (m_layout->isAnyDependencyDummy(_levelsBelow))
287-
return true;
288-
289-
for (uint32_t t = 0u; t < static_cast<uint32_t>(IDescriptor::E_TYPE::ET_COUNT); ++t)
290-
{
291-
const auto type = static_cast<IDescriptor::E_TYPE>(t);
292-
const auto descriptorCount = m_layout->getTotalDescriptorCount(type);
293-
if (descriptorCount == 0ull)
294-
continue;
295-
296-
auto descriptors = m_descriptors[t]->begin();
297-
assert(descriptors);
298-
299-
for (uint32_t i = 0u; i < descriptorCount; ++i)
300-
{
301-
switch (descriptors[i]->getTypeCategory())
302-
{
303-
case IDescriptor::EC_BUFFER:
304-
if (static_cast<ICPUBuffer*>(descriptors[i].get())->isAnyDependencyDummy(_levelsBelow))
305-
return true;
306-
break;
307-
308-
case IDescriptor::EC_IMAGE:
309-
if (static_cast<ICPUImageView*>(descriptors[i].get())->isAnyDependencyDummy(_levelsBelow))
310-
return true;
311-
break;
312-
313-
case IDescriptor::EC_BUFFER_VIEW:
314-
if (static_cast<ICPUBufferView*>(descriptors[i].get())->isAnyDependencyDummy(_levelsBelow))
315-
return true;
316-
break;
317-
318-
default:
319-
assert(!"Invalid code path.");
320-
}
321-
}
322-
}
323-
324-
for (uint32_t i = 0u; i < m_layout->getTotalMutableSamplerCount(); ++i)
325-
{
326-
if (m_mutableSamplers->begin()[i]->isAnyDependencyDummy(_levelsBelow))
327-
return true;
328-
}
329-
330-
return false;
92+
case IDescriptor::E_TYPE::ET_COMBINED_IMAGE_SAMPLER: [[fallthrough]];
93+
case IDescriptor::E_TYPE::ET_STORAGE_IMAGE: [[fallthrough]];
94+
case IDescriptor::E_TYPE::ET_INPUT_ATTACHMENT:
95+
category = IDescriptor::E_CATEGORY::EC_IMAGE;
96+
break;
97+
98+
case IDescriptor::E_TYPE::ET_UNIFORM_BUFFER: [[fallthrough]];
99+
case IDescriptor::E_TYPE::ET_UNIFORM_BUFFER_DYNAMIC: [[fallthrough]];
100+
case IDescriptor::E_TYPE::ET_STORAGE_BUFFER: [[fallthrough]];
101+
case IDescriptor::E_TYPE::ET_STORAGE_BUFFER_DYNAMIC:
102+
category = IDescriptor::E_CATEGORY::EC_BUFFER;
103+
break;
104+
105+
case IDescriptor::E_TYPE::ET_UNIFORM_TEXEL_BUFFER:
106+
case IDescriptor::E_TYPE::ET_STORAGE_TEXEL_BUFFER:
107+
category = IDescriptor::E_CATEGORY::EC_BUFFER_VIEW;
108+
break;
109+
110+
case IDescriptor::E_TYPE::ET_ACCELERATION_STRUCTURE:
111+
category = IDescriptor::E_CATEGORY::EC_ACCELERATION_STRUCTURE;
112+
break;
113+
114+
default:
115+
assert(!"Invalid code path.");
331116
}
117+
return category;
118+
}
332119

333-
virtual ~ICPUDescriptorSet() = default;
334-
335-
private:
336-
void allocateDescriptors() override { assert(!"Invalid code path."); }
120+
// TODO(achal): Remove.
121+
void allocateDescriptors() override { assert(!"Invalid code path."); }
337122

338-
// Mutable samplers are NOT stored in this array (in SDescriptorInfo::SImageInfo::sampler member), but in IEmulatedDescriptorSet::m_mutableSamplers.
339-
core::smart_refctd_dynamic_array<ICPUDescriptorSet::SDescriptorInfo::SBufferImageInfo> m_descriptorInfos[static_cast<uint32_t>(IDescriptor::E_TYPE::ET_COUNT)];
123+
core::smart_refctd_dynamic_array<ICPUDescriptorSet::SDescriptorInfo> m_descriptorInfos[static_cast<uint32_t>(IDescriptor::E_TYPE::ET_COUNT)];
340124
};
341125

342126
}

0 commit comments

Comments
 (0)