MCPcopy Create free account
hub / github.com/GameTechDev/PresentMon / HandleDxgkFlip

Method HandleDxgkFlip

PresentData/PresentMonTraceConsumer.cpp:423–502  ·  view source on GitHub ↗

A flip event is emitted during fullscreen present submission. We expect the following event sequence emitted on the same thread: PresentStart FlipMultiPlaneOverlay_Info QueuePacket_Start SubmitSequence MMIOFLIP bPresent=1 QueuePacket_Stop SubmitSequence PresentStop

Source from the content-addressed store, hash-verified

421// QueuePacket_Stop SubmitSequence
422// PresentStop
423std::shared_ptr<PresentEvent> PMTraceConsumer::HandleDxgkFlip(EVENT_HEADER const& hdr)
424{
425 // First, lookup the in-progress present on the same thread.
426 //
427 // The present should not have a known QueueSubmitSequence nor seen a DxgkPresent yet, so if it
428 // does then we've looked up the wrong present. Typically, this means we've lost tracking for
429 // the looked-up present, and it should be discarded.
430 //
431 // However, DWM on recent windows may omit the PresentStart/PresentStop events. In this case,
432 // we'll end up creating the present here and, because there is no PresentStop, it will be left
433 // in mPresentByThreadId and looked up again in the next HandleDxgkFlip().
434 std::shared_ptr<PresentEvent> presentEvent;
435 for (;;) {
436 // Lookup the in-progress present on this thread.
437 auto ii = mPresentByThreadId.find(hdr.ThreadId);
438 if (ii != mPresentByThreadId.end()) {
439 presentEvent = ii->second;
440
441 // If the in-progress present has seen DxgkPresent, it has lost tracking.
442 if (presentEvent->SeenDxgkPresent) {
443 RemoveLostPresent(presentEvent);
444 continue;
445 }
446
447 // If the in-progress present has seen PresentStop, it has lost tracking.
448 if (presentEvent->QueueSubmitSequence != 0 &&
449 presentEvent->TimeInPresent != 0 &&
450 presentEvent->Runtime != Runtime::Other) {
451 RemoveLostPresent(presentEvent);
452 continue;
453 }
454
455 // If we did see a PresentStart, then use this present
456 if (presentEvent->Runtime != Runtime::Other) {
457 // There may be duplicate flip events for MPO situations, so only handle the first.
458 if (presentEvent->PresentMode != PresentMode::Unknown) {
459 return nullptr;
460 }
461 break;
462 }
463
464 // The looked-up present was created by the last Flip, and didn't see a PresentStop; remove
465 // it from the thread tracking and create a new present for this flip.
466 mPresentByThreadId.erase(ii);
467 }
468
469 // Create a new present for this flip
470 if (!IsProcessTrackedForFiltering(hdr.ProcessId)) {
471 return nullptr;
472 }
473
474 presentEvent = std::make_shared<PresentEvent>();
475
476 VerboseTraceBeforeModifyingPresent(presentEvent.get());
477 presentEvent->PresentStartTime = *(uint64_t*) &hdr.TimeStamp;
478 presentEvent->ProcessId = hdr.ProcessId;
479 presentEvent->ThreadId = hdr.ThreadId;
480

Callers

nothing calls this directly

Calls 2

emptyMethod · 0.80
endMethod · 0.45

Tested by

no test coverage detected