@@ -335,29 +335,76 @@ void QueueBatchContext::ApplyPredicatedWait(Predicate& predicate, const LastSync
335335 });
336336}
337337
338+ struct WaitQueueTagPredicate {
339+ QueueId queue;
340+ ResourceUsageTag tag;
341+
342+ bool operator ()(const ReadState& read_access) const {
343+ return read_access.queue == queue && read_access.tag <= tag &&
344+ read_access.stage != VK_PIPELINE_STAGE_2_PRESENT_ENGINE_BIT_SYNCVAL;
345+ }
346+ bool operator ()(const AccessState& access) const {
347+ if (!access.HasWriteOp ()) {
348+ return false ;
349+ }
350+ const WriteState& write_state = access.LastWrite ();
351+ return write_state.queue == queue && write_state.tag <= tag &&
352+ write_state.access_index != SYNC_PRESENT_ENGINE_SYNCVAL_PRESENT_PRESENTED_SYNCVAL;
353+ }
354+ };
355+
356+ struct DeviceWaitPredicate {
357+ bool operator ()(const ReadState& read_access) const {
358+ return read_access.stage != VK_PIPELINE_STAGE_2_PRESENT_ENGINE_BIT_SYNCVAL;
359+ }
360+ bool operator ()(const AccessState& access) const {
361+ if (!access.HasWriteOp ()) {
362+ return false ;
363+ }
364+ return access.LastWrite ().access_index != SYNC_PRESENT_ENGINE_SYNCVAL_PRESENT_PRESENTED_SYNCVAL;
365+ }
366+ };
367+
368+ // Present operations matching only the *exactly* tagged present and acquire operations
369+ struct WaitAcquirePredicate {
370+ ResourceUsageTag present_tag;
371+ ResourceUsageTag acquire_tag;
372+
373+ bool operator ()(const ReadState& read_access) const {
374+ return read_access.tag == acquire_tag && read_access.stage == VK_PIPELINE_STAGE_2_PRESENT_ENGINE_BIT_SYNCVAL;
375+ }
376+ bool operator ()(const AccessState& access) const {
377+ if (!access.HasWriteOp ()) {
378+ return false ;
379+ }
380+ const WriteState& write_state = access.LastWrite ();
381+ return write_state.tag == present_tag && write_state.access_index == SYNC_PRESENT_ENGINE_SYNCVAL_PRESENT_PRESENTED_SYNCVAL;
382+ }
383+ };
384+
338385void QueueBatchContext::ApplyTaggedWait (QueueId queue_id, ResourceUsageTag tag,
339386 const LastSynchronizedPresent& last_synchronized_present) {
340- const bool any_queue = (queue_id == kQueueAny );
341-
342- if (any_queue) {
343- // This isn't just avoid an unneeded test, but to allow *all* queues to to be waited in a single pass
344- // (and it does avoid doing the same test for every access, as well as avoiding the need for the predicate
345- // to grok Queue/Device/Wait differences.
346- AccessState::WaitTagPredicate predicate{tag};
347- ApplyPredicatedWait (predicate, last_synchronized_present);
348- } else {
349- AccessState::WaitQueueTagPredicate predicate{queue_id, tag};
350- ApplyPredicatedWait (predicate, last_synchronized_present);
351- }
387+ WaitQueueTagPredicate predicate{queue_id, tag};
388+ ApplyPredicatedWait (predicate, last_synchronized_present);
352389
353- // SwapChain acquire QBC's have no queue, but also, events are always empty.
354- if (queue_state_ && ( queue_id == GetQueueId () || any_queue )) {
390+ // SwapChain acquire batch contexts have no queue
391+ if (queue_state_ && queue_id == GetQueueId ()) {
355392 events_context_.ApplyTaggedWait (queue_state_->GetQueueFlags (), tag);
356393 }
357394}
358395
396+ void QueueBatchContext::ApplyDeviceWait (const LastSynchronizedPresent& last_synchronized_present) {
397+ DeviceWaitPredicate predicate;
398+ ApplyPredicatedWait (predicate, last_synchronized_present);
399+
400+ // SwapChain acquire batch contexts have no queue
401+ if (queue_state_) {
402+ events_context_.ApplyTaggedWait (queue_state_->GetQueueFlags (), ResourceUsageRecord::kMaxIndex );
403+ }
404+ }
405+
359406void QueueBatchContext::ApplyAcquireWait (const AcquiredImage& acquired) {
360- AccessState:: WaitAcquirePredicate predicate{acquired.present_tag , acquired.acquire_tag };
407+ WaitAcquirePredicate predicate{acquired.present_tag , acquired.acquire_tag };
361408 ApplyPredicatedWait (predicate, {});
362409}
363410
0 commit comments