Skip to content

Commit c08c307

Browse files
[PresentData] Convert deferred reason bitmask into bools
Should have no functional change, this is to make the code conceptually simpler.
1 parent 02e85da commit c08c307

File tree

5 files changed

+66
-70
lines changed

5 files changed

+66
-70
lines changed

IntelPresentMon/PresentMonUtils/PresentMonNamedPipe.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,6 @@ struct PmNsmPresentEvent {
144144
uint32_t QueueSubmitSequence; // mPresentBySubmitSequence
145145
uint32_t RingIndex; // mTrackedPresents and mCompletedPresents
146146

147-
uint32_t DeferredReason; // The reason(s) this present is being deferred (see DeferredReason enum).
148-
149147
// Properties deduced by watching events through present pipeline
150148
uint32_t DestWidth;
151149
uint32_t DestHeight;

IntelPresentMon/Streamer/Streamer.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,6 @@ void Streamer::CopyFromPresentMonPresentEvent(
101101
nsm_present_event->RingIndex =
102102
present_event->RingIndex;
103103

104-
nsm_present_event->DeferredReason =
105-
present_event->DeferredReason;
106-
107104
nsm_present_event->DestWidth = present_event->DestWidth;
108105
nsm_present_event->DestHeight = present_event->DestHeight;
109106
nsm_present_event->DriverThreadId = present_event->DriverThreadId;

PresentData/Debug.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,6 @@ void PrintPresentResult(PresentResult value)
124124
default: wprintf(L"Unknown (%u)", value); assert(false); break;
125125
}
126126
}
127-
void PrintDeferredReason(uint32_t value)
128-
{
129-
switch (value) {
130-
case DeferredReason_None: wprintf(L"None"); break;
131-
case DeferredReason_WaitingForPresentStop: wprintf(L"WaitingForPresentStop"); break;
132-
case DeferredReason_WaitingForFlipFrameType: wprintf(L"WaitingForFlipFrameType"); break;
133-
default: wprintf(L"Unknown (%u)", value); assert(false); break;
134-
}
135-
}
136127
void PrintPresentHistoryModel(uint32_t model)
137128
{
138129
using namespace Microsoft_Windows_DxgKrnl;
@@ -286,7 +277,8 @@ void FlushModifiedPresent()
286277
FLUSH_MEMBER(PrintBool, IsCompleted)
287278
FLUSH_MEMBER(PrintBool, IsLost)
288279
FLUSH_MEMBER(PrintBool, PresentFailed)
289-
FLUSH_MEMBER(PrintDeferredReason, DeferredReason)
280+
FLUSH_MEMBER(PrintBool, WaitingForPresentStop)
281+
FLUSH_MEMBER(PrintBool, WaitingForFlipFrameType)
290282
FLUSH_MEMBER(PrintFrameType, FrameType)
291283
#undef FLUSH_MEMBER
292284

PresentData/PresentMonTraceConsumer.cpp

Lines changed: 50 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ PresentEvent::PresentEvent()
124124
, PresentFailed(false)
125125
, PresentInDwmWaitingStruct(false)
126126

127-
, DeferredReason(DeferredReason_None)
127+
, WaitingForPresentStop(false)
128+
, WaitingForFlipFrameType(false)
128129

129130
#ifdef TRACK_PRESENT_PATHS
130131
, AnalysisPath(0ull)
@@ -400,7 +401,7 @@ void PMTraceConsumer::HandleDxgkQueueSubmit(
400401
if (packetType == (uint32_t) Microsoft_Windows_DxgKrnl::QueuePacketType::DXGKETW_MMIOFLIP_COMMAND_BUFFER ||
401402
packetType == (uint32_t) Microsoft_Windows_DxgKrnl::QueuePacketType::DXGKETW_SOFTWARE_COMMAND_BUFFER ||
402403
isPresentPacket) {
403-
auto present = FindThreadPresent(hdr.ThreadId);
404+
auto present = FindPresentByThreadId(hdr.ThreadId);
404405
if (present != nullptr && present->QueueSubmitSequence == 0) {
405406

406407
TRACK_PRESENT_PATH(present);
@@ -1020,7 +1021,7 @@ void PMTraceConsumer::HandleDXGKEvent(EVENT_RECORD* pEventRecord)
10201021
// no further work was needed.
10211022
case Microsoft_Windows_DxgKrnl::BlitCancel_Info::Id:
10221023
{
1023-
auto present = FindThreadPresent(hdr.ThreadId);
1024+
auto present = FindPresentByThreadId(hdr.ThreadId);
10241025
if (present != nullptr) {
10251026
TRACK_PRESENT_PATH(present);
10261027

@@ -1219,18 +1220,21 @@ void PMTraceConsumer::HandleDXGKEvent(EVENT_RECORD* pEventRecord)
12191220
DebugAssert(present == nullptr || present->PresentIds.empty());
12201221

12211222
for (uint32_t i = 0; i < PlaneCount; ++i) {
1222-
// Any previous present on this VidPnLayer will not get any more
1223-
// FlipFrameType events.
1223+
1224+
// Mark any present already assigned to this VidPnLayer as they will not be
1225+
// getting any more FlipFrameType events.
12241226
auto vidPnLayerId = GenerateVidPnLayerId(VidPnSourceId, LayerIndex[i]);
12251227
{
12261228
auto ii = mPresentByVidPnLayerId.find(vidPnLayerId);
12271229
if (ii != mPresentByVidPnLayerId.end()) {
12281230
auto p2 = ii->second;
1229-
mPresentByVidPnLayerId.erase(ii); // Remove first because ClearDeferredReason() may
1230-
// complete the present can trigger removal.
1231+
mPresentByVidPnLayerId.erase(ii); // Remove first because UpdateReadyCount() may
1232+
// call StopTrackingPresent()
12311233

1232-
if (p2->DeferredReason & DeferredReason_WaitingForFlipFrameType) {
1233-
ClearDeferredReason(p2, DeferredReason_WaitingForFlipFrameType);
1234+
VerboseTraceBeforeModifyingPresent(p2.get());
1235+
if (p2->WaitingForFlipFrameType) {
1236+
p2->WaitingForFlipFrameType = false;
1237+
UpdateReadyCount(p2);
12341238
} else {
12351239
p2->PresentIds.clear();
12361240
}
@@ -1242,7 +1246,6 @@ void PMTraceConsumer::HandleDXGKEvent(EVENT_RECORD* pEventRecord)
12421246
if (present != nullptr) {
12431247
VerboseTraceBeforeModifyingPresent(present.get());
12441248
present->PresentIds.emplace(vidPnLayerId, PresentId[i]);
1245-
12461249
mPresentByVidPnLayerId.emplace(vidPnLayerId, present);
12471250
}
12481251

@@ -1706,8 +1709,9 @@ void PMTraceConsumer::RemovePresentFromSubmitSequenceIdTracking(std::shared_ptr<
17061709
// presentsBySubmitSequence is expected to be small (typically one element)
17071710
// this should be faster.
17081711
if (presentsBySubmitSequence->size() == 1) {
1709-
DebugAssert(presentsBySubmitSequence->begin()->second == present);
1710-
mPresentBySubmitSequence.erase(ii);
1712+
if (presentsBySubmitSequence->begin()->second == present) {
1713+
mPresentBySubmitSequence.erase(ii);
1714+
}
17111715
} else {
17121716
for (auto jj = presentsBySubmitSequence->begin(), je = presentsBySubmitSequence->end(); jj != je; ++jj) {
17131717
if (jj->second == present) {
@@ -1743,7 +1747,7 @@ void PMTraceConsumer::StopTrackingPresent(std::shared_ptr<PresentEvent> const& p
17431747
//
17441748
// We don't reset ThreadId nor DriverThreadId as both are useful outside of
17451749
// tracking.
1746-
if ((p->DeferredReason & DeferredReason_WaitingForPresentStop) == 0) {
1750+
if (!p->WaitingForPresentStop) {
17471751
auto ii = mPresentByThreadId.find(p->ThreadId);
17481752
if (ii != mPresentByThreadId.end() && ii->second == p) {
17491753
mPresentByThreadId.erase(ii);
@@ -1808,7 +1812,7 @@ void PMTraceConsumer::StopTrackingPresent(std::shared_ptr<PresentEvent> const& p
18081812
}
18091813

18101814
// mPresentByVidPnLayerId (unless it will be needed by deferred FlipFrameType handling)
1811-
if ((p->DeferredReason & DeferredReason_WaitingForFlipFrameType) == 0 ) {
1815+
if (!p->WaitingForFlipFrameType) {
18121816
for (auto const& pr : p->PresentIds) {
18131817
auto ii = mPresentByVidPnLayerId.find(pr.first);
18141818
if (ii != mPresentByVidPnLayerId.end() && ii->second == p) {
@@ -1936,8 +1940,10 @@ void PMTraceConsumer::CompletePresent(std::shared_ptr<PresentEvent> const& p)
19361940
p2->IsLost = true;
19371941
}
19381942

1939-
if (p2->DeferredReason & DeferredReason_WaitingForFlipFrameType) {
1940-
ClearDeferredReason(p2, DeferredReason_WaitingForFlipFrameType);
1943+
if (p2->WaitingForFlipFrameType) {
1944+
VerboseTraceBeforeModifyingPresent(p2.get());
1945+
p2->WaitingForFlipFrameType = false;
1946+
UpdateReadyCount(p2);
19411947
} else {
19421948
CompletePresent(p2);
19431949
}
@@ -1951,7 +1957,7 @@ void PMTraceConsumer::CompletePresent(std::shared_ptr<PresentEvent> const& p)
19511957
// Present_Stop will check if the present is completed and add it to the dequeue list if so.
19521958
if (!p->IsLost && p->Runtime != Runtime::Other && p->TimeInPresent == 0) {
19531959
VerboseTraceBeforeModifyingPresent(p.get());
1954-
p->DeferredReason |= DeferredReason_WaitingForPresentStop;
1960+
p->WaitingForPresentStop = true;
19551961
}
19561962

19571963
// If flip frame type tracking is enabled, we defer the completion because we may see subsequent
@@ -1960,7 +1966,7 @@ void PMTraceConsumer::CompletePresent(std::shared_ptr<PresentEvent> const& p)
19601966
// (VidPnSourceId, LayerIndex) pair.
19611967
if (mTrackFrameType && !p->PresentIds.empty()) {
19621968
VerboseTraceBeforeModifyingPresent(p.get());
1963-
p->DeferredReason |= DeferredReason_WaitingForFlipFrameType;
1969+
p->WaitingForFlipFrameType = true;
19641970
}
19651971

19661972
// Remove the present from tracking structures.
@@ -2006,12 +2012,10 @@ void PMTraceConsumer::AddPresentToCompletedList(std::shared_ptr<PresentEvent> co
20062012
}
20072013

20082014
mCompletedPresents[index] = present;
2009-
2010-
if (present->DeferredReason == DeferredReason_None && index == GetRingIndex(mCompletedIndex + mReadyCount)) {
2011-
mReadyCount++;
2012-
}
20132015
}
20142016

2017+
UpdateReadyCount(present);
2018+
20152019
// It's possible for a deferred condition to never be cleared. e.g., a process' last present
20162020
// doesn't get a Present_Stop event. When this happens the deferred present will prevent all
20172021
// subsequent presents from other processes from being dequeued until the ring buffer wraps and
@@ -2023,27 +2027,31 @@ void PMTraceConsumer::AddPresentToCompletedList(std::shared_ptr<PresentEvent> co
20232027
present->PresentStartTime - deferredPresent->PresentStartTime > mDeferralTimeLimit) {
20242028
VerboseTraceBeforeModifyingPresent(deferredPresent.get());
20252029
deferredPresent->IsLost = true;
2026-
ClearDeferredReason(deferredPresent, deferredPresent->DeferredReason);
2030+
deferredPresent->WaitingForPresentStop = false;
2031+
deferredPresent->WaitingForFlipFrameType = false;
2032+
UpdateReadyCount(deferredPresent);
20272033
}
20282034
}
20292035
}
20302036

2031-
void PMTraceConsumer::ClearDeferredReason(std::shared_ptr<PresentEvent> const& present, uint32_t deferredReason)
2037+
void PMTraceConsumer::UpdateReadyCount(std::shared_ptr<PresentEvent> const& present)
20322038
{
2033-
// Remove the deferred reason
2034-
if (present->DeferredReason != DeferredReason_None) {
2035-
VerboseTraceBeforeModifyingPresent(present.get());
2036-
present->DeferredReason &= ~deferredReason;
2039+
if (!present->WaitingForPresentStop &&
2040+
!present->WaitingForFlipFrameType) {
20372041

20382042
StopTrackingPresent(present);
20392043

2040-
if (present->DeferredReason == DeferredReason_None) {
2044+
{
20412045
std::lock_guard<std::mutex> lock(mPresentEventMutex);
20422046

2043-
uint32_t nextIndex = GetRingIndex(mCompletedIndex + mReadyCount);
2044-
while (mReadyCount < mCompletedCount && mCompletedPresents[nextIndex]->DeferredReason == DeferredReason_None) {
2045-
mReadyCount++;
2046-
nextIndex = GetRingIndex(mCompletedIndex + mReadyCount);
2047+
uint32_t i = GetRingIndex(mCompletedIndex + mReadyCount);
2048+
if (present == mCompletedPresents[i]) {
2049+
DebugAssert(mReadyCount < mCompletedCount);
2050+
do {
2051+
mReadyCount += 1;
2052+
i = GetRingIndex(i + 1);
2053+
} while (mReadyCount < mCompletedCount && !mCompletedPresents[i]->WaitingForPresentStop
2054+
&& !mCompletedPresents[i]->WaitingForFlipFrameType);
20472055
}
20482056
}
20492057
}
@@ -2061,7 +2069,7 @@ void PMTraceConsumer::SetThreadPresent(uint32_t threadId, std::shared_ptr<Presen
20612069
mPresentByThreadId.emplace(threadId, present);
20622070
}
20632071

2064-
std::shared_ptr<PresentEvent> PMTraceConsumer::FindThreadPresent(uint32_t threadId)
2072+
std::shared_ptr<PresentEvent> PMTraceConsumer::FindPresentByThreadId(uint32_t threadId)
20652073
{
20662074
auto ii = mPresentByThreadId.find(threadId);
20672075
return ii == mPresentByThreadId.end() ? std::shared_ptr<PresentEvent>() : ii->second;
@@ -2071,7 +2079,7 @@ std::shared_ptr<PresentEvent> PMTraceConsumer::FindOrCreatePresent(EVENT_HEADER
20712079
{
20722080
// First, we check if there is an in-progress present that was last
20732081
// operated on from this same thread.
2074-
auto present = FindThreadPresent(hdr.ThreadId);
2082+
auto present = FindPresentByThreadId(hdr.ThreadId);
20752083
if (present != nullptr) {
20762084
return present;
20772085
}
@@ -2204,19 +2212,19 @@ void PMTraceConsumer::RuntimePresentStop(Runtime runtime, EVENT_HEADER const& hd
22042212

22052213
// If this present completed early and was deferred until the Present_Stop, then no more
22062214
// analysis is needed; we just clear the deferral.
2207-
if (present->DeferredReason & DeferredReason_WaitingForPresentStop) {
2215+
if (present->WaitingForPresentStop) {
2216+
present->WaitingForPresentStop = false;
22082217
mPresentByThreadId.erase(eventIter);
2209-
ClearDeferredReason(present, DeferredReason_WaitingForPresentStop);
2218+
UpdateReadyCount(present);
22102219
return;
22112220
}
22122221

22132222
// If the Present() call failed, no more analysis is needed.
22142223
if (FAILED(result)) {
22152224
// Check expected state (a new Present() that has only been started).
2216-
DebugAssert(present->TimeInPresent == 0);
2217-
DebugAssert(present->IsCompleted == false);
2218-
DebugAssert(present->IsLost == false);
2219-
DebugAssert(present->DeferredReason == 0);
2225+
DebugAssert(present->TimeInPresent == 0);
2226+
DebugAssert(present->IsCompleted == false);
2227+
DebugAssert(present->IsLost == false);
22202228
DebugAssert(present->DependentPresents.empty());
22212229

22222230
present->PresentFailed = true;
@@ -2403,7 +2411,7 @@ void PMTraceConsumer::ApplyFlipFrameType(
24032411
auto copy = std::make_shared<PresentEvent>();
24042412
*copy = *present;
24052413
copy->IsLost = false;
2406-
copy->DeferredReason &= ~DeferredReason_WaitingForFlipFrameType;
2414+
copy->WaitingForFlipFrameType = false;
24072415

24082416
VerboseTraceBeforeModifyingPresent(present.get());
24092417
present->IsLost = true;

PresentData/PresentMonTraceConsumer.hpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,6 @@ enum class FrameType {
125125
AMD_AFMF = 100,
126126
};
127127

128-
enum DeferredReason {
129-
DeferredReason_None = 0,
130-
DeferredReason_WaitingForPresentStop = 1 << 0,
131-
DeferredReason_WaitingForFlipFrameType = 1 << 1,
132-
};
133-
134128
struct InputEvent {
135129
uint64_t Time;
136130
InputDeviceType Type;
@@ -189,6 +183,9 @@ struct PresentEvent {
189183
// ThreadId, DriverThreadId -> mPresentByThreadId
190184
// PresentInDwmWaitingStruct -> mPresentsWaitingForDWM
191185

186+
// Additional transient tracking state
187+
std::deque<std::shared_ptr<PresentEvent>> DependentPresents;
188+
192189
// Properties deduced by watching events through present pipeline
193190
uint32_t DestWidth;
194191
uint32_t DestHeight;
@@ -217,10 +214,14 @@ struct PresentEvent {
217214
bool PresentInDwmWaitingStruct; // Whether this PresentEvent is currently stored in
218215
// PMTraceConsumer::mPresentsWaitingForDWM
219216

220-
// Additional transient tracking state
221-
std::deque<std::shared_ptr<PresentEvent>> DependentPresents;
217+
// If WaitingForPresentStop, then the present has been completed but it has not seen a
218+
// PresentStop event yet. The present is marked not-ready for dequeue until the PresentStop is
219+
// seen.
220+
bool WaitingForPresentStop;
222221

223-
uint32_t DeferredReason; // The reason(s) this present is being deferred (see DeferredReason enum).
222+
// If WaitingForFlipFrameType, the present is waiting for a FlipFrameType event (or, until an
223+
// MMIOFlipMultiPlaneOverlay3_Info event signals a higher present id).
224+
bool WaitingForFlipFrameType;
224225

225226
// Track the path the present took through the PresentMon analysis.
226227
#ifdef TRACK_PRESENT_PATHS
@@ -447,21 +448,21 @@ struct PMTraceConsumer
447448

448449

449450
void SetThreadPresent(uint32_t threadId, std::shared_ptr<PresentEvent> const& present);
450-
std::shared_ptr<PresentEvent> FindThreadPresent(uint32_t threadId);
451-
std::shared_ptr<PresentEvent> FindOrCreatePresent(EVENT_HEADER const& hdr);
451+
std::shared_ptr<PresentEvent> FindPresentByThreadId(uint32_t threadId);
452452
std::shared_ptr<PresentEvent> FindPresentBySubmitSequence(uint32_t submitSequence);
453+
std::shared_ptr<PresentEvent> FindOrCreatePresent(EVENT_HEADER const& hdr);
453454

454455
void TrackPresent(std::shared_ptr<PresentEvent> present, OrderedPresents* presentsByThisProcess);
455456
void StopTrackingPresent(std::shared_ptr<PresentEvent> const& present);
456457
void RemovePresentFromSubmitSequenceIdTracking(std::shared_ptr<PresentEvent> const& present);
457458

458459
void RuntimePresentStart(Runtime runtime, EVENT_HEADER const& hdr, uint64_t swapchainAddr, uint32_t dxgiPresentFlags, int32_t syncInterval);
459460
void RuntimePresentStop(Runtime runtime, EVENT_HEADER const& hdr, uint32_t result);
460-
void CompletePresent(std::shared_ptr<PresentEvent> const& p);
461+
void CompletePresent(std::shared_ptr<PresentEvent> const& present);
461462
void RemoveLostPresent(std::shared_ptr<PresentEvent> present);
462463

463464
void AddPresentToCompletedList(std::shared_ptr<PresentEvent> const& present);
464-
void ClearDeferredReason(std::shared_ptr<PresentEvent> const& present, uint32_t deferredReason);
465+
void UpdateReadyCount(std::shared_ptr<PresentEvent> const& present);
465466

466467
void DeferFlipFrameType(uint64_t vidPnLayerId, uint64_t presentId, uint64_t timestamp, FrameType frameType);
467468
void ApplyFlipFrameType(std::shared_ptr<PresentEvent> const& present, uint64_t timestamp, FrameType frameType);

0 commit comments

Comments
 (0)