@@ -59,15 +59,16 @@ class IDescriptorPool : public core::IReferenceCounted, public IBackendObject
59
59
return nullptr ;
60
60
}
61
61
62
- bool createDescriptorSets (uint32_t count, const IGPUDescriptorSetLayout* const * layouts, core::smart_refctd_ptr<IGPUDescriptorSet>* output);
62
+ uint32_t createDescriptorSets (uint32_t count, const IGPUDescriptorSetLayout* const * layouts, core::smart_refctd_ptr<IGPUDescriptorSet>* output);
63
63
64
64
bool reset ();
65
65
66
66
inline uint32_t getCapacity () const { return m_creationParameters.maxSets ; }
67
+ inline bool allowsFreeing () const { return m_creationParameters.flags .hasFlags (ECF_FREE_DESCRIPTOR_SET_BIT); }
67
68
68
69
protected:
69
70
explicit IDescriptorPool (core::smart_refctd_ptr<const ILogicalDevice>&& dev, SCreateInfo&& createInfo)
70
- : IBackendObject(std::move(dev)), m_creationParameters(std::move(createInfo)), m_version( 0u )
71
+ : IBackendObject(std::move(dev)), m_creationParameters(std::move(createInfo))
71
72
{
72
73
for (auto i = 0 ; i < static_cast <uint32_t >(asset::IDescriptor::E_TYPE::ET_COUNT); ++i)
73
74
m_descriptorAllocators[i] = std::make_unique<allocator_state_t >(m_creationParameters.maxDescriptorCount [i], m_creationParameters.flags .hasFlags (ECF_FREE_DESCRIPTOR_SET_BIT));
@@ -82,11 +83,27 @@ class IDescriptorPool : public core::IReferenceCounted, public IBackendObject
82
83
m_UBO_SSBOStorage = std::make_unique<core::StorageTrivializer<core::smart_refctd_ptr<IGPUBuffer>>[]>(m_creationParameters.maxDescriptorCount [static_cast <uint32_t >(asset::IDescriptor::E_TYPE::ET_UNIFORM_BUFFER)] + m_creationParameters.maxDescriptorCount [static_cast <uint32_t >(asset::IDescriptor::E_TYPE::ET_STORAGE_BUFFER)] + m_creationParameters.maxDescriptorCount [static_cast <uint32_t >(asset::IDescriptor::E_TYPE::ET_UNIFORM_BUFFER_DYNAMIC)] + m_creationParameters.maxDescriptorCount [static_cast <uint32_t >(asset::IDescriptor::E_TYPE::ET_STORAGE_BUFFER_DYNAMIC)]);
83
84
m_UTB_STBStorage = std::make_unique<core::StorageTrivializer<core::smart_refctd_ptr<IGPUBufferView>>[]>(m_creationParameters.maxDescriptorCount [static_cast <uint32_t >(asset::IDescriptor::E_TYPE::ET_UNIFORM_TEXEL_BUFFER)] + m_creationParameters.maxDescriptorCount [static_cast <uint32_t >(asset::IDescriptor::E_TYPE::ET_STORAGE_BUFFER_DYNAMIC)]);
84
85
m_accelerationStructureStorage = std::make_unique<core::StorageTrivializer<core::smart_refctd_ptr<IGPUAccelerationStructure>>[]>(m_creationParameters.maxDescriptorCount [static_cast <uint32_t >(asset::IDescriptor::E_TYPE::ET_ACCELERATION_STRUCTURE)]);
86
+
87
+ m_allocatedDescriptorSets = std::make_unique<IGPUDescriptorSet* []>(m_creationParameters.maxSets );
88
+ std::fill_n (m_allocatedDescriptorSets.get (), m_creationParameters.maxSets , nullptr );
89
+
90
+ m_descriptorSetAllocatorReservedSpace = std::make_unique<uint8_t []>(core::IteratablePoolAddressAllocator<uint32_t >::reserved_size (1 , m_creationParameters.maxSets , 1 ));
91
+ m_descriptorSetAllocator = core::IteratablePoolAddressAllocator<uint32_t >(m_descriptorSetAllocatorReservedSpace.get (), 0 , 0 , 1 , m_creationParameters.maxSets , 1 );
85
92
}
86
93
87
- virtual ~IDescriptorPool () {}
94
+ virtual ~IDescriptorPool ()
95
+ {
96
+ if (allowsFreeing ())
97
+ {
98
+ assert (m_descriptorSetAllocator.get_allocated_size () == 0 );
99
+ #ifdef _NBL_DEBUG
100
+ for (uint32_t i = 0u ; i < m_creationParameters.maxSets ; ++i)
101
+ assert (m_allocatedDescriptorSets[i] == nullptr );
102
+ #endif
103
+ }
104
+ }
88
105
89
- virtual bool createDescriptorSets_impl (uint32_t count, const IGPUDescriptorSetLayout* const * layouts, SDescriptorOffsets* const offsets, core::smart_refctd_ptr<IGPUDescriptorSet>* output) = 0;
106
+ virtual bool createDescriptorSets_impl (uint32_t count, const IGPUDescriptorSetLayout* const * layouts, SDescriptorOffsets* const offsets, const uint32_t firstSetOffsetInPool, core::smart_refctd_ptr<IGPUDescriptorSet>* output) = 0;
90
107
91
108
virtual bool reset_impl () = 0;
92
109
@@ -142,16 +159,19 @@ class IDescriptorPool : public core::IReferenceCounted, public IBackendObject
142
159
friend class IGPUDescriptorSet ;
143
160
// Returns the offset into the pool's descriptor storage. These offsets will be combined
144
161
// later with base memory addresses to get the actual memory address where we put the core::smart_refctd_ptr<const IDescriptor>.
145
- SDescriptorOffsets allocateDescriptorOffsets (const IGPUDescriptorSetLayout* layout);
162
+ bool allocateDescriptorOffsets (SDescriptorOffsets& offsets, const IGPUDescriptorSetLayout* layout);
163
+ void freeDescriptorOffsets (SDescriptorOffsets& offsets, const IGPUDescriptorSetLayout* layout);
164
+
165
+ void deleteSetStorage (IGPUDescriptorSet* set);
146
166
147
167
struct allocator_state_t
148
168
{
149
- allocator_state_t (const uint32_t maxDescriptorCount, const bool allowsFreeing )
169
+ allocator_state_t (const uint32_t maxDescriptorCount, const bool useGeneralAllocator )
150
170
{
151
171
if (maxDescriptorCount == 0 )
152
172
return ;
153
173
154
- if (allowsFreeing )
174
+ if (useGeneralAllocator )
155
175
{
156
176
generalAllocatorReservedSpace = std::make_unique<uint8_t []>(core::GeneralpurposeAddressAllocator<uint32_t >::reserved_size (1u , maxDescriptorCount, 1u ));
157
177
generalAllocator = core::GeneralpurposeAddressAllocator<uint32_t >(generalAllocatorReservedSpace.get (), 0u , 0u , 1u , maxDescriptorCount, 1u );
@@ -164,17 +184,12 @@ class IDescriptorPool : public core::IReferenceCounted, public IBackendObject
164
184
165
185
~allocator_state_t () {}
166
186
167
- inline uint32_t allocate (const uint32_t count, const bool allowsFreeing )
187
+ inline uint32_t allocate (const uint32_t count)
168
188
{
169
- if (allowsFreeing)
170
- {
171
- assert (generalAllocatorReservedSpace);
189
+ if (generalAllocatorReservedSpace)
172
190
return generalAllocator.alloc_addr (count, 1u );
173
- }
174
191
else
175
- {
176
192
return linearAllocator.alloc_addr (count, 1u );
177
- }
178
193
}
179
194
180
195
inline void free (const uint32_t allocatedOffset, const uint32_t count)
@@ -183,20 +198,20 @@ class IDescriptorPool : public core::IReferenceCounted, public IBackendObject
183
198
generalAllocator.free_addr (allocatedOffset, count);
184
199
}
185
200
186
- inline void reset (const bool allowsFreeing )
201
+ inline void reset ()
187
202
{
188
- if (!allowsFreeing)
189
- linearAllocator.reset ();
190
- else
203
+ if (generalAllocatorReservedSpace)
191
204
generalAllocator.reset ();
205
+ else
206
+ linearAllocator.reset ();
192
207
}
193
208
194
- inline uint32_t getAllocatedDescriptorCount (const bool allowsFreeing ) const
209
+ inline uint32_t getAllocatedDescriptorCount () const
195
210
{
196
- if (!allowsFreeing)
197
- return linearAllocator.get_allocated_size ();
198
- else
211
+ if (generalAllocatorReservedSpace)
199
212
return generalAllocator.get_allocated_size ();
213
+ else
214
+ return linearAllocator.get_allocated_size ();
200
215
}
201
216
202
217
union
@@ -209,7 +224,10 @@ class IDescriptorPool : public core::IReferenceCounted, public IBackendObject
209
224
std::unique_ptr<allocator_state_t > m_descriptorAllocators[static_cast <uint32_t >(asset::IDescriptor::E_TYPE::ET_COUNT) + 1 ];
210
225
211
226
const SCreateInfo m_creationParameters;
212
- std::atomic_uint32_t m_version;
227
+
228
+ core::IteratablePoolAddressAllocator<uint32_t > m_descriptorSetAllocator;
229
+ std::unique_ptr<uint8_t []> m_descriptorSetAllocatorReservedSpace = nullptr ;
230
+ std::unique_ptr<IGPUDescriptorSet* []> m_allocatedDescriptorSets = nullptr ; // This array might be sparse.
213
231
214
232
std::unique_ptr<core::StorageTrivializer<core::smart_refctd_ptr<video::IGPUImageView>>[]> m_textureStorage;
215
233
std::unique_ptr<core::StorageTrivializer<core::smart_refctd_ptr<video::IGPUSampler>>[]> m_mutableSamplerStorage;
0 commit comments