Skip to content

Commit a615003

Browse files
fix a smal bug and introduce a base class for TimelineEventHandler, also get everything to compile
1 parent 159277e commit a615003

File tree

3 files changed

+45
-34
lines changed

3 files changed

+45
-34
lines changed

include/nbl/video/TimelineEventHandlers.h

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,48 @@
99

1010
namespace nbl::video
1111
{
12+
class TimelineEventHandlerBase : core::Unmovable, core::Uncopyable
13+
{
14+
public:
15+
struct PollResult
16+
{
17+
uint32_t eventsLeft = ~0u;
18+
bool bailed = false;
19+
};
20+
21+
// little utility
22+
inline const ISemaphore* getSemaphore() const { return m_sema.get(); }
23+
24+
// todo: rename to default_wait_point ?
25+
template<class Clock=std::chrono::steady_clock>
26+
static inline Clock::time_point default_wait()
27+
{
28+
return Clock::now()+std::chrono::microseconds(50);
29+
}
30+
31+
protected:
32+
TimelineEventHandlerBase(core::smart_refctd_ptr<const ISemaphore>&& sema) : m_sema(std::move(sema)) {}
33+
34+
core::smart_refctd_ptr<const ISemaphore> m_sema;
35+
};
36+
1237
template<typename Functor>
1338
class MultiTimelineEventHandlerST;
1439

1540
// Could be made MT and relatively lockless, if only had a good lock-few circular buffer impl
1641
// Not sure its worth the effort as anything using this will probably need to be lockful to be MT
1742
template<typename Functor>
18-
class TimelineEventHandlerST final : core::Unmovable, core::Uncopyable
43+
class TimelineEventHandlerST final : TimelineEventHandlerBase
1944
{
2045
public:
2146
// Theoretically could make a factory function cause passing a null semaphore is invalid, but counting on users to be relatively intelligent.
2247
inline TimelineEventHandlerST(core::smart_refctd_ptr<const ISemaphore>&& sema, const uint64_t initialCapacity=4095/sizeof(FunctorValuePair)+1) :
23-
m_sema(std::move(sema)), m_greatestLatch(0)
24-
{
25-
m_greatestSignal = m_sema->getCounterValue();
26-
}
48+
TimelineEventHandlerBase(std::move(sema)), m_greatestLatch(0), m_greatestSignal(m_sema->getCounterValue()) {}
2749
// If you don't want to deadlock here, look into the `abort*` family of methods
2850
~TimelineEventHandlerST()
2951
{
3052
while (wait(std::chrono::steady_clock::now()+std::chrono::seconds(5))) {}
3153
}
32-
// little utility
33-
inline const ISemaphore* getSemaphore() const {return m_sema.get();}
3454

3555
inline uint32_t count() const {return m_cb.size();}
3656

@@ -44,23 +64,12 @@ class TimelineEventHandlerST final : core::Unmovable, core::Uncopyable
4464
}
4565

4666
//
47-
struct PollResult
48-
{
49-
uint32_t eventsLeft = ~0u;
50-
bool bailed = false;
51-
};
5267
template<typename... Args>
5368
inline PollResult poll(Args&&... args)
5469
{
5570
return poll_impl<true>(std::forward<Args>(args)...);
5671
}
5772

58-
template<class Clock=std::chrono::steady_clock>
59-
static inline Clock::time_point default_wait()
60-
{
61-
return Clock::now()+std::chrono::microseconds(50);
62-
}
63-
6473
template<class Clock, class Duration=typename Clock::duration, typename... Args>
6574
inline uint32_t wait(const std::chrono::time_point<Clock,Duration>& timeout_time, Args&&... args)
6675
{
@@ -160,7 +169,6 @@ class TimelineEventHandlerST final : core::Unmovable, core::Uncopyable
160169
};
161170
// could be a circular buffer but whatever for now
162171
core::deque<FunctorValuePair> m_cb;
163-
core::smart_refctd_ptr<const ISemaphore> m_sema;
164172
uint64_t m_greatestSignal;
165173
uint64_t m_greatestLatch;
166174

@@ -410,7 +418,7 @@ class MultiTimelineEventHandlerST final : core::Unmovable, core::Uncopyable
410418
inline container_t::iterator eraseTimeline(typename container_t::iterator timeline)
411419
{
412420
// if not the last in scratch
413-
if (timeline->waitInfoIx<m_scratchWaitInfos.size())
421+
if (timeline->waitInfoIx+1<m_scratchWaitInfos.size())
414422
{
415423
// swap the mapping with the end scratch element
416424
const auto& lastScratch = m_scratchWaitInfos.back();

include/nbl/video/alloc/CAsyncSingleBufferSubAllocator.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ class CAsyncSingleBufferSubAllocator
117117

118118
// perfect forward ctor to `CSingleBufferSubAllocator`
119119
template<typename... Args>
120-
inline CAsyncSingleBufferSubAllocator(Args&&... args) : m_composed(std::forward<Args>(args)...) {}
120+
inline CAsyncSingleBufferSubAllocator(Args&&... args) : m_composed(std::forward<Args>(args)...),
121+
deferredFrees(core::smart_refctd_ptr<ILogicalDevice>(const_cast<ILogicalDevice*>(m_composed.getBuffer()->getOriginDevice()))) {}
121122
virtual ~CAsyncSingleBufferSubAllocator() {}
122123

123124

@@ -135,7 +136,7 @@ class CAsyncSingleBufferSubAllocator
135136
std::unique_lock<std::recursive_mutex> tLock(stAccessVerfier,std::try_to_lock_t());
136137
assert(tLock.owns_lock());
137138
#endif // _NBL_DEBUG
138-
return deferredFrees.poll();
139+
return deferredFrees.poll().eventsLeft;
139140
}
140141

141142
//! Returns max possible currently allocatable single allocation size, without having to wait for GPU more
@@ -200,7 +201,7 @@ class CAsyncSingleBufferSubAllocator
200201
std::unique_lock<std::recursive_mutex> tLock(stAccessVerfier,std::try_to_lock_t());
201202
assert(tLock.owns_lock());
202203
#endif // _NBL_DEBUG
203-
multi_deallocate(count,addr,bytes,nullptr);
204+
multi_deallocate(count,addr,bytes,{});
204205
}
205206
// TODO: improve signature of this function in the future
206207
template<typename T=core::IReferenceCounted>

include/nbl/video/alloc/StreamingTransientDataBuffer.h

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2018-2020 - DevSH Graphics Programming Sp. z O.O.
1+
// Copyright (C) 2018-2024 - DevSH Graphics Programming Sp. z O.O.
22
// This file is part of the "Nabla Engine".
33
// For conditions of distribution and use, see copyright notice in nabla.h
44
#ifndef _NBL_VIDEO_STREAMING_TRANSIENT_DATA_BUFFER_H_
@@ -15,7 +15,6 @@
1515
namespace nbl::video
1616
{
1717

18-
#if 0 // TODO: port
1918
template<class HostAllocator=core::allocator<uint8_t>, class RecursiveLockable=std::recursive_mutex>
2019
class StreamingTransientDataBufferMT;
2120

@@ -39,24 +38,28 @@ class StreamingTransientDataBuffer
3938
template<typename... Args>
4039
inline StreamingTransientDataBuffer(asset::SBufferRange<IGPUBuffer>&& _bufferRange, Args&&... args) : m_composed(std::move(_bufferRange),std::forward<Args>(args)...)
4140
{
42-
assert(getBuffer()->getBoundMemory()->isMappable());
43-
assert(getBuffer()->getBoundMemory()->getMappedPointer());
41+
assert(getBuffer()->getBoundMemory().memory->isMappable());
42+
assert(getBuffer()->getBoundMemory().memory->getMappedPointer());
4443
// we're suballocating from a buffer, whole buffer needs to be reachable from the mapped pointer
45-
const auto mappedRange = getBuffer()->getBoundMemory()->getMappedRange();
46-
assert(mappedRange.offset<=getBuffer()->getBoundMemoryOffset());
47-
assert(mappedRange.offset+mappedRange.length>=getBuffer()->getBoundMemoryOffset()+getBuffer()->getSize());
44+
const auto mappedRange = getBuffer()->getBoundMemory().memory->getMappedRange();
45+
assert(mappedRange.offset<=getBuffer()->getBoundMemory().offset);
46+
assert(mappedRange.offset+mappedRange.length>=getBuffer()->getBoundMemory().offset+getBuffer()->getSize());
4847
}
4948
virtual ~StreamingTransientDataBuffer() {}
5049

5150
//
52-
inline bool needsManualFlushOrInvalidate() const {return getBuffer()->getBoundMemory()->haveToMakeVisible();}
51+
inline bool needsManualFlushOrInvalidate() const {return getBuffer()->getBoundMemory().memory->haveToMakeVisible();}
5352

5453
// getters
5554
inline IGPUBuffer* getBuffer() noexcept {return m_composed.getBuffer();}
5655
inline const IGPUBuffer* getBuffer() const noexcept {return m_composed.getBuffer();}
5756

5857
//
59-
inline void* getBufferPointer() noexcept {return getBuffer()->getBoundMemory()->getMappedPointer();}
58+
inline void* getBufferPointer() noexcept
59+
{
60+
const auto bound = getBuffer()->getBoundMemory();
61+
return reinterpret_cast<uint8_t*>(bound.memory->getMappedPointer())+bound.offset;
62+
}
6063

6164
//
6265
inline uint32_t cull_frees() noexcept {return m_composed.cull_frees();}
@@ -99,7 +102,7 @@ class StreamingTransientDataBuffer
99102
template<typename... Args>
100103
inline size_type multi_place(uint32_t count, Args&&... args) noexcept
101104
{
102-
return multi_place(GPUEventWrapper::default_wait(), count, std::forward<Args>(args)...);
105+
return multi_place(TimelineEventHandlerBase::default_wait(),count,std::forward<Args>(args)...);
103106
}
104107
};
105108
}
@@ -206,7 +209,6 @@ class StreamingTransientDataBufferMT : public core::IReferenceCounted
206209
return lock;
207210
}
208211
};
209-
#endif
210212

211213
}
212214

0 commit comments

Comments
 (0)