| 434 | } |
| 435 | |
| 436 | void vvl::Semaphore::RetireWait(vvl::Queue* current_queue, uint64_t payload, const Location& loc, bool queue_thread) { |
| 437 | std::shared_future<void> waiter; |
| 438 | bool retire_external_payload = false; |
| 439 | uint64_t external_payload = 0; |
| 440 | { |
| 441 | auto guard = WriteLock(); |
| 442 | if (payload <= completed_.payload) { |
| 443 | return; |
| 444 | } |
| 445 | if (scope_ != kInternal) { |
| 446 | if (!vvl::Find(timeline_, payload)) { |
| 447 | // GetSemaphoreCounterValue for external semaphore might not have a registered timepoint. |
| 448 | // Add timepoint so we can retire timeline up to that point. |
| 449 | assert(type == VK_SEMAPHORE_TYPE_TIMELINE); |
| 450 | auto payload_it = timeline_.insert({payload, TimePoint{}}).first; |
| 451 | |
| 452 | // Search existing signal. If found, notify corresponding submission. |
| 453 | // (external payload, which is already reached by the gpu, is larger than found signal, |
| 454 | // this means that earlier signals were also processed, so we can retire them) |
| 455 | for (auto it = std::make_reverse_iterator(payload_it); it != timeline_.rend(); ++it) { |
| 456 | const TimePoint& t = it->second; |
| 457 | if (t.signal_submit.has_value() && t.signal_submit->queue) { |
| 458 | retire_external_payload = true; |
| 459 | external_payload = payload; |
| 460 | // Update payload value to retire existing signal. |
| 461 | // External payload will be retired after that to update current payload value. |
| 462 | payload = it->first; |
| 463 | break; |
| 464 | } |
| 465 | } |
| 466 | } |
| 467 | if (scope_ == kExternalTemporary) { |
| 468 | scope_ = kInternal; |
| 469 | imported_handle_type_.reset(); |
| 470 | } |
| 471 | } |
| 472 | TimePoint& timepoint = vvl::FindExisting(timeline_, payload); |
| 473 | |
| 474 | bool retire = false; |
| 475 | if (timepoint.acquire_command) { |
| 476 | retire = true; // There is resolving acquire signal, timepoint can be retired |
| 477 | } else if (type == VK_SEMAPHORE_TYPE_BINARY) { |
| 478 | retire = CanRetireBinaryWait(timepoint); |
| 479 | } else { |
| 480 | retire = CanRetireTimelineWait(current_queue, payload); |
| 481 | } |
| 482 | if (retire) { |
| 483 | RetireTimePoint(payload, kWait, current_queue); |
| 484 | return; |
| 485 | } |
| 486 | |
| 487 | // Wait for some other queue or a host operation to retire |
| 488 | assert(timepoint.waiter.valid()); |
| 489 | // the current timepoint should get destroyed while we're waiting, so copy out the waiter. |
| 490 | waiter = timepoint.waiter; |
| 491 | } |
| 492 | |
| 493 | WaitTimePoint(std::move(waiter), payload, !queue_thread, loc); |
no test coverage detected