nvapi_sys/gpu/
pstate.rs

1use status::NvAPI_Status;
2use handles::NvPhysicalGpuHandle;
3use types::BoolU32;
4use gpu::clock;
5
6pub const NVAPI_MAX_GPU_PSTATE20_PSTATES: usize = 16;
7pub const NVAPI_MAX_GPU_PSTATE20_CLOCKS: usize = 8;
8pub const NVAPI_MAX_GPU_PSTATE20_BASE_VOLTAGES: usize = 4;
9
10nvstruct! {
11    pub struct NV_GPU_DYNAMIC_PSTATES_INFO_EX_UTILIZATION {
12        /// Set if this utilization domain is present on this GPU
13        pub bIsPresent: BoolU32,
14        /// Percentage of time where the domain is considered busy in the last 1 second interval
15        pub percentage: u32,
16    }
17}
18
19pub const NVAPI_MAX_GPU_UTILIZATIONS: usize = 8;
20
21nvstruct! {
22    /// Used in NvAPI_GPU_GetDynamicPstatesInfoEx().
23    pub struct NV_GPU_DYNAMIC_PSTATES_INFO_EX {
24        /// Structure version
25        pub version: u32,
26        /// bit 0 indicates if the dynamic Pstate is enabled or not
27        pub flags: u32,
28        pub utilization: [NV_GPU_DYNAMIC_PSTATES_INFO_EX_UTILIZATION; NVAPI_MAX_GPU_UTILIZATIONS],
29    }
30}
31
32impl NV_GPU_DYNAMIC_PSTATES_INFO_EX {
33    pub fn flag_enabled(&self) -> bool {
34        self.flags & 1 != 0
35    }
36}
37
38nvenum! {
39    /// Domain index into NV_GPU_DYNAMIC_PSTATES_INFO_EX.utilization.
40    ///
41    /// Definition missing from the nvapi headers for some reason.
42    pub enum NV_GPU_UTILIZATION_DOMAIN_ID / UtilizationDomain {
43        NVAPI_GPU_UTILIZATION_DOMAIN_GPU / Graphics = 0,
44        NVAPI_GPU_UTILIZATION_DOMAIN_FB / FrameBuffer = 1,
45        NVAPI_GPU_UTILIZATION_DOMAIN_VID / VideoEngine = 2,
46        NVAPI_GPU_UTILIZATION_DOMAIN_BUS / BusInterface = 3,
47    }
48}
49
50nvenum_display! {
51    UtilizationDomain => {
52        FrameBuffer = "Frame Buffer",
53        VideoEngine = "Video Engine",
54        BusInterface = "Bus Interface",
55        _ = _,
56    }
57}
58
59impl UtilizationDomain {
60    pub fn from_clock(c: clock::PublicClockId) -> Option<Self> {
61        match c {
62            clock::PublicClockId::Graphics => Some(UtilizationDomain::Graphics),
63            clock::PublicClockId::Memory => Some(UtilizationDomain::FrameBuffer),
64            clock::PublicClockId::Video => Some(UtilizationDomain::VideoEngine),
65            _ => None,
66        }
67    }
68}
69
70nvversion! { NV_GPU_DYNAMIC_PSTATES_INFO_EX_VER(NV_GPU_DYNAMIC_PSTATES_INFO_EX = 4 * 2 + (4 * 2) * NVAPI_MAX_GPU_UTILIZATIONS, 1) }
71
72nvapi! {
73    pub type GPU_GetDynamicPstatesInfoExFn = extern "C" fn(hPhysicalGPU: NvPhysicalGpuHandle, pDynamicPstatesInfoEx: *mut NV_GPU_DYNAMIC_PSTATES_INFO_EX) -> NvAPI_Status;
74
75    /// This API retrieves the NV_GPU_DYNAMIC_PSTATES_INFO_EX structure for the specified physical GPU.
76    ///
77    /// Each domain's info is indexed in the array.  For example:
78    /// - pDynamicPstatesInfo->utilization[NVAPI_GPU_UTILIZATION_DOMAIN_GPU] holds the info for the GPU domain.
79    ///
80    /// There are currently 4 domains for which GPU utilization and dynamic P-State thresholds can be retrieved:
81    /// - graphic engine (GPU)
82    /// - frame buffer (FB)
83    /// - video engine (VID)
84    /// - bus interface (BUS)
85    pub unsafe fn NvAPI_GPU_GetDynamicPstatesInfoEx;
86}
87
88nvenum! {
89    pub enum NV_GPU_PERF_PSTATE_ID / PstateId {
90        NVAPI_GPU_PERF_PSTATE_P0 / P0 = 0,
91        NVAPI_GPU_PERF_PSTATE_P1 / P1 = 1,
92        NVAPI_GPU_PERF_PSTATE_P2 / P2 = 2,
93        NVAPI_GPU_PERF_PSTATE_P3 / P3 = 3,
94        NVAPI_GPU_PERF_PSTATE_P4 / P4 = 4,
95        NVAPI_GPU_PERF_PSTATE_P5 / P5 = 5,
96        NVAPI_GPU_PERF_PSTATE_P6 / P6 = 6,
97        NVAPI_GPU_PERF_PSTATE_P7 / P7 = 7,
98        NVAPI_GPU_PERF_PSTATE_P8 / P8 = 8,
99        NVAPI_GPU_PERF_PSTATE_P9 / P9 = 9,
100        NVAPI_GPU_PERF_PSTATE_P10 / P10 = 10,
101        NVAPI_GPU_PERF_PSTATE_P11 / P11 = 11,
102        NVAPI_GPU_PERF_PSTATE_P12 / P12 = 12,
103        NVAPI_GPU_PERF_PSTATE_P13 / P13 = 13,
104        NVAPI_GPU_PERF_PSTATE_P14 / P14 = 14,
105        NVAPI_GPU_PERF_PSTATE_P15 / P15 = 15,
106        NVAPI_GPU_PERF_PSTATE_UNDEFINED / Undefined = clock::NVAPI_MAX_GPU_PERF_PSTATES,
107        NVAPI_GPU_PERF_PSTATE_ALL / All = clock::NVAPI_MAX_GPU_PERF_PSTATES + 1,
108    }
109}
110
111nvenum_display! {
112    PstateId => _
113}
114
115nvapi! {
116    pub type GPU_GetCurrentPstateFn = extern "C" fn(hPhysicalGPU: NvPhysicalGpuHandle, pCurrentPstate: *mut NV_GPU_PERF_PSTATE_ID) -> NvAPI_Status;
117
118    /// This function retrieves the current performance state (P-State).
119    pub unsafe fn NvAPI_GPU_GetCurrentPstate;
120}
121
122nvenum! {
123    pub enum NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID / VoltageInfoDomain {
124        NVAPI_GPU_PERF_VOLTAGE_INFO_DOMAIN_CORE / Core = 0,
125        // 1 - 15?
126        NVAPI_GPU_PERF_VOLTAGE_INFO_DOMAIN_UNDEFINED / Undefined = clock::NVAPI_MAX_GPU_PERF_VOLTAGES,
127    }
128}
129
130nvenum_display! {
131    VoltageInfoDomain => _
132}
133
134nvenum! {
135    /// Used to identify clock type
136    pub enum NV_GPU_PERF_PSTATE20_CLOCK_TYPE_ID / PstateClockType {
137        /// Clock domains that use single frequency value within given pstate
138        NVAPI_GPU_PERF_PSTATE20_CLOCK_TYPE_SINGLE / Single = 0,
139        /// Clock domains that allow range of frequency values within given pstate
140        NVAPI_GPU_PERF_PSTATE20_CLOCK_TYPE_RANGE / Range = 1,
141    }
142}
143
144nvstruct! {
145    /// Used to describe both voltage and frequency deltas
146    pub struct NV_GPU_PERF_PSTATES20_PARAM_DELTA {
147        /// Value of parameter delta (in respective units [kHz, uV])
148        pub value: i32,
149        /// Min value allowed for parameter delta (in respective units [kHz, uV])
150        pub min: i32,
151        /// Max value allowed for parameter delta (in respective units [kHz, uV])
152        pub max: i32,
153    }
154}
155
156nvstruct! {
157    /// Used to describe single clock entry
158    pub struct NV_GPU_PSTATE20_CLOCK_ENTRY_V1 {
159        /// ID of the clock domain
160        pub domainId: clock::NV_GPU_PUBLIC_CLOCK_ID,
161        /// Clock type ID
162        pub typeId: NV_GPU_PERF_PSTATE20_CLOCK_TYPE_ID,
163        pub bIsEditable: BoolU32,
164        /// Current frequency delta from nominal settings in (kHz)
165        pub freqDelta_kHz: NV_GPU_PERF_PSTATES20_PARAM_DELTA,
166        pub data: NV_GPU_PSTATE20_CLOCK_ENTRY_DATA,
167    }
168}
169
170#[repr(C)]
171#[derive(Copy, Clone, Debug)]
172pub struct NV_GPU_PSTATE20_CLOCK_ENTRY_DATA(NV_GPU_PSTATE20_CLOCK_ENTRY_RANGE);
173
174#[derive(Copy, Clone, Debug)]
175pub enum NV_GPU_PSTATE20_CLOCK_ENTRY_DATA_VALUE {
176    Single(NV_GPU_PSTATE20_CLOCK_ENTRY_SINGLE),
177    Range(NV_GPU_PSTATE20_CLOCK_ENTRY_RANGE),
178}
179
180impl NV_GPU_PSTATE20_CLOCK_ENTRY_DATA {
181    pub fn get(&self, kind: PstateClockType) -> NV_GPU_PSTATE20_CLOCK_ENTRY_DATA_VALUE {
182        match kind {
183            PstateClockType::Single => NV_GPU_PSTATE20_CLOCK_ENTRY_DATA_VALUE::Single(
184                NV_GPU_PSTATE20_CLOCK_ENTRY_SINGLE {
185                    freq_kHz: (self.0).minFreq_kHz,
186                }
187            ),
188            PstateClockType::Range => NV_GPU_PSTATE20_CLOCK_ENTRY_DATA_VALUE::Range(self.0),
189        }
190    }
191
192    pub fn set_single(&mut self, value: NV_GPU_PSTATE20_CLOCK_ENTRY_SINGLE) {
193        (self.0).minFreq_kHz = value.freq_kHz;
194    }
195
196    pub fn set_range(&mut self, value: NV_GPU_PSTATE20_CLOCK_ENTRY_RANGE) {
197        self.0 = value;
198    }
199}
200
201nvstruct! {
202    pub struct NV_GPU_PSTATE20_CLOCK_ENTRY_SINGLE {
203        /// Clock frequency within given pstate in (kHz)
204        pub freq_kHz: u32,
205    }
206}
207
208nvstruct! {
209    pub struct NV_GPU_PSTATE20_CLOCK_ENTRY_RANGE {
210        /// Min clock frequency within given pstate in (kHz)
211        pub minFreq_kHz: u32,
212        /// Max clock frequency within given pstate in (kHz)
213        pub maxFreq_kHz: u32,
214        /// Voltage domain ID
215        pub domainId: NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID,
216        /// Minimum value in (uV) required for this clock
217        pub minVoltage_uV: u32,
218        /// Maximum value in (uV) required for this clock
219        pub maxVoltage_uV: u32,
220    }
221}
222
223nvstruct! {
224    pub struct NV_GPU_PERF_PSTATE20_BASE_VOLTAGE_ENTRY_V1 {
225        /// ID of the voltage domain
226        pub domainId: NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID,
227        pub bIsEditable: BoolU32,
228        /// Current base voltage settings in [uV]
229        pub volt_uV: u32,
230        /// Current base voltage delta from nominal settings in [uV]
231        pub voltDelta_uV: NV_GPU_PERF_PSTATES20_PARAM_DELTA,
232    }
233}
234
235nvstruct! {
236    /// Performance state (P-State) settings
237    pub struct NV_GPU_PERF_PSTATES20_PSTATE {
238        /// ID of the P-State
239        pub pstateId: NV_GPU_PERF_PSTATE_ID,
240        /// Value must be 0 or 1.
241        /// These bits are reserved for future use (must be always 0)
242        pub bIsEditable: BoolU32,
243        /// Array of clock entries
244        /// Valid index range is 0 to numClocks-1
245        pub clocks: [NV_GPU_PSTATE20_CLOCK_ENTRY_V1; NVAPI_MAX_GPU_PSTATE20_CLOCKS],
246        /// Array of baseVoltage entries
247        /// Valid index range is 0 to numBaseVoltages-1
248        pub baseVoltages: [NV_GPU_PERF_PSTATE20_BASE_VOLTAGE_ENTRY_V1; NVAPI_MAX_GPU_PSTATE20_BASE_VOLTAGES],
249    }
250}
251
252nvstruct! {
253    /// Used in NvAPI_GPU_GetPstates20() interface call.
254    pub struct NV_GPU_PERF_PSTATES20_INFO_V1 {
255        /// Version info of the structure (NV_GPU_PERF_PSTATES20_INFO_VER<n>)
256        pub version: u32,
257        pub bIsEditable: BoolU32,
258        /// Number of populated pstates
259        pub numPstates: u32,
260        /// Number of populated clocks (per pstate)
261        pub numClocks: u32,
262        /// Number of populated base voltages (per pstate)
263        pub numBaseVoltages: u32,
264        /// Performance state (P-State) settings
265        /// Valid index range is 0 to numPstates-1
266        pub pstates: [NV_GPU_PERF_PSTATES20_PSTATE; NVAPI_MAX_GPU_PSTATE20_PSTATES],
267    }
268}
269
270nvstruct! {
271    /// Used in NvAPI_GPU_GetPstates20() interface call.
272    pub struct NV_GPU_PERF_PSTATES20_INFO_V2 {
273        pub v1: NV_GPU_PERF_PSTATES20_INFO_V1,
274        /// Number of populated voltages
275        pub numVoltages: u32,
276        /// OV settings - Please refer to NVIDIA over-volting recommendation to understand impact of this functionality
277        /// Valid index range is 0 to numVoltages-1
278        pub voltages: [NV_GPU_PERF_PSTATE20_BASE_VOLTAGE_ENTRY_V1; NVAPI_MAX_GPU_PSTATE20_BASE_VOLTAGES],
279    }
280}
281nvinherit! { NV_GPU_PERF_PSTATES20_INFO_V2(v1: NV_GPU_PERF_PSTATES20_INFO_V1) }
282
283pub type NV_GPU_PERF_PSTATES20_INFO = NV_GPU_PERF_PSTATES20_INFO_V2;
284
285// ugh why can't I just use const fns
286const NV_GPU_PERF_PSTATES20_PARAM_DELTA_SIZE: usize = 4 * 3;
287const NV_GPU_PERF_PSTATE20_BASE_VOLTAGE_ENTRY_V1_SIZE: usize = 3 * 4 + NV_GPU_PERF_PSTATES20_PARAM_DELTA_SIZE;
288const NV_GPU_PSTATE20_CLOCK_ENTRY_DATA_SIZE: usize = 4 * 5;
289const NV_GPU_PERF_PSTATE20_CLOCK_ENTRY_V1_SIZE: usize = 4 * 3 + NV_GPU_PERF_PSTATES20_PARAM_DELTA_SIZE + NV_GPU_PSTATE20_CLOCK_ENTRY_DATA_SIZE;
290const NV_GPU_PERF_PSTATES20_PSTATE_SIZE: usize = 4 * 2 + NV_GPU_PERF_PSTATE20_CLOCK_ENTRY_V1_SIZE * NVAPI_MAX_GPU_PSTATE20_CLOCKS + NV_GPU_PERF_PSTATE20_BASE_VOLTAGE_ENTRY_V1_SIZE * NVAPI_MAX_GPU_PSTATE20_BASE_VOLTAGES;
291const NV_GPU_PERF_PSTATES20_INFO_V1_SIZE: usize = 4 * 5 + NV_GPU_PERF_PSTATES20_PSTATE_SIZE * NVAPI_MAX_GPU_PSTATE20_PSTATES;
292const NV_GPU_PERF_PSTATES20_INFO_V2_SIZE: usize = NV_GPU_PERF_PSTATES20_INFO_V1_SIZE + 4 + (NV_GPU_PERF_PSTATE20_BASE_VOLTAGE_ENTRY_V1_SIZE) * NVAPI_MAX_GPU_PSTATE20_BASE_VOLTAGES;
293
294nvversion! { NV_GPU_PERF_PSTATES20_INFO_VER1(NV_GPU_PERF_PSTATES20_INFO_V1 = NV_GPU_PERF_PSTATES20_INFO_V1_SIZE, 1) }
295nvversion! { NV_GPU_PERF_PSTATES20_INFO_VER2(NV_GPU_PERF_PSTATES20_INFO_V2 = NV_GPU_PERF_PSTATES20_INFO_V2_SIZE, 2) }
296nvversion! { NV_GPU_PERF_PSTATES20_INFO_VER3(NV_GPU_PERF_PSTATES20_INFO_V2 = NV_GPU_PERF_PSTATES20_INFO_V2_SIZE, 3) }
297nvversion! { NV_GPU_PERF_PSTATES20_INFO_VER = NV_GPU_PERF_PSTATES20_INFO_VER3 }
298
299nvapi! {
300    pub type GPU_GetPstates20Fn = extern "C" fn(hPhysicalGPU: NvPhysicalGpuHandle, pPstatesInfo: *mut NV_GPU_PERF_PSTATES20_INFO) -> NvAPI_Status;
301
302    /// This API retrieves all performance states (P-States) 2.0 information.
303    ///
304    /// P-States are GPU active/executing performance capability states.
305    /// They range from P0 to P15, with P0 being the highest performance state,
306    /// and P15 being the lowest performance state. Each P-State, if available,
307    /// maps to a performance level. Not all P-States are available on a given system.
308    /// The definition of each P-States are currently as follow:
309    /// - P0/P1 - Maximum 3D performance
310    /// - P2/P3 - Balanced 3D performance-power
311    /// - P8 - Basic HD video playback
312    /// - P10 - DVD playback
313    /// - P12 - Minimum idle power consumption
314    pub unsafe fn NvAPI_GPU_GetPstates20;
315}
316
317/// Undocumented API
318pub mod private {
319    use status::NvAPI_Status;
320
321    nvapi! {
322        pub type GPU_SetPstates20Fn = extern "C" fn(hPhysicalGPU: super::NvPhysicalGpuHandle, pPstatesInfo: *const super::NV_GPU_PERF_PSTATES20_INFO) -> NvAPI_Status;
323
324        /// Undocumented private API
325        pub unsafe fn NvAPI_GPU_SetPstates20;
326    }
327}