1
- // Copyright (C) 2018-2020 - DevSH Graphics Programming Sp. z O.O.
1
+ // Copyright (C) 2018-2022 - DevSH Graphics Programming Sp. z O.O.
2
2
// This file is part of the "Nabla Engine".
3
3
// For conditions of distribution and use, see copyright notice in nabla.h
4
4
@@ -25,250 +25,115 @@ namespace nbl::asset
25
25
@see IDescriptorSet
26
26
*/
27
27
28
- class ICPUDescriptorSet final : public IDescriptorSet<ICPUDescriptorSetLayout>, public IAsset, public impl::IEmulatedDescriptorSet<ICPUDescriptorSetLayout>
28
+ class ICPUDescriptorSet final : public IDescriptorSet<ICPUDescriptorSetLayout>, public IAsset
29
29
{
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)
194
38
{
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 ;
197
43
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);
202
45
}
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)
206
107
{
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." );
269
132
}
133
+ return category;
134
+ }
270
135
271
- virtual ~ ICPUDescriptorSet() = default ;
136
+ core::smart_refctd_dynamic_array< ICPUDescriptorSet::SDescriptorInfo> m_descriptorInfos[ static_cast < uint32_t >(IDescriptor::E_TYPE::ET_COUNT)] ;
272
137
};
273
138
274
139
}
0 commit comments