秋筱Autbam
秋筱Autbam

Reputation: 11

NVAPI problem return INCOMPATIBLE_STRUCT_VERSION

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

Answers (1)

Justin Smyth
Justin Smyth

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

Related Questions