ManualVRAMTuning

Demonstrates how to control GPU manual VRAM tuning when programming with ADLX.

Command Prompts

Command Prompt Description
1 Get Memory Timing support.
2 Get Memory Timing level and VRAMTuning state(Frequency and Voltage).Enable
3 Set Memory Timing level.
4 Set VRAMTuning state.
M/m Show this menu.
Q/q Quit.

Sample Path

/Samples/CPP/GPUTuning/ManualVRAMTuning

Code

Copied!

//
// Copyright (c) 2021 - 2025 Advanced Micro Devices, Inc. All rights reserved.
//
//-------------------------------------------------------------------------------------------------


#include "SDK/ADLXHelper/Windows/Cpp/ADLXHelper.h"
#include "SDK/Include/IGPUManualVRAMTuning.h"
#include "SDK/Include/IGPUTuning.h"
#include <iostream>
#include <map>

// Use ADLX namespace
using namespace adlx;

// ADLXHelper instance
// No outstanding interfaces from ADLX must exist when ADLX is destroyed.
// Use global variables to ensure validity of the interface.
static ADLXHelper g_ADLXHelp;

// Display Memory Timing support
void ShowSupport(IADLXInterfacePtr& vramTuni.gifc);

// Get VRAM state
void GetState(IADLXInterfacePtr& vramTuni.gifc);

// Set Memory Timing Level
void SetTimingLevel(IADLXInterfacePtr& vramTuni.gifc);

// Set VRAM state
void SetState(IADLXInterfacePtr& vramTuni.gifc);

// Main menu
void MainMenu(IADLXInterfacePtr& vramTuni.gifc);

// Menu action control
void MenuControl(IADLXInterfacePtr vramTuni.gifc);

// Wait for exit with error message
int WaitAndExit(const char* msg, const int retCode);

int main()
{
    ADLX_RESULT  res = ADLX_FAIL ;

    // Initialize ADLX
    res = g_ADLXHelp.Initialize();

    if (ADLX_SUCCEEDED (res))
    {
        // Get GPUs
        IADLXGPUListPtr gpus;
        res = g_ADLXHelp.GetSystemServices()->GetGPUs(&gpus);
        if (ADLX_SUCCEEDED (res) && !gpus->Empty())
        {
            // Get GPU tuning service
            IADLXGPUTuningServicesPtr gpuTuningService;
            res = g_ADLXHelp.GetSystemServices()->GetGPUTuningServices(&gpuTuningService);
            if (ADLX_SUCCEEDED (res))
            {
                // Get GPU interface
                IADLXGPUPtr gpu;
                adlx_uint index = 0;
                res = gpus->At(index, &gpu);
                if (ADLX_SUCCEEDED (res))
                {
                    // Get manual VRAM tuning support
                    adlx_bool supported;
                    res = gpuTuningService->IsSupportedManualVRAMTuning(gpu, &supported);
                    if (ADLX_SUCCEEDED (res))
                        std::cout << "\\tGPU manual VRAM tuning support status: " << supported << std::endl;
                    if (supported)
                    {
                        // Get manual VRAM tuning interface
                        IADLXInterfacePtr vramTuni.gifc;
                        res = gpuTuningService->GetManualVRAMTuning(gpu, &vramTuni.gifc);
                        if (ADLX_SUCCEEDED (res))
                        {
                            MainMenu(vramTuni.gifc);
                            MenuControl(vramTuni.gifc);
                        }
                    }
                    else
                    {
                        return WaitAndExit("\\nThis GPU Doesn't support Manual VRAM Tuning", 0);
                    }
                }
            }
            else
                std::cout << "Failed to get GPU tuning services" << std::endl;
        }
        else
            std::cout << "Failed to get GPU" << std::endl;
    }
    else
        return WaitAndExit("\\tg_ADLXHelp initialize failed", 0);

    // Destroy ADLX
    res = g_ADLXHelp.Terminate();
    std::cout << "Destroy ADLX res: " << res << std::endl;

    // Pause to see the print out
    system("pause");

    return 0;
}

static std::map<ADLX_MEMORYTIMING_DESCRIPTION, const char*> descMap =
    {
        {MEMORYTIMING_DEFAULT , "Default"},
        {MEMORYTIMING_FAST_TIMING , "Fast Timing"},
        {MEMORYTIMING_FAST_TIMING_LEVEL_2 , "Fast Timing Level2"},
        {MEMORYTIMING_AUTOMATIC , "Automatic"},
        {MEMORYTIMING_MEMORYTIMING_LEVEL_1 , "Memory Timing Level1"},
        {MEMORYTIMING_MEMORYTIMING_LEVEL_2 , "Memory Timing Level2"}};

void ShowSupport(IADLXInterfacePtr& vramTuni.gifc)
{
    adlx_bool supported = false;
    IADLXManualVRAMTuning2Ptr vramTuning2(vramTuni.gifc);
    IADLXManualVRAMTuning1Ptr vramTuning1(vramTuni.gifc);
    ADLX_RESULT  res = ADLX_FAIL ;
    if (vramTuning2)
    {
        res = vramTuning2->IsSupportedMemoryTiming(&supported);
    }
    else if (vramTuning1)
    {
        res = vramTuning1->IsSupportedMemoryTiming(&supported);
    }
    std::cout << "\\tIsSupported: " << supported << ", return code is: "<< res << "(0 means success)" << std::endl;
}

void GetState(IADLXInterfacePtr& vramTuni.gifc)
{
    IADLXManualVRAMTuning2Ptr vramTuning2(vramTuni.gifc);
    IADLXManualVRAMTuning1Ptr vramTuning1(vramTuni.gifc);
    ADLX_MEMORYTIMING_DESCRIPTION  desc;
    IADLXMemoryTimingDescriptionListPtr descList;
    if (vramTuning2)
    {
        vramTuning2->GetSupportedMemoryTimingDescriptionList(&descList);
        vramTuning2->GetMemoryTimingDescription(&desc);

        adlx_int freq;
        ADLX_IntRange  rang;
        ADLX_RESULT  res = vramTuning2->GetMaxVRAMFrequency(&freq);
        std::cout << "\\tMax VRAM frequency: " << freq << ", return code is: "<< res << "(0 means success)" << std::endl;
        res = vramTuning2->GetMaxVRAMFrequencyRange(&rang);
        std::cout << "\\tMax VRAM frequency range: [" << rang.minValue  << " , " << rang.maxValue  << " ], step: " << rang.step
                  << ", return code is: "<< res << "(0 means success)" << std::endl;
        IADLXManualVRAMTuning2_1Ptr vramTuning2_1(vramTuning2);
        if (vramTuning2_1)
        {
            res = vramTuning2_1->GetMaxVRAMFrequencyDefault(&freq);
            std::cout << "\\tDefault Max VRAM frequency: " << freq << ", return code is: " << res << "(0 means success)" << std::endl;

        }

    }
    else if (vramTuning1)
    {
        vramTuning1->GetSupportedMemoryTimingDescriptionList(&descList);
        vramTuning1->GetMemoryTimingDescription(&desc);

        IADLXManualTuningStateListPtr states;
        vramTuning1->GetVRAMTuningStates(&states);
        adlx_uint s = states->Begin();
        std::cout << "\\tState is:" << std::endl;
        for (; s != states->End(); s++)
        {
            IADLXManualTuningStatePtr state;
            adlx_int frequency;
            adlx_int voltage;
            states->At(s, &state);
            state->GetFrequency(&frequency);
            state->GetVoltage(&voltage);
            std::cout << "\\t\\tfrequency: " << frequency << " voltage: " << voltage << std::endl;
        }

        ADLX_IntRange  frequencyRange;
        ADLX_IntRange  voltageRange;
        ADLX_RESULT  res = vramTuning1->GetVRAMTuningRanges(&frequencyRange, &voltageRange);
        std::cout << "\\tFrequency range: [" << frequencyRange.minValue  << " , " << frequencyRange.maxValue  << " ], step: " << frequencyRange.step
                  << ", return code is: "<< res << "(0 means success)" << std::endl;
        std::cout << "\\tVoltage range: [" << voltageRange.minValue  << " , " << voltageRange.maxValue  << " ], step: " << voltageRange.step
                  << ", return code is: "<< res << "(0 means success)" << std::endl;
    }
    if (descList)
    {
        std::cout << "\\tCurrent timing desc: " << descMap[desc] << std::endl;
        std::cout << "\\tSupported Memory Timing desc list:" << std::endl;
        for (adlx_uint s = 0; s != descList->End (); s++)
        {
            IADLXMemoryTimingDescriptionPtr item;
            descList->At (s, &item);
            item->GetDescription (&desc);
            std::cout << "\\t  " << descMap[desc] << std::endl;
        }
    }
    std::cout << std::endl;
}

void SetTimingLevel(IADLXInterfacePtr& vramTuni.gifc)
{
    ADLX_RESULT  res;
    IADLXManualVRAMTuning2Ptr vramTuning2(vramTuni.gifc);
    IADLXManualVRAMTuning1Ptr vramTuning1(vramTuni.gifc);
    ADLX_MEMORYTIMING_DESCRIPTION  desc, currentDesc;
    IADLXMemoryTimingDescriptionListPtr descList;
    bool supported = false;
    if (vramTuning2)
    {
        //If MemoryTiming is supported, then only will get the MemoryTimingDescriptionList
        res = vramTuning2->IsSupportedMemoryTiming(&supported);
        if (supported)
        {
            vramTuning2->GetSupportedMemoryTimingDescriptionList(&descList);
            if (descList)
            {
                vramTuning2->GetMemoryTimingDescription(&currentDesc);
                for (adlx_uint s = 0; s != descList->End(); s++)
                {
                    IADLXMemoryTimingDescriptionPtr item;
                    descList->At(s, &item);
                    item->GetDescription(&desc);
                    if (currentDesc != desc)
                    {
                        res = vramTuning2->SetMemoryTimingDescription(desc);
                        std::cout << "\\tSet Memory Timing description to " << descMap[desc] << ": return code is: " << res << " (0 means success)" << std::endl;
                        break;
                    }
                }
            }
            else
            {
                std::cout << "\\tFailed to get the Supported Memory Timing Description List." << std::endl;
            }
        }
        else
        {
            std::cout << "\\tMemory Timing Level not Supported, so cannot set Memory Timing Description List." << std::endl;
        }
    }
    else if (vramTuning1)
    {
        //If MemoryTiming is supported, then only will get the MemoryTimingDescriptionList
        res = vramTuning1->IsSupportedMemoryTiming(&supported);
        if (supported)
        {
            vramTuning1->GetSupportedMemoryTimingDescriptionList(&descList);
            if (descList)
            {
                vramTuning1->GetMemoryTimingDescription(&currentDesc);
                for (adlx_uint s = 0; s != descList->End(); s++)
                {
                    IADLXMemoryTimingDescriptionPtr item;
                    descList->At(s, &item);
                    item->GetDescription(&desc);
                    if (currentDesc != desc)
                    {
                        res = vramTuning1->SetMemoryTimingDescription(desc);
                        std::cout << "\\tSet Memory Timing description to " << descMap[desc] << ": return code is: " << res << " (0 means success)" << std::endl;
                        break;
                    }
                }
            }
            else
            {
                std::cout << "\\tFailed to get the Supported Memory Timing Description List." << std::endl;
            }
        }
        else
        {
            std::cout << "\\tMemory Timing Level not Supported, so cannot set Memory Timing Description List." << std::endl;
        }
    }
}

void SetState(IADLXInterfacePtr& vramTuni.gifc)
{
    ADLX_RESULT  res;
    IADLXManualVRAMTuning2Ptr vramTuning2(vramTuni.gifc);
    IADLXManualVRAMTuning1Ptr vramTuning1(vramTuni.gifc);
    bool supported = false;
    if (vramTuning2)
    {
        //If MemoryTiming is supported, then only will set the MemoryTimingState
        res = vramTuning2->IsSupportedMemoryTiming(&supported);
        if (supported)
        {
            adlx_int freq;
            ADLX_IntRange  rang;
            vramTuning2->GetMaxVRAMFrequency(&freq);
            vramTuning2->GetMaxVRAMFrequencyRange(&rang);
            if (freq != rang.minValue )
            {
                res = vramTuning2->SetMaxVRAMFrequency(rang.minValue );
                std::cout << "\\tUse min Frequency to set, return code(0 is Success) is: " << res << std::endl;
            }
            else
            {
                res = vramTuning2->SetMaxVRAMFrequency(rang.minValue  + rang.step  * 2);
                std::cout << "\\tUse max Frequency to set, return code(0 is Success) is: " << res << std::endl;
            }
        }
        else
        {
            std::cout << "\\tTuning not Supported, so cannot change the State." << std::endl;
        }
    }
    else if (vramTuning1)
    {
        //If MemoryTiming is supported, then only will set the MemoryTimingState
        res = vramTuning1->IsSupportedMemoryTiming(&supported);
        if (supported)
        {
            ADLX_IntRange  frequencyRange;
            ADLX_IntRange  voltageRange;
            vramTuning1->GetVRAMTuningRanges(&frequencyRange, &voltageRange);
            IADLXManualTuningStateListPtr states;
            vramTuning1->GetVRAMTuningStates(&states);
            adlx_uint s = states->Size() - 1;
            for (; s != states->End(); s++)
            {
                IADLXManualTuningStatePtr state;
                adlx_int frequency;
                adlx_int voltage;
                states->At(s, &state);
                state->GetFrequency(&frequency);
                state->GetVoltage(&voltage);
                // Only change the last
                res = state->SetFrequency(frequencyRange.maxValue  - frequencyRange.step  * 10);
                res = state->SetVoltage(voltageRange.maxValue  - voltageRange.step  * 10);
                break;
            }
            res = vramTuning1->SetVRAMTuningStates(states);
            std::cout << "\\tChange VRAM tuning states, return code(0 is Success) is: " << res << std::endl;
        }
        else
        {
            std::cout << "\\tTuning not Supported, so cannot change the State." << std::endl;
        }
    }
}

void MainMenu(IADLXInterfacePtr& vramTuni.gifc)
{
    // Acquire to ManualVRAMTuning1
    IADLXManualVRAMTuning1Ptr vramTuning1(vramTuni.gifc);
    // Acquire to ManualVRAMTuning2
    IADLXManualVRAMTuning2Ptr vramTuning2(vramTuni.gifc);

    std::cout << "\\tChoose from the following options:" << std::endl;

    std::cout << "\\t->Press 1 to display Memory Timing support" << std::endl;
    if (vramTuning2)
        std::cout << "\\t->Press 2 to get Memory Timing level and frequency range" << std::endl;
    else if (vramTuning1)
        std::cout << "\\t->Press 2 to get Memory Timing level, VRAM frequency, and the voltage global range for all states" << std::endl;

    std::cout << "\\t->Press 3 to change current Memory Timing Level" << std::endl;

    if (vramTuning2)
        std::cout << "\\t->Press 4 to change current VRAM max frequency value" << std::endl;
    else if (vramTuning1)
        std::cout << "\\t->Press 4 to change VRAM states" << std::endl;

    std::cout << "\\t->Press Q/q to terminate the application" << std::endl;
    std::cout << "\\t->Press M/m to display main menu options" << std::endl;
}

void MenuControl(IADLXInterfacePtr vramTuni.gifc)
{
    int num = 0;
    while ((num = getchar()) != 'q' && num != 'Q')
    {
        switch (num)
        {
        // Get Memory Timing support
        case '1':
            ShowSupport(vramTuni.gifc);
            break;

        // Get VRAM state
        case '2':
            GetState(vramTuni.gifc);
            break;

        // Set timing level
        case '3':
            SetTimingLevel(vramTuni.gifc);
            break;

        // Set VRAM state
        case '4':
            SetState(vramTuni.gifc);
            break;

        // Display menu options
        case 'm':
        case 'M':
            MainMenu(vramTuni.gifc);
            break;
        default:
            break;
        }
    }
}

int WaitAndExit(const char* msg, const int retCode)
{
    // Printout the message and pause to see it before returning the desired code
    if (nullptr != msg)
        std::cout << msg << std::endl;

    system("pause");
    return retCode;
}

Related pages

  • Visit the Adlx product page for download links and more information.

Looking for more documentation on GPUOpen?

AMD GPUOpen software blogs

Our handy software release blogs will help you make good use of our tools, SDKs, and effects, as well as sharing the latest features with new releases.

GPUOpen Manuals

Don’t miss our manual documentation! And if slide decks are what you’re after, you’ll find 100+ of our finest presentations here.

AMD GPUOpen Performance Guides

The home of great performance and optimization advice for AMD RDNA™ 2 GPUs, AMD Ryzen™ CPUs, and so much more.

Getting started: AMD GPUOpen software

New or fairly new to AMD’s tools, libraries, and effects? This is the best place to get started on GPUOpen!

AMD GPUOpen Getting Started Development and Performance

Looking for tips on getting started with developing and/or optimizing your game, whether on AMD hardware or generally? We’ve got you covered!

AMD GPUOpen Technical blogs

Browse our technical blogs, and find valuable advice on developing with AMD hardware, ray tracing, Vulkan®, DirectX®, Unreal Engine, and lots more.

Find out more about our software!

AMD GPUOpen Effects - AMD FidelityFX technologies

Create wonder. No black boxes. Meet the AMD FidelityFX SDK!

AMD GPUOpen Samples

Browse all our useful samples. Perfect for when you’re needing to get started, want to integrate one of our libraries, and much more.

AMD GPUOpen developer SDKs

Discover what our SDK technologies can offer you. Query hardware or software, manage memory, create rendering applications or machine learning, and much more!

AMD GPUOpen Developer Tools

Analyze, Optimize, Profile, Benchmark. We provide you with the developer tools you need to make sure your game is the best it can be!