From e9e325459d1bf116fa89b27e16871bf9f9eb11a4 Mon Sep 17 00:00:00 2001 From: Ben Hansen Date: Sat, 29 Aug 2020 15:22:06 -0600 Subject: [PATCH] using anyhow instead of failure --- Cargo.lock | 13 ++-- code/beginner/tutorial3-pipeline/Cargo.toml | 4 +- code/beginner/tutorial3-pipeline/build.rs | 34 +++++---- code/beginner/tutorial4-buffer/Cargo.toml | 6 +- code/beginner/tutorial4-buffer/build.rs | 34 +++++---- code/beginner/tutorial5-textures/Cargo.toml | 17 +++-- code/beginner/tutorial5-textures/build.rs | 74 +++++++++++++++++++ code/beginner/tutorial5-textures/src/main.rs | 29 ++++---- .../tutorial5-textures/src/texture.rs | 12 ++- docs/beginner/tutorial3-pipeline/README.md | 6 +- 10 files changed, 167 insertions(+), 62 deletions(-) create mode 100644 code/beginner/tutorial5-textures/build.rs diff --git a/Cargo.lock b/Cargo.lock index 3bf149d3..a7d4bba3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2461,8 +2461,8 @@ dependencies = [ name = "tutorial3-pipeline" version = "0.1.0" dependencies = [ + "anyhow 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", "cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "fs_extra 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2476,9 +2476,9 @@ dependencies = [ name = "tutorial4-buffer" version = "0.1.0" dependencies = [ + "anyhow 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", "bytemuck 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "fs_extra 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2492,14 +2492,17 @@ dependencies = [ name = "tutorial5-textures" version = "0.1.0" dependencies = [ + "anyhow 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", "bytemuck 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "fs_extra 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "image 0.22.5 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "image 0.23.7 (registry+https://github.com/rust-lang/crates.io-index)", "shaderc 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wgpu 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winit 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wgpu 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winit 0.22.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/code/beginner/tutorial3-pipeline/Cargo.toml b/code/beginner/tutorial3-pipeline/Cargo.toml index 4a2a11ac..a38c1b2a 100644 --- a/code/beginner/tutorial3-pipeline/Cargo.toml +++ b/code/beginner/tutorial3-pipeline/Cargo.toml @@ -16,8 +16,8 @@ futures = "0.3" [build-dependencies] shaderc = "0.6" glob = "0.3" -failure = "0.1" -fs_extra = "1.1" +fs_extra = "1.2" +anyhow = "1.0" [[bin]] name = "tutorial3-pipeline" diff --git a/code/beginner/tutorial3-pipeline/build.rs b/code/beginner/tutorial3-pipeline/build.rs index 5fdb06da..59820097 100644 --- a/code/beginner/tutorial3-pipeline/build.rs +++ b/code/beginner/tutorial3-pipeline/build.rs @@ -1,5 +1,5 @@ use glob::glob; -use failure::bail; +use anyhow::*; use std::fs::{read_to_string, write}; use std::path::{PathBuf}; @@ -11,8 +11,11 @@ struct ShaderData { } impl ShaderData { - pub fn load(src_path: PathBuf) -> Result { - let extension = src_path.extension().unwrap().to_str().unwrap(); + pub fn load(src_path: PathBuf) -> Result { + let extension = src_path.extension() + .context("File has no extension")? + .to_str() + .context("Extension cannot be converted to &str")?; let kind = match extension { "vert" => shaderc::ShaderKind::Vertex, "frag" => shaderc::ShaderKind::Fragment, @@ -27,40 +30,45 @@ impl ShaderData { } } -fn main() { +fn main() -> Result<()> { // This tells cargo to rerun this script if something in /src/ changes. println!("cargo:rerun-if-changed=src/*"); // Collect all shaders recursively within /src/ let mut shader_paths = [ - glob("./src/**/*.vert").unwrap(), - glob("./src/**/*.frag").unwrap(), - glob("./src/**/*.comp").unwrap(), + glob("./src/**/*.vert")?, + glob("./src/**/*.frag")?, + glob("./src/**/*.comp")?, ]; // This could be parallelized let shaders = shader_paths.iter_mut() .flatten() .map(|glob_result| { - ShaderData::load(glob_result.unwrap()).unwrap() + ShaderData::load(glob_result?) }) - .collect::>(); + .collect::>>() + .into_iter() + .collect::>>(); - let mut compiler = shaderc::Compiler::new().unwrap(); + let mut compiler = shaderc::Compiler::new() + .context("Unable to create shader compiler")?; // This can't be parallelized. The [shaderc::Compiler] is not // thread safe. Also, it creates a lot of resources. You could // spawn multiple processes to handle this, but it would probably // be better just to only compile shaders that have been changed // recently. - for shader in shaders { + for shader in shaders? { let compiled = compiler.compile_into_spirv( &shader.src, shader.kind, &shader.src_path.to_str().unwrap(), "main", None - ).unwrap(); - write(shader.spv_path, compiled.as_binary_u8()).unwrap(); + )?; + write(shader.spv_path, compiled.as_binary_u8())?; } + + Ok(()) } \ No newline at end of file diff --git a/code/beginner/tutorial4-buffer/Cargo.toml b/code/beginner/tutorial4-buffer/Cargo.toml index 7fe03e3e..85870de9 100644 --- a/code/beginner/tutorial4-buffer/Cargo.toml +++ b/code/beginner/tutorial4-buffer/Cargo.toml @@ -15,10 +15,10 @@ futures = "0.3" bytemuck = "1.4" [build-dependencies] -shaderc = "0.6" -glob = "0.3" -failure = "0.1" +anyhow = "1.0" fs_extra = "1.2" +glob = "0.3" +shaderc = "0.6" [[bin]] name = "tutorial4-buffer" diff --git a/code/beginner/tutorial4-buffer/build.rs b/code/beginner/tutorial4-buffer/build.rs index 5fdb06da..59820097 100644 --- a/code/beginner/tutorial4-buffer/build.rs +++ b/code/beginner/tutorial4-buffer/build.rs @@ -1,5 +1,5 @@ use glob::glob; -use failure::bail; +use anyhow::*; use std::fs::{read_to_string, write}; use std::path::{PathBuf}; @@ -11,8 +11,11 @@ struct ShaderData { } impl ShaderData { - pub fn load(src_path: PathBuf) -> Result { - let extension = src_path.extension().unwrap().to_str().unwrap(); + pub fn load(src_path: PathBuf) -> Result { + let extension = src_path.extension() + .context("File has no extension")? + .to_str() + .context("Extension cannot be converted to &str")?; let kind = match extension { "vert" => shaderc::ShaderKind::Vertex, "frag" => shaderc::ShaderKind::Fragment, @@ -27,40 +30,45 @@ impl ShaderData { } } -fn main() { +fn main() -> Result<()> { // This tells cargo to rerun this script if something in /src/ changes. println!("cargo:rerun-if-changed=src/*"); // Collect all shaders recursively within /src/ let mut shader_paths = [ - glob("./src/**/*.vert").unwrap(), - glob("./src/**/*.frag").unwrap(), - glob("./src/**/*.comp").unwrap(), + glob("./src/**/*.vert")?, + glob("./src/**/*.frag")?, + glob("./src/**/*.comp")?, ]; // This could be parallelized let shaders = shader_paths.iter_mut() .flatten() .map(|glob_result| { - ShaderData::load(glob_result.unwrap()).unwrap() + ShaderData::load(glob_result?) }) - .collect::>(); + .collect::>>() + .into_iter() + .collect::>>(); - let mut compiler = shaderc::Compiler::new().unwrap(); + let mut compiler = shaderc::Compiler::new() + .context("Unable to create shader compiler")?; // This can't be parallelized. The [shaderc::Compiler] is not // thread safe. Also, it creates a lot of resources. You could // spawn multiple processes to handle this, but it would probably // be better just to only compile shaders that have been changed // recently. - for shader in shaders { + for shader in shaders? { let compiled = compiler.compile_into_spirv( &shader.src, shader.kind, &shader.src_path.to_str().unwrap(), "main", None - ).unwrap(); - write(shader.spv_path, compiled.as_binary_u8()).unwrap(); + )?; + write(shader.spv_path, compiled.as_binary_u8())?; } + + Ok(()) } \ No newline at end of file diff --git a/code/beginner/tutorial5-textures/Cargo.toml b/code/beginner/tutorial5-textures/Cargo.toml index 7d02f2d5..3a228519 100644 --- a/code/beginner/tutorial5-textures/Cargo.toml +++ b/code/beginner/tutorial5-textures/Cargo.toml @@ -7,14 +7,19 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -image = "0.22" -winit = "0.20.0-alpha3" -shaderc = "0.6" +image = "0.23" +winit = "0.22" cgmath = "0.17" failure = "0.1" -wgpu = "0.5.0" -futures = "0.3.4" -bytemuck = "1.2.0" +wgpu = "0.6" +futures = "0.3" +bytemuck = "1.4" + +[build-dependencies] +anyhow = "1.0" +fs_extra = "1.2" +glob = "0.3" +shaderc = "0.6" [[bin]] name = "tutorial5-textures" diff --git a/code/beginner/tutorial5-textures/build.rs b/code/beginner/tutorial5-textures/build.rs new file mode 100644 index 00000000..59820097 --- /dev/null +++ b/code/beginner/tutorial5-textures/build.rs @@ -0,0 +1,74 @@ +use glob::glob; +use anyhow::*; +use std::fs::{read_to_string, write}; +use std::path::{PathBuf}; + +struct ShaderData { + src: String, + src_path: PathBuf, + spv_path: PathBuf, + kind: shaderc::ShaderKind, +} + +impl ShaderData { + pub fn load(src_path: PathBuf) -> Result { + let extension = src_path.extension() + .context("File has no extension")? + .to_str() + .context("Extension cannot be converted to &str")?; + let kind = match extension { + "vert" => shaderc::ShaderKind::Vertex, + "frag" => shaderc::ShaderKind::Fragment, + "comp" => shaderc::ShaderKind::Compute, + _ => bail!("Unsupported shader: {}", src_path.display()), + }; + + let src = read_to_string(src_path.clone())?; + let spv_path = src_path.with_extension(format!("{}.spv", extension)); + + Ok(Self { src, src_path, spv_path, kind }) + } +} + +fn main() -> Result<()> { + // This tells cargo to rerun this script if something in /src/ changes. + println!("cargo:rerun-if-changed=src/*"); + + // Collect all shaders recursively within /src/ + let mut shader_paths = [ + glob("./src/**/*.vert")?, + glob("./src/**/*.frag")?, + glob("./src/**/*.comp")?, + ]; + + // This could be parallelized + let shaders = shader_paths.iter_mut() + .flatten() + .map(|glob_result| { + ShaderData::load(glob_result?) + }) + .collect::>>() + .into_iter() + .collect::>>(); + + let mut compiler = shaderc::Compiler::new() + .context("Unable to create shader compiler")?; + + // This can't be parallelized. The [shaderc::Compiler] is not + // thread safe. Also, it creates a lot of resources. You could + // spawn multiple processes to handle this, but it would probably + // be better just to only compile shaders that have been changed + // recently. + for shader in shaders? { + let compiled = compiler.compile_into_spirv( + &shader.src, + shader.kind, + &shader.src_path.to_str().unwrap(), + "main", + None + )?; + write(shader.spv_path, compiled.as_binary_u8())?; + } + + Ok(()) +} \ No newline at end of file diff --git a/code/beginner/tutorial5-textures/src/main.rs b/code/beginner/tutorial5-textures/src/main.rs index fabd591d..47feced9 100644 --- a/code/beginner/tutorial5-textures/src/main.rs +++ b/code/beginner/tutorial5-textures/src/main.rs @@ -58,40 +58,39 @@ struct State { queue: wgpu::Queue, sc_desc: wgpu::SwapChainDescriptor, swap_chain: wgpu::SwapChain, - render_pipeline: wgpu::RenderPipeline, - + size: winit::dpi::PhysicalSize, vertex_buffer: wgpu::Buffer, index_buffer: wgpu::Buffer, num_indices: u32, - + // NEW! #[allow(dead_code)] diffuse_texture: texture::Texture, diffuse_bind_group: wgpu::BindGroup, - - size: winit::dpi::PhysicalSize, } impl State { async fn new(window: &Window) -> Self { let size = window.inner_size(); - let surface = wgpu::Surface::create(window); - - let adapter = wgpu::Adapter::request( + // The instance is a handle to our GPU + // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU + let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY); + let surface = unsafe { instance.create_surface(window) }; + let adapter = instance.request_adapter( &wgpu::RequestAdapterOptions { power_preference: wgpu::PowerPreference::Default, compatible_surface: Some(&surface), }, - wgpu::BackendBit::PRIMARY, // Vulkan + Metal + DX12 + Browser WebGPU ).await.unwrap(); - - let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor { - extensions: wgpu::Extensions { - anisotropic_filtering: false, + let (device, queue) = adapter.request_device( + &wgpu::DeviceDescriptor { + features: wgpu::Features::empty(), + limits: wgpu::Limits::default(), + shader_validation: true, }, - limits: Default::default(), - }).await; + None, // Trace path + ).await.unwrap(); let sc_desc = wgpu::SwapChainDescriptor { diff --git a/code/beginner/tutorial5-textures/src/texture.rs b/code/beginner/tutorial5-textures/src/texture.rs index a94acfd6..4a71668b 100644 --- a/code/beginner/tutorial5-textures/src/texture.rs +++ b/code/beginner/tutorial5-textures/src/texture.rs @@ -7,12 +7,20 @@ pub struct Texture { } impl Texture { - pub fn from_bytes(device: &wgpu::Device, bytes: &[u8], label: &str) -> Result<(Self, wgpu::CommandBuffer), failure::Error> { + pub fn from_bytes( + device: &wgpu::Device, + bytes: &[u8], + label: &str + ) -> Result<(Self, wgpu::CommandBuffer), failure::Error> { let img = image::load_from_memory(bytes)?; Self::from_image(device, &img, Some(label)) } - pub fn from_image(device: &wgpu::Device, img: &image::DynamicImage, label: Option<&str>) -> Result<(Self, wgpu::CommandBuffer), failure::Error> { + pub fn from_image( + device: &wgpu::Device, + img: &image::DynamicImage, + label: Option<&str> + ) -> Result<(Self, wgpu::CommandBuffer), failure::Error> { let rgba = img.as_rgba8().unwrap(); let dimensions = img.dimensions(); diff --git a/docs/beginner/tutorial3-pipeline/README.md b/docs/beginner/tutorial3-pipeline/README.md index 6c96c2ef..7737095f 100644 --- a/docs/beginner/tutorial3-pipeline/README.md +++ b/docs/beginner/tutorial3-pipeline/README.md @@ -274,10 +274,10 @@ futures = "0.3" # NEW! [build-dependencies] -shaderc = "0.6" -glob = "0.3" -failure = "0.1" +anyhow = "1.0" fs_extra = "1.1" +glob = "0.3" +shaderc = "0.6" ``` We've removed shaderc from our dependencies and added a new `[build-depencies]` block. These are dependencies for our build script. We know about shaderc, but the other ones are meant to simplify dealing with the file system and dealing with rust errors.