Reputation: 11
I am using NVAPI.dll to change gpu's core clock. using NvAPI_GPU_SetPstates20 function in nvapi.dll The struct in C# for nvapi.dll is this:
[StructLayout(LayoutKind.Explicit, Pack = 8)]
internal struct dataStruct
{
[FieldOffset(0)]
public singleStruct single;
[FieldOffset(0)]
public rangeStruct range;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct valuerange
{
public int min;
public int max;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY
{
public uint domainId;
public uint editable;//1
public uint reserved;//31
public uint voltageUV;
public NV_GPU_PERF_PSTATES20_PARAM_DELTA voltageDeltaUV;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NV_GPU_PERF_PSTATES20_PARAM_DELTA
{
public int value;
public valuerange valueRanges;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct pstateStruct
{
public uint pStateId;
public uint editable;//1
public uint reserved;//31
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public NV_GPU_PSTATE20_CLOCK_ENTRY[]clocks;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY[]baseVoltages;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct singleStruct
{
public uint frequencyKHz;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct rangeStruct
{
public uint minFrequencyKHz;
public uint maxFrequencyKHz;
public uint domainId;
public uint minVoltageUV;
public uint maxVoltageUV;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct overVoltageStruct
{
public uint numVoltages;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY []voltages;//[4]
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NV_GPU_PSTATE20_CLOCK_ENTRY
{
public uint domainId;
public uint typeId;
public uint editable;//1
public uint reserved;//31
public NV_GPU_PERF_PSTATES20_PARAM_DELTA frequencyDeltaKHz;
public dataStruct data;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NV_GPU_PERF_PSTATES20_INFO
{
public uint version;
public uint editable;//1
public uint reserved;//31
public uint numPStates;
public uint numClocks;
public uint numBaseVoltages;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public pstateStruct[] pStates;
public overVoltageStruct overVoltage;
}
This is my function:
public static void SetCoreClock(NvPhysicalGpuHandle handle,int clock)
{
NV_GPU_PERF_PSTATES20_INFO pStatesInfo=new NV_GPU_PERF_PSTATES20_INFO();
pStatesInfo.version = (uint) Marshal.SizeOf(typeof(NV_GPU_PERF_PSTATES20_INFO)) | 0x10000;
pStatesInfo.numPStates = 1;
pStatesInfo.numClocks = 1;
pStatesInfo.editable = 1;
pStatesInfo.reserved = 31;
pStatesInfo.pStates = new pstateStruct[16];
pStatesInfo.overVoltage.voltages = new NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY[4];
pStatesInfo.pStates[0].baseVoltages = new NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY[4];
pStatesInfo.pStates[0].clocks = new NV_GPU_PSTATE20_CLOCK_ENTRY[8];
pStatesInfo.pStates[0].clocks[0].editable = 1;
pStatesInfo.pStates[0].clocks[0].reserved = 31;
pStatesInfo.pStates[0].pStateId = 0;
pStatesInfo.pStates[0].clocks[0].domainId = 0;
pStatesInfo.pStates[0].clocks[0].typeId = 0;
pStatesInfo.pStates[0].clocks[0].frequencyDeltaKHz.value = clock;
pStatesInfo.pStates[0].clocks[0].frequencyDeltaKHz.valueRanges.max = 0;
pStatesInfo.pStates[0].clocks[0].frequencyDeltaKHz.valueRanges.min = 0;
a = NVAPI.NvAPI_GPU_SetPstates20(handle,ref pStatesInfo);
}
when I run the function "SetCoreClock". The value a return "INCOMPATIBLE_STRUCT_VERSION". Is my struct wrong? I found a C++ code. the code's struct is:
struct NV_GPU_PERF_PSTATES20_PARAM_DELTA
{
int value;
struct
{
int min;
int max;
} valueRange;
};
struct NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY
{
unsigned int domainId;
unsigned int editable : 1;
unsigned int reserved : 31;
unsigned int voltageUV;
NV_GPU_PERF_PSTATES20_PARAM_DELTA voltageDeltaUV;
};
struct NV_GPU_PSTATE20_CLOCK_ENTRY
{
unsigned int domainId;
unsigned int typeId;
unsigned int editable : 1;
unsigned int reserved : 31;
NV_GPU_PERF_PSTATES20_PARAM_DELTA frequencyDeltaKHz;
union
{
struct
{
unsigned int frequencyKHz;
} single;
struct
{
unsigned int minFrequencyKHz;
unsigned int maxFrequencyKHz;
unsigned int domainId;
unsigned int minVoltageUV;
unsigned int maxVoltageUV;
} range;
} data;
};
struct NV_GPU_PERF_PSTATES20_INFO
{
unsigned int version;
unsigned int editable : 1;
unsigned int reserved : 31;
unsigned int numPStates;
unsigned int numClocks;
unsigned int numBaseVoltages;
struct
{
unsigned int pStateId;
unsigned int editable : 1;
unsigned int reserved : 31;
NV_GPU_PSTATE20_CLOCK_ENTRY clocks[8];
NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY baseVoltages[4];
} pStates[16];
struct
{
unsigned int numVoltages;
NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY voltages[4];
} overVoltage;
};```
Thanks for helping me solved the problem.
Upvotes: 1
Views: 344
Reputation: 1
it means you have the struct the incorrect size. a example I found said the version should be 0x11c94
. things like reserved IMHO need to be removed. I had same issue and I did this to find the version:
uint GPUVER3 = (uint)Marshal.SizeOf(typeof(NV_GPU_PERF_PSTATES20_INFO_V1)) | 0x20000;
Once you get the version the same as 0x11c94
it should work.
C code I used to work this out
https://github.com/suppai/nvidia-overclock
Upvotes: 0