Skip to content

Commit 8ce6e0c

Browse files
Refactor the MultiTimelineEventHandlerST to not refcount the device (so it can be used in the IQueue)
1 parent 7c9ab31 commit 8ce6e0c

File tree

5 files changed

+45
-18
lines changed

5 files changed

+45
-18
lines changed

include/nbl/video/TimelineEventHandlers.h

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,10 @@ class TimelineEventHandlerBase : core::Unmovable, core::Uncopyable
3434
core::smart_refctd_ptr<const ISemaphore> m_sema;
3535
};
3636

37-
template<typename Functor>
38-
class MultiTimelineEventHandlerST;
39-
4037
// Could be made MT and relatively lockless, if only had a good lock-few circular buffer impl
4138
// Not sure its worth the effort as anything using this will probably need to be lockful to be MT
4239
template<typename Functor>
43-
class TimelineEventHandlerST final : TimelineEventHandlerBase
40+
class TimelineEventHandlerST final : public TimelineEventHandlerBase
4441
{
4542
public:
4643
// Theoretically could make a factory function cause passing a null semaphore is invalid, but counting on users to be relatively intelligent.
@@ -160,7 +157,8 @@ class TimelineEventHandlerST final : TimelineEventHandlerBase
160157
inline void abortAll(Args&&... args) {abortOldest(~0ull,std::forward<Args>(args)...);}
161158

162159
private:
163-
friend MultiTimelineEventHandlerST<Functor>;
160+
// To get access to almost everything
161+
template<typename Functor_, bool RefcountTheDevice> friend class MultiTimelineEventHandlerST;
164162

165163
struct FunctorValuePair
166164
{
@@ -227,21 +225,53 @@ class TimelineEventHandlerST final : TimelineEventHandlerBase
227225
}
228226
};
229227

230-
//
231-
template<typename Functor>
228+
// `RefcountTheDevice` should be false for any "internal user" of the Handler inside the Logical Device, such as the IQueue to avoid circular refs
229+
/*
230+
template<bool RefcountTheDevice>
231+
class MultiTimelineEventHandlerBase : core::Unmovable, core::Uncopyable
232+
{
233+
public:
234+
using device_ptr_t = std::conditional_t<RefcountTheDevice,core::smart_refctd_ptr<ILogicalDevice>,ILogicalDevice*>;
235+
inline MultiTimelineEventHandlerBase(device_ptr_t&& device) : m_device(std::move(device)) {}
236+
237+
inline ILogicalDevice* getLogicalDevice() const {return m_device.get();}
238+
239+
protected:
240+
template<typename Functor>
241+
static inline auto getGreatestSignal(const TimelineEventHandlerST<Functor>* handler) {return handler->m_greatestSignal;}
242+
template<typename Functor>
243+
static inline auto getEmpty(const TimelineEventHandlerST<Functor>* handler) {return handler->m_cb.empty();}
244+
245+
device_ptr_t m_device;
246+
};
247+
*/
248+
template<typename Functor, bool RefcountTheDevice=true>
232249
class MultiTimelineEventHandlerST final : core::Unmovable, core::Uncopyable
233250
{
234251
public:
235252
using TimelineEventHandler = TimelineEventHandlerST<Functor>;
253+
using device_ptr_t = std::conditional_t<RefcountTheDevice,core::smart_refctd_ptr<ILogicalDevice>,ILogicalDevice*>;
236254

237-
inline MultiTimelineEventHandlerST(core::smart_refctd_ptr<ILogicalDevice>&& device) : m_device(std::move(device)) {}
255+
inline MultiTimelineEventHandlerST(ILogicalDevice* device) : m_device(device) {}
256+
MultiTimelineEventHandlerST(const MultiTimelineEventHandlerST&) = delete;
238257
inline ~MultiTimelineEventHandlerST()
239258
{
240259
clear();
241260
}
242261

243-
inline ILogicalDevice* getLogicalDevice() const {return m_device.get();}
262+
//
263+
MultiTimelineEventHandlerST& operator=(const MultiTimelineEventHandlerST&) = delete;
264+
265+
//
266+
inline ILogicalDevice* getLogicalDevice() const
267+
{
268+
if constexpr (RefcountTheDevice)
269+
return m_device.get();
270+
else
271+
return m_device;
272+
}
244273

274+
//
245275
inline const auto& getTimelines() const {return m_timelines;}
246276

247277
// all the members are counteparts of the single timeline version
@@ -258,7 +288,7 @@ class MultiTimelineEventHandlerST final : core::Unmovable, core::Uncopyable
258288
auto found = m_timelines.find(futureWait.semaphore);
259289
if (found==m_timelines.end())
260290
{
261-
if (futureWait.semaphore->getOriginDevice()!=m_device.get())
291+
if (futureWait.semaphore->getOriginDevice()!=getLogicalDevice())
262292
return false;
263293
STimeline newTimeline = {
264294
.handler = new TimelineEventHandler(core::smart_refctd_ptr<const ISemaphore>(futureWait.semaphore)),
@@ -441,7 +471,7 @@ class MultiTimelineEventHandlerST final : core::Unmovable, core::Uncopyable
441471

442472
container_t m_timelines;
443473
core::vector<ISemaphore::SWaitInfo> m_scratchWaitInfos;
444-
core::smart_refctd_ptr<ILogicalDevice> m_device;
474+
device_ptr_t m_device;
445475
};
446476

447477
}

include/nbl/video/alloc/CAsyncSingleBufferSubAllocator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ class CAsyncSingleBufferSubAllocator
118118
// perfect forward ctor to `CSingleBufferSubAllocator`
119119
template<typename... Args>
120120
inline CAsyncSingleBufferSubAllocator(Args&&... args) : m_composed(std::forward<Args>(args)...),
121-
deferredFrees(core::smart_refctd_ptr<ILogicalDevice>(const_cast<ILogicalDevice*>(m_composed.getBuffer()->getOriginDevice()))) {}
121+
deferredFrees(const_cast<ILogicalDevice*>(m_composed.getBuffer()->getOriginDevice())) {}
122122
virtual ~CAsyncSingleBufferSubAllocator() {}
123123

124124

include/nbl/video/utilities/ICommandPoolCache.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ class ICommandPoolCache : public core::IReferenceCounted
119119
protected:
120120
friend class DeferredCommandPoolResetter;
121121
inline ICommandPoolCache(core::smart_refctd_ptr<ILogicalDevice>&& device, core::smart_refctd_ptr<IGPUCommandPool>* cache, const uint32_t capacity, void* reserved) :
122-
m_cache(cache), m_reserved(malloc(CommandPoolAllocator::reserved_size(1u,capacity,1u))), m_cmdPoolAllocator(m_reserved,0u,0u,1u,capacity,1u), m_deferredResets(std::move(device)) {}
122+
m_cache(cache), m_reserved(malloc(CommandPoolAllocator::reserved_size(1u,capacity,1u))), m_cmdPoolAllocator(m_reserved,0u,0u,1u,capacity,1u), m_deferredResets(device.get()) {}
123123
inline virtual ~ICommandPoolCache()
124124
{
125125
// normally the dtor would do this, but we need all the events to run before we delete the storage they reference

include/nbl/video/utilities/IDescriptorSetCache.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ class IDescriptorSetCache : public core::IReferenceCounted
137137
void* const reserved
138138
) : m_descPool(std::move(pool)), m_canonicalLayout(std::move(canonicalLayout)), m_cache(cache),
139139
m_reserved(reserved), m_setAllocator(m_reserved,0u,0u,1u,m_descPool->getCapacity(),1u),
140-
m_deferredReclaims(core::smart_refctd_ptr<ILogicalDevice>(const_cast<ILogicalDevice*>(m_descPool->getOriginDevice())))
140+
m_deferredReclaims(const_cast<ILogicalDevice*>(m_descPool->getOriginDevice()))
141141
{}
142142
virtual inline ~IDescriptorSetCache()
143143
{

src/nbl/video/ISwapchain.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,7 @@ ISwapchain::ISwapchain(core::smart_refctd_ptr<const ILogicalDevice>&& dev, SCrea
2828
m_params.queueFamilyIndices = {m_queueFamilies.data(),m_params.queueFamilyIndices.size()};
2929

3030
for (auto i=0; i<m_imageCount; i++)
31-
{
32-
auto device = core::smart_refctd_ptr<ILogicalDevice>(const_cast<ILogicalDevice*>(getOriginDevice()));
33-
m_frameResources[i] = std::make_unique<MultiTimelineEventHandlerST<DeferredFrameResourceDrop>>(std::move(device));
34-
}
31+
m_frameResources[i] = std::make_unique<MultiTimelineEventHandlerST<DeferredFrameResourceDrop>>(const_cast<ILogicalDevice*>(getOriginDevice()));
3532
}
3633

3734
}

0 commit comments

Comments
 (0)