diff options
author | 2023-02-07 23:55:16 +0100 | |
---|---|---|
committer | 2023-02-24 13:37:31 +0100 | |
commit | b8c1809ea101cece6943432fd3597f785c39af09 (patch) | |
tree | 662b5e85e67ff33be892811bc29bfe52ae041302 | |
parent | 23ed352e83dcb8a13acdac1cd4c7e2a9df492ebd (diff) | |
download | iced-b8c1809ea101cece6943432fd3597f785c39af09.tar.gz iced-b8c1809ea101cece6943432fd3597f785c39af09.tar.bz2 iced-b8c1809ea101cece6943432fd3597f785c39af09.zip |
Refactor `triangle::Pipeline` into `prepare` and `render` architecture
And get rid of the staging belt! :tada:
-rw-r--r-- | examples/integration/src/main.rs | 9 | ||||
-rw-r--r-- | wgpu/src/backend.rs | 17 | ||||
-rw-r--r-- | wgpu/src/buffer/dynamic.rs | 23 | ||||
-rw-r--r-- | wgpu/src/buffer/static.rs | 21 | ||||
-rw-r--r-- | wgpu/src/quad.rs | 7 | ||||
-rw-r--r-- | wgpu/src/triangle.rs | 561 | ||||
-rw-r--r-- | wgpu/src/window/compositor.rs | 11 |
7 files changed, 358 insertions, 291 deletions
diff --git a/examples/integration/src/main.rs b/examples/integration/src/main.rs index 69f6961e..5af30ab1 100644 --- a/examples/integration/src/main.rs +++ b/examples/integration/src/main.rs @@ -125,9 +125,6 @@ pub fn main() { let mut resized = false; - // Initialize staging belt - let mut staging_belt = wgpu::util::StagingBelt::new(5 * 1024); - // Initialize scene and GUI controls let scene = Scene::new(&device, format); let controls = Controls::new(); @@ -252,7 +249,6 @@ pub fn main() { backend.present( &device, &queue, - &mut staging_belt, &mut encoder, &view, primitive, @@ -262,7 +258,6 @@ pub fn main() { }); // Then we submit the work - staging_belt.finish(); queue.submit(Some(encoder.finish())); frame.present(); @@ -272,10 +267,6 @@ pub fn main() { state.mouse_interaction(), ), ); - - // And recall staging buffers - staging_belt.recall(); - } Err(error) => match error { wgpu::SurfaceError::OutOfMemory => { diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index 90a511ef..8c4c0daa 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -70,7 +70,6 @@ impl Backend { &mut self, device: &wgpu::Device, queue: &wgpu::Queue, - staging_belt: &mut wgpu::util::StagingBelt, encoder: &mut wgpu::CommandEncoder, frame: &wgpu::TextureView, primitives: &[Primitive], @@ -95,7 +94,6 @@ impl Backend { scale_factor, transformation, &layer, - staging_belt, encoder, frame, target_size, @@ -104,6 +102,7 @@ impl Backend { self.quad_pipeline.end_frame(); self.text_pipeline.end_frame(); + self.triangle_pipeline.end_frame(); #[cfg(any(feature = "image", feature = "svg"))] self.image_pipeline.end_frame(device, queue, encoder); @@ -116,7 +115,6 @@ impl Backend { scale_factor: f32, transformation: Transformation, layer: &Layer<'_>, - staging_belt: &mut wgpu::util::StagingBelt, encoder: &mut wgpu::CommandEncoder, target: &wgpu::TextureView, target_size: Size<u32>, @@ -159,15 +157,20 @@ impl Backend { let scaled = transformation * Transformation::scale(scale_factor, scale_factor); - self.triangle_pipeline.draw( + self.triangle_pipeline.prepare( + device, + queue, + &layer.meshes, + scaled, + ); + + self.triangle_pipeline.render( device, - staging_belt, encoder, target, target_size, - scaled, - scale_factor, &layer.meshes, + scale_factor, ); } diff --git a/wgpu/src/buffer/dynamic.rs b/wgpu/src/buffer/dynamic.rs index 88289b98..43fc47ac 100644 --- a/wgpu/src/buffer/dynamic.rs +++ b/wgpu/src/buffer/dynamic.rs @@ -112,25 +112,8 @@ impl<T: ShaderType + WriteInto> Buffer<T> { } /// Write the contents of this dynamic buffer to the GPU via staging belt command. - pub fn write( - &mut self, - device: &wgpu::Device, - staging_belt: &mut wgpu::util::StagingBelt, - encoder: &mut wgpu::CommandEncoder, - ) { - let size = self.cpu.get_ref().len(); - - if let Some(buffer_size) = wgpu::BufferSize::new(size as u64) { - let mut buffer = staging_belt.write_buffer( - encoder, - &self.gpu, - 0, - buffer_size, - device, - ); - - buffer.copy_from_slice(self.cpu.get_ref()); - } + pub fn write(&mut self, queue: &wgpu::Queue) { + queue.write_buffer(&self.gpu, 0, self.cpu.get_ref()); } // Gets the aligned offset at the given index from the CPU buffer. @@ -184,7 +167,7 @@ impl Internal { } /// Returns bytearray of aligned CPU buffer. - pub(super) fn get_ref(&self) -> &Vec<u8> { + pub(super) fn get_ref(&self) -> &[u8] { match self { Internal::Uniform(buf) => buf.as_ref(), #[cfg(not(target_arch = "wasm32"))] diff --git a/wgpu/src/buffer/static.rs b/wgpu/src/buffer/static.rs index ef87422f..7ae7edd2 100644 --- a/wgpu/src/buffer/static.rs +++ b/wgpu/src/buffer/static.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use std::mem; //128 triangles/indices -const DEFAULT_STATIC_BUFFER_COUNT: wgpu::BufferAddress = 128; +const DEFAULT_STATIC_BUFFER_COUNT: wgpu::BufferAddress = 1_000; /// A generic buffer struct useful for items which have no alignment requirements /// (e.g. Vertex, Index buffers) & no dynamic offsets. @@ -71,28 +71,15 @@ impl<T: Pod + Zeroable> Buffer<T> { /// Returns the size of the written bytes. pub fn write( &mut self, - device: &wgpu::Device, - staging_belt: &mut wgpu::util::StagingBelt, - encoder: &mut wgpu::CommandEncoder, + queue: &wgpu::Queue, offset: u64, content: &[T], ) -> u64 { let bytes = bytemuck::cast_slice(content); let bytes_size = bytes.len() as u64; - if let Some(buffer_size) = wgpu::BufferSize::new(bytes_size) { - let mut buffer = staging_belt.write_buffer( - encoder, - &self.gpu, - offset, - buffer_size, - device, - ); - - buffer.copy_from_slice(bytes); - - self.offsets.push(offset); - } + queue.write_buffer(&self.gpu, offset, bytes); + self.offsets.push(offset); bytes_size } diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs index 94bcec92..c1aa49c4 100644 --- a/wgpu/src/quad.rs +++ b/wgpu/src/quad.rs @@ -1,5 +1,4 @@ -use crate::buffer::Buffer; -use crate::Transformation; +use crate::{Buffer, Transformation}; use iced_graphics::layer; use iced_native::Rectangle; @@ -228,7 +227,7 @@ impl Layer { let instances = Buffer::new( device, "iced_wgpu::quad instance buffer", - MAX_INSTANCES, + INITIAL_INSTANCES, wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, ); @@ -302,7 +301,7 @@ const QUAD_VERTS: [Vertex; 4] = [ }, ]; -const MAX_INSTANCES: usize = 100_000; +const INITIAL_INSTANCES: usize = 10_000; #[repr(C)] #[derive(Debug, Clone, Copy, Zeroable, Pod)] diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs index efdd214b..572af1e8 100644 --- a/wgpu/src/triangle.rs +++ b/wgpu/src/triangle.rs @@ -14,50 +14,56 @@ use tracing::info_span; #[derive(Debug)] pub struct Pipeline { blit: Option<msaa::Blit>, - index_buffer: Buffer<u32>, - index_strides: Vec<u32>, solid: solid::Pipeline, /// Gradients are currently not supported on WASM targets due to their need of storage buffers. #[cfg(not(target_arch = "wasm32"))] gradient: gradient::Pipeline, + + layers: Vec<Layer>, + prepare_layer: usize, + render_layer: usize, } -impl Pipeline { - pub fn new( +#[derive(Debug)] +struct Layer { + index_buffer: Buffer<u32>, + index_strides: Vec<u32>, + solid: solid::Layer, + + #[cfg(not(target_arch = "wasm32"))] + gradient: gradient::Layer, +} + +impl Layer { + fn new( device: &wgpu::Device, - format: wgpu::TextureFormat, - antialiasing: Option<settings::Antialiasing>, - ) -> Pipeline { - Pipeline { - blit: antialiasing.map(|a| msaa::Blit::new(device, format, a)), + solid: &solid::Pipeline, + #[cfg(not(target_arch = "wasm32"))] gradient: &gradient::Pipeline, + ) -> Self { + Self { index_buffer: Buffer::new( device, "iced_wgpu::triangle vertex buffer", wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST, ), index_strides: Vec::new(), - solid: solid::Pipeline::new(device, format, antialiasing), + solid: solid::Layer::new(device, &solid.constants_layout), #[cfg(not(target_arch = "wasm32"))] - gradient: gradient::Pipeline::new(device, format, antialiasing), + gradient: gradient::Layer::new(device, &gradient.constants_layout), } } - pub fn draw( + fn prepare( &mut self, device: &wgpu::Device, - staging_belt: &mut wgpu::util::StagingBelt, - encoder: &mut wgpu::CommandEncoder, - target: &wgpu::TextureView, - target_size: Size<u32>, - transformation: Transformation, - scale_factor: f32, + queue: &wgpu::Queue, + solid: &solid::Pipeline, + #[cfg(not(target_arch = "wasm32"))] gradient: &gradient::Pipeline, meshes: &[Mesh<'_>], + transformation: Transformation, ) { - #[cfg(feature = "tracing")] - let _ = info_span!("Wgpu::Triangle", "DRAW").entered(); - // Count the total amount of vertices & indices we need to handle let count = mesh::attribute_count_of(meshes); @@ -75,6 +81,7 @@ impl Pipeline { .resize(device, count.gradient_vertices); // Prepare dynamic buffers & data store for writing + self.index_buffer.clear(); self.index_strides.clear(); self.solid.vertices.clear(); self.solid.uniforms.clear(); @@ -99,13 +106,8 @@ impl Pipeline { let transform = transformation * Transformation::translate(origin.x, origin.y); - let new_index_offset = self.index_buffer.write( - device, - staging_belt, - encoder, - index_offset, - indices, - ); + let new_index_offset = + self.index_buffer.write(queue, index_offset, indices); index_offset += new_index_offset; self.index_strides.push(indices.len() as u32); @@ -116,9 +118,7 @@ impl Pipeline { self.solid.uniforms.push(&solid::Uniforms::new(transform)); let written_bytes = self.solid.vertices.write( - device, - staging_belt, - encoder, + queue, solid_vertex_offset, &buffers.vertices, ); @@ -130,9 +130,7 @@ impl Pipeline { buffers, gradient, .. } => { let written_bytes = self.gradient.vertices.write( - device, - staging_belt, - encoder, + queue, gradient_vertex_offset, &buffers.vertices, ); @@ -196,14 +194,14 @@ impl Pipeline { let uniforms_resized = self.solid.uniforms.resize(device); if uniforms_resized { - self.solid.bind_group = solid::Pipeline::bind_group( + self.solid.constants = solid::Layer::bind_group( device, self.solid.uniforms.raw(), - &self.solid.bind_group_layout, + &solid.constants_layout, ) } - self.solid.uniforms.write(device, staging_belt, encoder); + self.solid.uniforms.write(queue); } #[cfg(not(target_arch = "wasm32"))] @@ -218,22 +216,169 @@ impl Pipeline { let storage_resized = self.gradient.storage.resize(device); if uniforms_resized || storage_resized { - self.gradient.bind_group = gradient::Pipeline::bind_group( + self.gradient.constants = gradient::Layer::bind_group( device, self.gradient.uniforms.raw(), self.gradient.storage.raw(), - &self.gradient.bind_group_layout, + &gradient.constants_layout, ); } // Write to GPU - self.gradient.uniforms.write(device, staging_belt, encoder); - self.gradient.storage.write(device, staging_belt, encoder); + self.gradient.uniforms.write(queue); + self.gradient.storage.write(queue); // Cleanup self.gradient.color_stop_offset = 0; self.gradient.color_stops_pending_write.color_stops.clear(); } + } + + fn render<'a>( + &'a mut self, + solid: &'a solid::Pipeline, + #[cfg(not(target_arch = "wasm32"))] gradient: &'a gradient::Pipeline, + meshes: &[Mesh<'_>], + scale_factor: f32, + render_pass: &mut wgpu::RenderPass<'a>, + ) { + let mut num_solids = 0; + #[cfg(not(target_arch = "wasm32"))] + let mut num_gradients = 0; + let mut last_is_solid = None; + + for (index, mesh) in meshes.iter().enumerate() { + let clip_bounds = (mesh.clip_bounds() * scale_factor).snap(); + + render_pass.set_scissor_rect( + clip_bounds.x, + clip_bounds.y, + clip_bounds.width, + clip_bounds.height, + ); + + match mesh { + Mesh::Solid { .. } => { + if !last_is_solid.unwrap_or(false) { + render_pass.set_pipeline(&solid.pipeline); + + last_is_solid = Some(true); + } + + render_pass.set_bind_group( + 0, + &self.solid.constants, + &[self.solid.uniforms.offset_at_index(num_solids)], + ); + + render_pass.set_vertex_buffer( + 0, + self.solid.vertices.slice_from_index(num_solids), + ); + + num_solids += 1; + } + #[cfg(not(target_arch = "wasm32"))] + Mesh::Gradient { .. } => { + if last_is_solid.unwrap_or(true) { + render_pass.set_pipeline(&gradient.pipeline); + + last_is_solid = Some(false); + } + + render_pass.set_bind_group( + 0, + &self.gradient.constants, + &[self + .gradient + .uniforms + .offset_at_index(num_gradients)], + ); + + render_pass.set_vertex_buffer( + 0, + self.gradient.vertices.slice_from_index(num_gradients), + ); + + num_gradients += 1; + } + #[cfg(target_arch = "wasm32")] + Mesh::Gradient { .. } => {} + }; + + render_pass.set_index_buffer( + self.index_buffer.slice_from_index(index), + wgpu::IndexFormat::Uint32, + ); + + render_pass.draw_indexed(0..self.index_strides[index], 0, 0..1); + } + } +} + +impl Pipeline { + pub fn new( + device: &wgpu::Device, + format: wgpu::TextureFormat, + antialiasing: Option<settings::Antialiasing>, + ) -> Pipeline { + Pipeline { + blit: antialiasing.map(|a| msaa::Blit::new(device, format, a)), + solid: solid::Pipeline::new(device, format, antialiasing), + + #[cfg(not(target_arch = "wasm32"))] + gradient: gradient::Pipeline::new(device, format, antialiasing), + + layers: Vec::new(), + prepare_layer: 0, + render_layer: 0, + } + } + + pub fn prepare( + &mut self, + device: &wgpu::Device, + queue: &wgpu::Queue, + meshes: &[Mesh<'_>], + transformation: Transformation, + ) { + #[cfg(feature = "tracing")] + let _ = info_span!("Wgpu::Triangle", "PREPARE").entered(); + + if self.layers.len() <= self.prepare_layer { + self.layers.push(Layer::new( + device, + &self.solid, + #[cfg(not(target_arch = "wasm32"))] + &self.gradient, + )); + } + + let layer = &mut self.layers[self.prepare_layer]; + layer.prepare( + device, + queue, + &self.solid, + #[cfg(not(target_arch = "wasm32"))] + &self.gradient, + meshes, + transformation, + ); + + self.prepare_layer += 1; + } + + pub fn render( + &mut self, + device: &wgpu::Device, + encoder: &mut wgpu::CommandEncoder, + target: &wgpu::TextureView, + target_size: Size<u32>, + meshes: &[Mesh<'_>], + scale_factor: f32, + ) { + #[cfg(feature = "tracing")] + let _ = info_span!("Wgpu::Triangle", "DRAW").entered(); // Configure render pass { @@ -268,87 +413,29 @@ impl Pipeline { depth_stencil_attachment: None, }); - let mut num_solids = 0; - #[cfg(not(target_arch = "wasm32"))] - let mut num_gradients = 0; - let mut last_is_solid = None; - - for (index, mesh) in meshes.iter().enumerate() { - let clip_bounds = (mesh.clip_bounds() * scale_factor).snap(); - - render_pass.set_scissor_rect( - clip_bounds.x, - clip_bounds.y, - clip_bounds.width, - clip_bounds.height, - ); - - match mesh { - Mesh::Solid { .. } => { - if !last_is_solid.unwrap_or(false) { - render_pass.set_pipeline(&self.solid.pipeline); - - last_is_solid = Some(true); - } - - render_pass.set_bind_group( - 0, - &self.solid.bind_group, - &[self.solid.uniforms.offset_at_index(num_solids)], - ); - - render_pass.set_vertex_buffer( - 0, - self.solid.vertices.slice_from_index(num_solids), - ); - - num_solids += 1; - } - #[cfg(not(target_arch = "wasm32"))] - Mesh::Gradient { .. } => { - if last_is_solid.unwrap_or(true) { - render_pass.set_pipeline(&self.gradient.pipeline); - - last_is_solid = Some(false); - } - - render_pass.set_bind_group( - 0, - &self.gradient.bind_group, - &[self - .gradient - .uniforms - .offset_at_index(num_gradients)], - ); - - render_pass.set_vertex_buffer( - 0, - self.gradient - .vertices - .slice_from_index(num_gradients), - ); - - num_gradients += 1; - } - #[cfg(target_arch = "wasm32")] - Mesh::Gradient { .. } => {} - }; - - render_pass.set_index_buffer( - self.index_buffer.slice_from_index(index), - wgpu::IndexFormat::Uint32, - ); + let layer = &mut self.layers[self.render_layer]; - render_pass.draw_indexed(0..self.index_strides[index], 0, 0..1); - } + layer.render( + &self.solid, + #[cfg(not(target_arch = "wasm32"))] + &self.gradient, + meshes, + scale_factor, + &mut render_pass, + ); } - self.index_buffer.clear(); + self.render_layer += 1; if let Some(blit) = &mut self.blit { blit.draw(encoder, target); } } + + pub fn end_frame(&mut self) { + self.prepare_layer = 0; + self.render_layer = 0; + } } fn fragment_target( @@ -390,10 +477,62 @@ mod solid { #[derive(Debug)] pub struct Pipeline { pub pipeline: wgpu::RenderPipeline, + pub constants_layout: wgpu::BindGroupLayout, + } + + #[derive(Debug)] + pub struct Layer { pub vertices: Buffer<triangle::ColoredVertex2D>, pub uniforms: dynamic::Buffer<Uniforms>, - pub bind_group_layout: wgpu::BindGroupLayout, - pub bind_group: wgpu::BindGroup, + pub constants: wgpu::BindGroup, + } + + impl Layer { + pub fn new( + device: &wgpu::Device, + constants_layout: &wgpu::BindGroupLayout, + ) -> Self { + let vertices = Buffer::new( + device, + "iced_wgpu::triangle::solid vertex buffer", + wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, + ); + + let uniforms = dynamic::Buffer::uniform( + device, + "iced_wgpu::triangle::solid uniforms", + ); + + let constants = + Self::bind_group(device, uniforms.raw(), constants_layout); + + Self { + vertices, + uniforms, + constants, + } + } + + pub fn bind_group( + device: &wgpu::Device, + buffer: &wgpu::Buffer, + layout: &wgpu::BindGroupLayout, + ) -> wgpu::BindGroup { + device.create_bind_group(&wgpu::BindGroupDescriptor { + label: Some("iced_wgpu::triangle::solid bind group"), + layout, + entries: &[wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::Buffer( + wgpu::BufferBinding { + buffer, + offset: 0, + size: Some(Uniforms::min_size()), + }, + ), + }], + }) + } } #[derive(Debug, Clone, Copy, ShaderType)] @@ -416,18 +555,7 @@ mod solid { format: wgpu::TextureFormat, antialiasing: Option<settings::Antialiasing>, ) -> Self { - let vertices = Buffer::new( - device, - "iced_wgpu::triangle::solid vertex buffer", - wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, - ); - - let uniforms = dynamic::Buffer::uniform( - device, - "iced_wgpu::triangle::solid uniforms", - ); - - let bind_group_layout = device.create_bind_group_layout( + let constants_layout = device.create_bind_group_layout( &wgpu::BindGroupLayoutDescriptor { label: Some("iced_wgpu::triangle::solid bind group layout"), entries: &[wgpu::BindGroupLayoutEntry { @@ -443,13 +571,10 @@ mod solid { }, ); - let bind_group = - Self::bind_group(device, uniforms.raw(), &bind_group_layout); - let layout = device.create_pipeline_layout( &wgpu::PipelineLayoutDescriptor { label: Some("iced_wgpu::triangle::solid pipeline layout"), - bind_group_layouts: &[&bind_group_layout], + bind_group_layouts: &[&constants_layout], push_constant_ranges: &[], }, ); @@ -501,33 +626,9 @@ mod solid { Self { pipeline, - vertices, - uniforms, - bind_group_layout, - bind_group, + constants_layout, } } - - pub fn bind_group( - device: &wgpu::Device, - buffer: &wgpu::Buffer, - layout: &wgpu::BindGroupLayout, - ) -> wgpu::BindGroup { - device.create_bind_group(&wgpu::BindGroupDescriptor { - label: Some("iced_wgpu::triangle::solid bind group"), - layout, - entries: &[wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::Buffer( - wgpu::BufferBinding { - buffer, - offset: 0, - size: Some(Uniforms::min_size()), - }, - ), - }], - }) - } } } @@ -545,15 +646,90 @@ mod gradient { #[derive(Debug)] pub struct Pipeline { pub pipeline: wgpu::RenderPipeline, + pub constants_layout: wgpu::BindGroupLayout, + } + + #[derive(Debug)] + pub struct Layer { pub vertices: Buffer<Vertex2D>, pub uniforms: dynamic::Buffer<Uniforms>, pub storage: dynamic::Buffer<Storage>, + pub constants: wgpu::BindGroup, pub color_stop_offset: i32, //Need to store these and then write them all at once //or else they will be padded to 256 and cause gaps in the storage buffer pub color_stops_pending_write: Storage, - pub bind_group_layout: wgpu::BindGroupLayout, - pub bind_group: wgpu::BindGroup, + } + + impl Layer { + pub fn new( + device: &wgpu::Device, + constants_layout: &wgpu::BindGroupLayout, + ) -> Self { + let vertices = Buffer::new( + device, + "iced_wgpu::triangle::gradient vertex buffer", + wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, + ); + + let uniforms = dynamic::Buffer::uniform( + device, + "iced_wgpu::triangle::gradient uniforms", + ); + + // Note: with a WASM target storage buffers are not supported. Will need to use UBOs & static + // sized array (eg like the 32-sized array on OpenGL side right now) to make gradients work + let storage = dynamic::Buffer::storage( + device, + "iced_wgpu::triangle::gradient storage", + ); + + let constants = Self::bind_group( + device, + uniforms.raw(), + storage.raw(), + constants_layout, + ); + + Self { + vertices, + uniforms, + storage, + constants, + color_stop_offset: 0, + color_stops_pending_write: Storage { + color_stops: vec![], + }, + } + } + + pub fn bind_group( + device: &wgpu::Device, + uniform_buffer: &wgpu::Buffer, + storage_buffer: &wgpu::Buffer, + layout: &wgpu::BindGroupLayout, + ) -> wgpu::BindGroup { + device.create_bind_group(&wgpu::BindGroupDescriptor { + label: Some("iced_wgpu::triangle::gradient bind group"), + layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::Buffer( + wgpu::BufferBinding { + buffer: uniform_buffer, + offset: 0, + size: Some(Uniforms::min_size()), + }, + ), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: storage_buffer.as_entire_binding(), + }, + ], + }) + } } #[derive(Debug, ShaderType)] @@ -584,25 +760,7 @@ mod gradient { format: wgpu::TextureFormat, antialiasing: Option<settings::Antialiasing>, ) -> Self { - let vertices = Buffer::new( - device, - "iced_wgpu::triangle::gradient vertex buffer", - wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, - ); - - let uniforms = dynamic::Buffer::uniform( - device, - "iced_wgpu::triangle::gradient uniforms", - ); - - //Note: with a WASM target storage buffers are not supported. Will need to use UBOs & static - // sized array (eg like the 32-sized array on OpenGL side right now) to make gradients work - let storage = dynamic::Buffer::storage( - device, - "iced_wgpu::triangle::gradient storage", - ); - - let bind_group_layout = device.create_bind_group_layout( + let constants_layout = device.create_bind_group_layout( &wgpu::BindGroupLayoutDescriptor { label: Some( "iced_wgpu::triangle::gradient bind group layout", @@ -634,19 +792,12 @@ mod gradient { }, ); - let bind_group = Pipeline::bind_group( - device, - uniforms.raw(), - storage.raw(), - &bind_group_layout, - ); - let layout = device.create_pipeline_layout( &wgpu::PipelineLayoutDescriptor { label: Some( "iced_wgpu::triangle::gradient pipeline layout", ), - bind_group_layouts: &[&bind_group_layout], + bind_group_layouts: &[&constants_layout], push_constant_ranges: &[], }, ); @@ -694,44 +845,8 @@ mod gradient { Self { pipeline, - vertices, - uniforms, - storage, - color_stop_offset: 0, - color_stops_pending_write: Storage { - color_stops: vec![], - }, - bind_group_layout, - bind_group, + constants_layout, } } - - pub fn bind_group( - device: &wgpu::Device, - uniform_buffer: &wgpu::Buffer, - storage_buffer: &wgpu::Buffer, - layout: &wgpu::BindGroupLayout, - ) -> wgpu::BindGroup { - device.create_bind_group(&wgpu::BindGroupDescriptor { - label: Some("iced_wgpu::triangle::gradient bind group"), - layout, - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::Buffer( - wgpu::BufferBinding { - buffer: uniform_buffer, - offset: 0, - size: Some(Uniforms::min_size()), - }, - ), - }, - wgpu::BindGroupEntry { - binding: 1, - resource: storage_buffer.as_entire_binding(), - }, - ], - }) - } } } diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index 50231f7c..6e1acc06 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -16,14 +16,11 @@ pub struct Compositor<Theme> { adapter: wgpu::Adapter, device: wgpu::Device, queue: wgpu::Queue, - staging_belt: wgpu::util::StagingBelt, format: wgpu::TextureFormat, theme: PhantomData<Theme>, } impl<Theme> Compositor<Theme> { - const CHUNK_SIZE: u64 = 10 * 1024; - /// Requests a new [`Compositor`] with the given [`Settings`]. /// /// Returns `None` if no compatible graphics adapter could be found. @@ -98,15 +95,12 @@ impl<Theme> Compositor<Theme> { .next() .await?; - let staging_belt = wgpu::util::StagingBelt::new(Self::CHUNK_SIZE); - Some(Compositor { instance, settings, adapter, device, queue, - staging_belt, format, theme: PhantomData, }) @@ -228,7 +222,6 @@ impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> { backend.present( &self.device, &self.queue, - &mut self.staging_belt, &mut encoder, view, primitives, @@ -238,13 +231,9 @@ impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> { }); // Submit work - self.staging_belt.finish(); let _submission = self.queue.submit(Some(encoder.finish())); frame.present(); - // Recall staging buffers - self.staging_belt.recall(); - Ok(()) } Err(error) => match error { |