@@ -2523,9 +2523,7 @@ bool SyncValidator::ProcessQueueSubmit(VkQueue queue, uint32_t submitCount, cons
25232523 queue_state.SetLastBatch (std::move (new_last_batch));
25242524 }
25252525 if (!new_unresolved_batches.empty () && !skip) {
2526- auto unresolved_batches = queue_state.UnresolvedBatches ();
2527- vvl::Append (unresolved_batches, new_unresolved_batches);
2528- queue_state.SetUnresolvedBatches (std::move (unresolved_batches));
2526+ vvl::Append (queue_state.UnresolvedBatches (), new_unresolved_batches);
25292527 }
25302528
25312529 // Check if timeline signals resolve existing wait-before-signal dependencies
@@ -2549,94 +2547,73 @@ bool SyncValidator::ProcessQueueSubmit(VkQueue queue, uint32_t submitCount, cons
25492547
25502548bool SyncValidator::PropagateTimelineSignals (SignalsUpdate& signals_update, const ErrorObject& error_obj) {
25512549 bool skip = false ;
2552- // Initialize per-queue unresolved batches state.
2553- std::vector<UnresolvedQueue> queues;
2554- for (QueueState& queue_state : queue_states_) {
2555- if (!queue_state.UnresolvedBatches ().empty ()) {
2556- queues.emplace_back (UnresolvedQueue{&queue_state, queue_state.UnresolvedBatches ()});
2557- }
2558- }
25592550
2560- // Each iteration uses registered timeline signals to resolve existing unresolved batches.
2561- // Each resolved batch can generate new timeline signals which can resolve more unresolved batches on the next iteration.
2562- // This finishes when all unresolved batches are resolved or when iteration does not generate new timeline signals.
2563- while (ProcessUnresolvedBatches (queues, signals_update, skip, error_obj)) {
2564- ;
2565- }
2551+ // The caller ensures we just registered new timeline signals
2552+ bool new_timeline_signals = true ;
25662553
2567- // Update unresolved state
2568- for (UnresolvedQueue& queue : queues) {
2569- if (queue.update_unresolved ) {
2570- queue.queue_state ->SetUnresolvedBatches (std::move (queue.unresolved_batches ));
2571- }
2572- }
2573- return skip;
2574- }
2554+ // Each iteration uses registered timeline signals to resolve batches.
2555+ // If a resolved batch generates new timeline signals, the loop runs again
2556+ while (new_timeline_signals) {
2557+ new_timeline_signals = false ;
25752558
2576- bool SyncValidator::ProcessUnresolvedBatches (std::vector<UnresolvedQueue>& queues, SignalsUpdate& signals_update, bool & skip,
2577- const ErrorObject& error_obj) const {
2578- bool has_new_timeline_signals = false ;
2579- for ( auto & queue : queues) {
2580- if (queue. unresolved_batches . empty ()) {
2581- continue ; // all batches for this queue were resolved by previous iterations
2582- }
2583- // Resolve waits that have matching signal
2584- for (UnresolvedBatch& unresolved_batch : queue. unresolved_batches ) {
2585- auto it = unresolved_batch. unresolved_waits . begin () ;
2586- while (it != unresolved_batch. unresolved_waits . end ()) {
2587- const VkSemaphoreSubmitInfo& wait_info = *it;
2588- auto resolving_signal = signals_update. OnTimelineWait (wait_info. semaphore , wait_info. value ) ;
2589- if (!resolving_signal. has_value ()) {
2590- ++it;
2591- continue ; // resolving signal not found, the wait stays unresolved
2592- }
2593- if (resolving_signal-> batch ) { // null for host signals
2594- unresolved_batch.batch -> ResolveSubmitSemaphoreWait (* resolving_signal, wait_info. stageMask );
2595- unresolved_batch. batch -> ImportTags (*resolving_signal-> batch );
2596- unresolved_batch.resolved_dependencies . emplace_back (resolving_signal-> batch );
2559+ for (QueueState& queue_state : queue_states_) {
2560+ auto & unresolved_batches = queue_state. UnresolvedBatches ();
2561+ if (unresolved_batches. empty ()) {
2562+ continue ;
2563+ }
2564+ // Resolve waits that have matching signal
2565+ for (UnresolvedBatch& unresolved_batch : unresolved_batches) {
2566+ auto it = unresolved_batch. unresolved_waits . begin ();
2567+ while (it != unresolved_batch. unresolved_waits . end () ) {
2568+ const VkSemaphoreSubmitInfo& wait_info = *it ;
2569+ auto resolving_signal = signals_update. OnTimelineWait (wait_info. semaphore , wait_info. value );
2570+ if (!resolving_signal. has_value ()) {
2571+ ++it ;
2572+ continue ; // resolving signal not found, the wait stays unresolved
2573+ }
2574+ if (resolving_signal-> batch ) { // null for host signals
2575+ unresolved_batch. batch -> ResolveSubmitSemaphoreWait (*resolving_signal, wait_info. stageMask );
2576+ unresolved_batch. batch -> ImportTags (*resolving_signal-> batch );
2577+ unresolved_batch.resolved_dependencies . emplace_back ( resolving_signal-> batch );
2578+ }
2579+ it = unresolved_batch.unresolved_waits . erase (it );
25972580 }
2598- it = unresolved_batch.unresolved_waits .erase (it);
25992581 }
2600- }
2601-
2602- BatchContextPtr last_batch = queue.queue_state ->LastBatch ();
2603- const BatchContextPtr initial_last_batch = last_batch;
26042582
2605- // Process batches that do not have unresolved waits anymore.
2606- // Stop when find a batch with unresolved waits or when all the batches are processed.
2607- while (!queue.unresolved_batches .empty () && queue.unresolved_batches .front ().unresolved_waits .empty ()) {
2608- UnresolvedBatch& ready_batch = queue.unresolved_batches .front ();
2609-
2610- // Import the previous batch information
2611- if (last_batch && !vvl::Contains (ready_batch.resolved_dependencies , last_batch)) {
2612- ready_batch.batch ->ResolveLastBatch (last_batch);
2613- ready_batch.resolved_dependencies .emplace_back (std::move (last_batch));
2614- }
2615- last_batch = ready_batch.batch ;
2583+ BatchContextPtr last_batch = queue_state.LastBatch ();
2584+ const BatchContextPtr initial_last_batch = last_batch;
26162585
2617- const auto async_batches = ready_batch.batch ->RegisterAsyncContexts (ready_batch.resolved_dependencies );
2586+ // Process batches that do not have unresolved waits anymore.
2587+ // Stop when find a batch with unresolved waits or when all the batches are processed.
2588+ while (!unresolved_batches.empty () && unresolved_batches.front ().unresolved_waits .empty ()) {
2589+ UnresolvedBatch& ready_batch = unresolved_batches.front ();
26182590
2619- skip |= ready_batch.batch ->ValidateSubmit (ready_batch.command_buffers , ready_batch.submit_index ,
2620- ready_batch.batch_index , ready_batch.label_stack , error_obj);
2591+ // Import the previous batch information
2592+ if (last_batch && !vvl::Contains (ready_batch.resolved_dependencies , last_batch)) {
2593+ ready_batch.batch ->ResolveLastBatch (last_batch);
2594+ ready_batch.resolved_dependencies .emplace_back (std::move (last_batch));
2595+ }
26212596
2622- // Process signals. New timeline signals can resolve more batches on the next iteration
2623- const auto submit_signals = vvl::make_span (ready_batch.signals .data (), ready_batch.signals .size ());
2624- has_new_timeline_signals |= signals_update.RegisterSignals (ready_batch.batch , submit_signals);
2597+ const auto async_batches = ready_batch.batch ->RegisterAsyncContexts (ready_batch.resolved_dependencies );
26252598
2626- // Remove processed batch from the (local) unresolved list
2627- queue. unresolved_batches . erase (queue. unresolved_batches . begin () );
2599+ skip |= ready_batch. batch -> ValidateSubmit (ready_batch. command_buffers , ready_batch. submit_index ,
2600+ ready_batch. batch_index , ready_batch. label_stack , error_obj );
26282601
2629- // Propagate change into the queue's (global) unresolved state
2630- queue.update_unresolved = true ;
2602+ // Process signals. New timeline signals can resolve more batches on the next iteration
2603+ const auto submit_signals = vvl::make_span (ready_batch.signals .data (), ready_batch.signals .size ());
2604+ new_timeline_signals |= signals_update.RegisterSignals (ready_batch.batch , submit_signals);
26312605
2632- stats.RemoveUnresolvedBatch ();
2633- }
2606+ last_batch = ready_batch.batch ;
2607+ unresolved_batches.erase (unresolved_batches.begin ());
2608+ stats.RemoveUnresolvedBatch ();
2609+ }
26342610
2635- if (last_batch != initial_last_batch) {
2636- queue.queue_state ->SetLastBatch (std::move (last_batch));
2611+ if (last_batch != initial_last_batch) {
2612+ queue_state.SetLastBatch (std::move (last_batch));
2613+ }
26372614 }
26382615 }
2639- return has_new_timeline_signals ;
2616+ return skip ;
26402617}
26412618
26422619void SyncValidator::PostCallRecordGetFenceStatus (VkDevice device, VkFence fence, const RecordObject& record_obj) {
0 commit comments