Skip to content

Commit 41b9a5b

Browse files
committed
Work on try allocate and timings
1 parent 58c4e90 commit 41b9a5b

File tree

1 file changed

+55
-5
lines changed

1 file changed

+55
-5
lines changed

include/nbl/video/alloc/SubAllocatedDescriptorSet.h

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,10 @@ class SubAllocatedDescriptorSet : public core::IReferenceCounted
6464
uint32_t m_binding;
6565
std::vector<value_type> m_addresses;
6666
};
67+
using EventHandler = MultiTimelineEventHandlerST<DeferredFreeFunctor>;
6768
protected:
6869
struct SubAllocDescriptorSetRange {
69-
MultiTimelineEventHandlerST<DeferredFreeFunctor> eventHandler = MultiTimelineEventHandlerST<DeferredFreeFunctor>({});
70+
EventHandler eventHandler = EventHandler({});
7071
std::unique_ptr<AddressAllocator> addressAllocator = nullptr;
7172
std::unique_ptr<ReservedAllocator> reservedAllocator = nullptr;
7273
size_t reservedSize = 0;
@@ -179,7 +180,7 @@ class SubAllocatedDescriptorSet : public core::IReferenceCounted
179180
video::IGPUDescriptorSet* getDescriptorSet() { return m_descriptorSet.get(); }
180181

181182
//! Warning `outAddresses` needs to be primed with `invalid_value` values, otherwise no allocation happens for elements not equal to `invalid_value`
182-
inline void multi_allocate(uint32_t binding, size_type count, video::IGPUDescriptorSet::SDescriptorInfo* descriptors, value_type* outAddresses)
183+
inline size_type try_multi_allocate(uint32_t binding, size_type count, video::IGPUDescriptorSet::SDescriptorInfo* descriptors, value_type* outAddresses)
183184
{
184185
auto debugGuard = stAccessVerifyDebugGuard();
185186

@@ -190,13 +191,18 @@ class SubAllocatedDescriptorSet : public core::IReferenceCounted
190191
writes.reserve(count);
191192
infos.reserve(count);
192193

194+
size_type unallocatedSize = 0u;
193195
for (size_type i=0; i<count; i++)
194196
{
195197
if (outAddresses[i]!=AddressAllocator::invalid_address)
196198
continue;
197199

198200
outAddresses[i] = allocator->alloc_addr(1,1);
199-
// TODO: should also write something to the descriptor set (or probably leave that to the caller?)
201+
if (outAddresses[i] == AddressAllocator::invalid_address)
202+
{
203+
unallocatedSize = count - i;
204+
break;
205+
}
200206

201207
auto& descriptor = descriptors[i];
202208

@@ -216,12 +222,56 @@ class SubAllocatedDescriptorSet : public core::IReferenceCounted
216222
}
217223

218224
m_logicalDevice->updateDescriptorSets(writes, {});
225+
return unallocatedSize;
226+
}
227+
228+
template<class Clock=typename std::chrono::steady_clock>
229+
inline size_type multi_allocate(const std::chrono::time_point<Clock>& maxWaitPoint, uint32_t binding, size_type count, video::IGPUDescriptorSet::SDescriptorInfo* descriptors, value_type* outAddresses) noexcept
230+
{
231+
auto debugGuard = stAccessVerifyDebugGuard();
232+
233+
auto range = m_allocatableRanges.find(binding);
234+
// Check if this binding has an allocator
235+
if (range == m_allocatableRanges.end())
236+
return count;
237+
238+
auto& eventHandler = range->second.eventHandler;
239+
240+
// try allocate once
241+
size_type unallocatedSize = try_multi_allocate(binding, count, descriptors, outAddresses);
242+
if (!unallocatedSize)
243+
return 0u;
244+
245+
// then try to wait at least once and allocate
246+
do
247+
{
248+
eventHandler.wait(maxWaitPoint, unallocatedSize);
249+
250+
unallocatedSize = try_multi_allocate(binding, unallocatedSize, &descriptors[count - unallocatedSize], &outAddresses[count - unallocatedSize]);
251+
if (!unallocatedSize)
252+
return 0u;
253+
} while(Clock::now()<maxWaitPoint);
254+
255+
return unallocatedSize;
256+
}
257+
258+
inline size_type multi_allocate(uint32_t binding, size_type count, video::IGPUDescriptorSet::SDescriptorInfo* descriptors, value_type* outAddresses) noexcept
259+
{
260+
auto range = m_allocatableRanges.find(binding);
261+
// Check if this binding has an allocator
262+
if (range == m_allocatableRanges.end())
263+
return count;
264+
265+
return multi_allocate(TimelineEventHandlerBase::default_wait(), binding, count, descriptors, outAddresses);
219266
}
267+
220268
inline void multi_deallocate(uint32_t binding, size_type count, const size_type* addr)
221269
{
222270
auto debugGuard = stAccessVerifyDebugGuard();
223271

224272
auto allocator = getBindingAllocator(binding);
273+
if (!allocator)
274+
return;
225275
for (size_type i=0; i<count; i++)
226276
{
227277
if (addr[i]==AddressAllocator::invalid_address)
@@ -231,7 +281,7 @@ class SubAllocatedDescriptorSet : public core::IReferenceCounted
231281
// TODO: should also write something to the descriptor sets
232282
}
233283
}
234-
//!
284+
235285
inline void multi_deallocate(uint32_t binding, const ISemaphore::SWaitInfo& futureWait, DeferredFreeFunctor&& functor) noexcept
236286
{
237287
auto range = m_allocatableRanges.find(binding);
@@ -243,7 +293,7 @@ class SubAllocatedDescriptorSet : public core::IReferenceCounted
243293
auto debugGuard = stAccessVerifyDebugGuard();
244294
eventHandler.latch(futureWait,std::move(functor));
245295
}
246-
// TODO: improve signature of this function in the future
296+
247297
inline void multi_deallocate(uint32_t binding, size_type count, const value_type* addr, const ISemaphore::SWaitInfo& futureWait) noexcept
248298
{
249299
if (futureWait.semaphore)

0 commit comments

Comments
 (0)