mirror of
https://gitlab.com/gabmus/envision.git
synced 2025-04-20 03:24:52 +00:00
Compare commits
8 commits
Author | SHA1 | Date | |
---|---|---|---|
|
139f72e294 | ||
|
7a02fcc5d1 | ||
|
2f5ec57a0a | ||
|
8742a27b7c | ||
|
25c90d175f | ||
|
2fc33b10b0 | ||
|
f38199601e | ||
|
db45103d1b |
16 changed files with 180 additions and 113 deletions
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "envision"
|
||||
version = "3.0.1"
|
||||
version = "3.1.0"
|
||||
edition = "2021"
|
||||
authors = [
|
||||
"Gabriele Musco <gabmus@disroot.org>",
|
||||
|
|
|
@ -30,6 +30,26 @@
|
|||
<url type="bugtracker">@REPO_URL@/issues</url>
|
||||
<content_rating type="oars-1.0" />
|
||||
<releases>
|
||||
<release version="3.1.0" date="2025-04-08">
|
||||
<description>
|
||||
<p>What's new</p>
|
||||
<ul>
|
||||
<li>don't set openvrpaths as read only during profile startup</li>
|
||||
<li>small design changes to build window ui</li>
|
||||
<li>add support for vapor openvr compatibility module</li>
|
||||
<li>remove monado vulkan layers check for nvidia</li>
|
||||
</ul>
|
||||
<p>Fixes</p>
|
||||
<ul>
|
||||
<li>disable and blacklist wayvr dashboard plugin</li>
|
||||
<li>monado dependencies: use wayland-protocols-devel on Fedora</li>
|
||||
</ul>
|
||||
<p>Other changes</p>
|
||||
<ul>
|
||||
<li>clippy</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="3.0.1" date="2025-03-02">
|
||||
<description>
|
||||
<p>Fixes</p>
|
||||
|
|
1
dist/arch/PKGBUILD
vendored
1
dist/arch/PKGBUILD
vendored
|
@ -33,7 +33,6 @@ makedepends=(
|
|||
)
|
||||
optdepends=(
|
||||
'libudev0-shim: steamvr_lh lighthouse driver support'
|
||||
'monado-vulkan-layers-git: Vulkan layers for NVIDIA users'
|
||||
)
|
||||
provides=(envision)
|
||||
conflicts=(envision)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
project(
|
||||
'envision',
|
||||
'rust',
|
||||
version: '3.0.1', # version number row
|
||||
version: '3.1.0', # version number row
|
||||
meson_version: '>= 0.59',
|
||||
license: 'AGPL-3.0-or-later',
|
||||
)
|
||||
|
|
85
src/builders/build_vapor.rs
Normal file
85
src/builders/build_vapor.rs
Normal file
|
@ -0,0 +1,85 @@
|
|||
use crate::{
|
||||
build_tools::{cmake::Cmake, git::Git},
|
||||
profile::Profile,
|
||||
termcolor::TermColor,
|
||||
ui::job_worker::job::{FuncWorkerData, FuncWorkerOut, WorkerJob},
|
||||
util::file_utils::{copy_file, rm_rf},
|
||||
};
|
||||
use std::{
|
||||
collections::{HashMap, VecDeque},
|
||||
fs::create_dir_all,
|
||||
path::Path,
|
||||
};
|
||||
|
||||
pub fn get_build_vapor_jobs(profile: &Profile, clean_build: bool) -> VecDeque<WorkerJob> {
|
||||
let mut jobs = VecDeque::<WorkerJob>::new();
|
||||
jobs.push_back(WorkerJob::new_printer(
|
||||
"Building VapoR...",
|
||||
Some(TermColor::Blue),
|
||||
));
|
||||
|
||||
let git = Git {
|
||||
repo: profile
|
||||
.ovr_comp
|
||||
.repo
|
||||
.as_ref()
|
||||
.unwrap_or(&"https://github.com/micheal65536/VapoR.git".into())
|
||||
.clone(),
|
||||
dir: profile.ovr_comp.path.clone(),
|
||||
branch: profile
|
||||
.ovr_comp
|
||||
.branch
|
||||
.as_ref()
|
||||
.unwrap_or(&"master".into())
|
||||
.clone(),
|
||||
};
|
||||
|
||||
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
||||
|
||||
let build_dir = profile.ovr_comp.path.join("build");
|
||||
let cmake = Cmake {
|
||||
env: None,
|
||||
vars: Some({
|
||||
let mut cmake_vars: HashMap<String, String> = HashMap::new();
|
||||
for (k, v) in [
|
||||
("VAPOR_LOG_SILENT=ON", "ON"),
|
||||
("CMAKE_BUILD_TYPE", "RelWithDebInfo"),
|
||||
] {
|
||||
cmake_vars.insert(k.to_string(), v.to_string());
|
||||
}
|
||||
cmake_vars
|
||||
}),
|
||||
source_dir: profile.ovr_comp.path.clone(),
|
||||
build_dir: build_dir.clone(),
|
||||
};
|
||||
if !Path::new(&build_dir).is_dir() || clean_build {
|
||||
rm_rf(&build_dir);
|
||||
jobs.push_back(cmake.get_prepare_job());
|
||||
}
|
||||
jobs.push_back(cmake.get_build_job());
|
||||
jobs.push_back(WorkerJob::Func(FuncWorkerData {
|
||||
func: Box::new(move || {
|
||||
let dest_dir = build_dir.join("bin/linux64");
|
||||
if let Err(e) = create_dir_all(&dest_dir) {
|
||||
return FuncWorkerOut {
|
||||
success: false,
|
||||
out: vec![format!(
|
||||
"failed to create dir {}: {e}",
|
||||
dest_dir.to_string_lossy()
|
||||
)],
|
||||
};
|
||||
}
|
||||
copy_file(
|
||||
&build_dir.join("src/vrclient.so"),
|
||||
&dest_dir.join("vrclient.so"),
|
||||
);
|
||||
|
||||
FuncWorkerOut {
|
||||
success: true,
|
||||
out: Vec::default(),
|
||||
}
|
||||
}),
|
||||
}));
|
||||
|
||||
jobs
|
||||
}
|
|
@ -4,5 +4,6 @@ pub mod build_mercury;
|
|||
pub mod build_monado;
|
||||
pub mod build_opencomposite;
|
||||
pub mod build_openhmd;
|
||||
pub mod build_vapor;
|
||||
pub mod build_wivrn;
|
||||
pub mod build_xrizer;
|
||||
|
|
|
@ -37,7 +37,7 @@ fn monado_deps() -> Vec<Dependency> {
|
|||
packages: HashMap::from([
|
||||
(LinuxDistro::Arch, "wayland-protocols".into()),
|
||||
(LinuxDistro::Debian, "wayland-protocols".into()),
|
||||
(LinuxDistro::Fedora, "wayland-protocols".into()),
|
||||
(LinuxDistro::Fedora, "wayland-protocols-devel".into()),
|
||||
(LinuxDistro::Gentoo, "dev-libs/wayland-protocols".into()),
|
||||
(LinuxDistro::Suse, "wayland-protocols-devel".into()),
|
||||
]),
|
||||
|
|
|
@ -85,6 +85,7 @@ fn build_steam_openvrpaths() -> OpenVrPaths {
|
|||
}
|
||||
|
||||
pub fn set_current_openvrpaths_to_steam() -> anyhow::Result<()> {
|
||||
// removing readonly flag just in case, remove this line in the future
|
||||
set_file_readonly(&get_openvrpaths_vrpath_path(), false)?;
|
||||
dump_current_openvrpaths(&build_steam_openvrpaths())?;
|
||||
Ok(())
|
||||
|
@ -104,18 +105,17 @@ pub fn build_profile_openvrpaths(profile: &Profile) -> OpenVrPaths {
|
|||
|
||||
pub fn set_current_openvrpaths_to_profile(profile: &Profile) -> anyhow::Result<()> {
|
||||
let dest = get_openvrpaths_vrpath_path();
|
||||
// removing readonly flag just in case, remove this line in the future
|
||||
set_file_readonly(&dest, false)?;
|
||||
backup_steam_openvrpaths();
|
||||
dump_current_openvrpaths(&build_profile_openvrpaths(profile))?;
|
||||
set_file_readonly(&dest, true)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
|
||||
use super::{dump_openvrpaths_to_path, get_openvrpaths_from_path, OpenVrPaths};
|
||||
use std::path::Path;
|
||||
|
||||
#[test]
|
||||
fn can_read_openvrpaths_vrpath_steamvr() {
|
||||
|
|
|
@ -49,13 +49,13 @@ impl LinuxDistro {
|
|||
Ok(_) if buf.starts_with("PRETTY_NAME=\"") => {
|
||||
return buf
|
||||
.split('=')
|
||||
.last()
|
||||
.next_back()
|
||||
.map(|b| b.trim().trim_matches('"').trim().to_string());
|
||||
}
|
||||
Ok(_) if buf.starts_with("NAME=\"") => {
|
||||
name = buf
|
||||
.split('=')
|
||||
.last()
|
||||
.next_back()
|
||||
.map(|b| b.trim().trim_matches('"').trim().to_string());
|
||||
}
|
||||
_ => {}
|
||||
|
@ -79,7 +79,7 @@ impl LinuxDistro {
|
|||
{
|
||||
let name = buf
|
||||
.split('=')
|
||||
.last()
|
||||
.next_back()
|
||||
.unwrap_or_default()
|
||||
.trim()
|
||||
.trim_matches('"')
|
||||
|
|
|
@ -265,6 +265,7 @@ pub enum OvrCompatibilityModuleType {
|
|||
#[default]
|
||||
Opencomposite,
|
||||
Xrizer,
|
||||
Vapor,
|
||||
}
|
||||
|
||||
impl Display for OvrCompatibilityModuleType {
|
||||
|
@ -272,13 +273,14 @@ impl Display for OvrCompatibilityModuleType {
|
|||
f.write_str(match self {
|
||||
Self::Opencomposite => "OpenComposite",
|
||||
Self::Xrizer => "xrizer",
|
||||
Self::Vapor => "VapoR",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl OvrCompatibilityModuleType {
|
||||
pub fn iter() -> Iter<'static, Self> {
|
||||
[Self::Opencomposite, Self::Xrizer].iter()
|
||||
[Self::Opencomposite, Self::Xrizer, Self::Vapor].iter()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,6 +291,7 @@ impl FromStr for OvrCompatibilityModuleType {
|
|||
match s.to_lowercase().trim() {
|
||||
"opencomposite" => Ok(Self::Opencomposite),
|
||||
"xrizer" => Ok(Self::Xrizer),
|
||||
"vapor" => Ok(Self::Vapor),
|
||||
_ => Err(format!("no match for ovr compatibility module `{s}`")),
|
||||
}
|
||||
}
|
||||
|
@ -299,7 +302,8 @@ impl From<u32> for OvrCompatibilityModuleType {
|
|||
match value {
|
||||
0 => Self::Opencomposite,
|
||||
1 => Self::Xrizer,
|
||||
_ => panic!("OvrCompatibilityModuleType index out of bounds"),
|
||||
2 => Self::Vapor,
|
||||
_ => panic!("OvrCompatibilityModuleType index out of bounds"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -327,7 +331,9 @@ impl ProfileOvrCompatibilityModule {
|
|||
/// this should correspond to the build output directory
|
||||
pub fn runtime_dir(&self) -> PathBuf {
|
||||
match self.mod_type {
|
||||
OvrCompatibilityModuleType::Opencomposite => self.path.join("build"),
|
||||
OvrCompatibilityModuleType::Opencomposite | OvrCompatibilityModuleType::Vapor => {
|
||||
self.path.join("build")
|
||||
}
|
||||
OvrCompatibilityModuleType::Xrizer => self.path.join("target/release"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ pub fn create_about_dialog() -> adw::AboutDialog {
|
|||
const UNKNOWN: &str = "UNKNOWN";
|
||||
|
||||
pub fn populate_debug_info(dialog: &adw::AboutDialog, vkinfo: Option<&VulkanInfo>) {
|
||||
if dialog.debug_info().len() > 0 {
|
||||
if !dialog.debug_info().is_empty() {
|
||||
return;
|
||||
}
|
||||
let distro_family = LinuxDistro::get();
|
||||
|
@ -70,7 +70,7 @@ pub fn populate_debug_info(dialog: &adw::AboutDialog, vkinfo: Option<&VulkanInfo
|
|||
.and_then(|s| {
|
||||
s.split("\n")
|
||||
.find(|line| line.starts_with("model name"))
|
||||
.map(|line| line.split(':').last().map(|s| s.trim().to_string()))
|
||||
.map(|line| line.split(':').next_back().map(|s| s.trim().to_string()))
|
||||
})
|
||||
.flatten()
|
||||
.unwrap_or(UNKNOWN.into())
|
||||
|
@ -81,12 +81,6 @@ pub fn populate_debug_info(dialog: &adw::AboutDialog, vkinfo: Option<&VulkanInfo
|
|||
.map(|i| i.gpu_names.join(", "))
|
||||
.unwrap_or(UNKNOWN.into())
|
||||
),
|
||||
format!(
|
||||
"Monado Vulkan Layers: {}",
|
||||
vkinfo
|
||||
.map(|i| i.has_monado_vulkan_layers.to_string())
|
||||
.unwrap_or(UNKNOWN.into())
|
||||
),
|
||||
format!("Detected XR Devices: {}", {
|
||||
let devs = PhysicalXRDevice::from_usb();
|
||||
if devs.is_empty() {
|
||||
|
|
|
@ -20,7 +20,8 @@ use crate::{
|
|||
build_basalt::get_build_basalt_jobs, build_libsurvive::get_build_libsurvive_jobs,
|
||||
build_mercury::get_build_mercury_jobs, build_monado::get_build_monado_jobs,
|
||||
build_opencomposite::get_build_opencomposite_jobs, build_openhmd::get_build_openhmd_jobs,
|
||||
build_wivrn::get_build_wivrn_jobs, build_xrizer::get_build_xrizer_jobs,
|
||||
build_vapor::get_build_vapor_jobs, build_wivrn::get_build_wivrn_jobs,
|
||||
build_xrizer::get_build_xrizer_jobs,
|
||||
},
|
||||
config::{Config, PluginConfig},
|
||||
constants::APP_NAME,
|
||||
|
@ -248,6 +249,10 @@ impl App {
|
|||
.plugins
|
||||
.values()
|
||||
.filter_map(|cp| {
|
||||
// disable potentially unsafe wayvr_dashboard
|
||||
if cp.plugin.appid.contains("wayvr_dashboard") {
|
||||
return None;
|
||||
}
|
||||
if cp.enabled && cp.plugin.validate() {
|
||||
if let Err(e) = cp.plugin.mark_as_executable() {
|
||||
error!(
|
||||
|
@ -533,6 +538,9 @@ impl AsyncComponent for App {
|
|||
OvrCompatibilityModuleType::Xrizer => {
|
||||
get_build_xrizer_jobs(&profile, clean_build)
|
||||
}
|
||||
OvrCompatibilityModuleType::Vapor => {
|
||||
get_build_vapor_jobs(&profile, clean_build)
|
||||
}
|
||||
});
|
||||
let missing_deps = profile.missing_dependencies();
|
||||
if !(self.skip_depcheck || profile.skip_dependency_check || missing_deps.is_empty())
|
||||
|
@ -998,7 +1006,6 @@ impl AsyncComponent for App {
|
|||
config: config.clone(),
|
||||
selected_profile: selected_profile.clone(),
|
||||
root_win: root.clone().into(),
|
||||
vkinfo: vkinfo.clone(),
|
||||
})
|
||||
.forward(sender.input_sender(), |message| match message {
|
||||
MainViewOutMsg::DoStartStopXRService => Msg::DoStartStopXRService,
|
||||
|
|
|
@ -88,43 +88,54 @@ impl SimpleComponent for BuildWindow {
|
|||
gtk::Label {
|
||||
#[track = "model.changed(BuildWindow::build_status())"]
|
||||
set_markup: match &model.build_status {
|
||||
BuildStatus::Building => "Build in progress...".to_string(),
|
||||
BuildStatus::Done => "Build done, you can close this window".to_string(),
|
||||
BuildStatus::Building => String::default(),
|
||||
BuildStatus::Done => "Build done, you can close this window".into(),
|
||||
BuildStatus::Error(code) => {
|
||||
format!("Build failed: \"{c}\"", c = code)
|
||||
}
|
||||
}.as_str(),
|
||||
#[track = "model.changed(BuildWindow::build_status())"]
|
||||
set_visible: match &model.build_status {
|
||||
BuildStatus::Building => false,
|
||||
BuildStatus::Done | BuildStatus::Error(_) => true,
|
||||
},
|
||||
add_css_class: "title-2",
|
||||
set_wrap: true,
|
||||
set_wrap_mode: gtk::pango::WrapMode::Word,
|
||||
set_justify: gtk::Justification::Center,
|
||||
},
|
||||
gtk::Button {
|
||||
#[track = "model.changed(BuildWindow::build_status())"]
|
||||
set_visible: matches!(&model.build_status, BuildStatus::Building),
|
||||
add_css_class: "destructive-action",
|
||||
add_css_class: "circular",
|
||||
set_icon_name: "window-close-symbolic",
|
||||
set_tooltip_text: Some("Cancel build"),
|
||||
connect_clicked[sender] => move |_| {
|
||||
sender.output(Self::Output::CancelBuild).expect(SENDER_IO_ERR_MSG);
|
||||
}
|
||||
},
|
||||
},
|
||||
model.term.container.clone(),
|
||||
},
|
||||
add_bottom_bar: bottom_bar = >k::Button {
|
||||
add_css_class: "pill",
|
||||
add_bottom_bar: bottom_bar = >k::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_halign: gtk::Align::Center,
|
||||
set_label: "Close",
|
||||
set_margin_all: 12,
|
||||
#[track = "model.changed(BuildWindow::can_close())"]
|
||||
set_sensitive: model.can_close,
|
||||
connect_clicked[win] => move |_| {
|
||||
|
||||
win.close();
|
||||
set_hexpand: true,
|
||||
set_margin_bottom: 24,
|
||||
set_spacing: 12,
|
||||
gtk::Button {
|
||||
add_css_class: "pill",
|
||||
set_halign: gtk::Align::Center,
|
||||
set_label: "Close",
|
||||
#[track = "model.changed(BuildWindow::can_close())"]
|
||||
set_visible: model.can_close,
|
||||
connect_clicked[win] => move |_| {
|
||||
win.close();
|
||||
},
|
||||
},
|
||||
}
|
||||
// this
|
||||
gtk::Button {
|
||||
#[track = "model.changed(BuildWindow::build_status())"]
|
||||
set_visible: matches!(&model.build_status, BuildStatus::Building),
|
||||
add_css_class: "destructive-action",
|
||||
add_css_class: "pill",
|
||||
set_label: "Cancel build",
|
||||
connect_clicked[sender] => move |_| {
|
||||
sender.output(Self::Output::CancelBuild).expect(SENDER_IO_ERR_MSG);
|
||||
}
|
||||
},
|
||||
// ^^^
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ use crate::{
|
|||
file_utils::{get_writer, mount_has_nosuid},
|
||||
steamvr_utils::chaperone_info_exists,
|
||||
},
|
||||
vulkaninfo::VulkanInfo,
|
||||
wivrn_dbus,
|
||||
xr_devices::XRDevice,
|
||||
};
|
||||
|
@ -75,8 +74,6 @@ pub struct MainView {
|
|||
#[tracker::do_not_track]
|
||||
profile_export_action: gtk::gio::SimpleAction,
|
||||
xrservice_ready: bool,
|
||||
#[tracker::do_not_track]
|
||||
vkinfo: Option<VulkanInfo>,
|
||||
wivrn_pairing_mode: bool,
|
||||
wivrn_pin: Option<String>,
|
||||
wivrn_supports_pairing: bool,
|
||||
|
@ -126,7 +123,6 @@ pub struct MainViewInit {
|
|||
pub config: Config,
|
||||
pub selected_profile: Profile,
|
||||
pub root_win: gtk::Window,
|
||||
pub vkinfo: Option<VulkanInfo>,
|
||||
}
|
||||
|
||||
impl MainView {
|
||||
|
@ -461,34 +457,6 @@ impl AsyncComponent for MainView {
|
|||
set_wrap_mode: gtk::pango::WrapMode::Word,
|
||||
}
|
||||
},
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_hexpand: true,
|
||||
set_vexpand: false,
|
||||
set_spacing: 12,
|
||||
add_css_class: "card",
|
||||
add_css_class: "padded",
|
||||
set_visible: model
|
||||
.vkinfo
|
||||
.as_ref()
|
||||
.is_some_and(
|
||||
|i| i.has_nvidia_gpu && !i.has_monado_vulkan_layers
|
||||
),
|
||||
warning_heading(),
|
||||
gtk::Label {
|
||||
set_label: concat!(
|
||||
"An Nvidia GPU has been detected, but it ",
|
||||
"seems you don't have the Monado Vulkan Layers ",
|
||||
"installed on your system.\n\nInstall the ",
|
||||
"Monado Vulkan Layers or your XR session will ",
|
||||
"crash."
|
||||
),
|
||||
add_css_class: "warning",
|
||||
set_xalign: 0.0,
|
||||
set_wrap: true,
|
||||
set_wrap_mode: gtk::pango::WrapMode::Word,
|
||||
}
|
||||
},
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_hexpand: true,
|
||||
|
@ -1103,7 +1071,6 @@ impl AsyncComponent for MainView {
|
|||
xrservice_ready: false,
|
||||
profile_delete_action,
|
||||
profile_export_action,
|
||||
vkinfo: init.vkinfo,
|
||||
wivrn_pairing_mode: false,
|
||||
wivrn_supports_pairing: false,
|
||||
wivrn_pin: None,
|
||||
|
|
|
@ -163,10 +163,10 @@ impl Plugin {
|
|||
|
||||
/// urls to manifest json files representing plugins.
|
||||
/// each manifest should be json and the link should always point to the latest version
|
||||
const MANIFESTS: [&str;3] = [
|
||||
const MANIFESTS: [&str;2] = [
|
||||
"https://github.com/galister/wlx-overlay-s/raw/refs/heads/meta/com.github.galister.wlx-overlay-s.json",
|
||||
"https://github.com/olekolek1000/wayvr-dashboard/raw/refs/heads/meta/dev.oo8.wayvr_dashboard.json",
|
||||
"https://github.com/StardustXR/telescope/raw/refs/heads/main/envision/org.stardustxr.telescope.json",
|
||||
// wayvr dashboard potentially unsafe
|
||||
];
|
||||
|
||||
pub async fn refresh_plugins() -> anyhow::Result<Vec<anyhow::Result<Plugin>>> {
|
||||
|
|
|
@ -5,12 +5,10 @@ use ash::{
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct VulkanInfo {
|
||||
pub has_nvidia_gpu: bool,
|
||||
pub has_monado_vulkan_layers: bool,
|
||||
pub gpu_names: Vec<String>,
|
||||
}
|
||||
|
||||
const NVIDIA_VENDOR_ID: u32 = 0x10de;
|
||||
// const NVIDIA_VENDOR_ID: u32 = 0x10de;
|
||||
|
||||
impl VulkanInfo {
|
||||
/// # Safety
|
||||
|
@ -25,40 +23,19 @@ impl VulkanInfo {
|
|||
None,
|
||||
)
|
||||
}?;
|
||||
let mut has_nvidia_gpu = false;
|
||||
let mut has_monado_vulkan_layers = false;
|
||||
let gpu_names = unsafe { instance.enumerate_physical_devices() }?
|
||||
.into_iter()
|
||||
.filter_map(|d| {
|
||||
let props = unsafe { instance.get_physical_device_properties(d) };
|
||||
if props.vendor_id == NVIDIA_VENDOR_ID {
|
||||
has_nvidia_gpu = true;
|
||||
}
|
||||
if !has_monado_vulkan_layers {
|
||||
has_monado_vulkan_layers =
|
||||
unsafe { instance.enumerate_device_layer_properties(d) }
|
||||
.ok()
|
||||
.map(|layerprops| {
|
||||
layerprops.iter().any(|lp| {
|
||||
lp.layer_name_as_c_str().is_ok_and(|name| {
|
||||
name.to_string_lossy()
|
||||
== "VK_LAYER_MND_enable_timeline_semaphore"
|
||||
})
|
||||
})
|
||||
})
|
||||
== Some(true);
|
||||
}
|
||||
props
|
||||
.device_name_as_c_str()
|
||||
.ok()
|
||||
.map(|cs| cs.to_string_lossy().to_string())
|
||||
Some(
|
||||
unsafe { instance.get_physical_device_properties(d) }
|
||||
.device_name_as_c_str()
|
||||
.ok()?
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
unsafe { instance.destroy_instance(None) };
|
||||
Ok(Self {
|
||||
gpu_names,
|
||||
has_nvidia_gpu,
|
||||
has_monado_vulkan_layers,
|
||||
})
|
||||
Ok(Self { gpu_names })
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue