diff --git a/wgpu/CHANGELOG.md b/wgpu/CHANGELOG.md index bda8e65ebd..964ef9581b 100644 --- a/wgpu/CHANGELOG.md +++ b/wgpu/CHANGELOG.md @@ -1,4 +1,7 @@ # Change Log +### unreleased +- introduce `ShaderModuleDescriptor` + ### v0.6.2 (2020-11-24) - don't panic in the staging belt if the channel is dropped diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 1804946f73..7c60e2058a 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -26,14 +26,14 @@ vulkan-portability = ["wgc/gfx-backend-vulkan"] package = "wgpu-core" #version = "0.6" git = "https://github.com/gfx-rs/wgpu" -rev = "4513fb2b83fe2cd19682ccca9c55a6995f061699" +rev = "9960ded7ae83762e7e84f7f2e8d974b9a38580a1" features = ["raw-window-handle"] [dependencies.wgt] package = "wgpu-types" #version = "0.6" git = "https://github.com/gfx-rs/wgpu" -rev = "4513fb2b83fe2cd19682ccca9c55a6995f061699" +rev = "9960ded7ae83762e7e84f7f2e8d974b9a38580a1" [dependencies] arrayvec = "0.5" @@ -48,8 +48,10 @@ serde = { version = "1", features = ["derive"], optional = true } # Enable X11 support for GL # Note: we may consider switching this to "dev-dependencies" if users # want to opt into X11 explicitly. -[target.'cfg(all(unix, not(target_os = "ios"), not(target_os = "macos")))'.dependencies] -gfx-backend-gl = { git = "https://github.com/gfx-rs/gfx", features = ["x11"] } +[target.'cfg(all(unix, not(target_os = "ios"), not(target_os = "macos")))'.dependencies.gfx-backend-gl] +git = "https://github.com/gfx-rs/gfx" +rev = "654ad48ee39ce2a341407ae2857ddf4db639ea54" +features = ["x11"] [dev-dependencies] cgmath = "0.17" diff --git a/wgpu/examples/boids/main.rs b/wgpu/examples/boids/main.rs index 9624b2e463..9aeda25ce4 100644 --- a/wgpu/examples/boids/main.rs +++ b/wgpu/examples/boids/main.rs @@ -34,9 +34,9 @@ impl framework::Example for Example { ) -> Self { // load (and compile) shaders and create shader modules - let boids_module = device.create_shader_module(wgpu::include_spirv!("boids.comp.spv")); - let vs_module = device.create_shader_module(wgpu::include_spirv!("shader.vert.spv")); - let fs_module = device.create_shader_module(wgpu::include_spirv!("shader.frag.spv")); + let boids_module = device.create_shader_module(&wgpu::include_spirv!("boids.comp.spv")); + let vs_module = device.create_shader_module(&wgpu::include_spirv!("shader.vert.spv")); + let fs_module = device.create_shader_module(&wgpu::include_spirv!("shader.frag.spv")); // buffer for simulation parameters uniform diff --git a/wgpu/examples/cube/main.rs b/wgpu/examples/cube/main.rs index 8b4160e36f..867d8d6d6a 100644 --- a/wgpu/examples/cube/main.rs +++ b/wgpu/examples/cube/main.rs @@ -273,8 +273,8 @@ impl framework::Example for Example { }], }; - let vs_module = device.create_shader_module(wgpu::include_spirv!("shader.vert.spv")); - let fs_module = device.create_shader_module(wgpu::include_spirv!("shader.frag.spv")); + let vs_module = device.create_shader_module(&wgpu::include_spirv!("shader.vert.spv")); + let fs_module = device.create_shader_module(&wgpu::include_spirv!("shader.frag.spv")); let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: None, @@ -310,7 +310,8 @@ impl framework::Example for Example { .features() .contains(wgt::Features::NON_FILL_POLYGON_MODE) { - let fs_wire_module = device.create_shader_module(wgpu::include_spirv!("wire.frag.spv")); + let fs_wire_module = + device.create_shader_module(&wgpu::include_spirv!("wire.frag.spv")); let pipeline_wire = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: None, layout: Some(&pipeline_layout), diff --git a/wgpu/examples/hello-compute/main.rs b/wgpu/examples/hello-compute/main.rs index 7ad7817880..ca1cdd0789 100644 --- a/wgpu/examples/hello-compute/main.rs +++ b/wgpu/examples/hello-compute/main.rs @@ -45,7 +45,7 @@ async fn execute_gpu(numbers: Vec) -> Vec { .unwrap(); // Loads the shader from the SPIR-V file.arrayvec - let cs_module = device.create_shader_module(wgpu::include_spirv!("shader.comp.spv")); + let cs_module = device.create_shader_module(&wgpu::include_spirv!("shader.comp.spv")); // Gets the size in bytes of the buffer. let slice_size = numbers.len() * std::mem::size_of::(); diff --git a/wgpu/examples/hello-triangle/main.rs b/wgpu/examples/hello-triangle/main.rs index e41c5a18dd..24d23ed5c6 100644 --- a/wgpu/examples/hello-triangle/main.rs +++ b/wgpu/examples/hello-triangle/main.rs @@ -32,8 +32,8 @@ async fn run(event_loop: EventLoop<()>, window: Window, swapchain_format: wgpu:: .expect("Failed to create device"); // Load the shaders from disk - let vs_module = device.create_shader_module(wgpu::include_spirv!("shader.vert.spv")); - let fs_module = device.create_shader_module(wgpu::include_spirv!("shader.frag.spv")); + let vs_module = device.create_shader_module(&wgpu::include_spirv!("shader.vert.spv")); + let fs_module = device.create_shader_module(&wgpu::include_spirv!("shader.frag.spv")); let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, diff --git a/wgpu/examples/mipmap/main.rs b/wgpu/examples/mipmap/main.rs index d9e47548da..c579c3fc19 100644 --- a/wgpu/examples/mipmap/main.rs +++ b/wgpu/examples/mipmap/main.rs @@ -79,8 +79,8 @@ impl Example { texture: &wgpu::Texture, mip_count: u32, ) { - let vs_module = device.create_shader_module(wgpu::include_spirv!("blit.vert.spv")); - let fs_module = device.create_shader_module(wgpu::include_spirv!("blit.frag.spv")); + let vs_module = device.create_shader_module(&wgpu::include_spirv!("blit.vert.spv")); + let fs_module = device.create_shader_module(&wgpu::include_spirv!("blit.frag.spv")); let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("blit"), @@ -257,8 +257,8 @@ impl framework::Example for Example { }); // Create the render pipeline - let vs_module = device.create_shader_module(wgpu::include_spirv!("draw.vert.spv")); - let fs_module = device.create_shader_module(wgpu::include_spirv!("draw.frag.spv")); + let vs_module = device.create_shader_module(&wgpu::include_spirv!("draw.vert.spv")); + let fs_module = device.create_shader_module(&wgpu::include_spirv!("draw.frag.spv")); let draw_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("draw"), diff --git a/wgpu/examples/msaa-line/main.rs b/wgpu/examples/msaa-line/main.rs index a117398de1..ca8e855de1 100644 --- a/wgpu/examples/msaa-line/main.rs +++ b/wgpu/examples/msaa-line/main.rs @@ -128,8 +128,8 @@ impl framework::Example for Example { log::info!("Press left/right arrow keys to change sample_count."); let sample_count = 4; - let vs_module = device.create_shader_module(wgpu::include_spirv!("shader.vert.spv")); - let fs_module = device.create_shader_module(wgpu::include_spirv!("shader.frag.spv")); + let vs_module = device.create_shader_module(&wgpu::include_spirv!("shader.vert.spv")); + let fs_module = device.create_shader_module(&wgpu::include_spirv!("shader.frag.spv")); let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, diff --git a/wgpu/examples/shadow/main.rs b/wgpu/examples/shadow/main.rs index 50da73b9c4..cf79576b88 100644 --- a/wgpu/examples/shadow/main.rs +++ b/wgpu/examples/shadow/main.rs @@ -464,7 +464,7 @@ impl framework::Example for Example { }); // Create the render pipeline - let vs_module = device.create_shader_module(wgpu::include_spirv!("bake.vert.spv")); + let vs_module = device.create_shader_module(&wgpu::include_spirv!("bake.vert.spv")); let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("shadow"), @@ -600,8 +600,8 @@ impl framework::Example for Example { }); // Create the render pipeline - let vs_module = device.create_shader_module(wgpu::include_spirv!("forward.vert.spv")); - let fs_module = device.create_shader_module(wgpu::include_spirv!("forward.frag.spv")); + let vs_module = device.create_shader_module(&wgpu::include_spirv!("forward.vert.spv")); + let fs_module = device.create_shader_module(&wgpu::include_spirv!("forward.frag.spv")); let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("main"), diff --git a/wgpu/examples/skybox/main.rs b/wgpu/examples/skybox/main.rs index a1993d6306..77f83ce2dd 100644 --- a/wgpu/examples/skybox/main.rs +++ b/wgpu/examples/skybox/main.rs @@ -84,8 +84,8 @@ impl framework::Example for Skybox { }); // Create the render pipeline - let vs_module = device.create_shader_module(wgpu::include_spirv!("shader.vert.spv")); - let fs_module = device.create_shader_module(wgpu::include_spirv!("shader.frag.spv")); + let vs_module = device.create_shader_module(&wgpu::include_spirv!("shader.vert.spv")); + let fs_module = device.create_shader_module(&wgpu::include_spirv!("shader.frag.spv")); let aspect = sc_desc.width as f32 / sc_desc.height as f32; let uniforms = Self::generate_uniforms(aspect); diff --git a/wgpu/examples/texture-arrays/main.rs b/wgpu/examples/texture-arrays/main.rs index 85567993a6..f02009b36b 100644 --- a/wgpu/examples/texture-arrays/main.rs +++ b/wgpu/examples/texture-arrays/main.rs @@ -91,7 +91,7 @@ impl framework::Example for Example { queue: &wgpu::Queue, ) -> Self { let mut uniform_workaround = false; - let vs_module = device.create_shader_module(wgpu::include_spirv!("shader.vert.spv")); + let vs_module = device.create_shader_module(&wgpu::include_spirv!("shader.vert.spv")); let fs_source = match device.features() { f if f.contains(wgpu::Features::UNSIZED_BINDING_ARRAY) => { wgpu::include_spirv!("unsized-non-uniform.frag.spv") @@ -108,7 +108,7 @@ impl framework::Example for Example { } _ => unreachable!(), }; - let fs_module = device.create_shader_module(fs_source); + let fs_module = device.create_shader_module(&fs_source); let vertex_size = std::mem::size_of::(); let vertex_data = create_vertices(); diff --git a/wgpu/examples/water/main.rs b/wgpu/examples/water/main.rs index 7f9ff24722..e39227f255 100644 --- a/wgpu/examples/water/main.rs +++ b/wgpu/examples/water/main.rs @@ -486,13 +486,13 @@ impl framework::Example for Example { // Upload/compile them to GPU code. let water_vs_module = - device.create_shader_module(wgpu::include_spirv!("water_shader.vert.spv")); + device.create_shader_module(&wgpu::include_spirv!("water_shader.vert.spv")); let water_fs_module = - device.create_shader_module(wgpu::include_spirv!("water_shader.frag.spv")); + device.create_shader_module(&wgpu::include_spirv!("water_shader.frag.spv")); let terrain_vs_module = - device.create_shader_module(wgpu::include_spirv!("terrain_shader.vert.spv")); + device.create_shader_module(&wgpu::include_spirv!("terrain_shader.vert.spv")); let terrain_fs_module = - device.create_shader_module(wgpu::include_spirv!("terrain_shader.frag.spv")); + device.create_shader_module(&wgpu::include_spirv!("terrain_shader.frag.spv")); // Create the render pipelines. These describe how the data will flow through the GPU, and what // constraints and modifiers it will have. diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 069242ab41..8b6b3640ee 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -3,7 +3,7 @@ use crate::{ BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, CommandEncoderDescriptor, ComputePipelineDescriptor, Features, Label, Limits, LoadOp, MapMode, Operations, PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, RenderPipelineDescriptor, - SamplerDescriptor, ShaderModuleSource, SwapChainStatus, TextureDescriptor, + SamplerDescriptor, ShaderModuleDescriptor, ShaderSource, SwapChainStatus, TextureDescriptor, TextureViewDescriptor, }; @@ -725,18 +725,19 @@ impl crate::Context for Context { fn device_create_shader_module( &self, device: &Self::DeviceId, - source: ShaderModuleSource, + desc: &ShaderModuleDescriptor, ) -> Self::ShaderModuleId { - let descriptor = wgc::pipeline::ShaderModuleDescriptor { - label: None, - source: match source { - ShaderModuleSource::SpirV(spv) => wgc::pipeline::ShaderModuleSource::SpirV(spv), - ShaderModuleSource::Wgsl(code) => wgc::pipeline::ShaderModuleSource::Wgsl(code), - }, - }; let global = &self.0; + let descriptor = wgc::pipeline::ShaderModuleDescriptor { + label: desc.label.map(Borrowed), + experimental_translation: desc.experimental_translation, + }; + let source = match desc.source { + ShaderSource::SpirV(ref spv) => wgc::pipeline::ShaderModuleSource::SpirV(Borrowed(spv)), + ShaderSource::Wgsl(ref code) => wgc::pipeline::ShaderModuleSource::Wgsl(Borrowed(code)), + }; let (id, error) = wgc::gfx_select!( - device.id => global.device_create_shader_module(device.id, &descriptor, PhantomData) + device.id => global.device_create_shader_module(device.id, &descriptor, source, PhantomData) ); if let Some(cause) = error { self.handle_error( diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index ce4106d43f..641651fca2 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -2,8 +2,9 @@ use crate::{ BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, BindingType, BufferBindingType, BufferDescriptor, CommandEncoderDescriptor, ComputePipelineDescriptor, LoadOp, PipelineLayoutDescriptor, ProgrammableStageDescriptor, RenderBundleEncoderDescriptor, - RenderPipelineDescriptor, SamplerDescriptor, ShaderModuleSource, StorageTextureAccess, - SwapChainStatus, TextureDescriptor, TextureViewDescriptor, TextureViewDimension, + RenderPipelineDescriptor, SamplerDescriptor, ShaderModuleDescriptor, ShaderSource, + StorageTextureAccess, SwapChainStatus, TextureDescriptor, TextureViewDescriptor, + TextureViewDimension, }; use futures::FutureExt; @@ -965,18 +966,20 @@ impl crate::Context for Context { fn device_create_shader_module( &self, device: &Self::DeviceId, - source: ShaderModuleSource, + desc: &ShaderModuleDescriptor, ) -> Self::ShaderModuleId { - let desc = match source { - ShaderModuleSource::SpirV(spv) => { - web_sys::GpuShaderModuleDescriptor::new(&js_sys::Uint32Array::from(&*spv)) + let mut descriptor = match desc.source { + ShaderSource::SpirV(ref spv) => { + web_sys::GpuShaderModuleDescriptor::new(&js_sys::Uint32Array::from(&**spv)) } - ShaderModuleSource::Wgsl(_code) => { + ShaderSource::Wgsl(_) => { panic!("WGSL is not yet supported by the Web backend") } }; - // TODO: label - Sendable(device.0.create_shader_module(&desc)) + if let Some(ref label) = desc.label { + descriptor.label(label); + } + Sendable(device.0.create_shader_module(&descriptor)) } fn device_create_bind_group_layout( diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index fbd32f81bb..cf98bb414c 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -210,7 +210,7 @@ trait Context: Debug + Send + Sized + Sync { fn device_create_shader_module( &self, device: &Self::DeviceId, - source: ShaderModuleSource, + desc: &ShaderModuleDescriptor, ) -> Self::ShaderModuleId; fn device_create_bind_group_layout( &self, @@ -672,7 +672,7 @@ impl Drop for ShaderModule { } /// Source of a shader module. -pub enum ShaderModuleSource<'a> { +pub enum ShaderSource<'a> { /// SPIR-V module represented as a slice of words. /// /// wgpu will attempt to parse and validate it, but the original binary @@ -687,6 +687,16 @@ pub enum ShaderModuleSource<'a> { Wgsl(Cow<'a, str>), } +/// Descriptor for a shader module. +pub struct ShaderModuleDescriptor<'a> { + /// Debug label of the shader module. This will show up in graphics debuggers for easy identification. + pub label: Label<'a>, + /// Source code for the shader. + pub source: ShaderSource<'a>, + /// Experimental translation path attempts to avoid SPIR-V and work with Naga IR directly. + pub experimental_translation: bool, +} + /// Handle to a pipeline layout. /// /// A `PipelineLayout` object describes the available binding groups of a pipeline. @@ -1415,10 +1425,10 @@ impl Device { } /// Creates a shader module from either SPIR-V or WGSL source code. - pub fn create_shader_module(&self, source: ShaderModuleSource) -> ShaderModule { + pub fn create_shader_module(&self, desc: &ShaderModuleDescriptor) -> ShaderModule { ShaderModule { context: Arc::clone(&self.context), - id: Context::device_create_shader_module(&*self.context, &self.id, source), + id: Context::device_create_shader_module(&*self.context, &self.id, desc), } } diff --git a/wgpu/src/macros.rs b/wgpu/src/macros.rs index 41bd81d518..5521df199e 100644 --- a/wgpu/src/macros.rs +++ b/wgpu/src/macros.rs @@ -49,7 +49,11 @@ macro_rules! include_spirv { ($($token:tt)*) => { { //log::info!("including '{}'", $($token)*); - $crate::util::make_spirv(include_bytes!($($token)*)) + $crate::ShaderModuleDescriptor { + label: Some($($token)*), + source: $crate::util::make_spirv(include_bytes!($($token)*)), + experimental_translation: false, + } } }; } diff --git a/wgpu/src/util/mod.rs b/wgpu/src/util/mod.rs index 6c25d8ed81..850fd65385 100644 --- a/wgpu/src/util/mod.rs +++ b/wgpu/src/util/mod.rs @@ -19,7 +19,7 @@ pub use belt::StagingBelt; /// - Input length isn't multiple of 4 /// - Input is longer than [`usize::max_value`] /// - SPIR-V magic number is missing from beginning of stream -pub fn make_spirv<'a>(data: &'a [u8]) -> super::ShaderModuleSource<'a> { +pub fn make_spirv<'a>(data: &'a [u8]) -> super::ShaderSource<'a> { const MAGIC_NUMBER: u32 = 0x0723_0203; assert_eq!( @@ -48,7 +48,7 @@ pub fn make_spirv<'a>(data: &'a [u8]) -> super::ShaderModuleSource<'a> { "wrong magic word {:x}. Make sure you are using a binary SPIRV file.", words[0] ); - super::ShaderModuleSource::SpirV(words) + super::ShaderSource::SpirV(words) } /// Utility methods not meant to be in the main API.