diff --git a/Cargo.lock b/Cargo.lock index aa145ca8464..4ccfa2d5dbe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3978,6 +3978,7 @@ name = "wgpu" version = "23.0.1" dependencies = [ "arrayvec", + "bitflags 2.6.0", "cfg_aliases 0.2.1", "document-features", "js-sys", diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index ca757e122c9..86a75152235 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -187,6 +187,7 @@ optional = true [dependencies] arrayvec.workspace = true +bitflags.workspace = true document-features.workspace = true log.workspace = true parking_lot.workspace = true diff --git a/wgpu/src/api/instance.rs b/wgpu/src/api/instance.rs index f03e348183e..8ee15b7c642 100644 --- a/wgpu/src/api/instance.rs +++ b/wgpu/src/api/instance.rs @@ -2,6 +2,23 @@ use parking_lot::Mutex; use crate::{dispatch::InstanceInterface, *}; +bitflags::bitflags! { + /// WGSL language extensions. + /// + /// WGSL spec.: + #[derive(Debug, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)] + pub struct WGSLLanguageFeatures: u32 { + /// + const ReadOnlyAndReadWriteStorageTextures = 1 << 0; + /// + const Packed4x8IntegerDotProduct = 1 << 1; + /// + const UnrestrictedPointerParameters = 1 << 2; + /// + const PointerCompositeAccess = 1 << 3; + } +} + use std::future::Future; /// Context for all other wgpu objects. Instance of wgpu. @@ -385,4 +402,12 @@ impl Instance { pub fn generate_report(&self) -> Option { self.inner.as_core_opt().map(|ctx| ctx.generate_report()) } + + /// Returns set of supported WGSL language extensions supported by this instance + /// + /// + #[cfg(feature = "wgsl")] + pub fn wgsl_language_features(&self) -> WGSLLanguageFeatures { + self.inner.wgsl_language_features() + } } diff --git a/wgpu/src/backend/webgpu.rs b/wgpu/src/backend/webgpu.rs index b2f1f190791..06144c05660 100644 --- a/wgpu/src/backend/webgpu.rs +++ b/wgpu/src/backend/webgpu.rs @@ -1562,6 +1562,40 @@ impl dispatch::InstanceInterface for ContextWebGpu { // Devices are automatically polled. true } + + #[cfg(feature = "wgsl")] + fn wgsl_language_features(&self) -> crate::WGSLLanguageFeatures { + let mut wgsl_language_features = crate::WGSLLanguageFeatures::empty(); + if let Some(gpu) = &self.gpu { + gpu.wgsl_language_features() + .keys() + .into_iter() + .map(|wlf| wlf.expect("WGSLLanguageFeatures elements should be valid")) + .map(|wlf| { + wlf.as_string() + .expect("WGSLLanguageFeatures should be string set") + }) + .filter_map(|wlf| match wlf.as_str() { + "readonly_and_readwrite_storage_textures" => { + Some(crate::WGSLLanguageFeatures::ReadOnlyAndReadWriteStorageTextures) + } + "packed_4x8_integer_dot_product" => { + Some(crate::WGSLLanguageFeatures::Packed4x8IntegerDotProduct) + } + "unrestricted_pointer_parameters" => { + Some(crate::WGSLLanguageFeatures::UnrestrictedPointerParameters) + } + "pointer_composite_access" => { + Some(crate::WGSLLanguageFeatures::PointerCompositeAccess) + } + _ => None, + }) + .for_each(|wlf| { + wgsl_language_features |= wlf; + }) + } + wgsl_language_features + } } impl Drop for ContextWebGpu { diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 4becb1e8dd1..48d3ff2ee91 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -850,6 +850,16 @@ impl dispatch::InstanceInterface for ContextWgpuCore { Err(err) => self.handle_error_fatal(err, "Instance::poll_all_devices"), } } + + #[cfg(feature = "wgsl")] + fn wgsl_language_features(&self) -> crate::WGSLLanguageFeatures { + use wgc::naga::front::wgsl::WGSLLanguageExtension; + let wgsl_language_features = crate::WGSLLanguageFeatures::empty(); + WGSLLanguageExtension::all() + .iter() + .for_each(|wle| match *wle {}); + wgsl_language_features + } } impl dispatch::AdapterInterface for CoreAdapter { diff --git a/wgpu/src/dispatch.rs b/wgpu/src/dispatch.rs index ee1a8c4b25e..2765b2c429c 100644 --- a/wgpu/src/dispatch.rs +++ b/wgpu/src/dispatch.rs @@ -100,6 +100,9 @@ pub trait InstanceInterface: CommonTraits { ) -> Pin>; fn poll_all_devices(&self, force_wait: bool) -> bool; + + #[cfg(feature = "wgsl")] + fn wgsl_language_features(&self) -> crate::WGSLLanguageFeatures; } pub trait AdapterInterface: CommonTraits {