You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							115 lines
						
					
					
						
							3.3 KiB
						
					
					
				
			
		
		
	
	
							115 lines
						
					
					
						
							3.3 KiB
						
					
					
				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,
 | 
						|
}
 | 
						|
 | 
						|
/// An owned GEM handle that will be closed when dropped
 | 
						|
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> {
 | 
						|
        // Avoid invoking GemHandle::is_valid() here to prevent the drop() method from trying to drop an invalid handle
 | 
						|
        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::InvalidHandle));
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn close(self) -> Result<(), i32> {
 | 
						|
        return unsafe { uapi::i915::close_gem_ref(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) {
 | 
						|
        // Ignoring the close failing as an invalid Gem handle's drop is a no-op
 | 
						|
        _ = unsafe { uapi::i915::close_gem_ref(self.node.fd.as_raw_fd(), &self.handle) };
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#[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)
 | 
						|
    }
 | 
						|
} |