Skip to content

Instantly share code, notes, and snippets.

@iuridiniz
Last active April 7, 2021 11:23
Show Gist options
  • Save iuridiniz/16df9ac9149c5063907e6eff5c44e28b to your computer and use it in GitHub Desktop.
Save iuridiniz/16df9ac9149c5063907e6eff5c44e28b to your computer and use it in GitHub Desktop.
overclock nvidia (reverse engineering)
/*
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
*/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
typedef unsigned long NvU32;
typedef struct {
NvU32 version;
NvU32 ClockType:2;
NvU32 reserved:22;
NvU32 reserved1:8;
struct {
NvU32 bIsPresent:1;
NvU32 reserved:31;
NvU32 frequency;
}domain[32];
} NV_GPU_CLOCK_FREQUENCIES_V2;
typedef struct {
int value;
struct {
int mindelta;
int maxdelta;
} valueRange;
} NV_GPU_PERF_PSTATES20_PARAM_DELTA;
typedef struct {
NvU32 domainId;
NvU32 typeId;
NvU32 bIsEditable:1;
NvU32 reserved:31;
NV_GPU_PERF_PSTATES20_PARAM_DELTA freqDelta_kHz;
union {
struct {
NvU32 freq_kHz;
} single;
struct {
NvU32 minFreq_kHz;
NvU32 maxFreq_kHz;
NvU32 domainId;
NvU32 minVoltage_uV;
NvU32 maxVoltage_uV;
} range;
} data;
} NV_GPU_PSTATE20_CLOCK_ENTRY_V1;
typedef struct {
NvU32 domainId;
NvU32 bIsEditable:1;
NvU32 reserved:31;
NvU32 volt_uV;
int voltDelta_uV;
} NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1;
typedef struct {
NvU32 version;
NvU32 bIsEditable:1;
NvU32 reserved:31;
NvU32 numPstates;
NvU32 numClocks;
NvU32 numBaseVoltages;
struct {
NvU32 pstateId;
NvU32 bIsEditable:1;
NvU32 reserved:31;
NV_GPU_PSTATE20_CLOCK_ENTRY_V1 clocks[8];
NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1 baseVoltages[4];
} pstates[16];
} NV_GPU_PERF_PSTATES20_INFO_V1;
typedef void *(*NvAPI_QueryInterface_t)(unsigned int offset);
typedef int (*NvAPI_Initialize_t)();
typedef int (*NvAPI_Unload_t)();
typedef int (*NvAPI_EnumPhysicalGPUs_t)(int **handles, int *count);
typedef int (*NvAPI_GPU_GetSystemType_t)(int *handle, int *systype);
typedef int (*NvAPI_GPU_GetFullName_t)(int *handle, char *sysname);
typedef int (*NvAPI_GPU_GetPhysicalFrameBufferSize_t)(int *handle, int *memsize);
typedef int (*NvAPI_GPU_GetRamType_t)(int *handle, int *memtype);
typedef int (*NvAPI_GPU_GetVbiosVersionString_t)(int *handle, char *biosname);
typedef int (*NvAPI_GPU_GetAllClockFrequencies_t)(int *handle, NV_GPU_PERF_PSTATES20_INFO_V1 *pstates_info);
typedef int (*NvAPI_GPU_GetPstates20_t)(int *handle, NV_GPU_PERF_PSTATES20_INFO_V1 *pstates_info);
typedef int (*NvAPI_GPU_SetPstates20_t)(int *handle, int *pstates_info);
NvAPI_QueryInterface_t NvQueryInterface = 0;
NvAPI_Initialize_t NvInit = 0;
NvAPI_Unload_t NvUnload = 0;
NvAPI_EnumPhysicalGPUs_t NvEnumGPUs = 0;
NvAPI_GPU_GetSystemType_t NvGetSysType = 0;
NvAPI_GPU_GetFullName_t NvGetName = 0;
NvAPI_GPU_GetPhysicalFrameBufferSize_t NvGetMemSize = 0;
NvAPI_GPU_GetRamType_t NvGetMemType = 0;
NvAPI_GPU_GetVbiosVersionString_t NvGetBiosName = 0;
NvAPI_GPU_GetAllClockFrequencies_t NvGetFreq = 0;
NvAPI_GPU_GetPstates20_t NvGetPstates = 0;
NvAPI_GPU_SetPstates20_t NvSetPstates = 0;
int main(int argc, char **argv)
{
int nGPU=0, userfreq = 0, systype=0, memsize=0, memtype=0;
int *hdlGPU[64]={0}, *buf=0;
char sysname[64]={0}, biosname[64]={0};
NV_GPU_PERF_PSTATES20_INFO_V1 pstates_info;
pstates_info.version = 0x11c94;
NvQueryInterface = (void*)GetProcAddress(LoadLibrary("nvapi.dll"), "nvapi_QueryInterface");
NvInit = NvQueryInterface(0x0150E828);
NvUnload = NvQueryInterface(0xD22BDD7E);
NvEnumGPUs = NvQueryInterface(0xE5AC921F);
NvGetSysType = NvQueryInterface(0xBAAABFCC);
NvGetName = NvQueryInterface(0xCEEE8E9F);
NvGetMemSize = NvQueryInterface(0x46FBEB03);
NvGetMemType = NvQueryInterface(0x57F7CAAC);
NvGetBiosName = NvQueryInterface(0xA561FD7D);
NvGetFreq = NvQueryInterface(0xDCB616C3);
NvGetPstates = NvQueryInterface(0x6FF81213);
NvSetPstates = NvQueryInterface(0x0F4DAE6B);
NvInit();
NvEnumGPUs(hdlGPU, &nGPU);
NvGetSysType(hdlGPU[0], &systype);
NvGetName(hdlGPU[0], sysname);
NvGetMemSize(hdlGPU[0], &memsize);
NvGetMemType(hdlGPU[0], &memtype);
NvGetBiosName(hdlGPU[0], biosname);
NvGetPstates(hdlGPU[0], &pstates_info);
switch(systype){
case 1: printf("\nType: Laptop\n"); break;
case 2: printf("\nType: Desktop\n"); break;
default: printf("\nType: Unknown\n"); break;
}
printf("Name: %s\n", sysname);
printf("VRAM: %dMB GDDR%d\n", memsize/1024, memtype<=7?3:5);
printf("BIOS: %s\n", biosname);
printf("\nGPU: %dMHz\n", (int)((pstates_info.pstates[0].clocks[0]).data.range.maxFreq_kHz)/1000);
printf("RAM: %dMHz\n", (int)((pstates_info.pstates[0].clocks[1]).data.single.freq_kHz)/1000);
printf("\nCurrent GPU OC: %dMHz\n", (int)((pstates_info.pstates[0].clocks[0]).freqDelta_kHz.value)/1000);
printf("Current RAM OC: %dMHz\n", (int)((pstates_info.pstates[0].clocks[1]).freqDelta_kHz.value)/1000);
if(argc > 1){
userfreq = atoi(argv[1])*1000;
if(-250000 <= userfreq && userfreq <= 250000) {
buf = malloc(0x1c94);
memset(buf, 0, 0x1c94);
buf[0] = 0x11c94; buf[2] = 1; buf[3] = 1;
buf[10] = userfreq;
NvSetPstates(hdlGPU[0], buf)? printf("\nGPU OC failed!\n") : printf("\nGPU OC OK: %d MHz\n", userfreq/1000);
free(buf);
} else {
printf("\nGPU Frequency not in safe range (-250MHz to +250MHz).\n");
return 1;
} }
if(argc > 2){
userfreq = atoi(argv[2])*1000;
if(-250000 <= userfreq && userfreq <= 250000) {
buf = malloc(0x1c94);
memset(buf, 0, 0x1c94);
buf[0] = 0x11c94; buf[2] = 1; buf[3] = 1;
buf[7] = 4; buf[10] = memtype<=7?userfreq:userfreq*2;
NvSetPstates(hdlGPU[0], buf)? printf("VRAM OC failed!\n") : printf("RAM OC OK: %d MHz\n", userfreq/1000);
free(buf);
} else {
printf("\nRAM Frequency not in safe range (-250MHz to +250MHz).\n");
return 1;
} }
NvUnload();
return 0;
}
/*
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>, All rights reserved.
Copyright (C) 2017 Evgeniy Zheltonozhskiy <zheltonozhskiy@gmail.com>, All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* https://1vwjbxf1wko0yhnr.wordpress.com/2015/08/10/overclocking-tools-for-nvidia-gpus-suck-i-made-my-own/ */
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
typedef unsigned long NvU32;
/* data structures we need from the NvAPI headers */
typedef struct {
NvU32 version;
NvU32 ClockType:2;
NvU32 reserved:22;
NvU32 reserved1:8;
struct {
NvU32 bIsPresent:1;
NvU32 reserved:31;
NvU32 frequency;
} domain[32];
} NV_GPU_CLOCK_FREQUENCIES_V2;
typedef struct {
int value;
struct {
int mindelta;
int maxdelta;
} valueRange;
} NV_GPU_PERF_PSTATES20_PARAM_DELTA;
typedef struct {
NvU32 domainId;
NvU32 typeId;
NvU32 bIsEditable:1;
NvU32 reserved:31;
NV_GPU_PERF_PSTATES20_PARAM_DELTA freqDelta_kHz;
union {
struct {
NvU32 freq_kHz;
} single;
struct {
NvU32 minFreq_kHz;
NvU32 maxFreq_kHz;
NvU32 domainId;
NvU32 minVoltage_uV;
NvU32 maxVoltage_uV;
} range;
} data;
} NV_GPU_PSTATE20_CLOCK_ENTRY_V1;
typedef struct {
NvU32 domainId;
NvU32 bIsEditable:1;
NvU32 reserved:31;
NvU32 volt_uV;
int voltDelta_uV;
} NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1;
typedef struct {
NvU32 version;
NvU32 bIsEditable:1;
NvU32 reserved:31;
NvU32 numPstates;
NvU32 numClocks;
NvU32 numBaseVoltages;
struct {
NvU32 pstateId;
NvU32 bIsEditable:1;
NvU32 reserved:31;
NV_GPU_PSTATE20_CLOCK_ENTRY_V1 clocks[8];
NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1 baseVoltages[4];
} pstates[16];
} NV_GPU_PERF_PSTATES20_INFO_V1;
/* prototypes for the functions we’ll use. */
typedef void *(*NvAPI_QueryInterface_t)(unsigned int offset);
typedef int (*NvAPI_Initialize_t)();
typedef int (*NvAPI_Unload_t)();
typedef int (*NvAPI_EnumPhysicalGPUs_t)(int **handles, int *count);
typedef int (*NvAPI_GPU_GetSystemType_t)(int *handle, int *systype);
typedef int (*NvAPI_GPU_GetFullName_t)(int *handle, char *sysname);
typedef int (*NvAPI_GPU_GetPhysicalFrameBufferSize_t)(int *handle, int *memsize);
typedef int (*NvAPI_GPU_GetRamType_t)(int *handle, int *memtype);
typedef int (*NvAPI_GPU_GetVbiosVersionString_t)(int *handle, char *biosname);
typedef int (*NvAPI_GPU_GetAllClockFrequencies_t)(int *handle, NV_GPU_PERF_PSTATES20_INFO_V1 *pstates_info);
typedef int (*NvAPI_GPU_GetPstates20_t)(int *handle, NV_GPU_PERF_PSTATES20_INFO_V1 *pstates_info);
typedef int (*NvAPI_GPU_SetPstates20_t)(int *handle, int *pstates_info);
NvAPI_QueryInterface_t NvQueryInterface = 0;
NvAPI_Initialize_t NvInit = 0;
NvAPI_Unload_t NvUnload = 0;
NvAPI_EnumPhysicalGPUs_t NvEnumGPUs = 0;
NvAPI_GPU_GetSystemType_t NvGetSysType = 0;
NvAPI_GPU_GetFullName_t NvGetName = 0;
NvAPI_GPU_GetPhysicalFrameBufferSize_t NvGetMemSize = 0;
NvAPI_GPU_GetRamType_t NvGetMemType = 0;
NvAPI_GPU_GetVbiosVersionString_t NvGetBiosName = 0;
NvAPI_GPU_GetAllClockFrequencies_t NvGetFreq = 0;
NvAPI_GPU_GetPstates20_t NvGetPstates = 0;
NvAPI_GPU_SetPstates20_t NvSetPstates = 0;
int main(int argc, char **argv) {
int nGPU = 0, userfreq = 0, systype = 0, memsize = 0, memtype = 0;
int *hdlGPU[64] = {0}, *buf = 0;
char sysname[64] = {0}, biosname[64] = {0};
NV_GPU_PERF_PSTATES20_INFO_V1 pstates_info;
pstates_info.version = 0x11c94;
if (!(NvQueryInterface = (void *) GetProcAddress(LoadLibrary("nvapi.dll"), "nvapi_QueryInterface"))
&& !(NvQueryInterface = (void *) GetProcAddress(LoadLibrary("nvapi64.dll"), "nvapi_QueryInterface"))) {
fprintf(stderr, "Can't load nvapi.dll or nvapi64.dll. Error %d", GetLastError());
return -1;
}
NvInit = NvQueryInterface(0x0150E828);
NvUnload = NvQueryInterface(0xD22BDD7E);
NvEnumGPUs = NvQueryInterface(0xE5AC921F);
NvGetSysType = NvQueryInterface(0xBAAABFCC);
NvGetName = NvQueryInterface(0xCEEE8E9F);
NvGetMemSize = NvQueryInterface(0x46FBEB03);
NvGetMemType = NvQueryInterface(0x57F7CAAC);
NvGetBiosName = NvQueryInterface(0xA561FD7D);
NvGetFreq = NvQueryInterface(0xDCB616C3);
NvGetPstates = NvQueryInterface(0x6FF81213);
NvSetPstates = NvQueryInterface(0x0F4DAE6B);
NvInit();
NvEnumGPUs(hdlGPU, &nGPU);
NvGetSysType(hdlGPU[0], &systype);
NvGetName(hdlGPU[0], sysname);
NvGetMemSize(hdlGPU[0], &memsize);
NvGetMemType(hdlGPU[0], &memtype);
NvGetBiosName(hdlGPU[0], biosname);
NvGetPstates(hdlGPU[0], &pstates_info);
switch (systype) {
case 1: printf("\nType: Laptop\n");
break;
case 2: printf("\nType: Desktop\n");
break;
default: printf("\nType: Unknown\n");
break;
}
printf("Name: %s\n", sysname);
printf("VRAM: %dMB GDDR%d\n", memsize / 1024, memtype <= 7 ? 3 : 5);
printf("BIOS: %s\n", biosname);
printf("\nGPU: %dMHz\n", (int) ((pstates_info.pstates[0].clocks[0]).data.range.maxFreq_kHz) / 1000);
printf("RAM: %dMHz\n", (int) ((pstates_info.pstates[0].clocks[1]).data.single.freq_kHz) / 1000);
printf("\nCurrent GPU OC: %dMHz\n", (int) ((pstates_info.pstates[0].clocks[0]).freqDelta_kHz.value) / 1000);
printf("Current RAM OC: %dMHz\n", (int) ((pstates_info.pstates[0].clocks[1]).freqDelta_kHz.value) / 1000);
if (argc > 1) {
userfreq = atoi(argv[1]) * 1000;
if (-250000 <= userfreq && userfreq <= 250000) {
buf = malloc(0x1c94);
memset(buf, 0, 0x1c94);
buf[0] = 0x11c94;
buf[2] = 1;
buf[3] = 1;
buf[10] = userfreq;
NvSetPstates(hdlGPU[0], buf) ? printf("\nGPU OC failed!\n") : printf("\nGPU OC OK: %d MHz\n", userfreq / 1000);
free(buf);
} else {
printf("\nGPU Frequency not in safe range (-250MHz to +250MHz).\n");
return 1;
}
}
if (argc > 2) {
userfreq = atoi(argv[2]) * 1000;
if (-250000 <= userfreq && userfreq <= 250000) {
buf = malloc(0x1c94);
memset(buf, 0, 0x1c94);
buf[0] = 0x11c94;
buf[2] = 1;
buf[3] = 1;
buf[7] = 4;
buf[10] = memtype <= 7 ? userfreq : userfreq * 2;
NvSetPstates(hdlGPU[0], buf) ? printf("VRAM OC failed!\n") : printf("RAM OC OK: %d MHz\n", userfreq / 1000);
free(buf);
} else {
printf("\nRAM Frequency not in safe range (-250MHz to +250MHz).\n");
return 1;
}
}
NvUnload();
return 0;
}
/* from: https://gist.github.com/Randl/a055a45cb6960019e0324130c96123ff */
#include "nvidiaapi.h"
#include <QDebug>
fanSpeedThread::fanSpeedThread(nvidiaAPI *nvapi, QObject */*pParent*/) :
_nvapi(nvapi),
_downLimit(30),
_upLimit(65)
{
}
void fanSpeedThread::run()
{
unsigned int gpuCount = _nvapi->getGPUCount();
while(!_needToStop)
{
int previous = 0;
for(uint i = 0; i < gpuCount; i++)
{
int gpuTemp = _nvapi->getGpuTemperature(i);
if(gpuTemp > _downLimit)
{
float step = 100 / (float)(_upLimit - _downLimit);
float fanLevel = step * (gpuTemp - _downLimit);
if(previous != (int)fanLevel)
{
_nvapi->setFanSpeed(i, (int)fanLevel);
previous = (int)fanLevel;
}
}
}
QThread::sleep(2);
}
}
nvidiaAPI::nvidiaAPI():
QLibrary("nvapi64"),
_gpuHandles{0},
_gpuCount(0),
_libLoaded(false),
NvQueryInterface(NULL),
NvInit(NULL),
NvUnload(NULL),
NvEnumGPUs(NULL),
NvGetSysType(NULL),
NvGetName(NULL),
NvGetMemSize(NULL),
NvGetMemType(NULL),
NvGetBiosName(NULL),
NvGetFreq(NULL),
NvGetPstates(NULL),
NvSetPstates(NULL),
NvGetPStatesInfoEx(NULL),
NvQueryIlluminationSupport(NULL),
NvGetIllumination(NULL),
NvSetIllumination(NULL),
NvGetCoolersSettings(NULL),
NvSetCoolerLevel(NULL),
NvGetThermalSettings(NULL)
{
NvQueryInterface = (NvAPI_QueryInterface_t)resolve("nvapi_QueryInterface");
if(NvQueryInterface)
{
NvInit = (NvAPI_Initialize_t)NvQueryInterface(0x0150E828);
NvUnload = (NvAPI_Unload_t)NvQueryInterface(0xD22BDD7E);
NvEnumGPUs = (NvAPI_EnumPhysicalGPUs_t)NvQueryInterface(0xE5AC921F);
NvGetSysType = (NvAPI_GPU_GetSystemType_t)NvQueryInterface(0xBAAABFCC);
NvGetName = (NvAPI_GPU_GetFullName_t)NvQueryInterface(0xCEEE8E9F);
NvGetMemSize = (NvAPI_GPU_GetPhysicalFrameBufferSize_t)NvQueryInterface(0x46FBEB03);
NvGetMemType = (NvAPI_GPU_GetRamType_t)NvQueryInterface(0x57F7CAAC);
NvGetBiosName = (NvAPI_GPU_GetVbiosVersionString_t)NvQueryInterface(0xA561FD7D);
NvGetFreq = (NvAPI_GPU_GetAllClockFrequencies_t)NvQueryInterface(0xDCB616C3);
NvGetPstates = (NvAPI_GPU_GetPstates20_t)NvQueryInterface(0x6FF81213);
NvSetPstates = (NvAPI_GPU_SetPstates20_t)NvQueryInterface(0x0F4DAE6B);
NvGetPStatesInfoEx = (NvAPI_GPU_GetPstatesInfoEx_t)NvQueryInterface(0x843C0256);
NvClientPowerPoliciesGetStatus = (NvAPI_DLL_ClientPowerPoliciesGetStatus_t)NvQueryInterface(0x70916171);
NvClientPowerPoliciesGetInfo = (NvAPI_DLL_ClientPowerPoliciesGetInfo_t)NvQueryInterface(0x34206D86);
NvClientPowerPoliciesSetStatus = (NvAPI_DLL_ClientPowerPoliciesSetStatus_t)NvQueryInterface(0xAD95F5ED);
//let's have some fun with LED
NvQueryIlluminationSupport = (NvAPI_GPU_QueryIlluminationSupport_t)NvQueryInterface(0xA629DA31);
NvGetIllumination = (NvAPI_GPU_GetIllumination_t)NvQueryInterface(0x9A1B9365);
NvSetIllumination = (NvAPI_GPU_SetIllumination_t)NvQueryInterface(0x254A187);
NvGetCoolersSettings = (NvAPI_GPU_GetCoolersSettings_t)NvQueryInterface(0xDA141340);
NvSetCoolerLevel = (NvAPI_GPU_SetCoolerLevel_t)NvQueryInterface(0x891FA0AE);
NvGetThermalSettings = (NvAPI_GPU_GetThermalSettings_t)NvQueryInterface(0xE3640A56);
NvAPI_Status ret = NvInit();
qDebug() << "NVAPI success " << ret;
_libLoaded = true;
}
}
nvidiaAPI::~nvidiaAPI()
{
}
unsigned int nvidiaAPI::getGPUCount()
{
NvEnumGPUs(_gpuHandles, &_gpuCount);
return _gpuCount;
}
void nvidiaAPI::setLED(unsigned int gpu, int color)
{
NvAPI_Status ret = NVAPI_OK;
NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM illu;
illu.bSupported = false;
illu.version = NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM_VER;
illu.hPhysicalGpu = _gpuHandles[gpu];
illu.Attribute = NV_GPU_IA_LOGO_BRIGHTNESS;
ret = NvQueryIlluminationSupport(&illu);
if (!ret && illu.bSupported)
{
NV_GPU_GET_ILLUMINATION_PARM led;
led.version = NV_GPU_GET_ILLUMINATION_PARM_VER;
led.hPhysicalGpu = _gpuHandles[gpu];
led.Attribute = NV_GPU_IA_LOGO_BRIGHTNESS;
NvGetIllumination(&led);
qDebug( "GPU %x: Led level was %d, set to %d", (int) _gpuHandles[gpu], led.Value, color);
led.Value = (uint32_t) color;
ret = NvSetIllumination((NV_GPU_SET_ILLUMINATION_PARM*)&led);
}
else
{
qDebug() << "Unsupported device";
}
}
int nvidiaAPI::getGpuTemperature(unsigned int gpu)
{
NvAPI_Status ret;
NV_GPU_THERMAL_SETTINGS thermal = {0};
// thermal.version = NV_GPU_THERMAL_SETTINGS_VER;
thermal.version = NV_GPU_THERMAL_SETTINGS_VER;
thermal.sensor[0].controller = NVAPI_THERMAL_CONTROLLER_GPU_INTERNAL;
thermal.sensor[0].target = NVAPI_THERMAL_TARGET_GPU;
ret = NvGetThermalSettings(_gpuHandles[gpu], 0, &thermal);
if (ret != NVAPI_OK)
{
qDebug() << "NVAPI NvAPI_GPU_GetThermalSettings error " << ret;
return -1;
}
return thermal.sensor[0].currentTemp;
}
int nvidiaAPI::getGPUOffset(unsigned int gpu)
{
NvAPI_Status ret;
NV_GPU_PERF_PSTATES20_INFO pset1 = { 0 };
pset1.version = NV_GPU_PERF_PSTATES20_INFO_VER1;
pset1.numPstates = 1;
pset1.numClocks = 1;
// Ok on both 1080 and 970
pset1.pstates[0].clocks[0].domainId = NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS;
ret = NvGetPstates(_gpuHandles[gpu], &pset1);
if (ret == NVAPI_OK) {
return pset1.pstates[0].clocks[0].freqDelta_kHz.value / 1000;
}
return 0;
}
int nvidiaAPI::getMemOffset(unsigned int gpu)
{
NvAPI_Status ret;
NV_GPU_PERF_PSTATES20_INFO pset1 = { 0 };
pset1.version = NV_GPU_PERF_PSTATES20_INFO_VER1;
pset1.numPstates = 1;
pset1.numClocks = 1;
// Ok on both 1080 and 970
pset1.pstates[0].clocks[0].domainId = NVAPI_GPU_PUBLIC_CLOCK_MEMORY;
ret = NvGetPstates(_gpuHandles[gpu], &pset1);
if (ret == NVAPI_OK) {
return pset1.pstates[0].clocks[1].freqDelta_kHz.value / 1000;
}
return 0;
}
unsigned int nvidiaAPI::getGpuClock(unsigned int gpu)
{
NvAPI_Status ret = NVAPI_OK;
unsigned int freq = 0;
NV_GPU_CLOCK_FREQUENCIES freqs = { 0 };
freqs.version = NV_GPU_CLOCK_FREQUENCIES_VER;
freqs.ClockType = NV_GPU_CLOCK_FREQUENCIES_CURRENT_FREQ;
ret = NvGetFreq(_gpuHandles[gpu], &freqs);
if (ret == NVAPI_OK) {
freq = freqs.domain[NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS].frequency / 1000;
}
return freq; // in MHz
}
unsigned int nvidiaAPI::getPowerLimit(unsigned int gpu)
{
NvAPI_Status ret = NVAPI_OK;
NVAPI_GPU_POWER_STATUS pol = { 0 };
pol.version = NVAPI_GPU_POWER_STATUS_VER;
if ((ret = NvClientPowerPoliciesGetStatus(_gpuHandles[gpu], &pol)) != NVAPI_OK)
{
qDebug() << "error";
return 0;
}
return (uint8_t) (pol.entries[0].power / 1000); // in percent
}
unsigned int nvidiaAPI::getFanSpeed(unsigned int gpu)
{
NV_GPU_COOLER_SETTINGS coolerSettings;
coolerSettings.version = NV_GPU_COOLER_SETTINGS_VER;
NvAPI_Status ret = NvGetCoolersSettings(_gpuHandles[gpu], 0, &coolerSettings);
if(ret == NVAPI_OK)
{
return coolerSettings.cooler[0].currentLevel;
}
return 0;
}
int nvidiaAPI::setPowerLimitPercent(unsigned int gpu, unsigned int percent)
{
NvAPI_Status ret = NVAPI_OK;
uint32_t val = percent * 1000;
NVAPI_GPU_POWER_INFO nfo = { 0 };
nfo.version = NVAPI_GPU_POWER_INFO_VER;
ret = NvClientPowerPoliciesGetInfo(_gpuHandles[gpu], &nfo);
if (ret == NVAPI_OK) {
if (val == 0)
val = nfo.entries[0].def_power;
else if (val < nfo.entries[0].min_power)
val = nfo.entries[0].min_power;
else if (val > nfo.entries[0].max_power)
val = nfo.entries[0].max_power;
}
NVAPI_GPU_POWER_STATUS pol = { 0 };
pol.version = NVAPI_GPU_POWER_STATUS_VER;
pol.flags = 1;
pol.entries[0].power = val;
if ((ret = NvClientPowerPoliciesSetStatus(_gpuHandles[gpu], &pol)) != NVAPI_OK)
{
return -1;
}
return ret;
}
int nvidiaAPI::setMemClockOffset(unsigned int gpu, int clock)
{
NvAPI_Status ret;
NvS32 deltaKHz = clock * 1000;
// todo: bounds check with GetPstates20
NV_GPU_PERF_PSTATES20_INFO_V1 pset1 = { 0 };
pset1.version = NV_GPU_PERF_PSTATES20_INFO_VER1;
pset1.numPstates = 1;
pset1.numClocks = 1;
pset1.pstates[0].clocks[0].domainId = NVAPI_GPU_PUBLIC_CLOCK_MEMORY;
pset1.pstates[0].clocks[0].freqDelta_kHz.value = deltaKHz;
ret = NvSetPstates(_gpuHandles[gpu], &pset1);
if (ret == NVAPI_OK)
qDebug("GPU #%u: Memory clock offset set to %+d MHz", gpu, deltaKHz / 1000);
return ret;
}
int nvidiaAPI::setGPUOffset(unsigned int gpu, int offset)
{
NvAPI_Status ret;
NvS32 deltaKHz = offset * 1000;
NV_GPU_PERF_PSTATES20_INFO_V1 pset1 = { 0 };
pset1.version = NV_GPU_PERF_PSTATES20_INFO_VER1;
pset1.numPstates = 1;
pset1.numClocks = 1;
pset1.pstates[0].clocks[0].domainId = NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS;
pset1.pstates[0].clocks[0].freqDelta_kHz.value = deltaKHz;
ret = NvSetPstates(_gpuHandles[gpu], &pset1);
if (ret == NVAPI_OK) {
qDebug("GPU #%u: pu clock offset set to %d MHz", gpu, deltaKHz/1000);
}
return ret;
}
int nvidiaAPI::setTempLimitOffset(unsigned int gpu, unsigned int offset)
{
return 0;
}
int nvidiaAPI::setFanSpeed(unsigned int gpu, unsigned int percent)
{
NV_GPU_COOLER_LEVELS coolerLvl;
coolerLvl.cooler[0].policy = 1;
coolerLvl.version = NV_GPU_COOLER_LEVELS_VER;
coolerLvl.cooler[0].level = percent;
NvAPI_Status ret = NvSetCoolerLevel(_gpuHandles[gpu], 0, &coolerLvl);
return ret;
}
void nvidiaAPI::setAllLED(int color)
{
for(unsigned int i = 0; i < _gpuCount; i++)
setLED(i, color);
}
void nvidiaAPI::startFanThread()
{
//if(!_fanThread->isRunning())
_fanThread = new fanSpeedThread(this);
connect(_fanThread, SIGNAL(finished()), _fanThread, SLOT(deleteLater()));
connect(this, SIGNAL(stopFanThrdSignal()), _fanThread, SLOT(onStop()));
_fanThread->start();
}
void nvidiaAPI::stopFanThread()
{
//if(_fanThread->isRunning())
emit stopFanThrdSignal();
while(_fanThread->isRunning()) QThread::msleep(10);
disconnect(this, SIGNAL(stopFanThrdSignal()), _fanThread, SLOT(onStop()));
}
/* from: https://github.com/orkblutt/MinerLamp */
@iuridiniz
Copy link
Author

FROM: OVERCLOCKING TOOLS FOR NVIDIA GPUS SUCK, I MADE MY OWN

USAGE:

C:\>overclock.exe    [+/- GPU MHz offset]    [+/- RAM MHz offset]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment