diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index e4fb28d448..e59b7eab62 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -28,14 +28,14 @@ vulkan = ["wgc/gfx-backend-vulkan"] package = "wgpu-core" version = "0.5" git = "https://github.com/gfx-rs/wgpu" -rev = "d1deae5747f5bd0a6503c1462555f201eaae02c9" +rev = "fc2dd481b2713cd0eda6ffa540faeaf7418fd051" features = ["raw-window-handle"] [dependencies.wgt] package = "wgpu-types" version = "0.5" git = "https://github.com/gfx-rs/wgpu" -rev = "d1deae5747f5bd0a6503c1462555f201eaae02c9" +rev = "fc2dd481b2713cd0eda6ffa540faeaf7418fd051" [dependencies] arrayvec = "0.5" diff --git a/wgpu/examples/boids/main.rs b/wgpu/examples/boids/main.rs index 609c358f14..c70b7f3c93 100644 --- a/wgpu/examples/boids/main.rs +++ b/wgpu/examples/boids/main.rs @@ -48,35 +48,60 @@ impl framework::Example for Example { let fs_module = device.create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(&fs[..])).unwrap()); + // buffer for simulation parameters uniform + + let sim_param_data = [ + 0.04f32, // deltaT + 0.1, // rule1Distance + 0.025, // rule2Distance + 0.025, // rule3Distance + 0.02, // rule1Scale + 0.05, // rule2Scale + 0.005, // rule3Scale + ] + .to_vec(); + let sim_param_buffer = device.create_buffer_with_data( + bytemuck::cast_slice(&sim_param_data), + wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + ); + // create compute bind layout group and compute pipeline layout let compute_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { bindings: &[ - wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStage::COMPUTE, - ty: wgpu::BindingType::UniformBuffer { dynamic: false }, - ..Default::default() - }, - wgpu::BindGroupLayoutEntry { - binding: 1, - visibility: wgpu::ShaderStage::COMPUTE, - ty: wgpu::BindingType::StorageBuffer { + wgpu::BindGroupLayoutEntry::new( + 0, + wgpu::ShaderStage::COMPUTE, + wgpu::BindingType::UniformBuffer { dynamic: false, + min_binding_size: wgpu::NonZeroBufferAddress::new( + sim_param_data.len() as _ + ), + }, + ), + wgpu::BindGroupLayoutEntry::new( + 1, + wgpu::ShaderStage::COMPUTE, + wgpu::BindingType::StorageBuffer { + dynamic: false, + min_binding_size: wgpu::NonZeroBufferAddress::new( + (NUM_PARTICLES * 16) as _, + ), readonly: false, }, - ..Default::default() - }, - wgpu::BindGroupLayoutEntry { - binding: 2, - visibility: wgpu::ShaderStage::COMPUTE, - ty: wgpu::BindingType::StorageBuffer { + ), + wgpu::BindGroupLayoutEntry::new( + 2, + wgpu::ShaderStage::COMPUTE, + wgpu::BindingType::StorageBuffer { dynamic: false, + min_binding_size: wgpu::NonZeroBufferAddress::new( + (NUM_PARTICLES * 16) as _, + ), readonly: false, }, - ..Default::default() - }, + ), ], label: None, }); @@ -155,23 +180,6 @@ impl framework::Example for Example { wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST, ); - // buffer for simulation parameters uniform - - let sim_param_data = [ - 0.04f32, // deltaT - 0.1, // rule1Distance - 0.025, // rule2Distance - 0.025, // rule3Distance - 0.02, // rule1Scale - 0.05, // rule2Scale - 0.005, // rule3Scale - ] - .to_vec(); - let sim_param_buffer = device.create_buffer_with_data( - bytemuck::cast_slice(&sim_param_data), - wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, - ); - // buffer for all particles data of type [(posx,posy,velx,vely),...] let mut initial_particle_data = vec![0.0f32; (4 * NUM_PARTICLES) as usize]; diff --git a/wgpu/examples/cube/main.rs b/wgpu/examples/cube/main.rs index b66bb0f0a5..65a1c81d21 100644 --- a/wgpu/examples/cube/main.rs +++ b/wgpu/examples/cube/main.rs @@ -135,28 +135,28 @@ impl framework::Example for Example { let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { label: None, bindings: &[ - wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStage::VERTEX, - ty: wgpu::BindingType::UniformBuffer { dynamic: false }, - ..Default::default() - }, - wgpu::BindGroupLayoutEntry { - binding: 1, - visibility: wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::SampledTexture { + wgpu::BindGroupLayoutEntry::new( + 0, + wgpu::ShaderStage::VERTEX, + wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: wgpu::NonZeroBufferAddress::new(64), + }, + ), + wgpu::BindGroupLayoutEntry::new( + 1, + wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::SampledTexture { multisampled: false, component_type: wgpu::TextureComponentType::Float, dimension: wgpu::TextureViewDimension::D2, }, - ..Default::default() - }, - wgpu::BindGroupLayoutEntry { - binding: 2, - visibility: wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::Sampler { comparison: false }, - ..Default::default() - }, + ), + wgpu::BindGroupLayoutEntry::new( + 2, + wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::Sampler { comparison: false }, + ), ], }); let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { @@ -198,7 +198,6 @@ impl framework::Example for Example { // Create other resources let sampler = device.create_sampler(&wgpu::SamplerDescriptor { - label: None, address_mode_u: wgpu::AddressMode::ClampToEdge, address_mode_v: wgpu::AddressMode::ClampToEdge, address_mode_w: wgpu::AddressMode::ClampToEdge, diff --git a/wgpu/examples/hello-compute/main.rs b/wgpu/examples/hello-compute/main.rs index 0ddf645831..e6ab9c7f64 100644 --- a/wgpu/examples/hello-compute/main.rs +++ b/wgpu/examples/hello-compute/main.rs @@ -65,15 +65,15 @@ async fn execute_gpu(numbers: Vec) -> Vec { let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { label: None, - bindings: &[wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStage::COMPUTE, - ty: wgpu::BindingType::StorageBuffer { + bindings: &[wgpu::BindGroupLayoutEntry::new( + 0, + wgpu::ShaderStage::COMPUTE, + wgpu::BindingType::StorageBuffer { dynamic: false, readonly: false, + min_binding_size: wgpu::NonZeroBufferAddress::new(4), }, - ..Default::default() - }], + )], }); let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { @@ -154,12 +154,6 @@ fn main() { mod tests { use super::*; - #[test] - fn test_compute_0() { - let input = vec![]; - futures::executor::block_on(assert_execute_gpu(input, vec![])); - } - #[test] fn test_compute_1() { let input = vec![1, 2, 3, 4]; diff --git a/wgpu/examples/mipmap/main.rs b/wgpu/examples/mipmap/main.rs index 071be587f3..59479bcb26 100644 --- a/wgpu/examples/mipmap/main.rs +++ b/wgpu/examples/mipmap/main.rs @@ -84,22 +84,20 @@ impl Example { ) { let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { bindings: &[ - wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::SampledTexture { + wgpu::BindGroupLayoutEntry::new( + 0, + wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::SampledTexture { multisampled: false, component_type: wgpu::TextureComponentType::Float, dimension: wgpu::TextureViewDimension::D2, }, - ..Default::default() - }, - wgpu::BindGroupLayoutEntry { - binding: 1, - visibility: wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::Sampler { comparison: false }, - ..Default::default() - }, + ), + wgpu::BindGroupLayoutEntry::new( + 1, + wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::Sampler { comparison: false }, + ), ], label: None, }); @@ -229,28 +227,28 @@ impl framework::Example for Example { // Create pipeline layout let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { bindings: &[ - wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStage::VERTEX, - ty: wgpu::BindingType::UniformBuffer { dynamic: false }, - ..Default::default() - }, - wgpu::BindGroupLayoutEntry { - binding: 1, - visibility: wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::SampledTexture { + wgpu::BindGroupLayoutEntry::new( + 0, + wgpu::ShaderStage::VERTEX, + wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: wgpu::NonZeroBufferAddress::new(64), + }, + ), + wgpu::BindGroupLayoutEntry::new( + 1, + wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::SampledTexture { component_type: wgpu::TextureComponentType::Float, multisampled: false, dimension: wgpu::TextureViewDimension::D2, }, - ..Default::default() - }, - wgpu::BindGroupLayoutEntry { - binding: 2, - visibility: wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::Sampler { comparison: false }, - ..Default::default() - }, + ), + wgpu::BindGroupLayoutEntry::new( + 2, + wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::Sampler { comparison: false }, + ), ], label: None, }); diff --git a/wgpu/examples/shadow/main.rs b/wgpu/examples/shadow/main.rs index f4ae65f20c..d9d0e76c8e 100644 --- a/wgpu/examples/shadow/main.rs +++ b/wgpu/examples/shadow/main.rs @@ -244,12 +244,18 @@ impl framework::Example for Example { let local_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - bindings: &[wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::UniformBuffer { dynamic: false }, - ..Default::default() - }], + bindings: &[wgpu::BindGroupLayoutEntry::new( + 0, + wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: wgpu::NonZeroBufferAddress::new(mem::size_of::< + EntityUniforms, + >( + ) + as _), + }, + )], label: None, }); @@ -424,22 +430,24 @@ impl framework::Example for Example { }; let shadow_pass = { + let uniform_size = mem::size_of::() as wgpu::BufferAddress; // Create pipeline layout let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - bindings: &[wgpu::BindGroupLayoutEntry { - binding: 0, // global - visibility: wgpu::ShaderStage::VERTEX, - ty: wgpu::BindingType::UniformBuffer { dynamic: false }, - ..Default::default() - }], + bindings: &[wgpu::BindGroupLayoutEntry::new( + 0, // global + wgpu::ShaderStage::VERTEX, + wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: wgpu::NonZeroBufferAddress::new(uniform_size), + }, + )], label: None, }); let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { bind_group_layouts: &[&bind_group_layout, &local_bind_group_layout], }); - let uniform_size = mem::size_of::() as wgpu::BufferAddress; let uniform_buf = device.create_buffer(&wgpu::BufferDescriptor { label: None, size: uniform_size, @@ -516,34 +524,42 @@ impl framework::Example for Example { let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { bindings: &[ - wgpu::BindGroupLayoutEntry { - binding: 0, // global - visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::UniformBuffer { dynamic: false }, - ..Default::default() - }, - wgpu::BindGroupLayoutEntry { - binding: 1, // lights - visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::UniformBuffer { dynamic: false }, - ..Default::default() - }, - wgpu::BindGroupLayoutEntry { - binding: 2, - visibility: wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::SampledTexture { + wgpu::BindGroupLayoutEntry::new( + 0, // global + wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: wgpu::NonZeroBufferAddress::new(mem::size_of::< + ForwardUniforms, + >( + ) + as _), + }, + ), + wgpu::BindGroupLayoutEntry::new( + 1, // lights + wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: wgpu::NonZeroBufferAddress::new( + light_uniform_size, + ), + }, + ), + wgpu::BindGroupLayoutEntry::new( + 2, + wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::SampledTexture { multisampled: false, component_type: wgpu::TextureComponentType::Float, dimension: wgpu::TextureViewDimension::D2Array, }, - ..Default::default() - }, - wgpu::BindGroupLayoutEntry { - binding: 3, - visibility: wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::Sampler { comparison: true }, - ..Default::default() - }, + ), + wgpu::BindGroupLayoutEntry::new( + 3, + wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::Sampler { comparison: true }, + ), ], label: None, }); diff --git a/wgpu/examples/skybox/main.rs b/wgpu/examples/skybox/main.rs index acbf7250bd..6cc6bb23f6 100644 --- a/wgpu/examples/skybox/main.rs +++ b/wgpu/examples/skybox/main.rs @@ -42,28 +42,28 @@ impl framework::Example for Skybox { ) -> (Self, Option) { let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { bindings: &[ - wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::UniformBuffer { dynamic: false }, - ..Default::default() - }, - wgpu::BindGroupLayoutEntry { - binding: 1, - visibility: wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::SampledTexture { + wgpu::BindGroupLayoutEntry::new( + 0, + wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: None, + }, + ), + wgpu::BindGroupLayoutEntry::new( + 1, + wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::SampledTexture { component_type: wgpu::TextureComponentType::Float, multisampled: false, dimension: wgpu::TextureViewDimension::Cube, }, - ..Default::default() - }, - wgpu::BindGroupLayoutEntry { - binding: 2, - visibility: wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::Sampler { comparison: false }, - ..Default::default() - }, + ), + wgpu::BindGroupLayoutEntry::new( + 2, + wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::Sampler { comparison: false }, + ), ], label: None, }); diff --git a/wgpu/examples/texture-arrays/main.rs b/wgpu/examples/texture-arrays/main.rs index fc24ff23d0..e731eaaa88 100644 --- a/wgpu/examples/texture-arrays/main.rs +++ b/wgpu/examples/texture-arrays/main.rs @@ -144,12 +144,14 @@ impl framework::Example for Example { let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - bindings: &[wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::UniformBuffer { dynamic: false }, - ..wgpu::BindGroupLayoutEntry::default() - }], + bindings: &[wgpu::BindGroupLayoutEntry::new( + 0, + wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: None, + }, + )], label: Some("uniform workaround bind group layout"), }); @@ -248,26 +250,26 @@ impl framework::Example for Example { let sampler = device.create_sampler(&wgpu::SamplerDescriptor::default()); let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("bind group layout"), bindings: &[ wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::SampledTexture { - component_type: wgpu::TextureComponentType::Float, - dimension: wgpu::TextureViewDimension::D2, - multisampled: false, - }, count: Some(2), - ..Default::default() - }, - wgpu::BindGroupLayoutEntry { - binding: 1, - visibility: wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::Sampler { comparison: false }, - ..Default::default() + ..wgpu::BindGroupLayoutEntry::new( + 0, + wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::SampledTexture { + component_type: wgpu::TextureComponentType::Float, + dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + ) }, + wgpu::BindGroupLayoutEntry::new( + 1, + wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::Sampler { comparison: false }, + ), ], - label: Some("bind group layout"), }); let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { diff --git a/wgpu/examples/water/main.rs b/wgpu/examples/water/main.rs index 94244a45fc..0bc7e0507e 100644 --- a/wgpu/examples/water/main.rs +++ b/wgpu/examples/water/main.rs @@ -4,7 +4,7 @@ mod framework; mod point_gen; use cgmath::Point3; - +use std::{io, mem}; use wgpu::vertex_attr_array; /// @@ -21,7 +21,11 @@ const SIZE: f32 = 10.0; /// Location of the camera. /// Location of light is in terrain/water shaders. /// -const CAMERA: Point3 = Point3 { x: -100.0, y: 50.0, z: 100.0 }; +const CAMERA: Point3 = Point3 { + x: -100.0, + y: 50.0, + z: 100.0, +}; struct Matrices { view: cgmath::Matrix4, @@ -45,7 +49,7 @@ struct WaterUniforms { view: [f32; 16], projection: [f32; 16], time_size_width: [f32; 4], - height: f32, + height: [f32; 4], } struct Uniforms { @@ -103,7 +107,7 @@ impl Example { let reg_view = cgmath::Matrix4::look_at( CAMERA, cgmath::Point3::new(0f32, 0.0, 0.0), - cgmath::Vector3::unit_y(), //Note that y is up. Differs from other examples. + cgmath::Vector3::unit_y(), //Note that y is up. Differs from other examples. ); let scale = cgmath::Matrix4::from_nonuniform_scale(8.0, 1.5, 8.0); @@ -116,7 +120,6 @@ impl Example { cgmath::Vector3::unit_y(), ); - let correction = framework::OPENGL_TO_WGPU_MATRIX; let flipped_view = flipped_view * scale; @@ -132,7 +135,7 @@ impl Example { let Matrices { view, flipped_view, - projection + projection, } = Self::generate_matrices(width as f32 / height as f32); Uniforms { @@ -148,8 +151,8 @@ impl Example { view: *view.as_ref(), projection: *projection.as_ref(), time_size_width: [0.0, 1.0, SIZE * 2.0, width as f32], - height: height as f32 - } + height: [height as f32, 0.0, 0.0, 0.0], + }, } } @@ -174,8 +177,16 @@ impl Example { } = Self::generate_uniforms(sc_desc.width, sc_desc.height); // Put the uniforms into buffers on the GPU - queue.write_buffer(terrain_normal_uniforms, 0, bytemuck::cast_slice(&[terrain_normal])); - queue.write_buffer(terrain_flipped_uniforms, 0, bytemuck::cast_slice(&[terrain_flipped])); + queue.write_buffer( + terrain_normal_uniforms, + 0, + bytemuck::cast_slice(&[terrain_normal]), + ); + queue.write_buffer( + terrain_flipped_uniforms, + 0, + bytemuck::cast_slice(&[terrain_flipped]), + ); queue.write_buffer(water_uniforms, 0, bytemuck::cast_slice(&[water])); let texture_extent = wgpu::Extent3d { @@ -191,7 +202,9 @@ impl Example { sample_count: 1, dimension: wgpu::TextureDimension::D2, format: sc_desc.format, - usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST | wgpu::TextureUsage::OUTPUT_ATTACHMENT, + usage: wgpu::TextureUsage::SAMPLED + | wgpu::TextureUsage::COPY_DST + | wgpu::TextureUsage::OUTPUT_ATTACHMENT, }); let draw_depth_buffer = device.create_texture(&wgpu::TextureDescriptor { @@ -201,7 +214,9 @@ impl Example { sample_count: 1, dimension: wgpu::TextureDimension::D2, format: wgpu::TextureFormat::Depth32Float, - usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST | wgpu::TextureUsage::OUTPUT_ATTACHMENT, + usage: wgpu::TextureUsage::SAMPLED + | wgpu::TextureUsage::COPY_DST + | wgpu::TextureUsage::OUTPUT_ATTACHMENT, }); let sampler = device.create_sampler(&wgpu::SamplerDescriptor { @@ -224,11 +239,15 @@ impl Example { }, wgpu::Binding { binding: 1, - resource: wgpu::BindingResource::TextureView(&reflection_texture.create_default_view()), + resource: wgpu::BindingResource::TextureView( + &reflection_texture.create_default_view(), + ), }, wgpu::Binding { binding: 2, - resource: wgpu::BindingResource::TextureView(&draw_depth_buffer.create_default_view()) + resource: wgpu::BindingResource::TextureView( + &draw_depth_buffer.create_default_view(), + ), }, wgpu::Binding { binding: 3, @@ -238,7 +257,11 @@ impl Example { label: Some("Water Bind Group"), }); - (reflection_texture.create_default_view(), draw_depth_buffer.create_default_view(), water_bind_group) + ( + reflection_texture.create_default_view(), + draw_depth_buffer.create_default_view(), + water_bind_group, + ) } } @@ -248,8 +271,6 @@ impl framework::Example for Example { device: &wgpu::Device, queue: &wgpu::Queue, ) -> (Self, Option) { - use std::mem; - // Size of one water vertex let water_vertex_size = mem::size_of::(); @@ -265,48 +286,53 @@ impl framework::Example for Example { let mut terrain_random = rand::thread_rng(); // Generate terrain. The closure determines what each hexagon will look like. - let terrain = point_gen::HexTerrainMesh::generate(SIZE, |point| -> point_gen::TerrainVertex { - use rand::Rng; - use noise::NoiseFn; - let noise = terrain_noise.get([point[0] as f64 / 5.0, point[1] as f64 / 5.0]) + 0.1; + let terrain = + point_gen::HexTerrainMesh::generate(SIZE, |point| -> point_gen::TerrainVertex { + use noise::NoiseFn; + use rand::Rng; + let noise = terrain_noise.get([point[0] as f64 / 5.0, point[1] as f64 / 5.0]) + 0.1; - let y = noise as f32 * 8.0; + let y = noise as f32 * 8.0; - // Multiplies a colour by some random amount. - fn mul_arr(mut arr: [u8; 4], by: f32) -> [u8; 4] { - arr[0] = (arr[0] as f32 * by).min(255.0) as u8; - arr[1] = (arr[1] as f32 * by).min(255.0) as u8; - arr[2] = (arr[2] as f32 * by).min(255.0) as u8; - arr - } + // Multiplies a colour by some random amount. + fn mul_arr(mut arr: [u8; 4], by: f32) -> [u8; 4] { + arr[0] = (arr[0] as f32 * by).min(255.0) as u8; + arr[1] = (arr[1] as f32 * by).min(255.0) as u8; + arr[2] = (arr[2] as f32 * by).min(255.0) as u8; + arr + } - // Under water - const DARK_SAND: [u8; 4] = [235, 175, 71, 255]; - // Coast - const SAND: [u8; 4] = [217, 191, 76, 255]; - // Normal - const GRASS: [u8; 4] = [122, 170, 19, 255]; - // Mountain - const SNOW: [u8; 4] = [175, 224, 237, 255]; + // Under water + const DARK_SAND: [u8; 4] = [235, 175, 71, 255]; + // Coast + const SAND: [u8; 4] = [217, 191, 76, 255]; + // Normal + const GRASS: [u8; 4] = [122, 170, 19, 255]; + // Mountain + const SNOW: [u8; 4] = [175, 224, 237, 255]; - // Random colouration. - let random = terrain_random.gen::() * 0.2 + 0.9; + // Random colouration. + let random = terrain_random.gen::() * 0.2 + 0.9; - // Choose colour. - let colour = if y <= 0.0 { - DARK_SAND - } else if y <= 0.8 { - SAND - } else if y <= 3.0 { - GRASS - } else { - SNOW - }; - point_gen::TerrainVertex { - position: Point3 { x: point[0], y, z: point[1] }, - colour: mul_arr(colour, random), - } - }); + // Choose colour. + let colour = if y <= 0.0 { + DARK_SAND + } else if y <= 0.8 { + SAND + } else if y <= 3.0 { + GRASS + } else { + SNOW + }; + point_gen::TerrainVertex { + position: Point3 { + x: point[0], + y, + z: point[1], + }, + colour: mul_arr(colour, random), + } + }); // Generate the buffer data. let terrain_vertices = terrain.make_buffer_data(); @@ -323,92 +349,100 @@ impl framework::Example for Example { ); // Create the bind group layout. This is what our uniforms will look like. - let water_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - label: Some("Water Bind Group Layout"), - bindings: &[ - // Uniform variables such as projection/view. - wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::UniformBuffer { dynamic: false }, - count: None, - ..Default::default() - }, - // Reflection texture. - wgpu::BindGroupLayoutEntry { - binding: 1, - visibility: wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::SampledTexture { - multisampled: false, - component_type: wgpu::TextureComponentType::Float, - dimension: wgpu::TextureViewDimension::D2, - }, - count: None, - ..Default::default() - }, - // Depth texture for terrain. - wgpu::BindGroupLayoutEntry { - binding: 2, - visibility: wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::SampledTexture { - multisampled: false, - component_type: wgpu::TextureComponentType::Float, - dimension: wgpu::TextureViewDimension::D2, - }, - count: None, - ..Default::default() - }, - // Sampler to be able to sample the textures. - wgpu::BindGroupLayoutEntry { - binding: 3, - visibility: wgpu::ShaderStage::FRAGMENT, - ty: wgpu::BindingType::Sampler { comparison: false }, - count: None, - ..Default::default() - }, - ], - }); + let water_bind_group_layout = + device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("Water Bind Group Layout"), + bindings: &[ + // Uniform variables such as projection/view. + wgpu::BindGroupLayoutEntry::new( + 0, + wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: wgpu::NonZeroBufferAddress::new(mem::size_of::< + WaterUniforms, + >( + ) + as _), + }, + ), + // Reflection texture. + wgpu::BindGroupLayoutEntry::new( + 1, + wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::SampledTexture { + multisampled: false, + component_type: wgpu::TextureComponentType::Float, + dimension: wgpu::TextureViewDimension::D2, + }, + ), + // Depth texture for terrain. + wgpu::BindGroupLayoutEntry::new( + 2, + wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::SampledTexture { + multisampled: false, + component_type: wgpu::TextureComponentType::Float, + dimension: wgpu::TextureViewDimension::D2, + }, + ), + // Sampler to be able to sample the textures. + wgpu::BindGroupLayoutEntry::new( + 3, + wgpu::ShaderStage::FRAGMENT, + wgpu::BindingType::Sampler { comparison: false }, + ), + ], + }); - let terrain_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - label: Some("Terrain Bind Group Layout"), - bindings: &[ - // Regular uniform variables like view/projection. - wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStage::VERTEX, - ty: wgpu::BindingType::UniformBuffer { dynamic: false }, - count: None, - ..Default::default() - }, - ], - }); + let terrain_bind_group_layout = + device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("Terrain Bind Group Layout"), + bindings: &[ + // Regular uniform variables like view/projection. + wgpu::BindGroupLayoutEntry::new( + 0, + wgpu::ShaderStage::VERTEX, + wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: wgpu::NonZeroBufferAddress::new(mem::size_of::< + TerrainUniforms, + >( + ) + as _), + }, + ), + ], + }); // Create our pipeline layouts. - let water_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - bind_group_layouts: &[&water_bind_group_layout], - }); + let water_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + bind_group_layouts: &[&water_bind_group_layout], + }); - let terrain_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - bind_group_layouts: &[&terrain_bind_group_layout], - }); + let terrain_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + bind_group_layouts: &[&terrain_bind_group_layout], + }); let water_uniform_buf = device.create_buffer(&wgpu::BufferDescriptor { label: Some("Water Uniforms"), - size: std::mem::size_of::() as _, + size: mem::size_of::() as _, usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, mapped_at_creation: false, }); let terrain_normal_uniform_buf = device.create_buffer(&wgpu::BufferDescriptor { label: Some("Normal Terrain Uniforms"), - size: std::mem::size_of::() as _, + size: mem::size_of::() as _, usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, mapped_at_creation: false, }); let terrain_flipped_uniform_buf = device.create_buffer(&wgpu::BufferDescriptor { label: Some("Flipped Terrain Uniforms"), - size: std::mem::size_of::() as _, + size: mem::size_of::() as _, usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, mapped_at_creation: false, }); @@ -423,27 +457,23 @@ impl framework::Example for Example { &water_uniform_buf, &terrain_normal_uniform_buf, &terrain_flipped_uniform_buf, - &water_bind_group_layout + &water_bind_group_layout, ); let terrain_normal_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { layout: &terrain_bind_group_layout, - bindings: &[ - wgpu::Binding { - binding: 0, - resource: wgpu::BindingResource::Buffer(terrain_normal_uniform_buf.slice(..)), - }, - ], + bindings: &[wgpu::Binding { + binding: 0, + resource: wgpu::BindingResource::Buffer(terrain_normal_uniform_buf.slice(..)), + }], label: Some("Terrain Normal Bind Group"), }); let terrain_flipped_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { layout: &terrain_bind_group_layout, - bindings: &[ - wgpu::Binding { - binding: 0, - resource: wgpu::BindingResource::Buffer(terrain_flipped_uniform_buf.slice(..)) - } - ], + bindings: &[wgpu::Binding { + binding: 0, + resource: wgpu::BindingResource::Buffer(terrain_flipped_uniform_buf.slice(..)), + }], label: Some("Terrain Flipped Bind Group"), }); @@ -452,16 +482,18 @@ impl framework::Example for Example { let water_fs_bytes = include_bytes!("water_shader.frag.spv"); // Upload/compile them to GPU code. let water_vs_module = device - .create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(&water_vs_bytes[..])).unwrap()); + .create_shader_module(&wgpu::read_spirv(io::Cursor::new(&water_vs_bytes[..])).unwrap()); let water_fs_module = device - .create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(&water_fs_bytes[..])).unwrap()); + .create_shader_module(&wgpu::read_spirv(io::Cursor::new(&water_fs_bytes[..])).unwrap()); let terrain_vs_bytes = include_bytes!("terrain_shader.vert.spv"); let terrain_fs_bytes = include_bytes!("terrain_shader.frag.spv"); - let terrain_vs_module = device - .create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(&terrain_vs_bytes[..])).unwrap()); - let terrain_fs_module = device - .create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(&terrain_fs_bytes[..])).unwrap()); + let terrain_vs_module = device.create_shader_module( + &wgpu::read_spirv(io::Cursor::new(&terrain_vs_bytes[..])).unwrap(), + ); + let terrain_fs_module = device.create_shader_module( + &wgpu::read_spirv(io::Cursor::new(&terrain_fs_bytes[..])).unwrap(), + ); // Create the render pipelines. These describe how the data will flow through the GPU, and what // constraints and modifiers it will have. @@ -531,13 +563,11 @@ impl framework::Example for Example { // because we duplicate all the data anyway. This is // necessary to achieve the low-poly effect. index_format: wgpu::IndexFormat::Uint16, - vertex_buffers: &[ - wgpu::VertexBufferDescriptor { - stride: water_vertex_size as wgpu::BufferAddress, - step_mode: wgpu::InputStepMode::Vertex, - attributes: &vertex_attr_array![0 => Short2, 1 => Char4], - }, - ], + vertex_buffers: &[wgpu::VertexBufferDescriptor { + stride: water_vertex_size as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Vertex, + attributes: &vertex_attr_array![0 => Short2, 1 => Char4], + }], }, sample_count: 1, sample_mask: !0, @@ -580,13 +610,11 @@ impl framework::Example for Example { }), vertex_state: wgpu::VertexStateDescriptor { index_format: wgpu::IndexFormat::Uint16, - vertex_buffers: &[ - wgpu::VertexBufferDescriptor { - stride: terrain_vertex_size as wgpu::BufferAddress, - step_mode: wgpu::InputStepMode::Vertex, - attributes: &vertex_attr_array![0 => Float3, 1 => Float3, 2 => Uchar4Norm], - }, - ], + vertex_buffers: &[wgpu::VertexBufferDescriptor { + stride: terrain_vertex_size as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Vertex, + attributes: &vertex_attr_array![0 => Float3, 1 => Float3, 2 => Uchar4Norm], + }], }, sample_count: 1, sample_mask: !0, @@ -652,7 +680,7 @@ impl framework::Example for Example { &self.water_uniform_buf, &self.terrain_normal_uniform_buf, &self.terrain_flipped_uniform_buf, - &self.water_bind_group_layout + &self.water_bind_group_layout, ); self.water_bind_group = water_bind_group; @@ -671,12 +699,17 @@ impl framework::Example for Example { // Write the sin/cos values to the uniform buffer for the water. let (water_sin, water_cos) = ((self.current_frame as f32) / 600.0).sin_cos(); - queue.write_buffer(&self.water_uniform_buf, std::mem::size_of::<[f32; 16]>() as wgpu::BufferAddress * 2, bytemuck::cast_slice(&[water_sin, water_cos])); + queue.write_buffer( + &self.water_uniform_buf, + mem::size_of::<[f32; 16]>() as wgpu::BufferAddress * 2, + bytemuck::cast_slice(&[water_sin, water_cos]), + ); // The encoder provides a way to turn our instructions here, into // a command buffer the GPU can understand. - let mut encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some("Main Command Encoder") }); + let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { + label: Some("Main Command Encoder"), + }); // Only render valid frames. See resize method. if let Some(active) = self.active { @@ -690,20 +723,18 @@ impl framework::Example for Example { // First pass: render the reflection. { let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - color_attachments: &[ - wgpu::RenderPassColorAttachmentDescriptor { - attachment: &self.reflect_view, - resolve_target: None, - load_op: wgpu::LoadOp::Clear, - store_op: wgpu::StoreOp::Store, - clear_color: wgpu::Color { - r: 161.0 / 255.0, - g: 246.0 / 255.0, - b: 255.0 / 255.0, - a: 1.0, - }, + color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor { + attachment: &self.reflect_view, + resolve_target: None, + load_op: wgpu::LoadOp::Clear, + store_op: wgpu::StoreOp::Store, + clear_color: wgpu::Color { + r: 161.0 / 255.0, + g: 246.0 / 255.0, + b: 255.0 / 255.0, + a: 1.0, }, - ], + }], // We still need to use the depth buffer here // since the pipeline requires it. depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor { @@ -727,20 +758,18 @@ impl framework::Example for Example { // depth values, so we must use StoreOp::Store. { let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - color_attachments: &[ - wgpu::RenderPassColorAttachmentDescriptor { - attachment: &frame.view, - resolve_target: None, - load_op: wgpu::LoadOp::Clear, - store_op: wgpu::StoreOp::Store, - clear_color: wgpu::Color { - r: 161.0 / 255.0, - g: 246.0 / 255.0, - b: 255.0 / 255.0, - a: 1.0, - }, + color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor { + attachment: &frame.view, + resolve_target: None, + load_op: wgpu::LoadOp::Clear, + store_op: wgpu::StoreOp::Store, + clear_color: wgpu::Color { + r: 161.0 / 255.0, + g: 246.0 / 255.0, + b: 255.0 / 255.0, + a: 1.0, }, - ], + }], depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor { attachment: &self.depth_buffer, depth_load_op: wgpu::LoadOp::Clear, @@ -762,20 +791,18 @@ impl framework::Example for Example { // to it, so it cannot be in the same render pass. { let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - color_attachments: &[ - wgpu::RenderPassColorAttachmentDescriptor { - attachment: &frame.view, - resolve_target: None, - load_op: wgpu::LoadOp::Load, - store_op: wgpu::StoreOp::Store, - clear_color: wgpu::Color { - r: 161.0 / 255.0, - g: 246.0 / 255.0, - b: 255.0 / 255.0, - a: 1.0, - }, + color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor { + attachment: &frame.view, + resolve_target: None, + load_op: wgpu::LoadOp::Load, + store_op: wgpu::StoreOp::Store, + clear_color: wgpu::Color { + r: 161.0 / 255.0, + g: 246.0 / 255.0, + b: 255.0 / 255.0, + a: 1.0, }, - ], + }], depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor { attachment: &self.depth_buffer, depth_load_op: wgpu::LoadOp::Load, @@ -795,7 +822,6 @@ impl framework::Example for Example { rpass.draw(0..self.water_vertex_count as u32, 0..1); } - encoder.finish() } } diff --git a/wgpu/examples/water/point_gen.rs b/wgpu/examples/water/point_gen.rs index b94b9a50ca..7b380175e0 100644 --- a/wgpu/examples/water/point_gen.rs +++ b/wgpu/examples/water/point_gen.rs @@ -2,8 +2,8 @@ //! This module covers generating points in a hexagonal fashion. //! +use cgmath::{InnerSpace, Point3, Vector3}; use std::collections::HashMap; -use cgmath::{Vector3, Point3, InnerSpace}; // The following constants are used in calculations. // A and B are multiplication factors for x and y. @@ -83,9 +83,16 @@ fn surrounding_hexagonal_points(x: isize, y: isize) -> [(isize, isize); 6] { ] } -fn surrounding_point_values_iter(hashmap: &HashMap<(isize, isize), T>, x: isize, y: isize, for_each: impl FnMut((&T, &T))) { +fn surrounding_point_values_iter( + hashmap: &HashMap<(isize, isize), T>, + x: isize, + y: isize, + for_each: impl FnMut((&T, &T)), +) { let points = surrounding_hexagonal_points(x, y); - let points = [points[0], points[1], points[2], points[3], points[4], points[5], points[0]]; + let points = [ + points[0], points[1], points[2], points[3], points[4], points[5], points[0], + ]; points .windows(2) .map(|x| (hashmap.get(&x[0]), hashmap.get(&x[1]))) @@ -160,9 +167,16 @@ impl HexTerrainMesh { } } fn half(p1: &TerrainVertex, p2: &TerrainVertex) -> Point3 { - Point3 { x: (p1.position.x + p2.position.x) / 2.0, y: (p1.position.y + p2.position.y) / 2.0, z: (p1.position.z + p2.position.z) / 2.0 } + Point3 { + x: (p1.position.x + p2.position.x) / 2.0, + y: (p1.position.y + p2.position.y) / 2.0, + z: (p1.position.z + p2.position.z) / 2.0, + } } - let mut push_triangle = |p1: &TerrainVertex, p2: &TerrainVertex, p: &TerrainVertex, c: [u8; 4]| { + let mut push_triangle = |p1: &TerrainVertex, + p2: &TerrainVertex, + p: &TerrainVertex, + c: [u8; 4]| { let m = middle(p1, p2, p); let ap = half(p1, p); let bp = half(p2, p); @@ -170,28 +184,27 @@ impl HexTerrainMesh { let n1 = calculate_normal(ap, m, p); let n2 = calculate_normal(m, bp, p); - vertices - .extend( - [ap, m, p, m, bp, p] - .iter() - .zip(std::iter::repeat::<[f32; 3]>(n1.into()).chain(std::iter::repeat::<[f32; 3]>(n2.into()))) - .zip(std::iter::repeat(c)) - .map(|((pos, normal), colour)| TerrainVertexAttributes { - position: *pos.as_ref(), - normal, - colour, - }) - ); + vertices.extend( + [ap, m, p, m, bp, p] + .iter() + .zip( + std::iter::repeat::<[f32; 3]>(n1.into()) + .chain(std::iter::repeat::<[f32; 3]>(n2.into())), + ) + .zip(std::iter::repeat(c)) + .map(|((pos, normal), colour)| TerrainVertexAttributes { + position: *pos.as_ref(), + normal, + colour, + }), + ); }; for i in -self.half_size..=self.half_size { for j in -self.half_size..=self.half_size { if let Some(p) = self.vertices.get(&(i, j)) { - surrounding_point_values_iter( - &self.vertices, - i, - j, - |(a, b)| push_triangle(a, b, p, p.colour) - ); + surrounding_point_values_iter(&self.vertices, i, j, |(a, b)| { + push_triangle(a, b, p, p.colour) + }); } } } @@ -246,7 +259,7 @@ impl HexWaterMesh { (b[0] - a[0]) as i8, (b[1] - a[1]) as i8, (c[0] - a[0]) as i8, - (c[1] - a[1]) as i8 + (c[1] - a[1]) as i8, ] } @@ -259,7 +272,7 @@ impl HexWaterMesh { [a, b, c] .iter() .zip([bc, ca, ab].iter()) - .map(|(&position, &offsets)| WaterVertexAttributes { position, offsets }) + .map(|(&position, &offsets)| WaterVertexAttributes { position, offsets }), ); }; @@ -267,12 +280,9 @@ impl HexWaterMesh { for j in -self.half_size..=self.half_size { if (i - j) % 3 == 0 { if let Some(&p) = self.vertices.get(&(i, j)) { - surrounding_point_values_iter( - &self.vertices, - i, - j, - |(a, b)| push_triangle(*a, *b, p) - ); + surrounding_point_values_iter(&self.vertices, i, j, |(a, b)| { + push_triangle(*a, *b, p) + }); } } } diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index 7e0f161e09..0369f8439b 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -806,14 +806,20 @@ impl crate::Context for Context { ); match bind.ty { - BindingType::UniformBuffer { dynamic } + BindingType::UniformBuffer { dynamic, .. } | BindingType::StorageBuffer { dynamic, .. } => { mapped_entry.has_dynamic_offset(dynamic); } _ => {} } - if let BindingType::SampledTexture { multisampled, .. } = bind.ty { + if let BindingType::SampledTexture { + component_type, + multisampled, + .. + } = bind.ty + { + mapped_entry.texture_component_type(map_texture_component_type(component_type)); mapped_entry.multisampled(multisampled); } @@ -829,15 +835,6 @@ impl crate::Context for Context { mapped_entry.storage_texture_format(map_texture_format(format)); } - match bind.ty { - BindingType::SampledTexture { component_type, .. } - | BindingType::StorageTexture { component_type, .. } => { - mapped_entry - .texture_component_type(map_texture_component_type(component_type)); - } - _ => {} - } - mapped_entry }) .collect::(); diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index b9cdf38ea9..f7226ee177 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -1,7 +1,7 @@ //! A cross-platform graphics and compute library based on WebGPU. mod backend; - +mod util; #[macro_use] mod macros; @@ -19,20 +19,21 @@ use parking_lot::Mutex; #[cfg(not(target_arch = "wasm32"))] pub use wgc::instance::{AdapterInfo, DeviceType}; pub use wgt::{ - read_spirv, AddressMode, Backend, BackendBit, BindGroupLayoutDescriptor, BindGroupLayoutEntry, - BindingType, BlendDescriptor, BlendFactor, BlendOperation, BufferAddress, BufferSize, - BufferUsage, Capabilities, Color, ColorStateDescriptor, ColorWrite, CommandBufferDescriptor, + AddressMode, Backend, BackendBit, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType, + BlendDescriptor, BlendFactor, BlendOperation, BufferAddress, BufferSize, BufferUsage, + Capabilities, Color, ColorStateDescriptor, ColorWrite, CommandBufferDescriptor, CompareFunction, CullMode, DepthStencilStateDescriptor, DeviceDescriptor, DynamicOffset, Extensions, Extent3d, FilterMode, FrontFace, IndexFormat, InputStepMode, Limits, LoadOp, - Origin3d, PowerPreference, PresentMode, PrimitiveTopology, RasterizationStateDescriptor, - RenderBundleEncoderDescriptor, ShaderLocation, ShaderStage, StencilOperation, - StencilStateFaceDescriptor, StoreOp, SwapChainDescriptor, SwapChainStatus, TextureAspect, - TextureComponentType, TextureDataLayout, TextureDimension, TextureFormat, TextureUsage, - TextureViewDimension, UnsafeExtensions, VertexAttributeDescriptor, VertexFormat, + NonZeroBufferAddress, Origin3d, PowerPreference, PresentMode, PrimitiveTopology, + RasterizationStateDescriptor, RenderBundleEncoderDescriptor, ShaderLocation, ShaderStage, + StencilOperation, StencilStateFaceDescriptor, StoreOp, SwapChainDescriptor, SwapChainStatus, + TextureAspect, TextureComponentType, TextureDataLayout, TextureDimension, TextureFormat, + TextureUsage, TextureViewDimension, UnsafeExtensions, VertexAttributeDescriptor, VertexFormat, BIND_BUFFER_ALIGNMENT, COPY_BYTES_PER_ROW_ALIGNMENT, }; use backend::Context as C; +pub use util::read_spirv; trait ComputePassInner { fn set_pipeline(&mut self, pipeline: &Ctx::ComputePipelineId); diff --git a/wgpu/src/util/mod.rs b/wgpu/src/util/mod.rs new file mode 100644 index 0000000000..6ab30d0319 --- /dev/null +++ b/wgpu/src/util/mod.rs @@ -0,0 +1,41 @@ +use std::{io, slice}; + +// TODO: This is copy/pasted from gfx-hal, so we need to find a new place to put +// this function +pub fn read_spirv(mut x: R) -> io::Result> { + let size = x.seek(io::SeekFrom::End(0))?; + if size % 4 != 0 { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "input length not divisible by 4", + )); + } + if size > usize::max_value() as u64 { + return Err(io::Error::new(io::ErrorKind::InvalidData, "input too long")); + } + let words = (size / 4) as usize; + let mut result = Vec::::with_capacity(words); + x.seek(io::SeekFrom::Start(0))?; + unsafe { + // Writing all bytes through a pointer with less strict alignment when our type has no + // invalid bitpatterns is safe. + x.read_exact(slice::from_raw_parts_mut( + result.as_mut_ptr() as *mut u8, + words * 4, + ))?; + result.set_len(words); + } + const MAGIC_NUMBER: u32 = 0x0723_0203; + if !result.is_empty() && result[0] == MAGIC_NUMBER.swap_bytes() { + for word in &mut result { + *word = word.swap_bytes(); + } + } + if result.is_empty() || result[0] != MAGIC_NUMBER { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "input missing SPIR-V magic number", + )); + } + Ok(result) +}