| 43 | } |
| 44 | |
| 45 | int AddGpuMetric(pmapi::Session& pSession, unsigned int processId, double windowSize, double metricOffset) |
| 46 | { |
| 47 | try { |
| 48 | auto processTracker = pSession.TrackProcess(processId); |
| 49 | |
| 50 | std::vector<PM_QUERY_ELEMENT> elements; |
| 51 | elements.push_back(PM_QUERY_ELEMENT{ .metric = PM_METRIC_APPLICATION, .stat = PM_STAT_MID_POINT, .deviceId = 0, .arrayIndex = 0 }); |
| 52 | elements.push_back(PM_QUERY_ELEMENT{ .metric = PM_METRIC_PRESENTED_FPS, .stat = PM_STAT_AVG, .deviceId = 0, .arrayIndex = 0 }); |
| 53 | elements.push_back(PM_QUERY_ELEMENT{ .metric = PM_METRIC_PRESENTED_FPS, .stat = PM_STAT_PERCENTILE_90, .deviceId = 0, .arrayIndex = 0 }); |
| 54 | elements.push_back(PM_QUERY_ELEMENT{ .metric = PM_METRIC_PRESENTED_FPS, .stat = PM_STAT_PERCENTILE_95, .deviceId = 0, .arrayIndex = 0 }); |
| 55 | elements.push_back(PM_QUERY_ELEMENT{ .metric = PM_METRIC_PRESENTED_FPS, .stat = PM_STAT_PERCENTILE_90, .deviceId = 0, .arrayIndex = 0 }); |
| 56 | elements.push_back(PM_QUERY_ELEMENT{ .metric = PM_METRIC_PRESENTED_FPS, .stat = PM_STAT_MAX, .deviceId = 0, .arrayIndex = 0 }); |
| 57 | elements.push_back(PM_QUERY_ELEMENT{ .metric = PM_METRIC_PRESENTED_FPS, .stat = PM_STAT_MIN, .deviceId = 0, .arrayIndex = 0 }); |
| 58 | elements.push_back(PM_QUERY_ELEMENT{ .metric = PM_METRIC_CPU_FRAME_TIME, .stat = PM_STAT_AVG, .deviceId = 0, .arrayIndex = 0 }); |
| 59 | elements.push_back(PM_QUERY_ELEMENT{ .metric = PM_METRIC_CPU_WAIT, .stat = PM_STAT_AVG, .deviceId = 0, .arrayIndex = 0 }); |
| 60 | elements.push_back(PM_QUERY_ELEMENT{ .metric = PM_METRIC_GPU_TIME, .stat = PM_STAT_AVG, .deviceId = 0, .arrayIndex = 0 }); |
| 61 | elements.push_back(PM_QUERY_ELEMENT{ .metric = PM_METRIC_GPU_BUSY, .stat = PM_STAT_AVG, .deviceId = 0, .arrayIndex = 0 }); |
| 62 | elements.push_back(PM_QUERY_ELEMENT{ .metric = PM_METRIC_DISPLAY_LATENCY, .stat = PM_STAT_AVG, .deviceId = 0, .arrayIndex = 0 }); |
| 63 | elements.push_back(PM_QUERY_ELEMENT{ .metric = PM_METRIC_DISPLAYED_TIME, .stat = PM_STAT_AVG, .deviceId = 0, .arrayIndex = 0 }); |
| 64 | elements.push_back(PM_QUERY_ELEMENT{ .metric = PM_METRIC_CLICK_TO_PHOTON_LATENCY, .stat = PM_STAT_NON_ZERO_AVG, .deviceId = 0, .arrayIndex = 0 }); |
| 65 | |
| 66 | PM_METRIC gpuMetric; |
| 67 | uint32_t gpuDeviceId; |
| 68 | std::string gpuMetricName; |
| 69 | if (FindFirstAvailableGpuMetric(pSession, gpuMetric, gpuDeviceId, gpuMetricName)) { |
| 70 | elements.push_back(PM_QUERY_ELEMENT{ .metric = gpuMetric, .stat = PM_STAT_AVG, .deviceId = gpuDeviceId, .arrayIndex = 0 }); |
| 71 | } |
| 72 | |
| 73 | auto dynamicQuery = pSession.RegisterDynamicQuery(elements, windowSize, metricOffset); |
| 74 | auto blobs = dynamicQuery.MakeBlobContainer(1u); |
| 75 | |
| 76 | if (InitializeConsole() == false) { |
| 77 | std::cout << "\nFailed to initialize console.\n"; |
| 78 | return -1; |
| 79 | } |
| 80 | |
| 81 | while (!_kbhit()) { |
| 82 | dynamicQuery.Poll(processTracker, blobs); |
| 83 | |
| 84 | for (auto pBlob : blobs) { |
| 85 | ConsolePrintLn("Process Name = %s", *reinterpret_cast<const std::string*>(&pBlob[elements[0].dataOffset])); |
| 86 | ConsolePrintLn("Presented FPS Average = %f", *reinterpret_cast<const double*>(&pBlob[elements[1].dataOffset])); |
| 87 | ConsolePrintLn("Presented FPS 90% = %f", *reinterpret_cast<const double*>(&pBlob[elements[2].dataOffset])); |
| 88 | ConsolePrintLn("Presented FPS 95% = %f", *reinterpret_cast<const double*>(&pBlob[elements[3].dataOffset])); |
| 89 | ConsolePrintLn("Presented FPS 99% = %f", *reinterpret_cast<const double*>(&pBlob[elements[4].dataOffset])); |
| 90 | ConsolePrintLn("Presented FPS Max = %f", *reinterpret_cast<const double*>(&pBlob[elements[5].dataOffset])); |
| 91 | ConsolePrintLn("Presented FPS Min = %f", *reinterpret_cast<const double*>(&pBlob[elements[6].dataOffset])); |
| 92 | ConsolePrintLn("Frame Duration Average = %f", *reinterpret_cast<const double*>(&pBlob[elements[7].dataOffset])); |
| 93 | ConsolePrintLn("Frame Pacing Stall Average = %f", *reinterpret_cast<const double*>(&pBlob[elements[8].dataOffset])); |
| 94 | ConsolePrintLn("GPU Duration Average = %f", *reinterpret_cast<const double*>(&pBlob[elements[9].dataOffset])); |
| 95 | ConsolePrintLn("GPU Busy Time Average = %f", *reinterpret_cast<const double*>(&pBlob[elements[10].dataOffset])); |
| 96 | ConsolePrintLn("Display Latency Average = %f", *reinterpret_cast<const double*>(&pBlob[elements[11].dataOffset])); |
| 97 | ConsolePrintLn("Display Duration Average = %f", *reinterpret_cast<const double*>(&pBlob[elements[12].dataOffset])); |
| 98 | ConsolePrintLn("Input Latency Average = %f", *reinterpret_cast<const double*>(&pBlob[elements[13].dataOffset])); |
| 99 | if (gpuMetricName.length() != 0) |
| 100 | { |
| 101 | ConsolePrintLn( |
| 102 | std::format("{} Average = {}", |
no test coverage detected