@@ -99,31 +99,34 @@ class SubAllocatedDescriptorSet : public core::IReferenceCounted
9999 using EventHandler = MultiTimelineEventHandlerST<DeferredFreeFunctor>;
100100protected:
101101 struct SubAllocDescriptorSetRange {
102- EventHandler eventHandler = EventHandler({}) ;
102+ std::unique_ptr< EventHandler> eventHandler = nullptr ;
103103 std::unique_ptr<AddressAllocator> addressAllocator = nullptr ;
104104 std::unique_ptr<ReservedAllocator> reservedAllocator = nullptr ;
105105 size_t reservedSize = 0 ;
106106 asset::IDescriptor::E_TYPE descriptorType = asset::IDescriptor::E_TYPE::ET_COUNT;
107107
108108 SubAllocDescriptorSetRange (
109+ std::unique_ptr<EventHandler>&& inEventHandler,
109110 std::unique_ptr<AddressAllocator>&& inAddressAllocator,
110111 std::unique_ptr<ReservedAllocator>&& inReservedAllocator,
111112 size_t inReservedSize,
112113 asset::IDescriptor::E_TYPE inDescriptorType) :
113- eventHandler ({} ), addressAllocator(std::move(inAddressAllocator)),
114+ eventHandler (std::move(inEventHandler) ), addressAllocator(std::move(inAddressAllocator)),
114115 reservedAllocator (std::move(inReservedAllocator)),
115116 reservedSize(inReservedSize),
116117 descriptorType(inDescriptorType) {}
117118 SubAllocDescriptorSetRange () {}
118119
119120 SubAllocDescriptorSetRange& operator =(SubAllocDescriptorSetRange&& other)
120121 {
122+ eventHandler = std::move (other.eventHandler );
121123 addressAllocator = std::move (other.addressAllocator );
122124 reservedAllocator = std::move (other.reservedAllocator );
123125 reservedSize = other.reservedSize ;
124126 descriptorType = other.descriptorType ;
125127
126128 // Nullify other
129+ other.eventHandler = nullptr ;
127130 other.addressAllocator = nullptr ;
128131 other.reservedAllocator = nullptr ;
129132 other.reservedSize = 0u ;
@@ -147,7 +150,7 @@ class SubAllocatedDescriptorSet : public core::IReferenceCounted
147150
148151 // constructors
149152 inline SubAllocatedDescriptorSet (core::smart_refctd_ptr<video::IGPUDescriptorSet>&& descriptorSet,
150- core::smart_refctd_ptr<video::ILogicalDevice>&& logicalDevice) : m_logicalDevice(std::move(logicalDevice))
153+ core::smart_refctd_ptr<video::ILogicalDevice>&& logicalDevice)
151154 {
152155 auto layout = descriptorSet->getLayout ();
153156 for (uint32_t descriptorType = 0 ; descriptorType < static_cast <uint32_t >(asset::IDescriptor::E_TYPE::ET_COUNT); descriptorType++)
@@ -175,12 +178,15 @@ class SubAllocatedDescriptorSet : public core::IReferenceCounted
175178 static_cast <size_type>(0 ), 0u , MaxDescriptorSetAllocationAlignment, static_cast <size_type>(count),
176179 MinDescriptorSetAllocationSize
177180 ));
181+ auto eventHandler = std::unique_ptr<EventHandler>(new EventHandler (core::smart_refctd_ptr<ILogicalDevice>(logicalDevice)));
178182
179- m_allocatableRanges[binding.data ] = SubAllocDescriptorSetRange (std::move (addressAllocator), std::move (reservedAllocator), reservedSize, descType);
183+ m_allocatableRanges[binding.data ] = SubAllocDescriptorSetRange (std::move (eventHandler), std::move (addressAllocator), std::move (reservedAllocator), reservedSize, descType);
184+ assert (m_allocatableRanges[binding.data ].eventHandler ->getLogicalDevice ());
180185 }
181186 }
182187 }
183188 m_descriptorSet = std::move (descriptorSet);
189+ m_logicalDevice = std::move (logicalDevice);
184190 }
185191
186192 inline ~SubAllocatedDescriptorSet ()
@@ -272,7 +278,7 @@ class SubAllocatedDescriptorSet : public core::IReferenceCounted
272278 // FUTURE TODO: later we could only nullify the descriptors we don't end up reallocating if without robustness features
273279 nulls.resize (m_totalDeferredFrees);
274280 auto outNulls = nulls.data ();
275- eventHandler. wait (maxWaitPoint, unallocatedSize, outNulls);
281+ eventHandler-> wait (maxWaitPoint, unallocatedSize, outNulls);
276282 m_logicalDevice->nullifyDescriptors ({ nulls.data (),outNulls }, range->second .descriptorType );
277283
278284 // always call with the same parameters, otherwise this turns into a mess with the non invalid_address gaps
@@ -299,17 +305,19 @@ class SubAllocatedDescriptorSet : public core::IReferenceCounted
299305
300306 auto allocator = getBindingAllocator (binding);
301307 if (allocator)
302- for (size_type i=0 ; i<count; i++)
303308 {
304- if (addr[i]==AddressAllocator::invalid_address)
305- continue ;
306-
307- allocator->free_addr (addr[i],1 );
308- outNullify->dstSet = m_descriptorSet.get ();
309- outNullify->binding = binding;
310- outNullify->arrayElement = i;
311- outNullify->count = 1 ;
312- outNullify++;
309+ for (size_type i = 0 ; i < count; i++)
310+ {
311+ if (addr[i] == AddressAllocator::invalid_address)
312+ continue ;
313+
314+ allocator->free_addr (addr[i], 1 );
315+ outNullify->dstSet = m_descriptorSet.get ();
316+ outNullify->binding = binding;
317+ outNullify->arrayElement = i;
318+ outNullify->count = 1 ;
319+ outNullify++;
320+ }
313321 }
314322 return outNullify;
315323 }
@@ -325,7 +333,7 @@ class SubAllocatedDescriptorSet : public core::IReferenceCounted
325333 auto & eventHandler = range->second .eventHandler ;
326334 auto debugGuard = stAccessVerifyDebugGuard ();
327335 m_totalDeferredFrees += functor.getWorstCaseCount ();
328- eventHandler. latch (futureWait,std::move (functor));
336+ eventHandler-> latch (futureWait,std::move (functor));
329337 }
330338
331339 // defers based on the conservative estimation if `futureWait` needs to be waited on, if doesn't will call nullify descriiptors internally immediately
@@ -353,7 +361,7 @@ class SubAllocatedDescriptorSet : public core::IReferenceCounted
353361 for (uint32_t i = 0 ; i < m_allocatableRanges.size (); i++)
354362 {
355363 auto & it = m_allocatableRanges[i];
356- frees += it.eventHandler . poll (outNulls).eventsLeft ;
364+ frees += it.eventHandler -> poll (outNulls).eventsLeft ;
357365 // TODO: this could be optimized to be put outside the loop
358366 m_logicalDevice->nullifyDescriptors ({nulls.data (),outNulls}, it.descriptorType );
359367 }
0 commit comments