cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

olivierb
Journeyman III

ADL SDK

Hi,

Did anyone successfully use the ADL SDK under windows XP/7 to control the clock of the FirePro? Any code snippets available?

Thanks and regards

Olivier

0 Likes
7 Replies
chm
Staff
Staff

Hi Oliver,

what exactly do you want to control? On FirePro you cannot overclock the engine or memory clock. If you call ADL_Display_ODClockInfo_Get to get the ClockInfo you will notice that MinClock and MaxClock are identical.If you call ADL_Display_ODClockConfig_Set you need to pass a clock value that is in between MinClock and MaxClock otherwise the function will fail. So if you get an error when calling ADL_Display_ODClockConfig_Set it might be due to this.

Chris

0 Likes

Hi Chris,

Actually, I was trying to use the following API. The problem is that I only get NULL pointers returned which are indeed unusable.

ADL_Adapter_Speed_get = (ADL_ADAPTER_SPEED_GET)GetProcAddress(hDLL,"ADL_Display_Speed_Get");

ADL_Adapter_Speed_set = (ADL_ADAPTER_SPEED_SET)GetProcAddress(hDLL,"ADL_Display_Speed_Set");

Any suggestions?

Thank you for your help.

Olivier

0 Likes

Hi Oliver,

the following code works fine for me:

typedef int ( *ADL_ADAPTER_SPEED_GET) (int iAdapterIndex, int *lpCurrent, int *lpDefault);

typedef int ( *ADL_ADAPTER_SPEED_SET) (int iAdapterIndex, int iSpeed);

ADL_ADAPTER_SPEED_GET            ADL_Adapter_Speed_Get;

ADL_ADAPTER_SPEED_SET            ADL_Adapter_Speed_Set;

...

ADL_Adapter_Speed_Get = (ADL_ADAPTER_SPEED_GET)GetProcAddress(hDLL, "ADL_Adapter_Speed_Get");

ADL_Adapter_Speed_Set = (ADL_ADAPTER_SPEED_SET)GetProcAddress(hDLL, "ADL_Adapter_Speed_Set");

Chris

0 Likes

Hi Chris,

Thank you for your input. I suppose we did something wrong before but now it works.

Unfortunately, it didn’t take us much further. We could successfully get the speed of the adapter (see code snippet below) but the values returned are always zero regardless if the FirePro is under full load or just idle.

Now, what is it we are trying to do: we are processing images in bursts of variable lengths separated by idle periods of variable duration (more than 10s usually). We are experiencing an annoying slow first frame after every idle period. We were candidly hoping that the get and set speed could help us put the FirePro into a “high speed” state so that the slow frame problem goes away.

It may be possible but there may be other ways to achieve that goal. Please advise.

Thank you for your help.

Best regards

Olivier

Adapted from the sample code that comes with the ADL package.

// Repeat for all available adapters in the system

for ( i = 0; i < iNumberAdapters; i++ )

{

int cur, def, rc;

iAdapterIndex = lpAdapterInfo[ i ].iAdapterIndex;

ADL_Main_Memory_Free ( &lpAdlDisplayInfo );

if (ADL_OK != ADL_Display_DisplayInfo_Get (lpAdapterInfo.iAdapterIndex, &iNumDisplays, &lpAdlDisplayInfo, 0))

continue;

if (ADL_OK != ADL_Adapter_Speed_Get (i, &cur, &def))

{

printf ("Cannot get the speed\n");

return 0;

}

else

{

printf ("Current %d, Default %d\n", cur, def);

}

}

0 Likes

Hi Olivier,

to get high clocks from the beginning I would recommend you to set the performance levels using the ADL_Overdrive5_ODPerformanceLevels_Set function. The code below will copy the clock setting of the high profile to all other profiles. After having done this you will have high clocks.

bool setPerfLevel(unsigned int uiAdapterIdx, bool bHeigh = false)

{

      ADLODParameters ODParam;

      ODParam.iSize = sizeof(ADLODParameters);

 
      ADL_Overdrive5_ODParameters_Get(uiAdapterIdx, &ODParam);

     if (ODParam.iNumberOfPerformanceLevels > 0)

     {

        unsigned int uiSize = sizeof(ADLODPerformanceLevels) + (sizeof(ADLODPerformanceLevel) * ODParam.iNumberOfPerformanceLevels - 1));

        ADLODPerformanceLevels* PerfLevels = (ADLODPerformanceLevels*)malloc(uiSize);

                               

        PerfLevels->iSize = uiSize;

    

        ADL_Overdrive5_ODPerformanceLevels_Get(uiAdapterIdx,1, PerfLevels);

        for (int i = 0; bHeigh && i < ODParam.iNumberOfPerformanceLevels - 1 ; ++i)

        {

             PerfLevels->aLevels.iEngineClock = PerfLevels->aLevels[ODParam.iNumberOfPerformanceLevels-1].iEngineClock;         
             PerfLevels->aLevels.iMemoryClock = PerfLevels->aLevels[ODParam.iNumberOfPerformanceLevels-1].iMemoryClock;

             PerfLevels->aLevels.iVddc   = PerfLevels->aLevels[ODParam.iNumberOfPerformanceLevels-1].iVddc;

        }

    

        int nStatus = ADL_Overdrive5_ODPerformanceLevels_Set(uiAdapterIdx, PerfLevels);

    

        free(PerfLevels);

        if ( nStatus == ADL_OK)

       {

             return true;

        }

    }

    

    return false;

}

Chris

0 Likes

Hi Chris,

I am sorry but you got me confused. I don’t know what a profile is (Could you point me to some documentation where the whole concept of the overdrive is explained?). What we are trying to do is pretty simple:

- Other application can keep the FirePro run at any level before the image processing is invoked. Some application may require higher clock frequencies some may be happy with lower ones,

- Just before the image processing starts we would like to crank up the clock to nominal high, i.e. no overclocking,

- When the processing is done, we’d like to return the FirePro to its clock state before we started processing.

This is pretty lean and mean, and that is why we opted for the straightforward calls to ADL_Adapter_Speed_Get() and ADL_Adapter_Speed_Set(). But they do not seem to work the way we expected. Can you advise?

Best regards.

Olivier

0 Likes

Hi Olivier,

the GPU has multiple performance levels. Each level defines the clock frequency that should be used. Depending on the load that is detected on the GPU the performance level changes. If the GPU is idle the lowest performance level is active. This one runs the engine and memory clock at low frequency.If you application starts processing after an idle period it will take some time for the GPU to detect the load and to switch to the next performance level. If you want to avoid the ramp up time the GPU needs to detect the load and to switch to the next performance level you should adapt the clocks of the lower performance level. In your case the application can copy the clock settings of the highest performance level to all other before its actually starts the processing. You can do this with the code I sent you. After the processing is finished you can reset the clocks. Since the clock speeds are related to a performance level you should need to change the settings of the performance level and not the clock settings directly.

Chris