fix: wgpu panics
This commit is contained in:
parent
37572b76f9
commit
c40264a6ed
1 changed files with 65 additions and 57 deletions
|
|
@ -1,4 +1,6 @@
|
||||||
//! Connect a window with a renderer.
|
//! Connect a window with a renderer.
|
||||||
|
use wgpu::Backends;
|
||||||
|
|
||||||
use crate::core::Color;
|
use crate::core::Color;
|
||||||
use crate::graphics::color;
|
use crate::graphics::color;
|
||||||
use crate::graphics::compositor;
|
use crate::graphics::compositor;
|
||||||
|
|
@ -53,7 +55,7 @@ impl Compositor {
|
||||||
/// Requests a new [`Compositor`] with the given [`Settings`].
|
/// Requests a new [`Compositor`] with the given [`Settings`].
|
||||||
///
|
///
|
||||||
/// Returns `None` if no compatible graphics adapter could be found.
|
/// Returns `None` if no compatible graphics adapter could be found.
|
||||||
pub async fn request<W: compositor::Window>(
|
pub async fn request<W: compositor::Window + Clone>(
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
compatible_window: Option<W>,
|
compatible_window: Option<W>,
|
||||||
shell: Shell,
|
shell: Shell,
|
||||||
|
|
@ -82,10 +84,13 @@ impl Compositor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX: try getting non-gl adapter first
|
||||||
|
// Otherwise it will panic when it drops the available adapters!
|
||||||
|
let non_gl_backends = settings.backends.difference(Backends::GL);
|
||||||
// only load the instance after setting environment variables, this initializes the vulkan loader
|
// only load the instance after setting environment variables, this initializes the vulkan loader
|
||||||
let instance = wgpu::util::new_instance_with_webgpu_detection(
|
let mut instance = wgpu::util::new_instance_with_webgpu_detection(
|
||||||
&wgpu::InstanceDescriptor {
|
&wgpu::InstanceDescriptor {
|
||||||
backends: settings.backends,
|
backends: non_gl_backends,
|
||||||
flags: if cfg!(feature = "strict-assertions") {
|
flags: if cfg!(feature = "strict-assertions") {
|
||||||
wgpu::InstanceFlags::debugging()
|
wgpu::InstanceFlags::debugging()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -113,10 +118,11 @@ impl Compositor {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
let compatible_surface = compatible_window
|
let mut compatible_surface = compatible_window
|
||||||
|
.clone()
|
||||||
.and_then(|window| instance.create_surface(window).ok());
|
.and_then(|window| instance.create_surface(window).ok());
|
||||||
|
|
||||||
let adapter_options = wgpu::RequestAdapterOptions {
|
let mut adapter_options = wgpu::RequestAdapterOptions {
|
||||||
power_preference: wgpu::PowerPreference::from_env()
|
power_preference: wgpu::PowerPreference::from_env()
|
||||||
.unwrap_or(wgpu::PowerPreference::HighPerformance),
|
.unwrap_or(wgpu::PowerPreference::HighPerformance),
|
||||||
compatible_surface: compatible_surface.as_ref(),
|
compatible_surface: compatible_surface.as_ref(),
|
||||||
|
|
@ -131,50 +137,13 @@ impl Compositor {
|
||||||
not(target_os = "redox")
|
not(target_os = "redox")
|
||||||
))]
|
))]
|
||||||
if let Some((vendor_id, device_id)) = ids {
|
if let Some((vendor_id, device_id)) = ids {
|
||||||
let a = instance
|
adapter = instance
|
||||||
.request_adapter(&adapter_options)
|
|
||||||
.await
|
|
||||||
.map_err(|_error| {
|
|
||||||
Error::NoAdapterFound(format!("{adapter_options:?}"))
|
|
||||||
})?;
|
|
||||||
let info = a.get_info();
|
|
||||||
adapter = if info.device == device_id as u32
|
|
||||||
&& info.vendor == vendor_id as u32
|
|
||||||
{
|
|
||||||
Some(a)
|
|
||||||
} else {
|
|
||||||
instance
|
|
||||||
.enumerate_adapters(settings.backends)
|
|
||||||
.into_iter()
|
|
||||||
.filter(|adapter| {
|
|
||||||
let info = adapter.get_info();
|
|
||||||
info.device == device_id as u32
|
|
||||||
&& info.vendor == vendor_id as u32
|
|
||||||
})
|
|
||||||
.find(|adapter| {
|
|
||||||
if let Some(surface) = compatible_surface.as_ref() {
|
|
||||||
adapter.is_surface_supported(surface)
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else if let Ok(name) = std::env::var("WGPU_ADAPTER_NAME") {
|
|
||||||
let a = instance.request_adapter(&adapter_options).await.map_err(
|
|
||||||
|_error| Error::NoAdapterFound(format!("{adapter_options:?}")),
|
|
||||||
)?;
|
|
||||||
let info = a.get_info();
|
|
||||||
adapter = if info.name == name
|
|
||||||
{
|
|
||||||
Some(a)
|
|
||||||
} else {
|
|
||||||
instance
|
|
||||||
.enumerate_adapters(settings.backends)
|
.enumerate_adapters(settings.backends)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|adapter| {
|
.filter(|adapter| {
|
||||||
let info = adapter.get_info();
|
let info = adapter.get_info();
|
||||||
info.name == name
|
info.device == device_id as u32
|
||||||
|
&& info.vendor == vendor_id as u32
|
||||||
})
|
})
|
||||||
.find(|adapter| {
|
.find(|adapter| {
|
||||||
if let Some(surface) = compatible_surface.as_ref() {
|
if let Some(surface) = compatible_surface.as_ref() {
|
||||||
|
|
@ -182,30 +151,69 @@ impl Compositor {
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
};
|
}
|
||||||
|
} else if let Ok(name) = std::env::var("WGPU_ADAPTER_NAME") {
|
||||||
|
adapter = instance
|
||||||
|
.enumerate_adapters(settings.backends)
|
||||||
|
.into_iter()
|
||||||
|
.filter(|adapter| {
|
||||||
|
let info = adapter.get_info();
|
||||||
|
info.name == name
|
||||||
|
})
|
||||||
|
.find(|adapter| {
|
||||||
|
if let Some(surface) = compatible_surface.as_ref() {
|
||||||
|
adapter.is_surface_supported(surface)
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
dbg!(&adapter);
|
|
||||||
let adapter = match adapter {
|
let adapter = match adapter {
|
||||||
Some(adapter) => adapter,
|
Some(adapter) => adapter,
|
||||||
None => instance.request_adapter(&adapter_options).await.map_err(
|
None => {
|
||||||
|_| Error::NoAdapterFound(format!("{:?}", adapter_options)),
|
// fall back to allowing GL backend if enabled
|
||||||
)?,
|
instance = wgpu::util::new_instance_with_webgpu_detection(
|
||||||
|
&wgpu::InstanceDescriptor {
|
||||||
|
backends: settings.backends,
|
||||||
|
flags: if cfg!(feature = "strict-assertions") {
|
||||||
|
wgpu::InstanceFlags::debugging()
|
||||||
|
} else {
|
||||||
|
wgpu::InstanceFlags::empty()
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
compatible_surface = compatible_window
|
||||||
|
.and_then(|window| instance.create_surface(window).ok());
|
||||||
|
adapter_options = wgpu::RequestAdapterOptions {
|
||||||
|
power_preference: wgpu::PowerPreference::from_env()
|
||||||
|
.unwrap_or(wgpu::PowerPreference::HighPerformance),
|
||||||
|
compatible_surface: compatible_surface.as_ref(),
|
||||||
|
force_fallback_adapter: false,
|
||||||
|
};
|
||||||
|
instance.request_adapter(&adapter_options).await.map_err(
|
||||||
|
|_| Error::NoAdapterFound(format!("{:?}", adapter_options)),
|
||||||
|
)?
|
||||||
|
}
|
||||||
};
|
};
|
||||||
log::info!("Selected: {:#?}", adapter.get_info());
|
log::info!("Selected: {:#?}", adapter.get_info());
|
||||||
|
|
||||||
let (format, alpha_mode) = compatible_surface
|
let (format, alpha_mode) = compatible_surface
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|surface| {
|
.and_then(|surface: &wgpu::Surface<'_>| {
|
||||||
let capabilities = surface.get_capabilities(&adapter);
|
let capabilities = surface.get_capabilities(&adapter);
|
||||||
|
|
||||||
let formats = capabilities.formats.iter().copied();
|
let formats = capabilities.formats.iter().copied();
|
||||||
|
|
||||||
log::info!("Available formats: {formats:#?}");
|
log::info!("Available formats: {formats:#?}");
|
||||||
|
|
||||||
let mut formats = formats.filter(|format| {
|
let mut formats =
|
||||||
format.required_features() == wgpu::Features::empty()
|
formats.filter(|format: &wgpu::TextureFormat| {
|
||||||
});
|
format.required_features() == wgpu::Features::empty()
|
||||||
|
});
|
||||||
|
|
||||||
let format = if color::GAMMA_CORRECTION {
|
let format = if color::GAMMA_CORRECTION {
|
||||||
formats.find(wgpu::TextureFormat::is_srgb)
|
formats.find(wgpu::TextureFormat::is_srgb)
|
||||||
|
|
@ -305,7 +313,7 @@ impl Compositor {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a [`Compositor`] with the given [`Settings`] and window.
|
/// Creates a [`Compositor`] with the given [`Settings`] and window.
|
||||||
pub async fn new<W: compositor::Window>(
|
pub async fn new<W: compositor::Window + Clone>(
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
compatible_window: W,
|
compatible_window: W,
|
||||||
shell: Shell,
|
shell: Shell,
|
||||||
|
|
@ -363,7 +371,7 @@ impl graphics::Compositor for Compositor {
|
||||||
async fn with_backend(
|
async fn with_backend(
|
||||||
settings: graphics::Settings,
|
settings: graphics::Settings,
|
||||||
_display: impl compositor::Display,
|
_display: impl compositor::Display,
|
||||||
compatible_window: impl compositor::Window,
|
compatible_window: impl compositor::Window + Clone,
|
||||||
shell: Shell,
|
shell: Shell,
|
||||||
backend: Option<&str>,
|
backend: Option<&str>,
|
||||||
) -> Result<Self, graphics::Error> {
|
) -> Result<Self, graphics::Error> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue