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

Method CompleteWork

PresentData/GpuTrace.cpp:316–440  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

314}
315
316bool GpuTrace::CompleteWork(Context* context, uint32_t sequenceId, uint64_t timestamp)
317{
318 auto node = context->mNode;
319
320 // It's possible to miss DmaPacket events during realtime analysis, so try
321 // to handle it gracefully here.
322 //
323 // If we get a DmaPacket_Info event for a packet that we didn't get a
324 // DmaPacket_Start event for (or that we ignored because we didn't know the
325 // process yet) then sequenceId will be smaller than expected. If this
326 // happens, we ignore the DmaPacket_Info event which means that, if there
327 // was idle time before the missing DmaPacket_Start event,
328 // mAccumulatedPacketTime will be too large.
329 //
330 // measured: ---------------- ------- ---------------------
331 // [--- [--
332 // actual: [-----] [-----] [-----] [-----]-----]-------]
333 // ^ ^ x ^ ^ ^ x ^ ^
334 // s1 i1 s2 i2 s3 i3 s2 i1 s3
335 if (context->mPacketTrace == nullptr || node->mQueueCount == 0) {
336 return false;
337 }
338
339 auto runningSequenceId = node->mQueue[node->mQueueIndex].mSequenceId;
340 if (sequenceId < runningSequenceId) {
341 return false;
342 }
343
344 // If we get a DmaPacket_Start event with no corresponding DmaPacket_Info,
345 // then sequenceId will be larger than expected. If this happens, we search
346 // through the queue for a match and if no match was found then we ignore
347 // this event (we missed both the DmaPacket_Start and DmaPacket_Info for
348 // the packet). In this case, both the missing packet's execution time as
349 // well as any idle time afterwards will be associated with the previous
350 // packet.
351 //
352 // If a match is found, then we don't know when the pre-match packets ended
353 // (nor when the matched packet started). We treat this case as if the
354 // first packet with a missed DmaPacket_Info ran the whole time, and all
355 // other packets up to the match executed with zero time. Any idle time
356 // during this range is ignored, and the correct association of gpu work to
357 // process will not be correct (unless all these contexts come from the
358 // same process).
359 //
360 // measured: ------- ---------------- ---------------------
361 // [--- [--
362 // actual: [-----] [-----] [-----] [-----]-----]-------]
363 // ^ ^ ^ x ^ ^ ^ ^ x
364 // s1 i1 s2 i2 s3 i3 s2 i1 i2
365 if (sequenceId > runningSequenceId) {
366 for (uint32_t missingCount = 1; ; ++missingCount) {
367 if (missingCount == node->mQueueCount) {
368 return false;
369 }
370
371 uint32_t queueIndex = (node->mQueueIndex + missingCount) % (uint32_t) node->mQueue.size();
372 auto entry = &node->mQueue[queueIndex];
373 if (entry->mSequenceId == sequenceId) {

Callers

nothing calls this directly

Calls 3

sizeMethod · 0.45
beginMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected