rusticl/device: fix default device enumeration
There were a couple of issues this fixes: - Using the env "RUSTICL_DEVICE_TYPE" variable made no device be default. - If multiple GPUs were detected, multiple devices were default. - If zink was used, no default device was advertized either. The spec requires that there must be one and only one default device. Cc: mesa-stable Reviewed-by @LingMan Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32875>
This commit is contained in:
@@ -290,7 +290,11 @@ unsafe impl CLInfo<cl_device_info> for cl_device_id {
|
|||||||
.into(),
|
.into(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
CL_DEVICE_TYPE => v.write::<cl_device_type>(dev.device_type(false)),
|
CL_DEVICE_TYPE => {
|
||||||
|
// CL_DEVICE_TYPE_DEFAULT ... will never be returned in CL_DEVICE_TYPE for any
|
||||||
|
// OpenCL device.
|
||||||
|
v.write::<cl_device_type>((dev.device_type & !CL_DEVICE_TYPE_DEFAULT).into())
|
||||||
|
}
|
||||||
CL_DEVICE_UUID_KHR => v.write::<[cl_uchar; CL_UUID_SIZE_KHR as usize]>(
|
CL_DEVICE_UUID_KHR => v.write::<[cl_uchar; CL_UUID_SIZE_KHR as usize]>(
|
||||||
dev.screen().device_uuid().unwrap_or_default(),
|
dev.screen().device_uuid().unwrap_or_default(),
|
||||||
),
|
),
|
||||||
|
@@ -36,7 +36,7 @@ pub struct Device {
|
|||||||
pub cl_version: CLVersion,
|
pub cl_version: CLVersion,
|
||||||
pub clc_version: CLVersion,
|
pub clc_version: CLVersion,
|
||||||
pub clc_versions: Vec<cl_name_version>,
|
pub clc_versions: Vec<cl_name_version>,
|
||||||
pub custom: bool,
|
pub device_type: u32,
|
||||||
pub embedded: bool,
|
pub embedded: bool,
|
||||||
pub extension_string: String,
|
pub extension_string: String,
|
||||||
pub extensions: Vec<cl_name_version>,
|
pub extensions: Vec<cl_name_version>,
|
||||||
@@ -200,7 +200,7 @@ impl Device {
|
|||||||
cl_version: CLVersion::Cl3_0,
|
cl_version: CLVersion::Cl3_0,
|
||||||
clc_version: CLVersion::Cl3_0,
|
clc_version: CLVersion::Cl3_0,
|
||||||
clc_versions: Vec::new(),
|
clc_versions: Vec::new(),
|
||||||
custom: false,
|
device_type: 0,
|
||||||
embedded: false,
|
embedded: false,
|
||||||
extension_string: String::from(""),
|
extension_string: String::from(""),
|
||||||
extensions: Vec::new(),
|
extensions: Vec::new(),
|
||||||
@@ -214,8 +214,7 @@ impl Device {
|
|||||||
// check if we are embedded or full profile first
|
// check if we are embedded or full profile first
|
||||||
d.embedded = d.check_embedded_profile();
|
d.embedded = d.check_embedded_profile();
|
||||||
|
|
||||||
// check if we have to report it as a custom device
|
d.set_device_type();
|
||||||
d.custom = d.check_custom();
|
|
||||||
|
|
||||||
d.fill_format_tables();
|
d.fill_format_tables();
|
||||||
|
|
||||||
@@ -477,21 +476,6 @@ impl Device {
|
|||||||
!self.int64_supported()
|
!self.int64_supported()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_env_device_type() -> Option<cl_device_type> {
|
|
||||||
let mut val = env::var("RUSTICL_DEVICE_TYPE").ok()?;
|
|
||||||
val.make_ascii_lowercase();
|
|
||||||
Some(
|
|
||||||
match &*val {
|
|
||||||
"accelerator" => CL_DEVICE_TYPE_ACCELERATOR,
|
|
||||||
"cpu" => CL_DEVICE_TYPE_CPU,
|
|
||||||
"custom" => CL_DEVICE_TYPE_CUSTOM,
|
|
||||||
"gpu" => CL_DEVICE_TYPE_GPU,
|
|
||||||
_ => return None,
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_env_version() -> Option<CLVersion> {
|
fn parse_env_version() -> Option<CLVersion> {
|
||||||
let val = env::var("RUSTICL_CL_VERSION").ok()?;
|
let val = env::var("RUSTICL_CL_VERSION").ok()?;
|
||||||
let (major, minor) = val.split_once('.')?;
|
let (major, minor) = val.split_once('.')?;
|
||||||
@@ -697,8 +681,40 @@ impl Device {
|
|||||||
.shader_param(pipe_shader_type::PIPE_SHADER_COMPUTE, cap)
|
.shader_param(pipe_shader_type::PIPE_SHADER_COMPUTE, cap)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all() -> impl Iterator<Item = Device> {
|
pub fn all() -> Vec<Device> {
|
||||||
load_screens().filter_map(Device::new)
|
let mut devs: Vec<_> = load_screens().filter_map(Device::new).collect();
|
||||||
|
|
||||||
|
// Pick a default device. One must be the default one no matter what. And custom devices can
|
||||||
|
// only be that one if they are the only devices available.
|
||||||
|
//
|
||||||
|
// The entry with the highest value will be the default device.
|
||||||
|
let default = devs.iter_mut().max_by_key(|dev| {
|
||||||
|
let mut val = if dev.device_type == CL_DEVICE_TYPE_CUSTOM {
|
||||||
|
// needs to be small enough so it's always going to be the smallest value
|
||||||
|
-100
|
||||||
|
} else if dev.device_type == CL_DEVICE_TYPE_CPU {
|
||||||
|
0
|
||||||
|
} else if dev.unified_memory() {
|
||||||
|
// we give unified memory devices max priority, because we don't want to spin up the
|
||||||
|
// discrete GPU on laptops by default.
|
||||||
|
100
|
||||||
|
} else {
|
||||||
|
10
|
||||||
|
};
|
||||||
|
|
||||||
|
// we deprioritize zink for now.
|
||||||
|
if dev.screen.driver_name() == c"zink" {
|
||||||
|
val -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
val
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(default) = default {
|
||||||
|
default.device_type |= CL_DEVICE_TYPE_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
devs
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn address_bits(&self) -> cl_uint {
|
pub fn address_bits(&self) -> cl_uint {
|
||||||
@@ -726,26 +742,30 @@ impl Device {
|
|||||||
self.shader_param(pipe_shader_cap::PIPE_SHADER_CAP_MAX_CONST_BUFFERS) as cl_uint
|
self.shader_param(pipe_shader_cap::PIPE_SHADER_CAP_MAX_CONST_BUFFERS) as cl_uint
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn device_type(&self, internal: bool) -> cl_device_type {
|
fn set_device_type(&mut self) {
|
||||||
if let Some(env) = Self::parse_env_device_type() {
|
let env = env::var("RUSTICL_DEVICE_TYPE").ok().and_then(|env| {
|
||||||
return env;
|
Some(match &*env.to_ascii_lowercase() {
|
||||||
}
|
"accelerator" => CL_DEVICE_TYPE_ACCELERATOR,
|
||||||
|
"cpu" => CL_DEVICE_TYPE_CPU,
|
||||||
|
"custom" => CL_DEVICE_TYPE_CUSTOM,
|
||||||
|
"gpu" => CL_DEVICE_TYPE_GPU,
|
||||||
|
// if no valid string is set we treat is as no value was set
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
if self.custom {
|
self.device_type = if let Some(env) = env {
|
||||||
return CL_DEVICE_TYPE_CUSTOM as cl_device_type;
|
env
|
||||||
}
|
} else if self.check_custom() {
|
||||||
let mut res = match self.screen.device_type() {
|
CL_DEVICE_TYPE_CUSTOM
|
||||||
pipe_loader_device_type::PIPE_LOADER_DEVICE_SOFTWARE => CL_DEVICE_TYPE_CPU,
|
} else {
|
||||||
pipe_loader_device_type::PIPE_LOADER_DEVICE_PCI => CL_DEVICE_TYPE_GPU,
|
match self.screen.device_type() {
|
||||||
pipe_loader_device_type::PIPE_LOADER_DEVICE_PLATFORM => CL_DEVICE_TYPE_GPU,
|
pipe_loader_device_type::PIPE_LOADER_DEVICE_SOFTWARE => CL_DEVICE_TYPE_CPU,
|
||||||
pipe_loader_device_type::NUM_PIPE_LOADER_DEVICE_TYPES => CL_DEVICE_TYPE_CUSTOM,
|
pipe_loader_device_type::PIPE_LOADER_DEVICE_PCI => CL_DEVICE_TYPE_GPU,
|
||||||
|
pipe_loader_device_type::PIPE_LOADER_DEVICE_PLATFORM => CL_DEVICE_TYPE_GPU,
|
||||||
|
pipe_loader_device_type::NUM_PIPE_LOADER_DEVICE_TYPES => CL_DEVICE_TYPE_CUSTOM,
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if internal && res == CL_DEVICE_TYPE_GPU && self.screen.driver_name() != c"zink" {
|
|
||||||
res |= CL_DEVICE_TYPE_DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
res as cl_device_type
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fp16_supported(&self) -> bool {
|
pub fn fp16_supported(&self) -> bool {
|
||||||
@@ -1108,7 +1128,7 @@ pub fn devs() -> &'static Vec<Device> {
|
|||||||
pub fn get_devs_for_type(device_type: cl_device_type) -> Vec<&'static Device> {
|
pub fn get_devs_for_type(device_type: cl_device_type) -> Vec<&'static Device> {
|
||||||
devs()
|
devs()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|d| device_type & d.device_type(true) != 0)
|
.filter(|d| device_type & d.device_type as cl_device_type != 0)
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -161,7 +161,7 @@ impl Platform {
|
|||||||
glsl_type_singleton_init_or_ref();
|
glsl_type_singleton_init_or_ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.devs = Device::all().collect();
|
self.devs = Device::all();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_once() {
|
pub fn init_once() {
|
||||||
|
Reference in New Issue
Block a user