GPU (Windows): greatly improve performance of GPU temp detection

... when `--gpu-driver-specific` is not set. Supported on Windows 10 and later
This commit is contained in:
李通洲
2025-07-12 01:26:33 +08:00
parent 939f428da7
commit ab496b23b7
2 changed files with 86 additions and 6 deletions
+15 -1
View File
@@ -164,7 +164,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
__typeof__(&ffDetectNvidiaGpuInfo) detectFn;
const char* dllName;
if (getDriverSpecificDetectionFn(gpu->vendor.chars, &detectFn, &dllName) && (options->temp || options->driverSpecific))
if (options->driverSpecific && getDriverSpecificDetectionFn(gpu->vendor.chars, &detectFn, &dllName))
{
unsigned vendorId = 0, deviceId = 0, subSystemId = 0, revId = 0;
bufferLen = sizeof(buffer);
@@ -242,6 +242,20 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
gpu->type = FF_GPU_TYPE_INTEGRATED;
}
}
if (options->temp && gpu->temperature != gpu->temperature)
{
D3DKMT_QUERYSTATISTICS queryStatistics = {
.Type = D3DKMT_QUERYSTATISTICS_PHYSICAL_ADAPTER,
.AdapterLuid = *(LUID*)&adapterLuid,
.QueryPhysAdapter = { .PhysicalAdapterIndex = 0 },
};
if (NT_SUCCESS(D3DKMTQueryStatistics(&queryStatistics)))
gpu->temperature = queryStatistics.QueryResult.PhysAdapterInformation.AdapterPerfData.Temperature / 10.0;
}
D3DKMT_CLOSEADAPTER closeAdapter = { .hAdapter = openAdapterFromLuid.hAdapter };
(void) D3DKMTCloseAdapter(&closeAdapter);
}
}
}
+71 -5
View File
@@ -3,6 +3,8 @@
#include <winnt.h>
#include <winternl.h>
#define D3DKMT_ALIGN64 __attribute__((aligned(8)))
typedef struct _PROCESSOR_POWER_INFORMATION {
ULONG Number;
ULONG MaxMhz;
@@ -48,20 +50,20 @@ typedef struct _D3DKMT_ADAPTERTYPE
{
struct
{
UINT RenderSupported : 1;
UINT RenderSupported : 1; // WDDM 1.2, Windows 8
UINT DisplaySupported : 1;
UINT SoftwareDevice : 1;
UINT PostDevice : 1;
UINT HybridDiscrete : 1;
UINT HybridDiscrete : 1; // WDDM 1.3, Windows 8.1
UINT HybridIntegrated : 1;
UINT IndirectDisplayDevice : 1;
UINT Paravirtualized : 1;
UINT Paravirtualized : 1; // WDDM 2.3, Windows 10 Fall Creators Update (version 1709)
UINT ACGSupported : 1;
UINT SupportSetTimingsFromVidPn : 1;
UINT Detachable : 1;
UINT ComputeOnly : 1;
UINT ComputeOnly : 1; // WDDM 2.6, Windows 10 May 2019 Update (Version 1903)
UINT Prototype : 1;
UINT RuntimePowerManagement : 1;
UINT RuntimePowerManagement : 1; // WDDM 2.9, Windows 10 Insider Preview "Iron"
UINT Reserved : 18;
};
UINT Value;
@@ -81,3 +83,67 @@ typedef struct _D3DKMT_QUERYADAPTERINFO
} D3DKMT_QUERYADAPTERINFO;
EXTERN_C _Check_return_ NTSTATUS APIENTRY D3DKMTQueryAdapterInfo(_Inout_ CONST D3DKMT_QUERYADAPTERINFO*);
#endif
typedef enum _D3DKMT_QUERYSTATISTICS_TYPE
{
D3DKMT_QUERYSTATISTICS_PHYSICAL_ADAPTER = 10, // WDDM 2.4, Windows 10 April 2018 Update (version 1803)
} D3DKMT_QUERYSTATISTICS_TYPE;
typedef struct _D3DKMT_QUERYSTATISTICS_QUERY_PHYSICAL_ADAPTER
{
ULONG PhysicalAdapterIndex;
} D3DKMT_QUERYSTATISTICS_QUERY_PHYSICAL_ADAPTER;
typedef struct _D3DKMT_ADAPTER_PERFDATA
{
UINT32 PhysicalAdapterIndex; // in: The physical adapter index, in an LDA chain
D3DKMT_ALIGN64 ULONGLONG MemoryFrequency; // out: Clock frequency of the memory in hertz
D3DKMT_ALIGN64 ULONGLONG MaxMemoryFrequency; // out: Max memory clock frequency
D3DKMT_ALIGN64 ULONGLONG MaxMemoryFrequencyOC; // out: Clock frequency of the memory while overclocked in hertz.
D3DKMT_ALIGN64 ULONGLONG MemoryBandwidth; // out: Amount of memory transferred in bytes
D3DKMT_ALIGN64 ULONGLONG PCIEBandwidth; // out: Amount of memory transferred over PCI-E in bytes
ULONG FanRPM; // out: Fan rpm
ULONG Power; // out: Power draw of the adapter in tenths of a percentage
ULONG Temperature; // out: Temperature in deci-Celsius 1 = 0.1C
UCHAR PowerStateOverride; // out: Overrides dxgkrnls power view of linked adapters.
} D3DKMT_ADAPTER_PERFDATA;
typedef struct _D3DKMT_ADAPTER_PERFDATACAPS
{
UINT32 PhysicalAdapterIndex; // in: The physical adapter index, in an LDA chain
D3DKMT_ALIGN64 ULONGLONG MaxMemoryBandwidth; // out: Max memory bandwidth in bytes for 1 second
D3DKMT_ALIGN64 ULONGLONG MaxPCIEBandwidth; // out: Max pcie bandwidth in bytes for 1 second
ULONG MaxFanRPM; // out: Max fan rpm
ULONG TemperatureMax; // out: Max temperature before damage levels
ULONG TemperatureWarning; // out: The temperature level where throttling begins.
} D3DKMT_ADAPTER_PERFDATACAPS;
#define DXGK_MAX_GPUVERSION_NAME_LENGTH 32
typedef struct _D3DKMT_GPUVERSION
{
UINT32 PhysicalAdapterIndex; // in: The physical adapter index, in an LDA chain
WCHAR BiosVersion[DXGK_MAX_GPUVERSION_NAME_LENGTH]; //out: The gpu bios version
WCHAR GpuArchitecture[DXGK_MAX_GPUVERSION_NAME_LENGTH]; //out: The gpu architectures name.
} D3DKMT_GPUVERSION;
typedef struct _D3DKMT_QUERYSTATISTICS_PHYSICAL_ADAPTER_INFORMATION
{
D3DKMT_ADAPTER_PERFDATA AdapterPerfData;
D3DKMT_ADAPTER_PERFDATACAPS AdapterPerfDataCaps;
D3DKMT_GPUVERSION GpuVersion;
} D3DKMT_QUERYSTATISTICS_PHYSICAL_ADAPTER_INFORMATION;
typedef union _D3DKMT_QUERYSTATISTICS_RESULT
{
D3DKMT_QUERYSTATISTICS_PHYSICAL_ADAPTER_INFORMATION PhysAdapterInformation; // in: id of physical adapter to get statistics for
uint8_t Padding[776];
} D3DKMT_QUERYSTATISTICS_RESULT;
typedef struct _D3DKMT_QUERYSTATISTICS
{
D3DKMT_QUERYSTATISTICS_TYPE Type; // in: type of data requested
LUID AdapterLuid; // in: adapter to get export / statistics from
HANDLE* hProcess; // in: process to get statistics for, if required for this query type
D3DKMT_QUERYSTATISTICS_RESULT QueryResult; // out: requested data
union
{
D3DKMT_QUERYSTATISTICS_QUERY_PHYSICAL_ADAPTER QueryPhysAdapter;
};
} D3DKMT_QUERYSTATISTICS;
static_assert(sizeof(D3DKMT_QUERYSTATISTICS) == 0x328, "D3DKMT_QUERYSTATISTICS structure size mismatch");
EXTERN_C _Check_return_ NTSTATUS APIENTRY D3DKMTQueryStatistics(_In_ CONST D3DKMT_QUERYSTATISTICS*);