ManualGraphicsTuning
Navigation: Programming with ADLX → ADLX Samples → C Samples → GPU Tuning
Demonstrates how to control manual graphics tuning when programming with ADLX.
Command Prompts
Command Prompt | Description |
---|---|
1 | Get GPU frequency and voltage. |
2 | Get current GPU states. |
3 | Set GPU states. |
4 | Get default GPU states. |
M/m | Show this menu. |
Q/q | Quit. |
Sample Path
/Samples/C/GPUTuning/ManualGraphicsTuning
C
Code
C
//// Copyright Advanced Micro Devices, Inc. All rights reserved.////-------------------------------------------------------------------------------------------------
/// \file mainManualGraphicsTuning.c/// \brief Demonstrates how to control manual graphics tuning when programming with ADLX.
#include "SDK/ADLXHelper/Windows/C/ADLXHelper.h"#include "SDK/Include/IGPUManualGFXTuning.h"#include "SDK/Include/IGPUTuning.h"
// Main menuvoid MainMenu(IADLXManualGraphicsTuning1* manualGFXTuning1, IADLXManualGraphicsTuning2* manualGFXTuning2);
// Menu action controlvoid MenuControl(IADLXManualGraphicsTuning1* manualGFXTuning1, IADLXManualGraphicsTuning2* manualGFXTuning2);
// Wait for exit with error messageint WaitAndExit(const char* msg, const int retCode, IADLXGPUTuningServices* gpuTuningService, IADLXGPUList* gpus, IADLXGPU* oneGPU, IADLXInterface* manualGFXTuningIfc, IADLXManualGraphicsTuning1* manualGFXTuning1, IADLXManualGraphicsTuning2* manualGFXTuning2);
/***** The first is pre-Navi, the second is post-Navi *****/// Display GPU frequency and voltage rangevoid ShowFrequencyAndVoltageRange1(IADLXManualGraphicsTuning1* manualGFXTuning1);void ShowFrequencyAndVoltageRange2(IADLXManualGraphicsTuning2* manualGFXTuning2);// Display current GPU tuning statesvoid GetCurrentStates1(IADLXManualGraphicsTuning1* manualGFXTuning1);void GetCurrentStates2(IADLXManualGraphicsTuning2* manualGFXTuning2);// Display default GPU tuning statesvoid GetDefaultStates2(IADLXManualGraphicsTuning2* manualGFXTuning2);// Set GPU statesvoid SetGPUStates1(IADLXManualGraphicsTuning1* manualGFXTuning1);void SetGPUStates2(IADLXManualGraphicsTuning2* manualGFXTuning2);
int main(){ ADLX_RESULT res = ADLX_FAIL;
// Initialize ADLX res = ADLXHelper_Initialize();
if (ADLX_SUCCEEDED(res)) { IADLXSystem* sys = ADLXHelper_GetSystemServices(); IADLXGPUTuningServices* gpuTuningService = NULL; IADLXGPUList* gpus = NULL; IADLXGPU* oneGPU = NULL; IADLXInterface* manualGFXTuningIfc = NULL; IADLXManualGraphicsTuning1* manualGFXTuning1 = NULL; IADLXManualGraphicsTuning2* manualGFXTuning2 = NULL;
res = sys->pVtbl->GetGPUTuningServices(sys, &gpuTuningService); if (ADLX_FAILED(res)) return WaitAndExit("\tGet GPU tuning services failed", 0, gpuTuningService, gpus, oneGPU, manualGFXTuningIfc, manualGFXTuning1, manualGFXTuning2);
res = sys->pVtbl->GetGPUs(sys, &gpus); if (ADLX_FAILED(res)) return WaitAndExit("\tGet GPU list failed", 0, gpuTuningService, gpus, oneGPU, manualGFXTuningIfc, manualGFXTuning1, manualGFXTuning2);
ADLX_RESULT res = gpus->pVtbl->At_GPUList(gpus, 0, &oneGPU); if (ADLX_FAILED(res) || oneGPU == NULL) return WaitAndExit("\tGet GPU failed", 0, gpuTuningService, gpus, oneGPU, manualGFXTuningIfc, manualGFXTuning1, manualGFXTuning2);
adlx_bool supported = false; res = gpuTuningService->pVtbl->IsSupportedManualGFXTuning(gpuTuningService, oneGPU, &supported); if (ADLX_FAILED(res) || supported == false) return WaitAndExit("\tThis GPU does not support manual graphics tuning", 0, gpuTuningService, gpus, oneGPU, manualGFXTuningIfc, manualGFXTuning1, manualGFXTuning2);
res = gpuTuningService->pVtbl->GetManualGFXTuning(gpuTuningService, oneGPU, &manualGFXTuningIfc); if (ADLX_FAILED(res) || manualGFXTuningIfc == NULL) return WaitAndExit("\tGet manual graphics tuning interface failed", 0, gpuTuningService, gpus, oneGPU, manualGFXTuningIfc, manualGFXTuning1, manualGFXTuning2);
// Pre-Navi ASIC manualGFXTuningIfc->pVtbl->QueryInterface(manualGFXTuningIfc, IID_IADLXManualGraphicsTuning1(), (void**)&manualGFXTuning1); // Post-Navi ASIC manualGFXTuningIfc->pVtbl->QueryInterface(manualGFXTuningIfc, IID_IADLXManualGraphicsTuning2(), (void**)&manualGFXTuning2);
if (manualGFXTuning1 == NULL && manualGFXTuning2 == NULL) return WaitAndExit("\tGet manual graphics tuning failed", 0, gpuTuningService, gpus, oneGPU, manualGFXTuningIfc, manualGFXTuning1, manualGFXTuning2); // Display main menu options MainMenu(manualGFXTuning1, manualGFXTuning2);
// Get and execute the choice MenuControl(manualGFXTuning1, manualGFXTuning2);
// Release the manualGFXTuning1 interface if (manualGFXTuning1 != NULL) { manualGFXTuning1->pVtbl->Release(manualGFXTuning1); manualGFXTuning1 = NULL; } if (manualGFXTuning2 != NULL) { manualGFXTuning2->pVtbl->Release(manualGFXTuning2); manualGFXTuning2 = NULL; } if (manualGFXTuningIfc != NULL) { manualGFXTuningIfc->pVtbl->Release(manualGFXTuningIfc); manualGFXTuningIfc = NULL; } if (oneGPU != NULL) { oneGPU->pVtbl->Release(oneGPU); oneGPU = NULL; } if (gpus != NULL) { gpus->pVtbl->Release(gpus); gpus = NULL; } if (gpuTuningService != NULL) { gpuTuningService->pVtbl->Release(gpuTuningService); gpuTuningService = NULL; } } else { printf("\tg_ADLXHelp initialize failed\n"); system("pause"); return 0; }
// Destroy ADLX res = ADLXHelper_Terminate(); printf("Destroy ADLX res: %d\n", res);
// Pause to see the print out system("pause");
return 0;}
// Main menuvoid MainMenu(IADLXManualGraphicsTuning1* manualGFXTuning1, IADLXManualGraphicsTuning2* manualGFXTuning2){ if (manualGFXTuning1) printf("\tThe current GPU is pre-Navi. Choose from the following options:\n"); else if (manualGFXTuning2) printf("\tThe current GPU is post-Navi. Choose from the following options:\n"); printf("\t->Press 1 to display GPU frequency and voltage\n"); printf("\t->Press 2 to display current GPU states\n"); printf("\t->Press 3 to set GPU states\n"); printf("\t->Press 4 to display default GPU states\n"); printf("\t->Press Q/q to terminate the application\n"); printf("\t->Press M/m to display main menu options\n");}
void MenuControl(IADLXManualGraphicsTuning1* manualGFXTuning1, IADLXManualGraphicsTuning2* manualGFXTuning2){ char num = 0; while ((num = getchar()) != 'q' && num != 'Q') { // Pre-Navi Menu action control if (manualGFXTuning1) { switch (num) { // Display GPU frequency and voltage range case '1': ShowFrequencyAndVoltageRange1(manualGFXTuning1); break;
// Display current GPU tuning states case '2': GetCurrentStates1(manualGFXTuning1); break;
// Set GPU states case '3': SetGPUStates1(manualGFXTuning1); break;
// Display menu options case 'm': case 'M': MainMenu(manualGFXTuning1, manualGFXTuning2); break; default: break; } } // Post-Navi Menu action control else { switch (num) { // Display GPU frequency and voltage range case '1': ShowFrequencyAndVoltageRange2(manualGFXTuning2); break;
// Display current GPU tuning states case '2': GetCurrentStates2(manualGFXTuning2); break;
// Set GPU states case '3': SetGPUStates2(manualGFXTuning2); break;
// Display default GPU tuning states case '4': GetDefaultStates2(manualGFXTuning2); break;
// Display menu options case 'm': case 'M': MainMenu(manualGFXTuning1, manualGFXTuning2); break; default: break; } } }}
// Wait for exit with error messageint WaitAndExit(const char* msg, const int retCode, IADLXGPUTuningServices* gpuTuningService, IADLXGPUList* gpus, IADLXGPU* oneGPU, IADLXInterface* manualGFXTuningIfc, IADLXManualGraphicsTuning1* manualGFXTuning1, IADLXManualGraphicsTuning2* manualGFXTuning2){ // Printout the message and pause to see it before returning the desired code if (NULL != msg) printf("%s\n", msg);
// Release the manualGFXTuning interface if (manualGFXTuning1 != NULL) { manualGFXTuning1->pVtbl->Release(manualGFXTuning1); manualGFXTuning1 = NULL; } if (manualGFXTuning2 != NULL) { manualGFXTuning2->pVtbl->Release(manualGFXTuning2); manualGFXTuning2 = NULL; } if (manualGFXTuningIfc != NULL) { manualGFXTuningIfc->pVtbl->Release(manualGFXTuningIfc); manualGFXTuningIfc = NULL; } if (oneGPU != NULL) { oneGPU->pVtbl->Release(oneGPU); oneGPU = NULL; } if (gpus != NULL) { gpus->pVtbl->Release(gpus); gpus = NULL; } if (gpuTuningService != NULL) { gpuTuningService->pVtbl->Release(gpuTuningService); gpuTuningService = NULL; } // Destroy ADLX ADLX_RESULT res = ADLXHelper_Terminate(); printf("Destroy ADLX res: %d\n", res);
system("pause"); return retCode;}
// Display GPU frequency and voltage rangevoid ShowFrequencyAndVoltageRange1(IADLXManualGraphicsTuning1* manualGFXTuning1){ ADLX_IntRange freqRange, voltRange; ADLX_RESULT res = manualGFXTuning1->pVtbl->GetGPUTuningRanges(manualGFXTuning1, &freqRange, &voltRange); printf("\tFrequency range: (%d, %d), return code is: %d(0 means success)\n", freqRange.minValue, freqRange.maxValue, res); printf("\tVoltage range: (%d, %d), return code is: %d(0 means success)\n", voltRange.minValue, voltRange.maxValue, res);}
// Display current GPU tuning statesvoid GetCurrentStates1(IADLXManualGraphicsTuning1* manualGFXTuning1){ IADLXManualTuningStateList* states; IADLXManualTuningState* oneState; ADLX_RESULT res = manualGFXTuning1->pVtbl->GetGPUTuningStates(manualGFXTuning1, &states); if (ADLX_SUCCEEDED (res)) { for (adlx_uint crt = states->pVtbl->Begin(states); crt != states->pVtbl->End(states); ++crt) { states->pVtbl->At_ManualTuningStateList(states, crt, &oneState); adlx_int freq = 0, volt = 0; res = oneState->pVtbl->GetFrequency(oneState, &freq); printf("\tThe current state %d: frequency is %d, return code is: %d(0 means success)\n", crt, freq, res); res = oneState->pVtbl->GetVoltage(oneState, &volt); printf("\tThe current state %d: voltage is %d, return code is: %d(0 means success)\n", crt, volt, res); if (oneState != NULL) { oneState->pVtbl->Release (oneState); oneState = NULL; } } } if (states != NULL) { states->pVtbl->Release (states); states = NULL; }}
// Set GPU statesvoid SetGPUStates1(IADLXManualGraphicsTuning1* manualGFXTuning1){ IADLXManualTuningStateList* states; IADLXManualTuningState* oneState; ADLX_RESULT res1 = manualGFXTuning1->pVtbl->GetEmptyGPUTuningStates(manualGFXTuning1, &states); ADLX_IntRange freqRange, voltRange; ADLX_RESULT res2 = manualGFXTuning1->pVtbl->GetGPUTuningRanges(manualGFXTuning1, &freqRange, &voltRange); if (ADLX_SUCCEEDED (res1) && ADLX_SUCCEEDED (res2)) { for (adlx_uint crt = states->pVtbl->Begin(states); crt != states->pVtbl->End(states); ++crt) { states->pVtbl->At_ManualTuningStateList(states, crt, &oneState); adlx_int freq = 0, volt = 0; int freqStep = (freqRange.maxValue - freqRange.minValue) / (states->pVtbl->Size(states)); // The Step should not be too large if (freqStep >= 60) freqStep = 60; int voltStep = (voltRange.maxValue - voltRange.minValue) / (states->pVtbl->Size(states)); // The Step should not be too large if (voltStep >= 20) voltStep = 20; ADLX_RESULT res = oneState->pVtbl->SetFrequency(oneState, freqRange.minValue + freqStep * crt); res = oneState->pVtbl->GetFrequency(oneState, &freq); res = oneState->pVtbl->SetVoltage(oneState, voltRange.minValue + voltStep * crt); res = oneState->pVtbl->GetVoltage(oneState, &volt); printf("\tSet empty state %d: frequency is %d, voltage is %d, return code is: %d(0 means success)\n", crt, freq, volt, res); if (oneState != NULL) { oneState->pVtbl->Release (oneState); oneState = NULL; } } } adlx_int errorIndex; ADLX_RESULT res = manualGFXTuning1->pVtbl->IsValidGPUTuningStates(manualGFXTuning1, states, &errorIndex); printf("\tIsValidGPUTuningStates, errorIndex is : %d, return code is: %d(0 means success)\n", errorIndex, res); if (ADLX_SUCCEEDED(res)) { res = manualGFXTuning1->pVtbl->SetGPUTuningStates(manualGFXTuning1, states); printf ("\tSet GPU tuning states %s\n", (ADLX_SUCCEEDED (res) ? "succeeded" : "failed")); } if (states != NULL) { states->pVtbl->Release (states); states = NULL; }
res = manualGFXTuning1->pVtbl->GetGPUTuningStates(manualGFXTuning1, &states); printf("\tAfter setting:\n"); if (ADLX_SUCCEEDED (res)) { for (adlx_uint crt = states->pVtbl->Begin(states); crt != states->pVtbl->End(states); ++crt) { states->pVtbl->At_ManualTuningStateList(states, crt, &oneState); adlx_int freq = 0, volt = 0; res = oneState->pVtbl->GetFrequency(oneState, &freq); res = oneState->pVtbl->GetVoltage(oneState, &volt); printf("\tThe current state %d: frequency is %d, voltage is %d, return code is: %d(0 means success)\n", crt, freq, volt, res); if (oneState != NULL) { oneState->pVtbl->Release (oneState); oneState = NULL; } } } if (states != NULL) { states->pVtbl->Release (states); states = NULL; }}
// Display GPU frequency and voltage rangevoid ShowFrequencyAndVoltageRange2(IADLXManualGraphicsTuning2* manualGFXTuning2){ ADLX_IntRange freqRange, voltRange; ADLX_RESULT res= manualGFXTuning2->pVtbl->GetGPUMinFrequencyRange(manualGFXTuning2, &freqRange); printf("\tGPU minimum frequency range: (%d, %d), return code is: %d(0 means success)\n", freqRange.minValue, freqRange.maxValue, res); res = manualGFXTuning2->pVtbl->GetGPUMaxFrequencyRange(manualGFXTuning2, &freqRange); printf("\tGPU maximum frequency range: (%d, %d), return code is: %d(0 means success)\n", freqRange.minValue, freqRange.maxValue, res); res = manualGFXTuning2->pVtbl->GetGPUVoltageRange(manualGFXTuning2, &voltRange); printf("\tVoltage range: (%d, %d), return code is: %d(0 means success)\n", voltRange.minValue, voltRange.maxValue, res);}
// Display current GPU tuning statesvoid GetCurrentStates2(IADLXManualGraphicsTuning2* manualGFXTuning2){ adlx_int minFreq = 0, maxFreq = 0, volt = 0; ADLX_RESULT res = manualGFXTuning2->pVtbl->GetGPUMinFrequency(manualGFXTuning2, &minFreq); printf("\tCurrent GPU minimum frequency: %d, return code is: %d(0 means success)\n", minFreq, res); res = manualGFXTuning2->pVtbl->GetGPUMaxFrequency(manualGFXTuning2, &maxFreq); printf("\tCurrent GPU maximum frequency: %d, return code is: %d(0 means success)\n", maxFreq, res); res = manualGFXTuning2->pVtbl->GetGPUVoltage(manualGFXTuning2, &volt); printf("\tCurrent GPU clock voltage: %d, return code is: %d(0 means success)\n", volt, res);}
void GetDefaultStates2(IADLXManualGraphicsTuning2* manualGFXTuning2){ IADLXManualGraphicsTuning2_1* manualFanTuning2_1; manualGFXTuning2->pVtbl->QueryInterface(manualGFXTuning2, IID_IADLXManualGraphicsTuning2_1(), (void**)&manualFanTuning2_1); if (manualFanTuning2_1) { adlx_int minFreq = 0, maxFreq = 0, volt = 0; ADLX_RESULT res = manualFanTuning2_1->pVtbl->GetGPUMinFrequencyDefault(manualFanTuning2_1, &minFreq); printf("\tDefault GPU minimum frequency: %d, return code is: %d(0 means success)\n", minFreq, res); res = manualFanTuning2_1->pVtbl->GetGPUMaxFrequencyDefault(manualFanTuning2_1, &maxFreq); printf("\tDefault GPU maximum frequency: %d, return code is: %d(0 means success)\n", maxFreq, res); res = manualFanTuning2_1->pVtbl->GetGPUVoltageDefault(manualFanTuning2_1, &volt); printf("\tDefault GPU clock voltage: %d, return code is: %d(0 means success)\n", volt, res);
// release manualFanTuning2_1 manualFanTuning2_1->pVtbl->Release(manualFanTuning2_1); manualFanTuning2_1 = NULL; }}// Set GPU statesvoid SetGPUStates2(IADLXManualGraphicsTuning2* manualGFXTuning2){ ADLX_IntRange freqRange, voltRange; ADLX_RESULT res = manualGFXTuning2->pVtbl->GetGPUMinFrequencyRange(manualGFXTuning2, &freqRange); res = manualGFXTuning2->pVtbl->GetGPUVoltageRange(manualGFXTuning2, &voltRange); res = manualGFXTuning2->pVtbl->SetGPUMinFrequency(manualGFXTuning2, freqRange.minValue); printf ("\tSet GPU min frequency %s\n", (ADLX_SUCCEEDED (res) ? "succeeded" : "failed")); res = manualGFXTuning2->pVtbl->SetGPUMaxFrequency(manualGFXTuning2, freqRange.minValue + 100); printf ("\tSet GPU max frequency %s\n", (ADLX_SUCCEEDED (res) ? "succeeded" : "failed")); res = manualGFXTuning2->pVtbl->SetGPUVoltage(manualGFXTuning2, voltRange.minValue + (voltRange.maxValue - voltRange.minValue) / 2); printf ("\tSet GPU voltage %s\n", (ADLX_SUCCEEDED (res) ? "succeeded" : "failed")); printf("\tAfter setting:\n"); adlx_int minFreq = 0, maxFreq = 0, volt = 0; res = manualGFXTuning2->pVtbl->GetGPUMinFrequency(manualGFXTuning2, &minFreq); printf("\tCurrent GPU min frequency: %d, return code is: %d(0 means success)\n", minFreq, res); res = manualGFXTuning2->pVtbl->GetGPUMaxFrequency(manualGFXTuning2, &maxFreq); printf("\tCurrent GPU max frequency: %d, return code is: %d(0 means success)\n", maxFreq, res); res = manualGFXTuning2->pVtbl->GetGPUVoltage(manualGFXTuning2, &volt); printf("\tCurrent GPU clock voltage: %d, return code is: %d(0 means success)\n", volt, res);}