summaryrefslogtreecommitdiffstats
path: root/src/detection/gpu/d3dkmthk.h
diff options
context:
space:
mode:
authorsumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
committersumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
commit76424950e373d3b04ac3dd13019151bfba3e8423 (patch)
tree4c3cfdbda039e592b9186be3e28f8d7cfd439e8a /src/detection/gpu/d3dkmthk.h
Add the files
Diffstat (limited to 'src/detection/gpu/d3dkmthk.h')
-rw-r--r--src/detection/gpu/d3dkmthk.h362
1 files changed, 362 insertions, 0 deletions
diff --git a/src/detection/gpu/d3dkmthk.h b/src/detection/gpu/d3dkmthk.h
new file mode 100644
index 0000000..da0087b
--- /dev/null
+++ b/src/detection/gpu/d3dkmthk.h
@@ -0,0 +1,362 @@
+#pragma once
+
+#include <stdint.h>
+#include <limits.h>
+#include <assert.h>
+#include <stdalign.h>
+
+#if _WIN32
+ #include <ntdef.h>
+ #include <windef.h>
+#else
+ #include <sys/ioctl.h>
+ #include <uchar.h>
+ #include <errno.h>
+
+typedef struct _LUID {
+ uint32_t LowPart;
+ uint32_t HighPart;
+} LUID;
+
+typedef uint32_t UINT;
+typedef uint64_t ULONGLONG;
+typedef uint64_t UINT64;
+typedef uint32_t UINT32;
+typedef uint16_t UINT16;
+typedef uint32_t ULONG;
+typedef uint16_t USHORT;
+typedef uint8_t UCHAR;
+typedef void VOID;
+typedef char16_t WCHAR;
+typedef void* HANDLE;
+typedef uint8_t BYTE;
+typedef int32_t BOOL;
+typedef uint8_t BOOLEAN;
+typedef union {
+ struct {
+ uint32_t LowPart;
+ int32_t HighPart;
+ } u;
+ int64_t QuadPart;
+} LARGE_INTEGER;
+typedef int32_t NTSTATUS; // 0 for success, -1 for failure
+ #define NT_SUCCESS(Status) ((NTSTATUS) (Status) >= 0)
+ #define _In_range_(low, hi)
+#endif
+
+#define D3DKMT_ALIGN64 alignas(8)
+
+typedef struct D3DKMT_HANDLE {
+ union {
+ struct {
+ uint32_t Instance : 6;
+ uint32_t Index : 24;
+ uint32_t Unique : 2;
+ };
+ uint32_t Value;
+ };
+} D3DKMT_HANDLE;
+
+typedef struct _D3DKMT_OPENADAPTERFROMLUID {
+ LUID AdapterLuid;
+ D3DKMT_HANDLE hAdapter;
+} D3DKMT_OPENADAPTERFROMLUID;
+
+typedef struct _D3DKMT_ADAPTERINFO {
+ D3DKMT_HANDLE hAdapter;
+ LUID AdapterLuid;
+ ULONG NumOfSources;
+ BOOL bPrecisePresentRegionsPreferred;
+} D3DKMT_ADAPTERINFO;
+
+#define MAX_ENUM_ADAPTERS 16
+typedef struct _D3DKMT_ENUMADAPTERS {
+ _In_range_(0, MAX_ENUM_ADAPTERS) ULONG NumAdapters;
+ D3DKMT_ADAPTERINFO Adapters[MAX_ENUM_ADAPTERS];
+} D3DKMT_ENUMADAPTERS;
+
+typedef struct _D3DKMT_ENUMADAPTERS2 {
+ ULONG NumAdapters; // in/out: On input, the count of the pAdapters array buffer. On output, the number of adapters enumerated.
+ D3DKMT_ADAPTERINFO* pAdapters; // out: Array of enumerated adapters containing NumAdapters elements
+} D3DKMT_ENUMADAPTERS2;
+static_assert(sizeof(D3DKMT_ENUMADAPTERS2) ==
+#if SIZE_MAX == UINT64_MAX
+ 0x10
+#else
+ 0x08
+#endif
+ ,
+ "D3DKMT_ENUMADAPTERS2 structure size mismatch");
+
+typedef struct _D3DKMT_ADAPTERREGISTRYINFO {
+ WCHAR AdapterString[260];
+ WCHAR BiosString[260];
+ WCHAR DacType[260];
+ WCHAR ChipType[260];
+} D3DKMT_ADAPTERREGISTRYINFO;
+
+typedef struct _D3DKMT_CLOSEADAPTER {
+ D3DKMT_HANDLE hAdapter; // in: adapter handle
+} D3DKMT_CLOSEADAPTER;
+
+typedef struct _D3DKMT_SEGMENTSIZEINFO {
+ D3DKMT_ALIGN64 ULONGLONG DedicatedVideoMemorySize;
+ D3DKMT_ALIGN64 ULONGLONG DedicatedSystemMemorySize;
+ D3DKMT_ALIGN64 ULONGLONG SharedSystemMemorySize;
+} D3DKMT_SEGMENTSIZEINFO;
+
+typedef struct _D3DKMT_ADAPTERTYPE {
+ union {
+ struct {
+ UINT RenderSupported : 1; // WDDM 1.2, Windows 8
+ UINT DisplaySupported : 1;
+ UINT SoftwareDevice : 1;
+ UINT PostDevice : 1;
+ UINT HybridDiscrete : 1; // WDDM 1.3, Windows 8.1
+ UINT HybridIntegrated : 1;
+ UINT IndirectDisplayDevice : 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; // WDDM 2.6, Windows 10 May 2019 Update (Version 1903)
+ UINT Prototype : 1;
+ UINT RuntimePowerManagement : 1; // WDDM 2.9, Windows 10 Insider Preview "Iron"
+ UINT Reserved : 18;
+ };
+ UINT Value;
+ };
+} D3DKMT_ADAPTERTYPE;
+
+typedef struct _D3DKMT_ADAPTERADDRESS {
+ UINT BusNumber; // Bus number on which the physical device is located.
+ UINT DeviceNumber; // Index of the physical device on the bus.
+ UINT FunctionNumber; // Function number of the adapter on the physical device.
+} D3DKMT_ADAPTERADDRESS;
+
+typedef struct _D3DKMT_DEVICE_IDS {
+ UINT VendorID;
+ UINT DeviceID;
+ UINT SubVendorID;
+ UINT SubSystemID;
+ UINT RevisionID;
+ UINT BusType;
+} D3DKMT_DEVICE_IDS;
+
+typedef struct _D3DKMT_UMD_DRIVER_VERSION {
+ D3DKMT_ALIGN64 LARGE_INTEGER DriverVersion;
+} D3DKMT_UMD_DRIVER_VERSION;
+
+typedef struct _D3DKMT_QUERY_DEVICE_IDS {
+ UINT PhysicalAdapterIndex; // in:
+ D3DKMT_DEVICE_IDS DeviceIds; // out:
+} D3DKMT_QUERY_DEVICE_IDS;
+
+typedef enum _QAI_DRIVERVERSION {
+ KMT_DRIVERVERSION_WDDM_1_0 = 1000, // Windows Vista
+ KMT_DRIVERVERSION_WDDM_1_1_PRERELEASE = 1102, // Windows Vista with prereleased Win7 features
+ KMT_DRIVERVERSION_WDDM_1_1 = 1105, // Windows 7
+ KMT_DRIVERVERSION_WDDM_1_2 = 1200, // Windows 8
+ KMT_DRIVERVERSION_WDDM_1_3 = 1300, // Windows 8.1
+ KMT_DRIVERVERSION_WDDM_2_0 = 2000, // Windows 10
+ KMT_DRIVERVERSION_WDDM_2_1 = 2100, // Windows 10 (1607)
+ KMT_DRIVERVERSION_WDDM_2_2 = 2200, // Windows 10 (1703)
+ KMT_DRIVERVERSION_WDDM_2_3 = 2300, // Windows 10 (1709)
+ KMT_DRIVERVERSION_WDDM_2_4 = 2400, // Windows 10 (1803)
+ KMT_DRIVERVERSION_WDDM_2_5 = 2500, // Windows 10 (1809)
+ KMT_DRIVERVERSION_WDDM_2_6 = 2600, // Windows 10 (1903)
+ KMT_DRIVERVERSION_WDDM_2_7 = 2700, // Windows 10 (2004)
+ KMT_DRIVERVERSION_WDDM_2_8 = 2800, // Windows 11 Insider Preview Manganese
+ KMT_DRIVERVERSION_WDDM_2_9 = 2900, // Windows 11 Insider Preview Iron
+ KMT_DRIVERVERSION_WDDM_3_0 = 3000, // Windows 11 (21H2)
+ KMT_DRIVERVERSION_WDDM_3_1 = 3100, // Windows 11 (22H2)
+ KMT_DRIVERVERSION_WDDM_3_2 = 3200, // Windows 11 (24H2)
+} D3DKMT_DRIVERVERSION;
+
+typedef struct _D3DKMT_QUERY_ADAPTER_UNIQUE_GUID {
+ WCHAR AdapterUniqueGUID[40];
+} D3DKMT_QUERY_ADAPTER_UNIQUE_GUID;
+
+typedef enum _KMTQUERYADAPTERINFOTYPE {
+ KMTQAITYPE_GETSEGMENTSIZE = 3,
+ KMTQAITYPE_ADAPTERGUID = 4,
+ KMTQAITYPE_ADAPTERADDRESS = 6,
+ KMTQAITYPE_ADAPTERREGISTRYINFO = 8,
+ KMTQAITYPE_DRIVERVERSION = 13,
+ KMTQAITYPE_ADAPTERTYPE = 15, // WDDM 1.2, Windows 8
+ KMTQAITYPE_UMD_DRIVER_VERSION = 18,
+ KMTQAITYPE_NODEMETADATA = 25, // WDDM 2.0, Windows 10
+ KMTQAITYPE_PHYSICALADAPTERDEVICEIDS = 31,
+ KMTQAITYPE_QUERY_ADAPTER_UNIQUE_GUID = 60, // WDDM 2.4, Windows 10 (1803)
+ KMTQAITYPE_NODEPERFDATA = 61,
+ KMTQAITYPE_ADAPTERPERFDATA = 62,
+} KMTQUERYADAPTERINFOTYPE;
+
+typedef struct _D3DKMT_QUERYADAPTERINFO {
+ D3DKMT_HANDLE hAdapter;
+ KMTQUERYADAPTERINFOTYPE Type;
+ VOID* pPrivateDriverData;
+ UINT PrivateDriverDataSize;
+} D3DKMT_QUERYADAPTERINFO;
+
+#define D3DKMT_MAX_SEGMENT_COUNT 32
+
+typedef enum _D3DKMT_MEMORY_SEGMENT_GROUP {
+ D3DKMT_MEMORY_SEGMENT_GROUP_LOCAL = 0,
+ D3DKMT_MEMORY_SEGMENT_GROUP_NON_LOCAL = 1
+} D3DKMT_MEMORY_SEGMENT_GROUP;
+
+typedef enum _D3DKMT_QUERYSTATISTICS_TYPE {
+ D3DKMT_QUERYSTATISTICS_SEGMENT_GROUP_USAGE = 17, // WDDM 3.1, Windows 11 2022 Update (version 22H2)
+} D3DKMT_QUERYSTATISTICS_TYPE;
+
+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_NODE_PERFDATA {
+ UINT32 NodeOrdinal; // in: Node ordinal of the requested engine.
+ UINT32 PhysicalAdapterIndex; // in: The physical adapter index, in an LDA chain
+ D3DKMT_ALIGN64 ULONGLONG Frequency; // out: Clock frequency of the engine in hertz
+ D3DKMT_ALIGN64 ULONGLONG MaxFrequency; // out: Max engine clock frequency
+ D3DKMT_ALIGN64 ULONGLONG MaxFrequencyOC; // out: Max engine over clock frequency
+ ULONG Voltage; // out: Voltage of the engine in milli volts mV
+ ULONG VoltageMax; // out: Max voltage levels in milli volts.
+ ULONG VoltageMaxOC; // out: Max voltage level while overclocked in milli volts.
+ // WDDM 2.5
+ D3DKMT_ALIGN64 ULONGLONG MaxTransitionLatency; // out: Max transition latency to change the frequency in 100 nanoseconds
+} D3DKMT_NODE_PERFDATA;
+
+typedef struct _D3DKMT_QUERYSTATISTICS_MEMORY_USAGE {
+ D3DKMT_ALIGN64 UINT64 AllocatedBytes;
+ D3DKMT_ALIGN64 UINT64 FreeBytes;
+ D3DKMT_ALIGN64 UINT64 ZeroBytes;
+ D3DKMT_ALIGN64 UINT64 ModifiedBytes;
+ D3DKMT_ALIGN64 UINT64 StandbyBytes;
+} D3DKMT_QUERYSTATISTICS_MEMORY_USAGE;
+
+typedef union _D3DKMT_QUERYSTATISTICS_RESULT {
+ D3DKMT_QUERYSTATISTICS_MEMORY_USAGE SegmentGroupUsageInformation;
+ uint8_t Padding[776];
+} D3DKMT_QUERYSTATISTICS_RESULT;
+
+typedef struct _D3DKMT_QUERYSTATISTICS_QUERY_SEGMENT_GROUP_USAGE {
+ UINT16 PhysicalAdapterIndex;
+ UINT16 SegmentGroup; // D3DKMT_MEMORY_SEGMENT_GROUP
+} D3DKMT_QUERYSTATISTICS_QUERY_SEGMENT_GROUP_USAGE;
+
+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_SEGMENT_GROUP_USAGE QuerySegmentGroupUsage;
+ };
+} D3DKMT_QUERYSTATISTICS;
+static_assert(sizeof(D3DKMT_QUERYSTATISTICS) ==
+#if SIZE_MAX == UINT64_MAX
+ 0x328
+#else
+ 0x320
+#endif
+ ,
+ "D3DKMT_QUERYSTATISTICS structure size mismatch");
+
+#define DXGK_MAX_METADATA_NAME_LENGTH 32
+typedef enum {
+ DXGK_ENGINE_TYPE_OTHER,
+ DXGK_ENGINE_TYPE_3D,
+ DXGK_ENGINE_TYPE_VIDEO_DECODE,
+ DXGK_ENGINE_TYPE_VIDEO_ENCODE,
+ DXGK_ENGINE_TYPE_VIDEO_PROCESSING,
+ DXGK_ENGINE_TYPE_SCENE_ASSEMBLY,
+ DXGK_ENGINE_TYPE_COPY,
+ DXGK_ENGINE_TYPE_OVERLAY,
+ DXGK_ENGINE_TYPE_CRYPTO,
+ DXGK_ENGINE_TYPE_VIDEO_CODEC,
+ DXGK_ENGINE_TYPE_MAX
+} DXGK_ENGINE_TYPE;
+
+typedef struct _DXGK_NODEMETADATA_FLAGS {
+ union {
+ struct {
+ UINT ContextSchedulingSupported : 1; // WDDM 2.2
+ UINT RingBufferFenceRelease : 1; // WDDM 2.5
+ UINT SupportTrackedWorkload : 1;
+ UINT UserModeSubmission : 1;
+ UINT SupportBuildTestCommandBuffer : 1; // WDDM 3.2
+ UINT Reserved : 11;
+ UINT MaxInFlightHwQueueBuffers : 16;
+ };
+ UINT32 Value;
+ };
+} DXGK_NODEMETADATA_FLAGS;
+
+typedef struct _DXGK_NODEMETADATA {
+ DXGK_ENGINE_TYPE EngineType;
+ WCHAR FriendlyName[DXGK_MAX_METADATA_NAME_LENGTH];
+ DXGK_NODEMETADATA_FLAGS Flags; // WDDM 2.2
+ BOOLEAN GpuMmuSupported; // WDDM 2.0 ???
+ BOOLEAN IoMmuSupported;
+} FF_A_PACKED DXGK_NODEMETADATA;
+
+typedef struct _D3DKMT_NODEMETADATA {
+ UINT NodeOrdinalAndAdapterIndex; // WDDMv2: High word is physical adapter index, low word is node ordinal
+ DXGK_NODEMETADATA NodeData;
+} FF_A_PACKED D3DKMT_NODEMETADATA;
+static_assert(sizeof(D3DKMT_NODEMETADATA) == 0x4E, "D3DKMT_NODEMETADATA structure size mismatch");
+
+// Functions
+
+#if _WIN32
+
+EXTERN_C _Check_return_ NTSTATUS APIENTRY D3DKMTOpenAdapterFromLuid(_Inout_ CONST D3DKMT_OPENADAPTERFROMLUID*);
+EXTERN_C _Check_return_ NTSTATUS APIENTRY D3DKMTQueryAdapterInfo(_Inout_ CONST D3DKMT_QUERYADAPTERINFO*);
+EXTERN_C _Check_return_ NTSTATUS APIENTRY D3DKMTCloseAdapter(_In_ CONST D3DKMT_CLOSEADAPTER*);
+EXTERN_C _Check_return_ NTSTATUS APIENTRY D3DKMTEnumAdapters(_Inout_ CONST D3DKMT_ENUMADAPTERS*);
+EXTERN_C _Check_return_ NTSTATUS APIENTRY D3DKMTEnumAdapters2(_Inout_ CONST D3DKMT_ENUMADAPTERS2*);
+EXTERN_C _Check_return_ NTSTATUS APIENTRY D3DKMTQueryStatistics(_In_ CONST D3DKMT_QUERYSTATISTICS*);
+
+#else
+
+ // Ref: https://github.com/microsoft/WSL2-Linux-Kernel/blob/linux-msft-wsl-6.6.y/include/uapi/misc/d3dkmthk.h
+ #define LX_DXOPENADAPTERFROMLUID _IOWR(0x47, 0x01, D3DKMT_OPENADAPTERFROMLUID)
+ #define LX_DXQUERYADAPTERINFO _IOWR(0x47, 0x09, D3DKMT_QUERYADAPTERINFO)
+ #define LX_DXENUMADAPTERS2 _IOWR(0x47, 0x14, D3DKMT_ENUMADAPTERS2)
+ #define LX_DXCLOSEADAPTER _IOWR(0x47, 0x15, D3DKMT_CLOSEADAPTER)
+ #define LX_DXQUERYSTATISTICS _IOWR(0x47, 0x43, D3DKMT_QUERYSTATISTICS)
+
+extern int dxgfd; // File descriptor for /dev/dxg, initialized in gpu_wsl.c
+
+static inline NTSTATUS D3DKMTOpenAdapterFromLuid(const D3DKMT_OPENADAPTERFROMLUID* params) {
+ return ioctl(dxgfd, LX_DXOPENADAPTERFROMLUID, params) < 0 ? -errno : 0;
+}
+
+static inline NTSTATUS D3DKMTQueryAdapterInfo(const D3DKMT_QUERYADAPTERINFO* params) {
+ return ioctl(dxgfd, LX_DXQUERYADAPTERINFO, params) < 0 ? -errno : 0;
+}
+
+static inline NTSTATUS D3DKMTCloseAdapter(const D3DKMT_CLOSEADAPTER* params) {
+ return ioctl(dxgfd, LX_DXCLOSEADAPTER, params) < 0 ? -errno : 0;
+}
+
+static inline NTSTATUS D3DKMTEnumAdapters2(D3DKMT_ENUMADAPTERS2* params) {
+ return ioctl(dxgfd, LX_DXENUMADAPTERS2, params) < 0 ? -errno : 0;
+}
+
+static inline NTSTATUS D3DKMTQueryStatistics(const D3DKMT_QUERYSTATISTICS* params) {
+ return ioctl(dxgfd, LX_DXQUERYSTATISTICS, params) < 0 ? -errno : 0;
+}
+
+#endif