Skip to content

Commit 77dd4d7

Browse files
Use Frames In Flight Timeline Semaphores for the acquires as per the conversion with Erfan
1 parent 55241a6 commit 77dd4d7

File tree

1 file changed

+17
-20
lines changed

1 file changed

+17
-20
lines changed

include/nbl/video/utilities/ISimpleManagedSurface.h

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -160,19 +160,14 @@ class NBL_API2 ISimpleManagedSurface : public core::IReferenceCounted
160160
{
161161
deinit_impl();
162162

163-
if (m_acquireSemaphore)
164-
{
165-
auto device = const_cast<ILogicalDevice*>(m_acquireSemaphore->getOriginDevice());
166-
const ISemaphore::SWaitInfo info[1] = {{
167-
.semaphore = m_acquireSemaphore.get(), .value = m_acquireCount
168-
}};
169-
device->blockForSemaphores(info);
170-
}
163+
// I'm going to be lazy and do this instead of blocking on each of `m_acquireSemaphores`
164+
if (m_queue)
165+
m_queue->waitIdle();
171166

172167
m_queue = nullptr;
173168
m_maxFramesInFlight = 0;
174-
m_acquireSemaphore = 0;
175169
m_acquireCount = 0;
170+
std::fill(m_acquireSemaphores.begin(),m_acquireSemaphores.end(),nullptr);
176171
}
177172

178173
//
@@ -183,7 +178,7 @@ class NBL_API2 ISimpleManagedSurface : public core::IReferenceCounted
183178

184179
// An interesting solution to the "Frames In Flight", our tiny wrapper class will have its own Timeline Semaphore incrementing with each acquire, and thats it.
185180
inline uint64_t getAcquireCount() {return m_acquireCount;}
186-
inline ISemaphore* getAcquireSemaphore() {return m_acquireSemaphore.get();}
181+
inline ISemaphore* getAcquireSemaphore() {return m_acquireSemaphores[m_acquireCount%m_maxFramesInFlight].get(); }
187182

188183
protected: // some of the methods need to stay protected in this base class because they need to be performed under a Mutex for smooth resize variants
189184
inline ISimpleManagedSurface(core::smart_refctd_ptr<ISurface>&& _surface, ICallback* _cb) : m_surface(std::move(_surface)), m_cb(_cb) {}
@@ -211,15 +206,15 @@ class NBL_API2 ISimpleManagedSurface : public core::IReferenceCounted
211206
m_maxFramesInFlight = core::min(caps.maxImageCount+1-caps.minImageCount,ISwapchain::MaxImages);
212207
}
213208

214-
if (m_maxFramesInFlight)
209+
for (uint8_t i=0u; i<m_maxFramesInFlight; i++)
215210
{
216-
m_acquireSemaphore = device->createSemaphore(0u);
217-
if (m_acquireSemaphore)
218-
return true;
211+
m_acquireSemaphores[i] = device->createSemaphore(0u);
212+
if (!m_acquireSemaphores[i])
213+
return init_fail();
219214
}
220215
}
221216
}
222-
return init_fail();
217+
return true;
223218
}
224219

225220
// just a simple convenience wrapper
@@ -243,10 +238,11 @@ class NBL_API2 ISimpleManagedSurface : public core::IReferenceCounted
243238
if (!swapchainResources || swapchainResources->getStatus()!=ISwapchainResources::STATUS::USABLE)
244239
return ISwapchain::MaxImages;
245240

241+
const auto nextAcquireSignal = m_acquireCount+1;
246242
const IQueue::SSubmitInfo::SSemaphoreInfo signalInfos[1] = {
247243
{
248-
.semaphore=m_acquireSemaphore.get(),
249-
.value=m_acquireCount+1
244+
.semaphore=m_acquireSemaphores[nextAcquireSignal%m_maxFramesInFlight].get(),
245+
.value=nextAcquireSignal
250246
}
251247
};
252248

@@ -257,7 +253,7 @@ class NBL_API2 ISimpleManagedSurface : public core::IReferenceCounted
257253
case ISwapchain::ACQUIRE_IMAGE_RESULT::SUBOPTIMAL: [[fallthrough]];
258254
case ISwapchain::ACQUIRE_IMAGE_RESULT::SUCCESS:
259255
// the semaphore will only get signalled upon a successful acquire
260-
m_acquireCount++;
256+
m_acquireCount = nextAcquireSignal;
261257
return static_cast<uint8_t>(imageIndex);
262258
case ISwapchain::ACQUIRE_IMAGE_RESULT::TIMEOUT: [[fallthrough]];
263259
case ISwapchain::ACQUIRE_IMAGE_RESULT::NOT_READY: // don't throw our swapchain away just because of a timeout XD
@@ -327,8 +323,9 @@ class NBL_API2 ISimpleManagedSurface : public core::IReferenceCounted
327323
CThreadSafeQueueAdapter* m_queue = nullptr;
328324
//
329325
uint8_t m_maxFramesInFlight = 0;
330-
// created and persistent after first initialization
331-
core::smart_refctd_ptr<ISemaphore> m_acquireSemaphore;
326+
// Created and persistent after first initialization, Note that we need one swapchain per Frame In Fligth because Acquires can't wait or synchronize with anything
327+
// The only rule is that you can only have `m_maxFramesInFlight` pending acquires to wait with an infinte timeout, so thats about as far as they synchronize.
328+
std::array<core::smart_refctd_ptr<ISemaphore>,ISwapchain::MaxImages> m_acquireSemaphores;
332329
// You don't want to use `m_swapchainResources.swapchain->getAcquireCount()` because it resets when swapchain gets recreated
333330
uint64_t m_acquireCount = 0;
334331
};

0 commit comments

Comments
 (0)