1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
use crate::pipe::screen::*;
use mesa_rust_gen::*;
use mesa_rust_util::string::c_string_to_string;
use std::collections::HashMap;
use std::sync::Arc;
use std::{env, ptr};
#[derive(PartialEq)]
pub(super) struct PipeLoaderDevice {
pub(super) ldev: *mut pipe_loader_device,
}
impl PipeLoaderDevice {
fn new(ldev: *mut pipe_loader_device) -> Option<Self> {
if ldev.is_null() {
return None;
}
Some(Self { ldev })
}
fn load_screen(self) -> Option<Arc<PipeScreen>> {
let s = unsafe { pipe_loader_create_screen(self.ldev) };
PipeScreen::new(self, s)
}
}
impl Drop for PipeLoaderDevice {
fn drop(&mut self) {
unsafe {
pipe_loader_release(&mut self.ldev, 1);
}
}
}
fn load_devs() -> Vec<PipeLoaderDevice> {
let n = unsafe { pipe_loader_probe(ptr::null_mut(), 0) };
let mut devices: Vec<*mut pipe_loader_device> = vec![ptr::null_mut(); n as usize];
unsafe {
pipe_loader_probe(devices.as_mut_ptr(), n);
}
devices
.into_iter()
.filter_map(PipeLoaderDevice::new)
.collect()
}
fn get_enabled_devs() -> HashMap<String, u32> {
let mut res = HashMap::new();
if let Ok(enabled_devs) = env::var("RUSTICL_ENABLE") {
let mut last_driver = None;
for driver_str in enabled_devs.split(',') {
if driver_str.is_empty() {
continue;
}
// if the string parses to a number, just updated the device bitset
if let Ok(dev_id) = driver_str.parse::<u8>() {
if let Some(last_driver) = last_driver {
*res.get_mut(last_driver).unwrap() |= 1 << dev_id;
}
continue;
} else {
let driver_str: Vec<_> = driver_str.split(':').collect();
let mut devices = 0;
if driver_str.len() == 1 {
devices = !0;
} else if let Ok(dev_id) = driver_str[1].parse::<u8>() {
devices |= 1 << dev_id;
}
let driver_str = match driver_str[0] {
"llvmpipe" | "lp" => "swrast",
a => a,
};
res.insert(driver_str.to_owned(), devices);
last_driver = Some(driver_str);
}
}
}
res
}
pub fn load_screens() -> Vec<Arc<PipeScreen>> {
let devs = load_devs();
let mut enabled_devs = get_enabled_devs();
devs.into_iter()
.filter(|dev| {
let driver_name = unsafe { c_string_to_string(dev.ldev.as_ref().unwrap().driver_name) };
if let Some(enabled_devs) = enabled_devs.get_mut(&driver_name) {
let res = (*enabled_devs & 1) == 1;
*enabled_devs >>= 1;
res
} else {
false
}
})
.filter_map(PipeLoaderDevice::load_screen)
.collect()
}
|