Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/gsync.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use sys::{self};
use sys::gsync::{self};

use crate::PhysicalGpu;

#[derive(Debug)]
pub struct GSyncDevice {
handle: sys::handles::NvGSyncDeviceHandle,
}

impl GSyncDevice {
pub fn new(handle: sys::handles::NvGSyncDeviceHandle) -> Self {
Self {handle}
}

pub fn handle(&self) -> &sys::handles::NvGSyncDeviceHandle {
&self.handle
}

pub fn get_sync_devices() -> sys::Result<Vec<GSyncDevice>> {
trace!("gsync.enumerate()");
let mut handles = [Default::default(); sys::types::NVAPI_MAX_GSYNC_DEVICES];
let mut len = 0;
match unsafe { gsync::NvAPI_GSync_EnumSyncDevices(&mut handles, &mut len) } {
status => sys::status_result(status).map(move |_| handles[..len as usize].iter().cloned().map(|x| GSyncDevice::new(x)).collect()),
}
}

pub fn get_sync_status(&self, gpu: PhysicalGpu) -> sys::Result<gsync::NV_GSYNC_STATUS> {
let mut status: gsync::NV_GSYNC_STATUS::default();
status.version = gsync::NV_GSYNC_STATUS_VER;
match unsafe {
gsync::NvAPI_GSync_GetSyncStatus(*self.handle(), *gpu.handle(), &mut status)
} {
status => sys::status_result(status)
}
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod pstate;
mod clock;
mod thermal;
mod gpu;
mod gsync;
mod info;
#[cfg(feature = "i2c")]
mod i2c_impl;
Expand Down
228 changes: 228 additions & 0 deletions sys/src/gsync.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
use status::NvAPI_Status;
use handles::NvPhysicalGpuHandle;
use handles::NvGSyncDeviceHandle;

nvstruct! {
pub struct NV_GSYNC_CAPABILITIES_V1 {
version: u32,
boardId: u32,
revision: u32,
capFlags: u32,
}
}

const NV_GSYNC_CAPABILITIES_V1_SIZE: usize = 4 * 4;

nvstruct! {
pub struct NV_GSYNC_CAPABILITIES_V2 {
v1: NV_GSYNC_CAPABILITIES_V1,
extendedRevision: u32,
}
}

nvinherit! { NV_GSYNC_CAPABILITIES_V2(v1: NV_GSYNC_CAPABILITIES_V1) }

const NV_GSYNC_CAPABILITIES_V2_SIZE: usize = NV_GSYNC_CAPABILITIES_V1_SIZE + 4;

pub type NV_GSYNC_CAPABILITIES = NV_GSYNC_CAPABILITIES_V2;

nvversion! { NV_GSYNC_CAPABILITIES_VER_1(NV_GSYNC_CAPABILITIES_V1 = NV_GSYNC_CAPABILITIES_V1_SIZE, 1) }
nvversion! { NV_GSYNC_CAPABILITIES_VER_2(NV_GSYNC_CAPABILITIES_V2 = NV_GSYNC_CAPABILITIES_V2_SIZE, 2) }
nvversion! { NV_GSYNC_CAPABILITIES_VER = NV_GSYNC_CAPABILITIES_VER_2 }

nvenum! {
pub enum NVAPI_GSYNC_DISPLAY_SYNC_STATE / DisplaySyncState {
NVAPI_GSYNC_DISPLAY_SYNC_STATE_UNSYNCED / Unsynced = 0,
NVAPI_GSYNC_DISPLAY_SYNC_STATE_SLAVE / Slave = 1,
NVAPI_GSYNC_DISPLAY_SYNC_STATE_MASTER / Master = 2,
}
}

nvstruct! {
pub struct NV_GSYNC_DISPLAY {
version: u32,
displayId: u32,
isMasterable: u32,
reserved: u32,
syncState: NVAPI_GSYNC_DISPLAY_SYNC_STATE,
}
}

nvenum! {
pub enum NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR / TopologyConnector {
NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR_NONE / None = 0,
NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR_PRIMARY / Primary = 1,
NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR_SECONDARY / Secondary = 2,
NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR_TERTIARY / Tertiary = 3,
NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR_QUARTERNARY / Quarternary = 4,
}
}

nvstruct! {
pub struct NV_GSYNC_GPU {
version: u32,
hPhysicalGpu: NvPhysicalGpuHandle,
connector: NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR,
hProxyPhysicalGpu: NvPhysicalGpuHandle,
isSynced: u32,
reserved: u32,
}
}

nvenum! {
pub enum NVAPI_GSYNC_POLARITY / Polarity {
NVAPI_GSYNC_POLARITY_RISING_EDGE / RisingEdge = 0,
NVAPI_GSYNC_POLARITY_FALLING_EDGE / FallingEdge = 1,
NVAPI_GSYNC_POLARITY_BOTH_EDGES / BothEdges = 2,
}
}

nvenum! {
pub enum NVAPI_GSYNC_VIDEO_MODE / VideoMode {
NVAPI_GSYNC_VIDEO_MODE_NONE / None = 0,
NVAPI_GSYNC_VIDEO_MODE_TTL / TTL = 1,
NVAPI_GSYNC_VIDEO_MODE_NTSCPALSECAM / NtscPalCam = 2,
NVAPI_GSYNC_VIDEO_MODE_HDTV / Hdtv = 3,
NVAPI_GSYNC_VIDEO_MODE_COMPOSITE / Composite = 4,
}
}

nvenum! {
pub enum NVAPI_GSYNC_SYNC_SOURCE / SyncSource {
NVAPI_GSYNC_SYNC_SOURCE_VSYNC / VSync = 0,
NVAPI_GSYNC_SYNC_SOURCE_HOUSESYNC / HouseSync = 1,
}
}

nvstruct! {
pub struct NV_GSYNC_DELAY {
version: u32,
numLines: u32,
numPixels: u32,
maxLines: u32,
minPixels: u32,
}
}

nvstruct! {
pub struct NV_GSYNC_CONTROL_PARAMS {
version: u32,
polarity: NVAPI_GSYNC_POLARITY,
vmode: NVAPI_GSYNC_VIDEO_MODE,
interval: u32,
source: NVAPI_GSYNC_SYNC_SOURCE,
interlaceMode: u32,
syncSourceIsOutput: u32,
reserved: u32,
syncSkew: NV_GSYNC_DELAY,
startupDelay: NV_GSYNC_DELAY,
}
}

nvenum! {
pub enum NVAPI_GSYNC_DELAY_TYPE / DelayType {
NVAPI_GSYNC_DELAY_TYPE_UNKNOWN / Unknown = 0,
NVAPI_GSYNC_DELAY_TYPE_SYNC_SKEW / SyncSkew = 1,
NVAPI_GSYNC_DELAY_TYPE_STARTUP / Startup = 2,
}
}

nvstruct! {
#[derive(Debug, Default)]
pub struct NV_GSYNC_STATUS {
pub version: u32,
pub bIsSynced: u32,
pub bIsStereoSynced: u32,
pub bIsSyncSignalAvailable: u32,
}
}

// TODO: this most likely wont work and needs to be updated.
nvversion! { NV_GSYNC_STATUS_VER(NV_GSYNC_STATUS = 0, 1) /* temp */}

nvenum! {
pub enum NVAPI_GSYNC_RJ45_IO / RJ45_IO {
NVAPI_GSYNC_RJ45_OUTPUT / Output = 0,
NVAPI_GSYNC_RJ45_INPUT / Input = 1,
NVAPI_GSYNC_RJ45_UNUSED / Unused = 2,
}
}

pub const NVAPI_MAX_RJ45_PER_GSYNC: usize = 2;

nvstruct! {
pub struct NV_GSYNC_STATUS_PARAMS_V1 {
version: u32,
refreshRate: u32,
RJ45_IO: [NVAPI_GSYNC_RJ45_IO; NVAPI_MAX_RJ45_PER_GSYNC],
RJ45_Ethernet: [u32; NVAPI_MAX_RJ45_PER_GSYNC],
houseSyncIncoming: u32,
bHouseSync: u32,
}
}

const NV_GSYNC_STATUS_PARAMS_V1_SIZE: usize = std::mem::size_of::<NV_GSYNC_STATUS_PARAMS_V1>();

nvstruct! {
pub struct NV_GSYNC_STATUS_PARAMS_V2 {
v1: NV_GSYNC_STATUS_PARAMS_V1,
bInternalSlave: u32,
reserved: u32,
}
}

nvinherit! { NV_GSYNC_STATUS_PARAMS_V2(v1: NV_GSYNC_STATUS_PARAMS_V1) }

const NV_GSYNC_STATUS_PARAMS_V2_SIZE: usize = std::mem::size_of::<NV_GSYNC_STATUS_PARAMS_V2>();

pub type NV_GSYNC_STATUS_PARAMS = NV_GSYNC_STATUS_PARAMS_V2;

nvversion! { NV_GSYNC_STATUS_PARAMS_VER_1(NV_GSYNC_STATUS_PARAMS_V1 = NV_GSYNC_STATUS_PARAMS_V1_SIZE, 1) }
nvversion! { NV_GSYNC_STATUS_PARAMS_VER_2(NV_GSYNC_STATUS_PARAMS_V2 = NV_GSYNC_STATUS_PARAMS_V2_SIZE, 2) }
nvversion! { NV_GSYNC_STATUS_PARAMS_VER = NV_GSYNC_STATUS_PARAMS_VER_2 }

nvapi! {
pub type GSync_EnumSyncDevicesFn = extern "C" fn(nvGSyncHandles: *mut [NvGSyncDeviceHandle; super::types::NVAPI_MAX_GSYNC_DEVICES], gsyncCount: *mut u32) -> NvAPI_Status;
pub unsafe fn NvAPI_GSync_EnumSyncDevices;
}

nvapi! {
pub type GSync_QueryCapabilitiesFn = extern "C" fn(hNvGSyncDevice: NvGSyncDeviceHandle, pNvGSyncCapabilities: *mut NV_GSYNC_CAPABILITIES) -> NvAPI_Status;
pub unsafe fn NvAPI_GSync_QueryCapabilities;
}

nvapi! {
pub type GSync_GetTopologyFn = extern "C" fn(hNvGSyncDevice: NvGSyncDeviceHandle, gsyncGpuCount: *mut u32, gsyncGPUs: *mut NV_GSYNC_GPU, gsyncDisplayCount: u32, gsyncDisplays: *mut NV_GSYNC_DISPLAY) -> NvAPI_Status;
pub unsafe fn NvAPI_GSync_GetTopology;
}

nvapi! {
pub type GSync_SetSyncStateSettingsFn = extern "C" fn(gsyncDisplayCount: u32, pGsyncDisplays: NV_GSYNC_DISPLAY, flags: u32) -> NvAPI_Status;
pub unsafe fn NvAPI_GSync_SetSyncStateSettings;
}

nvapi! {
pub type GSync_GetControlParametersFn = extern "C" fn(hNvGSyncDevice: NvGSyncDeviceHandle, pGsyncControls: *mut NV_GSYNC_CONTROL_PARAMS) -> NvAPI_Status;
pub unsafe fn NvAPI_GSync_GetControlParameters;
}

nvapi! {
pub type GSync_SetControlParametersFn = extern "C" fn(hNvGSyncDevice: NvGSyncDeviceHandle, pGsyncControls: *mut NV_GSYNC_CONTROL_PARAMS) -> NvAPI_Status;
pub unsafe fn NvAPI_GSync_SetControlParameters;
}

nvapi! {
// Parameter should be pointer?
pub type GSync_AdjustSyncDelayFn = extern "C" fn(hNvGSyncDevice: NvGSyncDeviceHandle, delayType: NVAPI_GSYNC_DELAY_TYPE, pGsyncDelay: *mut NV_GSYNC_DELAY, syncSteps: *mut u32) -> NvAPI_Status;
pub unsafe fn NvAPI_GSync_AdjustSyncDelay;
}

nvapi! {
pub type GSync_GetSyncStatusFn = extern "C" fn(hNvGSyncDevice: NvGSyncDeviceHandle, hPhysicalGpu: NvPhysicalGpuHandle, status: *mut NV_GSYNC_STATUS) -> NvAPI_Status;
pub unsafe fn NvAPI_GSync_GetSyncStatus;
}

nvapi! {
pub type GSync_GetStatusParametersFn = extern "C" fn(hNvGSyncDevice: NvGSyncDeviceHandle, pStatusParams: *mut NV_GSYNC_STATUS_PARAMS) -> NvAPI_Status;
pub unsafe fn NvAPI_GSync_GetStatusParameters;
}
1 change: 1 addition & 0 deletions sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub mod nvid;
pub mod nvapi;
pub mod status;
pub mod types;
pub mod gsync;

/// NVAPI Handles - These handles are retrieved from various calls and passed in
/// to others in NvAPI These are meant to be opaque types. Do not assume they
Expand Down
11 changes: 11 additions & 0 deletions sys/src/nvid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -650,4 +650,15 @@ Unknown_36E39E6B = 0x36e39e6b,
/// `GPU_GetRasterOperators(hGpu, *mut u32)`
Unknown_GetROPCount = 0xfdc129fa,

//source: nvapi.h
NvAPI_GSync_EnumSyncDevices = 0x0D9639601,
NvAPI_GSync_QueryCapabilities = 0x44A3F1D1,
NvAPI_GSync_GetTopology = 0x4562BC38,
NvAPI_GSync_SetSyncStateSettings = 0x60ACDFDD,
NvAPI_GSync_GetControlParameters = 0x16DE1C6A,
NvAPI_GSync_SetControlParameters = 0x8BBFF88B,
NvAPI_GSync_AdjustSyncDelay = 0x2D11FF51,
NvAPI_GSync_GetSyncStatus = 0x0F1F5B434,
NvAPI_GSync_GetStatusParameters = 0x70D404EC,

}
2 changes: 2 additions & 0 deletions sys/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ pub const NVAPI_MAX_ACPI_IDS: usize = 16;
pub const NVAPI_MAX_VIEW_MODES: usize = 8;
pub const NVAPI_MAX_HEADS_PER_GPU: usize = 32;

pub const NVAPI_MAX_GSYNC_DEVICES: usize = 4;

/// Maximum heads, each with `NVAPI_DESKTOP_RES` resolution
pub const NV_MAX_HEADS: usize = 4;
/// Maximum number of input video streams, each with a `NVAPI_VIDEO_SRC_INFO`
Expand Down