| 569 | } |
| 570 | |
| 571 | void PMTraceConsumer::HandleDxgkQueueComplete(uint64_t timestamp, uint64_t hContext, uint32_t submitSequence) |
| 572 | { |
| 573 | // Track GPU execution of the packet |
| 574 | if (mTrackGPU) { |
| 575 | mGpuTrace.CompleteQueuePacket(hContext, submitSequence, timestamp); |
| 576 | } |
| 577 | |
| 578 | // If this packet was a present packet being tracked... |
| 579 | auto ii = mPresentBySubmitSequence.find(submitSequence); |
| 580 | if (ii != mPresentBySubmitSequence.end()) { |
| 581 | auto presentsBySubmitSequence = &ii->second; |
| 582 | auto jj = presentsBySubmitSequence->find(hContext); |
| 583 | if (jj != presentsBySubmitSequence->end()) { |
| 584 | auto pEvent = jj->second; |
| 585 | |
| 586 | // Stop tracking GPU work for this present. |
| 587 | // |
| 588 | // Note: there is a potential race here because QueuePacket_Stop |
| 589 | // occurs sometime after DmaPacket_Info it's possible that some |
| 590 | // small portion of the next frame's GPU work has started before |
| 591 | // QueuePacket_Stop and will be attributed to this frame. However, |
| 592 | // this is necessarily a small amount of work, and we can't use DMA |
| 593 | // packets as not all present types create them. |
| 594 | if (mTrackGPU) { |
| 595 | mGpuTrace.CompleteFrame(pEvent.get(), timestamp); |
| 596 | } |
| 597 | |
| 598 | // We use present packet completion as the screen time for |
| 599 | // Hardware_Legacy_Copy_To_Front_Buffer and Hardware_Legacy_Flip |
| 600 | // present modes, unless we are expecting a subsequent flip/*sync |
| 601 | // event from DXGK. |
| 602 | if (pEvent->PresentMode == PresentMode::Hardware_Legacy_Copy_To_Front_Buffer || |
| 603 | (pEvent->PresentMode == PresentMode::Hardware_Legacy_Flip && !pEvent->WaitForFlipEvent)) { |
| 604 | VerboseTraceBeforeModifyingPresent(pEvent.get()); |
| 605 | |
| 606 | if (pEvent->ReadyTime == 0) { |
| 607 | pEvent->ReadyTime = timestamp; |
| 608 | } |
| 609 | |
| 610 | SetScreenTime(pEvent, timestamp); |
| 611 | |
| 612 | // Sometimes, the queue packets associated with a present will complete |
| 613 | // before the DxgKrnl PresentInfo event is fired. For blit presents in |
| 614 | // this case, we have no way to differentiate between fullscreen and |
| 615 | // windowed blits, so we defer the completion of this present until |
| 616 | // we've also seen the Dxgk Present_Info event. |
| 617 | if (pEvent->SeenDxgkPresent || pEvent->PresentMode != PresentMode::Hardware_Legacy_Copy_To_Front_Buffer) { |
| 618 | CompletePresent(pEvent); |
| 619 | } |
| 620 | } |
| 621 | } |
| 622 | } |
| 623 | } |
| 624 | |
| 625 | // Lookup the present associated with this submit sequence. Because some DXGK |
| 626 | // events that reference submit sequence id don't include the queue context, |
nothing calls this directly
no test coverage detected