Added caches & tiling data fetching

master
itycodes 3 weeks ago
parent 11dba56a3f
commit 360ddc4462

@ -1,7 +1,6 @@
use std::{ffi::OsString, os::fd::{AsRawFd, OwnedFd}}; use std::{ffi::OsString, os::fd::{AsRawFd, OwnedFd}};
use crate::uapi::i915::DrmGemHandle; use crate::{native, uapi::{self, i915::DrmGemTileInfo}};
use uapi::i915::DrmGemHandle;
use super::super::uapi;
use std::path::Path; use std::path::Path;
use std::fs::File; use std::fs::File;
@ -19,6 +18,42 @@ pub struct GemHandle<'a> {
pub node: &'a DrmDeviceNode, pub node: &'a DrmDeviceNode,
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum DrmCacheType {
None = native::I915_CACHING_NONE,
Cached = native::I915_CACHING_CACHED,
Display = native::I915_CACHING_DISPLAY,
}
impl From<u32> for DrmCacheType {
fn from(val: u32) -> DrmCacheType {
match val {
native::I915_CACHING_NONE => DrmCacheType::None,
native::I915_CACHING_CACHED => DrmCacheType::Cached,
native::I915_CACHING_DISPLAY => DrmCacheType::Display,
_ => panic!("Invalid cache type encountered"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct GemTileInfo {
pub tiling_mode: u32,
pub swizzle_mode: u32,
pub phys_swizzle_mode: u32,
}
impl From<DrmGemTileInfo> for GemTileInfo {
fn from(info: DrmGemTileInfo) -> GemTileInfo {
GemTileInfo {
tiling_mode: info.tiling_mode,
swizzle_mode: info.swizzle_mode,
phys_swizzle_mode: info.phys_swizzle_mode,
}
}
}
/// An owned GEM handle that will be closed when dropped /// An owned GEM handle that will be closed when dropped
impl GemHandle<'_> { impl GemHandle<'_> {
pub fn new(node: &DrmDeviceNode, size: u64) -> Option<GemHandle> { pub fn new(node: &DrmDeviceNode, size: u64) -> Option<GemHandle> {
@ -47,6 +82,14 @@ impl GemHandle<'_> {
return unsafe { uapi::i915::close_gem_ref(self.node.fd.as_raw_fd(), &self.handle) }; return unsafe { uapi::i915::close_gem_ref(self.node.fd.as_raw_fd(), &self.handle) };
} }
pub fn get_tiling(&self) -> Result<GemTileInfo, GemIoctlError> {
uapi::i915::gem_get_tiling(self.node.fd.as_raw_fd(), &self.handle).map(|info| GemTileInfo::from(info))
}
pub fn get_caching(&self) -> Result<DrmCacheType, GemIoctlError> {
uapi::i915::gem_get_caching(self.node.fd.as_raw_fd(), &self.handle).map(|info| DrmCacheType::try_from(info).unwrap())
}
pub fn has_tiling(&self) -> Result<bool, uapi::i915::GemIoctlError> { pub fn has_tiling(&self) -> Result<bool, uapi::i915::GemIoctlError> {
uapi::i915::gem_has_tiling(self.node.fd.as_raw_fd(), &self.handle) uapi::i915::gem_has_tiling(self.node.fd.as_raw_fd(), &self.handle)
} }

@ -204,10 +204,19 @@ pub fn close_gem(fd: RawFd, handle: DrmGemHandle) -> Result<(), i32> {
pub enum GemIoctlError { pub enum GemIoctlError {
InvalidHandle, InvalidHandle,
PermissionDenied, PermissionDenied,
UnsupportedOnDevice,
UnsupportedOnHandle,
Unknown(i32), Unknown(i32),
} }
pub fn gem_has_tiling(fd: RawFd, handle: &DrmGemHandle) -> Result<bool, GemIoctlError> { #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct DrmGemTileInfo {
pub tiling_mode: u32,
pub swizzle_mode: u32,
pub phys_swizzle_mode: u32,
}
pub fn gem_get_tiling(fd: RawFd, handle: &DrmGemHandle) -> Result<DrmGemTileInfo, GemIoctlError> {
unsafe { unsafe {
let mut tiling = native::drm_i915_gem_get_tiling { let mut tiling = native::drm_i915_gem_get_tiling {
handle: handle.handle, handle: handle.handle,
@ -216,12 +225,47 @@ pub fn gem_has_tiling(fd: RawFd, handle: &DrmGemHandle) -> Result<bool, GemIoctl
phys_swizzle_mode: 0, phys_swizzle_mode: 0,
}; };
let res = libc::ioctl(fd, native::DRM_IOCTL_I915_GEM_GET_TILING, &mut tiling); let res = libc::ioctl(fd, native::DRM_IOCTL_I915_GEM_GET_TILING, &mut tiling);
let tile_info = DrmGemTileInfo {
tiling_mode: tiling.tiling_mode,
swizzle_mode: tiling.swizzle_mode,
phys_swizzle_mode: tiling.phys_swizzle_mode,
};
let errno = *libc::__errno_location();
match errno {
0 => Ok(tile_info),
libc::ENOENT => Err(GemIoctlError::InvalidHandle),
libc::EPERM => Err(GemIoctlError::PermissionDenied),
libc::EOPNOTSUPP => Err(GemIoctlError::UnsupportedOnDevice),
_ => Err(GemIoctlError::Unknown(res)),
}
}
}
pub fn gem_has_tiling(fd: RawFd, handle: &DrmGemHandle) -> Result<bool, GemIoctlError> {
let res = gem_get_tiling(fd, handle);
if res.is_ok() {
return Ok(true);
}
if res.is_err() && res.unwrap_err() == GemIoctlError::UnsupportedOnDevice {
return Ok(false);
}
return Err(res.unwrap_err());
}
pub fn gem_get_caching(fd: RawFd, handle: &DrmGemHandle) -> Result<u32, GemIoctlError> {
unsafe {
let mut caching = native::drm_i915_gem_caching {
handle: handle.handle,
caching: 0,
};
let res = libc::ioctl(fd, native::DRM_IOCTL_I915_GEM_GET_CACHING, &mut caching);
let errno = *libc::__errno_location(); let errno = *libc::__errno_location();
match errno { match errno {
0 => Ok(true), 0 => Ok(caching.caching),
libc::ENOENT => Err(GemIoctlError::InvalidHandle), libc::ENOENT => Err(GemIoctlError::InvalidHandle),
libc::EPERM => Err(GemIoctlError::PermissionDenied), libc::EPERM => Err(GemIoctlError::PermissionDenied),
libc::EINVAL => Ok(false), libc::ENODEV => Err(GemIoctlError::UnsupportedOnDevice),
libc::EOPNOTSUPP => Err(GemIoctlError::UnsupportedOnHandle),
_ => Err(GemIoctlError::Unknown(res)), _ => Err(GemIoctlError::Unknown(res)),
} }
} }
@ -237,7 +281,6 @@ pub fn gem_is_valid(fd: RawFd, handle: &DrmGemHandle) -> Result<bool, GemIoctlEr
return Ok(false); return Ok(false);
} }
println!("Unexpected error: {:?}", res.unwrap_err());
return Err(res.unwrap_err()); return Err(res.unwrap_err());
} }

Loading…
Cancel
Save