Compare commits

...

2 Commits

Author SHA1 Message Date
itycodes 55612ec953 More tests
2 weeks ago
itycodes 360ddc4462 Added caches & tiling data fetching
2 weeks ago

@ -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());
} }

@ -126,4 +126,12 @@ fn test_i915_gpu_gem_has_tiling() {
let device = i915::find_device().expect("Failed to find i915 device"); let device = i915::find_device().expect("Failed to find i915 device");
let gem = i915::GemHandle::new(&device.node, 4096).expect("Failed to create gem handle"); let gem = i915::GemHandle::new(&device.node, 4096).expect("Failed to create gem handle");
assert!(gem.has_tiling().unwrap()); assert!(gem.has_tiling().unwrap());
}
#[test]
fn test_i915_gpu_fences() {
let device = i915::find_device().expect("Failed to find i915 device");
let num_fences = device.get_param(native::I915_PARAM_NUM_FENCES_AVAIL).expect("Failed to get fences");
println!("Number of fences: {}", num_fences);
assert!(num_fences > 0);
} }

@ -1,6 +1,5 @@
use intel_gpu::*; use intel_gpu::*;
use std::ffi::c_void; use std::ffi::c_void;
use std::ffi::CStr;
use nix::{self}; use nix::{self};
#[test] #[test]
@ -28,13 +27,6 @@ fn test_raw_drm_version() {
desc_len: 128, desc_len: 128,
}; };
assert!(libc::ioctl(fd, native::DRM_IOCTL_VERSION, &mut version) == 0); assert!(libc::ioctl(fd, native::DRM_IOCTL_VERSION, &mut version) == 0);
println!("version_major: {}, version_minor: {}, version_patchlevel: {}, name: {:?}, date: {:?}, desc: {:?}",
version.version_major,
version.version_minor,
version.version_patchlevel,
CStr::from_ptr(version.name),
CStr::from_ptr(version.date),
CStr::from_ptr(version.desc));
} }
} }

@ -1,9 +1,11 @@
#![allow(unused_imports)] #![allow(unused_imports)]
use gpu::i915::GemHandle;
use intel_gpu::*; use intel_gpu::*;
use uapi::i915; use uapi::i915::{self, DrmGemHandle};
use std::fs; use std::fs;
use std::{fs::File, os::fd::{AsRawFd, RawFd}}; use std::{fs::File, os::fd::{AsRawFd, RawFd}};
use std::thread;
#[test] #[test]
fn test_i915_uapi_get_version() { fn test_i915_uapi_get_version() {
@ -78,4 +80,26 @@ fn test_i915_uapi_gem_tiling() {
// TODO figure out which devices this holds for // TODO figure out which devices this holds for
assert!(i915::gem_has_tiling(node.fd.as_raw_fd(), &gem).is_ok_and(|e| e == true)); assert!(i915::gem_has_tiling(node.fd.as_raw_fd(), &gem).is_ok_and(|e| e == true));
i915::close_gem(node.fd.as_raw_fd(), gem).expect("Failed to close gem"); i915::close_gem(node.fd.as_raw_fd(), gem).expect("Failed to close gem");
}
#[test]
fn test_i915_uapi_gem_caching() {
let node = i915::find_node().expect("Failed to find i915 fd");
let gem = i915::make_gem(node.fd.as_raw_fd(), 4096).expect("Failed to make gem");
let caching = i915::gem_get_caching(node.fd.as_raw_fd(), &gem).expect("Failed to get caching");
assert!(caching > 0);
i915::close_gem(node.fd.as_raw_fd(), gem).expect("Failed to close gem");
}
#[test]
fn test_i915_uapi_gem_thread() {
let node = i915::find_node().expect("Failed to find i915 fd");
let gem = i915::make_gem(node.fd.as_raw_fd(), 4096).expect("Failed to make gem");
thread::scope(|s| {
let handle = s.spawn(|| {
assert!(i915::gem_is_valid(node.fd.as_raw_fd(), &gem).unwrap());
});
assert!(i915::gem_is_valid(node.fd.as_raw_fd(), &gem).unwrap());
handle.join().expect("Failed to join thread");
});
} }
Loading…
Cancel
Save