VOID NvGpuInitialize( VOID ) { ULONG sampleCount; sampleCount = PhGetIntegerSetting(L"SampleCount"); PhInitializeCircularBuffer_FLOAT(&GpuUtilizationHistory, sampleCount); PhInitializeCircularBuffer_ULONG(&GpuMemoryHistory, sampleCount); PhInitializeCircularBuffer_FLOAT(&GpuBoardHistory, sampleCount); PhInitializeCircularBuffer_FLOAT(&GpuBusHistory, sampleCount); }
INT_PTR CALLBACK EtpGpuPageDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { LPPROPSHEETPAGE propSheetPage; PPH_PROCESS_PROPPAGECONTEXT propPageContext; PPH_PROCESS_ITEM processItem; PET_GPU_CONTEXT context; if (PhPropPageDlgProcHeader(hwndDlg, uMsg, lParam, &propSheetPage, &propPageContext, &processItem)) { context = propPageContext->Context; } else { return FALSE; } switch (uMsg) { case WM_INITDIALOG: { ULONG sampleCount; sampleCount = PhGetIntegerSetting(L"SampleCount"); context = PhAllocate(sizeof(ET_GPU_CONTEXT)); memset(context, 0, sizeof(ET_GPU_CONTEXT)); context->WindowHandle = hwndDlg; context->Block = EtGetProcessBlock(processItem); context->Enabled = TRUE; context->GpuGroupBox = GetDlgItem(hwndDlg, IDC_GROUPGPU); context->MemGroupBox = GetDlgItem(hwndDlg, IDC_GROUPMEM); context->SharedGroupBox = GetDlgItem(hwndDlg, IDC_GROUPSHARED); propPageContext->Context = context; PhInitializeLayoutManager(&context->LayoutManager, hwndDlg); PhInitializeGraphState(&context->GpuGraphState); PhInitializeGraphState(&context->MemoryGraphState); PhInitializeGraphState(&context->MemorySharedGraphState); PhInitializeCircularBuffer_FLOAT(&context->GpuHistory, sampleCount); PhInitializeCircularBuffer_ULONG(&context->MemoryHistory, sampleCount); PhInitializeCircularBuffer_ULONG(&context->MemorySharedHistory, sampleCount); GpuPropCreateGraphs(context); GpuPropCreatePanel(context); GpuPropUpdateInfo(context); GpuPropUpdatePanel(context); PhRegisterCallback( &PhProcessesUpdatedEvent, ProcessesUpdatedHandler, context, &context->ProcessesUpdatedRegistration ); } break; case WM_DESTROY: { PhDeleteLayoutManager(&context->LayoutManager); PhDeleteGraphState(&context->GpuGraphState); PhDeleteGraphState(&context->MemoryGraphState); PhDeleteGraphState(&context->MemorySharedGraphState); PhDeleteCircularBuffer_FLOAT(&context->GpuHistory); PhDeleteCircularBuffer_ULONG(&context->MemoryHistory); PhDeleteCircularBuffer_ULONG(&context->MemorySharedHistory); if (context->GpuGraphHandle) DestroyWindow(context->GpuGraphHandle); if (context->MemGraphHandle) DestroyWindow(context->MemGraphHandle); if (context->SharedGraphHandle) DestroyWindow(context->SharedGraphHandle); if (context->PanelHandle) DestroyWindow(context->PanelHandle); PhUnregisterCallback(&PhProcessesUpdatedEvent, &context->ProcessesUpdatedRegistration); PhFree(context); PhPropPageDlgProcDestroy(hwndDlg); } break; case WM_SHOWWINDOW: { if (PhBeginPropPageLayout(hwndDlg, propPageContext)) PhEndPropPageLayout(hwndDlg, propPageContext); } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_SETACTIVE: context->Enabled = TRUE; break; case PSN_KILLACTIVE: context->Enabled = FALSE; break; case GCN_GETDRAWINFO: { PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)header; PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo; if (header->hwndFrom == context->GpuGraphHandle) { if (PhGetIntegerSetting(L"GraphShowText")) { HDC hdc; PhMoveReference(&context->GpuGraphState.Text, PhFormatString( L"%.2f%%", context->CurrentGpuUsage * 100 )); hdc = Graph_GetBufferedContext(context->GpuGraphHandle); SelectObject(hdc, PhApplicationFont); PhSetGraphText(hdc, drawInfo, &context->GpuGraphState.Text->sr, &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT); } else { drawInfo->Text.Buffer = NULL; } drawInfo->Flags = PH_GRAPH_USE_GRID; PhSiSetColorsGraphDrawInfo(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0); PhGraphStateGetDrawInfo(&context->GpuGraphState, getDrawInfo, context->GpuHistory.Count); if (!context->GpuGraphState.Valid) { PhCopyCircularBuffer_FLOAT(&context->GpuHistory, context->GpuGraphState.Data1, drawInfo->LineDataCount); context->GpuGraphState.Valid = TRUE; } } else if (header->hwndFrom == context->MemGraphHandle) { if (PhGetIntegerSetting(L"GraphShowText")) { HDC hdc; PhMoveReference(&context->MemoryGraphState.Text, PhFormatString( L"%s", PhaFormatSize(UInt32x32To64(context->CurrentMemUsage, PAGE_SIZE), -1)->Buffer )); hdc = Graph_GetBufferedContext(context->MemGraphHandle); SelectObject(hdc, PhApplicationFont); PhSetGraphText( hdc, drawInfo, &context->MemoryGraphState.Text->sr, &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT ); } else { drawInfo->Text.Buffer = NULL; } drawInfo->Flags = PH_GRAPH_USE_GRID; PhSiSetColorsGraphDrawInfo(drawInfo, PhGetIntegerSetting(L"ColorPhysical"), 0); PhGraphStateGetDrawInfo( &context->MemoryGraphState, getDrawInfo, context->MemoryHistory.Count ); if (!context->MemoryGraphState.Valid) { ULONG i = 0; for (i = 0; i < drawInfo->LineDataCount; i++) { context->MemoryGraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG(&context->MemoryHistory, i); } if (EtGpuDedicatedLimit != 0) { PhDivideSinglesBySingle( context->MemoryGraphState.Data1, (FLOAT)EtGpuDedicatedLimit / PAGE_SIZE, drawInfo->LineDataCount ); } context->MemoryGraphState.Valid = TRUE; } } else if (header->hwndFrom == context->SharedGraphHandle) { if (PhGetIntegerSetting(L"GraphShowText")) { HDC hdc; PhMoveReference(&context->MemorySharedGraphState.Text, PhFormatString( L"%s", PhaFormatSize(UInt32x32To64(context->CurrentMemSharedUsage, PAGE_SIZE), -1)->Buffer )); hdc = Graph_GetBufferedContext(context->SharedGraphHandle); SelectObject(hdc, PhApplicationFont); PhSetGraphText(hdc, drawInfo, &context->MemorySharedGraphState.Text->sr, &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT); } else { drawInfo->Text.Buffer = NULL; } drawInfo->Flags = PH_GRAPH_USE_GRID; PhSiSetColorsGraphDrawInfo(drawInfo, PhGetIntegerSetting(L"ColorPrivate"), 0); PhGraphStateGetDrawInfo( &context->MemorySharedGraphState, getDrawInfo, context->MemorySharedHistory.Count ); if (!context->MemorySharedGraphState.Valid) { ULONG i = 0; for (i = 0; i < drawInfo->LineDataCount; i++) { context->MemorySharedGraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG(&context->MemorySharedHistory, i); } if (EtGpuSharedLimit != 0) { PhDivideSinglesBySingle( context->MemorySharedGraphState.Data1, (FLOAT)EtGpuSharedLimit / PAGE_SIZE, drawInfo->LineDataCount ); } context->MemorySharedGraphState.Valid = TRUE; } } } break; case GCN_GETTOOLTIPTEXT: { PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)lParam; if (getTooltipText->Index < getTooltipText->TotalCount) { if (header->hwndFrom == context->GpuGraphHandle) { if (context->GpuGraphState.TooltipIndex != getTooltipText->Index) { FLOAT gpuUsage = PhGetItemCircularBuffer_FLOAT( &context->GpuHistory, getTooltipText->Index ); PhMoveReference(&context->GpuGraphState.TooltipText, PhFormatString( L"%.2f%%", gpuUsage * 100 )); } getTooltipText->Text = context->GpuGraphState.TooltipText->sr; } else if (header->hwndFrom == context->MemGraphHandle) { if (context->MemoryGraphState.TooltipIndex != getTooltipText->Index) { ULONG gpuMemory = PhGetItemCircularBuffer_ULONG( &context->MemoryHistory, getTooltipText->Index ); PhMoveReference(&context->MemoryGraphState.TooltipText, PhFormatSize(UInt32x32To64(gpuMemory, PAGE_SIZE), -1) ); } getTooltipText->Text = context->MemoryGraphState.TooltipText->sr; } else if (header->hwndFrom == context->SharedGraphHandle) { if (context->MemorySharedGraphState.TooltipIndex != getTooltipText->Index) { ULONG gpuSharedMemory = PhGetItemCircularBuffer_ULONG( &context->MemorySharedHistory, getTooltipText->Index ); PhMoveReference(&context->MemorySharedGraphState.TooltipText, PhFormatSize(UInt32x32To64(gpuSharedMemory, PAGE_SIZE), -1) ); } getTooltipText->Text = context->MemorySharedGraphState.TooltipText->sr; } } } break; } } break; case MSG_UPDATE: { GpuPropUpdateInfo(context); GpuPropUpdateGraphs(context); GpuPropUpdatePanel(context); } break; case WM_SIZE: { GpuPropLayoutGraphs(context); } break; } return FALSE; }
VOID NvApiInitialize(VOID) { ULONG sampleCount; if (!PhGetIntegerSetting(SETTING_NAME_ENABLE_GPU)) return; sampleCount = PhGetIntegerSetting(L"SampleCount"); PhInitializeCircularBuffer_FLOAT(&GpuUtilizationHistory, sampleCount); PhInitializeCircularBuffer_ULONG(&GpuMemoryHistory, sampleCount); PhInitializeCircularBuffer_FLOAT(&GpuBoardHistory, sampleCount); PhInitializeCircularBuffer_FLOAT(&GpuBusHistory, sampleCount); NvGpuPhysicalHandleList = PhCreateList(1); NvGpuDisplayHandleList = PhCreateList(1); #ifdef _M_IX86 if (!(NvApiLibrary = LoadLibrary(L"nvapi.dll"))) return; #else if (!(NvApiLibrary = LoadLibrary(L"nvapi64.dll"))) return; #endif // Retrieve the NvAPI_QueryInterface function address if (!(NvAPI_QueryInterface = PhGetProcedureAddress(NvApiLibrary, "nvapi_QueryInterface", 0))) return; // Initialization functions if (!(NvAPI_Initialize = NvAPI_QueryInterface(0x150E828UL))) return; if (!(NvAPI_Unload = NvAPI_QueryInterface(0xD22BDD7EUL))) return; // Error functions NvAPI_GetErrorMessage = NvAPI_QueryInterface(0x6C2D048CUL); // Handle functions NvAPI_EnumPhysicalGPUs = NvAPI_QueryInterface(0xE5AC921FUL); NvAPI_EnumNvidiaDisplayHandle = NvAPI_QueryInterface(0x9ABDD40DUL); // Information functions NvAPI_SYS_GetDriverAndBranchVersion = NvAPI_QueryInterface(0x2926AAADUL); NvAPI_GPU_GetFullName = NvAPI_QueryInterface(0xCEEE8E9FUL); // Query functions NvAPI_GPU_GetMemoryInfo = NvAPI_QueryInterface(0x774AA982UL); NvAPI_GPU_GetThermalSettings = NvAPI_QueryInterface(0xE3640A56UL); NvAPI_GPU_GetCoolerSettings = NvAPI_QueryInterface(0xDA141340UL); NvAPI_GPU_GetPerfDecreaseInfo = NvAPI_QueryInterface(0x7F7F4600UL); NvAPI_GPU_GetTachReading = NvAPI_QueryInterface(0x5F608315UL); NvAPI_GPU_GetAllClockFrequencies = NvAPI_QueryInterface(0xDCB616C3UL); // Undocumented functions below NvAPI_GPU_GetUsages = NvAPI_QueryInterface(0x189A1FDFUL); NvAPI_GPU_GetAllClocks = NvAPI_QueryInterface(0x1BD69F49UL); NvAPI_GPU_GetVoltageDomainsStatus = NvAPI_QueryInterface(0xC16C7E2CUL); NvAPI_GPU_GetPerfClocks = NvAPI_QueryInterface(0x1EA54A3B); NvAPI_GPU_GetVoltages = NvAPI_QueryInterface(0x7D656244); NvAPI_GPU_QueryActiveApps = NvAPI_QueryInterface(0x65B1C5F5); NvAPI_GPU_GetShaderPipeCount = NvAPI_QueryInterface(0x63E2F56F); NvAPI_GPU_GetShaderSubPipeCount = NvAPI_QueryInterface(0x0BE17923); NvAPI_GPU_GetRamBusWidth = NvAPI_QueryInterface(0x7975C581); NvAPI_GPU_GetRamBankCount = NvAPI_QueryInterface(0x17073A3CUL); NvAPI_GPU_GetRamType = NvAPI_QueryInterface(0x57F7CAACUL); NvAPI_GPU_GetRamMaker = NvAPI_QueryInterface(0x42AEA16AUL); NvAPI_GPU_GetFoundry = NvAPI_QueryInterface(0x5D857A00UL); //NvAPI_GetDisplayDriverMemoryInfo = NvAPI_QueryInterface(0x774AA982); //NvAPI_GetPhysicalGPUsFromDisplay = NvAPI_QueryInterface(0x34EF9506); NvAPI_GetDisplayDriverVersion = NvAPI_QueryInterface(0xF951A4D1UL); NvAPI_GetDisplayDriverRegistryPath = NvAPI_QueryInterface(0x0E24CEEEUL); //NvAPI_RestartDisplayDriver = NvAPI_QueryInterface(0xB4B26B65UL); //NvAPI_GPU_GetBoardInfo = NvAPI_QueryInterface(0x22D54523); //NvAPI_GPU_GetBusType = NvAPI_QueryInterface(0x1BB18724); //NvAPI_GPU_GetIRQ = NvAPI_QueryInterface(0xE4715417); NvAPI_GPU_GetVbiosVersionString = NvAPI_QueryInterface(0xA561FD7DUL); NvAPI_GPU_GetShortName = NvAPI_QueryInterface(0xD988F0F3UL); NvAPI_GPU_GetArchInfo = NvAPI_QueryInterface(0xD8265D24UL); NvAPI_GPU_GetPCIIdentifiers = NvAPI_QueryInterface(0x2DDFB66EUL); NvAPI_GPU_GetPartitionCount = NvAPI_QueryInterface(0x86F05D7AUL); NvAPI_GPU_GetGpuCoreCount = NvAPI_QueryInterface(0xC7026A87UL); NvAPI_GPU_GetPCIEInfo = NvAPI_QueryInterface(0xE3795199UL); NvAPI_GPU_GetFBWidthAndLocation = NvAPI_QueryInterface(0x11104158UL); NvAPI_GPU_ClientPowerTopologyGetStatus = NvAPI_QueryInterface(0x0EDCF624EUL); NvAPI_GetDisplayDriverBuildTitle = NvAPI_QueryInterface(0x7562E947); NvAPI_GetDisplayDriverCompileType = NvAPI_QueryInterface(0x988AEA78); NvAPI_GetDisplayDriverSecurityLevel = NvAPI_QueryInterface(0x9D772BBA); NvAPI_GPU_GetVPECount = NvAPI_QueryInterface(0xD8CBF37B); NvAPI_GPU_GetTargetID = NvAPI_QueryInterface(0x35B5FD2F); //NvAPI_GPU_GetExtendedMinorRevision = NvAPI_QueryInterface(0x025F17421); //NvAPI_GPU_GetSerialNumber = NvAPI_QueryInterface(0x14B83A5F); if (NvAPI_Initialize() == NVAPI_OK) { NvGpuEnumPhysicalHandles(); NvGpuEnumDisplayHandles(); NvApiInitialized = TRUE; } }
INT_PTR CALLBACK MainWndProc( __in HWND hwndDlg, __in UINT uMsg, __in WPARAM wParam, __in LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { // Add the Graphics card name to the Window Title. //PPH_STRING gpuname = GetDriverName(); //PPH_STRING title = PhFormatString(L"Graphics Information (%s)", gpuname->Buffer); //SetWindowText(hwndDlg, title->Buffer); //PhDereferenceObject(gpuname); //PhDereferenceObject(title); // We have already set the group boxes to have WS_EX_TRANSPARENT to fix // the drawing issue that arises when using WS_CLIPCHILDREN. However // in removing the flicker from the graphs the group boxes will now flicker. // It's a good tradeoff since no one stares at the group boxes. PhSetWindowStyle(hwndDlg, WS_CLIPCHILDREN, WS_CLIPCHILDREN); PhCenterWindow(hwndDlg, PhMainWndHandle); PhInitializeLayoutManager(&WindowLayoutManager, hwndDlg); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_ALWAYSONTOP), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhLoadWindowPlacementFromSetting(SETTING_NAME_GFX_WINDOW_POSITION, SETTING_NAME_GFX_WINDOW_SIZE, hwndDlg); PhInitializeGraphState(&GpuGraphState); PhInitializeGraphState(&CoreGraphState); PhInitializeGraphState(&MemGraphState); // TEMP if (GpuHistory.Count == 0) { PhInitializeCircularBuffer_FLOAT(&GpuHistory, PhGetIntegerSetting(L"SampleCount")); PhInitializeCircularBuffer_FLOAT(&CoreHistory, PhGetIntegerSetting(L"SampleCount")); PhInitializeCircularBuffer_ULONG(&MemHistory, PhGetIntegerSetting(L"SampleCount")); } GpuGraphHandle = CreateWindow( PH_GRAPH_CLASSNAME, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, 0, 0, 3, 3, hwndDlg, (HMENU)110, PluginInstance->DllBase, NULL ); Graph_SetTooltip(GpuGraphHandle, TRUE); BringWindowToTop(GpuGraphHandle); CoreGraphHandle = CreateWindow( PH_GRAPH_CLASSNAME, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, 0, 0, 3, 3, hwndDlg, (HMENU)111, PluginInstance->DllBase, NULL ); Graph_SetTooltip(CoreGraphHandle, TRUE); BringWindowToTop(CoreGraphHandle); MemGraphHandle = CreateWindow( PH_GRAPH_CLASSNAME, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, 0, 0, 3, 3, hwndDlg, (HMENU)109, PluginInstance->DllBase, NULL ); Graph_SetTooltip(MemGraphHandle, TRUE); BringWindowToTop(MemGraphHandle); PhRegisterCallback( PhGetGeneralCallback(GeneralCallbackProcessesUpdated), GfxUpdateHandler, NULL, &ProcessesUpdatedRegistration ); } break; case WM_DESTROY: { // Unregister our callbacks. PhUnregisterCallback(&PhProcessesUpdatedEvent, &ProcessesUpdatedRegistration); // Save our settings. PhSetIntegerSetting(SETTING_NAME_GFX_ALWAYS_ON_TOP, AlwaysOnTop); PhSaveWindowPlacementToSetting(SETTING_NAME_GFX_WINDOW_POSITION, SETTING_NAME_GFX_WINDOW_SIZE, hwndDlg); // Reset our Window Management. PhDeleteLayoutManager(&WindowLayoutManager); // TEMP commented out. // Clear our buffers. //PhDeleteCircularBuffer_FLOAT(&GpuHistory); //PhDeleteCircularBuffer_ULONG(&MemHistory); // Clear our state. PhDeleteGraphState(&GpuGraphState); PhDeleteGraphState(&MemGraphState); // Quit. PostQuitMessage(0); } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case GCN_GETDRAWINFO: { PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)header; PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo; if (header->hwndFrom == GpuGraphHandle) { if (PhGetIntegerSetting(L"GraphShowText")) { HDC hdc; PhSwapReference2( &GpuGraphState.TooltipText, PhFormatString( L"%.0f%%", CurrentGpuUsage * 100 )); hdc = Graph_GetBufferedContext(GpuGraphHandle); SelectObject(hdc, PhApplicationFont); PhSetGraphText(hdc, drawInfo, &GpuGraphState.TooltipText->sr, &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT); } else { drawInfo->Text.Buffer = NULL; } drawInfo->Flags = PH_GRAPH_USE_GRID; drawInfo->LineColor1 = PhGetIntegerSetting(L"ColorCpuKernel"); //drawInfo->LineColor2 = PhGetIntegerSetting(L"ColorCpuUser"); drawInfo->LineBackColor1 = PhHalveColorBrightness(drawInfo->LineColor1); //drawInfo->LineBackColor2 = PhHalveColorBrightness(drawInfo->LineColor2); PhGraphStateGetDrawInfo( &GpuGraphState, getDrawInfo, GpuHistory.Count ); if (!GpuGraphState.Valid) { PhCopyCircularBuffer_FLOAT( &GpuHistory, getDrawInfo->DrawInfo->LineData1, getDrawInfo->DrawInfo->LineDataCount ); GpuGraphState.Valid = TRUE; } } else if (header->hwndFrom == MemGraphHandle) { if (PhGetIntegerSetting(L"GraphShowText")) { HDC hdc; PhSwapReference2(&MemGraphState.TooltipText, PhFormatString( L"%s / %s (%.2f%%)", PhaFormatSize(UInt32x32To64(CurrentMemUsage, 1024), -1)->Buffer, PhaFormatSize(UInt32x32To64(MaxMemUsage, 1024), -1)->Buffer, (FLOAT)CurrentMemUsage / MaxMemUsage * 100 )); hdc = Graph_GetBufferedContext(MemGraphHandle); SelectObject(hdc, PhApplicationFont); PhSetGraphText( hdc, drawInfo, &MemGraphState.TooltipText->sr, &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT ); } else { drawInfo->Text.Buffer = NULL; } drawInfo->Flags = PH_GRAPH_USE_GRID; drawInfo->LineColor1 = PhGetIntegerSetting(L"ColorCpuKernel"); //drawInfo->LineColor2 = PhGetIntegerSetting(L"ColorCpuUser"); drawInfo->LineBackColor1 = PhHalveColorBrightness(drawInfo->LineColor1); //drawInfo->LineBackColor2 = PhHalveColorBrightness(drawInfo->LineColor2); PhGraphStateGetDrawInfo( &MemGraphState, getDrawInfo, MemHistory.Count ); if (!MemGraphState.Valid) { ULONG i = 0; for (i = 0; i < drawInfo->LineDataCount; i++) { MemGraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG(&MemHistory, i); } // Scale the data. PhxfDivideSingle2U( MemGraphState.Data1, (FLOAT)MaxMemUsage, drawInfo->LineDataCount ); MemGraphState.Valid = TRUE; } } else if (header->hwndFrom == CoreGraphHandle) { if (PhGetIntegerSetting(L"GraphShowText")) { HDC hdc; PhSwapReference2( &CoreGraphState.TooltipText, PhFormatString( L"%.0f%%", CurrentCoreUsage * 100 )); hdc = Graph_GetBufferedContext(CoreGraphHandle); SelectObject(hdc, PhApplicationFont); PhSetGraphText(hdc, drawInfo, &CoreGraphState.TooltipText->sr, &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT); } else { drawInfo->Text.Buffer = NULL; } drawInfo->Flags = PH_GRAPH_USE_GRID; drawInfo->LineColor1 = PhGetIntegerSetting(L"ColorCpuKernel"); //drawInfo->LineColor2 = PhGetIntegerSetting(L"ColorCpuUser"); drawInfo->LineBackColor1 = PhHalveColorBrightness(drawInfo->LineColor1); //drawInfo->LineBackColor2 = PhHalveColorBrightness(drawInfo->LineColor2); PhGraphStateGetDrawInfo( &CoreGraphState, getDrawInfo, CoreHistory.Count ); if (!CoreGraphState.Valid) { PhCopyCircularBuffer_FLOAT( &CoreHistory, getDrawInfo->DrawInfo->LineData1, getDrawInfo->DrawInfo->LineDataCount ); CoreGraphState.Valid = TRUE; } } } break; case GCN_GETTOOLTIPTEXT: { PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)lParam; if (getTooltipText->Index < getTooltipText->TotalCount) { if (header->hwndFrom == GpuGraphHandle) { if (GpuGraphState.TooltipIndex != getTooltipText->Index) { FLOAT usage; usage = PhGetItemCircularBuffer_FLOAT(&GpuHistory, getTooltipText->Index); PhSwapReference2(&GpuGraphState.TooltipText, PhFormatString( L"%.0f%%", usage * 100 )); } getTooltipText->Text = GpuGraphState.TooltipText->sr; } else if (header->hwndFrom == MemGraphHandle) { if (MemGraphState.TooltipIndex != getTooltipText->Index) { ULONG usage; usage = PhGetItemCircularBuffer_ULONG(&MemHistory, getTooltipText->Index); PhSwapReference2(&MemGraphState.TooltipText, PhFormatString( L"%s / %s (%.2f%%)", PhaFormatSize(UInt32x32To64(usage, 1024), -1)->Buffer, PhaFormatSize(UInt32x32To64(MaxMemUsage, 1024), -1)->Buffer, (FLOAT)usage / MaxMemUsage * 100 )); } getTooltipText->Text = MemGraphState.TooltipText->sr; } else if (header->hwndFrom == CoreGraphHandle) { if (CoreGraphState.TooltipIndex != getTooltipText->Index) { FLOAT usage; usage = PhGetItemCircularBuffer_FLOAT(&CoreHistory, getTooltipText->Index); PhSwapReference2(&CoreGraphState.TooltipText, PhFormatString( L"%.0f%%", usage * 100 )); } getTooltipText->Text = CoreGraphState.TooltipText->sr; } } } break; case GCN_MOUSEEVENT: { PPH_GRAPH_MOUSEEVENT mouseEvent = (PPH_GRAPH_MOUSEEVENT)lParam; if (mouseEvent->Message == WM_LBUTTONDBLCLK) { if (header->hwndFrom == GpuGraphHandle) { PhShowInformation(hwndDlg, L"Double clicked!"); } } } break; } } break; case WM_SHOWWINDOW: { RECT margin; GfxPanelWindowHandle = CreateDialog( PluginInstance->DllBase, MAKEINTRESOURCE(IDD_SYSGFX_PANEL), hwndDlg, MainPanelDlgProc ); SetWindowPos( GfxPanelWindowHandle, NULL, 10, 0, 0, 0, SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOSIZE | SWP_NOZORDER ); ShowWindow(GfxPanelWindowHandle, SW_SHOW); AlwaysOnTop = (BOOLEAN)PhGetIntegerSetting(SETTING_NAME_GFX_ALWAYS_ON_TOP); Button_SetCheck(GetDlgItem(hwndDlg, IDC_ALWAYSONTOP), AlwaysOnTop ? BST_CHECKED : BST_UNCHECKED); GfxSetAlwaysOnTop(); margin.left = 0; margin.top = 0; margin.right = 0; margin.bottom = 25; MapDialogRect(hwndDlg, &margin); PhAddLayoutItemEx( &WindowLayoutManager, GfxPanelWindowHandle, NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT, margin ); SendMessage(hwndDlg, WM_SIZE, 0, 0); SendMessage(hwndDlg, WM_GFX_UPDATE, 0, 0); } break; case WM_SIZE: { HDWP deferHandle; HWND cpuGroupBox = GetDlgItem(hwndDlg, IDC_GROUPCONTROLLER); HWND diskGroupBox = GetDlgItem(hwndDlg, IDC_GROUPGPU); HWND networkGroupBox = GetDlgItem(hwndDlg, IDC_GROUPMEM); RECT clientRect; RECT panelRect; RECT margin = { 13, 13, 13, 13 }; RECT innerMargin = { 10, 20, 10, 10 }; LONG between = 3; LONG width; LONG height; PhLayoutManagerLayout(&WindowLayoutManager); GpuGraphState.Valid = FALSE; MemGraphState.Valid = FALSE; GetClientRect(hwndDlg, &clientRect); // Limit the rectangle bottom to the top of the panel. GetWindowRect(GfxPanelWindowHandle, &panelRect); MapWindowPoints(NULL, hwndDlg, (POINT *)&panelRect, 2); clientRect.bottom = panelRect.top; width = clientRect.right - margin.left - margin.right; height = (clientRect.bottom - margin.top - margin.bottom - between * 2) / 3; deferHandle = BeginDeferWindowPos(6); deferHandle = DeferWindowPos(deferHandle, diskGroupBox, NULL, margin.left, margin.top, width, height, SWP_NOACTIVATE | SWP_NOZORDER); deferHandle = DeferWindowPos( deferHandle, GpuGraphHandle, NULL, margin.left + innerMargin.left, margin.top + innerMargin.top, width - innerMargin.left - innerMargin.right, height - innerMargin.top - innerMargin.bottom, SWP_NOACTIVATE | SWP_NOZORDER ); deferHandle = DeferWindowPos(deferHandle, networkGroupBox, NULL, margin.left, margin.top + height + between, width, height, SWP_NOACTIVATE | SWP_NOZORDER); deferHandle = DeferWindowPos( deferHandle, MemGraphHandle, NULL, margin.left + innerMargin.left, margin.top + height + between + innerMargin.top, width - innerMargin.left - innerMargin.right, height - innerMargin.top - innerMargin.bottom, SWP_NOACTIVATE | SWP_NOZORDER ); deferHandle = DeferWindowPos(deferHandle, cpuGroupBox, NULL, margin.left, margin.top + (height + between) * 2, width, height, SWP_NOACTIVATE | SWP_NOZORDER); deferHandle = DeferWindowPos( deferHandle, CoreGraphHandle, NULL, margin.left + innerMargin.left, margin.top + (height + between) * 2 + innerMargin.top, width - innerMargin.left - innerMargin.right, height - innerMargin.top - innerMargin.bottom, SWP_NOACTIVATE | SWP_NOZORDER ); EndDeferWindowPos(deferHandle); } break; case WM_SIZING: { PhResizingMinimumSize((PRECT)lParam, wParam, 500, 400); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: DestroyWindow(hwndDlg); break; case IDC_ALWAYSONTOP: { AlwaysOnTop = Button_GetCheck(GetDlgItem(hwndDlg, IDC_ALWAYSONTOP)) == BST_CHECKED; GfxSetAlwaysOnTop(); } break; } } break; case WM_GFX_ACTIVATE: { if (IsIconic(hwndDlg)) ShowWindow(hwndDlg, SW_RESTORE); else ShowWindow(hwndDlg, SW_SHOW); SetForegroundWindow(hwndDlg); } break; case WM_GFX_UPDATE: { GetGfxUsages(); GetGfxTemp(); GetGfxClockSpeeds(); GpuGraphState.Valid = FALSE; GpuGraphState.TooltipIndex = -1; Graph_MoveGrid(GpuGraphHandle, 1); Graph_Draw(GpuGraphHandle); Graph_UpdateTooltip(GpuGraphHandle); InvalidateRect(GpuGraphHandle, NULL, FALSE); CoreGraphState.Valid = FALSE; CoreGraphState.TooltipIndex = -1; Graph_MoveGrid(CoreGraphHandle, 1); Graph_Draw(CoreGraphHandle); Graph_UpdateTooltip(CoreGraphHandle); InvalidateRect(CoreGraphHandle, NULL, FALSE); MemGraphState.Valid = FALSE; MemGraphState.TooltipIndex = -1; Graph_MoveGrid(MemGraphHandle, 1); Graph_Draw(MemGraphHandle); Graph_UpdateTooltip(MemGraphHandle); InvalidateRect(MemGraphHandle, NULL, FALSE); SendMessage(GfxPanelWindowHandle, WM_GFX_PANEL_UPDATE, 0, 0); } break; } return FALSE; }
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; }
VOID EtGpuMonitorInitialization( VOID ) { if (PhGetIntegerSetting(SETTING_NAME_ENABLE_GPU_MONITOR)) { EtpGpuAdapterList = PhCreateList(4); if (EtpInitializeD3DStatistics()) EtGpuEnabled = TRUE; } if (EtGpuEnabled) { ULONG sampleCount; ULONG i; ULONG j; PPH_STRING bitmapString; D3DKMT_QUERYSTATISTICS queryStatistics; sampleCount = PhGetIntegerSetting(L"SampleCount"); PhInitializeCircularBuffer_FLOAT(&EtGpuNodeHistory, sampleCount); PhInitializeCircularBuffer_ULONG(&EtMaxGpuNodeHistory, sampleCount); PhInitializeCircularBuffer_FLOAT(&EtMaxGpuNodeUsageHistory, sampleCount); PhInitializeCircularBuffer_ULONG(&EtGpuDedicatedHistory, sampleCount); PhInitializeCircularBuffer_ULONG(&EtGpuSharedHistory, sampleCount); EtGpuNodesTotalRunningTimeDelta = PhAllocate(sizeof(PH_UINT64_DELTA) * EtGpuTotalNodeCount); memset(EtGpuNodesTotalRunningTimeDelta, 0, sizeof(PH_UINT64_DELTA) * EtGpuTotalNodeCount); EtGpuNodesHistory = PhAllocate(sizeof(PH_CIRCULAR_BUFFER_FLOAT) * EtGpuTotalNodeCount); for (i = 0; i < EtGpuTotalNodeCount; i++) { PhInitializeCircularBuffer_FLOAT(&EtGpuNodesHistory[i], sampleCount); } PhRegisterCallback( &PhProcessesUpdatedEvent, EtGpuProcessesUpdatedCallback, NULL, &ProcessesUpdatedCallbackRegistration ); // Load the node bitmap. bitmapString = PhGetStringSetting(SETTING_NAME_GPU_NODE_BITMAP); if (!(bitmapString->Length & 3) && bitmapString->Length / 4 <= BYTES_NEEDED_FOR_BITS(EtGpuTotalNodeCount)) { PhHexStringToBuffer(&bitmapString->sr, (PUCHAR)EtGpuNodeBitMapBuffer); EtGpuNodeBitMapBitsSet = RtlNumberOfSetBits(&EtGpuNodeBitMap); } PhDereferenceObject(bitmapString); // Fix up the node bitmap if the current node count differs from what we've seen. if (EtGpuTotalNodeCount != PhGetIntegerSetting(SETTING_NAME_GPU_LAST_NODE_COUNT)) { ULONG maxContextSwitch = 0; ULONG maxContextSwitchNodeIndex = 0; RtlClearAllBits(&EtGpuNodeBitMap); EtGpuNodeBitMapBitsSet = 0; for (i = 0; i < EtpGpuAdapterList->Count; i++) { PETP_GPU_ADAPTER gpuAdapter = EtpGpuAdapterList->Items[i]; for (j = 0; j < gpuAdapter->NodeCount; j++) { memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS)); queryStatistics.Type = D3DKMT_QUERYSTATISTICS_NODE; queryStatistics.AdapterLuid = gpuAdapter->AdapterLuid; queryStatistics.QueryNode.NodeId = j; if (NT_SUCCESS(D3DKMTQueryStatistics(&queryStatistics))) { // The numbers below are quite arbitrary. if (queryStatistics.QueryResult.NodeInformation.GlobalInformation.RunningTime.QuadPart != 0 && queryStatistics.QueryResult.NodeInformation.GlobalInformation.ContextSwitch > 10000) { RtlSetBits(&EtGpuNodeBitMap, gpuAdapter->FirstNodeIndex + j, 1); EtGpuNodeBitMapBitsSet++; } if (maxContextSwitch < queryStatistics.QueryResult.NodeInformation.GlobalInformation.ContextSwitch) { maxContextSwitch = queryStatistics.QueryResult.NodeInformation.GlobalInformation.ContextSwitch; maxContextSwitchNodeIndex = gpuAdapter->FirstNodeIndex + j; } } } } // Just in case if (EtGpuNodeBitMapBitsSet == 0) { RtlSetBits(&EtGpuNodeBitMap, maxContextSwitchNodeIndex, 1); EtGpuNodeBitMapBitsSet = 1; } PhSetIntegerSetting(SETTING_NAME_GPU_LAST_NODE_COUNT, EtGpuTotalNodeCount); } } }