1- // Copyright (C) 2018-2020 - DevSH Graphics Programming Sp. z O.O.
1+ // Copyright (C) 2018-2022 - DevSH Graphics Programming Sp. z O.O.
22// This file is part of the "Nabla Engine".
33// For conditions of distribution and use, see copyright notice in nabla.h
44
@@ -25,250 +25,115 @@ namespace nbl::asset
2525 @see IDescriptorSet
2626*/
2727
28- class ICPUDescriptorSet final : public IDescriptorSet<ICPUDescriptorSetLayout>, public IAsset, public impl::IEmulatedDescriptorSet<ICPUDescriptorSetLayout>
28+ class ICPUDescriptorSet final : public IDescriptorSet<ICPUDescriptorSetLayout>, public IAsset
2929{
30- using impl_t = impl::IEmulatedDescriptorSet<ICPUDescriptorSetLayout>;
31- public:
32- using base_t = IDescriptorSet<ICPUDescriptorSetLayout>;
33-
34- // ! Contructor preallocating memory for SDescriptorBindings which user can fill later (using non-const getDescriptors()).
35- // ! @see getDescriptors()
36- ICPUDescriptorSet (core::smart_refctd_ptr<ICPUDescriptorSetLayout>&& _layout) : base_t (std::move(_layout)), IAsset(), impl_t (m_layout.get())
37- {
38- }
39-
40-
41- inline size_t conservativeSizeEstimate () const override
42- {
43- return sizeof (void *)+m_descriptors->size ()*sizeof (SDescriptorInfo)+m_bindingInfo->size ()*sizeof (impl::IEmulatedDescriptorSet<ICPUDescriptorSetLayout>::SBindingInfo);
44- }
45-
46- core::smart_refctd_ptr<IAsset> clone (uint32_t _depth = ~0u ) const override
47- {
48- auto layout = (_depth > 0u && m_layout) ? core::smart_refctd_ptr_static_cast<ICPUDescriptorSetLayout>(m_layout->clone (_depth - 1u )) : m_layout;
49- auto cp = core::make_smart_refctd_ptr<ICPUDescriptorSet>(std::move (layout));
50- clone_common (cp.get ());
51-
52- const uint32_t max_ix = getMaxDescriptorBindingIndex ();
53- for (uint32_t i = 0u ; i <= max_ix; ++i)
54- {
55- auto cloneDescriptor = [](const core::smart_refctd_ptr<IDescriptor>& _desc, uint32_t _depth) -> core::smart_refctd_ptr<IDescriptor> {
56- if (!_desc)
57- return nullptr ;
58-
59- IAsset* asset = nullptr ;
60- switch (_desc->getTypeCategory ())
61- {
62- case IDescriptor::EC_BUFFER:
63- asset = static_cast <ICPUBuffer*>(_desc.get ()); break ;
64- case IDescriptor::EC_BUFFER_VIEW:
65- asset = static_cast <ICPUBufferView*>(_desc.get ()); break ;
66- case IDescriptor::EC_IMAGE:
67- asset = static_cast <ICPUImageView*>(_desc.get ()); break ;
68- }
69-
70- auto cp = asset->clone (_depth);
71-
72- switch (_desc->getTypeCategory ())
73- {
74- case IDescriptor::EC_BUFFER:
75- return core::smart_refctd_ptr_static_cast<ICPUBuffer>(std::move (cp));
76- case IDescriptor::EC_BUFFER_VIEW:
77- return core::smart_refctd_ptr_static_cast<ICPUBufferView>(std::move (cp));
78- case IDescriptor::EC_IMAGE:
79- return core::smart_refctd_ptr_static_cast<ICPUImageView>(std::move (cp));
80- }
81- return nullptr ;
82- };
83-
84- auto desc = getDescriptors (i);
85- auto cp_desc = cp->getDescriptors (i);
86-
87- const E_DESCRIPTOR_TYPE type = getDescriptorsType (i);
88- for (uint32_t d = 0u ; d < desc.size (); ++d)
89- {
90- cp_desc.begin ()[d] = desc.begin ()[d];
91- if (_depth > 0u )
92- {
93- cp_desc.begin ()[d].desc = cloneDescriptor (cp_desc.begin ()[d].desc , _depth-1u );
94- if (cp_desc.begin ()[d].image .sampler && type==EDT_COMBINED_IMAGE_SAMPLER)
95- cp_desc.begin ()[d].image .sampler = core::smart_refctd_ptr_static_cast<ICPUSampler>(cp_desc.begin ()[d].image .sampler ->clone (_depth-1u ));
96- }
97- }
98- }
99-
100- return cp;
101- }
102-
103- inline void convertToDummyObject (uint32_t referenceLevelsBelowToConvert=0u ) override
104- {
105- convertToDummyObject_common (referenceLevelsBelowToConvert);
106-
107- if (referenceLevelsBelowToConvert)
108- {
109- --referenceLevelsBelowToConvert;
110- m_layout->convertToDummyObject (referenceLevelsBelowToConvert);
111- for (auto it=m_descriptors->begin (); it!=m_descriptors->end (); it++)
112- {
113- auto descriptor = it->desc .get ();
114- if (!descriptor)
115- continue ;
116- switch (descriptor->getTypeCategory ())
117- {
118- case IDescriptor::EC_BUFFER:
119- static_cast <asset::ICPUBuffer*>(descriptor)->convertToDummyObject (referenceLevelsBelowToConvert);
120- break ;
121- case IDescriptor::EC_IMAGE:
122- static_cast <asset::ICPUImageView*>(descriptor)->convertToDummyObject (referenceLevelsBelowToConvert);
123- if (descriptor->getTypeCategory ()==IDescriptor::EC_IMAGE && it->image .sampler )
124- it->image .sampler ->convertToDummyObject (referenceLevelsBelowToConvert);
125- break ;
126- case IDescriptor::EC_BUFFER_VIEW:
127- static_cast <asset::ICPUBufferView*>(descriptor)->convertToDummyObject (referenceLevelsBelowToConvert);
128- break ;
129- }
130- }
131- }
132- // dont drop descriptors so that we can access GPU descriptors through driver->getGPUObjectsFromAssets()
133- // m_descriptors = nullptr;
134- // m_bindingInfo = nullptr;
135- }
136-
137- _NBL_STATIC_INLINE_CONSTEXPR auto AssetType = ET_DESCRIPTOR_SET;
138- inline E_TYPE getAssetType () const override { return AssetType; }
139-
140- inline ICPUDescriptorSetLayout* getLayout ()
141- {
142- assert (!isImmutable_debug ());
143- return m_layout.get ();
144- }
145- inline const ICPUDescriptorSetLayout* getLayout () const { return m_layout.get (); }
146-
147- // !
148- inline uint32_t getMaxDescriptorBindingIndex () const
149- {
150- return m_bindingInfo ? static_cast <uint32_t >(m_bindingInfo->size ()-1u ):0u ;
151- }
152-
153- // !
154- inline E_DESCRIPTOR_TYPE getDescriptorsType (uint32_t index) const
155- {
156- if (m_bindingInfo && index<m_bindingInfo->size ())
157- return m_bindingInfo->operator [](index).descriptorType ;
158- return EDT_INVALID;
159- }
160-
161- // ! Can modify the array of descriptors bound to a particular bindings
162- inline core::SRange<SDescriptorInfo> getDescriptors (uint32_t index)
163- {
164- assert (!isImmutable_debug ());
165-
166- if (m_bindingInfo && index<m_bindingInfo->size ())
167- {
168- const auto & info = m_bindingInfo->operator [](index);
169- auto _begin = m_descriptors->begin ()+info.offset ;
170- if (index+1u !=m_bindingInfo->size ())
171- return core::SRange<SDescriptorInfo>{_begin, m_descriptors->begin ()+m_bindingInfo->operator [](index+1u ).offset };
172- else
173- return core::SRange<SDescriptorInfo>{_begin, m_descriptors->end ()};
174- }
175- else
176- return core::SRange<SDescriptorInfo>{nullptr , nullptr };
177- }
178- inline core::SRange<const SDescriptorInfo> getDescriptors (uint32_t index) const
179- {
180- if (m_bindingInfo && index<m_bindingInfo->size ())
181- {
182- const auto & info = m_bindingInfo->operator [](index);
183- auto _begin = m_descriptors->begin ()+info.offset ;
184- if (index+1u !=m_bindingInfo->size ())
185- return core::SRange<const SDescriptorInfo>{_begin, m_descriptors->begin ()+m_bindingInfo->operator [](index+1u ).offset };
186- else
187- return core::SRange<const SDescriptorInfo>{_begin, m_descriptors->end ()};
188- }
189- else
190- return core::SRange<const SDescriptorInfo>{nullptr , nullptr };
191- }
192-
193- inline auto getTotalDescriptorCount () const
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)
19438 {
195- return m_descriptors->size ();
196- }
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 ;
19743
198- bool canBeRestoredFrom (const IAsset* _other) const override
199- {
200- auto * other = static_cast <const ICPUDescriptorSet*>(_other);
201- return m_layout->canBeRestoredFrom (other->m_layout .get ());
44+ m_descriptorInfos[t] = core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<ICPUDescriptorSet::SDescriptorInfo>>(count);
20245 }
203-
204- protected:
205- void restoreFromDummy_impl (IAsset* _other, uint32_t _levelsBelow) override
46+ }
47+
48+ _NBL_STATIC_INLINE_CONSTEXPR auto AssetType = ET_DESCRIPTOR_SET;
49+ inline E_TYPE getAssetType () const override { return AssetType; }
50+
51+ inline ICPUDescriptorSetLayout* getLayout ()
52+ {
53+ assert (!isImmutable_debug ());
54+ return m_layout.get ();
55+ }
56+
57+ inline const ICPUDescriptorSetLayout* getLayout () const { return m_layout.get (); }
58+
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+ }
64+
65+ inline size_t conservativeSizeEstimate () const override
66+ {
67+ assert (!" Invalid code path." );
68+ return 0xdeadbeefull ;
69+ }
70+
71+ inline core::SRange<SDescriptorInfo> getDescriptorInfoStorage (const IDescriptor::E_TYPE type) const
72+ {
73+ // TODO: @Hazardu
74+ // Cannot do the mutability check here because it requires the function to be non-const, but the function cannot be non-const because it's called
75+ // from const functions in the asset converter.
76+ // Relevant comments/conversations:
77+ // https://github.com/Devsh-Graphics-Programming/Nabla/pull/345#discussion_r1054258384
78+ // https://github.com/Devsh-Graphics-Programming/Nabla/pull/345#discussion_r1056289599
79+ //
80+ // assert(!isImmutable_debug());
81+ if (!m_descriptorInfos[static_cast <uint32_t >(type)])
82+ return { nullptr , nullptr };
83+ else
84+ return { m_descriptorInfos[static_cast <uint32_t >(type)]->begin (), m_descriptorInfos[static_cast <uint32_t >(type)]->end () };
85+ }
86+
87+ core::SRange<SDescriptorInfo> getDescriptorInfos (const ICPUDescriptorSetLayout::CBindingRedirect::binding_number_t binding, IDescriptor::E_TYPE type = IDescriptor::E_TYPE::ET_COUNT);
88+
89+ core::SRange<const SDescriptorInfo> getDescriptorInfos (const ICPUDescriptorSetLayout::CBindingRedirect::binding_number_t binding, IDescriptor::E_TYPE type = IDescriptor::E_TYPE::ET_COUNT) const ;
90+
91+ core::smart_refctd_ptr<IAsset> clone (uint32_t _depth = ~0u ) const override ;
92+
93+ void convertToDummyObject (uint32_t referenceLevelsBelowToConvert = 0u ) override ;
94+
95+ protected:
96+ void restoreFromDummy_impl (IAsset* _other, uint32_t _levelsBelow) override ;
97+
98+ bool isAnyDependencyDummy_impl (uint32_t _levelsBelow) const override ;
99+
100+ virtual ~ICPUDescriptorSet () = default ;
101+
102+ private:
103+ static inline IDescriptor::E_CATEGORY getCategoryFromType (const IDescriptor::E_TYPE type)
104+ {
105+ auto category = IDescriptor::E_CATEGORY::EC_COUNT;
106+ switch (type)
206107 {
207- auto * other = static_cast <ICPUDescriptorSet*>(_other);
208-
209- if (_levelsBelow)
210- {
211- --_levelsBelow;
212- restoreFromDummy_impl_call (m_layout.get (), other->getLayout (), _levelsBelow);
213- for (auto it = m_descriptors->begin (); it != m_descriptors->end (); it++)
214- {
215- auto descriptor = it->desc .get ();
216- if (!descriptor)
217- continue ;
218- const auto i = it - m_descriptors->begin ();
219- auto * d_other = other->m_descriptors ->begin ()[i].desc .get ();
220-
221- switch (descriptor->getTypeCategory ())
222- {
223- case IDescriptor::EC_BUFFER:
224- restoreFromDummy_impl_call (static_cast <ICPUBuffer*>(descriptor), static_cast <ICPUBuffer*>(d_other), _levelsBelow);
225- break ;
226- case IDescriptor::EC_IMAGE:
227- restoreFromDummy_impl_call (static_cast <ICPUImageView*>(descriptor), static_cast <ICPUImageView*>(d_other), _levelsBelow);
228- if (descriptor->getTypeCategory () == IDescriptor::EC_IMAGE && it->image .sampler )
229- restoreFromDummy_impl_call (it->image .sampler .get (), other->m_descriptors ->begin ()[i].image .sampler .get (), _levelsBelow);
230- break ;
231- case IDescriptor::EC_BUFFER_VIEW:
232- restoreFromDummy_impl_call (static_cast <ICPUBufferView*>(descriptor), static_cast <ICPUBufferView*>(d_other), _levelsBelow);
233- break ;
234- }
235- }
236- }
237- }
238-
239- bool isAnyDependencyDummy_impl (uint32_t _levelsBelow) const override
240- {
241- --_levelsBelow;
242- if (m_layout->isAnyDependencyDummy (_levelsBelow))
243- return true ;
244- for (auto it = m_descriptors->begin (); it != m_descriptors->end (); it++)
245- {
246- auto descriptor = it->desc .get ();
247- if (!descriptor)
248- continue ;
249-
250- switch (descriptor->getTypeCategory ())
251- {
252- case IDescriptor::EC_BUFFER:
253- if (static_cast <ICPUBuffer*>(descriptor)->isAnyDependencyDummy (_levelsBelow))
254- return true ;
255- break ;
256- case IDescriptor::EC_IMAGE:
257- if (static_cast <ICPUImageView*>(descriptor)->isAnyDependencyDummy (_levelsBelow))
258- return true ;
259- if (it->image .sampler && it->image .sampler ->isAnyDependencyDummy (_levelsBelow))
260- return true ;
261- break ;
262- case IDescriptor::EC_BUFFER_VIEW:
263- if (static_cast <ICPUBufferView*>(descriptor)->isAnyDependencyDummy (_levelsBelow))
264- return true ;
265- break ;
266- }
267- }
268- return false ;
108+ case IDescriptor::E_TYPE::ET_COMBINED_IMAGE_SAMPLER: [[fallthrough]];
109+ case IDescriptor::E_TYPE::ET_STORAGE_IMAGE: [[fallthrough]];
110+ case IDescriptor::E_TYPE::ET_INPUT_ATTACHMENT:
111+ category = IDescriptor::E_CATEGORY::EC_IMAGE;
112+ break ;
113+
114+ case IDescriptor::E_TYPE::ET_UNIFORM_BUFFER: [[fallthrough]];
115+ case IDescriptor::E_TYPE::ET_UNIFORM_BUFFER_DYNAMIC: [[fallthrough]];
116+ case IDescriptor::E_TYPE::ET_STORAGE_BUFFER: [[fallthrough]];
117+ case IDescriptor::E_TYPE::ET_STORAGE_BUFFER_DYNAMIC:
118+ category = IDescriptor::E_CATEGORY::EC_BUFFER;
119+ break ;
120+
121+ case IDescriptor::E_TYPE::ET_UNIFORM_TEXEL_BUFFER:
122+ case IDescriptor::E_TYPE::ET_STORAGE_TEXEL_BUFFER:
123+ category = IDescriptor::E_CATEGORY::EC_BUFFER_VIEW;
124+ break ;
125+
126+ case IDescriptor::E_TYPE::ET_ACCELERATION_STRUCTURE:
127+ category = IDescriptor::E_CATEGORY::EC_ACCELERATION_STRUCTURE;
128+ break ;
129+
130+ default :
131+ assert (!" Invalid code path." );
269132 }
133+ return category;
134+ }
270135
271- virtual ~ ICPUDescriptorSet() = default ;
136+ core::smart_refctd_dynamic_array< ICPUDescriptorSet::SDescriptorInfo> m_descriptorInfos[ static_cast < uint32_t >(IDescriptor::E_TYPE::ET_COUNT)] ;
272137};
273138
274139}
0 commit comments