VOID NvGpuUpdate( VOID ) { static ULONG runCount = 0; // MUST keep in sync with runCount in process provider if (runCount != 0) { NvGpuUpdateValues(); PhAddItemCircularBuffer_FLOAT(&GpuUtilizationHistory, GpuCurrentGpuUsage); PhAddItemCircularBuffer_ULONG(&GpuMemoryHistory, GpuCurrentMemUsage); PhAddItemCircularBuffer_FLOAT(&GpuBoardHistory, GpuCurrentCoreUsage); PhAddItemCircularBuffer_FLOAT(&GpuBusHistory, GpuCurrentBusUsage); } runCount++; }
static VOID GpuPropUpdateInfo( _In_ PET_GPU_CONTEXT Context ) { PET_PROCESS_BLOCK block = Context->Block; Context->CurrentGpuUsage = block->GpuNodeUsage; Context->CurrentMemUsage = (ULONG)(block->GpuDedicatedUsage / PAGE_SIZE); Context->CurrentMemSharedUsage = (ULONG)(block->GpuSharedUsage / PAGE_SIZE); PhAddItemCircularBuffer_FLOAT(&Context->GpuHistory, Context->CurrentGpuUsage); PhAddItemCircularBuffer_ULONG(&Context->MemoryHistory, Context->CurrentMemUsage); PhAddItemCircularBuffer_ULONG(&Context->MemorySharedHistory, Context->CurrentMemSharedUsage); }
VOID GetGfxUsages(VOID) { switch (GraphicsType) { case NvidiaGraphics: { NvStatus status = NVAPI_ERROR; NV_USAGES_INFO_V1 gpuInfo = { 0 }; NV_MEMORY_INFO_V2 memInfo = { 0 }; gpuInfo.Version = NV_USAGES_INFO_VER; memInfo.Version = NV_MEMORY_INFO_VER; status = NvAPI_GetUsages(physHandle, &gpuInfo); if (NV_SUCCESS(status)) { UINT gfxCoreLoad = gpuInfo.Values[2]; //UINT gfxCoreUsage = gpuInfo.Values[3]; UINT gfxMemControllerLoad = gpuInfo.Values[6]; //UINT gfxVideoEngineLoad = gpuInfo.Values[10]; CurrentGpuUsage = (FLOAT)gfxCoreLoad / 100; CurrentCoreUsage = (FLOAT)gfxMemControllerLoad / 100; PhAddItemCircularBuffer_FLOAT(&GpuHistory, CurrentGpuUsage); PhAddItemCircularBuffer_FLOAT(&CoreHistory, CurrentCoreUsage); } else { LogEvent(L"gfxinfo: (GetGfxUsages) NvAPI_GetUsages failed (%s)", status); } if (NV_SUCCESS((status = NvAPI_GetMemoryInfo(dispHandle, &memInfo)))) { UINT totalMemory = memInfo.Values[0]; //UINT sharedMemory = memInfo.Values[3]; UINT freeMemory = memInfo.Values[4]; ULONG usedMemory = max(totalMemory - freeMemory, 0); MaxMemUsage = totalMemory; CurrentMemUsage = (FLOAT)usedMemory; PhAddItemCircularBuffer_ULONG(&MemHistory, usedMemory); } else { LogEvent(L"gfxinfo: (GetGfxUsages) NvAPI_GetMemoryInfo failed (%s)", status); } if (!NV_SUCCESS((status = NvAPI_GetPerfDecreaseInfo(physHandle, &perfStatus)))) { LogEvent(L"gfxinfo: (GetGfxUsages) NvAPI_GetMemoryInfo failed (%s)", status); } } break; case AtiGraphics: { int status = 0; //ADLPMActivity activity = { 0 }; //status = Adl_GetCurrentActivity(0, &activity); if (status == ADL_OK) { } else { //LogEvent(L"gfxinfo: (GetGfxUsages) Adl_GetCurrentActivity failed (%d)", status); } } break; } }
static VOID NTAPI ProcessesUpdatedCallback( _In_opt_ PVOID Parameter, _In_opt_ PVOID Context ) { static ULONG runCount = 0; // MUST keep in sync with runCount in process provider DOUBLE elapsedTime; // total GPU node elapsed time in micro-seconds ULONG i; PLIST_ENTRY listEntry; FLOAT maxNodeValue = 0; PET_PROCESS_BLOCK maxNodeBlock = NULL; // Update global statistics. EtpUpdateSegmentInformation(NULL); EtpUpdateNodeInformation(NULL); elapsedTime = (DOUBLE)EtClockTotalRunningTimeDelta.Delta * 10000000 / EtClockTotalRunningTimeFrequency.QuadPart; if (elapsedTime != 0) EtGpuNodeUsage = (FLOAT)(EtGpuTotalRunningTimeDelta.Delta / (elapsedTime * EtGpuNodeBitMapBitsSet)); else EtGpuNodeUsage = 0; if (EtGpuNodeUsage > 1) EtGpuNodeUsage = 1; // Do the update of the node bitmap if needed. if (EtGpuNewNodeBitMapBuffer) { PULONG newBuffer; newBuffer = _InterlockedExchangePointer(&EtGpuNewNodeBitMapBuffer, NULL); if (newBuffer) { PhFree(EtGpuNodeBitMap.Buffer); EtGpuNodeBitMap.Buffer = newBuffer; EtGpuNodeBitMapBuffer = newBuffer; EtGpuNodeBitMapBitsSet = RtlNumberOfSetBits(&EtGpuNodeBitMap); EtSaveGpuMonitorSettings(); } } // Update per-process statistics. // Note: no lock is needed because we only ever modify the list on this same thread. //@@HTK listEntry = EtProcessBlockListHead.Flink; while (listEntry != &EtProcessBlockListHead) { PET_PROCESS_BLOCK block; block = CONTAINING_RECORD(listEntry, ET_PROCESS_BLOCK, ListEntry); EtpUpdateSegmentInformation(block); EtpUpdateNodeInformation(block); if (elapsedTime != 0) { block->GpuNodeUsage = (FLOAT)(block->GpuRunningTimeDelta.Delta / (elapsedTime * EtGpuNodeBitMapBitsSet)); if (block->GpuNodeUsage > 1) block->GpuNodeUsage = 1; } if (maxNodeValue < block->GpuNodeUsage) { maxNodeValue = block->GpuNodeUsage; maxNodeBlock = block; } listEntry = listEntry->Flink; } // Update history buffers. if (runCount != 0) { PhAddItemCircularBuffer_FLOAT(&EtGpuNodeHistory, EtGpuNodeUsage); PhAddItemCircularBuffer_ULONG(&EtGpuDedicatedHistory, (ULONG)(EtGpuDedicatedUsage / PAGE_SIZE)); PhAddItemCircularBuffer_ULONG(&EtGpuSharedHistory, (ULONG)(EtGpuSharedUsage / PAGE_SIZE)); for (i = 0; i < EtGpuTotalNodeCount; i++) { FLOAT usage; usage = (FLOAT)(EtGpuNodesTotalRunningTimeDelta[i].Delta / elapsedTime); if (usage > 1) usage = 1; PhAddItemCircularBuffer_FLOAT(&EtGpuNodesHistory[i], usage); } if (maxNodeBlock) { PhAddItemCircularBuffer_ULONG(&EtMaxGpuNodeHistory, HandleToUlong(maxNodeBlock->ProcessItem->ProcessId)); PhAddItemCircularBuffer_FLOAT(&EtMaxGpuNodeUsageHistory, maxNodeBlock->GpuNodeUsage); PhReferenceProcessRecordForStatistics(maxNodeBlock->ProcessItem->Record); } else { PhAddItemCircularBuffer_ULONG(&EtMaxGpuNodeHistory, 0); PhAddItemCircularBuffer_FLOAT(&EtMaxGpuNodeUsageHistory, 0); } } runCount++; }
static BOOLEAN NvGpuSectionCallback( _In_ PPH_SYSINFO_SECTION Section, _In_ PH_SYSINFO_SECTION_MESSAGE Message, _In_opt_ PVOID Parameter1, _In_opt_ PVOID Parameter2 ) { PPH_NVGPU_SYSINFO_CONTEXT context = (PPH_NVGPU_SYSINFO_CONTEXT)Section->Context; switch (Message) { case SysInfoCreate: { ULONG sampleCount; sampleCount = PhGetIntegerSetting(L"SampleCount"); PhInitializeCircularBuffer_FLOAT(&context->GpuUtilizationHistory, sampleCount); PhInitializeCircularBuffer_ULONG(&context->GpuMemoryHistory, sampleCount); PhInitializeCircularBuffer_FLOAT(&context->GpuBoardHistory, sampleCount); PhInitializeCircularBuffer_FLOAT(&context->GpuBusHistory, sampleCount); } return TRUE; case SysInfoDestroy: { if (context->GpuName) PhDereferenceObject(context->GpuName); PhDeleteCircularBuffer_FLOAT(&context->GpuUtilizationHistory); PhDeleteCircularBuffer_ULONG(&context->GpuMemoryHistory); PhDeleteCircularBuffer_FLOAT(&context->GpuBoardHistory); PhDeleteCircularBuffer_FLOAT(&context->GpuBusHistory); PhFree(context); } return TRUE; case SysInfoTick: { NvGpuUpdateValues(); PhAddItemCircularBuffer_FLOAT(&context->GpuUtilizationHistory, GpuCurrentGpuUsage); PhAddItemCircularBuffer_ULONG(&context->GpuMemoryHistory, GpuCurrentMemUsage); PhAddItemCircularBuffer_FLOAT(&context->GpuBoardHistory, GpuCurrentCoreUsage); PhAddItemCircularBuffer_FLOAT(&context->GpuBusHistory, GpuCurrentBusUsage); } return TRUE; case SysInfoCreateDialog: { PPH_SYSINFO_CREATE_DIALOG createDialog = (PPH_SYSINFO_CREATE_DIALOG)Parameter1; createDialog->Instance = PluginInstance->DllBase; createDialog->Template = MAKEINTRESOURCE(IDD_GPU_DIALOG); createDialog->DialogProc = NvGpuDialogProc; createDialog->Parameter = context; } return TRUE; case SysInfoGraphGetDrawInfo: { PPH_GRAPH_DRAW_INFO drawInfo = (PPH_GRAPH_DRAW_INFO)Parameter1; drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y; Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0); PhGetDrawInfoGraphBuffers(&Section->GraphState.Buffers, drawInfo, context->GpuUtilizationHistory.Count); if (!Section->GraphState.Valid) { PhCopyCircularBuffer_FLOAT(&context->GpuUtilizationHistory, Section->GraphState.Data1, drawInfo->LineDataCount); Section->GraphState.Valid = TRUE; } } return TRUE; case SysInfoGraphGetTooltipText: { FLOAT gpuUsageValue; PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT getTooltipText = (PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT)Parameter1; gpuUsageValue = PhGetItemCircularBuffer_FLOAT(&context->GpuUtilizationHistory, getTooltipText->Index); PhMoveReference(&Section->GraphState.TooltipText, PhFormatString( L"%.0f%%\n%s", gpuUsageValue * 100, ((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer )); getTooltipText->Text = Section->GraphState.TooltipText->sr; } return TRUE; case SysInfoGraphDrawPanel: { PPH_SYSINFO_DRAW_PANEL drawPanel = (PPH_SYSINFO_DRAW_PANEL)Parameter1; drawPanel->Title = PhCreateString(Section->Name.Buffer); drawPanel->SubTitle = PhFormatString( L"%.0f%%", GpuCurrentGpuUsage * 100 ); } return TRUE; } return FALSE; }