From edb342cffef96be39c49a7d9eb6f3a2fff72b701 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Fri, 29 Jan 2021 00:51:44 -0500 Subject: [PATCH] [rs] Update wgpu to the new render pipeline descriptor API --- wgpu/Cargo.toml | 6 +- wgpu/examples/boids/main.rs | 44 +++----- wgpu/examples/cube/main.rs | 106 ++++++++--------- wgpu/examples/hello-compute/main.rs | 6 +- wgpu/examples/hello-triangle/main.rs | 21 ++-- wgpu/examples/mipmap/main.rs | 62 ++++------ wgpu/examples/msaa-line/main.rs | 39 +++---- wgpu/examples/shadow/main.rs | 70 +++++------- wgpu/examples/skybox/main.rs | 23 ++-- wgpu/examples/texture-arrays/main.rs | 35 +++--- wgpu/examples/water/main.rs | 137 +++++++++++----------- wgpu/src/backend/direct.rs | 60 +++++----- wgpu/src/backend/web.rs | 163 ++++++++++++++------------- wgpu/src/lib.rs | 137 +++++++++++----------- wgpu/src/macros.rs | 10 +- 15 files changed, 411 insertions(+), 508 deletions(-) diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index a6d6d857d3..96e6e3163c 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -26,20 +26,20 @@ webgl = ["wgc"] [target.'cfg(not(target_arch = "wasm32"))'.dependencies.wgc] package = "wgpu-core" git = "https://github.com/gfx-rs/wgpu" -rev = "60cd0f7e56f22a7b9d37f36559073cc844adace1" +rev = "ac81f3e7562eff96ca854b462b0893c38ea98de2" features = ["raw-window-handle"] [target.'cfg(target_arch = "wasm32")'.dependencies.wgc] package = "wgpu-core" git = "https://github.com/gfx-rs/wgpu" -rev = "60cd0f7e56f22a7b9d37f36559073cc844adace1" +rev = "ac81f3e7562eff96ca854b462b0893c38ea98de2" features = ["raw-window-handle"] optional = true [dependencies.wgt] package = "wgpu-types" git = "https://github.com/gfx-rs/wgpu" -rev = "60cd0f7e56f22a7b9d37f36559073cc844adace1" +rev = "ac81f3e7562eff96ca854b462b0893c38ea98de2" [dependencies] arrayvec = "0.5" diff --git a/wgpu/examples/boids/main.rs b/wgpu/examples/boids/main.rs index 36a32bf816..08be4f4759 100644 --- a/wgpu/examples/boids/main.rs +++ b/wgpu/examples/boids/main.rs @@ -116,40 +116,30 @@ impl framework::Example for Example { let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: None, layout: Some(&render_pipeline_layout), - vertex_stage: wgpu::ProgrammableStageDescriptor { + vertex: wgpu::VertexState { module: &vs_module, entry_point: "main", - }, - fragment_stage: Some(wgpu::ProgrammableStageDescriptor { - module: &fs_module, - entry_point: "main", - }), - rasterization_state: Some(wgpu::RasterizationStateDescriptor { - front_face: wgpu::FrontFace::Ccw, - cull_mode: wgpu::CullMode::None, - ..Default::default() - }), - primitive_topology: wgpu::PrimitiveTopology::TriangleList, - color_states: &[sc_desc.format.into()], - depth_stencil_state: None, - vertex_state: wgpu::VertexStateDescriptor { - index_format: None, - vertex_buffers: &[ - wgpu::VertexBufferDescriptor { - stride: 4 * 4, + buffers: &[ + wgpu::VertexBufferLayout { + array_stride: 4 * 4, step_mode: wgpu::InputStepMode::Instance, attributes: &wgpu::vertex_attr_array![0 => Float2, 1 => Float2], }, - wgpu::VertexBufferDescriptor { - stride: 2 * 4, + wgpu::VertexBufferLayout { + array_stride: 2 * 4, step_mode: wgpu::InputStepMode::Vertex, attributes: &wgpu::vertex_attr_array![2 => Float2], }, ], }, - sample_count: 1, - sample_mask: !0, - alpha_to_coverage_enabled: false, + fragment: Some(wgpu::FragmentState { + module: &fs_module, + entry_point: "main", + targets: &[sc_desc.format.into()], + }), + primitive: wgpu::PrimitiveState::default(), + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), }); // create compute pipeline @@ -157,10 +147,8 @@ impl framework::Example for Example { let compute_pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor { label: Some("Compute pipeline"), layout: Some(&compute_pipeline_layout), - compute_stage: wgpu::ProgrammableStageDescriptor { - module: &boids_module, - entry_point: "main", - }, + module: &boids_module, + entry_point: "main", }); // buffer for the three 2d triangle vertices of each instance diff --git a/wgpu/examples/cube/main.rs b/wgpu/examples/cube/main.rs index 50d84622b3..6b31988b1f 100644 --- a/wgpu/examples/cube/main.rs +++ b/wgpu/examples/cube/main.rs @@ -90,7 +90,6 @@ fn create_texels(size: usize) -> Vec { struct Example { vertex_buf: wgpu::Buffer, index_buf: wgpu::Buffer, - index_format: wgpu::IndexFormat, index_count: usize, bind_group: wgpu::BindGroup, uniform_buf: wgpu::Buffer, @@ -101,7 +100,7 @@ struct Example { impl Example { fn generate_matrix(aspect_ratio: f32) -> cgmath::Matrix4 { let mx_projection = cgmath::perspective(cgmath::Deg(45f32), aspect_ratio, 1.0, 10.0); - let mx_view = cgmath::Matrix4::look_at( + let mx_view = cgmath::Matrix4::look_at_rh( cgmath::Point3::new(1.5f32, -5.0, 3.0), cgmath::Point3::new(0f32, 0.0, 0.0), cgmath::Vector3::unit_z(), @@ -252,59 +251,46 @@ impl framework::Example for Example { label: None, }); - let index_format = wgpu::IndexFormat::Uint16; // Create the render pipeline - let vertex_state = wgpu::VertexStateDescriptor { - index_format: Some(index_format), - vertex_buffers: &[wgpu::VertexBufferDescriptor { - stride: vertex_size as wgpu::BufferAddress, - step_mode: wgpu::InputStepMode::Vertex, - attributes: &[ - wgpu::VertexAttributeDescriptor { - format: wgpu::VertexFormat::Float4, - offset: 0, - shader_location: 0, - }, - wgpu::VertexAttributeDescriptor { - format: wgpu::VertexFormat::Float2, - offset: 4 * 4, - shader_location: 1, - }, - ], - }], - }; - 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 vertex_buffers = [wgpu::VertexBufferLayout { + array_stride: vertex_size as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Vertex, + attributes: &[ + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float4, + offset: 0, + shader_location: 0, + }, + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float2, + offset: 4 * 4, + shader_location: 1, + }, + ], + }]; + let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: None, layout: Some(&pipeline_layout), - vertex_stage: wgpu::ProgrammableStageDescriptor { + vertex: wgpu::VertexState { module: &vs_module, entry_point: "main", + buffers: &vertex_buffers, }, - fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + fragment: Some(wgpu::FragmentState { module: &fs_module, entry_point: "main", + targets: &[sc_desc.format.into()], }), - rasterization_state: Some(wgpu::RasterizationStateDescriptor { - front_face: wgpu::FrontFace::Ccw, + primitive: wgpu::PrimitiveState { cull_mode: wgpu::CullMode::Back, ..Default::default() - }), - primitive_topology: wgpu::PrimitiveTopology::TriangleList, - color_states: &[wgpu::ColorStateDescriptor { - format: sc_desc.format, - color_blend: wgpu::BlendDescriptor::REPLACE, - alpha_blend: wgpu::BlendDescriptor::REPLACE, - write_mask: wgpu::ColorWrite::ALL, - }], - depth_stencil_state: None, - vertex_state: vertex_state.clone(), - sample_count: 1, - sample_mask: !0, - alpha_to_coverage_enabled: false, + }, + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), }); let pipeline_wire = if device @@ -316,36 +302,33 @@ impl framework::Example for Example { let pipeline_wire = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: None, layout: Some(&pipeline_layout), - vertex_stage: wgpu::ProgrammableStageDescriptor { + vertex: wgpu::VertexState { module: &vs_module, entry_point: "main", + buffers: &vertex_buffers, }, - fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + fragment: Some(wgpu::FragmentState { module: &fs_wire_module, entry_point: "main", + targets: &[wgpu::ColorTargetState { + format: sc_desc.format, + color_blend: wgpu::BlendState { + operation: wgpu::BlendOperation::Add, + src_factor: wgpu::BlendFactor::SrcAlpha, + dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha, + }, + alpha_blend: wgpu::BlendState::REPLACE, + write_mask: wgpu::ColorWrite::ALL, + }], }), - rasterization_state: Some(wgpu::RasterizationStateDescriptor { + primitive: wgpu::PrimitiveState { front_face: wgpu::FrontFace::Ccw, cull_mode: wgpu::CullMode::Back, polygon_mode: wgpu::PolygonMode::Line, ..Default::default() - }), - primitive_topology: wgpu::PrimitiveTopology::TriangleList, - color_states: &[wgpu::ColorStateDescriptor { - format: sc_desc.format, - color_blend: wgpu::BlendDescriptor { - operation: wgpu::BlendOperation::Add, - src_factor: wgpu::BlendFactor::SrcAlpha, - dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha, - }, - alpha_blend: wgpu::BlendDescriptor::REPLACE, - write_mask: wgpu::ColorWrite::ALL, - }], - depth_stencil_state: None, - vertex_state, - sample_count: 1, - sample_mask: !0, - alpha_to_coverage_enabled: false, + }, + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), }); Some(pipeline_wire) } else { @@ -356,7 +339,6 @@ impl framework::Example for Example { Example { vertex_buf, index_buf, - index_format, index_count: index_data.len(), bind_group, uniform_buf, @@ -410,7 +392,7 @@ impl framework::Example for Example { rpass.push_debug_group("Prepare data for draw."); rpass.set_pipeline(&self.pipeline); rpass.set_bind_group(0, &self.bind_group, &[]); - rpass.set_index_buffer(self.index_buf.slice(..), self.index_format); + rpass.set_index_buffer(self.index_buf.slice(..), wgpu::IndexFormat::Uint16); rpass.set_vertex_buffer(0, self.vertex_buf.slice(..)); rpass.pop_debug_group(); rpass.insert_debug_marker("Draw!"); diff --git a/wgpu/examples/hello-compute/main.rs b/wgpu/examples/hello-compute/main.rs index d08d995319..022de10881 100644 --- a/wgpu/examples/hello-compute/main.rs +++ b/wgpu/examples/hello-compute/main.rs @@ -119,10 +119,8 @@ async fn execute_gpu(numbers: Vec) -> Vec { let compute_pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor { label: None, layout: Some(&pipeline_layout), - compute_stage: wgpu::ProgrammableStageDescriptor { - module: &cs_module, - entry_point: "main", - }, + module: &cs_module, + entry_point: "main", }); // A command encoder executes one or many pipelines. diff --git a/wgpu/examples/hello-triangle/main.rs b/wgpu/examples/hello-triangle/main.rs index e071c00655..c87cafaf1b 100644 --- a/wgpu/examples/hello-triangle/main.rs +++ b/wgpu/examples/hello-triangle/main.rs @@ -49,26 +49,19 @@ async fn run(event_loop: EventLoop<()>, window: Window) { let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: None, layout: Some(&pipeline_layout), - vertex_stage: wgpu::ProgrammableStageDescriptor { + vertex: wgpu::VertexState { module: &shader, entry_point: "vs_main", + buffers: &[], }, - fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + fragment: Some(wgpu::FragmentState { module: &shader, entry_point: "fs_main", + targets: &[swapchain_format.into()], }), - // Use the default rasterizer state: no culling, no depth bias - rasterization_state: None, - primitive_topology: wgpu::PrimitiveTopology::TriangleList, - color_states: &[swapchain_format.into()], - depth_stencil_state: None, - vertex_state: wgpu::VertexStateDescriptor { - index_format: None, - vertex_buffers: &[], - }, - sample_count: 1, - sample_mask: !0, - alpha_to_coverage_enabled: false, + primitive: wgpu::PrimitiveState::default(), + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), }); let mut sc_desc = wgpu::SwapChainDescriptor { diff --git a/wgpu/examples/mipmap/main.rs b/wgpu/examples/mipmap/main.rs index 79b0896122..8577a5f288 100644 --- a/wgpu/examples/mipmap/main.rs +++ b/wgpu/examples/mipmap/main.rs @@ -87,7 +87,7 @@ struct Example { impl Example { fn generate_matrix(aspect_ratio: f32) -> cgmath::Matrix4 { let mx_projection = cgmath::perspective(cgmath::Deg(45f32), aspect_ratio, 1.0, 1000.0); - let mx_view = cgmath::Matrix4::look_at( + let mx_view = cgmath::Matrix4::look_at_rh( cgmath::Point3::new(0f32, 0.0, 10.0), cgmath::Point3::new(0f32, 50.0, 0.0), cgmath::Vector3::unit_z(), @@ -109,29 +109,22 @@ impl Example { let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("blit"), layout: None, - vertex_stage: wgpu::ProgrammableStageDescriptor { + vertex: wgpu::VertexState { module: &vs_module, entry_point: "main", + buffers: &[], }, - fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + fragment: Some(wgpu::FragmentState { module: &fs_module, entry_point: "main", + targets: &[TEXTURE_FORMAT.into()], }), - rasterization_state: Some(wgpu::RasterizationStateDescriptor { - front_face: wgpu::FrontFace::Ccw, - cull_mode: wgpu::CullMode::None, + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleStrip, ..Default::default() - }), - primitive_topology: wgpu::PrimitiveTopology::TriangleStrip, - color_states: &[TEXTURE_FORMAT.into()], - depth_stencil_state: None, - vertex_state: wgpu::VertexStateDescriptor { - index_format: None, - vertex_buffers: &[], }, - sample_count: 1, - sample_mask: !0, - alpha_to_coverage_enabled: false, + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), }); let bind_group_layout = pipeline.get_bind_group_layout(0); @@ -320,33 +313,28 @@ impl framework::Example for Example { let draw_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("draw"), layout: None, - vertex_stage: wgpu::ProgrammableStageDescriptor { + vertex: wgpu::VertexState { module: &vs_module, entry_point: "main", - }, - fragment_stage: Some(wgpu::ProgrammableStageDescriptor { - module: &fs_module, - entry_point: "main", - }), - rasterization_state: Some(wgpu::RasterizationStateDescriptor { - front_face: wgpu::FrontFace::Ccw, - cull_mode: wgpu::CullMode::Back, - ..Default::default() - }), - primitive_topology: wgpu::PrimitiveTopology::TriangleStrip, - color_states: &[sc_desc.format.into()], - depth_stencil_state: None, - vertex_state: wgpu::VertexStateDescriptor { - index_format: None, - vertex_buffers: &[wgpu::VertexBufferDescriptor { - stride: vertex_size as wgpu::BufferAddress, + buffers: &[wgpu::VertexBufferLayout { + array_stride: vertex_size as wgpu::BufferAddress, step_mode: wgpu::InputStepMode::Vertex, attributes: &wgpu::vertex_attr_array![0 => Float4], }], }, - sample_count: 1, - sample_mask: !0, - alpha_to_coverage_enabled: false, + fragment: Some(wgpu::FragmentState { + module: &fs_module, + entry_point: "main", + targets: &[sc_desc.format.into()], + }), + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleStrip, + front_face: wgpu::FrontFace::Ccw, + cull_mode: wgpu::CullMode::Back, + ..Default::default() + }, + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), }); // Create bind group diff --git a/wgpu/examples/msaa-line/main.rs b/wgpu/examples/msaa-line/main.rs index 277b969d1c..64a55c1bb2 100644 --- a/wgpu/examples/msaa-line/main.rs +++ b/wgpu/examples/msaa-line/main.rs @@ -50,33 +50,30 @@ impl Example { let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: None, layout: Some(&pipeline_layout), - vertex_stage: wgpu::ProgrammableStageDescriptor { + vertex: wgpu::VertexState { module: vs_module, entry_point: "main", - }, - fragment_stage: Some(wgpu::ProgrammableStageDescriptor { - module: fs_module, - entry_point: "main", - }), - rasterization_state: Some(wgpu::RasterizationStateDescriptor { - front_face: wgpu::FrontFace::Ccw, - cull_mode: wgpu::CullMode::None, - ..Default::default() - }), - primitive_topology: wgpu::PrimitiveTopology::LineList, - color_states: &[sc_desc.format.into()], - depth_stencil_state: None, - vertex_state: wgpu::VertexStateDescriptor { - index_format: None, - vertex_buffers: &[wgpu::VertexBufferDescriptor { - stride: std::mem::size_of::() as wgpu::BufferAddress, + buffers: &[wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as wgpu::BufferAddress, step_mode: wgpu::InputStepMode::Vertex, attributes: &wgpu::vertex_attr_array![0 => Float2, 1 => Float4], }], }, - sample_count, - sample_mask: !0, - alpha_to_coverage_enabled: false, + fragment: Some(wgpu::FragmentState { + module: fs_module, + entry_point: "main", + targets: &[sc_desc.format.into()], + }), + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::LineList, + front_face: wgpu::FrontFace::Ccw, + ..Default::default() + }, + depth_stencil: None, + multisample: wgpu::MultisampleState { + count: sample_count, + ..Default::default() + }, }); let mut encoder = device.create_render_bundle_encoder(&wgpu::RenderBundleEncoderDescriptor { diff --git a/wgpu/examples/shadow/main.rs b/wgpu/examples/shadow/main.rs index 1a6b48201f..8ab13bb0c5 100644 --- a/wgpu/examples/shadow/main.rs +++ b/wgpu/examples/shadow/main.rs @@ -110,7 +110,7 @@ impl Light { fn to_raw(&self) -> LightRaw { use cgmath::{Deg, EuclideanSpace, Matrix4, PerspectiveFov, Point3, Vector3}; - let mx_view = Matrix4::look_at(self.pos, Point3::origin(), Vector3::unit_z()); + let mx_view = Matrix4::look_at_rh(self.pos, Point3::origin(), Vector3::unit_z()); let projection = PerspectiveFov { fovy: Deg(self.fov).into(), aspect: 1.0, @@ -182,7 +182,7 @@ impl Example { fn generate_matrix(aspect_ratio: f32) -> cgmath::Matrix4 { let mx_projection = cgmath::perspective(cgmath::Deg(45f32), aspect_ratio, 1.0, 20.0); - let mx_view = cgmath::Matrix4::look_at( + let mx_view = cgmath::Matrix4::look_at_rh( cgmath::Point3::new(3.0f32, -10.0, 6.0), cgmath::Point3::new(0f32, 0.0, 0.0), cgmath::Vector3::unit_z(), @@ -418,8 +418,8 @@ impl framework::Example for Example { }); let vertex_attr = wgpu::vertex_attr_array![0 => Char4, 1 => Char4]; - let vb_desc = wgpu::VertexBufferDescriptor { - stride: vertex_size as wgpu::BufferAddress, + let vb_desc = wgpu::VertexBufferLayout { + array_stride: vertex_size as wgpu::BufferAddress, step_mode: wgpu::InputStepMode::Vertex, attributes: &vertex_attr, }; @@ -470,35 +470,31 @@ impl framework::Example for Example { let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("shadow"), layout: Some(&pipeline_layout), - vertex_stage: wgpu::ProgrammableStageDescriptor { + vertex: wgpu::VertexState { module: &vs_module, entry_point: "main", + buffers: &[vb_desc.clone()], }, - fragment_stage: None, - rasterization_state: Some(wgpu::RasterizationStateDescriptor { + fragment: None, + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleList, front_face: wgpu::FrontFace::Ccw, cull_mode: wgpu::CullMode::Back, - polygon_mode: wgpu::PolygonMode::Fill, - depth_bias: 2, // corresponds to bilinear filtering - depth_bias_slope_scale: 2.0, - depth_bias_clamp: 0.0, - clamp_depth: device.features().contains(wgpu::Features::DEPTH_CLAMPING), - }), - primitive_topology: wgpu::PrimitiveTopology::TriangleList, - color_states: &[], - depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { + ..Default::default() + }, + depth_stencil: Some(wgpu::DepthStencilState { format: Self::SHADOW_FORMAT, depth_write_enabled: true, depth_compare: wgpu::CompareFunction::LessEqual, - stencil: wgpu::StencilStateDescriptor::default(), + stencil: wgpu::StencilState::default(), + bias: wgpu::DepthBiasState { + constant: 2, // corresponds to bilinear filtering + slope_scale: 2.0, + clamp: 0.0, + }, + clamp_depth: device.features().contains(wgpu::Features::DEPTH_CLAMPING), }), - vertex_state: wgpu::VertexStateDescriptor { - index_format: Some(index_format), - vertex_buffers: &[vb_desc.clone()], - }, - sample_count: 1, - sample_mask: !0, - alpha_to_coverage_enabled: false, + multisample: wgpu::MultisampleState::default(), }); Pass { @@ -607,34 +603,30 @@ impl framework::Example for Example { let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("main"), layout: Some(&pipeline_layout), - vertex_stage: wgpu::ProgrammableStageDescriptor { + vertex: wgpu::VertexState { module: &vs_module, entry_point: "main", + buffers: &[vb_desc], }, - fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + fragment: Some(wgpu::FragmentState { module: &fs_module, entry_point: "main", + targets: &[sc_desc.format.into()], }), - rasterization_state: Some(wgpu::RasterizationStateDescriptor { + primitive: wgpu::PrimitiveState { front_face: wgpu::FrontFace::Ccw, cull_mode: wgpu::CullMode::Back, ..Default::default() - }), - primitive_topology: wgpu::PrimitiveTopology::TriangleList, - color_states: &[sc_desc.format.into()], - depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { + }, + depth_stencil: Some(wgpu::DepthStencilState { format: Self::DEPTH_FORMAT, depth_write_enabled: true, depth_compare: wgpu::CompareFunction::Less, - stencil: wgpu::StencilStateDescriptor::default(), + stencil: wgpu::StencilState::default(), + bias: wgpu::DepthBiasState::default(), + clamp_depth: false, }), - vertex_state: wgpu::VertexStateDescriptor { - index_format: Some(index_format), - vertex_buffers: &[vb_desc], - }, - sample_count: 1, - sample_mask: !0, - alpha_to_coverage_enabled: false, + multisample: wgpu::MultisampleState::default(), }); Pass { diff --git a/wgpu/examples/skybox/main.rs b/wgpu/examples/skybox/main.rs index 1012ab9ec3..c6b6145f96 100644 --- a/wgpu/examples/skybox/main.rs +++ b/wgpu/examples/skybox/main.rs @@ -27,7 +27,7 @@ pub struct Skybox { impl Skybox { fn generate_uniforms(aspect_ratio: f32) -> Uniforms { let mx_projection = cgmath::perspective(cgmath::Deg(45f32), aspect_ratio, 1.0, 10.0); - let mx_view = cgmath::Matrix4::look_at( + let mx_view = cgmath::Matrix4::look_at_rh( cgmath::Point3::new(1.5f32, -5.0, 3.0), cgmath::Point3::new(0f32, 0.0, 0.0), cgmath::Vector3::unit_z(), @@ -107,29 +107,22 @@ impl framework::Example for Skybox { let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: None, layout: Some(&pipeline_layout), - vertex_stage: wgpu::ProgrammableStageDescriptor { + vertex: wgpu::VertexState { module: &vs_module, entry_point: "main", + buffers: &[], }, - fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + fragment: Some(wgpu::FragmentState { module: &fs_module, entry_point: "main", + targets: &[sc_desc.format.into()], }), - rasterization_state: Some(wgpu::RasterizationStateDescriptor { + primitive: wgpu::PrimitiveState { front_face: wgpu::FrontFace::Cw, - cull_mode: wgpu::CullMode::None, ..Default::default() - }), - primitive_topology: wgpu::PrimitiveTopology::TriangleList, - color_states: &[sc_desc.format.into()], - vertex_state: wgpu::VertexStateDescriptor { - index_format: None, - vertex_buffers: &[], }, - depth_stencil_state: None, - sample_count: 1, - sample_mask: !0, - alpha_to_coverage_enabled: false, + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), }); let sampler = device.create_sampler(&wgpu::SamplerDescriptor { diff --git a/wgpu/examples/texture-arrays/main.rs b/wgpu/examples/texture-arrays/main.rs index b891cd60b7..8ef4d6b331 100644 --- a/wgpu/examples/texture-arrays/main.rs +++ b/wgpu/examples/texture-arrays/main.rs @@ -254,33 +254,26 @@ impl framework::Example for Example { let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: None, layout: Some(&pipeline_layout), - vertex_stage: wgpu::ProgrammableStageDescriptor { + vertex: wgpu::VertexState { module: &vs_module, entry_point: "main", - }, - fragment_stage: Some(wgpu::ProgrammableStageDescriptor { - module: &fs_module, - entry_point: "main", - }), - rasterization_state: Some(wgpu::RasterizationStateDescriptor { - front_face: wgpu::FrontFace::Ccw, - cull_mode: wgpu::CullMode::None, - ..Default::default() - }), - primitive_topology: wgpu::PrimitiveTopology::TriangleList, - color_states: &[sc_desc.format.into()], - depth_stencil_state: None, - vertex_state: wgpu::VertexStateDescriptor { - index_format: Some(index_format), - vertex_buffers: &[wgpu::VertexBufferDescriptor { - stride: vertex_size as wgpu::BufferAddress, + buffers: &[wgpu::VertexBufferLayout { + array_stride: vertex_size as wgpu::BufferAddress, step_mode: wgpu::InputStepMode::Vertex, attributes: &wgpu::vertex_attr_array![0 => Float2, 1 => Float2, 2 => Int], }], }, - sample_count: 1, - sample_mask: !0, - alpha_to_coverage_enabled: false, + fragment: Some(wgpu::FragmentState { + module: &fs_module, + entry_point: "main", + targets: &[sc_desc.format.into()], + }), + primitive: wgpu::PrimitiveState { + front_face: wgpu::FrontFace::Ccw, + ..Default::default() + }, + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), }); Self { diff --git a/wgpu/examples/water/main.rs b/wgpu/examples/water/main.rs index c81efe3954..720d04fc2e 100644 --- a/wgpu/examples/water/main.rs +++ b/wgpu/examples/water/main.rs @@ -99,7 +99,7 @@ impl Example { /// fn generate_matrices(aspect_ratio: f32) -> Matrices { let projection = cgmath::perspective(cgmath::Deg(45f32), aspect_ratio, 10.0, 400.0); - let reg_view = cgmath::Matrix4::look_at( + let reg_view = cgmath::Matrix4::look_at_rh( CAMERA, cgmath::Point3::new(0f32, 0.0, 0.0), cgmath::Vector3::unit_y(), //Note that y is up. Differs from other examples. @@ -109,7 +109,7 @@ impl Example { let reg_view = reg_view * scale; - let flipped_view = cgmath::Matrix4::look_at( + let flipped_view = cgmath::Matrix4::look_at_rh( cgmath::Point3::new(CAMERA.x, -CAMERA.y, CAMERA.z), cgmath::Point3::new(0f32, 0.0, 0.0), cgmath::Vector3::unit_y(), @@ -501,111 +501,102 @@ impl framework::Example for Example { label: Some("water"), // The "layout" is what uniforms will be needed. layout: Some(&water_pipeline_layout), - // Vertex & Fragment shaders - vertex_stage: wgpu::ProgrammableStageDescriptor { + // Vertex shader and input buffers + vertex: wgpu::VertexState { module: &water_vs_module, entry_point: "main", + // Layout of our vertices. This should match the structs + // which are uploaded to the GPU. This should also be + // ensured by tagging on either a `#[repr(C)]` onto a + // struct, or a `#[repr(transparent)]` if it only contains + // one item, which is itself `repr(C)`. + buffers: &[wgpu::VertexBufferLayout { + array_stride: water_vertex_size as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Vertex, + attributes: &wgpu::vertex_attr_array![0 => Short2, 1 => Char4], + }], }, - fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + // Fragment shader and output targets + fragment: Some(wgpu::FragmentState { module: &water_fs_module, entry_point: "main", + // Describes how the colour will be interpolated + // and assigned to the output attachment. + targets: &[wgpu::ColorTargetState { + format: sc_desc.format, + color_blend: wgpu::BlendState { + src_factor: wgpu::BlendFactor::SrcAlpha, + dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha, + operation: wgpu::BlendOperation::Add, + }, + alpha_blend: wgpu::BlendState { + src_factor: wgpu::BlendFactor::One, + dst_factor: wgpu::BlendFactor::One, + operation: wgpu::BlendOperation::Max, + }, + write_mask: wgpu::ColorWrite::ALL, + }], }), // How the triangles will be rasterized. This is more important // for the terrain because of the beneath-the water shot. // This is also dependent on how the triangles are being generated. - rasterization_state: Some(wgpu::RasterizationStateDescriptor { + primitive: wgpu::PrimitiveState { + // What kind of data are we passing in? + topology: wgpu::PrimitiveTopology::TriangleList, front_face: wgpu::FrontFace::Cw, - cull_mode: wgpu::CullMode::None, ..Default::default() - }), - // What kind of data are we passing in? - primitive_topology: wgpu::PrimitiveTopology::TriangleList, - // Describes how the colour will be interpolated - // and assigned to the output attachment. - color_states: &[wgpu::ColorStateDescriptor { - format: sc_desc.format, - color_blend: wgpu::BlendDescriptor { - src_factor: wgpu::BlendFactor::SrcAlpha, - dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha, - operation: wgpu::BlendOperation::Add, - }, - alpha_blend: wgpu::BlendDescriptor { - src_factor: wgpu::BlendFactor::One, - dst_factor: wgpu::BlendFactor::One, - operation: wgpu::BlendOperation::Max, - }, - write_mask: wgpu::ColorWrite::ALL, - }], + }, // Describes how us writing to the depth/stencil buffer // will work. Since this is water, we need to read from the // depth buffer both as a texture in the shader, and as an // input attachment to do depth-testing. We don't write, so // depth_write_enabled is set to false. This is called // RODS or read-only depth stencil. - depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { + depth_stencil: Some(wgpu::DepthStencilState { // We don't use stencil. format: wgpu::TextureFormat::Depth32Float, depth_write_enabled: false, depth_compare: wgpu::CompareFunction::Less, - stencil: wgpu::StencilStateDescriptor::default(), + stencil: wgpu::StencilState::default(), + bias: wgpu::DepthBiasState::default(), + clamp_depth: false, }), - // Layout of our vertices. This should match the structs - // which are uploaded to the GPU. This should also be - // ensured by tagging on either a `#[repr(C)]` onto a - // struct, or a `#[repr(transparent)]` if it only contains - // one item, which is itself `repr(C)`. - vertex_state: wgpu::VertexStateDescriptor { - // We don't actually use indices, since it's unnecessary - // because we duplicate all the data anyway. This is - // necessary to achieve the low-poly effect. - index_format: None, - vertex_buffers: &[wgpu::VertexBufferDescriptor { - stride: water_vertex_size as wgpu::BufferAddress, - step_mode: wgpu::InputStepMode::Vertex, - attributes: &wgpu::vertex_attr_array![0 => Short2, 1 => Char4], - }], - }, - sample_count: 1, - sample_mask: !0, - alpha_to_coverage_enabled: false, + // No multisampling is used. + multisample: wgpu::MultisampleState::default(), }); // Same idea as the water pipeline. let terrain_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("terrain"), layout: Some(&terrain_pipeline_layout), - vertex_stage: wgpu::ProgrammableStageDescriptor { + vertex: wgpu::VertexState { module: &terrain_vs_module, entry_point: "main", - }, - fragment_stage: Some(wgpu::ProgrammableStageDescriptor { - module: &terrain_fs_module, - entry_point: "main", - }), - rasterization_state: Some(wgpu::RasterizationStateDescriptor { - front_face: wgpu::FrontFace::Ccw, - cull_mode: wgpu::CullMode::Front, - ..Default::default() - }), - primitive_topology: wgpu::PrimitiveTopology::TriangleList, - color_states: &[sc_desc.format.into()], - depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { - format: wgpu::TextureFormat::Depth32Float, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, - stencil: wgpu::StencilStateDescriptor::default(), - }), - vertex_state: wgpu::VertexStateDescriptor { - index_format: None, - vertex_buffers: &[wgpu::VertexBufferDescriptor { - stride: terrain_vertex_size as wgpu::BufferAddress, + buffers: &[wgpu::VertexBufferLayout { + array_stride: terrain_vertex_size as wgpu::BufferAddress, step_mode: wgpu::InputStepMode::Vertex, attributes: &wgpu::vertex_attr_array![0 => Float3, 1 => Float3, 2 => Uchar4Norm], }], }, - sample_count: 1, - sample_mask: !0, - alpha_to_coverage_enabled: false, + fragment: Some(wgpu::FragmentState { + module: &terrain_fs_module, + entry_point: "main", + targets: &[sc_desc.format.into()], + }), + primitive: wgpu::PrimitiveState { + front_face: wgpu::FrontFace::Ccw, + cull_mode: wgpu::CullMode::Front, + ..Default::default() + }, + depth_stencil: Some(wgpu::DepthStencilState { + format: wgpu::TextureFormat::Depth32Float, + depth_write_enabled: true, + depth_compare: wgpu::CompareFunction::Less, + stencil: wgpu::StencilState::default(), + bias: wgpu::DepthBiasState::default(), + clamp_depth: false, + }), + multisample: wgpu::MultisampleState::default(), }); // Done diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index c5d6b7668c..7c5c24e54a 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -990,31 +990,16 @@ impl crate::Context for Context { wgc::span!(_guard, TRACE, "Device::create_render_pipeline wrapper"); use wgc::pipeline as pipe; - let vertex_stage = pipe::ProgrammableStageDescriptor { - module: desc.vertex_stage.module.id, - entry_point: Borrowed(&desc.vertex_stage.entry_point), - }; - let fragment_stage = - desc.fragment_stage - .as_ref() - .map(|fs| pipe::ProgrammableStageDescriptor { - module: fs.module.id, - entry_point: Borrowed(&fs.entry_point), - }); let vertex_buffers: ArrayVec<[_; wgc::device::MAX_VERTEX_BUFFERS]> = desc - .vertex_state - .vertex_buffers + .vertex + .buffers .iter() - .map(|vertex_buffer| pipe::VertexBufferDescriptor { - stride: vertex_buffer.stride, - step_mode: vertex_buffer.step_mode, - attributes: Borrowed(vertex_buffer.attributes), + .map(|vbuf| pipe::VertexBufferLayout { + array_stride: vbuf.array_stride, + step_mode: vbuf.step_mode, + attributes: Borrowed(vbuf.attributes), }) .collect(); - let vertex_state = pipe::VertexStateDescriptor { - index_format: desc.vertex_state.index_format, - vertex_buffers: Borrowed(&vertex_buffers), - }; let implicit_pipeline_ids = match desc.layout { Some(_) => None, @@ -1026,16 +1011,23 @@ impl crate::Context for Context { let descriptor = pipe::RenderPipelineDescriptor { label: desc.label.map(Borrowed), layout: desc.layout.map(|l| l.id), - vertex_stage, - fragment_stage, - rasterization_state: desc.rasterization_state.clone(), - primitive_topology: desc.primitive_topology, - color_states: Borrowed(&desc.color_states), - depth_stencil_state: desc.depth_stencil_state.clone(), - vertex_state: vertex_state, - sample_count: desc.sample_count, - sample_mask: desc.sample_mask, - alpha_to_coverage_enabled: desc.alpha_to_coverage_enabled, + vertex: pipe::VertexState { + stage: pipe::ProgrammableStageDescriptor { + module: desc.vertex.module.id, + entry_point: Borrowed(desc.vertex.entry_point), + }, + buffers: Borrowed(&vertex_buffers), + }, + primitive: desc.primitive.clone(), + depth_stencil: desc.depth_stencil.clone(), + multisample: desc.multisample.clone(), + fragment: desc.fragment.as_ref().map(|frag| pipe::FragmentState { + stage: pipe::ProgrammableStageDescriptor { + module: frag.module.id, + entry_point: Borrowed(frag.entry_point), + }, + targets: Borrowed(frag.targets), + }), }; let global = &self.0; @@ -1074,9 +1066,9 @@ impl crate::Context for Context { let descriptor = pipe::ComputePipelineDescriptor { label: desc.label.map(Borrowed), layout: desc.layout.map(|l| l.id), - compute_stage: pipe::ProgrammableStageDescriptor { - module: desc.compute_stage.module.id, - entry_point: Borrowed(&desc.compute_stage.entry_point), + stage: pipe::ProgrammableStageDescriptor { + module: desc.module.id, + entry_point: Borrowed(desc.entry_point), }, }; diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index a6dd4e5dd8..60eead872e 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -1,11 +1,3 @@ -use crate::{ - BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, BufferDescriptor, - CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, LoadOp, - PipelineLayoutDescriptor, ProgrammableStageDescriptor, RenderBundleEncoderDescriptor, - RenderPipelineDescriptor, SamplerDescriptor, ShaderModuleDescriptor, ShaderSource, - SwapChainStatus, TextureDescriptor, TextureViewDescriptor, -}; - use std::{ fmt, future::Future, @@ -515,12 +507,6 @@ fn map_texture_component_type( } } -fn map_stage_descriptor( - desc: &ProgrammableStageDescriptor, -) -> web_sys::GpuProgrammableStageDescriptor { - web_sys::GpuProgrammableStageDescriptor::new(&desc.entry_point, &desc.module.id.0) -} - fn map_cull_mode(cull_mode: wgt::CullMode) -> web_sys::GpuCullMode { use web_sys::GpuCullMode as cm; use wgt::CullMode; @@ -541,14 +527,16 @@ fn map_front_face(front_face: wgt::FrontFace) -> web_sys::GpuFrontFace { } fn map_rasterization_state_descriptor( - desc: &wgt::RasterizationStateDescriptor, + primitive: &wgt::PrimitiveState, + ds: Option<&wgt::DepthStencilState>, ) -> web_sys::GpuRasterizationStateDescriptor { let mut mapped = web_sys::GpuRasterizationStateDescriptor::new(); - mapped.cull_mode(map_cull_mode(desc.cull_mode)); - mapped.depth_bias(desc.depth_bias); - mapped.depth_bias_clamp(desc.depth_bias_clamp); - mapped.depth_bias_slope_scale(desc.depth_bias_slope_scale); - mapped.front_face(map_front_face(desc.front_face)); + mapped.front_face(map_front_face(primitive.front_face)); + mapped.cull_mode(map_cull_mode(primitive.cull_mode)); + let bias = ds.map_or(wgt::DepthBiasState::default(), |ds| ds.bias.clone()); + mapped.depth_bias(bias.constant); + mapped.depth_bias_clamp(bias.clamp); + mapped.depth_bias_slope_scale(bias.slope_scale); mapped } @@ -583,7 +571,7 @@ fn map_stencil_operation(op: wgt::StencilOperation) -> web_sys::GpuStencilOperat } fn map_stencil_state_face_descriptor( - desc: &wgt::StencilStateFaceDescriptor, + desc: &wgt::StencilFaceState, ) -> web_sys::GpuStencilStateFaceDescriptor { let mut mapped = web_sys::GpuStencilStateFaceDescriptor::new(); mapped.compare(map_compare_function(desc.compare)); @@ -594,7 +582,7 @@ fn map_stencil_state_face_descriptor( } fn map_depth_stencil_state_descriptor( - desc: &wgt::DepthStencilStateDescriptor, + desc: &wgt::DepthStencilState, ) -> web_sys::GpuDepthStencilStateDescriptor { let mut mapped = web_sys::GpuDepthStencilStateDescriptor::new(map_texture_format(desc.format)); mapped.depth_compare(map_compare_function(desc.depth_compare)); @@ -606,7 +594,7 @@ fn map_depth_stencil_state_descriptor( mapped } -fn map_blend_descriptor(desc: &wgt::BlendDescriptor) -> web_sys::GpuBlendDescriptor { +fn map_blend_descriptor(desc: &wgt::BlendState) -> web_sys::GpuBlendDescriptor { let mut mapped = web_sys::GpuBlendDescriptor::new(); mapped.dst_factor(map_blend_factor(desc.dst_factor)); mapped.operation(map_blend_operation(desc.operation)); @@ -708,11 +696,11 @@ fn map_input_step_mode(mode: wgt::InputStepMode) -> web_sys::GpuInputStepMode { } fn map_vertex_state_descriptor( - desc: &RenderPipelineDescriptor, + desc: &crate::RenderPipelineDescriptor, ) -> web_sys::GpuVertexStateDescriptor { let mapped_vertex_buffers = desc - .vertex_state - .vertex_buffers + .vertex + .buffers .iter() .map(|vbuf| { let mapped_attributes = vbuf @@ -728,7 +716,7 @@ fn map_vertex_state_descriptor( .collect::(); let mut mapped_vbuf = web_sys::GpuVertexBufferLayoutDescriptor::new( - vbuf.stride as f64, + vbuf.array_stride as f64, &mapped_attributes, ); mapped_vbuf.step_mode(map_input_step_mode(vbuf.step_mode)); @@ -737,11 +725,11 @@ fn map_vertex_state_descriptor( .collect::(); let mut mapped = web_sys::GpuVertexStateDescriptor::new(); - mapped.index_format(map_index_format( - desc.vertex_state - .index_format - .unwrap_or(wgt::IndexFormat::Uint16), - )); + mapped.index_format( + desc.primitive + .strip_index_format + .map_or(web_sys::GpuIndexFormat::Uint16, map_index_format), + ); mapped.vertex_buffers(&mapped_vertex_buffers); mapped } @@ -1051,13 +1039,13 @@ impl crate::Context for Context { fn device_create_shader_module( &self, device: &Self::DeviceId, - desc: &ShaderModuleDescriptor, + desc: &crate::ShaderModuleDescriptor, ) -> Self::ShaderModuleId { let mut descriptor = match desc.source { - ShaderSource::SpirV(ref spv) => { + crate::ShaderSource::SpirV(ref spv) => { web_sys::GpuShaderModuleDescriptor::new(&js_sys::Uint32Array::from(&**spv)) } - ShaderSource::Wgsl(_) => panic!("WGSL is not yet supported by the Web backend"), + crate::ShaderSource::Wgsl(_) => panic!("WGSL is not yet supported by the Web backend"), }; if let Some(ref label) = desc.label { descriptor.label(label); @@ -1068,7 +1056,7 @@ impl crate::Context for Context { fn device_create_bind_group_layout( &self, device: &Self::DeviceId, - desc: &BindGroupLayoutDescriptor, + desc: &crate::BindGroupLayoutDescriptor, ) -> Self::BindGroupLayoutId { use web_sys::GpuBindingType as bt; @@ -1152,14 +1140,14 @@ impl crate::Context for Context { fn device_create_bind_group( &self, device: &Self::DeviceId, - desc: &BindGroupDescriptor, + desc: &crate::BindGroupDescriptor, ) -> Self::BindGroupId { let mapped_entries = desc .entries .iter() .map(|binding| { let mapped_resource = match binding.resource { - BindingResource::Buffer { + crate::BindingResource::Buffer { ref buffer, offset, size, @@ -1172,11 +1160,13 @@ impl crate::Context for Context { } JsValue::from(mapped_buffer_binding.clone()) } - BindingResource::Sampler(ref sampler) => JsValue::from(sampler.id.0.clone()), - BindingResource::TextureView(ref texture_view) => { + crate::BindingResource::Sampler(ref sampler) => { + JsValue::from(sampler.id.0.clone()) + } + crate::BindingResource::TextureView(ref texture_view) => { JsValue::from(texture_view.id.0.clone()) } - BindingResource::TextureViewArray(..) => { + crate::BindingResource::TextureViewArray(..) => { panic!("Web backend does not support BINDING_INDEXING extension") } }; @@ -1196,7 +1186,7 @@ impl crate::Context for Context { fn device_create_pipeline_layout( &self, device: &Self::DeviceId, - desc: &PipelineLayoutDescriptor, + desc: &crate::PipelineLayoutDescriptor, ) -> Self::PipelineLayoutId { let temp_layouts = desc .bind_group_layouts @@ -1213,27 +1203,25 @@ impl crate::Context for Context { fn device_create_render_pipeline( &self, device: &Self::DeviceId, - desc: &RenderPipelineDescriptor, + desc: &crate::RenderPipelineDescriptor, ) -> Self::RenderPipelineId { use web_sys::GpuPrimitiveTopology as pt; - let mapped_color_states = desc - .color_states + let targets = desc.fragment.as_ref().map_or(&[][..], |frag| &frag.targets); + let mapped_color_states = targets .iter() - .map(|color_state_desc| { - let mapped_format = map_texture_format(color_state_desc.format); + .map(|target| { + let mapped_format = map_texture_format(target.format); let mut mapped_color_state_desc = web_sys::GpuColorStateDescriptor::new(mapped_format); - mapped_color_state_desc - .alpha_blend(&map_blend_descriptor(&color_state_desc.alpha_blend)); - mapped_color_state_desc - .color_blend(&map_blend_descriptor(&color_state_desc.color_blend)); - mapped_color_state_desc.write_mask(color_state_desc.write_mask.bits()); + mapped_color_state_desc.alpha_blend(&map_blend_descriptor(&target.alpha_blend)); + mapped_color_state_desc.color_blend(&map_blend_descriptor(&target.color_blend)); + mapped_color_state_desc.write_mask(target.write_mask.bits()); mapped_color_state_desc }) .collect::(); - let mapped_primitive_topology = match desc.primitive_topology { + let mapped_primitive_topology = match desc.primitive.topology { wgt::PrimitiveTopology::PointList => pt::PointList, wgt::PrimitiveTopology::LineList => pt::LineList, wgt::PrimitiveTopology::LineStrip => pt::LineStrip, @@ -1241,7 +1229,10 @@ impl crate::Context for Context { wgt::PrimitiveTopology::TriangleStrip => pt::TriangleStrip, }; - let mapped_vertex_stage = map_stage_descriptor(&desc.vertex_stage); + let mapped_vertex_stage = web_sys::GpuProgrammableStageDescriptor::new( + &desc.vertex.entry_point, + &desc.vertex.module.id.0, + ); let mut mapped_desc = web_sys::GpuRenderPipelineDescriptor::new( &mapped_color_states, @@ -1254,22 +1245,25 @@ impl crate::Context for Context { // TODO: label - if let Some(ref frag) = desc.fragment_stage { - mapped_desc.fragment_stage(&map_stage_descriptor(frag)); + if let Some(ref frag) = desc.fragment { + let mapped_fragment_desc = + web_sys::GpuProgrammableStageDescriptor::new(&frag.entry_point, &frag.module.id.0); + mapped_desc.fragment_stage(&mapped_fragment_desc); } - if let Some(ref rasterization) = desc.rasterization_state { - mapped_desc.rasterization_state(&map_rasterization_state_descriptor(rasterization)); - } + mapped_desc.rasterization_state(&map_rasterization_state_descriptor( + &desc.primitive, + desc.depth_stencil.as_ref(), + )); - if let Some(ref depth_stencil) = desc.depth_stencil_state { + if let Some(ref depth_stencil) = desc.depth_stencil { mapped_desc.depth_stencil_state(&map_depth_stencil_state_descriptor(depth_stencil)); } mapped_desc.vertex_state(&map_vertex_state_descriptor(&desc)); - mapped_desc.sample_count(desc.sample_count); - mapped_desc.sample_mask(desc.sample_mask); - mapped_desc.alpha_to_coverage_enabled(desc.alpha_to_coverage_enabled); + mapped_desc.sample_count(desc.multisample.count); + mapped_desc.sample_mask(desc.multisample.mask as u32); + mapped_desc.alpha_to_coverage_enabled(desc.multisample.alpha_to_coverage_enabled); Sendable(device.0.create_render_pipeline(&mapped_desc)) } @@ -1277,9 +1271,10 @@ impl crate::Context for Context { fn device_create_compute_pipeline( &self, device: &Self::DeviceId, - desc: &ComputePipelineDescriptor, + desc: &crate::ComputePipelineDescriptor, ) -> Self::ComputePipelineId { - let mapped_compute_stage = map_stage_descriptor(&desc.compute_stage); + let mapped_compute_stage = + web_sys::GpuProgrammableStageDescriptor::new(&desc.entry_point, &desc.module.id.0); let mut mapped_desc = web_sys::GpuComputePipelineDescriptor::new(&mapped_compute_stage); if let Some(layout) = desc.layout { mapped_desc.layout(&layout.id.0); @@ -1293,7 +1288,7 @@ impl crate::Context for Context { fn device_create_buffer( &self, device: &Self::DeviceId, - desc: &BufferDescriptor<'_>, + desc: &crate::BufferDescriptor, ) -> Self::BufferId { let mut mapped_desc = web_sys::GpuBufferDescriptor::new(desc.size as f64, desc.usage.bits()); @@ -1307,7 +1302,7 @@ impl crate::Context for Context { fn device_create_texture( &self, device: &Self::DeviceId, - desc: &TextureDescriptor, + desc: &crate::TextureDescriptor, ) -> Self::TextureId { let mut mapped_desc = web_sys::GpuTextureDescriptor::new( map_texture_format(desc.format), @@ -1326,7 +1321,7 @@ impl crate::Context for Context { fn device_create_sampler( &self, device: &Self::DeviceId, - desc: &SamplerDescriptor, + desc: &crate::SamplerDescriptor, ) -> Self::SamplerId { let mut mapped_desc = web_sys::GpuSamplerDescriptor::new(); mapped_desc.address_mode_u(map_address_mode(desc.address_mode_u)); @@ -1357,7 +1352,7 @@ impl crate::Context for Context { fn device_create_command_encoder( &self, device: &Self::DeviceId, - desc: &CommandEncoderDescriptor, + desc: &crate::CommandEncoderDescriptor, ) -> Self::CommandEncoderId { let mut mapped_desc = web_sys::GpuCommandEncoderDescriptor::new(); if let Some(ref label) = desc.label { @@ -1371,7 +1366,7 @@ impl crate::Context for Context { fn device_create_render_bundle_encoder( &self, device: &Self::DeviceId, - desc: &RenderBundleEncoderDescriptor, + desc: &crate::RenderBundleEncoderDescriptor, ) -> Self::RenderBundleEncoderId { let mapped_color_formats = desc .color_formats @@ -1450,14 +1445,14 @@ impl crate::Context for Context { swap_chain: &Self::SwapChainId, ) -> ( Option, - SwapChainStatus, + wgt::SwapChainStatus, Self::SwapChainOutputDetail, ) { // TODO: Should we pass a descriptor here? // Or is the default view always correct? ( Some(Sendable(swap_chain.0.get_current_texture().create_view())), - SwapChainStatus::Good, + wgt::SwapChainStatus::Good, (), ) } @@ -1473,7 +1468,7 @@ impl crate::Context for Context { fn texture_create_view( &self, texture: &Self::TextureId, - desc: &TextureViewDescriptor, + desc: &crate::TextureViewDescriptor, ) -> Self::TextureViewId { let mut mapped = web_sys::GpuTextureViewDescriptor::new(); if let Some(dim) = desc.dimension { @@ -1644,7 +1639,7 @@ impl crate::Context for Context { fn command_encoder_begin_compute_pass( &self, encoder: &Self::CommandEncoderId, - desc: &ComputePassDescriptor, + desc: &crate::ComputePassDescriptor, ) -> Self::ComputePassId { let mut mapped_desc = web_sys::GpuComputePassDescriptor::new(); if let Some(ref label) = desc.label { @@ -1674,8 +1669,12 @@ impl crate::Context for Context { web_sys::GpuRenderPassColorAttachmentDescriptor::new( &ca.attachment.id.0, &match ca.ops.load { - LoadOp::Clear(color) => wasm_bindgen::JsValue::from(map_color(color)), - LoadOp::Load => wasm_bindgen::JsValue::from(web_sys::GpuLoadOp::Load), + crate::LoadOp::Clear(color) => { + wasm_bindgen::JsValue::from(map_color(color)) + } + crate::LoadOp::Load => { + wasm_bindgen::JsValue::from(web_sys::GpuLoadOp::Load) + } }, ); @@ -1697,8 +1696,10 @@ impl crate::Context for Context { let (depth_load_op, depth_store_op) = match dsa.depth_ops { Some(ref ops) => { let load_op = match ops.load { - LoadOp::Clear(value) => wasm_bindgen::JsValue::from(value), - LoadOp::Load => wasm_bindgen::JsValue::from(web_sys::GpuLoadOp::Load), + crate::LoadOp::Clear(value) => wasm_bindgen::JsValue::from(value), + crate::LoadOp::Load => { + wasm_bindgen::JsValue::from(web_sys::GpuLoadOp::Load) + } }; (load_op, map_store_op(ops.store)) } @@ -1710,8 +1711,10 @@ impl crate::Context for Context { let (stencil_load_op, stencil_store_op) = match dsa.depth_ops { Some(ref ops) => { let load_op = match ops.load { - LoadOp::Clear(value) => wasm_bindgen::JsValue::from(value), - LoadOp::Load => wasm_bindgen::JsValue::from(web_sys::GpuLoadOp::Load), + crate::LoadOp::Clear(value) => wasm_bindgen::JsValue::from(value), + crate::LoadOp::Load => { + wasm_bindgen::JsValue::from(web_sys::GpuLoadOp::Load) + } }; (load_op, map_store_op(ops.store)) } diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index ec7444a717..b69539462b 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -25,19 +25,18 @@ use std::{ use parking_lot::Mutex; pub use wgt::{ - AdapterInfo, AddressMode, Backend, BackendBit, BindGroupLayoutEntry, BindingType, - BlendDescriptor, BlendFactor, BlendOperation, BufferAddress, BufferBindingType, BufferSize, - BufferUsage, Color, ColorStateDescriptor, ColorWrite, CommandBufferDescriptor, CompareFunction, - CullMode, DepthStencilStateDescriptor, DeviceType, DynamicOffset, Extent3d, Features, - FilterMode, FrontFace, IndexFormat, InputStepMode, Limits, Origin3d, PipelineStatisticsTypes, - PolygonMode, PowerPreference, PresentMode, PrimitiveTopology, PushConstantRange, - QuerySetDescriptor, QueryType, RasterizationStateDescriptor, SamplerBorderColor, ShaderFlags, - ShaderLocation, ShaderStage, StencilOperation, StencilStateDescriptor, - StencilStateFaceDescriptor, StorageTextureAccess, SwapChainDescriptor, SwapChainStatus, - TextureAspect, TextureDataLayout, TextureDimension, TextureFormat, TextureSampleType, - TextureUsage, TextureViewDimension, VertexAttributeDescriptor, VertexFormat, - BIND_BUFFER_ALIGNMENT, COPY_BUFFER_ALIGNMENT, COPY_BYTES_PER_ROW_ALIGNMENT, - PUSH_CONSTANT_ALIGNMENT, + AdapterInfo, AddressMode, Backend, BackendBit, BindGroupLayoutEntry, BindingType, BlendFactor, + BlendOperation, BlendState, BufferAddress, BufferBindingType, BufferSize, BufferUsage, Color, + ColorTargetState, ColorWrite, CommandBufferDescriptor, CompareFunction, CullMode, + DepthBiasState, DepthStencilState, DeviceType, DynamicOffset, Extent3d, Features, FilterMode, + FrontFace, IndexFormat, InputStepMode, Limits, MultisampleState, Origin3d, + PipelineStatisticsTypes, PolygonMode, PowerPreference, PresentMode, PrimitiveState, + PrimitiveTopology, PushConstantRange, QuerySetDescriptor, QueryType, SamplerBorderColor, + ShaderFlags, ShaderLocation, ShaderStage, StencilFaceState, StencilOperation, StencilState, + StorageTextureAccess, SwapChainDescriptor, SwapChainStatus, TextureAspect, TextureDataLayout, + TextureDimension, TextureFormat, TextureSampleType, TextureUsage, TextureViewDimension, + VertexAttribute, VertexFormat, BIND_BUFFER_ALIGNMENT, COPY_BUFFER_ALIGNMENT, + COPY_BYTES_PER_ROW_ALIGNMENT, PUSH_CONSTANT_ALIGNMENT, }; use backend::{BufferMappedRange, Context as C}; @@ -1152,25 +1151,53 @@ pub struct BindGroupDescriptor<'a> { pub entries: &'a [BindGroupEntry<'a>], } -/// Describes a programmable pipeline stage. +/// Describes the attachments of a render pass. +/// +/// Note: separate lifetimes are needed because the texture views +/// have to live as long as the pass is recorded, while everything else doesn't. +#[derive(Clone, Debug, Default)] +pub struct RenderPassDescriptor<'a, 'b> { + /// Debug label of the render pass. This will show up in graphics debuggers for easy identification. + pub label: Option<&'b str>, + /// The color attachments of the render pass. + pub color_attachments: &'b [RenderPassColorAttachmentDescriptor<'a>], + /// The depth and stencil attachment of the render pass, if any. + pub depth_stencil_attachment: Option>, +} + +/// Describes how the vertex buffer is interpreted. +#[derive(Clone, Debug, Hash, Eq, PartialEq)] +pub struct VertexBufferLayout<'a> { + /// The stride, in bytes, between elements of this buffer. + pub array_stride: BufferAddress, + /// How often this vertex buffer is "stepped" forward. + pub step_mode: InputStepMode, + /// The list of attributes which comprise a single vertex. + pub attributes: &'a [VertexAttribute], +} + +/// Describes the vertex process in a render pipeline. #[derive(Clone, Debug)] -pub struct ProgrammableStageDescriptor<'a> { +pub struct VertexState<'a> { /// The compiled shader module for this stage. pub module: &'a ShaderModule, /// The name of the entry point in the compiled shader. There must be a function that returns /// void with this name in the shader. pub entry_point: &'a str, + /// The format of any vertex buffers used with this pipeline. + pub buffers: &'a [VertexBufferLayout<'a>], } -/// Describes the attachments of a render pass. -#[derive(Clone, Debug, Default)] -pub struct RenderPassDescriptor<'a, 'b> { - /// Debug label of the render pass. This will show up in graphics debuggers for easy identification. - pub label: Option<&'a str>, - /// The color attachments of the render pass. - pub color_attachments: &'b [RenderPassColorAttachmentDescriptor<'a>], - /// The depth and stencil attachment of the render pass, if any. - pub depth_stencil_attachment: Option>, +/// Describes the fragment process in a render pipeline. +#[derive(Clone, Debug)] +pub struct FragmentState<'a> { + /// The compiled shader module for this stage. + pub module: &'a ShaderModule, + /// The name of the entry point in the compiled shader. There must be a function that returns + /// void with this name in the shader. + pub entry_point: &'a str, + /// The format of any vertex buffers used with this pipeline. + pub targets: &'a [ColorTargetState], } /// Describes a render (graphics) pipeline. @@ -1180,33 +1207,16 @@ pub struct RenderPipelineDescriptor<'a> { pub label: Option<&'a str>, /// The layout of bind groups for this pipeline. pub layout: Option<&'a PipelineLayout>, - /// The compiled vertex stage and its entry point. - pub vertex_stage: ProgrammableStageDescriptor<'a>, - /// The compiled fragment stage and its entry point, if any. - pub fragment_stage: Option>, - /// The rasterization process for this pipeline. - pub rasterization_state: Option, - /// The primitive topology used to interpret vertices. - pub primitive_topology: PrimitiveTopology, - /// The effect of draw calls on the color aspect of the output target. - pub color_states: &'a [ColorStateDescriptor], + /// The compiled vertex stage, its entry point, and the input buffers layout. + pub vertex: VertexState<'a>, + /// The properties of the pipeline at the primitive assembly and rasterization level. + pub primitive: PrimitiveState, /// The effect of draw calls on the depth and stencil aspects of the output target, if any. - pub depth_stencil_state: Option, - /// The vertex input state for this pipeline. - pub vertex_state: VertexStateDescriptor<'a>, - /// The number of samples calculated per pixel (for MSAA). For non-multisampled textures, - /// this should be `1` - pub sample_count: u32, - /// Bitmask that restricts the samples of a pixel modified by this pipeline. All samples - /// can be enabled using the value `!0` - pub sample_mask: u32, - /// When enabled, produces another sample mask per pixel based on the alpha output value, that - /// is ANDed with the sample_mask and the primitive coverage to restrict the set of samples - /// affected by a primitive. - /// - /// The implicit mask produced for alpha of zero is guaranteed to be zero, and for alpha of one - /// is guaranteed to be all 1-s. - pub alpha_to_coverage_enabled: bool, + pub depth_stencil: Option, + /// The multi-sampling properties of the pipeline. + pub multisample: MultisampleState, + /// The compiled fragment stage, its entry point, and the color targets. + pub fragment: Option>, } /// Describes the attachments of a compute pass. @@ -1223,8 +1233,11 @@ pub struct ComputePipelineDescriptor<'a> { pub label: Option<&'a str>, /// The layout of bind groups for this pipeline. pub layout: Option<&'a PipelineLayout>, - /// The compiled compute stage and its entry point. - pub compute_stage: ProgrammableStageDescriptor<'a>, + /// The compiled shader module for this stage. + pub module: &'a ShaderModule, + /// The name of the entry point in the compiled shader. There must be a function that returns + /// void with this name in the shader. + pub entry_point: &'a str, } pub use wgt::BufferCopyView as BufferCopyViewBase; @@ -1245,26 +1258,6 @@ pub struct BindGroupLayoutDescriptor<'a> { pub entries: &'a [BindGroupLayoutEntry], } -/// Describes how the vertex buffer is interpreted. -#[derive(Clone, Debug, Hash, Eq, PartialEq)] -pub struct VertexBufferDescriptor<'a> { - /// The stride, in bytes, between elements of this buffer. - pub stride: BufferAddress, - /// How often this vertex buffer is "stepped" forward. - pub step_mode: InputStepMode, - /// The list of attributes which comprise a single vertex. - pub attributes: &'a [VertexAttributeDescriptor], -} - -/// Describes vertex input state for a render pipeline. -#[derive(Clone, Debug, Hash, Eq, PartialEq)] -pub struct VertexStateDescriptor<'a> { - /// The format of any index buffers used with this pipeline. - pub index_format: Option, - /// The format of any vertex buffers used with this pipeline. - pub vertex_buffers: &'a [VertexBufferDescriptor<'a>], -} - /// Describes a [`RenderBundleEncoder`]. #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] pub struct RenderBundleEncoderDescriptor<'a> { diff --git a/wgpu/src/macros.rs b/wgpu/src/macros.rs index 62bb237e9c..d5a7dd0f01 100644 --- a/wgpu/src/macros.rs +++ b/wgpu/src/macros.rs @@ -1,13 +1,13 @@ //! Convenience macros -/// Macro to produce an array of [VertexAttributeDescriptor](crate::VertexAttributeDescriptor). +/// Macro to produce an array of [VertexAttribute](crate::VertexAttribute). /// -/// Output has type: `[VertexAttributeDescriptor; _]`. Usage is as follows: +/// Output has type: `[VertexAttribute; _]`. Usage is as follows: /// ``` /// # use wgpu::vertex_attr_array; /// let attrs = vertex_attr_array![0 => Float2, 1 => Float, 2 => Ushort4]; /// ``` -/// This example specifies a list of three [VertexAttributeDescriptor](crate::VertexAttributeDescriptor), +/// This example specifies a list of three [VertexAttribute](crate::VertexAttribute), /// each with the given `shader_location` and `format`. /// Offsets are calculated automatically. #[macro_export] @@ -19,7 +19,7 @@ macro_rules! vertex_attr_array { ([$($t:expr,)*] ; $off:expr ; $loc:expr => $item:ident, $($ll:expr => $ii:ident ,)*) => { $crate::vertex_attr_array!( [$($t,)* - $crate::VertexAttributeDescriptor { + $crate::VertexAttribute { format: $crate::VertexFormat :: $item, offset: $off, shader_location: $loc, @@ -33,7 +33,7 @@ macro_rules! vertex_attr_array { #[test] fn test_vertex_attr_array() { let attrs = vertex_attr_array![0 => Float2, 3 => Ushort4]; - // VertexAttributeDescriptor does not support PartialEq, so we cannot test directly + // VertexAttribute does not support PartialEq, so we cannot test directly assert_eq!(attrs.len(), 2); assert_eq!(attrs[0].offset, 0); assert_eq!(attrs[0].shader_location, 0);