| 502 | } |
| 503 | |
| 504 | void PMTraceConsumer::HandleDxgkQueueSubmit( |
| 505 | EVENT_HEADER const& hdr, |
| 506 | uint64_t hContext, |
| 507 | uint32_t submitSequence, |
| 508 | uint32_t packetType, |
| 509 | bool isPresentPacket, |
| 510 | bool isWin7) |
| 511 | { |
| 512 | // Track GPU execution |
| 513 | if (mTrackGPU) { |
| 514 | bool isWaitPacket = packetType == (uint32_t) Microsoft_Windows_DxgKrnl::QueuePacketType::DXGKETW_WAIT_COMMAND_BUFFER; |
| 515 | mGpuTrace.EnqueueQueuePacket(hContext, submitSequence, hdr.ProcessId, hdr.TimeStamp.QuadPart, isWaitPacket); |
| 516 | } |
| 517 | |
| 518 | // For blt presents on Win7, the only way to distinguish between DWM-off |
| 519 | // fullscreen blts and the DWM-on blt to redirection bitmaps is to track |
| 520 | // whether a PHT was submitted before submitting anything else to the same |
| 521 | // context, which indicates it's a redirected blt. If we get to here |
| 522 | // instead, the present is a fullscreen blt and considered completed once |
| 523 | // its work is done. |
| 524 | if (isWin7) { |
| 525 | auto eventIter = mPresentByDxgkContext.find(hContext); |
| 526 | if (eventIter != mPresentByDxgkContext.end()) { |
| 527 | auto present = eventIter->second; |
| 528 | |
| 529 | if (present->PresentMode == PresentMode::Hardware_Legacy_Copy_To_Front_Buffer) { |
| 530 | VerboseTraceBeforeModifyingPresent(present.get()); |
| 531 | present->SeenDxgkPresent = true; |
| 532 | |
| 533 | // If the work is already done, complete it now. |
| 534 | if (HasScreenTime(present)) { |
| 535 | CompletePresent(present); |
| 536 | } |
| 537 | } |
| 538 | |
| 539 | // We're done with DxgkContext tracking, if the present hasn't |
| 540 | // completed remove it from the tracking now. |
| 541 | if (present->DxgkContext != 0) { |
| 542 | mPresentByDxgkContext.erase(eventIter); |
| 543 | present->DxgkContext = 0; |
| 544 | } |
| 545 | } |
| 546 | } |
| 547 | |
| 548 | // This event is emitted after a flip/blt/PHT event, and may be the only |
| 549 | // way to trace completion of the present. |
| 550 | if (packetType == (uint32_t) Microsoft_Windows_DxgKrnl::QueuePacketType::DXGKETW_MMIOFLIP_COMMAND_BUFFER || |
| 551 | packetType == (uint32_t) Microsoft_Windows_DxgKrnl::QueuePacketType::DXGKETW_SOFTWARE_COMMAND_BUFFER || |
| 552 | isPresentPacket) { |
| 553 | auto present = FindPresentByThreadId(hdr.ThreadId); |
| 554 | if (present != nullptr && present->QueueSubmitSequence == 0) { |
| 555 | |
| 556 | VerboseTraceBeforeModifyingPresent(present.get()); |
| 557 | present->QueueSubmitSequence = submitSequence; |
| 558 | |
| 559 | auto presentsBySubmitSequence = &mPresentBySubmitSequence[submitSequence]; |
| 560 | DebugAssert(presentsBySubmitSequence->find(hContext) == presentsBySubmitSequence->end()); |
| 561 | (*presentsBySubmitSequence)[hContext] = present; |
nothing calls this directly
no test coverage detected