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

Method EnqueueWork

PresentData/GpuTrace.cpp:260–314  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

258}
259
260void GpuTrace::EnqueueWork(Context* context, uint32_t sequenceId, uint64_t timestamp, bool isWaitPacket)
261{
262 auto packetTrace = context->mPacketTrace;
263 auto node = context->mNode;
264
265 // A very rare (never observed) race exists where packetTrace can still be
266 // nullptr here. The context must have been created and this packet must
267 // have been submitted to the queue before the capture started.
268 //
269 // In this case, we have to ignore the DMA packet otherwise the node and
270 // process tracking will become out of sync.
271 if (packetTrace == nullptr) {
272 return;
273 }
274
275 // If the queue is too small, enlarge it by 16 entries at a time. Typically, this will only be
276 // needed for the first packet observed on this node, which will result in sizing the queue from
277 // 0 to 16. However, there are other cases where the queue entries can grow beyond that. e.g.,
278 // this seems to always happen when an application closes.
279 uint32_t queueSize = (uint32_t) node->mQueue.size();
280 if (node->mQueueCount == queueSize) {
281 Node::EnqueuedPacket empty{};
282 node->mQueue.insert(node->mQueue.begin() + node->mQueueIndex, 16, empty);
283 queueSize += 16;
284 node->mQueueIndex = (node->mQueueIndex + 16) % queueSize;
285 }
286
287 // Enqueue the packet.
288 //
289 // Wait packets aren't counted as GPU work, but we still need to enqueue
290 // them so they block future work. We encode wait packets by setting their
291 // packetTrace to null. This saves some memory as we don't need the
292 // packetTrace pointer for wait packets.
293 if (isWaitPacket) {
294 packetTrace = nullptr;
295 }
296
297 auto queueIndex = (node->mQueueIndex + node->mQueueCount) % queueSize;
298 auto entry = &node->mQueue[queueIndex];
299 entry->mPacketTrace = packetTrace;
300 entry->mSequenceId = sequenceId;
301 entry->mCompleted = false;
302 node->mQueueCount += 1;
303
304 // If the queue was empty, the packet starts running right away, otherwise
305 // it is just enqueued and will start running after all previous packets
306 // complete.
307 if (packetTrace != nullptr && node->mQueueCount == 1) {
308 StartPacket(packetTrace, timestamp);
309 }
310
311 if (IsVerboseTraceEnabled()) {
312 PrintRunningContexts();
313 }
314}
315
316bool GpuTrace::CompleteWork(Context* context, uint32_t sequenceId, uint64_t timestamp)
317{

Callers

nothing calls this directly

Calls 3

IsVerboseTraceEnabledFunction · 0.85
sizeMethod · 0.45
beginMethod · 0.45

Tested by

no test coverage detected