diff --git a/src/detection/gpu/gpu_windows.c b/src/detection/gpu/gpu_windows.c index 457fd6488..30b94a836 100644 --- a/src/detection/gpu/gpu_windows.c +++ b/src/detection/gpu/gpu_windows.c @@ -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); } } } diff --git a/src/util/windows/nt.h b/src/util/windows/nt.h index 8976ccbac..c1b854ebb 100644 --- a/src/util/windows/nt.h +++ b/src/util/windows/nt.h @@ -3,6 +3,8 @@ #include #include +#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*);