You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
//! Struct meant to be used with any utility (not just `IUtilities`) which exhibits "submit on overflow" behaviour.
198
+
//! Struct meant to be used with any Utility (not just `IUtilities`) which exhibits "submit on overflow" behaviour.
212
199
//! Such functions are non-blocking (unless overflow) and take `SIntendedSubmitInfo` by reference and patch it accordingly.
213
200
//! MAKE SURE to do a submit to `queue` by yourself with a submit info obtained by casting `this` to `IQueue::SSubmitInfo` !
214
201
//! for example: in the case the `frontHalf.waitSemaphores` were already waited upon, the struct will be modified to have it's `waitSemaphores` emptied.
@@ -219,8 +206,12 @@ class NBL_API2 IUtilities : public core::IReferenceCounted
219
206
{
220
207
if (!frontHalf.valid() || frontHalf.commandBuffers.empty() || signalSemaphores.empty())
221
208
returnfalse;
209
+
// Must be resettable so we can end, submit, wait, reset and continue recording commands into it as-if nothing happened
222
210
if (!frontHalf.getScratchCommandBuffer()->isResettable())
223
211
returnfalse;
212
+
// It makes no sense to reuse the same commands for a second submission.
213
+
// Moreover its dangerous because the utilities record their own internal commands which might use subresources for which
214
+
// frees have already been latched on the scratch semaphore you must signal anyway.
224
215
if (!frontHalf.getScratchCommandBuffer()->getRecordingFlags().hasFlags(IGPUCommandBuffer::USAGE::ONE_TIME_SUBMIT_BIT))
225
216
returnfalse;
226
217
returntrue;
@@ -263,9 +254,32 @@ class NBL_API2 IUtilities : public core::IReferenceCounted
263
254
}
264
255
265
256
266
-
//! The last CommandBuffer will be used to record the copy commands
267
-
SFrontHalfSubmitInfo frontHalf = {};
268
-
//! The first Semaphore will be used as a scratch, so don't use it yourself as we can advance the counter an arbitrary amount!
257
+
//! The last CommandBuffer will be used to record the copy commands
258
+
structSFrontHalffinal
259
+
{
260
+
//! We can't check it, but all (if any) all the command buffers except the last one should be in `EXECUTABLE` state.
261
+
inlineboolvalid() const {return queue;}
262
+
263
+
// Use the last command buffer in intendedNextSubmit, it should be in recording state
//! The first Semaphore will be used as a scratch, so don't choose the values for waits and signals yourself as we can advance the counter an arbitrary amount!
277
+
//! You can actually examine the change in `signalSemaphore.front().value` to figure out how many overflows occurred.
278
+
//! This semaphore is needed to "stitch together" additional submits if they occur so they occur before and after the original intended waits and signals.
279
+
//! We use the first semaphore to keep the intended order of original semaphore signal and waits unchanged no matter how many overflows occur.
280
+
//! You do however, NEED TO KEEP IT in the signal set of the last submit you're supposed to do manually, this allows freeing any resources used
281
+
//! after the submit is done, indicating that your streaming routine is done.
282
+
//! * Also use this parameter to signal new semaphores so that other submits know your Utility method is done.
@@ -280,55 +294,34 @@ class NBL_API2 IUtilities : public core::IReferenceCounted
280
294
//! Copies `data` to stagingBuffer and Records the commands needed to copy the data from stagingBuffer to `bufferRange.buffer`
281
295
//! If the allocation from staging memory fails due to large buffer size or fragmentation then This function may need to submit the command buffer via the `submissionQueue`.
282
296
//! Returns:
283
-
//! the number of times we overflown and had to submit, <0 [negative] on failure
297
+
//! True on successful recording of copy commands and handling of overflows, false on failure for any reason.
284
298
//! Parameters:
285
299
//! - nextSubmit:
286
300
//! Is the SubmitInfo you intended to submit your command buffers with, it will be patched if overflow occurred @see SIntendedSubmitInfo
287
301
//! - bufferRange: contains offset + size into bufferRange::buffer that will be copied from `data` (offset doesn't affect how `data` is accessed)
288
302
//! - data: raw pointer to data that will be copied to bufferRange::buffer
289
-
//! - submissionQueue: IQueue used to submit, when needed.
290
-
//! Note: This parameter is required but may not be used if there is no need to submit
291
-
//! - scratchSemaphore:
292
-
//! - since you've already decided on the semaphores you'll wait and signal in the `intendedNextSubmit`, we need an extra semaphore to "stich together" the submit if we split it
293
-
294
-
295
-
//! - This is the fence you will use to submit the copies to, this allows freeing up space in stagingBuffer when the fence is signalled, indicating that the copy has finished.
296
-
//! - This fence will be in `UNSIGNALED` state after exiting the function. (It will reset after each implicit submit)
297
-
//! - This fence may be used for CommandBuffer submissions using `submissionQueue` inside the function.
298
-
//! ** NOTE: This fence will be signalled everytime there is a submission inside this function, which may be more than one until the job is finished.
299
303
//! Valid Usage:
304
+
//! * nextSubmit must be valid (see `SIntendedSubmitInfo::valid()`)
305
+
//! * bufferRange must be valid (see `SBufferRange::isValid()`)
300
306
//! * data must not be nullptr
301
-
//! * bufferRange should be valid (see SBufferRange::isValid())
302
-
//! * intendedNextSubmit::commandBufferCount must be > 0
303
-
//! * The commandBuffers should have been allocated from a CommandPool with the same queueFamilyIndex as `submissionQueue`
304
-
//! * The last command buffer should be in `RECORDING` state.
305
-
//! * The last command buffer should be must've called "begin()" with `IGPUCommandBuffer::USAGE::ONE_TIME_SUBMIT_BIT` flag
306
-
//! The reason is the commands recorded into the command buffer would not be valid for a second submission and the stagingBuffer memory wouldv'e been freed/changed.
307
-
//! * The last command buffer should be "resettable". See `ICommandBuffer::E_STATE` comments
308
-
//! * To ensure correct execution order, (if any) all the command buffers except the last one should be in `EXECUTABLE` state.
309
-
//! * submissionQueue must point to a valid IQueue
310
-
//! * submissionFence must point to a valid IGPUFence
311
-
//! * submissionFence must be in `UNSIGNALED` state
312
-
//! ** IUtility::getDefaultUpStreamingBuffer()->cull_frees() should be called before reseting the submissionFence and after fence is signaled.
if (!bufferRange.isValid() || !bufferRange.buffer->getCreationParams().usage.hasFlags(asset::IBuffer::EUF_TRANSFER_DST_BIT))
316
310
{
317
311
m_logger.log("Invalid `bufferRange` or buffer has no `EUF_TRANSFER_DST_BIT` usage flag, cannot `updateBufferRangeViaStagingBuffer`!", system::ILogger::ELL_ERROR);
//! This function is an specialization of the `updateBufferRangeViaStagingBuffer` function above.
379
-
//! Submission of the commandBuffer to submissionQueue happens automatically, no need for the user to handle submit
370
+
//! This method lets you wrap any other function following the "submit on overflow" pattern with the final submission
371
+
//! to `intendedSubmit.queue` happening automatically, no need for the user to handle the submit at the end.
380
372
//! WARNING: Don't use this function in hot loops or to do batch updates, its merely a convenience for one-off uploads
373
+
//! of the `updateBufferRangeViaStagingBufferAutoSubmit` function above.
381
374
//! Parameters:
382
-
//! - `submitInfo`: IQueue::SSubmitInfo used to submit the copy operations.
383
-
//! * Use this parameter to wait for previous operations to finish using submitInfo::waitSemaphores or signal new semaphores using submitInfo::signalSemaphores
384
-
//! * Fill submitInfo::commandBuffers with the commandbuffers you want to be submitted before the copy in this struct as well, for example pipeline barrier commands.
385
-
//! * Empty by default: waits for no semaphore and signals no semaphores.
386
-
//! Patches the submitInfo::commandBuffers
375
+
//! - `intendedSubmit`: more lax than regular `SIntendedSubmitInfo::valid()`, only needs a valid queue and at least one semaphore to signal (how else will you know you're done?)
376
+
//! since the submit must and will happen, there's no point updating the semaphore and commandbuffer info spans in the intendedSubmit
//! Patches the intendedSubmit::frontHalf::commandBuffers
387
412
//! If submitInfo::commandBufferCount == 0, it will create an implicit command buffer to use for recording copy commands
388
413
//! If submitInfo::commandBufferCount > 0 the last command buffer is in `EXECUTABLE` state, It will add another temporary command buffer to end of the array and use it for recording and submission
389
414
//! If submitInfo::commandBufferCount > 0 the last command buffer is in `RECORDING` or `INITIAL` state, It won't add another command buffer and uses the last command buffer for the copy commands.
@@ -408,34 +433,16 @@ class NBL_API2 IUtilities : public core::IReferenceCounted
auto mem = m_device->allocate(mreqs,buffer.get());
438
-
if (!updateBufferRangeViaStagingBufferAutoSubmit(submit,asset::SBufferRange<IGPUBuffer>{0u,params.size,core::smart_refctd_ptr(buffer)},data))
445
+
if (!autoSubmitAndBlock(submit,[&](auto& info){returnupdateBufferRangeViaStagingBuffer(info,asset::SBufferRange<IGPUBuffer>{0u,params.size,core::smart_refctd_ptr(buffer)},data);}))
0 commit comments