use status::NvAPI_Status;
use handles::NvPhysicalGpuHandle;
use types::BoolU32;
use gpu::clock;
pub const NVAPI_MAX_GPU_PSTATE20_PSTATES: usize = 16;
pub const NVAPI_MAX_GPU_PSTATE20_CLOCKS: usize = 8;
pub const NVAPI_MAX_GPU_PSTATE20_BASE_VOLTAGES: usize = 4;
nvstruct! {
pub struct NV_GPU_DYNAMIC_PSTATES_INFO_EX_UTILIZATION {
pub bIsPresent: BoolU32,
pub percentage: u32,
}
}
pub const NVAPI_MAX_GPU_UTILIZATIONS: usize = 8;
nvstruct! {
pub struct NV_GPU_DYNAMIC_PSTATES_INFO_EX {
pub version: u32,
pub flags: u32,
pub utilization: [NV_GPU_DYNAMIC_PSTATES_INFO_EX_UTILIZATION; NVAPI_MAX_GPU_UTILIZATIONS],
}
}
impl NV_GPU_DYNAMIC_PSTATES_INFO_EX {
pub fn flag_enabled(&self) -> bool {
self.flags & 1 != 0
}
}
nvenum! {
pub enum NV_GPU_UTILIZATION_DOMAIN_ID / UtilizationDomain {
NVAPI_GPU_UTILIZATION_DOMAIN_GPU / Graphics = 0,
NVAPI_GPU_UTILIZATION_DOMAIN_FB / FrameBuffer = 1,
NVAPI_GPU_UTILIZATION_DOMAIN_VID / VideoEngine = 2,
NVAPI_GPU_UTILIZATION_DOMAIN_BUS / BusInterface = 3,
}
}
nvenum_display! {
UtilizationDomain => {
FrameBuffer = "Frame Buffer",
VideoEngine = "Video Engine",
BusInterface = "Bus Interface",
_ = _,
}
}
impl UtilizationDomain {
pub fn from_clock(c: clock::PublicClockId) -> Option<Self> {
match c {
clock::PublicClockId::Graphics => Some(UtilizationDomain::Graphics),
clock::PublicClockId::Memory => Some(UtilizationDomain::FrameBuffer),
clock::PublicClockId::Video => Some(UtilizationDomain::VideoEngine),
_ => None,
}
}
}
nvversion! { NV_GPU_DYNAMIC_PSTATES_INFO_EX_VER(NV_GPU_DYNAMIC_PSTATES_INFO_EX = 4 * 2 + (4 * 2) * NVAPI_MAX_GPU_UTILIZATIONS, 1) }
nvapi! {
pub type GPU_GetDynamicPstatesInfoExFn = extern "C" fn(hPhysicalGPU: NvPhysicalGpuHandle, pDynamicPstatesInfoEx: *mut NV_GPU_DYNAMIC_PSTATES_INFO_EX) -> NvAPI_Status;
pub unsafe fn NvAPI_GPU_GetDynamicPstatesInfoEx;
}
nvenum! {
pub enum NV_GPU_PERF_PSTATE_ID / PstateId {
NVAPI_GPU_PERF_PSTATE_P0 / P0 = 0,
NVAPI_GPU_PERF_PSTATE_P1 / P1 = 1,
NVAPI_GPU_PERF_PSTATE_P2 / P2 = 2,
NVAPI_GPU_PERF_PSTATE_P3 / P3 = 3,
NVAPI_GPU_PERF_PSTATE_P4 / P4 = 4,
NVAPI_GPU_PERF_PSTATE_P5 / P5 = 5,
NVAPI_GPU_PERF_PSTATE_P6 / P6 = 6,
NVAPI_GPU_PERF_PSTATE_P7 / P7 = 7,
NVAPI_GPU_PERF_PSTATE_P8 / P8 = 8,
NVAPI_GPU_PERF_PSTATE_P9 / P9 = 9,
NVAPI_GPU_PERF_PSTATE_P10 / P10 = 10,
NVAPI_GPU_PERF_PSTATE_P11 / P11 = 11,
NVAPI_GPU_PERF_PSTATE_P12 / P12 = 12,
NVAPI_GPU_PERF_PSTATE_P13 / P13 = 13,
NVAPI_GPU_PERF_PSTATE_P14 / P14 = 14,
NVAPI_GPU_PERF_PSTATE_P15 / P15 = 15,
NVAPI_GPU_PERF_PSTATE_UNDEFINED / Undefined = clock::NVAPI_MAX_GPU_PERF_PSTATES,
NVAPI_GPU_PERF_PSTATE_ALL / All = clock::NVAPI_MAX_GPU_PERF_PSTATES + 1,
}
}
nvenum_display! {
PstateId => _
}
nvapi! {
pub type GPU_GetCurrentPstateFn = extern "C" fn(hPhysicalGPU: NvPhysicalGpuHandle, pCurrentPstate: *mut NV_GPU_PERF_PSTATE_ID) -> NvAPI_Status;
pub unsafe fn NvAPI_GPU_GetCurrentPstate;
}
nvenum! {
pub enum NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID / VoltageInfoDomain {
NVAPI_GPU_PERF_VOLTAGE_INFO_DOMAIN_CORE / Core = 0,
NVAPI_GPU_PERF_VOLTAGE_INFO_DOMAIN_UNDEFINED / Undefined = clock::NVAPI_MAX_GPU_PERF_VOLTAGES,
}
}
nvenum_display! {
VoltageInfoDomain => _
}
nvenum! {
pub enum NV_GPU_PERF_PSTATE20_CLOCK_TYPE_ID / PstateClockType {
NVAPI_GPU_PERF_PSTATE20_CLOCK_TYPE_SINGLE / Single = 0,
NVAPI_GPU_PERF_PSTATE20_CLOCK_TYPE_RANGE / Range = 1,
}
}
nvstruct! {
pub struct NV_GPU_PERF_PSTATES20_PARAM_DELTA {
pub value: i32,
pub min: i32,
pub max: i32,
}
}
nvstruct! {
pub struct NV_GPU_PSTATE20_CLOCK_ENTRY_V1 {
pub domainId: clock::NV_GPU_PUBLIC_CLOCK_ID,
pub typeId: NV_GPU_PERF_PSTATE20_CLOCK_TYPE_ID,
pub bIsEditable: BoolU32,
pub freqDelta_kHz: NV_GPU_PERF_PSTATES20_PARAM_DELTA,
pub data: NV_GPU_PSTATE20_CLOCK_ENTRY_DATA,
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct NV_GPU_PSTATE20_CLOCK_ENTRY_DATA(NV_GPU_PSTATE20_CLOCK_ENTRY_RANGE);
#[derive(Copy, Clone, Debug)]
pub enum NV_GPU_PSTATE20_CLOCK_ENTRY_DATA_VALUE {
Single(NV_GPU_PSTATE20_CLOCK_ENTRY_SINGLE),
Range(NV_GPU_PSTATE20_CLOCK_ENTRY_RANGE),
}
impl NV_GPU_PSTATE20_CLOCK_ENTRY_DATA {
pub fn get(&self, kind: PstateClockType) -> NV_GPU_PSTATE20_CLOCK_ENTRY_DATA_VALUE {
match kind {
PstateClockType::Single => NV_GPU_PSTATE20_CLOCK_ENTRY_DATA_VALUE::Single(
NV_GPU_PSTATE20_CLOCK_ENTRY_SINGLE {
freq_kHz: (self.0).minFreq_kHz,
}
),
PstateClockType::Range => NV_GPU_PSTATE20_CLOCK_ENTRY_DATA_VALUE::Range(self.0),
}
}
pub fn set_single(&mut self, value: NV_GPU_PSTATE20_CLOCK_ENTRY_SINGLE) {
(self.0).minFreq_kHz = value.freq_kHz;
}
pub fn set_range(&mut self, value: NV_GPU_PSTATE20_CLOCK_ENTRY_RANGE) {
self.0 = value;
}
}
nvstruct! {
pub struct NV_GPU_PSTATE20_CLOCK_ENTRY_SINGLE {
pub freq_kHz: u32,
}
}
nvstruct! {
pub struct NV_GPU_PSTATE20_CLOCK_ENTRY_RANGE {
pub minFreq_kHz: u32,
pub maxFreq_kHz: u32,
pub domainId: NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID,
pub minVoltage_uV: u32,
pub maxVoltage_uV: u32,
}
}
nvstruct! {
pub struct NV_GPU_PERF_PSTATE20_BASE_VOLTAGE_ENTRY_V1 {
pub domainId: NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID,
pub bIsEditable: BoolU32,
pub volt_uV: u32,
pub voltDelta_uV: NV_GPU_PERF_PSTATES20_PARAM_DELTA,
}
}
nvstruct! {
pub struct NV_GPU_PERF_PSTATES20_PSTATE {
pub pstateId: NV_GPU_PERF_PSTATE_ID,
pub bIsEditable: BoolU32,
pub clocks: [NV_GPU_PSTATE20_CLOCK_ENTRY_V1; NVAPI_MAX_GPU_PSTATE20_CLOCKS],
pub baseVoltages: [NV_GPU_PERF_PSTATE20_BASE_VOLTAGE_ENTRY_V1; NVAPI_MAX_GPU_PSTATE20_BASE_VOLTAGES],
}
}
nvstruct! {
pub struct NV_GPU_PERF_PSTATES20_INFO_V1 {
pub version: u32,
pub bIsEditable: BoolU32,
pub numPstates: u32,
pub numClocks: u32,
pub numBaseVoltages: u32,
pub pstates: [NV_GPU_PERF_PSTATES20_PSTATE; NVAPI_MAX_GPU_PSTATE20_PSTATES],
}
}
nvstruct! {
pub struct NV_GPU_PERF_PSTATES20_INFO_V2 {
pub v1: NV_GPU_PERF_PSTATES20_INFO_V1,
pub numVoltages: u32,
pub voltages: [NV_GPU_PERF_PSTATE20_BASE_VOLTAGE_ENTRY_V1; NVAPI_MAX_GPU_PSTATE20_BASE_VOLTAGES],
}
}
nvinherit! { NV_GPU_PERF_PSTATES20_INFO_V2(v1: NV_GPU_PERF_PSTATES20_INFO_V1) }
pub type NV_GPU_PERF_PSTATES20_INFO = NV_GPU_PERF_PSTATES20_INFO_V2;
const NV_GPU_PERF_PSTATES20_PARAM_DELTA_SIZE: usize = 4 * 3;
const NV_GPU_PERF_PSTATE20_BASE_VOLTAGE_ENTRY_V1_SIZE: usize = 3 * 4 + NV_GPU_PERF_PSTATES20_PARAM_DELTA_SIZE;
const NV_GPU_PSTATE20_CLOCK_ENTRY_DATA_SIZE: usize = 4 * 5;
const 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;
const 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;
const NV_GPU_PERF_PSTATES20_INFO_V1_SIZE: usize = 4 * 5 + NV_GPU_PERF_PSTATES20_PSTATE_SIZE * NVAPI_MAX_GPU_PSTATE20_PSTATES;
const 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;
nvversion! { NV_GPU_PERF_PSTATES20_INFO_VER1(NV_GPU_PERF_PSTATES20_INFO_V1 = NV_GPU_PERF_PSTATES20_INFO_V1_SIZE, 1) }
nvversion! { NV_GPU_PERF_PSTATES20_INFO_VER2(NV_GPU_PERF_PSTATES20_INFO_V2 = NV_GPU_PERF_PSTATES20_INFO_V2_SIZE, 2) }
nvversion! { NV_GPU_PERF_PSTATES20_INFO_VER3(NV_GPU_PERF_PSTATES20_INFO_V2 = NV_GPU_PERF_PSTATES20_INFO_V2_SIZE, 3) }
nvversion! { NV_GPU_PERF_PSTATES20_INFO_VER = NV_GPU_PERF_PSTATES20_INFO_VER3 }
nvapi! {
pub type GPU_GetPstates20Fn = extern "C" fn(hPhysicalGPU: NvPhysicalGpuHandle, pPstatesInfo: *mut NV_GPU_PERF_PSTATES20_INFO) -> NvAPI_Status;
pub unsafe fn NvAPI_GPU_GetPstates20;
}
pub mod private {
use status::NvAPI_Status;
nvapi! {
pub type GPU_SetPstates20Fn = extern "C" fn(hPhysicalGPU: super::NvPhysicalGpuHandle, pPstatesInfo: *const super::NV_GPU_PERF_PSTATES20_INFO) -> NvAPI_Status;
pub unsafe fn NvAPI_GPU_SetPstates20;
}
}