diff --git a/Cargo.lock b/Cargo.lock index cb6b839bc..2f4ed4ed2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -996,6 +996,7 @@ dependencies = [ "log", "num-traits 0.2.14", "petgraph", + "pp-rs", "serde", "spirv", "thiserror", @@ -1271,6 +1272,15 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb20dcc30536a1508e75d47dd0e399bb2fe7354dcf35cda9127f2bf1ed92e30e" +[[package]] +name = "pp-rs" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb458bb7f6e250e6eb79d5026badc10a3ebb8f9a15d1fff0f13d17c71f4d6dee" +dependencies = [ + "unicode-xid", +] + [[package]] name = "ppv-lite86" version = "0.2.10" diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 89dcc09a8..d8c64e8bd 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -78,7 +78,7 @@ test = true [features] default = [] spirv = ["naga/spv-in"] -spirv-web = ["spirv", "naga/wgsl-out"] +glsl = ["naga/glsl-in"] trace = ["serde", "wgc/trace"] replay = ["serde", "wgc/replay"] webgl = ["wgc"] @@ -146,6 +146,10 @@ optional = true version = "0.7" features = ["wgsl-in"] +[target.'cfg(target_arch = "wasm32")'.dependencies.naga] +version = "0.7" +features = ["wgsl-out"] + [target.'cfg(target_arch = "wasm32")'.dependencies] wasm-bindgen = "0.2.76" # remember to change version in wiki as well web-sys = { version = "0.3.53", features = [ diff --git a/wgpu/README.md b/wgpu/README.md index 3ff7d4f3e..2de2ec07d 100644 --- a/wgpu/README.md +++ b/wgpu/README.md @@ -56,4 +56,4 @@ Users can run the [naga](https://github.com/gfx-rs/naga) binary in the following cargo run -- ``` -In addition, SPIR-V can be used by enabling the `spirv` feature, or the `spirv-web` feature for wasm targets, at the cost of slightly increased build times. +In addition, SPIR-V can be used by enabling the `spirv` feature and GLSL can be enabled by enabling the `glsl` feature at the cost of slightly increased build times. diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 22796c2f5..609992d23 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -1011,6 +1011,22 @@ impl crate::Context for Context { let module = parser.parse().unwrap(); wgc::pipeline::ShaderModuleSource::Naga(module) } + #[cfg(feature = "glsl")] + ShaderSource::Glsl { + ref shader, + stage, + ref defines, + } => { + // Parse the given shader code and store its representation. + let options = naga::front::glsl::Options { + stage, + defines: defines.clone(), + }; + let mut parser = naga::front::glsl::Parser::default(); + let module = parser.parse(&options, shader).unwrap(); + + wgc::pipeline::ShaderModuleSource::Naga(module) + } ShaderSource::Wgsl(ref code) => wgc::pipeline::ShaderModuleSource::Wgsl(Borrowed(code)), }; let (id, error) = wgc::gfx_select!( diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index 616c758fb..7b31d6de8 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -1193,7 +1193,7 @@ impl crate::Context for Context { _shader_bound_checks: wgt::ShaderBoundChecks, ) -> Self::ShaderModuleId { let mut descriptor = match desc.source { - #[cfg(feature = "spirv-web")] + #[cfg(feature = "spirv")] crate::ShaderSource::SpirV(ref spv) => { use naga::{back, front, valid}; @@ -1214,6 +1214,29 @@ impl crate::Context for Context { let wgsl_text = back::wgsl::write_string(&spv_module, &spv_module_info).unwrap(); web_sys::GpuShaderModuleDescriptor::new(wgsl_text.as_str()) } + #[cfg(feature = "glsl")] + ShaderSource::Glsl { + ref shader, + stage, + ref defines, + } => { + // Parse the given shader code and store its representation. + let options = naga::front::glsl::Options { + stage, + defines: defines.clone(), + }; + let mut parser = naga::front::glsl::Parser::default(); + let glsl_module = parser.parse(&options, shader).unwrap(); + + let mut validator = valid::Validator::new( + valid::ValidationFlags::all(), + valid::Capabilities::all(), + ); + let glsl_module_info = validator.validate(&glsl_module).unwrap(); + + let wgsl_text = back::wgsl::write_string(&glsl_module, &glsl_module_info).unwrap(); + web_sys::GpuShaderModuleDescriptor::new(wgsl_text.as_str()) + } crate::ShaderSource::Wgsl(ref code) => web_sys::GpuShaderModuleDescriptor::new(code), }; if let Some(label) = desc.label { diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 3a2da91c7..35dde3e9b 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -747,6 +747,21 @@ pub enum ShaderSource<'a> { /// is passed to `gfx-rs` and `spirv_cross` for translation. #[cfg(feature = "spirv")] SpirV(Cow<'a, [u32]>), + /// GSLS module as a string slice. + /// + /// wgpu will attempt to parse and validate it. The module will get + /// passed to wgpu-core where it will translate it to the required languages. + /// + /// Note: GLSL is not yet fully supported and must be a direct ShaderStage. + #[cfg(feature = "glsl")] + Glsl { + /// The shaders code + shader: Cow<'a, str>, + /// Stage in which the GLSL shader is for example: naga::ShaderStage::Vertex + stage: naga::ShaderStage, + /// Defines to unlock configured shader features + defines: naga::FastHashMap, + }, /// WGSL module as a string slice. /// /// wgpu-rs will parse it and use for validation. It will attempt