Autor Beitrag
LittleBen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 258
Erhaltene Danke: 4

Win 7, Mac OS
Delphi 7
BeitragVerfasst: Mo 31.12.12 12:24 
Hallo,
seit Weihnachten bin ich der glückliche Besitzer einer GTX 680er Grafikkarte von Nvidia. Nun arbeite ich daran, mir ein kleines Programm zu schreiben, dass die wichtigsten Daten erfasst und auf einem selbst gebauten Display ausgibt. Nach Recherchen habe ich herausgefunden, dass man dafür die von Nvidia mitgeliefert NvApi.dll benötigt. Auf der Embarcadero-Seite habe ich dann die Header von den Funktionen dieser Dll in Delphi gefunden ->
cc.embarcadero.com/Download.aspx?id=26524
Doch leider musste ich feststellen, dass die Sammlung nicht vollständig ist...Direkt von Nvidia bekommt man die Header in C. Habe mir dann die Datei heruntergeladen (developer.download.n...I-R304-developer.zip) und verglichen. Z.B. brauche ich noch die Funktion zum Auslesen der Lüfterrotation.
ausblenden Quelltext
1:
NVAPI_INTERFACE NvAPI_GPU_GetTachReading(NvPhysicalGpuHandle hPhysicalGPU, NvU32 *pValue);					

So sieht der Header dafür in C aus. Soweit kein Problem, muss halt noch in Delphi übersetzt werden.
Wo mein Problem liegt:
In der NvApi.pas hat der Autor zum Schluss alle Funktionen in ein Record gespeichert, mit ID.
Aber woher hat er die ID!? Hier mal der Code-Ausschnitt:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
type
  PNvAPIFuncRec = ^TNvAPIFuncRec;
  TNvAPIFuncRec = record
    ID: Cardinal;
    Func: Pointer;
  end;

const
  NvAPIFunctions: array[0..63of TNvAPIFuncRec = (
    (ID: $6C2D048C; Func: @@NvAPI_GetErrorMessage),
    (ID: $01053FA5; Func: @@NvAPI_GetInterfaceVersionString),
    (ID: $F951A4D1; Func: @@NvAPI_GetDisplayDriverVersion),
    (ID: $9ABDD40D; Func: @@NvAPI_EnumNvidiaDisplayHandle),
    (ID: $20DE9260; Func: @@NvAPI_EnumNvidiaUnAttachedDisplayHandle),
    (ID: $E5AC921F; Func: @@NvAPI_EnumPhysicalGPUs),
    (ID: $48B3EA59; Func: @@NvAPI_EnumLogicalGPUs),
    (ID: $34EF9506; Func: @@NvAPI_GetPhysicalGPUsFromDisplay),
    (ID: $5018ED61; Func: @@NvAPI_GetPhysicalGPUFromUnAttachedDisplay),
    (ID: $63F9799E; Func: @@NvAPI_CreateDisplayFromUnAttachedDisplay),
    (ID: $EE1370CF; Func: @@NvAPI_GetLogicalGPUFromDisplay),
    (ID: $ADD604D1; Func: @@NvAPI_GetLogicalGPUFromPhysicalGPU),
    (ID: $AEA3FA32; Func: @@NvAPI_GetPhysicalGPUsFromLogicalGPU),
    (ID: $35C29134; Func: @@NvAPI_GetAssociatedNvidiaDisplayHandle),
    (ID: $22A78B05; Func: @@NvAPI_GetAssociatedNvidiaDisplayName),
    (ID: $4888D790; Func: @@NvAPI_GetUnAttachedAssociatedDisplayName),
    (ID: $2863148D; Func: @@NvAPI_EnableHWCursor),
    (ID: $AB163097; Func: @@NvAPI_DisableHWCursor),
    (ID: $67B5DB55; Func: @@NvAPI_GetVBlankCounter),
    (ID: $3092AC32; Func: @@NvAPI_SetRefreshRateOverride),
    (ID: $D995937E; Func: @@NvAPI_GetAssociatedDisplayOutputId),
    (ID: $C64FF367; Func: @@NvAPI_GetDisplayPortInfo),
    (ID: $FA13E65A; Func: @@NvAPI_SetDisplayPort),
    (ID: $6AE16EC3; Func: @@NvAPI_GetHDMISupportInfo),
    (ID: $7D554F8E; Func: @@NvAPI_GPU_GetAllOutputs),
    (ID: $1730BFC9; Func: @@NvAPI_GPU_GetConnectedOutputs),
    (ID: $0680DE09; Func: @@NvAPI_GPU_GetConnectedSLIOutputs),
    (ID: $CF8CAF39; Func: @@NvAPI_GPU_GetConnectedOutputsWithLidState),
    (ID: $96043CC7; Func: @@NvAPI_GPU_GetConnectedSLIOutputsWithLidState),
    (ID: $BAAABFCC; Func: @@NvAPI_GPU_GetSystemType),
    (ID: $E3E89B6F; Func: @@NvAPI_GPU_GetActiveOutputs),
    (ID: $37D32E69; Func: @@NvAPI_GPU_GetEDID),
    (ID: $40A505E4; Func: @@NvAPI_GPU_GetOutputType),
    (ID: $34C9C2D4; Func: @@NvAPI_GPU_ValidateOutputCombination),
    (ID: $CEEE8E9F; Func: @@NvAPI_GPU_GetFullName),
    (ID: $2DDFB66E; Func: @@NvAPI_GPU_GetPCIIdentifiers),
    (ID: $C33BAEB1; Func: @@NvAPI_GPU_GetGPUType),
    (ID: $1BB18724; Func: @@NvAPI_GPU_GetBusType),
    (ID: $1BE0B8E5; Func: @@NvAPI_GPU_GetBusId),
    (ID: $2A0A350F; Func: @@NvAPI_GPU_GetBusSlotId),
    (ID: $E4715417; Func: @@NvAPI_GPU_GetIRQ),
    (ID: $ACC3DA0A; Func: @@NvAPI_GPU_GetVbiosRevision),
    (ID: $2D43FB31; Func: @@NvAPI_GPU_GetVbiosOEMRevision),
    (ID: $A561FD7D; Func: @@NvAPI_GPU_GetVbiosVersionString),
    (ID: $6E042794; Func: @@NvAPI_GPU_GetAGPAperture),
    (ID: $C74925A0; Func: @@NvAPI_GPU_GetCurrentAGPRate),
    (ID: $D048C3B1; Func: @@NvAPI_GPU_GetCurrentPCIEDownstreamWidth),
    (ID: $46FBEB03; Func: @@NvAPI_GPU_GetPhysicalFrameBufferSize),
    (ID: $5A04B644; Func: @@NvAPI_GPU_GetVirtualFrameBufferSize),
    (ID: $E3640A56; Func: @@NvAPI_GPU_GetThermalSettings),
    (ID: $2FDE12C5; Func: @@NvAPI_I2CRead),
    (ID: $E812EB07; Func: @@NvAPI_I2CWrite),
    (ID: $53DABBCA; Func: @@_NvAPI_SYS_GetChipSetInfo),
    (ID: $CDA14D8A; Func: @@NvAPI_SYS_GetLidAndDockInfo),
    (ID: $3805EF7A; Func: @@NvAPI_OGL_ExpertModeSet),
    (ID: $22ED9516; Func: @@NvAPI_OGL_ExpertModeGet),
    (ID: $B47A657E; Func: @@NvAPI_OGL_ExpertModeDefaultsSet),
    (ID: $AE921F12; Func: @@NvAPI_OGL_ExpertModeDefaultsGet),
    (ID: $0957D7B6; Func: @@NvAPI_SetView),
    (ID: $D6B99D89; Func: @@NvAPI_GetView),
    (ID: $06B89E68; Func: @@NvAPI_SetViewEx),
    (ID: $DBBC0AF4; Func: @@NvAPI_GetViewEx),
    (ID: $66FB7FC0; Func: @@NvAPI_GetSupportedViews),

    (ID: 0; Func: nil// stop signal
  );

function NotImplemented: NvAPI_Status; cdecl;
begin
  Result := NVAPI_NO_IMPLEMENTATION;
end;

function NvAPI_Initialize;
const
  NvAPILib = 'nvapi.dll';
  NvAPI_ID_INIT = $0150E828;
var
  Lib: THandle;
  nvapi_QueryInterface: function(ID: LongWord): Pointer; cdecl;
  InitFunc: function: Integer; stdcall;
  P: Pointer;
  Rec: PNvAPIFuncRec;
begin
  if Initialized then
  begin
    Result := NVAPI_OK;
    Exit;
  end;

  Lib := LoadLibrary(NvAPILib);
  if Lib <> 0 then
  begin
    nvapi_QueryInterface := GetProcAddress(Lib, 'nvapi_QueryInterface');
    Result := NVAPI_ERROR;
    if Assigned(nvapi_QueryInterface) then
    begin
      InitFunc := nvapi_QueryInterface(NvAPI_ID_INIT);
      if Assigned(InitFunc) then
      begin
        if InitFunc() >= 0 then
        begin
          { Initialize all function pointers }
          Rec := @NvAPIFunctions;
          while Rec.ID <> 0 do
          begin
            PPointer(Rec.Func)^ := @NotImplemented;
            P := nvapi_QueryInterface(Rec.ID);
            if P <> nil then
              PPointer(Rec.Func)^ := P;
            Inc(Rec);
          end;
          Result := NVAPI_OK;
        end;
      end;
    end;
  end
  else
    Result := NVAPI_LIBRARY_NOT_FOUND;

  Initialized := Result = NVAPI_OK;
end;

end.

Ich habe keine Ahnung, woher die ID kommt....
Kann mir da jemand helfen?

Viele Grüße und einen guten Rutsch ins neue Jahr!
Littleben
Gerd Kayser
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 632
Erhaltene Danke: 121

Win 7 32-bit
Delphi 2006/XE
BeitragVerfasst: Mo 31.12.12 12:53 
Vielleicht hilft Dir das hier weiter: www.forum-3dcenter.o...ex.php/t-517614.html
LittleBen Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 258
Erhaltene Danke: 4

Win 7, Mac OS
Delphi 7
BeitragVerfasst: Mo 31.12.12 16:36 
Vielen Dank für den Tipp. Die seite hat mir zwar nicht direkt weiter geholfen, habe dann aber nochmal noch ein den IDs recherchiert. Dabei bin ich auf folgende Seite gekommen: code.google.com/p/op...vidia/NVAPI.cs?r=382. Dort finden sich so die wichtigsten Funktion, die noch nicht in der NvApi.pas vorhanden sind. Doch auch hier gibt es für mich ein Problem, denn der Code ist in C# geschrieben und habe davon keine Ahnung...genauer gesagt betrifft es nur die Records, die ich in Delphi umschreiben muss.
Wenn ich die Funktion NvApi_GPU_GetUsages benutzen will, benötige ich ein Record. Dieses sieht in C# so aus:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
[StructLayout(LayoutKind.Sequential, Pack = 8)]
  internal struct NvUsages {
    public uint Version;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_USAGES_PER_GPU)]
    public uint[] Usage;
  }

Habe es dann einfach mal probiert in Delphi umzuschreiben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
  NV_USAGES = record
    version: NvU32;
    usage: array[0..NVAPI_MAX_USAGES_PER_GPU -1of
      record
        currentUsage: array of NvU32;
      end;
  end;
  TNvUsages = NV_USAGES;
  PNvUsages = ^TNvUsages;

Und die Funktion in C#:
ausblenden C#-Quelltext
1:
2:
public delegate NvStatus NvAPI_GPU_GetUsagesDelegate(
      NvPhysicalGpuHandle gpuHandle, ref NvUsages nvUsages);

Delphi:
ausblenden Delphi-Quelltext
1:
NvAPI_GPU_GetUsages: function(hPhysicalGPU: PNvPhysicalGpuHandle; nvUsages: PNvUsages): NvApi_Status; cdecl;					


Kann mir jemand sagen, was an dem Record falsch ist? Ich habe aus dem public uint[] Usage; einfach ein Array gemacht, da ich nicht genau weiß was uint[] bedeutet. Das ist wahrscheinlich falsch, oder?

EDIT: Der Aufruf sieht so aus:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
procedure TestGPUAPI;
var
  phys  : TNvPhysicalGpuHandleArray;
  log   : TNvLogicalGpuHandleArray;
  cnt   : LongWord;
  i     : Integer;
  name  : NvAPI_ShortString;
  usages: TNvUsages;
  thermal : TNvGPUThermalSettings;
  res   : NvAPI_Status;
begin
  writeln('GPU API: ' );
  if NvAPI_EnumPhysicalGPUs(phys, cnt) = NVAPI_OK then begin
    writeln('Physical GPUs ', cnt);
    for i:=0 to cnt - 1 do
      if NvAPI_GPU_GetFullName(phys[i], name) = NVAPI_OK then begin
        write('  ', name,' ');
        FillChar(thermal, sizeof(thermal), 0);
        thermal.version:=NV_GPU_THERMAL_SETTINGS_VER;
        res:=NvAPI_GPU_GetThermalSettings(phys[i],0, @thermal);
        if res= NVAPI_OK then
          write('temp: ', thermal.sensor[0].currentTemp, ' C');
        writeln;
        write('  ');
        if NvAPI_GPU_GetTachReading(phys[i], cnt) = NVAPI_OK then
          write('Fan Speed: ', cnt);
        writeln;
        write('  ');
        
// ******************* Hier wird die Funktion aufgerufen **************** //
        FillChar(usages, sizeof(usages), 0);
        usages.version:= NV_DISPLAY_DRIVER_VERSION_VER;
        NvAPI_GPU_GetUsages(phys[i], @usages);
        writeln('Usages: ', usages.usage[0].currentUsage[0]);
// ********************************************************************** //
      end;
  end;
  if NvAPI_EnumLogicalGPUs(log, cnt) = NVAPI_OK then
    writeln('Logical GPUs ', cnt);

  writeln;
end;
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 31.12.12 17:42 
Das ist einfach nur ein Array von uint Werten, das laut Marshal-Angabe als Wert und nicht als Pointer angegeben wird.
ausblenden Delphi-Quelltext
1:
 usage: array[0..NVAPI_MAX_USAGES_PER_GPU -1of NvU32;					
LittleBen Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 258
Erhaltene Danke: 4

Win 7, Mac OS
Delphi 7
BeitragVerfasst: Mo 31.12.12 18:01 
Eine Exception bekomme ich nun nicht mehr, aber die Funktion gibt "NVAPI_INCOMPATIBLE_STRUCT_VERSION" zurück. Also irgendetwas stimmt noch nicht...

EDIT: Habe es jetzt mit einer weiteren Struktur (bzw. Funktion) probiert, dort bekomme ich jedoch auch den Fehlerwert -9 zurück (inkompatible Versionen).
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
  NV_USAGES = record
    version: NvU32;
    usage: array[0..NVAPI_MAX_USAGES_PER_GPU -1of NvU32;
  end;
  TNvUsages = NV_USAGES;
  PNvUsages = ^TNvUsages;

  NV_MEMORY_INFO = record
    version: NvU32;
    values: array[0..NVAPI_MAX_MEMORY_VALUES_PER_GPU -1of NvU32;
  end;
  TNvMemoryInfo = NV_MEMORY_INFO;
  PNvMemoryInfo = ^TNvMemoryInfo;

Aber die Strukturen stimmen doch jetzt überein?!
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
[StructLayout(LayoutKind.Sequential, Pack = 8)]
  internal struct NvUsages {
    public uint Version;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_USAGES_PER_GPU)]
    public uint[] Usage;
  }

[StructLayout(LayoutKind.Sequential, Pack = 8)]
  internal struct NvMemoryInfo {
    public uint Version;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst =
      NVAPI.MAX_MEMORY_VALUES_PER_GPU)]
    public uint[] Values;
  }
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Mo 31.12.12 19:50 
Bin mir nicht ganz sicher, aber 3 Dinge:
1) Probiere mal ein packed record (oder ein Alignment bis 32Bit, original will er 8 bit)
2)
ausblenden C#-Quelltext
1:
2:
3:
NvUsages usages = new NvUsages();
        usages.Version = NVAPI.GPU_USAGES_VER;
        usages.Usage = new uint[NVAPI.MAX_USAGES_PER_GPU];

Kann es sein, dass es doch ein Pointer auf ein array ist? Kenne C# nicht wirklich, aber es sieht so aus...

3) Die richtige versionsnummer verwenden! Es ist GPU_USAGES_VER(=$10000) nicht NV_DISPLAY_DRIVER_VERSION_VER!
LittleBen Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 258
Erhaltene Danke: 4

Win 7, Mac OS
Delphi 7
BeitragVerfasst: Mi 02.01.13 13:59 
Also alle 3 Punkte sind es leider nicht, die den Error auslösen...
Nr. 1 nicht, weil bei der Struktur NV_GPU_THERMAL_SETTINGS, die in Delphi schon vorhanden ist, will er in dem CS-Code auch 8-Bit, doch in Delphi wird das auch nicht berücksichtigt und funktioniert trotzdem:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
  NV_GPU_THERMAL_SETTINGS = record
    version: NvU32;                   //structure version
    count: NvU32;                     //number of associated thermal sensors with the selected GPU
    sensor: array[0..NVAPI_MAX_THERMAL_SENSORS_PER_GPU - 1of
      record
        controller: NV_THERMAL_CONTROLLER;         //internal, ADM1032, MAX6649...
        defaultMinTemp: NvU32;                     //the min default temperature value of the thermal sensor in degrees centigrade
        defaultMaxTemp: NvU32;                     //the max default temperature value of the thermal sensor in degrees centigrade
        currentTemp: NvU32;                        //the current temperature value of the thermal sensor in degrees centigrade
        target: NV_THERMAL_TARGET;                 //thermal senor targeted @ GPU, memory, chipset, powersupply, canoas...
      end;
  end;
  TNvGPUThermalSettings = NV_GPU_THERMAL_SETTINGS;
  PNvGPUThermalSettings = ^TNvGPUThermalSettings;

Aufruf dieser Funktion habe ich bereits gepostet.
Nr. 2 kann es auch nicht sein, weil der Aufruf der Funktion NvAPI_GPU_GetThermalSettings funktioniert (ohne Pointer auf ein Array)
Nr. 3 habe ich ausprobiert, ändert sich aber nichts...
LittleBen Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 258
Erhaltene Danke: 4

Win 7, Mac OS
Delphi 7
BeitragVerfasst: Mi 02.01.13 18:27 
Ich poste jetzt einfach mal den ordnelich gemachten Code (Strukturen und Aufrufe). Vielleicht fällt euch etwas ins Auge...

NvApi.pas (Strukturen)
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
const
  NVAPI_MAX_USAGES_PER_GPU           = 33;
  NVAPI_MAX_MEMORY_VALUES_PER_GPU    = 5;
  NVAPI_MAX_COOLER_PER_GPU          = 20;

// --------------------- THERMAL war bereits vorhanden und funktioniert --------------------- //
///////////////////////////////////////////////////////////////////////////////////
//  Thermal API
//  Provides ability to get temperature levels from the various thermal sensors associated with the GPU

const
  NVAPI_MAX_THERMAL_SENSORS_PER_GPU = 3;

type
  NV_THERMAL_TARGET = (
    NVAPI_THERMAL_TARGET_NONE          = 0,
    NVAPI_THERMAL_TARGET_GPU           = 1,
    NVAPI_THERMAL_TARGET_MEMORY        = 2,
    NVAPI_THERMAL_TARGET_POWER_SUPPLY  = 4,
    NVAPI_THERMAL_TARGET_BOARD         = 8,
    NVAPI_THERMAL_TARGET_ALL           = 15,
    NVAPI_THERMAL_TARGET_UNKNOWN       = -1
  );

  NV_THERMAL_CONTROLLER = (
    NVAPI_THERMAL_CONTROLLER_NONE = 0,
    NVAPI_THERMAL_CONTROLLER_GPU_INTERNAL,
    NVAPI_THERMAL_CONTROLLER_ADM1032,
    NVAPI_THERMAL_CONTROLLER_MAX6649,
    NVAPI_THERMAL_CONTROLLER_MAX1617,
    NVAPI_THERMAL_CONTROLLER_LM99,
    NVAPI_THERMAL_CONTROLLER_LM89,
    NVAPI_THERMAL_CONTROLLER_LM64,
    NVAPI_THERMAL_CONTROLLER_ADT7473,
    NVAPI_THERMAL_CONTROLLER_SBMAX6649,
    NVAPI_THERMAL_CONTROLLER_VBIOSEVT,
    NVAPI_THERMAL_CONTROLLER_OS,
    NVAPI_THERMAL_CONTROLLER_UNKNOWN = -1
  );

  NV_GPU_THERMAL_SETTINGS = record
    version: NvU32;                   //structure version
    count: NvU32;                     //number of associated thermal sensors with the selected GPU
    sensor: array[0..NVAPI_MAX_THERMAL_SENSORS_PER_GPU - 1of
      record
        controller: NV_THERMAL_CONTROLLER;         //internal, ADM1032, MAX6649...
        defaultMinTemp: NvU32;                     //the min default temperature value of the thermal sensor in degrees centigrade
        defaultMaxTemp: NvU32;                     //the max default temperature value of the thermal sensor in degrees centigrade
        currentTemp: NvU32;                        //the current temperature value of the thermal sensor in degrees centigrade
        target: NV_THERMAL_TARGET;                 //thermal senor targeted @ GPU, memory, chipset, powersupply, canoas...
      end;
  end;
  TNvGPUThermalSettings = NV_GPU_THERMAL_SETTINGS;
  PNvGPUThermalSettings = ^TNvGPUThermalSettings;

// ------------------------------------------------------------------------------------------ //

///////////////////////////////////////////////////////////////////////////////////
//  Usages API

const
  NV_GPU_USAGES_VER = $10000;

type
  NV_USAGES = record
    Version: NvU32;
    Usage: array[0..NVAPI_MAX_USAGES_PER_GPU -1of NvU32;
  end;
  TNvUsages = NV_USAGES;
  PNvUsages = ^TNvUsages;

///////////////////////////////////////////////////////////////////////////////////
//  Memory API

const
  NV_GPU_MEMORY_INFO_VER = $20000;

type
  NV_MEMORY_INFO = record
    Version: NvU32;
    Values: array[0..NVAPI_MAX_MEMORY_VALUES_PER_GPU -1of NvU32;
  end;
  TNvMemoryInfo = NV_MEMORY_INFO;
  PNvMemoryInfo = ^TNvMemoryInfo;

///////////////////////////////////////////////////////////////////////////////////
//  Cooler API

const
  NV_GPU_COOLER_SETTINGS_VER = $20000;

type
  NV_COOLER_SETTINGS = record
    Version: NvU32;
    Count: NvU32;
    Cooler: array[0..NVAPI_MAX_COOLER_PER_GPU -1of
      record
        Controller: integer;
        DefaultMin: integer;
        DefaultMax: integer;
        CurrentMin: integer;
        CurrentMax: integer;
        CurrentLevel: integer;
        DefaultPolicy: integer;
        CurrentPolicy: integer;
        Target: integer;
        ControlType: integer;
        Active: integer;
      end;
  end;
  TNvCoolerSettings = NV_COOLER_SETTINGS;
  PNvCoolerSettings = ^TNvCoolerSettings;


const
  NV_GPU_COOLER_LEVELS_VER = $10000;

type
  NV_GPU_COOLER_LEVELS = record
    Version: NvU32;
    Levels: array[0..NVAPI_MAX_COOLER_PER_GPU -1of
      record
        Level: integer;
        Policy: integer;
      end;
  end;
  TNvGPUCoolerLevels = NV_GPU_COOLER_LEVELS;
  PNvGPUCoolerLevels = ^TNvGPUCoolerLevels;

{...}

var
  NvAPI_GPU_GetThermalSettings: function(hPhysicalGpu: PNvPhysicalGpuHandle; sensorIndex: NvU32; pThermalSettings: PNvGPUThermalSettings): NvAPI_Status; cdecl;  

  NvAPI_GPU_GetUsages: function(hPhysicalGPU: PNvPhysicalGpuHandle; nvUsages: PNvUsages): NvApi_Status; cdecl;

  NvAPI_GPU_GetMemoryInfo: function(pNvDispHandle: PNvDisplayHandle; nvMemoryInfo: PNvMemoryInfo): NvApi_Status; cdecl;

  NvAPI_GPU_GetCoolerSettings: function(hPhysicalGPU: PNvPhysicalGpuHandle; CoolerIndex: integer; NvCoolerSettings: PNvCoolerSettings): NvApi_Status; cdecl;


NvApiTest.pas (Verwendung)
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
procedure TestGPUAPI;
var n: Integer;
    nCount: LongWord;
    cName: NvAPI_ShortString;
    nSpeed: LongWord;

    Phys: TNvPhysicalGpuHandleArray;
    Log: TNvLogicalGpuHandleArray;

    Thermal: TNvGPUThermalSettings;
    Usages: TNvUsages;
    Memory: TNvMemoryInfo;
    Cooler: TNvCoolerSettings;
    Status: NvAPI_Status;
begin
  writeln('GPU API: ' );
  if NvAPI_EnumPhysicalGPUs(Phys, nCount) = NVAPI_OK then
  begin
   writeln('Physical GPUs ', nCount);
   for n:=0 to nCount - 1 do
   begin
    if NvAPI_GPU_GetFullName(Phys[n], cName) = NVAPI_OK then
    begin
     write('  ', cName, ' ');

     // ****************** TEMPERATUR ****************** //
     FillChar(Thermal, SizeOf(Thermal), 0);
     Thermal.Version:= NV_GPU_THERMAL_SETTINGS_VER;
     Status:= NvAPI_GPU_GetThermalSettings(Phys[n],0, @Thermal);
     if Status = NVAPI_OK then
     begin
      write('temp: ', Thermal.Sensor[0].CurrentTemp, ' C');
      writeln;
      write('  ');
     end
     else
      showmessage(inttostr(Integer(Status)));
     // ************************************************ //

     // ****************** FAN SPEED ******************* //
     Status:= NvAPI_GPU_GetTachReading(Phys[n], nSpeed);
     if Status = NVAPI_OK then
     begin
      write('Fan Speed: ', nSpeed);
      writeln;
      write('  ');
     end
     else
      showmessage(inttostr(Integer(Status)));
     // ************************************************ //

     // ******************** USAGES ******************** //
     FillChar(Usages, SizeOf(Usages), 0);
     Usages.Version:= NV_GPU_USAGES_VER;
     Status:= NvAPI_GPU_GetUsages(Phys[n], @Usages);
     if Status = NVAPI_OK then
     begin
      write('Usages: ', Usages.Usage[0]);
      writeln;
      write('  ');
     end
     else
      showmessage(inttostr(Integer(Status)));
     // ************************************************ //

     // ***************** MEMORY INFO ****************** //
     FillChar(Memory, SizeOf(Memory), 0);
     Memory.Version:= NV_GPU_MEMORY_INFO_VER;
     Status:= NvAPI_GPU_GetMemoryInfo(0, @Memory);
     if Status = NVAPI_OK then
     begin
      write('Memory: ', Memory.Values[0]);
      writeln;
      write('  ');
     end
     else
      showmessage(inttostr(Integer(Status)));
     // ************************************************ //

     // ***************** COOLER INFO ****************** //
     FillChar(Cooler, SizeOf(Cooler), 0);
     Cooler.Version:= NV_GPU_COOLER_SETTINGS_VER;
     Status:= NvAPI_GPU_GetCoolerSettings(Phys[n], 0, @Cooler);
     if Status = NVAPI_OK then
     begin
      write('Cooler: ', Cooler.Cooler[0].CurrentLevel);
      writeln;
      write('  ');
     end
     else
      showmessage(inttostr(Integer(Status)));
     // ************************************************ //
    end;
   end;
  end;

  if NvAPI_EnumLogicalGPUs(log, nCount) = NVAPI_OK then
    writeln('Logical GPUs ', nCount);

  writeln;
end;


Bei NvAPI_GPU_GetUsages und NvAPI_GPU_GetMemoryInfo bekommt man die Fehlermeldung NVAPI_INCOMPATIBLE_STRUCT_VERSION.
Bei NvAPI_GPU_GetCoolerSettings hängt sich das Programm auf.

Hat denn keiner eine Idee woran das liegen kann?

// EDIT: Ohhhhh sorry, doppel post, habe nicht drauf geachtet :oops:

// EDIT 2.0 : KOMMANDO ZURÜCK :autsch:
Die Konstanten müssen so aussehen -.-
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
const
  NV_GPU_USAGES_VER = NvU32(SizeOf(NV_USAGES) or ($10000));
  NV_GPU_MEMORY_INFO_VER = NvU32(SizeOf(NV_MEMORY_INFO) or ($20000));
  NV_GPU_COOLER_SETTINGS_VER = NvU32(SizeOf(NV_COOLER_SETTINGS) or ($20000));
  NV_GPU_COOLER_LEVELS_VER = NvU32(SizeOf(NV_GPU_COOLER_LEVELS) or ($10000));

Jetzt funktioniert alles ^^

Und hier das Endergebnis:
[url=www.abload.de/image....g=img_053411qis.jpg]user defined image[/url]