@@ -13,7 +13,7 @@ namespace nbl::video
13
13
IQueue::IQueue (ILogicalDevice* originDevice, const uint32_t _famIx, const core::bitflag<CREATE_FLAGS> _flags, const float _priority)
14
14
: m_originDevice(originDevice), m_familyIndex(_famIx), m_priority(_priority), m_flags(_flags)
15
15
{
16
- m_submittedResources = std::make_unique<MultiTimelineEventHandlerST<DeferredSubmitResourceDrop ,false >>(originDevice);
16
+ m_submittedResources = std::make_unique<MultiTimelineEventHandlerST<DeferredSubmitCallback ,false >>(originDevice);
17
17
}
18
18
19
19
auto IQueue::submit (const std::span<const SSubmitInfo> _submits) -> RESULT
@@ -111,7 +111,7 @@ auto IQueue::submit(const std::span<const SSubmitInfo> _submits) -> RESULT
111
111
{
112
112
// hold onto the semaphores and commandbuffers until the submit signals the last semaphore
113
113
const auto & lastSignal = submit.signalSemaphores .back ();
114
- m_submittedResources->latch ({.semaphore =lastSignal.semaphore ,.value =lastSignal.value },DeferredSubmitResourceDrop (submit));
114
+ m_submittedResources->latch ({.semaphore =lastSignal.semaphore ,.value =lastSignal.value },DeferredSubmitCallback (submit));
115
115
// Mark cmdbufs as done (wrongly but conservatively wrong)
116
116
// We can't use `m_submittedResources` to mark them done, because the functor may run "late" in the future, after the cmdbuf has already been validly reset or resubmitted
117
117
for (const auto & commandBuffer : submit.commandBuffers )
@@ -141,6 +141,64 @@ uint32_t IQueue::cullResources(const ISemaphore* sema)
141
141
return m_submittedResources->poll ().eventsLeft ;
142
142
}
143
143
144
+ IQueue::DeferredSubmitCallback::DeferredSubmitCallback (const SSubmitInfo& info)
145
+ {
146
+ // We could actually not hold any signal semaphore because you're expected to use the signal result somewhere else.
147
+ // However it's possible to you might only wait on one from the set and then drop the rest (UB)
148
+ m_resources = core::make_refctd_dynamic_array<decltype (m_resources)>(info.signalSemaphores .size ()-1 +info.commandBuffers .size ()+info.waitSemaphores .size ());
149
+ auto outRes = m_resources->data ();
150
+ for (const auto & sema : info.waitSemaphores )
151
+ *(outRes++) = smart_ptr (sema.semaphore );
152
+ for (const auto & cb : info.commandBuffers )
153
+ {
154
+ *(outRes++) = smart_ptr (cb.cmdbuf );
155
+ // get the TLAS BLAS tracking info and assign a pending build version number
156
+ for (const auto & refSet : cb.cmdbuf ->m_TLASToBLASReferenceSets )
157
+ {
158
+ const auto tlas = refSet.first ;
159
+ // in theory could assert no duplicate entries, but thats obvious
160
+ m_TLASToBLASReferenceSets[tlas] = { .m_BLASes = {refSet.second .begin (),refSet.second .end ()}, .m_buildVer = tlas->registerNextBuildVer ()};
161
+ }
162
+ }
163
+ // We don't hold the last signal semaphore, because the timeline does as an Event trigger.
164
+ for (auto i=0u ; i<info.signalSemaphores .size ()-1 ; i++)
165
+ *(outRes++) = smart_ptr (info.signalSemaphores [i].semaphore );
166
+ // copy the function object for the callback
167
+ if (info.completionCallback )
168
+ m_callback = *info.completionCallback ;
169
+ }
170
+
171
+ IQueue::DeferredSubmitCallback& IQueue::DeferredSubmitCallback::operator =(DeferredSubmitCallback&& other)
172
+ {
173
+ m_TLASToBLASReferenceSets = std::move (other.m_TLASToBLASReferenceSets );
174
+ m_resources = std::move (other.m_resources );
175
+ m_callback = std::move (other.m_callback );
176
+ other.m_TLASToBLASReferenceSets = {};
177
+ other.m_resources = nullptr ;
178
+ other.m_callback = {};
179
+ return *this ;
180
+ }
181
+
182
+ // always exhaustive poll, because we need to get rid of resources ASAP
183
+ void IQueue::DeferredSubmitCallback::operator ()()
184
+ {
185
+ // first update tracking info (needs resources alive)
186
+ for (const auto & refSet : m_TLASToBLASReferenceSets)
187
+ {
188
+ const auto tlas = refSet.first ;
189
+ const auto & blases = refSet.second .m_BLASes ;
190
+ tlas->setTrackedBLASes (blases.begin (),blases.end (),refSet.second .m_buildVer );
191
+ }
192
+ // then free all resources
193
+ m_resources = nullptr ;
194
+ // then execute the callback
195
+ if (m_callback)
196
+ {
197
+ m_callback ();
198
+ m_callback = {};
199
+ }
200
+ }
201
+
144
202
} // namespace nbl::video
145
203
146
204
#include " nbl/undef_logging_macros.h"
0 commit comments