From da38b8b07704a38b2ca64de0d29fcd2017a39ba4 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Fri, 18 Jun 2021 23:44:00 -0400 Subject: [PATCH] Make spirv an optional feature --- player/Cargo.toml | 2 +- wgpu-core/Cargo.toml | 3 ++- wgpu-core/src/device/mod.rs | 2 ++ wgpu-core/src/pipeline.rs | 1 + wgpu/Cargo.toml | 6 +++++- wgpu/README.md | 12 ++++++++++++ wgpu/src/backend/direct.rs | 1 + wgpu/src/backend/web.rs | 1 + wgpu/src/lib.rs | 1 + wgpu/src/util/mod.rs | 6 ++++-- 10 files changed, 30 insertions(+), 5 deletions(-) diff --git a/player/Cargo.toml b/player/Cargo.toml index 4ff38897e..dcb6ecb84 100644 --- a/player/Cargo.toml +++ b/player/Cargo.toml @@ -29,7 +29,7 @@ features = ["replay"] [dependencies.wgc] path = "../wgpu-core" package = "wgpu-core" -features = ["replay", "raw-window-handle"] +features = ["spirv", "replay", "raw-window-handle"] [dev-dependencies] serde = "1" diff --git a/wgpu-core/Cargo.toml b/wgpu-core/Cargo.toml index fee13faff..2cc5c49eb 100644 --- a/wgpu-core/Cargo.toml +++ b/wgpu-core/Cargo.toml @@ -13,6 +13,7 @@ license = "MIT OR Apache-2.0" [features] default = [] +spirv = ["naga/spv-in"] # Enable API tracing trace = ["ron", "serde", "wgt/trace", "arrayvec/serde"] # Enable API replaying @@ -37,7 +38,7 @@ thiserror = "1" [dependencies.naga] git = "https://github.com/gfx-rs/naga" tag = "gfx-26" -features = ["spv-in", "wgsl-in"] +features = ["wgsl-in"] [dependencies.wgt] path = "../wgpu-types" diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 323adbe79..2e39ac164 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -838,6 +838,7 @@ impl Device { source: pipeline::ShaderModuleSource<'a>, ) -> Result, pipeline::CreateShaderModuleError> { let module = match source { + #[cfg(feature = "spirv")] pipeline::ShaderModuleSource::SpirV(spv) => { profiling::scope!("naga::spv::parse"); // Parse the given shader code and store its representation. @@ -3476,6 +3477,7 @@ impl Global { if let Some(ref trace) = device.trace { let mut trace = trace.lock(); let data = match source { + #[cfg(feature = "spirv")] pipeline::ShaderModuleSource::SpirV(ref spv) => { trace.make_binary("spv", unsafe { std::slice::from_raw_parts(spv.as_ptr() as *const u8, spv.len() * 4) diff --git a/wgpu-core/src/pipeline.rs b/wgpu-core/src/pipeline.rs index c7ccb9598..fe0fe3943 100644 --- a/wgpu-core/src/pipeline.rs +++ b/wgpu-core/src/pipeline.rs @@ -9,6 +9,7 @@ use std::borrow::Cow; use thiserror::Error; pub enum ShaderModuleSource<'a> { + #[cfg(feature = "spirv")] SpirV(Cow<'a, [u32]>), Wgsl(Cow<'a, str>), Naga(naga::Module), diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 4b2ede3b9..6d1cfdc0d 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -17,6 +17,7 @@ all-features = true [features] default = [] +spirv = ["wgc/spirv"] trace = ["serde", "wgc/trace"] replay = ["serde", "wgc/replay"] webgl = ["wgc"] @@ -78,9 +79,12 @@ features = ["wgsl-in", "spv-out"] [[example]] name="hello-compute" -path="examples/hello-compute/main.rs" test = true +[[example]] +name="texture-arrays" +required-features = ["spirv"] + [target.'cfg(target_arch = "wasm32")'.dependencies] wasm-bindgen = "0.2.73" # remember to change version in wiki as well web-sys = { version = "=0.3.50", features = [ diff --git a/wgpu/README.md b/wgpu/README.md index 69af9056f..815452b26 100644 --- a/wgpu/README.md +++ b/wgpu/README.md @@ -43,6 +43,18 @@ The following environment variables can be used to configure how the framework e See [wiki article](https://github.com/gfx-rs/wgpu-rs/wiki/Running-on-the-Web-with-WebGPU-and-WebGL). +## Shaders + +[WGSL](https://gpuweb.github.io/gpuweb/wgsl/) is the main shading language of WebGPU. + +Users can run the [naga](https://github.com/gfx-rs/naga) binary in the following way to convert their SPIR-V shaders to WGSL: +```bash +cargo run -- + +``` + +In addition, SPIR-V can be used by enabling the `spirv` feature, and the cost of slightly increased build times. + ## Development If you need to test local fixes to gfx or other dependencies, the simplest way is to add a Cargo patch. For example, when working on DX12 backend on Windows, you can check out the latest release branch in the [gfx-hal repository](https://github.com/gfx-rs/gfx) (e.g. currently `hal-0.8`) and add this patch to the end of `Cargo.toml`: diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index feec3f9a1..d212af0ce 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -810,6 +810,7 @@ impl crate::Context for Context { label: desc.label.map(Borrowed), }; let source = match desc.source { + #[cfg(feature = "spirv")] ShaderSource::SpirV(ref spv) => wgc::pipeline::ShaderModuleSource::SpirV(Borrowed(spv)), ShaderSource::Wgsl(ref code) => wgc::pipeline::ShaderModuleSource::Wgsl(Borrowed(code)), }; diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index cfa102328..2dbce8e86 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -1140,6 +1140,7 @@ impl crate::Context for Context { desc: &crate::ShaderModuleDescriptor, ) -> Self::ShaderModuleId { let mut descriptor = match desc.source { + #[cfg(feature = "spirv")] crate::ShaderSource::SpirV(ref spv) => { web_sys::GpuShaderModuleDescriptor::new(&js_sys::Uint32Array::from(&**spv)) } diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 8dd0caf7f..d38c28a80 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -739,6 +739,7 @@ pub enum ShaderSource<'a> { /// /// wgpu will attempt to parse and validate it, but the original binary /// is passed to `gfx-rs` and `spirv_cross` for translation. + #[cfg(feature = "spirv")] SpirV(Cow<'a, [u32]>), /// WGSL module as a string slice. /// diff --git a/wgpu/src/util/mod.rs b/wgpu/src/util/mod.rs index d932cf90b..b18548eb0 100644 --- a/wgpu/src/util/mod.rs +++ b/wgpu/src/util/mod.rs @@ -4,9 +4,10 @@ mod belt; mod device; mod encoder; +use std::future::Future; +#[cfg(feature = "spirv")] use std::{ borrow::Cow, - future::Future, mem::{align_of, size_of}, ptr::copy_nonoverlapping, }; @@ -24,15 +25,16 @@ pub use encoder::RenderEncoder; /// - Input length isn't multiple of 4 /// - Input is longer than [`usize::max_value`] /// - SPIR-V magic number is missing from beginning of stream +#[cfg(feature = "spirv")] pub fn make_spirv(data: &[u8]) -> super::ShaderSource { super::ShaderSource::SpirV(make_spirv_raw(data)) } /// Version of [`make_spirv`] intended for use with [`Device::create_shader_module_spirv`]. /// Returns raw slice instead of ShaderSource. +#[cfg(feature = "spirv")] pub fn make_spirv_raw(data: &[u8]) -> Cow<[u32]> { const MAGIC_NUMBER: u32 = 0x0723_0203; - assert_eq!( data.len() % size_of::(), 0,