use std::{ffi::OsString, os::fd::{AsRawFd, OwnedFd}};
use crate::uapi::i915::DrmGemHandle;
use super::super::uapi;
use std::path::Path;
use std::fs::File;
pub use uapi::i915::GemIoctlError;
#[derive(Debug)]
pub struct DrmDeviceNode {
pub fd: OwnedFd,
pub path: Option<OsString>,
}
#[derive(Debug)]
pub struct GemHandle<'a> {
pub handle: DrmGemHandle,
pub node: &'a DrmDeviceNode,
}
impl GemHandle<'_> {
pub fn new(node: &DrmDeviceNode, size: u64) -> Option<GemHandle> {
uapi::i915::make_gem(node.fd.as_raw_fd(), size).map(|handle| GemHandle {
handle: handle,
node: &node,
})
}
pub fn from_handle(node: &DrmDeviceNode, handle: DrmGemHandle) -> Result<GemHandle, GemIoctlError> {
let is_valid = uapi::i915::gem_is_valid(node.fd.as_raw_fd(), handle);
if is_valid.is_ok() && is_valid.unwrap() {
let res = GemHandle {
handle: handle,
node: &node,
};
return Ok(res);
} else {
return Err(is_valid.err().unwrap_or(GemIoctlError::PermissionDenied));
}
}
pub fn close(&mut self) -> Result<(), i32> {
return uapi::i915::close_gem(self.node.fd.as_raw_fd(), self.handle);
}
pub fn has_tiling(&self) -> Result<bool, uapi::i915::GemIoctlError> {
uapi::i915::gem_has_tiling(self.node.fd.as_raw_fd(), self.handle)
}
pub fn is_valid(&self) -> Result<bool, GemIoctlError> {
uapi::i915::gem_is_valid(self.node.fd.as_raw_fd(), self.handle)
}
}
impl Drop for GemHandle<'_> {
fn drop(&mut self) {
let _ = self.close();
}
}
#[derive(Debug)]
pub struct Device {
pub node: DrmDeviceNode,
pub driver: uapi::DrmVersion,
}
#[derive(Debug)]
pub struct Engine {
pub info: uapi::i915::EngineInfo,
}
pub fn find_device() -> Option<Device> {
uapi::i915::find_node().and_then(|file| Device::from_path(file.path?))
}
impl Device {
pub fn from_fd(fd: OwnedFd) -> Option<Device> {
let driver = uapi::get_drm_version(fd.as_raw_fd())?;
Some(Device {
node: DrmDeviceNode {
fd: fd,
path: None,
},
driver: driver,
})
}
pub fn from_path(path: OsString) -> Option<Device> {
let file = File::open(Path::new(&path)).ok()?;
let driver = uapi::get_drm_version(file.as_raw_fd())?;
Some(Device {
node: DrmDeviceNode {
fd: OwnedFd::from(file),
path: Some(path),
},
driver: driver,
})
}
pub fn get_engines(&self) -> Option<Vec<Engine>> {
uapi::i915::get_engines(self.node.fd.as_raw_fd()).map(|engines| {
engines.into_iter().map(|engine_info| {
Engine {
info: engine_info,
}
}).collect()
})
}
pub fn get_param(&self, param: u32) -> Option<i32> {
uapi::i915::get_param(self.node.fd.as_raw_fd(), param as i32)
}
}