commit
						ca3f6c4d60
					
				| @ -0,0 +1 @@ | ||||
| /target | ||||
| @ -0,0 +1,306 @@ | ||||
| # This file is automatically @generated by Cargo. | ||||
| # It is not intended for manual editing. | ||||
| version = 3 | ||||
| 
 | ||||
| [[package]] | ||||
| name = "aho-corasick" | ||||
| version = "1.1.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" | ||||
| dependencies = [ | ||||
|  "memchr", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "bindgen" | ||||
| version = "0.70.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" | ||||
| dependencies = [ | ||||
|  "bitflags", | ||||
|  "cexpr", | ||||
|  "clang-sys", | ||||
|  "itertools", | ||||
|  "log", | ||||
|  "prettyplease", | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "regex", | ||||
|  "rustc-hash", | ||||
|  "shlex", | ||||
|  "syn", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "bitflags" | ||||
| version = "2.6.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "cexpr" | ||||
| version = "0.6.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" | ||||
| dependencies = [ | ||||
|  "nom", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "cfg-if" | ||||
| version = "1.0.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "cfg_aliases" | ||||
| version = "0.2.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "clang-sys" | ||||
| version = "1.8.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" | ||||
| dependencies = [ | ||||
|  "glob", | ||||
|  "libc", | ||||
|  "libloading", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "either" | ||||
| version = "1.13.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "glob" | ||||
| version = "0.3.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "intel_gpu_uapi" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "bindgen", | ||||
|  "libc", | ||||
|  "nix", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "itertools" | ||||
| version = "0.13.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" | ||||
| dependencies = [ | ||||
|  "either", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "libc" | ||||
| version = "0.2.161" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "libloading" | ||||
| version = "0.8.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" | ||||
| dependencies = [ | ||||
|  "cfg-if", | ||||
|  "windows-targets", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "log" | ||||
| version = "0.4.22" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "memchr" | ||||
| version = "2.7.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "minimal-lexical" | ||||
| version = "0.2.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "nix" | ||||
| version = "0.29.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" | ||||
| dependencies = [ | ||||
|  "bitflags", | ||||
|  "cfg-if", | ||||
|  "cfg_aliases", | ||||
|  "libc", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "nom" | ||||
| version = "7.1.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" | ||||
| dependencies = [ | ||||
|  "memchr", | ||||
|  "minimal-lexical", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "prettyplease" | ||||
| version = "0.2.25" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "syn", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "proc-macro2" | ||||
| version = "1.0.89" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" | ||||
| dependencies = [ | ||||
|  "unicode-ident", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "quote" | ||||
| version = "1.0.37" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "regex" | ||||
| version = "1.11.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" | ||||
| dependencies = [ | ||||
|  "aho-corasick", | ||||
|  "memchr", | ||||
|  "regex-automata", | ||||
|  "regex-syntax", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "regex-automata" | ||||
| version = "0.4.8" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" | ||||
| dependencies = [ | ||||
|  "aho-corasick", | ||||
|  "memchr", | ||||
|  "regex-syntax", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "regex-syntax" | ||||
| version = "0.8.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "rustc-hash" | ||||
| version = "1.1.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "shlex" | ||||
| version = "1.3.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "syn" | ||||
| version = "2.0.87" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "unicode-ident", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "unicode-ident" | ||||
| version = "1.0.13" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows-targets" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" | ||||
| dependencies = [ | ||||
|  "windows_aarch64_gnullvm", | ||||
|  "windows_aarch64_msvc", | ||||
|  "windows_i686_gnu", | ||||
|  "windows_i686_gnullvm", | ||||
|  "windows_i686_msvc", | ||||
|  "windows_x86_64_gnu", | ||||
|  "windows_x86_64_gnullvm", | ||||
|  "windows_x86_64_msvc", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_aarch64_gnullvm" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_aarch64_msvc" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_i686_gnu" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_i686_gnullvm" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_i686_msvc" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_x86_64_gnu" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_x86_64_gnullvm" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_x86_64_msvc" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" | ||||
| @ -0,0 +1,15 @@ | ||||
| [package] | ||||
| name = "intel_gpu_uapi" | ||||
| version = "0.1.0" | ||||
| edition = "2021" | ||||
| 
 | ||||
| [dependencies] | ||||
| libc = "0.2.161" | ||||
| 
 | ||||
| [build-dependencies] | ||||
| bindgen = "0.70.1" | ||||
| 
 | ||||
| [dev-dependencies] | ||||
| libc = "0.2.161" | ||||
| nix = { version = "0.29.0", features = ["fs"] } | ||||
| 
 | ||||
| @ -0,0 +1,15 @@ | ||||
| use std::env; | ||||
| use std::path::PathBuf; | ||||
| 
 | ||||
| fn main() { | ||||
|     let bindings = bindgen::Builder::default() | ||||
|         .header("clib/wrapper.h") | ||||
|         .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) | ||||
|         .generate() | ||||
|         .expect("Unable to generate bindings"); | ||||
| 
 | ||||
|     let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); | ||||
|     bindings | ||||
|         .write_to_file(out_path.join("bindings.rs")) | ||||
|         .expect("Couldn't write bindings!"); | ||||
| } | ||||
| @ -0,0 +1,14 @@ | ||||
| #include <libdrm/drm.h> | ||||
| #include <libdrm/i915_drm.h> | ||||
| 
 | ||||
| const __u64 _DRM_IOCTL_VERSION = DRM_IOCTL_VERSION; | ||||
| #undef DRM_IOCTL_VERSION | ||||
| const __u64 DRM_IOCTL_VERSION = _DRM_IOCTL_VERSION; | ||||
| 
 | ||||
| const __u64 _DRM_IOCTL_I915_QUERY = DRM_IOCTL_I915_QUERY; | ||||
| #undef DRM_IOCTL_I915_QUERY | ||||
| const __u64 DRM_IOCTL_I915_QUERY = _DRM_IOCTL_I915_QUERY; | ||||
| 
 | ||||
| const __u64 _DRM_IOCTL_I915_GETPARAM = DRM_IOCTL_I915_GETPARAM; | ||||
| #undef DRM_IOCTL_I915_GETPARAM | ||||
| const __u64 DRM_IOCTL_I915_GETPARAM = _DRM_IOCTL_I915_GETPARAM; | ||||
| @ -0,0 +1,61 @@ | ||||
| use std::{ffi::OsString, os::fd::{AsRawFd, OwnedFd}}; | ||||
| use super::super::uapi; | ||||
| use std::path::Path; | ||||
| use std::fs::File; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct DrmDeviceNode { | ||||
|     pub fd: OwnedFd, | ||||
|     pub path: Option<OsString>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Device { | ||||
|     pub node: DrmDeviceNode, | ||||
|     pub driver: uapi::DrmVersion, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Engine { | ||||
|     pub info: uapi::DrmI915EngineInfo, | ||||
| } | ||||
| 
 | ||||
| pub fn find_i915_device() -> Option<Device> { | ||||
|     uapi::find_i915_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::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::get_param(self.node.fd.as_raw_fd(), param as i32) | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1 @@ | ||||
| pub mod drm_i915; | ||||
| @ -0,0 +1,3 @@ | ||||
| pub mod native; | ||||
| pub mod uapi; | ||||
| pub mod gpu; | ||||
| @ -0,0 +1,4 @@ | ||||
| #![allow(non_upper_case_globals)] | ||||
| #![allow(non_camel_case_types)] | ||||
| #![allow(non_snake_case)] | ||||
| include!(concat!(env!("OUT_DIR"), "/bindings.rs")); | ||||
| @ -0,0 +1,209 @@ | ||||
| #![allow(non_camel_case_types)] | ||||
| 
 | ||||
| use std::os::fd::{AsRawFd, OwnedFd, RawFd}; | ||||
| use std::ffi::{CStr, OsString, c_void}; | ||||
| use libc; | ||||
| use crate::gpu::drm_i915::DrmDeviceNode; | ||||
| 
 | ||||
| use super::native; | ||||
| use std::fs; | ||||
| use std::fs::File; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct DrmVersion { | ||||
|     pub version_major: i32, | ||||
|     pub version_minor: i32, | ||||
|     pub version_patchlevel: i32, | ||||
|     pub name: OsString, | ||||
|     pub date: OsString, | ||||
|     pub desc: OsString, | ||||
| } | ||||
| 
 | ||||
| pub fn get_drm_version(fd: RawFd) -> Option<DrmVersion> { | ||||
|     unsafe { | ||||
|         let name_vec = libc::malloc(128); | ||||
|         libc::memset(name_vec, 0, 128); | ||||
|         let date_vec = libc::malloc(128); | ||||
|         libc::memset(date_vec, 0, 128); | ||||
|         let desc_vec = libc::malloc(128); | ||||
|         libc::memset(desc_vec, 0, 128); | ||||
|         
 | ||||
|         let mut version = native::drm_version { 
 | ||||
|             version_major: 0, | ||||
|             version_minor: 0, | ||||
|             version_patchlevel: 0, | ||||
|             name: name_vec as *mut i8, | ||||
|             date: date_vec as *mut i8, | ||||
|             desc: desc_vec as *mut i8, | ||||
|             name_len: 128, | ||||
|             date_len: 128, | ||||
|             desc_len: 128, | ||||
|         }; | ||||
|         let res_val = libc::ioctl(fd, native::DRM_IOCTL_VERSION, &mut version) == 0; | ||||
|         let res = if res_val { | ||||
|             let name = CStr::from_ptr(version.name).to_str().expect("Failed to convert name"); | ||||
|             let date = CStr::from_ptr(version.date).to_str().expect("Failed to convert date"); | ||||
|             let desc = CStr::from_ptr(version.desc).to_str().expect("Failed to convert desc"); | ||||
|             let drm_version = DrmVersion { | ||||
|                 version_major: version.version_major, | ||||
|                 version_minor: version.version_minor, | ||||
|                 version_patchlevel: version.version_patchlevel, | ||||
|                 name: OsString::from(name.to_string()), | ||||
|                 date: OsString::from(date.to_string()), | ||||
|                 desc: OsString::from(desc.to_string()), | ||||
|             }; | ||||
|             Some(drm_version) | ||||
|         } else {None}; | ||||
|         res | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||||
| pub enum DrmI915EngineClass { | ||||
|     Render, Copy, Video, VideoEnhance, Compute, Invalid | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct DrmI915EngineClassInstance { | ||||
|     pub engine_class: DrmI915EngineClass, | ||||
|     pub engine_instance: u16, | ||||
| } | ||||
| 
 | ||||
| pub type DrmI915EngineInfoFlags = u64; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct DrmI915EngineInfo { | ||||
|     pub engine: DrmI915EngineClassInstance, | ||||
|     pub logical_instance: u16, | ||||
|     pub flags: DrmI915EngineInfoFlags, | ||||
|     pub capabilities: u64, | ||||
| } | ||||
| 
 | ||||
| fn engine_class_from_u16(engine_class: u16) -> DrmI915EngineClass { | ||||
|     match engine_class { | ||||
|         0 => DrmI915EngineClass::Render, | ||||
|         1 => DrmI915EngineClass::Copy, | ||||
|         2 => DrmI915EngineClass::Video, | ||||
|         3 => DrmI915EngineClass::VideoEnhance, | ||||
|         4 => DrmI915EngineClass::Compute, | ||||
|         _ => DrmI915EngineClass::Invalid, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn engine_class_instance_from_native(engine_class_instance: native::i915_engine_class_instance) -> DrmI915EngineClassInstance { | ||||
|     DrmI915EngineClassInstance { | ||||
|         engine_class: engine_class_from_u16(engine_class_instance.engine_class), | ||||
|         engine_instance: engine_class_instance.engine_instance, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn engine_info_from_native(engine_info: native::drm_i915_engine_info) -> DrmI915EngineInfo { | ||||
|     DrmI915EngineInfo { | ||||
|         engine: engine_class_instance_from_native(engine_info.engine), | ||||
|         logical_instance: engine_info.logical_instance, | ||||
|         flags: engine_info.flags, | ||||
|         capabilities: engine_info.capabilities, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl DrmI915EngineInfo { | ||||
|     pub fn to_native(&self) -> native::drm_i915_engine_info { | ||||
|         native::drm_i915_engine_info { | ||||
|             engine: native::i915_engine_class_instance { | ||||
|                 engine_class: match self.engine.engine_class { | ||||
|                     DrmI915EngineClass::Render => 0, | ||||
|                     DrmI915EngineClass::Copy => 1, | ||||
|                     DrmI915EngineClass::Video => 2, | ||||
|                     DrmI915EngineClass::VideoEnhance => 3, | ||||
|                     DrmI915EngineClass::Compute => 4, | ||||
|                     DrmI915EngineClass::Invalid => 0xFFFF, | ||||
|                 }, | ||||
|                 engine_instance: self.engine.engine_instance, | ||||
|             }, | ||||
|             logical_instance: self.logical_instance, | ||||
|             flags: self.flags, | ||||
|             capabilities: self.capabilities, | ||||
|             rsvd0: 0, | ||||
|             rsvd1: [0; 3], | ||||
|             rsvd2: [0; 3], | ||||
|         } | ||||
|     } | ||||
|     pub fn from_native(engine_info: native::drm_i915_engine_info) -> DrmI915EngineInfo { | ||||
|         engine_info_from_native(engine_info) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn get_engines(fd: RawFd) -> Option<Vec<DrmI915EngineInfo>> { | ||||
|     unsafe { | ||||
|         let mut query_item = native::drm_i915_query_item { | ||||
|             query_id: native::DRM_I915_QUERY_ENGINE_INFO as u64, | ||||
|             length: 0, | ||||
|             data_ptr: core::ptr::null_mut::<c_void>() as u64, | ||||
|             flags: 0, | ||||
|         }; | ||||
|         let mut query = native::drm_i915_query { | ||||
|             items_ptr: (&mut query_item) as *mut native::drm_i915_query_item as u64, | ||||
|             num_items: 1, | ||||
|             flags: 0, | ||||
|         }; | ||||
|         let res = libc::ioctl(fd.as_raw_fd(), native::DRM_IOCTL_I915_QUERY, &mut query); | ||||
|         if res != 0 { | ||||
|             return None; | ||||
|         } | ||||
|         let engine_info = libc::malloc(query_item.length as usize) | ||||
|             as *mut native::drm_i915_query_engine_info; | ||||
|         libc::memset(engine_info as *mut c_void, 0, query_item.length as usize); | ||||
|         query_item.data_ptr = engine_info as u64; | ||||
|         let res = libc::ioctl(fd.as_raw_fd(), native::DRM_IOCTL_I915_QUERY, &mut query); | ||||
|         if res != 0 { | ||||
|             return None; | ||||
|         } | ||||
|         let engine_data = engine_info.as_mut().unwrap(); | ||||
|         let engines = engine_data.engines.as_mut_slice(engine_data.num_engines as usize); | ||||
|         let mut engines_res: Vec<DrmI915EngineInfo> = Vec::new(); | ||||
|         for i in 0..engine_data.num_engines { | ||||
|             let engine = DrmI915EngineInfo::from_native(engines[i as usize]); | ||||
|             engines_res.push(engine);            
 | ||||
|         } | ||||
|         Some(engines_res) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn get_param(fd: RawFd, param_id: i32) -> Option<i32> { | ||||
|     unsafe { | ||||
|         let mut value: i32 = 0; | ||||
|         let mut param = native::drm_i915_getparam { | ||||
|             param: param_id, | ||||
|             value: &mut value as *mut i32 | ||||
|         }; | ||||
|         let res = libc::ioctl(fd, native::DRM_IOCTL_I915_GETPARAM, &mut param); | ||||
|         if res != 0 { | ||||
|             return None; | ||||
|         } | ||||
|         Some(value) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn find_i915_node() -> Option<DrmDeviceNode> { | ||||
|     let inodes = fs::read_dir("/dev/dri").ok()?; | ||||
|     for inode in inodes { | ||||
|         let inode = inode.ok()?; | ||||
|         let path = inode.path(); | ||||
|         let path = path.to_str()?; | ||||
|         if path.starts_with("/dev/dri/renderD") { | ||||
|             let file = File::open(path).unwrap(); | ||||
|             let dev = get_drm_version(file.as_raw_fd()); | ||||
|             if dev.is_some() && dev.unwrap().name.to_str().unwrap() == "i915" { | ||||
|                 return Some(DrmDeviceNode { | ||||
|                     fd: OwnedFd::from(file), | ||||
|                     path: Some(OsString::from(path)), | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     None | ||||
| } | ||||
| 
 | ||||
| pub fn find_i915_fd() -> Option<RawFd> { | ||||
|     return find_i915_node().map(|node| node.fd.as_raw_fd()); | ||||
| } | ||||
| @ -0,0 +1,70 @@ | ||||
| use intel_gpu_uapi::*; | ||||
| use std::fmt::format; | ||||
| use std::os::fd::{AsRawFd, OwnedFd, RawFd}; | ||||
| use std::fs::File; | ||||
| use std::path::Path; | ||||
| 
 | ||||
| #[test] | ||||
| fn test_i915_find_device() { | ||||
|     let device = gpu::drm_i915::find_i915_device(); | ||||
|     assert!(device.is_some()); | ||||
|     let drm_version = device.unwrap().driver; | ||||
|     assert_eq!(drm_version.name.to_str().unwrap(), "i915"); | ||||
|     assert_eq!(drm_version.desc.to_str().unwrap(), "Intel Graphics"); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_drm_version() { | ||||
|     let device = gpu::drm_i915::find_i915_device(); | ||||
|     assert!(device.is_some()); | ||||
|     let drm_version = device.unwrap().driver; | ||||
|     assert_eq!(drm_version.name.to_str().unwrap(), "i915"); | ||||
|     assert_eq!(drm_version.desc.to_str().unwrap(), "Intel Graphics"); | ||||
|     let fd_null = File::open("/dev/null").expect("Failed to open /dev/null"); | ||||
|     assert!(gpu::drm_i915::Device::from_fd(OwnedFd::from(fd_null)).is_none()); | ||||
| } | ||||
| 
 | ||||
| fn has_engine_class(engines: &Vec<gpu::drm_i915::Engine>, engine_class: uapi::DrmI915EngineClass) -> bool { | ||||
|     engines.iter().filter(|engine| engine.info.engine.engine_class == engine_class).count() > 0 | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_i915_get_engines() { | ||||
|     let device = gpu::drm_i915::find_i915_device().expect("Failed to find i915 device"); | ||||
|     let drm_version = &device.driver; | ||||
|     assert_eq!(drm_version.name.to_str().unwrap(), "i915"); | ||||
|     assert_eq!(drm_version.desc.to_str().unwrap(), "Intel Graphics"); | ||||
|     let engines = device.get_engines().expect("Failed to get engines"); | ||||
|     assert!(engines.len() > 0); | ||||
|     assert!(has_engine_class(&engines, uapi::DrmI915EngineClass::Render)); | ||||
|     assert!(has_engine_class(&engines, uapi::DrmI915EngineClass::Copy)); | ||||
|     assert!(has_engine_class(&engines, uapi::DrmI915EngineClass::Video)); | ||||
|     assert!(has_engine_class(&engines, uapi::DrmI915EngineClass::VideoEnhance)); | ||||
|     // Compute engine is not always present
 | ||||
|     // assert!(has_engine_class(&engines, uapi::DrmI915EngineClass::Compute));
 | ||||
| } | ||||
| 
 | ||||
| fn get_vendor_for_fd(fd: RawFd) -> String{ | ||||
|     unsafe { | ||||
|         let mut stat: libc::stat = std::mem::zeroed(); | ||||
|         libc::fstat(fd, &mut stat); | ||||
|         let (major, minor) = (libc::major(stat.st_rdev), 
 | ||||
|             libc::minor(stat.st_rdev)); | ||||
|         let sysfs_path = format!("/sys/dev/char/{}:{}/device/device", major, minor); | ||||
|         let sysfs_path = Path::new(&sysfs_path); | ||||
|         let dev_id = std::fs::read_to_string(sysfs_path).expect("Unable to read device id"); | ||||
|         return dev_id.trim().to_string(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_i915_get_param() { | ||||
|     let device = gpu::drm_i915::find_i915_device().expect("Failed to find i915 device"); | ||||
|     let drm_version = &device.driver; | ||||
|     assert_eq!(drm_version.name.to_str().unwrap(), "i915"); | ||||
|     assert_eq!(drm_version.desc.to_str().unwrap(), "Intel Graphics"); | ||||
|     let chipset_id = device.get_param(native::I915_PARAM_CHIPSET_ID).expect("Failed to get param"); | ||||
|     let chip_id = format!("{:#04x}", chipset_id); | ||||
|     let dev_id = get_vendor_for_fd(device.node.fd.as_raw_fd()); | ||||
|     assert_eq!(dev_id, chip_id); | ||||
| } | ||||
| @ -0,0 +1,66 @@ | ||||
| use intel_gpu_uapi::*; | ||||
| use std::ffi::c_void; | ||||
| use std::ffi::CStr; | ||||
| use nix::{self}; | ||||
| 
 | ||||
| #[test] | ||||
| fn test_drm_version_raw() { | ||||
|     // TODO more robust render node detection
 | ||||
|     let fd = nix::fcntl::open("/dev/dri/renderD129", nix::fcntl::OFlag::O_RDWR | nix::fcntl::OFlag::O_CLOEXEC, nix::sys::stat::Mode::empty()) | ||||
|         .expect("Failed to open /dev/dri/renderD129"); | ||||
|     unsafe { | ||||
|         let name_vec = libc::malloc(128); | ||||
|         let date_vec = libc::malloc(128); | ||||
|         let desc_vec = libc::malloc(128); | ||||
|         
 | ||||
|         let mut version = native::drm_version { 
 | ||||
|             version_major: 0, | ||||
|             version_minor: 0, | ||||
|             version_patchlevel: 0, | ||||
|             name: name_vec as *mut i8, | ||||
|             date: date_vec as *mut i8, | ||||
|             desc: desc_vec as *mut i8, | ||||
|             name_len: 128, | ||||
|             date_len: 128, | ||||
|             desc_len: 128, | ||||
|         }; | ||||
|         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)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_i915_query_raw() { | ||||
|     let fd = nix::fcntl::open("/dev/dri/renderD129", nix::fcntl::OFlag::O_RDWR | nix::fcntl::OFlag::O_CLOEXEC, nix::sys::stat::Mode::empty()) | ||||
|         .expect("Failed to open /dev/dri/renderD129"); | ||||
|     unsafe { | ||||
|         let mut query_item = native::drm_i915_query_item { | ||||
|             query_id: native::DRM_I915_QUERY_ENGINE_INFO as u64, | ||||
|             length: 0, | ||||
|             data_ptr: core::ptr::null_mut::<c_void>() as u64, | ||||
|             flags: 0, | ||||
|         }; | ||||
|         let mut query = native::drm_i915_query { | ||||
|             items_ptr: (&mut query_item) as *mut native::drm_i915_query_item as u64, | ||||
|             num_items: 1, | ||||
|             flags: 0, | ||||
|         }; | ||||
|         assert!(libc::ioctl(fd, native::DRM_IOCTL_I915_QUERY, &mut query) == 0); | ||||
|         let engine_info = libc::malloc(query_item.length as usize) | ||||
|             as *mut native::drm_i915_query_engine_info; | ||||
|         query_item.data_ptr = engine_info as u64; | ||||
|         assert!(libc::ioctl(fd, native::DRM_IOCTL_I915_QUERY, &mut query) == 0); | ||||
|         println!("engine_info: {:?}", *engine_info); | ||||
|         let engine_data = engine_info.as_mut().unwrap(); | ||||
|         let engines = engine_data.engines.as_mut_slice(engine_data.num_engines as usize); | ||||
|         for engine in engines { | ||||
|             println!("engine: {:?}", engine); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,20 @@ | ||||
| #![allow(unused_imports)] | ||||
| 
 | ||||
| use intel_gpu_uapi::*; | ||||
| use uapi::find_i915_node; | ||||
| use std::fs; | ||||
| use std::{fs::File, os::fd::AsRawFd}; | ||||
| 
 | ||||
| #[test] | ||||
| fn test_drm_version() { | ||||
|     let node = find_i915_node().expect("Failed to find i915 fd"); | ||||
|     let drm_version = uapi::get_drm_version(node.fd.as_raw_fd()).expect("Failed to get drm version"); | ||||
|     println!("{:?}", drm_version); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_i915_get_engines() { | ||||
|     let node = find_i915_node().expect("Failed to find i915 fd"); | ||||
|     let engines = uapi::get_engines(node.fd.as_raw_fd()).expect("Failed to get engines"); | ||||
|     println!("{:?}", engines); | ||||
| } | ||||
					Loading…
					
					
				
		Reference in new issue