nvapi_sys/gpu/
clock.rs

1use status::NvAPI_Status;
2use handles::NvPhysicalGpuHandle;
3use types::BoolU32;
4
5pub const NVAPI_MAX_GPU_CLOCKS: usize = 32;
6pub const NVAPI_MAX_GPU_PUBLIC_CLOCKS: usize = 32;
7pub const NVAPI_MAX_GPU_PERF_CLOCKS: usize = 32;
8pub const NVAPI_MAX_GPU_PERF_VOLTAGES: usize = 16;
9pub const NVAPI_MAX_GPU_PERF_PSTATES: usize = 16;
10
11nvenum! {
12    /// An index into NV_GPU_CLOCK_FREQUENCIES.domain[]
13    pub enum NV_GPU_PUBLIC_CLOCK_ID / PublicClockId {
14        NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS / Graphics = 0,
15        NVAPI_GPU_PUBLIC_CLOCK_MEMORY / Memory = 4,
16        NVAPI_GPU_PUBLIC_CLOCK_PROCESSOR / Processor = 7,
17        NVAPI_GPU_PUBLIC_CLOCK_VIDEO / Video = 8,
18        NVAPI_GPU_PUBLIC_CLOCK_UNDEFINED / Undefined = NVAPI_MAX_GPU_PUBLIC_CLOCKS,
19    }
20}
21
22nvenum_display! {
23    PublicClockId => _
24}
25
26nvstruct! {
27    /// Used in NvAPI_GPU_GetAllClockFrequencies()
28    pub struct NV_GPU_CLOCK_FREQUENCIES_V1 {
29        /// Structure version
30        pub version: u32,
31        /// These bits are reserved for future use.
32        ///
33        /// bits:2 is NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE. Used to specify the type of clock to be returned.
34        pub reserved: u32,
35        pub domain: [NV_GPU_CLOCK_FREQUENCIES_DOMAIN; NVAPI_MAX_GPU_PUBLIC_CLOCKS],
36    }
37}
38
39impl NV_GPU_CLOCK_FREQUENCIES_V1 {
40    pub fn ClockType(&self) -> NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE {
41        (self.reserved & 3) as _
42    }
43
44    pub fn set_ClockType(&mut self, value: NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE) {
45        self.reserved = (value as u32) & 3;
46    }
47}
48
49pub type NV_GPU_CLOCK_FREQUENCIES_V2 = NV_GPU_CLOCK_FREQUENCIES_V1;
50
51/// Used in NvAPI_GPU_GetAllClockFrequencies()
52pub type NV_GPU_CLOCK_FREQUENCIES = NV_GPU_CLOCK_FREQUENCIES_V2;
53
54nvversion! { NV_GPU_CLOCK_FREQUENCIES_VER_1(NV_GPU_CLOCK_FREQUENCIES_V1 = 4 * 2 + (4 * 2) * NVAPI_MAX_GPU_PUBLIC_CLOCKS, 1) }
55nvversion! { NV_GPU_CLOCK_FREQUENCIES_VER_2(NV_GPU_CLOCK_FREQUENCIES_V2 = 4 * 2 + (4 * 2) * NVAPI_MAX_GPU_PUBLIC_CLOCKS, 2) }
56nvversion! { NV_GPU_CLOCK_FREQUENCIES_VER_3(NV_GPU_CLOCK_FREQUENCIES_V2 = 4 * 2 + (4 * 2) * NVAPI_MAX_GPU_PUBLIC_CLOCKS, 3) }
57nvversion! { NV_GPU_CLOCK_FREQUENCIES_VER = NV_GPU_CLOCK_FREQUENCIES_VER_3 }
58
59nvenum! {
60    /// Used in NvAPI_GPU_GetAllClockFrequencies()
61    pub enum NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE / ClockFrequencyType {
62        NV_GPU_CLOCK_FREQUENCIES_CURRENT_FREQ / Current = 0,
63        NV_GPU_CLOCK_FREQUENCIES_BASE_CLOCK / Base = 1,
64        NV_GPU_CLOCK_FREQUENCIES_BOOST_CLOCK / Boost = 2,
65        NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE_NUM / Count = 3,
66    }
67}
68
69nvenum_display! {
70    ClockFrequencyType => _
71}
72
73nvstruct! {
74    pub struct NV_GPU_CLOCK_FREQUENCIES_DOMAIN {
75        /// Set if this domain is present on this GPU
76        pub bIsPresent: BoolU32,
77        /// Clock frequency (kHz)
78        pub frequency: u32,
79    }
80}
81
82nvapi! {
83    pub type GPU_GetAllClockFrequenciesFn = extern "C" fn(hPhysicalGPU: NvPhysicalGpuHandle, pClkFreqs: *mut NV_GPU_CLOCK_FREQUENCIES) -> NvAPI_Status;
84
85    /// This function retrieves the NV_GPU_CLOCK_FREQUENCIES structure for the specified physical GPU.
86    ///
87    /// For each clock domain:
88    /// - bIsPresent is set for each domain that is present on the GPU
89    /// - frequency is the domain's clock freq in kHz
90    ///
91    /// Each domain's info is indexed in the array.  For example:
92    /// clkFreqs.domain[NVAPI_GPU_PUBLIC_CLOCK_MEMORY] holds the info for the MEMORY domain.
93    pub unsafe fn NvAPI_GPU_GetAllClockFrequencies;
94}
95
96/// Undocumented API
97pub mod private {
98    // undocumented constants
99    pub const NVAPI_MAX_USAGES_PER_GPU: usize = 8;
100    pub const NVAPI_MAX_CLOCKS_PER_GPU: usize = 288;
101
102    use types::BoolU32;
103    use status::NvAPI_Status;
104    use handles::NvPhysicalGpuHandle;
105    use debug_array::Array;
106
107    nvstruct! {
108        pub struct NV_USAGES_INFO_USAGE {
109            pub bIsPresent: BoolU32,
110            /// % 0 to 100 usage
111            pub percentage: u32,
112            pub unknown: [u32; 2],
113        }
114    }
115
116    nvstruct! {
117        pub struct NV_USAGES_INFO_V1 {
118            pub version: u32,
119            pub flags: u32,
120            /// (core_usage, memory_usage, video_engine_usage), probably indexed by NV_GPU_UTILIZATION_DOMAIN_ID
121            pub usages: [NV_USAGES_INFO_USAGE; NVAPI_MAX_USAGES_PER_GPU],
122        }
123    }
124
125    nvversion! { NV_USAGES_INFO_VER_1(NV_USAGES_INFO_V1 = 4 * (2 + 4 * NVAPI_MAX_USAGES_PER_GPU), 1) }
126    nvversion! { NV_USAGES_INFO_VER = NV_USAGES_INFO_VER_1 }
127
128    pub type NV_USAGES_INFO = NV_USAGES_INFO_V1;
129
130    nvapi! {
131        pub type GPU_GetUsagesFn = extern "C" fn(hPhysicalGPU: NvPhysicalGpuHandle, pUsagesInfo: *mut NV_USAGES_INFO) -> NvAPI_Status;
132
133        /// Undocumented function. Probably deprecated and replaced with NvAPI_GPU_GetDynamicPstatesInfoEx()
134        pub unsafe fn NvAPI_GPU_GetUsages;
135    }
136
137    debug_array_impl! { [u32; NVAPI_MAX_CLOCKS_PER_GPU] }
138
139    nvstruct! {
140        pub struct NV_CLOCKS_INFO_V1 {
141            pub version: u32,
142            pub clocks: Array<[u32; NVAPI_MAX_CLOCKS_PER_GPU]>,
143        }
144    }
145
146    nvversion! { NV_CLOCKS_INFO_VER_1(NV_CLOCKS_INFO_V1 = 4 * (1 + NVAPI_MAX_CLOCKS_PER_GPU), 1) }
147    nvversion! { NV_CLOCKS_INFO_VER = NV_CLOCKS_INFO_VER_1 }
148
149    pub type NV_CLOCKS_INFO = NV_CLOCKS_INFO_V1;
150
151    nvapi! {
152        pub type GPU_GetAllClocksFn = extern "C" fn(hPhysicalGPU: NvPhysicalGpuHandle, pClocksInfo: *mut NV_CLOCKS_INFO) -> NvAPI_Status;
153
154        /// Undocumented function. Probably deprecated and replaced with NvAPI_GPU_GetAllClockFrequencies()
155        ///
156        /// memory_clock = clocks[8] * 0.001f;
157        ///
158        /// if clocks[30] != 0 {
159        /// core_clock = clocks[30] * 0.0005f
160        /// shader_clock = clocks[30] * 0.001f
161        /// } else {
162        /// core_clock = clocks[0] * 0.001f
163        /// shader_clock = clocks[14] * 0.001f
164        /// }
165        pub unsafe fn NvAPI_GPU_GetAllClocks;
166    }
167
168    nvstruct! {
169        pub struct NV_CLOCK_TABLE_GPU_DELTA {
170            pub a: u32,
171            pub b: u32,
172            pub c: u32,
173            pub d: u32,
174            pub e: u32,
175            pub freqDeltaKHz: i32,
176            pub g: u32,
177            pub h: u32,
178            pub i: u32,
179        }
180    }
181
182    debug_array_impl! { [NV_CLOCK_TABLE_GPU_DELTA; 80] }
183    debug_array_impl! { [u32; 1529] }
184
185    nvstruct! {
186        pub struct NV_CLOCK_TABLE_V1 {
187            pub version: u32,
188            pub mask: [u32; 4], // 80 bits (might be 8xu32?)
189            pub unknown: [u32; 12],
190            pub gpuDeltas: Array<[NV_CLOCK_TABLE_GPU_DELTA; 80]>,
191            pub memFilled: [u32; 23], // maybe only 4 max
192            pub memDeltas: [i32; 23],
193            pub unknown2: Array<[u32; 1529]>,
194        }
195    }
196
197    nvversion! { NV_CLOCK_TABLE_VER_1(NV_CLOCK_TABLE_V1 = 9248, 1) }
198    nvversion! { NV_CLOCK_TABLE_VER = NV_CLOCK_TABLE_VER_1 }
199
200    pub type NV_CLOCK_TABLE = NV_CLOCK_TABLE_V1;
201
202    nvapi! {
203        /// Pascal only
204        pub unsafe fn NvAPI_GPU_GetClockBoostTable(hPhysicalGPU: NvPhysicalGpuHandle, pClockTable: *mut NV_CLOCK_TABLE) -> NvAPI_Status;
205    }
206
207    nvapi! {
208        /// Pascal only
209        pub unsafe fn NvAPI_GPU_SetClockBoostTable(hPhysicalGPU: NvPhysicalGpuHandle, pClockTable: *const NV_CLOCK_TABLE) -> NvAPI_Status;
210    }
211
212    nvstruct! {
213        pub struct NV_CLOCK_RANGES_ENTRY {
214            pub a: u32,
215            pub clockType: super::NV_GPU_PUBLIC_CLOCK_ID,
216            pub c: u32,
217            pub d: u32,
218            pub e: u32,
219            pub f: u32,
220            pub g: u32,
221            pub h: u32,
222            pub i: u32,
223            pub j: u32,
224            pub rangeMax: i32,
225            pub rangeMin: i32,
226            pub tempMax: i32, // unsure
227            pub n: u32,
228            pub o: u32,
229            pub p: u32,
230            pub q: u32,
231            pub r: u32,
232        }
233    }
234
235    nvstruct! {
236        pub struct NV_CLOCK_RANGES_V1 {
237            pub version: u32,
238            pub numClocks: u32, // unsure
239            pub zero: [u32; 8],
240            pub entries: [NV_CLOCK_RANGES_ENTRY; 32],
241        }
242    }
243
244    nvversion! { NV_CLOCK_RANGES_VER_1(NV_CLOCK_RANGES_V1 = 2344, 1) }
245    nvversion! { NV_CLOCK_RANGES_VER = NV_CLOCK_RANGES_VER_1 }
246
247    pub type NV_CLOCK_RANGES = NV_CLOCK_RANGES_V1;
248
249    nvapi! {
250        /// Pascal only
251        pub unsafe fn NvAPI_GPU_GetClockBoostRanges(hPhysicalGPU: NvPhysicalGpuHandle, pClockRanges: *mut NV_CLOCK_RANGES) -> NvAPI_Status;
252    }
253
254    nvstruct! {
255        pub struct NV_CLOCK_MASKS_CLOCK {
256            pub a: u32,
257            pub b: u32,
258            pub c: u32,
259            pub d: u32,
260            pub memDelta: u32, // 1 for mem
261            pub gpuDelta: u32, // 1 for gpu
262        }
263    }
264
265    debug_array_impl! { [NV_CLOCK_MASKS_CLOCK; 80 + 23] }
266    debug_array_impl! { [u32; 916] }
267
268    nvstruct! {
269        pub struct NV_CLOCK_MASKS_V1 {
270            pub version: u32,
271            pub mask: [u32; 4], // 80 bits
272            pub unknown: [u32; 8],
273            pub clocks: Array<[NV_CLOCK_MASKS_CLOCK; 80 + 23]>,
274            pub unknown2: Array<[u32; 916]>,
275        }
276    }
277
278    nvversion! { NV_CLOCK_MASKS_VER_1(NV_CLOCK_MASKS_V1 = 6188, 1) }
279    nvversion! { NV_CLOCK_MASKS_VER = NV_CLOCK_MASKS_VER_1 }
280
281    pub type NV_CLOCK_MASKS = NV_CLOCK_MASKS_V1;
282
283    nvapi! {
284        /// Pascal only
285        pub unsafe fn NvAPI_GPU_GetClockBoostMask(hPhysicalGPU: NvPhysicalGpuHandle, pClockMasks: *mut NV_CLOCK_MASKS) -> NvAPI_Status;
286    }
287
288    nvenum! {
289        pub enum NV_GPU_CLOCK_LOCK_MODE / ClockLockMode {
290            NVAPI_GPU_CLOCK_LOCK_NONE / None = 0,
291            NVAPI_GPU_CLOCK_LOCK_MANUAL / Manual = 3,
292        }
293    }
294
295    nvstruct! {
296        pub struct NV_CLOCK_LOCK_ENTRY {
297            pub id: u32, // entry index
298            pub b: u32, // 0
299            pub mode: NV_GPU_CLOCK_LOCK_MODE, // 0 = default, 3 = manual voltage
300            pub d: u32, // 0
301            pub voltage_uV: u32, // 0 unless set explicitly, seems to always get set on the last/highest entry only
302            pub f: u32, // 0
303        }
304    }
305
306    nvstruct! {
307        // 2-030c: 0C 03 02 00 00 00 00 00 01 00 00 00 06 00 00 00
308        pub struct NV_CLOCK_LOCK_V2 {
309            pub version: u32,
310            pub flags: u32, // unknown, only see 0
311            pub count: u32,
312            pub entries: [NV_CLOCK_LOCK_ENTRY; 0x20],
313        }
314    }
315
316    pub type NV_CLOCK_LOCK = NV_CLOCK_LOCK_V2;
317
318    nvversion! { NV_CLOCK_LOCK_VER_2(NV_CLOCK_LOCK_V2 = 0x30c, 2) }
319    nvversion! { NV_CLOCK_LOCK_VER = NV_CLOCK_LOCK_VER_2 }
320
321    nvapi! {
322        /// Pascal only
323        pub unsafe fn NvAPI_GPU_GetClockBoostLock(hPhysicalGPU: NvPhysicalGpuHandle, pClockLocks: *mut NV_CLOCK_LOCK) -> NvAPI_Status;
324    }
325
326    nvapi! {
327        /// Pascal only
328        pub unsafe fn NvAPI_GPU_SetClockBoostLock(hPhysicalGPU: NvPhysicalGpuHandle, pClockLocks: *const NV_CLOCK_LOCK) -> NvAPI_Status;
329    }
330}