Fix WASM support.

This commit is contained in:
Arjo Chakravarty 2024-11-17 11:24:26 +08:00
parent 996b274a12
commit 8ce55ca50b
2 changed files with 109 additions and 58 deletions

View File

@ -1,6 +1,6 @@
use std::sync::Arc;
use wgpu::{Backends, Instance, Surface};
use wgpu::{Instance, Surface};
use winit::{
dpi::PhysicalSize,
event::{Event, KeyEvent, StartCause, WindowEvent},
@ -278,64 +278,14 @@ impl ExampleContext {
gles_minor_version,
});
surface.pre_adapter(&instance, window);
// Get OS Environment WGPU_ADAPTER_NAME to select the adapter
let adapter = if std::env::var("WGPU_ADAPTER_NAME").is_ok() {
let adapter =
wgpu::util::initialize_adapter_from_env_or_default(&instance, surface.get())
.await
.expect("No suitable GPU adapters found on the system!");
let adapter_info = adapter.get_info();
log::info!("Using {} ({:?})", adapter_info.name, adapter_info.backend);
let optional_features = E::optional_features();
let required_features = E::required_features();
let adapter_features = adapter.features();
assert!(
adapter_features.contains(required_features),
"Adapter does not support required features for this example: {:?}",
required_features - adapter_features
);
let required_downlevel_capabilities = E::required_downlevel_capabilities();
let downlevel_capabilities = adapter.get_downlevel_capabilities();
assert!(
downlevel_capabilities.shader_model >= required_downlevel_capabilities.shader_model,
"Adapter does not support the minimum shader model required to run this example: {:?}",
required_downlevel_capabilities.shader_model
);
assert!(
downlevel_capabilities
.flags
.contains(required_downlevel_capabilities.flags),
"Adapter does not support the downlevel capabilities required to run this example: {:?}",
required_downlevel_capabilities.flags - downlevel_capabilities.flags
);
adapter
} else {
let adapters = instance.enumerate_adapters(Backends::all());
let mut chosen_adapter = None;
for adapter in adapters {
if let Some(surface) = surface.get() {
if !adapter.is_surface_supported(surface) {
continue;
}
}
let required_features = E::required_features();
let adapter_features = adapter.features();
if !adapter_features.contains(required_features) {
continue;
} else {
chosen_adapter = Some(adapter);
break;
}
}
chosen_adapter.expect("No suitable GPU adapters found on the system!")
};
let adapter = get_adapter_with_capabilities_or_from_env(
&instance,
&E::required_features(),
&E::required_downlevel_capabilities(),
&surface.get(),
)
.await;
// Make sure we use the texture resolution limits from the adapter, so we can support images the size of the surface.
let needed_limits = E::required_limits().using_resolution(adapter.limits());
@ -541,6 +491,8 @@ pub fn parse_url_query_string<'a>(query: &'a str, search_key: &str) -> Option<&'
#[cfg(test)]
pub use wgpu_test::image::ComparisonType;
use crate::utils::get_adapter_with_capabilities_or_from_env;
#[cfg(test)]
#[derive(Clone)]
pub struct ExampleTestParams<E> {

View File

@ -156,3 +156,102 @@ fn create_output_image_element(document: &web_sys::Document) -> web_sys::HtmlIma
log::info!("Created new output target image: {:?}", &new_image);
new_image
}
#[cfg(not(target_arch = "wasm32"))]
pub(crate) async fn get_adapter_with_capabilities_or_from_env(
instance: &wgpu::Instance,
required_features: &wgpu::Features,
required_downlevel_capabilities: &wgpu::DownlevelCapabilities,
surface: &Option<&wgpu::Surface<'_>>,
) -> wgpu::Adapter {
use wgpu::Backends;
if std::env::var("WGPU_ADAPTER_NAME").is_ok() {
let adapter = wgpu::util::initialize_adapter_from_env_or_default(instance, *surface)
.await
.expect("No suitable GPU adapters found on the system!");
let adapter_info = adapter.get_info();
log::info!("Using {} ({:?})", adapter_info.name, adapter_info.backend);
let adapter_features = adapter.features();
assert!(
adapter_features.contains(*required_features),
"Adapter does not support required features for this example: {:?}",
*required_features - adapter_features
);
let downlevel_capabilities = adapter.get_downlevel_capabilities();
assert!(
downlevel_capabilities.shader_model >= required_downlevel_capabilities.shader_model,
"Adapter does not support the minimum shader model required to run this example: {:?}",
required_downlevel_capabilities.shader_model
);
assert!(
downlevel_capabilities
.flags
.contains(required_downlevel_capabilities.flags),
"Adapter does not support the downlevel capabilities required to run this example: {:?}",
required_downlevel_capabilities.flags - downlevel_capabilities.flags
);
adapter
} else {
let adapters = instance.enumerate_adapters(Backends::all());
let mut chosen_adapter = None;
for adapter in adapters {
if let Some(surface) = surface {
if !adapter.is_surface_supported(surface) {
continue;
}
}
let required_features = *required_features;
let adapter_features = adapter.features();
if !adapter_features.contains(required_features) {
continue;
} else {
chosen_adapter = Some(adapter);
break;
}
}
chosen_adapter.expect("No suitable GPU adapters found on the system!")
}
}
#[cfg(target_arch = "wasm32")]
pub(crate) async fn get_adapter_with_capabilities_or_from_env(
instance: &wgpu::Instance,
required_features: &wgpu::Features,
required_downlevel_capabilities: &wgpu::DownlevelCapabilities,
surface: &Option<&wgpu::Surface<'_>>,
) -> wgpu::Adapter {
let adapter = wgpu::util::initialize_adapter_from_env_or_default(instance, *surface)
.await
.expect("No suitable GPU adapters found on the system!");
let adapter_info = adapter.get_info();
log::info!("Using {} ({:?})", adapter_info.name, adapter_info.backend);
let adapter_features = adapter.features();
assert!(
adapter_features.contains(*required_features),
"Adapter does not support required features for this example: {:?}",
*required_features - adapter_features
);
let downlevel_capabilities = adapter.get_downlevel_capabilities();
assert!(
downlevel_capabilities.shader_model >= required_downlevel_capabilities.shader_model,
"Adapter does not support the minimum shader model required to run this example: {:?}",
required_downlevel_capabilities.shader_model
);
assert!(
downlevel_capabilities
.flags
.contains(required_downlevel_capabilities.flags),
"Adapter does not support the downlevel capabilities required to run this example: {:?}",
required_downlevel_capabilities.flags - downlevel_capabilities.flags
);
adapter
}